agent-cli 0.84.1__tar.gz → 0.85.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.
- {agent_cli-0.84.1/agent_cli/dev/skill → agent_cli-0.85.0/.claude/skills/agent-cli-dev}/SKILL.md +1 -1
- {agent_cli-0.84.1/.claude → agent_cli-0.85.0/.claude-plugin}/skills/agent-cli-dev/SKILL.md +1 -1
- {agent_cli-0.84.1 → agent_cli-0.85.0}/PKG-INFO +1 -1
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/cli.py +4 -3
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/config.py +1 -0
- agent_cli-0.85.0/agent_cli/dev/_config.py +59 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/cli.py +64 -7
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/coding_agents/base.py +11 -0
- agent_cli-0.85.0/agent_cli/dev/coding_agents/codex.py +92 -0
- agent_cli-0.85.0/agent_cli/dev/hooks.py +138 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/launch.py +5 -26
- {agent_cli-0.84.1/.claude-plugin/skills/agent-cli-dev → agent_cli-0.85.0/agent_cli/dev/skill}/SKILL.md +1 -1
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/terminals/tmux.py +12 -16
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/example-config.toml +7 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/dev.md +30 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/dev/test_cli.py +147 -7
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/dev/test_coding_agents.py +60 -0
- agent_cli-0.85.0/tests/dev/test_hooks.py +154 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/dev/test_terminals.py +66 -20
- agent_cli-0.84.1/agent_cli/dev/coding_agents/codex.py +0 -24
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.claude/skills/agent-cli-dev/examples.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.claude-plugin/README.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.claude-plugin/marketplace.json +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.claude-plugin/plugin.json +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.claude-plugin/skills/agent-cli-dev/examples.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.cursorrules +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.dockerignore +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.env.example +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.github/logo.svg +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.github/release-drafter.yml +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.github/renovate.json +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.github/scripts/check_extras_sync.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.github/scripts/check_plugin_skill_sync.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.github/scripts/sync_extras.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.github/scripts/sync_requirements.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.github/workflows/automerge.yml +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.github/workflows/docker.yml +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.github/workflows/docs.yml +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.github/workflows/markdown-code-runner.yml +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.github/workflows/pytest.yml +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.github/workflows/release-drafter.yml +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.github/workflows/release.yml +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.github/workflows/toc.yaml +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.gitignore +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.jscpd.json +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.pre-commit-config.yaml +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.prompts/docs-review.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/.prompts/pr-review.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/CLAUDE.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/LICENSE +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/README.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/__main__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_extras.json +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_requirements/.gitkeep +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_requirements/audio.txt +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_requirements/faster-whisper.txt +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_requirements/kokoro.txt +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_requirements/llm.txt +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_requirements/memory.txt +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_requirements/mlx-whisper.txt +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_requirements/piper.txt +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_requirements/rag.txt +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_requirements/server.txt +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_requirements/speed.txt +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_requirements/vad.txt +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_requirements/vectordb.txt +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_requirements/whisper-transformers.txt +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_requirements/wyoming.txt +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/_tools.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/agents/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/agents/_voice_agent_common.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/agents/assistant.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/agents/autocorrect.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/agents/chat.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/agents/memory/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/agents/memory/add.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/agents/memory/proxy.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/agents/rag_proxy.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/agents/speak.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/agents/transcribe.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/agents/transcribe_live.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/agents/voice_edit.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/api.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/config_cmd.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/constants.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/core/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/core/audio.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/core/audio_format.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/core/chroma.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/core/deps.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/core/openai_proxy.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/core/process.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/core/reranker.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/core/sse.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/core/transcription_logger.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/core/utils.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/core/vad.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/core/watch.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/daemon/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/daemon/cli.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/_branch_name.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/_output.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/cleanup.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/coding_agents/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/coding_agents/aider.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/coding_agents/claude.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/coding_agents/continue_dev.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/coding_agents/copilot.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/coding_agents/cursor_agent.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/coding_agents/gemini.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/coding_agents/opencode.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/coding_agents/registry.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/editors/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/editors/base.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/editors/cursor.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/editors/emacs.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/editors/jetbrains.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/editors/nano.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/editors/neovim.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/editors/registry.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/editors/sublime.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/editors/vim.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/editors/vscode.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/editors/zed.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/project.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/registry.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/skill/examples.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/terminals/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/terminals/apple_terminal.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/terminals/base.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/terminals/gnome.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/terminals/iterm2.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/terminals/kitty.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/terminals/registry.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/terminals/warp.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/terminals/zellij.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/dev/worktree.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/docs_gen.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/install/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/install/common.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/install/extras.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/install/hotkeys.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/install/launchd.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/install/service_config.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/install/services.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/install/systemd.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/_files.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/_filters.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/_git.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/_indexer.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/_ingest.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/_persistence.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/_prompt.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/_retrieval.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/_store.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/_streaming.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/_tasks.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/api.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/client.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/engine.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/entities.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/memory/models.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/opts.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/py.typed +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/rag/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/rag/_indexer.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/rag/_indexing.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/rag/_prompt.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/rag/_retriever.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/rag/_store.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/rag/_utils.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/rag/api.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/rag/client.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/rag/engine.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/rag/models.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/.runtime/.gitkeep +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/linux-hotkeys/README.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/linux-hotkeys/toggle-autocorrect.sh +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/linux-hotkeys/toggle-transcription.sh +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/linux-hotkeys/toggle-voice-edit.sh +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/macos-hotkeys/README.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/macos-hotkeys/skhd-config-example +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/macos-hotkeys/toggle-autocorrect.sh +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/macos-hotkeys/toggle-transcription.sh +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/macos-hotkeys/toggle-voice-edit.sh +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/nvidia-asr-server/README.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/nvidia-asr-server/pyproject.toml +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/nvidia-asr-server/server.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/nvidia-asr-server/shell.nix +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/nvidia-asr-server/uv.lock +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/run-openwakeword.sh +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/setup-linux-hotkeys.sh +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/setup-linux.sh +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/setup-macos-hotkeys.sh +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/setup-macos.sh +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/setup-windows.ps1 +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/start-all-services-windows.ps1 +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/scripts/start-all-services.sh +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/cli.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/common.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/model_manager.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/model_registry.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/proxy/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/proxy/api.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/streaming.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/tts/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/tts/api.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/tts/backends/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/tts/backends/base.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/tts/backends/kokoro.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/tts/backends/piper.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/tts/model_manager.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/tts/model_registry.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/tts/wyoming_handler.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/whisper/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/whisper/api.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/whisper/backends/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/whisper/backends/base.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/whisper/backends/faster_whisper.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/whisper/backends/mlx.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/whisper/backends/transformers.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/whisper/languages.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/whisper/model_manager.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/whisper/model_registry.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/server/whisper/wyoming_handler.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/services/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/services/_wyoming_utils.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/services/asr.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/services/llm.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/services/tts.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/agent_cli/services/wake_word.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docker/docker-compose.yml +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docker/memory-proxy.Dockerfile +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docker/rag-proxy.Dockerfile +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docker/transcribe-proxy.Dockerfile +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docker/tts.Dockerfile +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docker/whisper.Dockerfile +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/CNAME +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/architecture/index.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/architecture/memory.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/architecture/rag.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/assistant.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/autocorrect.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/chat.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/config.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/daemon.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/index.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/install-extras.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/install-hotkeys.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/install-services.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/memory.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/rag-proxy.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/server/index.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/server/transcribe-proxy.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/server/tts.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/server/whisper.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/speak.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/start-services.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/transcribe-live.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/transcribe.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/commands/voice-edit.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/configuration.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/getting-started.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/iOS_Shortcut_Guide.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/index.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/installation/docker.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/installation/index.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/installation/linux.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/installation/macos.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/installation/nixos.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/installation/windows.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/logo-clean.svg +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/overrides/partials/integrations/analytics/custom.html +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/run_markdown_code_runner.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/docs/system-integration.md +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/example.agent-cli-config.toml +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/justfile +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/pyproject.toml +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/shell.nix +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_fix_my_text.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_interactive.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_interactive_extra.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_memory_add.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_speak.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_speak_e2e.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_transcribe.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_transcribe_agent.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_transcribe_e2e.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_transcribe_live.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_transcribe_recovery.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_tts_common.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_tts_common_extra.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_voice_agent_common.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_voice_edit.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_voice_edit_e2e.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/agents/test_wake_word_assistant.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/conftest.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/core/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/core/test_audio.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/core/test_audio_format.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/core/test_chroma.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/core/test_sse.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/core/test_vad.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/core/test_watch.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/dev/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/dev/test_editors.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/dev/test_launch.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/dev/test_project.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/dev/test_verification.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/dev/test_worktree.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/install/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/install/test_extras.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/memory/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/memory/test_api_health.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/memory/test_api_integration_liveish.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/memory/test_client.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/memory/test_engine.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/memory/test_files.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/memory/test_filters.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/memory/test_git_integration.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/memory/test_indexer.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/memory/test_memory_integration.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/memory/test_proxy_passthrough.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/memory/test_store.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/memory/test_utils.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/mocks/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/mocks/audio.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/mocks/llm.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/mocks/wyoming.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/rag/__init__.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/rag/test_api.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/rag/test_engine.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/rag/test_history.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/rag/test_indexer.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/rag/test_indexing.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/rag/test_rag_client.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/rag/test_rag_integration_liveish.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/rag/test_rag_proxy_passthrough.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/rag/test_retriever.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/rag/test_store.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/rag/test_utils.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_api.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_api_integration.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_asr.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_asr_recovery.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_audio_e2e.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_cli.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_config.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_config_cmd.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_daemon.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_docs_gen.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_env_vars.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_json_output.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_llm.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_llm_gemini.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_memory_tools.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_mlx_backend.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_process_manager.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_requires_extras.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_server_streaming.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_server_tts.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_server_whisper.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_services.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_tools.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_transformers_backend.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_tts.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_utils.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_wake_word.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/tests/test_wyoming_utils.py +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/uv.lock +0 -0
- {agent_cli-0.84.1 → agent_cli-0.85.0}/zensical.toml +0 -0
{agent_cli-0.84.1/agent_cli/dev/skill → agent_cli-0.85.0/.claude/skills/agent-cli-dev}/SKILL.md
RENAMED
|
@@ -174,7 +174,7 @@ agent-cli dev new validation-a --from HEAD --agent --with-agent codex -m tmux \
|
|
|
174
174
|
--prompt-file .claude/validation-a.md
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
-
This works without an attached terminal. `agent-cli` creates or reuses a detached tmux session and returns a pane handle plus attach command.
|
|
177
|
+
This works without an attached terminal. `agent-cli` creates or reuses a detached tmux session and returns a pane handle plus attach command. Launches may also run pre-launch preparation by default; use `--no-hooks` only when you explicitly need to bypass that behavior.
|
|
178
178
|
|
|
179
179
|
## Example: Multi-feature implementation
|
|
180
180
|
|
|
@@ -174,7 +174,7 @@ agent-cli dev new validation-a --from HEAD --agent --with-agent codex -m tmux \
|
|
|
174
174
|
--prompt-file .claude/validation-a.md
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
-
This works without an attached terminal. `agent-cli` creates or reuses a detached tmux session and returns a pane handle plus attach command.
|
|
177
|
+
This works without an attached terminal. `agent-cli` creates or reuses a detached tmux session and returns a pane handle plus attach command. Launches may also run pre-launch preparation by default; use `--no-hooks` only when you explicitly need to bypass that behavior.
|
|
178
178
|
|
|
179
179
|
## Example: Multi-feature implementation
|
|
180
180
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.85.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>
|
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import sys
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
from typing import Annotated
|
|
7
|
+
from typing import Annotated, Any
|
|
8
8
|
|
|
9
9
|
import typer
|
|
10
10
|
from rich.table import Table
|
|
@@ -93,7 +93,7 @@ def main(
|
|
|
93
93
|
set_process_title(ctx.invoked_subcommand)
|
|
94
94
|
|
|
95
95
|
|
|
96
|
-
def set_config_defaults(ctx: typer.Context, config_file: str | None) ->
|
|
96
|
+
def set_config_defaults(ctx: typer.Context, config_file: str | None) -> dict[str, Any]:
|
|
97
97
|
"""Set the default values for the CLI based on the config file."""
|
|
98
98
|
config = load_config(config_file)
|
|
99
99
|
wildcard_config = normalize_provider_defaults(config.get("defaults", {}))
|
|
@@ -101,7 +101,7 @@ def set_config_defaults(ctx: typer.Context, config_file: str | None) -> None:
|
|
|
101
101
|
command_key = ctx.command.name or ""
|
|
102
102
|
if not command_key:
|
|
103
103
|
ctx.default_map = wildcard_config
|
|
104
|
-
return
|
|
104
|
+
return config
|
|
105
105
|
|
|
106
106
|
# For nested subcommands (e.g., "memory proxy"), build "memory.proxy"
|
|
107
107
|
if ctx.parent and ctx.parent.command.name and ctx.parent.command.name != "agent-cli":
|
|
@@ -109,6 +109,7 @@ def set_config_defaults(ctx: typer.Context, config_file: str | None) -> None:
|
|
|
109
109
|
|
|
110
110
|
command_config = normalize_provider_defaults(config.get(command_key, {}))
|
|
111
111
|
ctx.default_map = {**wildcard_config, **command_config}
|
|
112
|
+
return config
|
|
112
113
|
|
|
113
114
|
|
|
114
115
|
# Import commands from other modules to register them
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""Helpers for reading runtime dev configuration."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
import click
|
|
8
|
+
|
|
9
|
+
from agent_cli.config import load_config
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_runtime_config() -> dict[str, Any]:
|
|
13
|
+
"""Return the config dict active for the current CLI invocation."""
|
|
14
|
+
ctx = click.get_current_context(silent=True)
|
|
15
|
+
while ctx is not None:
|
|
16
|
+
if isinstance(ctx.obj, dict) and isinstance(ctx.obj.get("config"), dict):
|
|
17
|
+
return ctx.obj["config"]
|
|
18
|
+
ctx = ctx.parent
|
|
19
|
+
return load_config(None)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_dev_config() -> dict[str, Any]:
|
|
23
|
+
"""Return the `[dev]` config table for the current CLI invocation."""
|
|
24
|
+
dev_config = get_runtime_config().get("dev", {})
|
|
25
|
+
return dev_config if isinstance(dev_config, dict) else {}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_dev_table(name: str) -> dict[str, Any]:
|
|
29
|
+
"""Return a merged `[dev.<name>]` table from nested or flattened config."""
|
|
30
|
+
result: dict[str, Any] = {}
|
|
31
|
+
|
|
32
|
+
nested = get_dev_config().get(name)
|
|
33
|
+
if isinstance(nested, dict):
|
|
34
|
+
result.update(nested)
|
|
35
|
+
|
|
36
|
+
flat = get_runtime_config().get(f"dev.{name}")
|
|
37
|
+
if isinstance(flat, dict):
|
|
38
|
+
result.update(flat)
|
|
39
|
+
|
|
40
|
+
return result
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def get_dev_child_tables(name: str) -> dict[str, dict[str, Any]]:
|
|
44
|
+
"""Return merged `[dev.<name>.<child>]` tables keyed by child name."""
|
|
45
|
+
result = {
|
|
46
|
+
child: value for child, value in get_dev_table(name).items() if isinstance(value, dict)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
prefix = f"dev.{name}."
|
|
50
|
+
for key, value in get_runtime_config().items():
|
|
51
|
+
if key.startswith(prefix) and isinstance(value, dict):
|
|
52
|
+
result[key[len(prefix) :]] = value
|
|
53
|
+
|
|
54
|
+
return result
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def get_dev_child_table(name: str, child: str) -> dict[str, Any]:
|
|
58
|
+
"""Return a single merged `[dev.<name>.<child>]` table."""
|
|
59
|
+
return get_dev_child_tables(name).get(child, {})
|
|
@@ -23,6 +23,7 @@ from . import cleanup, coding_agents, editors, terminals, worktree
|
|
|
23
23
|
from ._branch_name import AGENTS as BRANCH_NAME_AGENTS
|
|
24
24
|
from ._branch_name import generate_ai_branch_name, generate_random_branch_name
|
|
25
25
|
from ._output import error, info, success, warn
|
|
26
|
+
from .hooks import LaunchContext, prepare_agent_launch
|
|
26
27
|
from .launch import (
|
|
27
28
|
get_agent_env,
|
|
28
29
|
launch_agent,
|
|
@@ -83,7 +84,11 @@ def dev_callback(
|
|
|
83
84
|
Creates isolated working directories for each feature branch. Each worktree
|
|
84
85
|
has its own branch, allowing parallel development without stashing changes.
|
|
85
86
|
"""
|
|
86
|
-
set_config_defaults(ctx, config_file)
|
|
87
|
+
config = set_config_defaults(ctx, config_file)
|
|
88
|
+
if isinstance(ctx.obj, dict):
|
|
89
|
+
ctx.obj["config"] = config
|
|
90
|
+
else:
|
|
91
|
+
ctx.obj = {"config": config}
|
|
87
92
|
|
|
88
93
|
# The [dev] section config is intended for `dev new` options.
|
|
89
94
|
# Click expects subcommand defaults under ctx.default_map["new"].
|
|
@@ -134,6 +139,24 @@ def _require_available_agent(
|
|
|
134
139
|
return agent
|
|
135
140
|
|
|
136
141
|
|
|
142
|
+
def _resolve_prompt_text(
|
|
143
|
+
prompt: str | None,
|
|
144
|
+
*,
|
|
145
|
+
prompt_file: Path | None = None,
|
|
146
|
+
) -> str | None:
|
|
147
|
+
"""Resolve prompt text from CLI input and reject empty explicit prompts."""
|
|
148
|
+
if prompt_file is not None:
|
|
149
|
+
prompt = prompt_file.read_text().strip()
|
|
150
|
+
if not prompt:
|
|
151
|
+
error(f"Prompt file is empty: {prompt_file}")
|
|
152
|
+
return prompt
|
|
153
|
+
|
|
154
|
+
if prompt is not None and not prompt.strip():
|
|
155
|
+
error("--prompt cannot be empty")
|
|
156
|
+
|
|
157
|
+
return prompt
|
|
158
|
+
|
|
159
|
+
|
|
137
160
|
def _resolve_branch_name(
|
|
138
161
|
branch: str | None,
|
|
139
162
|
branch_name_mode: str,
|
|
@@ -372,6 +395,13 @@ def new(
|
|
|
372
395
|
help="Launch the agent in a specific multiplexer. Currently supported: tmux. When started outside tmux, creates or reuses a detached session and reports the pane handle",
|
|
373
396
|
),
|
|
374
397
|
] = None,
|
|
398
|
+
hooks: Annotated[
|
|
399
|
+
bool,
|
|
400
|
+
typer.Option(
|
|
401
|
+
"--hooks/--no-hooks",
|
|
402
|
+
help="Run built-in agent preparation (like Codex auto-trust) and configured pre-launch hooks before starting the agent",
|
|
403
|
+
),
|
|
404
|
+
] = True,
|
|
375
405
|
verbose: Annotated[
|
|
376
406
|
bool,
|
|
377
407
|
typer.Option(
|
|
@@ -406,9 +436,7 @@ def new(
|
|
|
406
436
|
- `dev new feature-x --from origin/develop` — Branch from develop instead
|
|
407
437
|
- `dev new feature-x --with-agent aider --with-editor cursor` — Specific tools
|
|
408
438
|
"""
|
|
409
|
-
|
|
410
|
-
if prompt_file is not None:
|
|
411
|
-
prompt = prompt_file.read_text().strip()
|
|
439
|
+
prompt = _resolve_prompt_text(prompt, prompt_file=prompt_file)
|
|
412
440
|
|
|
413
441
|
# If a prompt is provided, automatically enable agent mode
|
|
414
442
|
if prompt:
|
|
@@ -475,6 +503,18 @@ def new(
|
|
|
475
503
|
if resolved_agent and resolved_agent.is_available():
|
|
476
504
|
merged_args = merge_agent_args(resolved_agent, agent_args)
|
|
477
505
|
agent_env = get_agent_env(resolved_agent)
|
|
506
|
+
prepare_agent_launch(
|
|
507
|
+
LaunchContext(
|
|
508
|
+
agent=resolved_agent,
|
|
509
|
+
worktree_path=result.path,
|
|
510
|
+
repo_root=repo_root,
|
|
511
|
+
branch=result.branch,
|
|
512
|
+
worktree_name=result.path.name,
|
|
513
|
+
task_file=task_file,
|
|
514
|
+
agent_env=agent_env,
|
|
515
|
+
),
|
|
516
|
+
hooks_enabled=hooks,
|
|
517
|
+
)
|
|
478
518
|
agent_handle = launch_agent(
|
|
479
519
|
result.path,
|
|
480
520
|
resolved_agent,
|
|
@@ -916,6 +956,13 @@ def start_agent(
|
|
|
916
956
|
help="Launch the agent in a specific multiplexer instead of the current terminal. Currently supported: tmux",
|
|
917
957
|
),
|
|
918
958
|
] = None,
|
|
959
|
+
hooks: Annotated[
|
|
960
|
+
bool,
|
|
961
|
+
typer.Option(
|
|
962
|
+
"--hooks/--no-hooks",
|
|
963
|
+
help="Run built-in agent preparation (like Codex auto-trust) and configured pre-launch hooks before starting the agent",
|
|
964
|
+
),
|
|
965
|
+
] = True,
|
|
919
966
|
) -> None:
|
|
920
967
|
"""Start an AI coding agent in an existing dev environment.
|
|
921
968
|
|
|
@@ -928,9 +975,7 @@ def start_agent(
|
|
|
928
975
|
- `dev agent my-feature -a claude` — Start Claude specifically
|
|
929
976
|
- `dev agent my-feature -p "Continue the auth refactor"` — Start with a task
|
|
930
977
|
"""
|
|
931
|
-
|
|
932
|
-
if prompt_file is not None:
|
|
933
|
-
prompt = prompt_file.read_text().strip()
|
|
978
|
+
prompt = _resolve_prompt_text(prompt, prompt_file=prompt_file)
|
|
934
979
|
|
|
935
980
|
repo_root = _ensure_git_repo()
|
|
936
981
|
|
|
@@ -956,6 +1001,18 @@ def start_agent(
|
|
|
956
1001
|
|
|
957
1002
|
merged_args = merge_agent_args(agent, agent_args)
|
|
958
1003
|
agent_env = get_agent_env(agent)
|
|
1004
|
+
prepare_agent_launch(
|
|
1005
|
+
LaunchContext(
|
|
1006
|
+
agent=agent,
|
|
1007
|
+
worktree_path=wt.path,
|
|
1008
|
+
repo_root=repo_root,
|
|
1009
|
+
branch=wt.branch,
|
|
1010
|
+
worktree_name=wt.name,
|
|
1011
|
+
task_file=task_file,
|
|
1012
|
+
agent_env=agent_env,
|
|
1013
|
+
),
|
|
1014
|
+
hooks_enabled=hooks,
|
|
1015
|
+
)
|
|
959
1016
|
|
|
960
1017
|
if multiplexer:
|
|
961
1018
|
handle = launch_agent(
|
|
@@ -117,6 +117,17 @@ class CodingAgent(ABC):
|
|
|
117
117
|
"""Get any additional environment variables needed."""
|
|
118
118
|
return {}
|
|
119
119
|
|
|
120
|
+
def prepare_launch(
|
|
121
|
+
self,
|
|
122
|
+
worktree_path: Path, # noqa: ARG002
|
|
123
|
+
repo_root: Path, # noqa: ARG002
|
|
124
|
+
) -> str | None:
|
|
125
|
+
"""Perform any agent-specific preparation before launch.
|
|
126
|
+
|
|
127
|
+
Returns an optional human-readable message describing a change that was made.
|
|
128
|
+
"""
|
|
129
|
+
return None
|
|
130
|
+
|
|
120
131
|
def __repr__(self) -> str: # noqa: D105
|
|
121
132
|
status = "available" if self.is_available() else "not installed"
|
|
122
133
|
return f"<{self.__class__.__name__} {self.name!r} ({status})>"
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""OpenAI Codex CLI coding agent adapter."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from .base import CodingAgent
|
|
8
|
+
|
|
9
|
+
CODEX_CONFIG_PATH = Path.home() / ".codex" / "config.toml"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _project_section_header(path: Path) -> str:
|
|
13
|
+
"""Build the TOML section header for a trusted Codex project path."""
|
|
14
|
+
escaped = str(path).replace("\\", "\\\\").replace('"', '\\"')
|
|
15
|
+
return f'[projects."{escaped}"]'
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _ensure_project_trusted(project_path: Path, config_path: Path | None = None) -> bool:
|
|
19
|
+
"""Ensure Codex trusts the launched project path for headless launches.
|
|
20
|
+
|
|
21
|
+
Returns True when the config file was modified.
|
|
22
|
+
"""
|
|
23
|
+
project_path = project_path.expanduser().resolve()
|
|
24
|
+
config_path = (config_path or CODEX_CONFIG_PATH).expanduser()
|
|
25
|
+
header = _project_section_header(project_path)
|
|
26
|
+
trust_line = 'trust_level = "trusted"'
|
|
27
|
+
|
|
28
|
+
if not config_path.exists():
|
|
29
|
+
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
30
|
+
config_path.write_text(f"{header}\n{trust_line}\n", encoding="utf-8")
|
|
31
|
+
return True
|
|
32
|
+
|
|
33
|
+
text = config_path.read_text(encoding="utf-8")
|
|
34
|
+
lines = text.splitlines()
|
|
35
|
+
|
|
36
|
+
for idx, line in enumerate(lines):
|
|
37
|
+
if line.strip() != header:
|
|
38
|
+
continue
|
|
39
|
+
|
|
40
|
+
end = len(lines)
|
|
41
|
+
for j in range(idx + 1, len(lines)):
|
|
42
|
+
if lines[j].strip().startswith("[") and lines[j].strip().endswith("]"):
|
|
43
|
+
end = j
|
|
44
|
+
break
|
|
45
|
+
|
|
46
|
+
for j in range(idx + 1, end):
|
|
47
|
+
stripped = lines[j].strip()
|
|
48
|
+
if not stripped.startswith("trust_level"):
|
|
49
|
+
continue
|
|
50
|
+
if stripped == trust_line:
|
|
51
|
+
return False
|
|
52
|
+
msg = (
|
|
53
|
+
f"Codex trust for {project_path} is already configured in {config_path}. "
|
|
54
|
+
"Update that section or disable [dev].auto_trust."
|
|
55
|
+
)
|
|
56
|
+
raise RuntimeError(msg)
|
|
57
|
+
|
|
58
|
+
lines.insert(idx + 1, trust_line)
|
|
59
|
+
config_path.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
|
60
|
+
return True
|
|
61
|
+
|
|
62
|
+
new_text = text.rstrip("\n")
|
|
63
|
+
if new_text:
|
|
64
|
+
new_text += "\n\n"
|
|
65
|
+
new_text += f"{header}\n{trust_line}\n"
|
|
66
|
+
config_path.write_text(new_text, encoding="utf-8")
|
|
67
|
+
return True
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class Codex(CodingAgent):
|
|
71
|
+
"""OpenAI Codex CLI coding agent."""
|
|
72
|
+
|
|
73
|
+
name = "codex"
|
|
74
|
+
command = "codex"
|
|
75
|
+
install_url = "https://github.com/openai/codex"
|
|
76
|
+
detect_process_name = "codex"
|
|
77
|
+
|
|
78
|
+
def prompt_args(self, prompt: str) -> list[str]:
|
|
79
|
+
"""Return prompt as positional argument.
|
|
80
|
+
|
|
81
|
+
Codex accepts prompt as a positional argument:
|
|
82
|
+
`codex "your prompt here"`
|
|
83
|
+
|
|
84
|
+
See: codex --help
|
|
85
|
+
"""
|
|
86
|
+
return [prompt]
|
|
87
|
+
|
|
88
|
+
def prepare_launch(self, worktree_path: Path, repo_root: Path) -> str | None: # noqa: ARG002
|
|
89
|
+
"""Ensure Codex trusts the repository root before launch."""
|
|
90
|
+
if _ensure_project_trusted(repo_root, CODEX_CONFIG_PATH):
|
|
91
|
+
return f"Trusted {repo_root.resolve()} in Codex config"
|
|
92
|
+
return None
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""Launch preparation helpers for `agent-cli dev`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import shlex
|
|
7
|
+
import subprocess
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import TYPE_CHECKING, Any
|
|
11
|
+
|
|
12
|
+
from ._config import get_dev_child_table, get_dev_config, get_dev_table
|
|
13
|
+
from ._output import info
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from .coding_agents.base import CodingAgent
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass(frozen=True)
|
|
20
|
+
class LaunchContext:
|
|
21
|
+
"""Context provided to built-in preparation and user hooks."""
|
|
22
|
+
|
|
23
|
+
agent: CodingAgent
|
|
24
|
+
worktree_path: Path
|
|
25
|
+
repo_root: Path
|
|
26
|
+
branch: str | None
|
|
27
|
+
worktree_name: str
|
|
28
|
+
task_file: Path | None
|
|
29
|
+
agent_env: dict[str, str]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _normalize_hook_commands(value: Any, *, config_key: str) -> list[str]:
|
|
33
|
+
"""Normalize a hook config entry to a list of shell commands."""
|
|
34
|
+
if value is None:
|
|
35
|
+
return []
|
|
36
|
+
if isinstance(value, str):
|
|
37
|
+
value = [value]
|
|
38
|
+
if not isinstance(value, list) or not all(isinstance(item, str) for item in value):
|
|
39
|
+
msg = f"{config_key} must be a string or list of strings"
|
|
40
|
+
raise RuntimeError(msg)
|
|
41
|
+
commands = [item.strip() for item in value if item.strip()]
|
|
42
|
+
if len(commands) != len(value):
|
|
43
|
+
msg = f"{config_key} contains an empty command"
|
|
44
|
+
raise RuntimeError(msg)
|
|
45
|
+
return commands
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _load_dev_hook_settings(agent_name: str) -> tuple[bool, list[str]]:
|
|
49
|
+
"""Load auto-trust and pre-launch hook settings for an agent."""
|
|
50
|
+
auto_trust = bool(get_dev_config().get("auto_trust", True))
|
|
51
|
+
global_hooks = get_dev_table("hooks")
|
|
52
|
+
agent_hooks = get_dev_child_table("hooks", agent_name)
|
|
53
|
+
|
|
54
|
+
pre_launch_hooks = _normalize_hook_commands(
|
|
55
|
+
global_hooks.get("pre_launch"),
|
|
56
|
+
config_key="[dev.hooks].pre_launch",
|
|
57
|
+
)
|
|
58
|
+
pre_launch_hooks.extend(
|
|
59
|
+
_normalize_hook_commands(
|
|
60
|
+
agent_hooks.get("pre_launch"),
|
|
61
|
+
config_key=f"[dev.hooks.{agent_name}].pre_launch",
|
|
62
|
+
),
|
|
63
|
+
)
|
|
64
|
+
return auto_trust, pre_launch_hooks
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _build_hook_env(context: LaunchContext) -> dict[str, str]:
|
|
68
|
+
"""Build the environment passed to pre-launch hooks."""
|
|
69
|
+
env = os.environ.copy()
|
|
70
|
+
env.update(context.agent_env)
|
|
71
|
+
env.update(
|
|
72
|
+
{
|
|
73
|
+
"AGENT_CLI_AGENT": context.agent.name,
|
|
74
|
+
"AGENT_CLI_WORKTREE": str(context.worktree_path),
|
|
75
|
+
"AGENT_CLI_REPO_ROOT": str(context.repo_root),
|
|
76
|
+
"AGENT_CLI_BRANCH": context.branch or "",
|
|
77
|
+
"AGENT_CLI_NAME": context.worktree_name,
|
|
78
|
+
"AGENT_CLI_TASK_FILE": str(context.task_file or ""),
|
|
79
|
+
# Keep the proposal name as an alias for compatibility.
|
|
80
|
+
"AGENT_CLI_PROMPT_FILE": str(context.task_file or ""),
|
|
81
|
+
},
|
|
82
|
+
)
|
|
83
|
+
return env
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _resolve_hook_command(command: str) -> list[str]:
|
|
87
|
+
"""Parse a configured hook command into argv."""
|
|
88
|
+
argv = shlex.split(command)
|
|
89
|
+
if not argv:
|
|
90
|
+
msg = "Hook command cannot be empty"
|
|
91
|
+
raise RuntimeError(msg)
|
|
92
|
+
|
|
93
|
+
first = Path(argv[0]).expanduser()
|
|
94
|
+
if argv[0].startswith("~") or "/" in argv[0]:
|
|
95
|
+
argv[0] = str(first)
|
|
96
|
+
return argv
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _run_pre_launch_hook(command: str, context: LaunchContext) -> None:
|
|
100
|
+
"""Run a single pre-launch hook."""
|
|
101
|
+
argv = _resolve_hook_command(command)
|
|
102
|
+
info(f"Running pre-launch hook: {command}")
|
|
103
|
+
try:
|
|
104
|
+
result = subprocess.run(
|
|
105
|
+
argv,
|
|
106
|
+
cwd=context.worktree_path,
|
|
107
|
+
env=_build_hook_env(context),
|
|
108
|
+
check=False,
|
|
109
|
+
capture_output=True,
|
|
110
|
+
text=True,
|
|
111
|
+
)
|
|
112
|
+
except FileNotFoundError as e:
|
|
113
|
+
msg = f"Pre-launch hook not found: {argv[0]}"
|
|
114
|
+
raise RuntimeError(msg) from e
|
|
115
|
+
|
|
116
|
+
if result.returncode == 0:
|
|
117
|
+
return
|
|
118
|
+
|
|
119
|
+
details = (result.stderr or result.stdout).strip()
|
|
120
|
+
msg = f"Pre-launch hook failed ({result.returncode}): {command}"
|
|
121
|
+
if details:
|
|
122
|
+
msg += f"\n{details}"
|
|
123
|
+
raise RuntimeError(msg)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def prepare_agent_launch(context: LaunchContext, *, hooks_enabled: bool = True) -> None:
|
|
127
|
+
"""Run built-in preparation and configured pre-launch hooks."""
|
|
128
|
+
if not hooks_enabled:
|
|
129
|
+
return
|
|
130
|
+
|
|
131
|
+
auto_trust, pre_launch_hooks = _load_dev_hook_settings(context.agent.name)
|
|
132
|
+
if auto_trust and (
|
|
133
|
+
message := context.agent.prepare_launch(context.worktree_path, context.repo_root)
|
|
134
|
+
):
|
|
135
|
+
info(message)
|
|
136
|
+
|
|
137
|
+
for command in pre_launch_hooks:
|
|
138
|
+
_run_pre_launch_hook(command, context)
|
|
@@ -9,10 +9,10 @@ import tempfile
|
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
from typing import TYPE_CHECKING
|
|
11
11
|
|
|
12
|
-
from agent_cli.config import load_config
|
|
13
12
|
from agent_cli.core.utils import console
|
|
14
13
|
|
|
15
14
|
from . import coding_agents, editors, terminals, worktree
|
|
15
|
+
from ._config import get_dev_child_tables, get_dev_table
|
|
16
16
|
from ._output import success, warn
|
|
17
17
|
|
|
18
18
|
if TYPE_CHECKING:
|
|
@@ -95,15 +95,8 @@ def get_config_agent_args() -> dict[str, list[str]] | None:
|
|
|
95
95
|
Note: The config loader may flatten section names, so we check both
|
|
96
96
|
nested structure and flattened 'dev.agent_args' key.
|
|
97
97
|
"""
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
# First try the simple nested structure (for testing/mocks)
|
|
101
|
-
dev_config = config.get("dev", {})
|
|
102
|
-
if isinstance(dev_config, dict) and "agent_args" in dev_config:
|
|
103
|
-
return dev_config["agent_args"]
|
|
104
|
-
|
|
105
|
-
# Handle flattened key "dev.agent_args"
|
|
106
|
-
return config.get("dev.agent_args")
|
|
98
|
+
agent_args = get_dev_table("agent_args")
|
|
99
|
+
return agent_args or None
|
|
107
100
|
|
|
108
101
|
|
|
109
102
|
def get_config_agent_env() -> dict[str, dict[str, str]] | None:
|
|
@@ -117,22 +110,8 @@ def get_config_agent_env() -> dict[str, dict[str, str]] | None:
|
|
|
117
110
|
'dev.agent_env.claude' become top-level. We reconstruct the
|
|
118
111
|
agent_env dict from these flattened keys.
|
|
119
112
|
"""
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
# First try the simple nested structure (for testing/mocks)
|
|
123
|
-
dev_config = config.get("dev", {})
|
|
124
|
-
if isinstance(dev_config, dict) and "agent_env" in dev_config:
|
|
125
|
-
return dev_config["agent_env"]
|
|
126
|
-
|
|
127
|
-
# Handle flattened keys like "dev.agent_env.claude"
|
|
128
|
-
prefix = "dev.agent_env."
|
|
129
|
-
result: dict[str, dict[str, str]] = {}
|
|
130
|
-
for key, value in config.items():
|
|
131
|
-
if key.startswith(prefix) and isinstance(value, dict):
|
|
132
|
-
agent_name = key[len(prefix) :]
|
|
133
|
-
result[agent_name] = value
|
|
134
|
-
|
|
135
|
-
return result or None
|
|
113
|
+
agent_env = get_dev_child_tables("agent_env")
|
|
114
|
+
return agent_env or None
|
|
136
115
|
|
|
137
116
|
|
|
138
117
|
def get_agent_env(agent: CodingAgent) -> dict[str, str]:
|
|
@@ -174,7 +174,7 @@ agent-cli dev new validation-a --from HEAD --agent --with-agent codex -m tmux \
|
|
|
174
174
|
--prompt-file .claude/validation-a.md
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
-
This works without an attached terminal. `agent-cli` creates or reuses a detached tmux session and returns a pane handle plus attach command.
|
|
177
|
+
This works without an attached terminal. `agent-cli` creates or reuses a detached tmux session and returns a pane handle plus attach command. Launches may also run pre-launch preparation by default; use `--no-hooks` only when you explicitly need to bypass that behavior.
|
|
178
178
|
|
|
179
179
|
## Example: Multi-feature implementation
|
|
180
180
|
|
|
@@ -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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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,
|
|
@@ -191,6 +191,7 @@ enable_tts = true
|
|
|
191
191
|
# Defaults for `agent-cli dev new`
|
|
192
192
|
# editor = true
|
|
193
193
|
# agent = true
|
|
194
|
+
# auto_trust = true
|
|
194
195
|
# direnv = true
|
|
195
196
|
# setup = true
|
|
196
197
|
# copy_env = true
|
|
@@ -208,3 +209,9 @@ codex = ["--dangerously-bypass-approvals-and-sandbox"]
|
|
|
208
209
|
[dev.agent_env.claude]
|
|
209
210
|
# CLAUDE_CODE_USE_VERTEX = "1"
|
|
210
211
|
# ANTHROPIC_MODEL = "claude-opus-4-5"
|
|
212
|
+
|
|
213
|
+
[dev.hooks]
|
|
214
|
+
# pre_launch = ["~/.config/agent-cli/hooks/pre-launch.sh"]
|
|
215
|
+
|
|
216
|
+
[dev.hooks.codex]
|
|
217
|
+
# pre_launch = ["~/.config/agent-cli/hooks/codex-setup.sh"]
|