agent-cli 0.84.0__tar.gz → 0.84.2__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 (374) hide show
  1. {agent_cli-0.84.0 → agent_cli-0.84.2}/PKG-INFO +1 -1
  2. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/cli.py +49 -14
  3. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/terminals/tmux.py +12 -16
  4. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/dev/test_cli.py +118 -4
  5. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/dev/test_terminals.py +66 -20
  6. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/memory/test_client.py +9 -0
  7. {agent_cli-0.84.0 → agent_cli-0.84.2}/.claude/skills/agent-cli-dev/SKILL.md +0 -0
  8. {agent_cli-0.84.0 → agent_cli-0.84.2}/.claude/skills/agent-cli-dev/examples.md +0 -0
  9. {agent_cli-0.84.0 → agent_cli-0.84.2}/.claude-plugin/README.md +0 -0
  10. {agent_cli-0.84.0 → agent_cli-0.84.2}/.claude-plugin/marketplace.json +0 -0
  11. {agent_cli-0.84.0 → agent_cli-0.84.2}/.claude-plugin/plugin.json +0 -0
  12. {agent_cli-0.84.0 → agent_cli-0.84.2}/.claude-plugin/skills/agent-cli-dev/SKILL.md +0 -0
  13. {agent_cli-0.84.0 → agent_cli-0.84.2}/.claude-plugin/skills/agent-cli-dev/examples.md +0 -0
  14. {agent_cli-0.84.0 → agent_cli-0.84.2}/.cursorrules +0 -0
  15. {agent_cli-0.84.0 → agent_cli-0.84.2}/.dockerignore +0 -0
  16. {agent_cli-0.84.0 → agent_cli-0.84.2}/.env.example +0 -0
  17. {agent_cli-0.84.0 → agent_cli-0.84.2}/.github/logo.svg +0 -0
  18. {agent_cli-0.84.0 → agent_cli-0.84.2}/.github/release-drafter.yml +0 -0
  19. {agent_cli-0.84.0 → agent_cli-0.84.2}/.github/renovate.json +0 -0
  20. {agent_cli-0.84.0 → agent_cli-0.84.2}/.github/scripts/check_extras_sync.py +0 -0
  21. {agent_cli-0.84.0 → agent_cli-0.84.2}/.github/scripts/check_plugin_skill_sync.py +0 -0
  22. {agent_cli-0.84.0 → agent_cli-0.84.2}/.github/scripts/sync_extras.py +0 -0
  23. {agent_cli-0.84.0 → agent_cli-0.84.2}/.github/scripts/sync_requirements.py +0 -0
  24. {agent_cli-0.84.0 → agent_cli-0.84.2}/.github/workflows/automerge.yml +0 -0
  25. {agent_cli-0.84.0 → agent_cli-0.84.2}/.github/workflows/docker.yml +0 -0
  26. {agent_cli-0.84.0 → agent_cli-0.84.2}/.github/workflows/docs.yml +0 -0
  27. {agent_cli-0.84.0 → agent_cli-0.84.2}/.github/workflows/markdown-code-runner.yml +0 -0
  28. {agent_cli-0.84.0 → agent_cli-0.84.2}/.github/workflows/pytest.yml +0 -0
  29. {agent_cli-0.84.0 → agent_cli-0.84.2}/.github/workflows/release-drafter.yml +0 -0
  30. {agent_cli-0.84.0 → agent_cli-0.84.2}/.github/workflows/release.yml +0 -0
  31. {agent_cli-0.84.0 → agent_cli-0.84.2}/.github/workflows/toc.yaml +0 -0
  32. {agent_cli-0.84.0 → agent_cli-0.84.2}/.gitignore +0 -0
  33. {agent_cli-0.84.0 → agent_cli-0.84.2}/.jscpd.json +0 -0
  34. {agent_cli-0.84.0 → agent_cli-0.84.2}/.pre-commit-config.yaml +0 -0
  35. {agent_cli-0.84.0 → agent_cli-0.84.2}/.prompts/docs-review.md +0 -0
  36. {agent_cli-0.84.0 → agent_cli-0.84.2}/.prompts/pr-review.md +0 -0
  37. {agent_cli-0.84.0 → agent_cli-0.84.2}/CLAUDE.md +0 -0
  38. {agent_cli-0.84.0 → agent_cli-0.84.2}/LICENSE +0 -0
  39. {agent_cli-0.84.0 → agent_cli-0.84.2}/README.md +0 -0
  40. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/__init__.py +0 -0
  41. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/__main__.py +0 -0
  42. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_extras.json +0 -0
  43. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_requirements/.gitkeep +0 -0
  44. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_requirements/audio.txt +0 -0
  45. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_requirements/faster-whisper.txt +0 -0
  46. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_requirements/kokoro.txt +0 -0
  47. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_requirements/llm.txt +0 -0
  48. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_requirements/memory.txt +0 -0
  49. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_requirements/mlx-whisper.txt +0 -0
  50. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_requirements/piper.txt +0 -0
  51. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_requirements/rag.txt +0 -0
  52. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_requirements/server.txt +0 -0
  53. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_requirements/speed.txt +0 -0
  54. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_requirements/vad.txt +0 -0
  55. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_requirements/vectordb.txt +0 -0
  56. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_requirements/whisper-transformers.txt +0 -0
  57. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_requirements/wyoming.txt +0 -0
  58. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/_tools.py +0 -0
  59. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/agents/__init__.py +0 -0
  60. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/agents/_voice_agent_common.py +0 -0
  61. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/agents/assistant.py +0 -0
  62. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/agents/autocorrect.py +0 -0
  63. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/agents/chat.py +0 -0
  64. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/agents/memory/__init__.py +0 -0
  65. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/agents/memory/add.py +0 -0
  66. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/agents/memory/proxy.py +0 -0
  67. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/agents/rag_proxy.py +0 -0
  68. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/agents/speak.py +0 -0
  69. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/agents/transcribe.py +0 -0
  70. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/agents/transcribe_live.py +0 -0
  71. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/agents/voice_edit.py +0 -0
  72. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/api.py +0 -0
  73. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/cli.py +0 -0
  74. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/config.py +0 -0
  75. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/config_cmd.py +0 -0
  76. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/constants.py +0 -0
  77. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/core/__init__.py +0 -0
  78. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/core/audio.py +0 -0
  79. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/core/audio_format.py +0 -0
  80. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/core/chroma.py +0 -0
  81. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/core/deps.py +0 -0
  82. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/core/openai_proxy.py +0 -0
  83. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/core/process.py +0 -0
  84. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/core/reranker.py +0 -0
  85. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/core/sse.py +0 -0
  86. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/core/transcription_logger.py +0 -0
  87. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/core/utils.py +0 -0
  88. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/core/vad.py +0 -0
  89. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/core/watch.py +0 -0
  90. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/daemon/__init__.py +0 -0
  91. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/daemon/cli.py +0 -0
  92. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/__init__.py +0 -0
  93. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/_branch_name.py +0 -0
  94. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/_output.py +0 -0
  95. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/cleanup.py +0 -0
  96. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/coding_agents/__init__.py +0 -0
  97. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/coding_agents/aider.py +0 -0
  98. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/coding_agents/base.py +0 -0
  99. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/coding_agents/claude.py +0 -0
  100. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/coding_agents/codex.py +0 -0
  101. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/coding_agents/continue_dev.py +0 -0
  102. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/coding_agents/copilot.py +0 -0
  103. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/coding_agents/cursor_agent.py +0 -0
  104. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/coding_agents/gemini.py +0 -0
  105. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/coding_agents/opencode.py +0 -0
  106. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/coding_agents/registry.py +0 -0
  107. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/editors/__init__.py +0 -0
  108. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/editors/base.py +0 -0
  109. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/editors/cursor.py +0 -0
  110. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/editors/emacs.py +0 -0
  111. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/editors/jetbrains.py +0 -0
  112. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/editors/nano.py +0 -0
  113. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/editors/neovim.py +0 -0
  114. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/editors/registry.py +0 -0
  115. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/editors/sublime.py +0 -0
  116. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/editors/vim.py +0 -0
  117. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/editors/vscode.py +0 -0
  118. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/editors/zed.py +0 -0
  119. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/launch.py +0 -0
  120. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/project.py +0 -0
  121. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/registry.py +0 -0
  122. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/skill/SKILL.md +0 -0
  123. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/skill/examples.md +0 -0
  124. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/terminals/__init__.py +0 -0
  125. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/terminals/apple_terminal.py +0 -0
  126. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/terminals/base.py +0 -0
  127. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/terminals/gnome.py +0 -0
  128. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/terminals/iterm2.py +0 -0
  129. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/terminals/kitty.py +0 -0
  130. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/terminals/registry.py +0 -0
  131. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/terminals/warp.py +0 -0
  132. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/terminals/zellij.py +0 -0
  133. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/dev/worktree.py +0 -0
  134. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/docs_gen.py +0 -0
  135. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/example-config.toml +0 -0
  136. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/install/__init__.py +0 -0
  137. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/install/common.py +0 -0
  138. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/install/extras.py +0 -0
  139. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/install/hotkeys.py +0 -0
  140. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/install/launchd.py +0 -0
  141. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/install/service_config.py +0 -0
  142. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/install/services.py +0 -0
  143. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/install/systemd.py +0 -0
  144. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/__init__.py +0 -0
  145. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/_files.py +0 -0
  146. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/_filters.py +0 -0
  147. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/_git.py +0 -0
  148. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/_indexer.py +0 -0
  149. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/_ingest.py +0 -0
  150. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/_persistence.py +0 -0
  151. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/_prompt.py +0 -0
  152. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/_retrieval.py +0 -0
  153. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/_store.py +0 -0
  154. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/_streaming.py +0 -0
  155. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/_tasks.py +0 -0
  156. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/api.py +0 -0
  157. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/client.py +0 -0
  158. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/engine.py +0 -0
  159. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/entities.py +0 -0
  160. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/memory/models.py +0 -0
  161. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/opts.py +0 -0
  162. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/py.typed +0 -0
  163. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/rag/__init__.py +0 -0
  164. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/rag/_indexer.py +0 -0
  165. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/rag/_indexing.py +0 -0
  166. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/rag/_prompt.py +0 -0
  167. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/rag/_retriever.py +0 -0
  168. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/rag/_store.py +0 -0
  169. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/rag/_utils.py +0 -0
  170. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/rag/api.py +0 -0
  171. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/rag/client.py +0 -0
  172. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/rag/engine.py +0 -0
  173. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/rag/models.py +0 -0
  174. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/.runtime/.gitkeep +0 -0
  175. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/__init__.py +0 -0
  176. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/linux-hotkeys/README.md +0 -0
  177. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/linux-hotkeys/toggle-autocorrect.sh +0 -0
  178. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/linux-hotkeys/toggle-transcription.sh +0 -0
  179. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/linux-hotkeys/toggle-voice-edit.sh +0 -0
  180. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/macos-hotkeys/README.md +0 -0
  181. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/macos-hotkeys/skhd-config-example +0 -0
  182. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/macos-hotkeys/toggle-autocorrect.sh +0 -0
  183. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/macos-hotkeys/toggle-transcription.sh +0 -0
  184. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/macos-hotkeys/toggle-voice-edit.sh +0 -0
  185. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/nvidia-asr-server/README.md +0 -0
  186. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/nvidia-asr-server/pyproject.toml +0 -0
  187. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/nvidia-asr-server/server.py +0 -0
  188. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/nvidia-asr-server/shell.nix +0 -0
  189. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/nvidia-asr-server/uv.lock +0 -0
  190. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/run-openwakeword.sh +0 -0
  191. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/setup-linux-hotkeys.sh +0 -0
  192. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/setup-linux.sh +0 -0
  193. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/setup-macos-hotkeys.sh +0 -0
  194. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/setup-macos.sh +0 -0
  195. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/setup-windows.ps1 +0 -0
  196. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/start-all-services-windows.ps1 +0 -0
  197. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/scripts/start-all-services.sh +0 -0
  198. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/__init__.py +0 -0
  199. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/cli.py +0 -0
  200. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/common.py +0 -0
  201. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/model_manager.py +0 -0
  202. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/model_registry.py +0 -0
  203. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/proxy/__init__.py +0 -0
  204. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/proxy/api.py +0 -0
  205. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/streaming.py +0 -0
  206. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/tts/__init__.py +0 -0
  207. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/tts/api.py +0 -0
  208. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/tts/backends/__init__.py +0 -0
  209. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/tts/backends/base.py +0 -0
  210. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/tts/backends/kokoro.py +0 -0
  211. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/tts/backends/piper.py +0 -0
  212. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/tts/model_manager.py +0 -0
  213. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/tts/model_registry.py +0 -0
  214. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/tts/wyoming_handler.py +0 -0
  215. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/whisper/__init__.py +0 -0
  216. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/whisper/api.py +0 -0
  217. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/whisper/backends/__init__.py +0 -0
  218. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/whisper/backends/base.py +0 -0
  219. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/whisper/backends/faster_whisper.py +0 -0
  220. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/whisper/backends/mlx.py +0 -0
  221. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/whisper/backends/transformers.py +0 -0
  222. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/whisper/languages.py +0 -0
  223. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/whisper/model_manager.py +0 -0
  224. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/whisper/model_registry.py +0 -0
  225. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/server/whisper/wyoming_handler.py +0 -0
  226. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/services/__init__.py +0 -0
  227. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/services/_wyoming_utils.py +0 -0
  228. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/services/asr.py +0 -0
  229. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/services/llm.py +0 -0
  230. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/services/tts.py +0 -0
  231. {agent_cli-0.84.0 → agent_cli-0.84.2}/agent_cli/services/wake_word.py +0 -0
  232. {agent_cli-0.84.0 → agent_cli-0.84.2}/docker/docker-compose.yml +0 -0
  233. {agent_cli-0.84.0 → agent_cli-0.84.2}/docker/memory-proxy.Dockerfile +0 -0
  234. {agent_cli-0.84.0 → agent_cli-0.84.2}/docker/rag-proxy.Dockerfile +0 -0
  235. {agent_cli-0.84.0 → agent_cli-0.84.2}/docker/transcribe-proxy.Dockerfile +0 -0
  236. {agent_cli-0.84.0 → agent_cli-0.84.2}/docker/tts.Dockerfile +0 -0
  237. {agent_cli-0.84.0 → agent_cli-0.84.2}/docker/whisper.Dockerfile +0 -0
  238. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/CNAME +0 -0
  239. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/architecture/index.md +0 -0
  240. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/architecture/memory.md +0 -0
  241. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/architecture/rag.md +0 -0
  242. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/assistant.md +0 -0
  243. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/autocorrect.md +0 -0
  244. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/chat.md +0 -0
  245. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/config.md +0 -0
  246. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/daemon.md +0 -0
  247. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/dev.md +0 -0
  248. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/index.md +0 -0
  249. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/install-extras.md +0 -0
  250. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/install-hotkeys.md +0 -0
  251. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/install-services.md +0 -0
  252. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/memory.md +0 -0
  253. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/rag-proxy.md +0 -0
  254. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/server/index.md +0 -0
  255. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/server/transcribe-proxy.md +0 -0
  256. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/server/tts.md +0 -0
  257. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/server/whisper.md +0 -0
  258. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/speak.md +0 -0
  259. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/start-services.md +0 -0
  260. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/transcribe-live.md +0 -0
  261. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/transcribe.md +0 -0
  262. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/commands/voice-edit.md +0 -0
  263. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/configuration.md +0 -0
  264. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/getting-started.md +0 -0
  265. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/iOS_Shortcut_Guide.md +0 -0
  266. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/index.md +0 -0
  267. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/installation/docker.md +0 -0
  268. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/installation/index.md +0 -0
  269. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/installation/linux.md +0 -0
  270. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/installation/macos.md +0 -0
  271. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/installation/nixos.md +0 -0
  272. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/installation/windows.md +0 -0
  273. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/logo-clean.svg +0 -0
  274. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/overrides/partials/integrations/analytics/custom.html +0 -0
  275. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/run_markdown_code_runner.py +0 -0
  276. {agent_cli-0.84.0 → agent_cli-0.84.2}/docs/system-integration.md +0 -0
  277. {agent_cli-0.84.0 → agent_cli-0.84.2}/example.agent-cli-config.toml +0 -0
  278. {agent_cli-0.84.0 → agent_cli-0.84.2}/justfile +0 -0
  279. {agent_cli-0.84.0 → agent_cli-0.84.2}/pyproject.toml +0 -0
  280. {agent_cli-0.84.0 → agent_cli-0.84.2}/shell.nix +0 -0
  281. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/__init__.py +0 -0
  282. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/__init__.py +0 -0
  283. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_fix_my_text.py +0 -0
  284. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_interactive.py +0 -0
  285. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_interactive_extra.py +0 -0
  286. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_memory_add.py +0 -0
  287. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_speak.py +0 -0
  288. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_speak_e2e.py +0 -0
  289. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_transcribe.py +0 -0
  290. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_transcribe_agent.py +0 -0
  291. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_transcribe_e2e.py +0 -0
  292. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_transcribe_live.py +0 -0
  293. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_transcribe_recovery.py +0 -0
  294. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_tts_common.py +0 -0
  295. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_tts_common_extra.py +0 -0
  296. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_voice_agent_common.py +0 -0
  297. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_voice_edit.py +0 -0
  298. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_voice_edit_e2e.py +0 -0
  299. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/agents/test_wake_word_assistant.py +0 -0
  300. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/conftest.py +0 -0
  301. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/core/__init__.py +0 -0
  302. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/core/test_audio.py +0 -0
  303. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/core/test_audio_format.py +0 -0
  304. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/core/test_chroma.py +0 -0
  305. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/core/test_sse.py +0 -0
  306. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/core/test_vad.py +0 -0
  307. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/core/test_watch.py +0 -0
  308. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/dev/__init__.py +0 -0
  309. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/dev/test_coding_agents.py +0 -0
  310. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/dev/test_editors.py +0 -0
  311. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/dev/test_launch.py +0 -0
  312. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/dev/test_project.py +0 -0
  313. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/dev/test_verification.py +0 -0
  314. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/dev/test_worktree.py +0 -0
  315. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/install/__init__.py +0 -0
  316. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/install/test_extras.py +0 -0
  317. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/memory/__init__.py +0 -0
  318. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/memory/test_api_health.py +0 -0
  319. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/memory/test_api_integration_liveish.py +0 -0
  320. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/memory/test_engine.py +0 -0
  321. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/memory/test_files.py +0 -0
  322. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/memory/test_filters.py +0 -0
  323. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/memory/test_git_integration.py +0 -0
  324. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/memory/test_indexer.py +0 -0
  325. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/memory/test_memory_integration.py +0 -0
  326. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/memory/test_proxy_passthrough.py +0 -0
  327. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/memory/test_store.py +0 -0
  328. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/memory/test_utils.py +0 -0
  329. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/mocks/__init__.py +0 -0
  330. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/mocks/audio.py +0 -0
  331. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/mocks/llm.py +0 -0
  332. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/mocks/wyoming.py +0 -0
  333. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/rag/__init__.py +0 -0
  334. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/rag/test_api.py +0 -0
  335. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/rag/test_engine.py +0 -0
  336. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/rag/test_history.py +0 -0
  337. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/rag/test_indexer.py +0 -0
  338. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/rag/test_indexing.py +0 -0
  339. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/rag/test_rag_client.py +0 -0
  340. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/rag/test_rag_integration_liveish.py +0 -0
  341. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/rag/test_rag_proxy_passthrough.py +0 -0
  342. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/rag/test_retriever.py +0 -0
  343. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/rag/test_store.py +0 -0
  344. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/rag/test_utils.py +0 -0
  345. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_api.py +0 -0
  346. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_api_integration.py +0 -0
  347. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_asr.py +0 -0
  348. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_asr_recovery.py +0 -0
  349. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_audio_e2e.py +0 -0
  350. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_cli.py +0 -0
  351. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_config.py +0 -0
  352. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_config_cmd.py +0 -0
  353. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_daemon.py +0 -0
  354. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_docs_gen.py +0 -0
  355. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_env_vars.py +0 -0
  356. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_json_output.py +0 -0
  357. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_llm.py +0 -0
  358. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_llm_gemini.py +0 -0
  359. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_memory_tools.py +0 -0
  360. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_mlx_backend.py +0 -0
  361. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_process_manager.py +0 -0
  362. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_requires_extras.py +0 -0
  363. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_server_streaming.py +0 -0
  364. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_server_tts.py +0 -0
  365. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_server_whisper.py +0 -0
  366. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_services.py +0 -0
  367. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_tools.py +0 -0
  368. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_transformers_backend.py +0 -0
  369. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_tts.py +0 -0
  370. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_utils.py +0 -0
  371. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_wake_word.py +0 -0
  372. {agent_cli-0.84.0 → agent_cli-0.84.2}/tests/test_wyoming_utils.py +0 -0
  373. {agent_cli-0.84.0 → agent_cli-0.84.2}/uv.lock +0 -0
  374. {agent_cli-0.84.0 → agent_cli-0.84.2}/zensical.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-cli
3
- Version: 0.84.0
3
+ Version: 0.84.2
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>
@@ -111,6 +111,47 @@ def _ensure_git_repo() -> Path:
111
111
  return repo_root
112
112
 
113
113
 
114
+ def _require_available_agent(
115
+ agent: coding_agents.CodingAgent | None,
116
+ *,
117
+ requested_name: str | None = None,
118
+ ) -> coding_agents.CodingAgent:
119
+ """Fail fast when an explicit agent launch was requested but cannot happen."""
120
+ if agent is None:
121
+ if requested_name:
122
+ error(f"Agent not found: {requested_name}")
123
+ available_names = ", ".join(candidate.name for candidate in coding_agents.get_all_agents())
124
+ if available_names:
125
+ error(f"No AI coding agents found. Install one of: {available_names}")
126
+ error("No AI coding agents found")
127
+
128
+ if not agent.is_available():
129
+ msg = f"{agent.name} is not installed"
130
+ if agent.install_url:
131
+ msg += f". Install from: {agent.install_url}"
132
+ error(msg)
133
+
134
+ return agent
135
+
136
+
137
+ def _resolve_prompt_text(
138
+ prompt: str | None,
139
+ *,
140
+ prompt_file: Path | None = None,
141
+ ) -> str | None:
142
+ """Resolve prompt text from CLI input and reject empty explicit prompts."""
143
+ if prompt_file is not None:
144
+ prompt = prompt_file.read_text().strip()
145
+ if not prompt:
146
+ error(f"Prompt file is empty: {prompt_file}")
147
+ return prompt
148
+
149
+ if prompt is not None and not prompt.strip():
150
+ error("--prompt cannot be empty")
151
+
152
+ return prompt
153
+
154
+
114
155
  def _resolve_branch_name(
115
156
  branch: str | None,
116
157
  branch_name_mode: str,
@@ -383,9 +424,7 @@ def new(
383
424
  - `dev new feature-x --from origin/develop` — Branch from develop instead
384
425
  - `dev new feature-x --with-agent aider --with-editor cursor` — Specific tools
385
426
  """
386
- # Handle prompt-file option (takes precedence over --prompt)
387
- if prompt_file is not None:
388
- prompt = prompt_file.read_text().strip()
427
+ prompt = _resolve_prompt_text(prompt, prompt_file=prompt_file)
389
428
 
390
429
  # If a prompt is provided, automatically enable agent mode
391
430
  if prompt:
@@ -404,6 +443,10 @@ def new(
404
443
  from_ref,
405
444
  )
406
445
 
446
+ resolved_agent = resolve_agent(agent, agent_name, default_agent)
447
+ if agent:
448
+ resolved_agent = _require_available_agent(resolved_agent, requested_name=agent_name)
449
+
407
450
  # Create the worktree
408
451
  info(f"Creating worktree for branch '{branch}'...")
409
452
  result = worktree.create_worktree(
@@ -440,7 +483,6 @@ def new(
440
483
 
441
484
  # Resolve and launch editor/agent
442
485
  resolved_editor = resolve_editor(editor, editor_name, default_editor)
443
- resolved_agent = resolve_agent(agent, agent_name, default_agent)
444
486
 
445
487
  if resolved_editor and resolved_editor.is_available():
446
488
  launch_editor(result.path, resolved_editor)
@@ -902,9 +944,7 @@ def start_agent(
902
944
  - `dev agent my-feature -a claude` — Start Claude specifically
903
945
  - `dev agent my-feature -p "Continue the auth refactor"` — Start with a task
904
946
  """
905
- # Handle prompt-file option (takes precedence over --prompt)
906
- if prompt_file is not None:
907
- prompt = prompt_file.read_text().strip()
947
+ prompt = _resolve_prompt_text(prompt, prompt_file=prompt_file)
908
948
 
909
949
  repo_root = _ensure_git_repo()
910
950
 
@@ -914,18 +954,13 @@ def start_agent(
914
954
 
915
955
  if agent_name:
916
956
  agent = coding_agents.get_agent(agent_name)
917
- if agent is None:
918
- error(f"Agent not found: {agent_name}")
919
957
  else:
920
958
  agent = coding_agents.detect_current_agent()
921
959
  if agent is None:
922
960
  available = coding_agents.get_available_agents()
923
- if not available:
924
- error("No AI coding agents available")
925
- agent = available[0]
961
+ agent = available[0] if available else None
926
962
 
927
- if not agent.is_available():
928
- error(f"{agent.name} is not installed. Install from: {agent.install_url}")
963
+ agent = _require_available_agent(agent, requested_name=agent_name)
929
964
 
930
965
  # Write prompt to worktree (makes task available to the agent)
931
966
  task_file = None
@@ -49,19 +49,6 @@ class Tmux(Terminal):
49
49
  session_name = result.stdout.strip()
50
50
  return session_name or None
51
51
 
52
- def session_exists(self, session_name: str) -> bool:
53
- """Check if a tmux session exists."""
54
- try:
55
- subprocess.run(
56
- ["tmux", "has-session", "-t", session_name], # noqa: S607
57
- check=True,
58
- capture_output=True,
59
- text=True,
60
- )
61
- return True
62
- except subprocess.CalledProcessError:
63
- return False
64
-
65
52
  def open_in_session(
66
53
  self,
67
54
  path: Path,
@@ -84,9 +71,18 @@ class Tmux(Terminal):
84
71
  return None
85
72
  return self._open_window(path, command, tab_name, session_name=session_name)
86
73
 
87
- if self.session_exists(session_name):
88
- return self._open_window(path, command, tab_name, session_name=session_name)
89
- return self._create_session(path, command, tab_name, session_name=session_name)
74
+ # Avoid a has-session/new-session race when several launches try to create the
75
+ # same repo-scoped session concurrently: try new-window first, then create,
76
+ # then retry new-window in case another launcher created the session first.
77
+ handle = self._open_window(path, command, tab_name, session_name=session_name)
78
+ if handle is not None:
79
+ return handle
80
+
81
+ handle = self._create_session(path, command, tab_name, session_name=session_name)
82
+ if handle is not None:
83
+ return handle
84
+
85
+ return self._open_window(path, command, tab_name, session_name=session_name)
90
86
 
91
87
  def open_new_tab(
92
88
  self,
@@ -19,6 +19,7 @@ from agent_cli.dev._branch_name import (
19
19
  generate_random_branch_name,
20
20
  )
21
21
  from agent_cli.dev.cli import _clean_no_commits_worktrees
22
+ from agent_cli.dev.cli import app as dev_app
22
23
  from agent_cli.dev.coding_agents.base import CodingAgent
23
24
  from agent_cli.dev.launch import (
24
25
  _format_env_prefix,
@@ -300,8 +301,13 @@ class TestDevNewBranchNaming:
300
301
  return_value=wt_path / ".claude/TASK.md",
301
302
  ),
302
303
  patch("agent_cli.dev.cli.resolve_editor", return_value=None),
303
- patch("agent_cli.dev.cli.resolve_agent", return_value=None),
304
+ patch("agent_cli.dev.cli.resolve_agent") as mock_resolve_agent,
305
+ patch("agent_cli.dev.cli.merge_agent_args", return_value=None),
306
+ patch("agent_cli.dev.cli.get_agent_env", return_value={}),
307
+ patch("agent_cli.dev.cli.launch_agent", return_value=None),
304
308
  ):
309
+ mock_agent = mock_resolve_agent.return_value
310
+ mock_agent.is_available.return_value = True
305
311
  result = runner.invoke(
306
312
  app,
307
313
  [
@@ -559,6 +565,99 @@ direnv = false
559
565
  assert "%42" in result.output
560
566
  assert "tmux attach -t agent-cli-repo-1234" in result.output
561
567
 
568
+ def test_new_fails_before_creating_worktree_when_no_agent_is_available(
569
+ self,
570
+ tmp_path: Path,
571
+ ) -> None:
572
+ """Explicit agent launches should fail fast before creating side effects."""
573
+ prompt_file = tmp_path / "task.md"
574
+ prompt_file.write_text("Fix login retries")
575
+
576
+ with (
577
+ patch("agent_cli.dev.cli._ensure_git_repo", return_value=Path("/repo")),
578
+ patch("agent_cli.dev.cli.resolve_agent", return_value=None),
579
+ patch("agent_cli.dev.worktree.create_worktree") as mock_create,
580
+ ):
581
+ result = runner.invoke(
582
+ app,
583
+ [
584
+ "dev",
585
+ "new",
586
+ "my-feature",
587
+ "--agent",
588
+ "--multiplexer",
589
+ "tmux",
590
+ "--prompt-file",
591
+ str(prompt_file),
592
+ "--no-setup",
593
+ "--no-copy-env",
594
+ "--no-fetch",
595
+ "--no-direnv",
596
+ ],
597
+ )
598
+
599
+ assert result.exit_code == 1
600
+ assert "No AI coding agents found" in result.output
601
+ assert "Success" not in result.output
602
+ mock_create.assert_not_called()
603
+
604
+ def test_new_fails_before_creating_worktree_when_requested_agent_is_unavailable(self) -> None:
605
+ """Unavailable explicit agents should abort before worktree creation."""
606
+ with (
607
+ patch("agent_cli.dev.cli._ensure_git_repo", return_value=Path("/repo")),
608
+ patch("agent_cli.dev.cli.resolve_agent") as mock_resolve_agent,
609
+ patch("agent_cli.dev.worktree.create_worktree") as mock_create,
610
+ ):
611
+ mock_agent = mock_resolve_agent.return_value
612
+ mock_agent.name = "codex"
613
+ mock_agent.install_url = "https://example.com/codex"
614
+ mock_agent.is_available.return_value = False
615
+
616
+ result = runner.invoke(
617
+ app,
618
+ [
619
+ "dev",
620
+ "new",
621
+ "my-feature",
622
+ "--agent",
623
+ "--with-agent",
624
+ "codex",
625
+ "--no-setup",
626
+ "--no-copy-env",
627
+ "--no-fetch",
628
+ "--no-direnv",
629
+ ],
630
+ )
631
+
632
+ assert result.exit_code == 1
633
+ assert "codex is not installed. Install from: https://example.com/codex" in result.output
634
+ assert "Success" not in result.output
635
+ mock_create.assert_not_called()
636
+
637
+ def test_new_rejects_empty_prompt(self) -> None:
638
+ """Explicit empty prompts should error instead of silently becoming no-op."""
639
+ with patch("agent_cli.dev.cli._ensure_git_repo") as mock_ensure_repo:
640
+ result = runner.invoke(app, ["dev", "new", "my-feature", "--prompt", " "])
641
+
642
+ assert result.exit_code == 1
643
+ assert "--prompt cannot be empty" in result.output
644
+ mock_ensure_repo.assert_not_called()
645
+
646
+ def test_new_rejects_empty_prompt_file(self, tmp_path: Path) -> None:
647
+ """Empty prompt files should fail before any worktree setup starts."""
648
+ prompt_file = tmp_path / "empty.md"
649
+ prompt_file.write_text(" \n")
650
+
651
+ with patch("agent_cli.dev.cli._ensure_git_repo") as mock_ensure_repo:
652
+ result = runner.invoke(
653
+ app,
654
+ ["dev", "new", "my-feature", "--prompt-file", str(prompt_file)],
655
+ )
656
+
657
+ assert result.exit_code == 1
658
+ assert f"Prompt file is empty: {prompt_file}" in result.output
659
+ mock_ensure_repo.assert_not_called()
660
+
562
661
 
563
662
  class TestDevHelp:
564
663
  """Tests for dev command help."""
@@ -639,13 +738,28 @@ class TestDevAgent:
639
738
  assert result.exit_code == 0
640
739
  assert "tmux attach -t 'my session'" in result.output
641
740
 
741
+ def test_agent_rejects_empty_prompt_file(self, tmp_path: Path) -> None:
742
+ """Empty prompt files should fail before repo/worktree resolution."""
743
+ prompt_file = tmp_path / "empty.md"
744
+ prompt_file.write_text("\n")
745
+
746
+ with patch("agent_cli.dev.cli._ensure_git_repo") as mock_ensure_repo:
747
+ result = runner.invoke(
748
+ app,
749
+ ["dev", "agent", "feature", "--prompt-file", str(prompt_file)],
750
+ )
751
+
752
+ assert result.exit_code == 1
753
+ assert f"Prompt file is empty: {prompt_file}" in result.output
754
+ mock_ensure_repo.assert_not_called()
755
+
642
756
 
643
757
  class TestDevAgents:
644
758
  """Tests for dev agents command."""
645
759
 
646
760
  def test_list_agents(self) -> None:
647
761
  """List all agents."""
648
- result = runner.invoke(app, ["dev", "agents"])
762
+ result = runner.invoke(dev_app, ["agents"])
649
763
  assert result.exit_code == 0
650
764
  assert "claude" in result.output.lower()
651
765
  assert "aider" in result.output.lower()
@@ -656,7 +770,7 @@ class TestDevEditors:
656
770
 
657
771
  def test_list_editors(self) -> None:
658
772
  """List all editors."""
659
- result = runner.invoke(app, ["dev", "editors"])
773
+ result = runner.invoke(dev_app, ["editors"])
660
774
  assert result.exit_code == 0
661
775
  assert "vscode" in result.output.lower()
662
776
  assert "neovim" in result.output.lower()
@@ -667,7 +781,7 @@ class TestDevTerminals:
667
781
 
668
782
  def test_list_terminals(self) -> None:
669
783
  """List all terminals."""
670
- result = runner.invoke(app, ["dev", "terminals"])
784
+ result = runner.invoke(dev_app, ["terminals"])
671
785
  assert result.exit_code == 0
672
786
  assert "tmux" in result.output.lower()
673
787
  assert "zellij" in result.output.lower()
@@ -65,11 +65,14 @@ class TestTmux:
65
65
  def test_open_in_session_creates_detached_session_when_missing(self) -> None:
66
66
  """Outside tmux, a named session is created in detached mode if absent."""
67
67
  terminal = Tmux()
68
- mock_run = MagicMock(return_value=MagicMock(stdout="%42\n"))
69
68
  with (
70
- patch("subprocess.run", mock_run),
71
- patch.object(terminal, "session_exists", return_value=False),
72
- patch("shutil.which", return_value="/usr/bin/tmux"),
69
+ patch.object(terminal, "is_available", return_value=True),
70
+ patch.object(terminal, "_open_window", return_value=None) as mock_open,
71
+ patch.object(
72
+ terminal,
73
+ "_create_session",
74
+ return_value=MagicMock(handle="%42", session_name="repo-session"),
75
+ ) as mock_create,
73
76
  ):
74
77
  handle = terminal.open_in_session(
75
78
  Path("/some/path"),
@@ -81,23 +84,30 @@ class TestTmux:
81
84
  assert handle is not None
82
85
  assert handle.handle == "%42"
83
86
  assert handle.session_name == "repo-session"
84
- cmd = mock_run.call_args[0][0]
85
- assert "new-session" in cmd
86
- assert "-d" in cmd
87
- assert "-P" in cmd
88
- assert "-F" in cmd
89
- assert "#{pane_id}" in cmd
90
- assert "-s" in cmd
91
- assert "repo-session" in cmd
87
+ mock_open.assert_called_once_with(
88
+ Path("/some/path"),
89
+ "echo hello",
90
+ "test",
91
+ session_name="repo-session",
92
+ )
93
+ mock_create.assert_called_once_with(
94
+ Path("/some/path"),
95
+ "echo hello",
96
+ "test",
97
+ session_name="repo-session",
98
+ )
92
99
 
93
100
  def test_open_in_session_reuses_existing_session(self) -> None:
94
101
  """Outside tmux, a named session gets a new window when it already exists."""
95
102
  terminal = Tmux()
96
- mock_run = MagicMock(return_value=MagicMock(stdout="%5\n"))
97
103
  with (
98
- patch("subprocess.run", mock_run),
99
- patch.object(terminal, "session_exists", return_value=True),
100
- patch("shutil.which", return_value="/usr/bin/tmux"),
104
+ patch.object(terminal, "is_available", return_value=True),
105
+ patch.object(
106
+ terminal,
107
+ "_open_window",
108
+ return_value=MagicMock(handle="%5", session_name="repo-session"),
109
+ ) as mock_open,
110
+ patch.object(terminal, "_create_session") as mock_create,
101
111
  ):
102
112
  handle = terminal.open_in_session(
103
113
  Path("/some/path"),
@@ -109,10 +119,46 @@ class TestTmux:
109
119
  assert handle is not None
110
120
  assert handle.handle == "%5"
111
121
  assert handle.session_name == "repo-session"
112
- cmd = mock_run.call_args[0][0]
113
- assert "new-window" in cmd
114
- assert "-t" in cmd
115
- assert "repo-session" in cmd
122
+ mock_open.assert_called_once_with(
123
+ Path("/some/path"),
124
+ "echo hello",
125
+ "test",
126
+ session_name="repo-session",
127
+ )
128
+ mock_create.assert_not_called()
129
+
130
+ def test_open_in_session_retries_when_session_appears_during_race(self) -> None:
131
+ """Concurrent creators should fall back to opening a new window."""
132
+ terminal = Tmux()
133
+ with (
134
+ patch.object(terminal, "is_available", return_value=True),
135
+ patch.object(
136
+ terminal,
137
+ "_open_window",
138
+ side_effect=[
139
+ None,
140
+ MagicMock(handle="%7", session_name="repo-session"),
141
+ ],
142
+ ) as mock_open,
143
+ patch.object(terminal, "_create_session", return_value=None) as mock_create,
144
+ ):
145
+ handle = terminal.open_in_session(
146
+ Path("/some/path"),
147
+ "echo hello",
148
+ tab_name="test",
149
+ session_name="repo-session",
150
+ )
151
+
152
+ assert handle is not None
153
+ assert handle.handle == "%7"
154
+ assert handle.session_name == "repo-session"
155
+ assert mock_open.call_count == 2
156
+ mock_create.assert_called_once_with(
157
+ Path("/some/path"),
158
+ "echo hello",
159
+ "test",
160
+ session_name="repo-session",
161
+ )
116
162
 
117
163
 
118
164
  class TestZellij:
@@ -53,6 +53,9 @@ class _DummyReranker:
53
53
  def client(tmp_path: Path) -> MemoryClient:
54
54
  """Create a memory client with stubs."""
55
55
  with ExitStack() as stack:
56
+ stack.enter_context(
57
+ patch("agent_cli.memory.client.init_repo"),
58
+ )
56
59
  stack.enter_context(
57
60
  patch("agent_cli.memory.client.watch_memory_store"),
58
61
  )
@@ -150,6 +153,9 @@ async def test_client_startup_manual(tmp_path: Path) -> None:
150
153
  pass
151
154
 
152
155
  with ExitStack() as stack:
156
+ stack.enter_context(
157
+ patch("agent_cli.memory.client.init_repo"),
158
+ )
153
159
  mock_watch = stack.enter_context(patch("agent_cli.memory.client.watch_memory_store"))
154
160
  mock_watch.side_effect = _fake_watch
155
161
 
@@ -195,6 +201,9 @@ async def test_client_context_manager(tmp_path: Path) -> None:
195
201
  pass
196
202
 
197
203
  with ExitStack() as stack:
204
+ stack.enter_context(
205
+ patch("agent_cli.memory.client.init_repo"),
206
+ )
198
207
  mock_watch = stack.enter_context(patch("agent_cli.memory.client.watch_memory_store"))
199
208
  mock_watch.side_effect = _fake_watch
200
209
 
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
File without changes
File without changes