agent-cli 0.96.1__tar.gz → 0.96.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (444) hide show
  1. {agent_cli-0.96.1 → agent_cli-0.96.3}/Casks/agent-cli.rb +2 -2
  2. {agent_cli-0.96.1 → agent_cli-0.96.3}/PKG-INFO +1 -1
  3. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/AgentCommand.swift +4 -0
  4. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/AgentCommandRunner.swift +79 -19
  5. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/BootstrapState.swift +6 -7
  6. agent_cli-0.96.3/macos/AgentCLI/Sources/AgentCLI/MenuActivityStatus.swift +29 -0
  7. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/StatusMenuController.swift +48 -1
  8. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/VoiceLevelOverlay.swift +41 -18
  9. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Tests/AgentCLITests/AgentCommandTests.swift +30 -0
  10. agent_cli-0.96.3/macos/AgentCLI/Tests/AgentCLITests/VoiceLevelMeterTests.swift +39 -0
  11. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/appcast.xml +33 -0
  12. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_macos_app.py +1 -0
  13. agent_cli-0.96.1/macos/AgentCLI/Sources/AgentCLI/VoiceSpectrumAnalyzer.swift +0 -71
  14. agent_cli-0.96.1/macos/AgentCLI/Tests/AgentCLITests/VoiceSpectrumAnalyzerTests.swift +0 -49
  15. {agent_cli-0.96.1 → agent_cli-0.96.3}/.claude/skills/agent-cli-dev/SKILL.md +0 -0
  16. {agent_cli-0.96.1 → agent_cli-0.96.3}/.claude/skills/agent-cli-dev/examples.md +0 -0
  17. {agent_cli-0.96.1 → agent_cli-0.96.3}/.claude-plugin/README.md +0 -0
  18. {agent_cli-0.96.1 → agent_cli-0.96.3}/.claude-plugin/marketplace.json +0 -0
  19. {agent_cli-0.96.1 → agent_cli-0.96.3}/.claude-plugin/plugin.json +0 -0
  20. {agent_cli-0.96.1 → agent_cli-0.96.3}/.claude-plugin/skills/agent-cli-dev/SKILL.md +0 -0
  21. {agent_cli-0.96.1 → agent_cli-0.96.3}/.claude-plugin/skills/agent-cli-dev/examples.md +0 -0
  22. {agent_cli-0.96.1 → agent_cli-0.96.3}/.cursorrules +0 -0
  23. {agent_cli-0.96.1 → agent_cli-0.96.3}/.dockerignore +0 -0
  24. {agent_cli-0.96.1 → agent_cli-0.96.3}/.env.example +0 -0
  25. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/logo.svg +0 -0
  26. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/release-drafter.yml +0 -0
  27. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/renovate.json +0 -0
  28. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/scripts/check_extras_sync.py +0 -0
  29. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/scripts/check_plugin_skill_sync.py +0 -0
  30. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/scripts/normalize_appcast.py +0 -0
  31. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/scripts/sync_extras.py +0 -0
  32. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/scripts/sync_requirements.py +0 -0
  33. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/scripts/update_cask.py +0 -0
  34. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/workflows/automerge.yml +0 -0
  35. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/workflows/docker.yml +0 -0
  36. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/workflows/docs.yml +0 -0
  37. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/workflows/markdown-code-runner.yml +0 -0
  38. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/workflows/pytest.yml +0 -0
  39. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/workflows/release-drafter.yml +0 -0
  40. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/workflows/release.yml +0 -0
  41. {agent_cli-0.96.1 → agent_cli-0.96.3}/.github/workflows/toc.yaml +0 -0
  42. {agent_cli-0.96.1 → agent_cli-0.96.3}/.gitignore +0 -0
  43. {agent_cli-0.96.1 → agent_cli-0.96.3}/.jscpd.json +0 -0
  44. {agent_cli-0.96.1 → agent_cli-0.96.3}/.pre-commit-config.yaml +0 -0
  45. {agent_cli-0.96.1 → agent_cli-0.96.3}/.prompts/docs-review.md +0 -0
  46. {agent_cli-0.96.1 → agent_cli-0.96.3}/.prompts/pr-review.md +0 -0
  47. {agent_cli-0.96.1 → agent_cli-0.96.3}/CLAUDE.md +0 -0
  48. {agent_cli-0.96.1 → agent_cli-0.96.3}/LICENSE +0 -0
  49. {agent_cli-0.96.1 → agent_cli-0.96.3}/LLAMA_SERVER_USAGE.md +0 -0
  50. {agent_cli-0.96.1 → agent_cli-0.96.3}/README.md +0 -0
  51. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/__init__.py +0 -0
  52. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/__main__.py +0 -0
  53. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_extras.json +0 -0
  54. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_requirements/.gitkeep +0 -0
  55. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_requirements/audio.txt +0 -0
  56. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_requirements/diarization.txt +0 -0
  57. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_requirements/faster-whisper.txt +0 -0
  58. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_requirements/kokoro.txt +0 -0
  59. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_requirements/llm.txt +0 -0
  60. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_requirements/memory.txt +0 -0
  61. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_requirements/mlx-whisper.txt +0 -0
  62. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_requirements/piper.txt +0 -0
  63. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_requirements/rag.txt +0 -0
  64. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_requirements/server.txt +0 -0
  65. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_requirements/speed.txt +0 -0
  66. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_requirements/vad.txt +0 -0
  67. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_requirements/vectordb.txt +0 -0
  68. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_requirements/whisper-transformers.txt +0 -0
  69. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_requirements/wyoming.txt +0 -0
  70. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/_tools.py +0 -0
  71. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/agents/__init__.py +0 -0
  72. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/agents/_voice_agent_common.py +0 -0
  73. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/agents/assistant.py +0 -0
  74. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/agents/autocorrect.py +0 -0
  75. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/agents/chat.py +0 -0
  76. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/agents/diarize_live_session.py +0 -0
  77. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/agents/memory/__init__.py +0 -0
  78. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/agents/memory/add.py +0 -0
  79. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/agents/memory/proxy.py +0 -0
  80. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/agents/rag_proxy.py +0 -0
  81. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/agents/speak.py +0 -0
  82. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/agents/speakers.py +0 -0
  83. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/agents/transcribe.py +0 -0
  84. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/agents/transcribe_live.py +0 -0
  85. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/agents/voice_edit.py +0 -0
  86. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/api.py +0 -0
  87. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/cli.py +0 -0
  88. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/config.py +0 -0
  89. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/config_cmd.py +0 -0
  90. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/constants.py +0 -0
  91. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/core/__init__.py +0 -0
  92. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/core/alignment.py +0 -0
  93. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/core/audio.py +0 -0
  94. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/core/audio_format.py +0 -0
  95. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/core/chroma.py +0 -0
  96. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/core/deps.py +0 -0
  97. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/core/diarization.py +0 -0
  98. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/core/openai_proxy.py +0 -0
  99. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/core/process.py +0 -0
  100. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/core/reranker.py +0 -0
  101. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/core/speaker_identity.py +0 -0
  102. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/core/sse.py +0 -0
  103. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/core/transcription_logger.py +0 -0
  104. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/core/utils.py +0 -0
  105. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/core/vad.py +0 -0
  106. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/core/watch.py +0 -0
  107. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/daemon/__init__.py +0 -0
  108. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/daemon/cli.py +0 -0
  109. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/__init__.py +0 -0
  110. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/_branch_name.py +0 -0
  111. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/_config.py +0 -0
  112. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/_output.py +0 -0
  113. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/cleanup.py +0 -0
  114. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/cli.py +0 -0
  115. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/coding_agents/__init__.py +0 -0
  116. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/coding_agents/aider.py +0 -0
  117. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/coding_agents/base.py +0 -0
  118. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/coding_agents/claude.py +0 -0
  119. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/coding_agents/codex.py +0 -0
  120. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/coding_agents/continue_dev.py +0 -0
  121. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/coding_agents/copilot.py +0 -0
  122. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/coding_agents/cursor_agent.py +0 -0
  123. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/coding_agents/gemini.py +0 -0
  124. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/coding_agents/opencode.py +0 -0
  125. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/coding_agents/registry.py +0 -0
  126. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/editors/__init__.py +0 -0
  127. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/editors/base.py +0 -0
  128. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/editors/cursor.py +0 -0
  129. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/editors/emacs.py +0 -0
  130. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/editors/jetbrains.py +0 -0
  131. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/editors/nano.py +0 -0
  132. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/editors/neovim.py +0 -0
  133. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/editors/registry.py +0 -0
  134. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/editors/sublime.py +0 -0
  135. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/editors/vim.py +0 -0
  136. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/editors/vscode.py +0 -0
  137. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/editors/zed.py +0 -0
  138. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/hooks.py +0 -0
  139. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/launch.py +0 -0
  140. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/project.py +0 -0
  141. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/registry.py +0 -0
  142. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/skill/SKILL.md +0 -0
  143. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/skill/examples.md +0 -0
  144. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/terminals/__init__.py +0 -0
  145. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/terminals/apple_terminal.py +0 -0
  146. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/terminals/base.py +0 -0
  147. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/terminals/gnome.py +0 -0
  148. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/terminals/iterm2.py +0 -0
  149. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/terminals/kitty.py +0 -0
  150. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/terminals/registry.py +0 -0
  151. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/terminals/tmux.py +0 -0
  152. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/terminals/warp.py +0 -0
  153. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/terminals/zellij.py +0 -0
  154. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/dev/worktree.py +0 -0
  155. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/docs_gen.py +0 -0
  156. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/example-config.toml +0 -0
  157. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/install/__init__.py +0 -0
  158. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/install/common.py +0 -0
  159. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/install/extras.py +0 -0
  160. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/install/hotkeys.py +0 -0
  161. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/install/launchd.py +0 -0
  162. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/install/service_config.py +0 -0
  163. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/install/services.py +0 -0
  164. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/install/systemd.py +0 -0
  165. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/__init__.py +0 -0
  166. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/_files.py +0 -0
  167. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/_filters.py +0 -0
  168. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/_git.py +0 -0
  169. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/_indexer.py +0 -0
  170. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/_ingest.py +0 -0
  171. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/_persistence.py +0 -0
  172. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/_prompt.py +0 -0
  173. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/_retrieval.py +0 -0
  174. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/_store.py +0 -0
  175. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/_streaming.py +0 -0
  176. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/_tasks.py +0 -0
  177. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/api.py +0 -0
  178. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/client.py +0 -0
  179. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/engine.py +0 -0
  180. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/entities.py +0 -0
  181. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/memory/models.py +0 -0
  182. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/opts.py +0 -0
  183. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/py.typed +0 -0
  184. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/rag/__init__.py +0 -0
  185. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/rag/_indexer.py +0 -0
  186. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/rag/_indexing.py +0 -0
  187. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/rag/_prompt.py +0 -0
  188. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/rag/_retriever.py +0 -0
  189. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/rag/_store.py +0 -0
  190. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/rag/_utils.py +0 -0
  191. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/rag/api.py +0 -0
  192. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/rag/client.py +0 -0
  193. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/rag/engine.py +0 -0
  194. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/rag/models.py +0 -0
  195. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/.runtime/.gitkeep +0 -0
  196. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/__init__.py +0 -0
  197. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/linux-hotkeys/README.md +0 -0
  198. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/linux-hotkeys/toggle-autocorrect.sh +0 -0
  199. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/linux-hotkeys/toggle-transcription.sh +0 -0
  200. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/linux-hotkeys/toggle-voice-edit.sh +0 -0
  201. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/macos-hotkeys/README.md +0 -0
  202. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/macos-hotkeys/skhd-config-example +0 -0
  203. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/macos-hotkeys/toggle-autocorrect.sh +0 -0
  204. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/macos-hotkeys/toggle-transcription.sh +0 -0
  205. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/macos-hotkeys/toggle-voice-edit.sh +0 -0
  206. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/nvidia-asr-server/README.md +0 -0
  207. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/nvidia-asr-server/pyproject.toml +0 -0
  208. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/nvidia-asr-server/server.py +0 -0
  209. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/nvidia-asr-server/shell.nix +0 -0
  210. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/nvidia-asr-server/uv.lock +0 -0
  211. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/run-openwakeword.sh +0 -0
  212. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/setup-linux-hotkeys.sh +0 -0
  213. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/setup-linux.sh +0 -0
  214. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/setup-macos-hotkeys.sh +0 -0
  215. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/setup-macos.sh +0 -0
  216. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/setup-windows.ps1 +0 -0
  217. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/start-all-services-windows.ps1 +0 -0
  218. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/scripts/start-all-services.sh +0 -0
  219. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/__init__.py +0 -0
  220. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/cli.py +0 -0
  221. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/common.py +0 -0
  222. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/model_manager.py +0 -0
  223. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/model_registry.py +0 -0
  224. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/proxy/__init__.py +0 -0
  225. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/proxy/api.py +0 -0
  226. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/streaming.py +0 -0
  227. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/tts/__init__.py +0 -0
  228. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/tts/api.py +0 -0
  229. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/tts/backends/__init__.py +0 -0
  230. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/tts/backends/base.py +0 -0
  231. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/tts/backends/kokoro.py +0 -0
  232. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/tts/backends/piper.py +0 -0
  233. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/tts/model_manager.py +0 -0
  234. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/tts/model_registry.py +0 -0
  235. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/tts/wyoming_handler.py +0 -0
  236. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/whisper/__init__.py +0 -0
  237. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/whisper/api.py +0 -0
  238. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/whisper/backends/__init__.py +0 -0
  239. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/whisper/backends/base.py +0 -0
  240. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/whisper/backends/faster_whisper.py +0 -0
  241. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/whisper/backends/mlx.py +0 -0
  242. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/whisper/backends/transformers.py +0 -0
  243. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/whisper/languages.py +0 -0
  244. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/whisper/model_manager.py +0 -0
  245. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/whisper/model_registry.py +0 -0
  246. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/server/whisper/wyoming_handler.py +0 -0
  247. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/services/__init__.py +0 -0
  248. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/services/_wyoming_utils.py +0 -0
  249. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/services/asr.py +0 -0
  250. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/services/llm.py +0 -0
  251. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/services/tts.py +0 -0
  252. {agent_cli-0.96.1 → agent_cli-0.96.3}/agent_cli/services/wake_word.py +0 -0
  253. {agent_cli-0.96.1 → agent_cli-0.96.3}/docker/docker-compose.yml +0 -0
  254. {agent_cli-0.96.1 → agent_cli-0.96.3}/docker/memory-proxy.Dockerfile +0 -0
  255. {agent_cli-0.96.1 → agent_cli-0.96.3}/docker/rag-proxy.Dockerfile +0 -0
  256. {agent_cli-0.96.1 → agent_cli-0.96.3}/docker/transcribe-proxy.Dockerfile +0 -0
  257. {agent_cli-0.96.1 → agent_cli-0.96.3}/docker/tts.Dockerfile +0 -0
  258. {agent_cli-0.96.1 → agent_cli-0.96.3}/docker/whisper.Dockerfile +0 -0
  259. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/CNAME +0 -0
  260. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/architecture/index.md +0 -0
  261. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/architecture/memory.md +0 -0
  262. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/architecture/rag.md +0 -0
  263. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/assistant.md +0 -0
  264. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/autocorrect.md +0 -0
  265. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/chat.md +0 -0
  266. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/config.md +0 -0
  267. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/daemon.md +0 -0
  268. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/dev.md +0 -0
  269. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/diarize-live-session.md +0 -0
  270. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/index.md +0 -0
  271. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/install-extras.md +0 -0
  272. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/install-hotkeys.md +0 -0
  273. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/install-services.md +0 -0
  274. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/memory.md +0 -0
  275. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/rag-proxy.md +0 -0
  276. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/server/index.md +0 -0
  277. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/server/transcribe-proxy.md +0 -0
  278. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/server/tts.md +0 -0
  279. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/server/whisper.md +0 -0
  280. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/speak.md +0 -0
  281. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/speakers.md +0 -0
  282. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/start-services.md +0 -0
  283. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/transcribe-live.md +0 -0
  284. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/transcribe.md +0 -0
  285. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/commands/voice-edit.md +0 -0
  286. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/configuration.md +0 -0
  287. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/getting-started.md +0 -0
  288. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/iOS_Shortcut_Guide.md +0 -0
  289. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/index.md +0 -0
  290. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/installation/docker.md +0 -0
  291. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/installation/index.md +0 -0
  292. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/installation/linux.md +0 -0
  293. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/installation/macos-app.md +0 -0
  294. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/installation/macos.md +0 -0
  295. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/installation/nixos.md +0 -0
  296. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/installation/windows.md +0 -0
  297. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/logo-avatar.svg +0 -0
  298. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/logo-clean.svg +0 -0
  299. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/overrides/partials/integrations/analytics/custom.html +0 -0
  300. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/run_markdown_code_runner.py +0 -0
  301. {agent_cli-0.96.1 → agent_cli-0.96.3}/docs/system-integration.md +0 -0
  302. {agent_cli-0.96.1 → agent_cli-0.96.3}/example.agent-cli-config.toml +0 -0
  303. {agent_cli-0.96.1 → agent_cli-0.96.3}/justfile +0 -0
  304. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Package.resolved +0 -0
  305. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Package.swift +0 -0
  306. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/README.md +0 -0
  307. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Resources/AgentCLI.entitlements +0 -0
  308. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Resources/Info.plist +0 -0
  309. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Resources/dmg-background.svg +0 -0
  310. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/AgentCLIApp.swift +0 -0
  311. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/AgentRuntime.swift +0 -0
  312. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/AppDelegate.swift +0 -0
  313. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/AppMetadata.swift +0 -0
  314. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/AppUpdater.swift +0 -0
  315. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/CommandResult.swift +0 -0
  316. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/ConfigurableHotkeyController.swift +0 -0
  317. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/FocusedTextTarget.swift +0 -0
  318. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/LoginItemController.swift +0 -0
  319. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/MenuBarIcon.swift +0 -0
  320. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/RecentTranscriptionReader.swift +0 -0
  321. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/RecordingIndicatorController.swift +0 -0
  322. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/RecordingSoundSettings.swift +0 -0
  323. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/RuntimeSettings.swift +0 -0
  324. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/SettingsWindowController.swift +0 -0
  325. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/Shortcuts.swift +0 -0
  326. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/TranscriptPasteController.swift +0 -0
  327. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Sources/AgentCLI/TranscriptionSettings.swift +0 -0
  328. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Tests/AgentCLITests/LoginItemControllerTests.swift +0 -0
  329. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Tests/AgentCLITests/RecentTranscriptionReaderTests.swift +0 -0
  330. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Tests/AgentCLITests/RecordingIndicatorControllerTests.swift +0 -0
  331. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/AgentCLI/Tests/AgentCLITests/ShortcutDefaultsTests.swift +0 -0
  332. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/build-macos-app.sh +0 -0
  333. {agent_cli-0.96.1 → agent_cli-0.96.3}/macos/test-macos-app-e2e.sh +0 -0
  334. {agent_cli-0.96.1 → agent_cli-0.96.3}/pyproject.toml +0 -0
  335. {agent_cli-0.96.1 → agent_cli-0.96.3}/reddit.md +0 -0
  336. {agent_cli-0.96.1 → agent_cli-0.96.3}/shell.nix +0 -0
  337. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/__init__.py +0 -0
  338. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/__init__.py +0 -0
  339. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_fix_my_text.py +0 -0
  340. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_interactive.py +0 -0
  341. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_interactive_extra.py +0 -0
  342. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_memory_add.py +0 -0
  343. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_speak.py +0 -0
  344. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_speak_e2e.py +0 -0
  345. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_speakers.py +0 -0
  346. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_transcribe.py +0 -0
  347. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_transcribe_agent.py +0 -0
  348. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_transcribe_e2e.py +0 -0
  349. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_transcribe_live.py +0 -0
  350. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_transcribe_recovery.py +0 -0
  351. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_tts_common.py +0 -0
  352. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_tts_common_extra.py +0 -0
  353. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_voice_agent_common.py +0 -0
  354. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_voice_edit.py +0 -0
  355. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_voice_edit_e2e.py +0 -0
  356. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/agents/test_wake_word_assistant.py +0 -0
  357. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/conftest.py +0 -0
  358. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/core/__init__.py +0 -0
  359. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/core/test_audio.py +0 -0
  360. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/core/test_audio_format.py +0 -0
  361. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/core/test_chroma.py +0 -0
  362. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/core/test_sse.py +0 -0
  363. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/core/test_vad.py +0 -0
  364. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/core/test_watch.py +0 -0
  365. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/dev/__init__.py +0 -0
  366. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/dev/test_cleanup.py +0 -0
  367. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/dev/test_cli.py +0 -0
  368. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/dev/test_coding_agents.py +0 -0
  369. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/dev/test_editors.py +0 -0
  370. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/dev/test_hooks.py +0 -0
  371. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/dev/test_launch.py +0 -0
  372. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/dev/test_project.py +0 -0
  373. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/dev/test_terminals.py +0 -0
  374. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/dev/test_verification.py +0 -0
  375. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/dev/test_worktree.py +0 -0
  376. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/install/__init__.py +0 -0
  377. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/install/test_extras.py +0 -0
  378. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/install/test_launchd.py +0 -0
  379. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/memory/__init__.py +0 -0
  380. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/memory/test_api_health.py +0 -0
  381. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/memory/test_api_integration_liveish.py +0 -0
  382. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/memory/test_client.py +0 -0
  383. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/memory/test_engine.py +0 -0
  384. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/memory/test_files.py +0 -0
  385. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/memory/test_filters.py +0 -0
  386. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/memory/test_git_integration.py +0 -0
  387. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/memory/test_indexer.py +0 -0
  388. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/memory/test_memory_integration.py +0 -0
  389. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/memory/test_proxy_passthrough.py +0 -0
  390. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/memory/test_store.py +0 -0
  391. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/memory/test_utils.py +0 -0
  392. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/mocks/__init__.py +0 -0
  393. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/mocks/audio.py +0 -0
  394. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/mocks/llm.py +0 -0
  395. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/mocks/wyoming.py +0 -0
  396. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/rag/__init__.py +0 -0
  397. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/rag/test_api.py +0 -0
  398. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/rag/test_engine.py +0 -0
  399. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/rag/test_history.py +0 -0
  400. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/rag/test_indexer.py +0 -0
  401. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/rag/test_indexing.py +0 -0
  402. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/rag/test_rag_client.py +0 -0
  403. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/rag/test_rag_integration_liveish.py +0 -0
  404. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/rag/test_rag_proxy_passthrough.py +0 -0
  405. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/rag/test_retriever.py +0 -0
  406. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/rag/test_store.py +0 -0
  407. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/rag/test_utils.py +0 -0
  408. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_alignment.py +0 -0
  409. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_api.py +0 -0
  410. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_api_integration.py +0 -0
  411. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_asr.py +0 -0
  412. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_asr_recovery.py +0 -0
  413. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_audio_e2e.py +0 -0
  414. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_cli.py +0 -0
  415. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_config.py +0 -0
  416. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_config_cmd.py +0 -0
  417. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_daemon.py +0 -0
  418. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_diarization.py +0 -0
  419. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_diarize_live_session.py +0 -0
  420. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_docs_gen.py +0 -0
  421. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_env_vars.py +0 -0
  422. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_faster_whisper_backend.py +0 -0
  423. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_json_output.py +0 -0
  424. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_llm.py +0 -0
  425. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_llm_gemini.py +0 -0
  426. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_memory_tools.py +0 -0
  427. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_mlx_backend.py +0 -0
  428. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_normalize_appcast.py +0 -0
  429. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_process_manager.py +0 -0
  430. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_requires_extras.py +0 -0
  431. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_server_streaming.py +0 -0
  432. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_server_tts.py +0 -0
  433. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_server_whisper.py +0 -0
  434. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_services.py +0 -0
  435. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_speaker_identity.py +0 -0
  436. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_tools.py +0 -0
  437. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_transformers_backend.py +0 -0
  438. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_tts.py +0 -0
  439. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_update_cask.py +0 -0
  440. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_utils.py +0 -0
  441. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_wake_word.py +0 -0
  442. {agent_cli-0.96.1 → agent_cli-0.96.3}/tests/test_wyoming_utils.py +0 -0
  443. {agent_cli-0.96.1 → agent_cli-0.96.3}/uv.lock +0 -0
  444. {agent_cli-0.96.1 → agent_cli-0.96.3}/zensical.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  cask "agent-cli" do
2
- version "0.96.0"
3
- sha256 "69f2afd8934c1b8b547983a0ac272d274b28b136938e0ea7432ab236f28a7856"
2
+ version "0.96.2"
3
+ sha256 "7a059c89ab2476d90a4cabcb547c51179901329aa899cc7411d580d14c143727"
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.96.1
3
+ Version: 0.96.3
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>
@@ -55,6 +55,10 @@ struct AgentCommand {
55
55
  return arguments + ["--extra-instructions", trimmedInstructions]
56
56
  }
57
57
 
58
+ var menuActivityTitle: String {
59
+ title
60
+ }
61
+
58
62
  static let toggleTranscription = AgentCommand(
59
63
  identifier: "transcribe",
60
64
  title: "Toggle Transcription",
@@ -18,6 +18,11 @@ private enum HoldTranscriptionState {
18
18
  }
19
19
  }
20
20
 
21
+ private struct ActiveCommandActivity {
22
+ let title: String
23
+ let startedAt: Date
24
+ }
25
+
21
26
  @MainActor
22
27
  final class AgentCommandRunner: ObservableObject {
23
28
  static let shared = AgentCommandRunner()
@@ -32,6 +37,10 @@ final class AgentCommandRunner: ObservableObject {
32
37
  private let pasteController: TranscriptPasteController
33
38
  private let bootstrap: AgentBootstrap
34
39
  private var bootstrapPhaseStartedAt: Date?
40
+ private var recordingStartedAt: Date?
41
+ private var transcribingStartedAt: Date?
42
+ private var activeCommandActivities: [String: ActiveCommandActivity] = [:]
43
+ private var activeCommandActivityOrder: [String] = []
35
44
  private var pendingStopRecordingCommands: Set<String> = []
36
45
  private var holdTranscriptionState: HoldTranscriptionState = .idle
37
46
  private var holdToTranscribePasteTarget: FocusedTextTarget?
@@ -43,22 +52,34 @@ final class AgentCommandRunner: ObservableObject {
43
52
  }
44
53
 
45
54
  var menuStatusMessage: String {
46
- if isRecording {
47
- return "Recording"
48
- }
55
+ menuActivityStatus.message
56
+ }
57
+
58
+ var menuActivityStatus: MenuActivityStatus {
59
+ menuActivityStatus(now: Date())
60
+ }
61
+
62
+ func menuActivityStatus(now: Date) -> MenuActivityStatus {
49
63
  if bootstrapPhase.isPreparing {
50
- return bootstrapPhase.statusMessage(
51
- animationTick: bootstrapAnimationTick(now: Date()),
52
- elapsedSeconds: bootstrapElapsedSeconds(now: Date())
64
+ return MenuActivityStatus.active(
65
+ title: bootstrapPhase.activityTitle,
66
+ startedAt: bootstrapPhaseStartedAt ?? now,
67
+ now: now
53
68
  )
54
69
  }
55
- if holdTranscriptionState.isFinishing {
56
- return "Transcribing..."
70
+ if let transcribingStartedAt {
71
+ return MenuActivityStatus.active(title: "Transcribing", startedAt: transcribingStartedAt, now: now)
72
+ }
73
+ if isRecording {
74
+ return MenuActivityStatus.active(title: "Recording", startedAt: recordingStartedAt ?? now, now: now)
75
+ }
76
+ if let activity = currentCommandActivity {
77
+ return MenuActivityStatus.active(title: activity.title, startedAt: activity.startedAt, now: now)
57
78
  }
58
79
  if hasLastError && statusMessage.localizedCaseInsensitiveContains("failed") {
59
- return "Last command failed"
80
+ return MenuActivityStatus.inactive(message: "Last command failed")
60
81
  }
61
- return Self.compactMenuStatus(statusMessage)
82
+ return MenuActivityStatus.completed(title: Self.compactMenuStatus(statusMessage))
62
83
  }
63
84
 
64
85
  var menuBarIconState: MenuBarIconState {
@@ -140,15 +161,6 @@ final class AgentCommandRunner: ObservableObject {
140
161
  }
141
162
  }
142
163
 
143
- private func bootstrapAnimationTick(now: Date) -> Int {
144
- bootstrapElapsedSeconds(now: now) % 4
145
- }
146
-
147
- private func bootstrapElapsedSeconds(now: Date) -> Int {
148
- guard let startedAt = bootstrapPhaseStartedAt else { return 0 }
149
- return max(0, Int(now.timeIntervalSince(startedAt)))
150
- }
151
-
152
164
  @discardableResult
153
165
  func beginHoldToTranscribe() -> Bool {
154
166
  guard holdTranscriptionState == .idle else {
@@ -174,6 +186,7 @@ final class AgentCommandRunner: ObservableObject {
174
186
  holdTranscriptionState = .stopping
175
187
 
176
188
  let wasRecording = recordingIndicator.isRecordingCommand(.toggleTranscription)
189
+ beginTranscribingActivity()
177
190
  if wasRecording {
178
191
  endRecordingIndicator(for: .toggleTranscription)
179
192
  statusMessage = "Transcribing..."
@@ -206,9 +219,11 @@ final class AgentCommandRunner: ObservableObject {
206
219
 
207
220
  if isStopRequest {
208
221
  markStopRequested(for: command)
222
+ beginTranscribingActivity()
209
223
  }
210
224
 
211
225
  activeCommandCount += 1
226
+ beginCommandActivity(for: command)
212
227
  if !self.bootstrapPhase.isPreparing {
213
228
  statusMessage = isStopRequest
214
229
  ? "Stopping \(command.title)..."
@@ -233,6 +248,8 @@ final class AgentCommandRunner: ObservableObject {
233
248
  self.clearPasteAfterRecording(for: command)
234
249
  }
235
250
  self.clearHoldTranscriptionState(for: command)
251
+ self.clearTranscribingActivityIfFinished()
252
+ self.finishCommandActivity(for: command)
236
253
  self.activeCommandCount = max(0, self.activeCommandCount - 1)
237
254
  self.lastOutput = bootstrapResult.output
238
255
  self.recordFailure(command: command, result: bootstrapResult)
@@ -272,7 +289,9 @@ final class AgentCommandRunner: ObservableObject {
272
289
  }
273
290
  }
274
291
  self.clearPasteAfterRecording(for: command)
292
+ self.clearTranscribingActivityIfFinished()
275
293
  }
294
+ self.finishCommandActivity(for: command)
276
295
  self.activeCommandCount = max(0, self.activeCommandCount - 1)
277
296
 
278
297
  if isStopRequest && result.exitCode == 0 {
@@ -285,6 +304,7 @@ final class AgentCommandRunner: ObservableObject {
285
304
 
286
305
  if isStopRequest {
287
306
  self.clearStopRequested(for: command)
307
+ self.clearTranscribingActivityIfFinished()
288
308
  }
289
309
  self.lastOutput = result.output
290
310
  if result.exitCode != 0 {
@@ -319,6 +339,7 @@ final class AgentCommandRunner: ObservableObject {
319
339
  Task { @MainActor in
320
340
  self.reportBootstrapPhase(.failed)
321
341
  self.holdTranscriptionState = .idle
342
+ self.clearTranscribingActivityIfFinished()
322
343
  self.lastOutput = bootstrapResult.output
323
344
  self.recordFailure(command: AgentCommand.stopTranscription, result: bootstrapResult)
324
345
  self.statusMessage = message
@@ -345,6 +366,7 @@ final class AgentCommandRunner: ObservableObject {
345
366
  }
346
367
 
347
368
  self.holdTranscriptionState = .idle
369
+ self.clearTranscribingActivityIfFinished()
348
370
  let message = result.output.isEmpty
349
371
  ? "Toggle Transcription stop failed with exit code \(result.exitCode)"
350
372
  : "Toggle Transcription stop failed: \(result.output)"
@@ -368,6 +390,37 @@ final class AgentCommandRunner: ObservableObject {
368
390
  pendingStopRecordingCommands.remove(command.identifier)
369
391
  }
370
392
 
393
+ private var currentCommandActivity: ActiveCommandActivity? {
394
+ activeCommandActivityOrder.reversed().compactMap { activeCommandActivities[$0] }.first
395
+ }
396
+
397
+ private func beginCommandActivity(for command: AgentCommand) {
398
+ if activeCommandActivities[command.identifier] == nil {
399
+ activeCommandActivityOrder.append(command.identifier)
400
+ }
401
+ activeCommandActivities[command.identifier] = ActiveCommandActivity(
402
+ title: command.menuActivityTitle,
403
+ startedAt: Date()
404
+ )
405
+ }
406
+
407
+ private func finishCommandActivity(for command: AgentCommand) {
408
+ activeCommandActivities.removeValue(forKey: command.identifier)
409
+ activeCommandActivityOrder.removeAll { $0 == command.identifier }
410
+ }
411
+
412
+ private func beginTranscribingActivity() {
413
+ if transcribingStartedAt == nil {
414
+ transcribingStartedAt = Date()
415
+ }
416
+ }
417
+
418
+ private func clearTranscribingActivityIfFinished() {
419
+ if pendingStopRecordingCommands.isEmpty && !holdTranscriptionState.isFinishing {
420
+ transcribingStartedAt = nil
421
+ }
422
+ }
423
+
371
424
  private func shouldPasteAfterRecording(for command: AgentCommand) -> Bool {
372
425
  pasteAfterRecordingCommands.contains(command.identifier)
373
426
  }
@@ -390,14 +443,21 @@ final class AgentCommandRunner: ObservableObject {
390
443
  return false
391
444
  }
392
445
 
446
+ let wasRecording = isRecording
393
447
  recordingIndicator.begin(for: command)
394
448
  isRecording = recordingIndicator.isRecording
449
+ if !wasRecording && isRecording {
450
+ recordingStartedAt = Date()
451
+ }
395
452
  return true
396
453
  }
397
454
 
398
455
  private func endRecordingIndicator(for command: AgentCommand) {
399
456
  recordingIndicator.end(for: command)
400
457
  isRecording = recordingIndicator.isRecording
458
+ if !isRecording {
459
+ recordingStartedAt = nil
460
+ }
401
461
  }
402
462
 
403
463
  func copyLastOutput() {
@@ -46,18 +46,17 @@ enum BootstrapPhase: Equatable {
46
46
  func statusMessage(animationTick: Int, elapsedSeconds: Int) -> String {
47
47
  switch self {
48
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))"
49
+ return MenuActivityStatus.active(
50
+ title: activityTitle,
51
+ animationTick: animationTick,
52
+ elapsedSeconds: elapsedSeconds
53
+ ).message
55
54
  case .idle, .failed:
56
55
  return statusMessage
57
56
  }
58
57
  }
59
58
 
60
- private var animatedStatusMessage: String {
59
+ var activityTitle: String {
61
60
  switch self {
62
61
  case .checkingRuntime:
63
62
  return "Checking CLI runtime"
@@ -0,0 +1,29 @@
1
+ import Foundation
2
+
3
+ struct MenuActivityStatus: Equatable {
4
+ let message: String
5
+ let isActive: Bool
6
+
7
+ static func active(title: String, startedAt: Date, now: Date) -> MenuActivityStatus {
8
+ let elapsedSeconds = max(0, Int(now.timeIntervalSince(startedAt)))
9
+ return active(title: title, animationTick: elapsedSeconds % spinnerFrames.count, elapsedSeconds: elapsedSeconds)
10
+ }
11
+
12
+ static func active(title: String, animationTick: Int, elapsedSeconds: Int) -> MenuActivityStatus {
13
+ let spinner = spinnerFrames[animationTick % spinnerFrames.count]
14
+ let minutes = elapsedSeconds / 60
15
+ let seconds = elapsedSeconds % 60
16
+ let elapsedTime = String(format: "%02d:%02d", minutes, seconds)
17
+ return MenuActivityStatus(message: "\(title) \(spinner) (\(elapsedTime))", isActive: true)
18
+ }
19
+
20
+ static func completed(title: String) -> MenuActivityStatus {
21
+ MenuActivityStatus(message: "\(title) ✓", isActive: false)
22
+ }
23
+
24
+ static func inactive(message: String) -> MenuActivityStatus {
25
+ MenuActivityStatus(message: message, isActive: false)
26
+ }
27
+
28
+ private static let spinnerFrames = ["◐", "◓", "◑", "◒"]
29
+ }
@@ -8,6 +8,7 @@ final class StatusMenuController: NSObject, NSMenuDelegate {
8
8
  private static let statusRefreshInterval: TimeInterval = 0.8
9
9
  private static let statusRefreshRunLoopModes: [RunLoop.Mode] = [.common, .eventTracking]
10
10
  private static let voiceStatusTitlePrefix = "Voice: "
11
+ private static let activityStatusTitlePrefix = "Status: "
11
12
 
12
13
  private let runner = AgentCommandRunner.shared
13
14
  private let appUpdater = AppUpdater.shared
@@ -19,6 +20,10 @@ final class StatusMenuController: NSObject, NSMenuDelegate {
19
20
  private let recentRecordingsMenu = NSMenu()
20
21
  private let troubleshootingMenu = NSMenu()
21
22
  private var voiceStatusItem: NSMenuItem?
23
+ private var recentActivityStatusItem: NSMenuItem?
24
+ private var recentActivityStatusSeparator: NSMenuItem?
25
+ private var troubleshootingActivityStatusItem: NSMenuItem?
26
+ private var troubleshootingActivityStatusSeparator: NSMenuItem?
22
27
  private var statusRefreshTimer: Timer?
23
28
 
24
29
  private override init() {
@@ -108,9 +113,17 @@ final class StatusMenuController: NSObject, NSMenuDelegate {
108
113
 
109
114
  private func rebuildRecentRecordingsMenu() {
110
115
  recentRecordingsMenu.removeAllItems()
116
+ let activityItem = disabledItem("")
117
+ let activitySeparator = NSMenuItem.separator()
118
+ recentRecordingsMenu.addItem(activityItem)
119
+ recentRecordingsMenu.addItem(activitySeparator)
120
+ recentActivityStatusItem = activityItem
121
+ recentActivityStatusSeparator = activitySeparator
122
+
111
123
  let recentTranscriptions = RecentTranscriptionReader.recentTranscriptions()
112
124
  if recentTranscriptions.isEmpty {
113
125
  recentRecordingsMenu.addItem(disabledItem("No recent transcriptions"))
126
+ refreshDynamicStatus()
114
127
  return
115
128
  }
116
129
 
@@ -123,10 +136,18 @@ final class StatusMenuController: NSObject, NSMenuDelegate {
123
136
  item.representedObject = transcription.text
124
137
  recentRecordingsMenu.addItem(item)
125
138
  }
139
+ refreshDynamicStatus()
126
140
  }
127
141
 
128
142
  private func rebuildTroubleshootingMenu() {
129
143
  troubleshootingMenu.removeAllItems()
144
+ let activityItem = disabledItem("")
145
+ let activitySeparator = NSMenuItem.separator()
146
+ troubleshootingMenu.addItem(activityItem)
147
+ troubleshootingMenu.addItem(activitySeparator)
148
+ troubleshootingActivityStatusItem = activityItem
149
+ troubleshootingActivityStatusSeparator = activitySeparator
150
+
130
151
  troubleshootingMenu.addItem(actionItem(
131
152
  "Voice Service Status",
132
153
  symbolName: "waveform.path.ecg",
@@ -191,6 +212,7 @@ final class StatusMenuController: NSObject, NSMenuDelegate {
191
212
  symbolName: "arrow.counterclockwise",
192
213
  action: #selector(resetKeyboardShortcuts)
193
214
  ))
215
+ refreshDynamicStatus()
194
216
  }
195
217
 
196
218
  private func startStatusRefreshTimer() {
@@ -207,7 +229,9 @@ final class StatusMenuController: NSObject, NSMenuDelegate {
207
229
  }
208
230
 
209
231
  private func refreshDynamicStatus() {
210
- voiceStatusItem?.title = "\(Self.voiceStatusTitlePrefix)\(runner.menuStatusMessage)"
232
+ let activityStatus = runner.menuActivityStatus
233
+ voiceStatusItem?.title = "\(Self.voiceStatusTitlePrefix)\(activityStatus.message)"
234
+ updateSubmenuActivityStatus(activityStatus)
211
235
  if let button = statusItem?.button {
212
236
  button.image = MenuBarIconImage.logoImage(state: runner.menuBarIconState)
213
237
  button.imagePosition = .imageOnly
@@ -215,6 +239,29 @@ final class StatusMenuController: NSObject, NSMenuDelegate {
215
239
  }
216
240
  }
217
241
 
242
+ private func updateSubmenuActivityStatus(_ activityStatus: MenuActivityStatus) {
243
+ updateSubmenuActivityStatus(
244
+ item: recentActivityStatusItem,
245
+ separator: recentActivityStatusSeparator,
246
+ activityStatus: activityStatus
247
+ )
248
+ updateSubmenuActivityStatus(
249
+ item: troubleshootingActivityStatusItem,
250
+ separator: troubleshootingActivityStatusSeparator,
251
+ activityStatus: activityStatus
252
+ )
253
+ }
254
+
255
+ private func updateSubmenuActivityStatus(
256
+ item: NSMenuItem?,
257
+ separator: NSMenuItem?,
258
+ activityStatus: MenuActivityStatus
259
+ ) {
260
+ item?.title = "\(Self.activityStatusTitlePrefix)\(activityStatus.message)"
261
+ item?.isHidden = !activityStatus.isActive
262
+ separator?.isHidden = !activityStatus.isActive
263
+ }
264
+
218
265
  private var usesUserInstalledAgentCLI: Bool {
219
266
  UserDefaults.standard.bool(forKey: RuntimeSettings.useUserInstalledAgentCLIKey)
220
267
  }
@@ -94,9 +94,10 @@ final class VoiceLevelMeter: NSObject, ObservableObject {
94
94
  private static let barCount = 16
95
95
  private static let idleAmplitudes = Array(repeating: CGFloat(0.16), count: barCount)
96
96
  private static let minimumDisplayAmplitude = CGFloat(0.12)
97
+ private static let minimumInputDecibels: Float = -55
97
98
  private var engine: AVAudioEngine?
98
- private var analyzer: VoiceSpectrumAnalyzer?
99
- private var smoothedAmplitudes = VoiceLevelMeter.idleAmplitudes
99
+ private var phase = 0.0
100
+ private var smoothedLevel = CGFloat(0.16)
100
101
 
101
102
  private override init() {}
102
103
 
@@ -125,13 +126,14 @@ final class VoiceLevelMeter: NSObject, ObservableObject {
125
126
  engine?.inputNode.removeTap(onBus: 0)
126
127
  engine?.stop()
127
128
  engine = nil
128
- analyzer = nil
129
- smoothedAmplitudes = Self.idleAmplitudes
129
+ phase = 0
130
+ smoothedLevel = 0.16
130
131
  amplitudes = Self.idleAmplitudes
131
132
  }
132
133
 
133
134
  private func startMetering() {
134
- smoothedAmplitudes = Self.idleAmplitudes
135
+ phase = 0
136
+ smoothedLevel = 0.16
135
137
  let engine = AVAudioEngine()
136
138
  let input = engine.inputNode
137
139
  let format = input.outputFormat(forBus: 0)
@@ -139,17 +141,12 @@ final class VoiceLevelMeter: NSObject, ObservableObject {
139
141
  amplitudes = Self.idleAmplitudes
140
142
  return
141
143
  }
142
- let analyzer = VoiceSpectrumAnalyzer(
143
- sampleRate: format.sampleRate,
144
- bandCount: Self.barCount
145
- )
146
144
 
147
145
  do {
148
146
  input.installTap(onBus: 0, bufferSize: 1_024, format: format) { [weak self] buffer, _ in
149
147
  self?.process(buffer: buffer)
150
148
  }
151
149
  try engine.start()
152
- self.analyzer = analyzer
153
150
  self.engine = engine
154
151
  } catch {
155
152
  input.removeTap(onBus: 0)
@@ -158,21 +155,47 @@ final class VoiceLevelMeter: NSObject, ObservableObject {
158
155
  }
159
156
 
160
157
  private func process(buffer: AVAudioPCMBuffer) {
161
- guard let analyzer, let samples = Self.samples(from: buffer) else { return }
162
- let rawAmplitudes = analyzer.amplitudes(from: samples)
158
+ guard let samples = Self.samples(from: buffer) else { return }
159
+ let level = Self.normalizedLevel(from: samples)
163
160
 
164
161
  DispatchQueue.main.async { [weak self] in
165
162
  guard let self, self.engine != nil else { return }
166
- self.amplitudes = self.smoothedDisplayAmplitudes(from: rawAmplitudes)
163
+ self.updateDisplay(level: level)
167
164
  }
168
165
  }
169
166
 
170
- private func smoothedDisplayAmplitudes(from rawAmplitudes: [CGFloat]) -> [CGFloat] {
171
- smoothedAmplitudes = zip(smoothedAmplitudes, rawAmplitudes).map { previous, current in
172
- let smoothed = (previous * 0.62) + (current * 0.38)
173
- return max(Self.minimumDisplayAmplitude, min(1, smoothed))
167
+ private func updateDisplay(level: CGFloat) {
168
+ phase += 0.22
169
+ smoothedLevel = (smoothedLevel * 0.55) + (level * 0.45)
170
+ let displayLevel = smoothedLevel
171
+
172
+ amplitudes = Self.displayAmplitudes(level: displayLevel, phase: phase)
173
+ }
174
+
175
+ static func displayAmplitudes(level: CGFloat, phase: Double) -> [CGFloat] {
176
+ (0..<Self.barCount).map { index in
177
+ let wave = 0.74 + 0.26 * sin(phase + Double(index) * 0.74)
178
+ return max(Self.minimumDisplayAmplitude, min(1, level * CGFloat(wave)))
174
179
  }
175
- return smoothedAmplitudes
180
+ }
181
+
182
+ static func normalizedLevel(from samples: [Float]) -> CGFloat {
183
+ guard !samples.isEmpty else { return 0.08 }
184
+
185
+ let meanSquare = samples.reduce(0.0) { partialResult, sample in
186
+ let value = Double(sample)
187
+ return partialResult + (value * value)
188
+ } / Double(samples.count)
189
+ guard meanSquare > 0 else { return 0.08 }
190
+
191
+ let rootMeanSquare = sqrt(meanSquare)
192
+ let decibels = Float(20 * log10(rootMeanSquare))
193
+ return normalizedPower(decibels, minimumPower: minimumInputDecibels)
194
+ }
195
+
196
+ private static func normalizedPower(_ power: Float, minimumPower: Float) -> CGFloat {
197
+ guard power > minimumPower else { return 0.08 }
198
+ return CGFloat((power - minimumPower) / abs(minimumPower))
176
199
  }
177
200
 
178
201
  private static func samples(from buffer: AVAudioPCMBuffer) -> [Float]? {
@@ -280,6 +280,36 @@ final class AgentCommandTests: XCTestCase {
280
280
  )
281
281
  }
282
282
 
283
+ func testMenuActivityStatusFormatsActiveWorkWithSpinnerAndElapsedCounter() {
284
+ let startedAt = Date(timeIntervalSinceReferenceDate: 1_000)
285
+ let now = Date(timeIntervalSinceReferenceDate: 1_125)
286
+
287
+ XCTAssertEqual(
288
+ MenuActivityStatus.active(title: "Recording", startedAt: startedAt, now: now).message,
289
+ "Recording ◓ (02:05)"
290
+ )
291
+ XCTAssertTrue(MenuActivityStatus.active(title: "Recording", startedAt: startedAt, now: now).isActive)
292
+ }
293
+
294
+ func testMenuActivityStatusFormatsCompletedWorkWithCheckmark() {
295
+ XCTAssertEqual(MenuActivityStatus.completed(title: "Ready").message, "Ready ✓")
296
+ XCTAssertEqual(MenuActivityStatus.completed(title: "Text inserted").message, "Text inserted ✓")
297
+ XCTAssertFalse(MenuActivityStatus.completed(title: "Ready").isActive)
298
+ }
299
+
300
+ @MainActor
301
+ func testIdleMenuStatusUsesCompletedCheckmark() {
302
+ let runner = AgentCommandRunner { _, _, _ in
303
+ CommandResult(exitCode: 0, output: "")
304
+ }
305
+
306
+ XCTAssertEqual(runner.menuStatusMessage, "Ready ✓")
307
+
308
+ runner.statusMessage = "Text inserted"
309
+
310
+ XCTAssertEqual(runner.menuStatusMessage, "Text inserted ✓")
311
+ }
312
+
283
313
  @MainActor
284
314
  func testMenuStatusComputesElapsedPreparationTimeWhenRead() {
285
315
  let bootstrapStarted = expectation(description: "bootstrap started")
@@ -0,0 +1,39 @@
1
+ #if canImport(XCTest)
2
+ import Foundation
3
+ import XCTest
4
+ @testable import AgentCLI
5
+
6
+ final class VoiceLevelMeterTests: XCTestCase {
7
+ func testQuietInputProducesVisibleLevel() {
8
+ let quietTone = Self.sineWave(amplitude: Float(pow(10.0, -35.0 / 20.0)))
9
+
10
+ let level = VoiceLevelMeter.normalizedLevel(from: quietTone)
11
+
12
+ XCTAssertGreaterThan(level, 0.2)
13
+ }
14
+
15
+ func testSilenceUsesIdleLevel() {
16
+ let level = VoiceLevelMeter.normalizedLevel(from: Array(repeating: Float(0), count: 1_024))
17
+
18
+ XCTAssertEqual(level, CGFloat(0.08))
19
+ }
20
+
21
+ func testDisplayAmplitudesUseSineWaveShape() {
22
+ let amplitudes = VoiceLevelMeter.displayAmplitudes(level: 0.6, phase: 0.22)
23
+
24
+ XCTAssertEqual(amplitudes.count, 16)
25
+ XCTAssertGreaterThan((amplitudes.max() ?? 0) - (amplitudes.min() ?? 0), 0.1)
26
+ }
27
+
28
+ private static func sineWave(
29
+ frequency: Double = 220,
30
+ sampleRate: Double = 16_000,
31
+ sampleCount: Int = 2_048,
32
+ amplitude: Float = 1
33
+ ) -> [Float] {
34
+ (0..<sampleCount).map { index in
35
+ amplitude * Float(sin(2 * Double.pi * frequency * Double(index) / sampleRate))
36
+ }
37
+ }
38
+ }
39
+ #endif
@@ -4,6 +4,39 @@
4
4
  <title>Agent CLI Updates</title>
5
5
  <link>https://github.com/basnijholt/agent-cli</link>
6
6
  <description>Signed Agent CLI macOS app updates.</description>
7
+ <item>
8
+ <title>0.96.2</title>
9
+ <pubDate>Fri, 29 May 2026 05:56:37 +0000</pubDate>
10
+ <link>https://github.com/basnijholt/agent-cli</link>
11
+ <sparkle:version>176</sparkle:version>
12
+ <sparkle:shortVersionString>0.96.2</sparkle:shortVersionString>
13
+ <sparkle:minimumSystemVersion>13.0</sparkle:minimumSystemVersion>
14
+ <sparkle:hardwareRequirements>arm64</sparkle:hardwareRequirements>
15
+ <description sparkle:format="markdown"><![CDATA[## What’s Changed
16
+
17
+ * Fix macOS voice spectrum overlay sensitivity (#548) @basnijholt
18
+
19
+ ]]></description>
20
+ <enclosure url="https://github.com/basnijholt/agent-cli/releases/download/v0.96.2/AgentCLI.zip" length="22731154" type="application/octet-stream" sparkle:edSignature="MmlMlLHAK31VEqi0/9apTebWyh31p1jp1U76dw5KU5E9LCl2lqkWnIF2JTPpiTxoS4egpxom7D1FNAKZWQ2EAw=="/>
21
+ </item>
22
+ <item>
23
+ <title>0.96.1</title>
24
+ <pubDate>Fri, 29 May 2026 05:47:47 +0000</pubDate>
25
+ <link>https://github.com/basnijholt/agent-cli</link>
26
+ <sparkle:version>175</sparkle:version>
27
+ <sparkle:shortVersionString>0.96.1</sparkle:shortVersionString>
28
+ <sparkle:minimumSystemVersion>13.0</sparkle:minimumSystemVersion>
29
+ <sparkle:hardwareRequirements>arm64</sparkle:hardwareRequirements>
30
+ <description sparkle:format="markdown"><![CDATA[## What’s Changed
31
+
32
+ * Clean up macOS menu lifecycle wiring (#545) @basnijholt
33
+ * Remove uv Python 3.13 install workarounds (#521) @basnijholt
34
+ * Remove brittle macOS source-shape tests (#547) @basnijholt
35
+ * Fix macOS voice meter source assertions (#546) @basnijholt
36
+
37
+ ]]></description>
38
+ <enclosure url="https://github.com/basnijholt/agent-cli/releases/download/v0.96.1/AgentCLI.zip" length="22729845" type="application/octet-stream" sparkle:edSignature="YYq/64CSi+pxZD2NZ02GWIPAdusUf3mesEQ4MltVUOSheuOwimOZpHs81brT4g8rFBa2PRfnobfrfcTtfONqCQ=="/>
39
+ </item>
7
40
  <item>
8
41
  <title>0.96.0</title>
9
42
  <pubDate>Fri, 29 May 2026 05:30:42 +0000</pubDate>
@@ -50,6 +50,7 @@ def test_macos_app_package_files_exist() -> None:
50
50
  "ConfigurableHotkeyController.swift",
51
51
  "FocusedTextTarget.swift",
52
52
  "MenuBarIcon.swift",
53
+ "MenuActivityStatus.swift",
53
54
  "RecordingIndicatorController.swift",
54
55
  "SettingsWindowController.swift",
55
56
  "Shortcuts.swift",