agent-cli 0.61.5__tar.gz → 0.62.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. {agent_cli-0.61.5 → agent_cli-0.62.0}/.pre-commit-config.yaml +1 -1
  2. {agent_cli-0.61.5 → agent_cli-0.62.0}/PKG-INFO +3 -3
  3. {agent_cli-0.61.5 → agent_cli-0.62.0}/README.md +2 -2
  4. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/agents/assistant.py +1 -1
  5. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/agents/autocorrect.py +1 -1
  6. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/agents/chat.py +1 -1
  7. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/agents/memory/__init__.py +1 -1
  8. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/agents/rag_proxy.py +1 -1
  9. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/agents/speak.py +1 -1
  10. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/agents/transcribe.py +1 -1
  11. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/agents/transcribe_daemon.py +1 -1
  12. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/agents/voice_edit.py +1 -1
  13. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/cli.py +1 -1
  14. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/worktree.py +53 -5
  15. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/cli.py +1 -1
  16. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/dev.md +10 -0
  17. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/configuration.md +1 -1
  18. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/getting-started.md +1 -1
  19. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/index.md +1 -1
  20. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/dev/test_worktree.py +213 -0
  21. {agent_cli-0.61.5 → agent_cli-0.62.0}/.claude/skills/agent-cli-dev/SKILL.md +0 -0
  22. {agent_cli-0.61.5 → agent_cli-0.62.0}/.claude/skills/agent-cli-dev/examples.md +0 -0
  23. {agent_cli-0.61.5 → agent_cli-0.62.0}/.cursorrules +0 -0
  24. {agent_cli-0.61.5 → agent_cli-0.62.0}/.env.example +0 -0
  25. {agent_cli-0.61.5 → agent_cli-0.62.0}/.github/logo.svg +0 -0
  26. {agent_cli-0.61.5 → agent_cli-0.62.0}/.github/release-drafter.yml +0 -0
  27. {agent_cli-0.61.5 → agent_cli-0.62.0}/.github/renovate.json +0 -0
  28. {agent_cli-0.61.5 → agent_cli-0.62.0}/.github/workflows/automerge.yml +0 -0
  29. {agent_cli-0.61.5 → agent_cli-0.62.0}/.github/workflows/docker-tts.yml +0 -0
  30. {agent_cli-0.61.5 → agent_cli-0.62.0}/.github/workflows/docker-whisper.yml +0 -0
  31. {agent_cli-0.61.5 → agent_cli-0.62.0}/.github/workflows/docs.yml +0 -0
  32. {agent_cli-0.61.5 → agent_cli-0.62.0}/.github/workflows/markdown-code-runner.yml +0 -0
  33. {agent_cli-0.61.5 → agent_cli-0.62.0}/.github/workflows/pytest.yml +0 -0
  34. {agent_cli-0.61.5 → agent_cli-0.62.0}/.github/workflows/release-drafter.yml +0 -0
  35. {agent_cli-0.61.5 → agent_cli-0.62.0}/.github/workflows/release.yml +0 -0
  36. {agent_cli-0.61.5 → agent_cli-0.62.0}/.github/workflows/toc.yaml +0 -0
  37. {agent_cli-0.61.5 → agent_cli-0.62.0}/.gitignore +0 -0
  38. {agent_cli-0.61.5 → agent_cli-0.62.0}/.jscpd.json +0 -0
  39. {agent_cli-0.61.5 → agent_cli-0.62.0}/.prompts/docs-review.md +0 -0
  40. {agent_cli-0.61.5 → agent_cli-0.62.0}/.prompts/pr-review.md +0 -0
  41. {agent_cli-0.61.5 → agent_cli-0.62.0}/CLAUDE.md +0 -0
  42. {agent_cli-0.61.5 → agent_cli-0.62.0}/LICENSE +0 -0
  43. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/__init__.py +0 -0
  44. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/__main__.py +0 -0
  45. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/_tools.py +0 -0
  46. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/agents/__init__.py +0 -0
  47. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/agents/_voice_agent_common.py +0 -0
  48. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/agents/memory/add.py +0 -0
  49. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/agents/memory/proxy.py +0 -0
  50. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/api.py +0 -0
  51. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/cli.py +0 -0
  52. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/config.py +0 -0
  53. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/config_cmd.py +0 -0
  54. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/constants.py +0 -0
  55. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/core/__init__.py +0 -0
  56. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/core/audio.py +0 -0
  57. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/core/audio_format.py +0 -0
  58. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/core/chroma.py +0 -0
  59. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/core/deps.py +0 -0
  60. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/core/openai_proxy.py +0 -0
  61. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/core/process.py +0 -0
  62. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/core/reranker.py +0 -0
  63. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/core/sse.py +0 -0
  64. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/core/transcription_logger.py +0 -0
  65. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/core/utils.py +0 -0
  66. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/core/vad.py +0 -0
  67. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/core/watch.py +0 -0
  68. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/__init__.py +0 -0
  69. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/coding_agents/__init__.py +0 -0
  70. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/coding_agents/aider.py +0 -0
  71. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/coding_agents/base.py +0 -0
  72. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/coding_agents/claude.py +0 -0
  73. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/coding_agents/codex.py +0 -0
  74. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/coding_agents/continue_dev.py +0 -0
  75. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/coding_agents/copilot.py +0 -0
  76. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/coding_agents/cursor_agent.py +0 -0
  77. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/coding_agents/gemini.py +0 -0
  78. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/coding_agents/opencode.py +0 -0
  79. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/coding_agents/registry.py +0 -0
  80. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/editors/__init__.py +0 -0
  81. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/editors/base.py +0 -0
  82. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/editors/cursor.py +0 -0
  83. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/editors/emacs.py +0 -0
  84. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/editors/jetbrains.py +0 -0
  85. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/editors/nano.py +0 -0
  86. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/editors/neovim.py +0 -0
  87. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/editors/registry.py +0 -0
  88. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/editors/sublime.py +0 -0
  89. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/editors/vim.py +0 -0
  90. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/editors/vscode.py +0 -0
  91. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/editors/zed.py +0 -0
  92. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/project.py +0 -0
  93. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/registry.py +0 -0
  94. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/skill/SKILL.md +0 -0
  95. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/skill/examples.md +0 -0
  96. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/terminals/__init__.py +0 -0
  97. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/terminals/apple_terminal.py +0 -0
  98. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/terminals/base.py +0 -0
  99. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/terminals/gnome.py +0 -0
  100. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/terminals/iterm2.py +0 -0
  101. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/terminals/kitty.py +0 -0
  102. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/terminals/registry.py +0 -0
  103. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/terminals/tmux.py +0 -0
  104. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/terminals/warp.py +0 -0
  105. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/dev/terminals/zellij.py +0 -0
  106. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/docs_gen.py +0 -0
  107. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/example-config.toml +0 -0
  108. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/install/__init__.py +0 -0
  109. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/install/common.py +0 -0
  110. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/install/hotkeys.py +0 -0
  111. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/install/services.py +0 -0
  112. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/__init__.py +0 -0
  113. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/_files.py +0 -0
  114. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/_filters.py +0 -0
  115. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/_git.py +0 -0
  116. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/_indexer.py +0 -0
  117. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/_ingest.py +0 -0
  118. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/_persistence.py +0 -0
  119. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/_prompt.py +0 -0
  120. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/_retrieval.py +0 -0
  121. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/_store.py +0 -0
  122. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/_streaming.py +0 -0
  123. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/_tasks.py +0 -0
  124. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/api.py +0 -0
  125. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/client.py +0 -0
  126. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/engine.py +0 -0
  127. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/entities.py +0 -0
  128. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/memory/models.py +0 -0
  129. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/opts.py +0 -0
  130. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/py.typed +0 -0
  131. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/rag/__init__.py +0 -0
  132. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/rag/_indexer.py +0 -0
  133. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/rag/_indexing.py +0 -0
  134. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/rag/_prompt.py +0 -0
  135. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/rag/_retriever.py +0 -0
  136. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/rag/_store.py +0 -0
  137. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/rag/_utils.py +0 -0
  138. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/rag/api.py +0 -0
  139. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/rag/client.py +0 -0
  140. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/rag/engine.py +0 -0
  141. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/rag/models.py +0 -0
  142. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/.runtime/.gitkeep +0 -0
  143. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/__init__.py +0 -0
  144. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/linux-hotkeys/README.md +0 -0
  145. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/linux-hotkeys/toggle-autocorrect.sh +0 -0
  146. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/linux-hotkeys/toggle-transcription.sh +0 -0
  147. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/linux-hotkeys/toggle-voice-edit.sh +0 -0
  148. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/macos-hotkeys/README.md +0 -0
  149. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/macos-hotkeys/skhd-config-example +0 -0
  150. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/macos-hotkeys/toggle-autocorrect.sh +0 -0
  151. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/macos-hotkeys/toggle-transcription.sh +0 -0
  152. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/macos-hotkeys/toggle-voice-edit.sh +0 -0
  153. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/nvidia-asr-server/README.md +0 -0
  154. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/nvidia-asr-server/pyproject.toml +0 -0
  155. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/nvidia-asr-server/server.py +0 -0
  156. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/nvidia-asr-server/shell.nix +0 -0
  157. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/nvidia-asr-server/uv.lock +0 -0
  158. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/run-openwakeword.sh +0 -0
  159. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/run-piper-windows.ps1 +0 -0
  160. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/run-piper.sh +0 -0
  161. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/run-whisper-linux.sh +0 -0
  162. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/run-whisper-macos.sh +0 -0
  163. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/run-whisper-windows.ps1 +0 -0
  164. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/run-whisper.sh +0 -0
  165. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/run_faster_whisper_server.py +0 -0
  166. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/setup-linux-hotkeys.sh +0 -0
  167. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/setup-linux.sh +0 -0
  168. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/setup-macos-hotkeys.sh +0 -0
  169. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/setup-macos.sh +0 -0
  170. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/setup-windows.ps1 +0 -0
  171. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/start-all-services-windows.ps1 +0 -0
  172. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/scripts/start-all-services.sh +0 -0
  173. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/__init__.py +0 -0
  174. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/common.py +0 -0
  175. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/model_manager.py +0 -0
  176. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/model_registry.py +0 -0
  177. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/proxy/__init__.py +0 -0
  178. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/proxy/api.py +0 -0
  179. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/streaming.py +0 -0
  180. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/tts/__init__.py +0 -0
  181. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/tts/api.py +0 -0
  182. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/tts/backends/__init__.py +0 -0
  183. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/tts/backends/base.py +0 -0
  184. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/tts/backends/kokoro.py +0 -0
  185. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/tts/backends/piper.py +0 -0
  186. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/tts/model_manager.py +0 -0
  187. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/tts/model_registry.py +0 -0
  188. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/tts/wyoming_handler.py +0 -0
  189. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/whisper/__init__.py +0 -0
  190. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/whisper/api.py +0 -0
  191. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/whisper/backends/__init__.py +0 -0
  192. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/whisper/backends/base.py +0 -0
  193. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/whisper/backends/faster_whisper.py +0 -0
  194. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/whisper/backends/mlx.py +0 -0
  195. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/whisper/languages.py +0 -0
  196. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/whisper/model_manager.py +0 -0
  197. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/whisper/model_registry.py +0 -0
  198. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/server/whisper/wyoming_handler.py +0 -0
  199. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/services/__init__.py +0 -0
  200. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/services/_wyoming_utils.py +0 -0
  201. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/services/asr.py +0 -0
  202. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/services/llm.py +0 -0
  203. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/services/tts.py +0 -0
  204. {agent_cli-0.61.5 → agent_cli-0.62.0}/agent_cli/services/wake_word.py +0 -0
  205. {agent_cli-0.61.5 → agent_cli-0.62.0}/docker/docker-compose.yml +0 -0
  206. {agent_cli-0.61.5 → agent_cli-0.62.0}/docker/tts.Dockerfile +0 -0
  207. {agent_cli-0.61.5 → agent_cli-0.62.0}/docker/whisper.Dockerfile +0 -0
  208. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/CNAME +0 -0
  209. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/architecture/index.md +0 -0
  210. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/architecture/memory.md +0 -0
  211. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/architecture/rag.md +0 -0
  212. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/assistant.md +0 -0
  213. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/autocorrect.md +0 -0
  214. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/chat.md +0 -0
  215. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/config.md +0 -0
  216. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/index.md +0 -0
  217. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/install-hotkeys.md +0 -0
  218. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/install-services.md +0 -0
  219. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/memory.md +0 -0
  220. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/rag-proxy.md +0 -0
  221. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/server/index.md +0 -0
  222. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/server/transcription-proxy.md +0 -0
  223. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/server/tts.md +0 -0
  224. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/server/whisper.md +0 -0
  225. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/speak.md +0 -0
  226. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/start-services.md +0 -0
  227. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/transcribe-daemon.md +0 -0
  228. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/transcribe.md +0 -0
  229. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/commands/voice-edit.md +0 -0
  230. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/iOS_Shortcut_Guide.md +0 -0
  231. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/installation/docker.md +0 -0
  232. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/installation/index.md +0 -0
  233. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/installation/linux.md +0 -0
  234. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/installation/macos.md +0 -0
  235. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/installation/nixos.md +0 -0
  236. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/installation/windows.md +0 -0
  237. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/logo-clean.svg +0 -0
  238. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/overrides/partials/integrations/analytics/custom.html +0 -0
  239. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/run_markdown_code_runner.py +0 -0
  240. {agent_cli-0.61.5 → agent_cli-0.62.0}/docs/system-integration.md +0 -0
  241. {agent_cli-0.61.5 → agent_cli-0.62.0}/example.agent-cli-config.toml +0 -0
  242. {agent_cli-0.61.5 → agent_cli-0.62.0}/justfile +0 -0
  243. {agent_cli-0.61.5 → agent_cli-0.62.0}/pyproject.toml +0 -0
  244. {agent_cli-0.61.5 → agent_cli-0.62.0}/shell.nix +0 -0
  245. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/__init__.py +0 -0
  246. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/__init__.py +0 -0
  247. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_fix_my_text.py +0 -0
  248. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_interactive.py +0 -0
  249. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_interactive_extra.py +0 -0
  250. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_memory_add.py +0 -0
  251. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_speak.py +0 -0
  252. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_speak_e2e.py +0 -0
  253. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_transcribe.py +0 -0
  254. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_transcribe_agent.py +0 -0
  255. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_transcribe_daemon.py +0 -0
  256. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_transcribe_e2e.py +0 -0
  257. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_transcribe_recovery.py +0 -0
  258. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_tts_common.py +0 -0
  259. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_tts_common_extra.py +0 -0
  260. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_voice_agent_common.py +0 -0
  261. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_voice_edit.py +0 -0
  262. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_voice_edit_e2e.py +0 -0
  263. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/agents/test_wake_word_assistant.py +0 -0
  264. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/conftest.py +0 -0
  265. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/core/__init__.py +0 -0
  266. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/core/test_audio_format.py +0 -0
  267. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/core/test_chroma.py +0 -0
  268. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/core/test_sse.py +0 -0
  269. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/core/test_vad.py +0 -0
  270. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/core/test_watch.py +0 -0
  271. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/dev/__init__.py +0 -0
  272. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/dev/test_cli.py +0 -0
  273. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/dev/test_coding_agents.py +0 -0
  274. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/dev/test_editors.py +0 -0
  275. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/dev/test_project.py +0 -0
  276. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/dev/test_terminals.py +0 -0
  277. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/dev/test_verification.py +0 -0
  278. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/memory/__init__.py +0 -0
  279. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/memory/test_api_health.py +0 -0
  280. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/memory/test_api_integration_liveish.py +0 -0
  281. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/memory/test_client.py +0 -0
  282. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/memory/test_engine.py +0 -0
  283. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/memory/test_files.py +0 -0
  284. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/memory/test_filters.py +0 -0
  285. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/memory/test_git_integration.py +0 -0
  286. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/memory/test_indexer.py +0 -0
  287. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/memory/test_memory_integration.py +0 -0
  288. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/memory/test_proxy_passthrough.py +0 -0
  289. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/memory/test_store.py +0 -0
  290. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/memory/test_utils.py +0 -0
  291. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/mocks/__init__.py +0 -0
  292. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/mocks/audio.py +0 -0
  293. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/mocks/llm.py +0 -0
  294. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/mocks/wyoming.py +0 -0
  295. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/rag/__init__.py +0 -0
  296. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/rag/test_api.py +0 -0
  297. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/rag/test_engine.py +0 -0
  298. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/rag/test_history.py +0 -0
  299. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/rag/test_indexer.py +0 -0
  300. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/rag/test_indexing.py +0 -0
  301. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/rag/test_rag_client.py +0 -0
  302. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/rag/test_rag_integration_liveish.py +0 -0
  303. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/rag/test_rag_proxy_passthrough.py +0 -0
  304. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/rag/test_retriever.py +0 -0
  305. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/rag/test_store.py +0 -0
  306. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/rag/test_utils.py +0 -0
  307. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_api.py +0 -0
  308. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_api_integration.py +0 -0
  309. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_asr.py +0 -0
  310. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_asr_recovery.py +0 -0
  311. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_audio_e2e.py +0 -0
  312. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_cli.py +0 -0
  313. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_config.py +0 -0
  314. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_config_cmd.py +0 -0
  315. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_docs_gen.py +0 -0
  316. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_env_vars.py +0 -0
  317. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_json_output.py +0 -0
  318. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_llm.py +0 -0
  319. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_llm_gemini.py +0 -0
  320. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_memory_tools.py +0 -0
  321. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_mlx_backend.py +0 -0
  322. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_process_manager.py +0 -0
  323. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_server_streaming.py +0 -0
  324. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_server_tts.py +0 -0
  325. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_server_whisper.py +0 -0
  326. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_services.py +0 -0
  327. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_tools.py +0 -0
  328. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_tts.py +0 -0
  329. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_utils.py +0 -0
  330. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_wake_word.py +0 -0
  331. {agent_cli-0.61.5 → agent_cli-0.62.0}/tests/test_wyoming_utils.py +0 -0
  332. {agent_cli-0.61.5 → agent_cli-0.62.0}/uv.lock +0 -0
  333. {agent_cli-0.61.5 → agent_cli-0.62.0}/zensical.toml +0 -0
@@ -8,7 +8,7 @@ repos:
8
8
  - id: end-of-file-fixer
9
9
  - id: mixed-line-ending
10
10
  - repo: https://github.com/astral-sh/ruff-pre-commit
11
- rev: "v0.14.11"
11
+ rev: "v0.14.13"
12
12
  hooks:
13
13
  - id: ruff
14
14
  args: ["--fix"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-cli
3
- Version: 0.61.5
3
+ Version: 0.62.0
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>
@@ -128,7 +128,7 @@ Since then I have expanded the tool with many more features, all focused on loca
128
128
  - **[`memory`](docs/commands/memory.md)**: Long-term memory system with `memory proxy` and `memory add`.
129
129
  - **[`rag-proxy`](docs/commands/rag-proxy.md)**: RAG proxy server for chatting with your documents.
130
130
  - **[`dev`](docs/commands/dev.md)**: Parallel development with git worktrees and AI coding agents.
131
- - **[`server`](docs/commands/server.md)**: Local ASR and TTS servers with dual-protocol (Wyoming & OpenAI), TTL-based memory management, and multi-platform acceleration. Whisper uses MLX on Apple Silicon or Faster Whisper on Linux/CUDA. TTS supports Kokoro (GPU) or Piper (CPU).
131
+ - **[`server`](docs/commands/server/index.md)**: Local ASR and TTS servers with dual-protocol (Wyoming & OpenAI), TTL-based memory management, and multi-platform acceleration. Whisper uses MLX on Apple Silicon or Faster Whisper on Linux/CUDA. TTS supports Kokoro (GPU) or Piper (CPU).
132
132
  - **[`transcribe-daemon`](docs/commands/transcribe-daemon.md)**: Continuous background transcription with VAD. Install with `uv tool install "agent-cli[vad]"`.
133
133
 
134
134
  ## Quick Start
@@ -389,7 +389,7 @@ Our installation scripts automatically handle all dependencies:
389
389
  |---------|---------|-----------------|
390
390
  | **[Ollama](https://ollama.ai/)** | Local LLM for text processing | ✅ Yes, with default model |
391
391
  | **[Wyoming Faster Whisper](https://github.com/rhasspy/wyoming-faster-whisper)** | Speech-to-text | ✅ Yes, via `uvx` |
392
- | **[`agent-cli server whisper`](docs/commands/server.md#whisper)** | Speech-to-text (alternative) | ✅ Built-in, `pip install "agent-cli[whisper]"` |
392
+ | **[`agent-cli server whisper`](docs/commands/server/whisper.md)** | Speech-to-text (alternative) | ✅ Built-in, `pip install "agent-cli[whisper]"` |
393
393
  | **[Wyoming Piper](https://github.com/rhasspy/wyoming-piper)** | Text-to-speech | ✅ Yes, via `uvx` |
394
394
  | **[Kokoro-FastAPI](https://github.com/remsky/Kokoro-FastAPI)** | Premium TTS (optional) | ⚙️ Can be added later |
395
395
  | **[Wyoming openWakeWord](https://github.com/rhasspy/wyoming-openwakeword)** | Wake word detection | ✅ Yes, for `assistant` |
@@ -48,7 +48,7 @@ Since then I have expanded the tool with many more features, all focused on loca
48
48
  - **[`memory`](docs/commands/memory.md)**: Long-term memory system with `memory proxy` and `memory add`.
49
49
  - **[`rag-proxy`](docs/commands/rag-proxy.md)**: RAG proxy server for chatting with your documents.
50
50
  - **[`dev`](docs/commands/dev.md)**: Parallel development with git worktrees and AI coding agents.
51
- - **[`server`](docs/commands/server.md)**: Local ASR and TTS servers with dual-protocol (Wyoming & OpenAI), TTL-based memory management, and multi-platform acceleration. Whisper uses MLX on Apple Silicon or Faster Whisper on Linux/CUDA. TTS supports Kokoro (GPU) or Piper (CPU).
51
+ - **[`server`](docs/commands/server/index.md)**: Local ASR and TTS servers with dual-protocol (Wyoming & OpenAI), TTL-based memory management, and multi-platform acceleration. Whisper uses MLX on Apple Silicon or Faster Whisper on Linux/CUDA. TTS supports Kokoro (GPU) or Piper (CPU).
52
52
  - **[`transcribe-daemon`](docs/commands/transcribe-daemon.md)**: Continuous background transcription with VAD. Install with `uv tool install "agent-cli[vad]"`.
53
53
 
54
54
  ## Quick Start
@@ -309,7 +309,7 @@ Our installation scripts automatically handle all dependencies:
309
309
  |---------|---------|-----------------|
310
310
  | **[Ollama](https://ollama.ai/)** | Local LLM for text processing | ✅ Yes, with default model |
311
311
  | **[Wyoming Faster Whisper](https://github.com/rhasspy/wyoming-faster-whisper)** | Speech-to-text | ✅ Yes, via `uvx` |
312
- | **[`agent-cli server whisper`](docs/commands/server.md#whisper)** | Speech-to-text (alternative) | ✅ Built-in, `pip install "agent-cli[whisper]"` |
312
+ | **[`agent-cli server whisper`](docs/commands/server/whisper.md)** | Speech-to-text (alternative) | ✅ Built-in, `pip install "agent-cli[whisper]"` |
313
313
  | **[Wyoming Piper](https://github.com/rhasspy/wyoming-piper)** | Text-to-speech | ✅ Yes, via `uvx` |
314
314
  | **[Kokoro-FastAPI](https://github.com/remsky/Kokoro-FastAPI)** | Premium TTS (optional) | ⚙️ Can be added later |
315
315
  | **[Wyoming openWakeWord](https://github.com/rhasspy/wyoming-openwakeword)** | Wake word detection | ✅ Yes, for `assistant` |
@@ -253,7 +253,7 @@ async def _async_main(
253
253
  print_with_style("✨ Ready for next command...", style="green")
254
254
 
255
255
 
256
- @app.command("assistant")
256
+ @app.command("assistant", rich_help_panel="Voice Commands")
257
257
  def assistant(
258
258
  *,
259
259
  # --- Provider Selection ---
@@ -208,7 +208,7 @@ async def _async_autocorrect(
208
208
  sys.exit(1)
209
209
 
210
210
 
211
- @app.command("autocorrect")
211
+ @app.command("autocorrect", rich_help_panel="Text Commands")
212
212
  def autocorrect(
213
213
  *,
214
214
  text: str | None = typer.Argument(
@@ -373,7 +373,7 @@ async def _async_main(
373
373
  raise
374
374
 
375
375
 
376
- @app.command("chat")
376
+ @app.command("chat", rich_help_panel="Voice Commands")
377
377
  def chat(
378
378
  *,
379
379
  # --- Provider Selection ---
@@ -14,7 +14,7 @@ memory_app = typer.Typer(
14
14
  no_args_is_help=True,
15
15
  )
16
16
 
17
- app.add_typer(memory_app, name="memory")
17
+ app.add_typer(memory_app, name="memory", rich_help_panel="Servers")
18
18
 
19
19
 
20
20
  @memory_app.callback()
@@ -17,7 +17,7 @@ from agent_cli.core.utils import (
17
17
  )
18
18
 
19
19
 
20
- @app.command("rag-proxy")
20
+ @app.command("rag-proxy", rich_help_panel="Servers")
21
21
  def rag_proxy(
22
22
  docs_folder: Path = typer.Option( # noqa: B008
23
23
  "./rag_docs",
@@ -79,7 +79,7 @@ async def _async_main(
79
79
  return text
80
80
 
81
81
 
82
- @app.command("speak")
82
+ @app.command("speak", rich_help_panel="Text Commands")
83
83
  def speak(
84
84
  *,
85
85
  text: str | None = typer.Argument(
@@ -460,7 +460,7 @@ async def _async_main( # noqa: PLR0912, PLR0915, C901
460
460
  )
461
461
 
462
462
 
463
- @app.command("transcribe")
463
+ @app.command("transcribe", rich_help_panel="Voice Commands")
464
464
  def transcribe( # noqa: PLR0912
465
465
  *,
466
466
  extra_instructions: str | None = typer.Option(
@@ -286,7 +286,7 @@ async def _daemon_loop(cfg: DaemonConfig) -> None: # noqa: PLR0912, PLR0915
286
286
  await asyncio.wait(background_tasks, timeout=2.0)
287
287
 
288
288
 
289
- @app.command("transcribe-daemon")
289
+ @app.command("transcribe-daemon", rich_help_panel="Voice Commands")
290
290
  def transcribe_daemon( # noqa: PLR0912
291
291
  *,
292
292
  # Daemon-specific options
@@ -172,7 +172,7 @@ async def _async_main(
172
172
  )
173
173
 
174
174
 
175
- @app.command("voice-edit")
175
+ @app.command("voice-edit", rich_help_panel="Voice Commands")
176
176
  def voice_edit(
177
177
  *,
178
178
  # --- Provider Selection ---
@@ -122,7 +122,7 @@ app = typer.Typer(
122
122
  rich_markup_mode="markdown",
123
123
  no_args_is_help=True,
124
124
  )
125
- main_app.add_typer(app, name="dev")
125
+ main_app.add_typer(app, name="dev", rich_help_panel="Development")
126
126
 
127
127
 
128
128
  @app.callback()
@@ -55,6 +55,15 @@ def is_git_repo(path: Path | None = None) -> bool:
55
55
  return False
56
56
 
57
57
 
58
+ def has_origin_remote(path: Path | None = None) -> bool:
59
+ """Check if the repository has an 'origin' remote configured."""
60
+ try:
61
+ result = _run_git("remote", "get-url", "origin", cwd=path, check=False)
62
+ return result.returncode == 0
63
+ except Exception:
64
+ return False
65
+
66
+
58
67
  def get_repo_root(path: Path | None = None) -> Path | None:
59
68
  """Get the root directory of the git repository."""
60
69
  try:
@@ -461,6 +470,35 @@ def _init_submodules(
461
470
  )
462
471
 
463
472
 
473
+ def _pull_lfs(
474
+ worktree_path: Path,
475
+ *,
476
+ on_log: Callable[[str], None] | None = None,
477
+ capture_output: bool = True,
478
+ ) -> None:
479
+ """Pull Git LFS files in a worktree if LFS is used.
480
+
481
+ Evidence: https://git-lfs.com/ - `git lfs pull` fetches LFS objects.
482
+ This is a no-op if LFS is not used or files are already present.
483
+ """
484
+ # Check if .gitattributes contains LFS filters
485
+ gitattributes = worktree_path / ".gitattributes"
486
+ if not gitattributes.exists():
487
+ return
488
+
489
+ if "filter=lfs" not in gitattributes.read_text():
490
+ return
491
+
492
+ # Check if git-lfs is installed
493
+ if not shutil.which("git-lfs"):
494
+ return
495
+
496
+ if on_log:
497
+ on_log("Pulling Git LFS files...")
498
+
499
+ _run_git("lfs", "pull", cwd=worktree_path, check=False, capture_output=capture_output)
500
+
501
+
464
502
  def _add_worktree(
465
503
  branch_name: str,
466
504
  worktree_path: Path,
@@ -586,8 +624,11 @@ def create_worktree(
586
624
  # Create base directory if needed
587
625
  base_dir.mkdir(parents=True, exist_ok=True)
588
626
 
589
- # Fetch latest refs
590
- if fetch:
627
+ # Check if origin remote exists
628
+ origin_exists = has_origin_remote(repo_root)
629
+
630
+ # Fetch latest refs (only if origin exists)
631
+ if fetch and origin_exists:
591
632
  if on_log:
592
633
  on_log("Running: git fetch origin")
593
634
  _run_git("fetch", "origin", cwd=repo_root, check=False, capture_output=capture_output)
@@ -596,10 +637,10 @@ def create_worktree(
596
637
  from_ref_explicit = from_ref is not None
597
638
 
598
639
  # Determine the reference to create from
599
- # Use origin/{branch} to ensure we're using the freshly-fetched remote ref,
600
- # not a potentially stale local branch
640
+ # Use origin/{branch} if origin exists, otherwise use local branch
601
641
  if from_ref is None:
602
- from_ref = f"origin/{get_default_branch(repo_root)}"
642
+ default_branch = get_default_branch(repo_root)
643
+ from_ref = f"origin/{default_branch}" if origin_exists else default_branch
603
644
 
604
645
  # Check if branch exists remotely or locally
605
646
  remote_exists, local_exists = _check_branch_exists(branch_name, repo_root)
@@ -634,6 +675,13 @@ def create_worktree(
634
675
  capture_output=capture_output,
635
676
  )
636
677
 
678
+ # Pull Git LFS files if the repo uses LFS
679
+ _pull_lfs(
680
+ worktree_path,
681
+ on_log=on_log,
682
+ capture_output=capture_output,
683
+ )
684
+
637
685
  return CreateWorktreeResult(
638
686
  success=True,
639
687
  path=worktree_path,
@@ -34,7 +34,7 @@ app = typer.Typer(
34
34
  rich_markup_mode="markdown",
35
35
  no_args_is_help=True,
36
36
  )
37
- main_app.add_typer(app, name="server")
37
+ main_app.add_typer(app, name="server", rich_help_panel="Servers")
38
38
 
39
39
 
40
40
  @app.callback()
@@ -495,6 +495,16 @@ git submodule update --init --recursive
495
495
 
496
496
  This ensures all submodule dependencies are available in the worktree.
497
497
 
498
+ ### Git LFS
499
+
500
+ If the repository uses Git LFS (detected via `filter=lfs` in `.gitattributes`), LFS files are automatically pulled:
501
+
502
+ ```bash
503
+ git lfs pull
504
+ ```
505
+
506
+ This ensures large files tracked by LFS are available in the worktree.
507
+
498
508
  ### Environment Files
499
509
 
500
510
  The following files are automatically copied to new dev environments:
@@ -235,7 +235,7 @@ Now just run `agent-cli transcribe` - it automatically uses your local server.
235
235
 
236
236
  > [!TIP]
237
237
  > **OpenAI SDK users:** The server also exposes an OpenAI-compatible API on port 10301.
238
- > See [server whisper docs](commands/server.md#whisper) for all options.
238
+ > See [server whisper docs](commands/server/whisper.md) for all options.
239
239
 
240
240
  ## Audio Device Configuration
241
241
 
@@ -43,7 +43,7 @@ For a complete local setup with all AI services:
43
43
  > pip install "agent-cli[whisper-mlx]"
44
44
  > agent-cli server whisper --backend mlx
45
45
  > ```
46
- > See [Local Whisper Server](commands/server.md#whisper) for details.
46
+ > See [Local Whisper Server](commands/server/whisper.md) for details.
47
47
 
48
48
  === "Using CLI Commands"
49
49
 
@@ -64,7 +64,7 @@ Since then I have expanded the tool with many more features, all focused on loca
64
64
  | [`rag-proxy`](commands/rag-proxy.md) | Chat with your documents via RAG |
65
65
  | [`memory`](commands/memory.md) | Long-term memory system for conversations |
66
66
  | [`dev`](commands/dev.md) | Parallel development with git worktrees and AI coding agents |
67
- | [`server`](commands/server.md) | Local ASR & TTS servers with dual-protocol (Wyoming & OpenAI), TTL-based memory, and multi-platform acceleration (MLX/CUDA) |
67
+ | [`server`](commands/server/index.md) | Local ASR & TTS servers with dual-protocol (Wyoming & OpenAI), TTL-based memory, and multi-platform acceleration (MLX/CUDA) |
68
68
 
69
69
  ## Quick Start
70
70
 
@@ -11,9 +11,11 @@ from agent_cli.dev.worktree import (
11
11
  CreateWorktreeResult,
12
12
  WorktreeInfo,
13
13
  _parse_git_config_regexp,
14
+ _pull_lfs,
14
15
  create_worktree,
15
16
  find_worktree_by_name,
16
17
  get_main_repo_root,
18
+ has_origin_remote,
17
19
  list_worktrees,
18
20
  resolve_worktree_base_dir,
19
21
  sanitize_branch_name,
@@ -444,6 +446,7 @@ class TestCreateWorktreeFromRefWarning:
444
446
  patch("agent_cli.dev.worktree._check_branch_exists", return_value=(False, True)),
445
447
  patch("agent_cli.dev.worktree._add_worktree"),
446
448
  patch("agent_cli.dev.worktree._init_submodules"),
449
+ patch("agent_cli.dev.worktree._pull_lfs"),
447
450
  patch("pathlib.Path.exists", return_value=False),
448
451
  patch("pathlib.Path.mkdir"),
449
452
  ):
@@ -475,6 +478,7 @@ class TestCreateWorktreeFromRefWarning:
475
478
  patch("agent_cli.dev.worktree._check_branch_exists", return_value=(True, False)),
476
479
  patch("agent_cli.dev.worktree._add_worktree"),
477
480
  patch("agent_cli.dev.worktree._init_submodules"),
481
+ patch("agent_cli.dev.worktree._pull_lfs"),
478
482
  patch("pathlib.Path.exists", return_value=False),
479
483
  patch("pathlib.Path.mkdir"),
480
484
  ):
@@ -533,6 +537,7 @@ class TestCreateWorktreeFromRefWarning:
533
537
  patch("agent_cli.dev.worktree._check_branch_exists", return_value=(False, False)),
534
538
  patch("agent_cli.dev.worktree._add_worktree"),
535
539
  patch("agent_cli.dev.worktree._init_submodules"),
540
+ patch("agent_cli.dev.worktree._pull_lfs"),
536
541
  patch("pathlib.Path.exists", return_value=False),
537
542
  patch("pathlib.Path.mkdir"),
538
543
  ):
@@ -548,3 +553,211 @@ class TestCreateWorktreeFromRefWarning:
548
553
 
549
554
  assert result.success is True
550
555
  assert result.warning is None # No warning since branch is new
556
+
557
+
558
+ class TestPullLfs:
559
+ """Tests for _pull_lfs function.
560
+
561
+ Evidence: https://git-lfs.com/ - Git LFS stores large files outside the repo
562
+ and replaces them with pointers. `git lfs pull` fetches the actual content.
563
+ """
564
+
565
+ def test_no_gitattributes(self, tmp_path: Path) -> None:
566
+ """Skip LFS pull when .gitattributes doesn't exist."""
567
+ # No .gitattributes file
568
+ logged: list[str] = []
569
+ _pull_lfs(tmp_path, on_log=logged.append)
570
+ assert logged == [] # No log means no action taken
571
+
572
+ def test_no_lfs_filter_in_gitattributes(self, tmp_path: Path) -> None:
573
+ """Skip LFS pull when .gitattributes doesn't contain filter=lfs."""
574
+ (tmp_path / ".gitattributes").write_text("*.txt text\n")
575
+ logged: list[str] = []
576
+ _pull_lfs(tmp_path, on_log=logged.append)
577
+ assert logged == [] # No log means no action taken
578
+
579
+ def test_lfs_pull_when_filter_present(self, tmp_path: Path) -> None:
580
+ """Run git lfs pull when filter=lfs is in .gitattributes."""
581
+ (tmp_path / ".gitattributes").write_text("*.bin filter=lfs diff=lfs merge=lfs -text\n")
582
+
583
+ with (
584
+ patch("agent_cli.dev.worktree.shutil.which", return_value="/usr/bin/git-lfs"),
585
+ patch("agent_cli.dev.worktree._run_git") as mock_run,
586
+ ):
587
+ mock_run.return_value.returncode = 0
588
+ logged: list[str] = []
589
+ _pull_lfs(tmp_path, on_log=logged.append)
590
+
591
+ assert "Pulling Git LFS files..." in logged
592
+ mock_run.assert_called_once()
593
+ call_args = mock_run.call_args
594
+ assert call_args[0] == ("lfs", "pull")
595
+
596
+ def test_skip_when_git_lfs_not_installed(self, tmp_path: Path) -> None:
597
+ """Skip LFS pull when git-lfs is not installed."""
598
+ (tmp_path / ".gitattributes").write_text("*.bin filter=lfs diff=lfs merge=lfs -text\n")
599
+
600
+ with patch("agent_cli.dev.worktree.shutil.which", return_value=None):
601
+ logged: list[str] = []
602
+ _pull_lfs(tmp_path, on_log=logged.append)
603
+ assert logged == [] # No log means no action taken
604
+
605
+
606
+ class TestHasOriginRemote:
607
+ """Tests for has_origin_remote function.
608
+
609
+ Validates detection of origin remote presence using `git remote get-url origin`.
610
+ """
611
+
612
+ def test_origin_exists(self) -> None:
613
+ """Return True when origin remote is configured."""
614
+ mock_run = MagicMock()
615
+ mock_run.return_value.returncode = 0
616
+ mock_run.return_value.stdout = "https://github.com/user/repo.git"
617
+
618
+ with patch("agent_cli.dev.worktree._run_git", mock_run):
619
+ assert has_origin_remote(Path("/repo")) is True
620
+
621
+ mock_run.assert_called_once_with(
622
+ "remote",
623
+ "get-url",
624
+ "origin",
625
+ cwd=Path("/repo"),
626
+ check=False,
627
+ )
628
+
629
+ def test_origin_not_exists(self) -> None:
630
+ """Return False when origin remote is not configured."""
631
+ mock_run = MagicMock()
632
+ mock_run.return_value.returncode = 2 # git returns non-zero when remote doesn't exist
633
+ mock_run.return_value.stdout = ""
634
+
635
+ with patch("agent_cli.dev.worktree._run_git", mock_run):
636
+ assert has_origin_remote(Path("/repo")) is False
637
+
638
+ def test_git_command_fails(self) -> None:
639
+ """Return False when git command raises exception."""
640
+ with patch(
641
+ "agent_cli.dev.worktree._run_git",
642
+ side_effect=Exception("git not found"),
643
+ ):
644
+ assert has_origin_remote(Path("/repo")) is False
645
+
646
+
647
+ class TestCreateWorktreeNoOrigin:
648
+ """Tests for create_worktree when repository has no origin remote.
649
+
650
+ Bug fix: When a repository has no origin remote configured,
651
+ `dev new` would fail with "fatal: invalid reference: origin/main"
652
+ because it tried to create the worktree from origin/{branch}.
653
+
654
+ The fix:
655
+ 1. Skip `git fetch origin` when no origin exists
656
+ 2. Use the local default branch instead of origin/{branch} as the base ref
657
+ """
658
+
659
+ def test_uses_local_branch_when_no_origin(self) -> None:
660
+ """Use local branch as from_ref when no origin remote exists."""
661
+ with (
662
+ patch("agent_cli.dev.worktree.get_main_repo_root", return_value=Path("/repo")),
663
+ patch(
664
+ "agent_cli.dev.worktree.resolve_worktree_base_dir",
665
+ return_value=Path("/worktrees"),
666
+ ),
667
+ patch("agent_cli.dev.worktree._run_git") as mock_run,
668
+ patch("agent_cli.dev.worktree._check_branch_exists", return_value=(False, False)),
669
+ patch("agent_cli.dev.worktree._add_worktree") as mock_add_worktree,
670
+ patch("agent_cli.dev.worktree._init_submodules"),
671
+ patch("agent_cli.dev.worktree.get_default_branch", return_value="main"),
672
+ patch("agent_cli.dev.worktree.has_origin_remote", return_value=False),
673
+ patch("pathlib.Path.exists", return_value=False),
674
+ patch("pathlib.Path.mkdir"),
675
+ ):
676
+ mock_run.return_value.returncode = 0
677
+ mock_run.return_value.stdout = ""
678
+
679
+ result = create_worktree(
680
+ "new-branch",
681
+ repo_path=Path("/repo"),
682
+ from_ref=None, # Auto-determine
683
+ fetch=True,
684
+ )
685
+
686
+ assert result.success is True
687
+ # Verify that _add_worktree was called with local "main" branch, not "origin/main"
688
+ mock_add_worktree.assert_called_once()
689
+ call_args = mock_add_worktree.call_args
690
+ from_ref_used = call_args[0][3] # 4th positional arg is from_ref
691
+ assert from_ref_used == "main", f"Expected 'main', got '{from_ref_used}'"
692
+ assert "origin" not in from_ref_used
693
+
694
+ def test_skips_fetch_when_no_origin(self) -> None:
695
+ """Skip git fetch when no origin remote exists."""
696
+ fetch_called: list[tuple[str, ...]] = []
697
+
698
+ def mock_run_git(*args: str, **_kwargs: object) -> MagicMock:
699
+ if args[0] == "fetch":
700
+ fetch_called.append(args)
701
+ result = MagicMock()
702
+ result.returncode = 0
703
+ result.stdout = ""
704
+ return result
705
+
706
+ with (
707
+ patch("agent_cli.dev.worktree.get_main_repo_root", return_value=Path("/repo")),
708
+ patch(
709
+ "agent_cli.dev.worktree.resolve_worktree_base_dir",
710
+ return_value=Path("/worktrees"),
711
+ ),
712
+ patch("agent_cli.dev.worktree._run_git", side_effect=mock_run_git),
713
+ patch("agent_cli.dev.worktree._check_branch_exists", return_value=(False, False)),
714
+ patch("agent_cli.dev.worktree._add_worktree"),
715
+ patch("agent_cli.dev.worktree._init_submodules"),
716
+ patch("agent_cli.dev.worktree.get_default_branch", return_value="main"),
717
+ patch("agent_cli.dev.worktree.has_origin_remote", return_value=False),
718
+ patch("pathlib.Path.exists", return_value=False),
719
+ patch("pathlib.Path.mkdir"),
720
+ ):
721
+ result = create_worktree(
722
+ "new-branch",
723
+ repo_path=Path("/repo"),
724
+ from_ref=None,
725
+ fetch=True, # Fetch is requested but should be skipped
726
+ )
727
+
728
+ assert result.success is True
729
+ assert len(fetch_called) == 0, "git fetch should not be called when no origin"
730
+
731
+ def test_uses_origin_when_available(self) -> None:
732
+ """Use origin/{branch} as from_ref when origin remote exists."""
733
+ with (
734
+ patch("agent_cli.dev.worktree.get_main_repo_root", return_value=Path("/repo")),
735
+ patch(
736
+ "agent_cli.dev.worktree.resolve_worktree_base_dir",
737
+ return_value=Path("/worktrees"),
738
+ ),
739
+ patch("agent_cli.dev.worktree._run_git") as mock_run,
740
+ patch("agent_cli.dev.worktree._check_branch_exists", return_value=(False, False)),
741
+ patch("agent_cli.dev.worktree._add_worktree") as mock_add_worktree,
742
+ patch("agent_cli.dev.worktree._init_submodules"),
743
+ patch("agent_cli.dev.worktree.get_default_branch", return_value="main"),
744
+ patch("agent_cli.dev.worktree.has_origin_remote", return_value=True),
745
+ patch("pathlib.Path.exists", return_value=False),
746
+ patch("pathlib.Path.mkdir"),
747
+ ):
748
+ mock_run.return_value.returncode = 0
749
+ mock_run.return_value.stdout = ""
750
+
751
+ result = create_worktree(
752
+ "new-branch",
753
+ repo_path=Path("/repo"),
754
+ from_ref=None, # Auto-determine
755
+ fetch=True,
756
+ )
757
+
758
+ assert result.success is True
759
+ # Verify that _add_worktree was called with "origin/main"
760
+ mock_add_worktree.assert_called_once()
761
+ call_args = mock_add_worktree.call_args
762
+ from_ref_used = call_args[0][3] # 4th positional arg is from_ref
763
+ assert from_ref_used == "origin/main", f"Expected 'origin/main', got '{from_ref_used}'"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes