Conversation
Plugin Version StatusVersions are auto-bumped in PRs. Manual bumps to higher versions are preserved.
|
… comprehensive skills New plugin that auto-configures Claude Code to route through a LiteLLM proxy on session start. Supports local/remote proxy modes, Cloudflare AI Gateway, and multi-provider routing with observability. Plugin includes: - SessionStart hook for proxy detection and ANTHROPIC_BASE_URL configuration - 5 skills: setup-litellm, configure-providers, configure-observability, configure-remote-proxy, configure-claude-code - Config template for LiteLLM proxy with all major providers - Plugin settings with env var, 1Password, and literal secret resolution - Support for pass-through (/anthropic) and unified endpoints https://claude.ai/code/session_01KqUVPTGpmvGdPSu9ZeQxNe
…-write Replace settings.local.json writes with CLAUDE_ENV_FILE exports, which is the proper session-scoped mechanism for SessionStart hooks. Remove the safe-settings-write.sh shared lib dependency. https://claude.ai/code/session_01KqUVPTGpmvGdPSu9ZeQxNe
…d secret resolution Create shared/lib/plugin-config.sh providing: - plugin_config(): three-level YAML config resolution (project → user → plugin defaults) - plugin_resolve_secret(): env var, 1Password, and literal secret resolution - plugin_is_enabled(): convenience check Update litellm-proxy and datadog-otel-setup to use the shared lib instead of duplicating read_config_key/get_config/resolve_secret functions inline. https://claude.ai/code/session_01KqUVPTGpmvGdPSu9ZeQxNe
Rename plugin directory, plugin.json name, YAML config keys, settings file, log prefixes, and all documentation references. https://claude.ai/code/session_01KqUVPTGpmvGdPSu9ZeQxNe
5501022 to
57b9113
Compare
There was a problem hiding this comment.
❌ Two blocking issues remain unaddressed since prior reviews: camelCase settings keys and symlinks for shared libs
❌ Settings keys use snake_case — must be camelCase per repo convention (thread)
❌ plugin-config.sh is a copy in poc-litellm-proxy/lib/ and mise/lib/ — should be symlinks (thread 1, thread 2 in this review)
⚠️ memory.jsonl has stale observations after refactoring (thread)
⚠️ write_env quoting could break on special characters (thread)
✅ Secure secret resolution via indirect expansion, no eval
✅ Plugin structure follows conventions (hooks.json, skills, plugin.json)
✅ CLAUDE_ENV_FILE usage is the correct session-scoped pattern
✅ Config resolution chain (project → user → plugin defaults) is clean
✅ Graceful degradation when yq/curl/docker not available
🖱️ Click to expand for full details
❌
plugin-config.sh is a copy in poc-litellm-proxy/lib/ and mise/lib/ — should be symlinks (thread 1, thread 2 in this review)memory.jsonl has stale observations after refactoring (thread)write_env quoting could break on special characters (thread)✅ Secure secret resolution via indirect expansion, no eval
✅ Plugin structure follows conventions (hooks.json, skills, plugin.json)
✅ CLAUDE_ENV_FILE usage is the correct session-scoped pattern
✅ Config resolution chain (project → user → plugin defaults) is clean
✅ Graceful degradation when yq/curl/docker not available
No Code Changes Since Last Review
The only new commit (59526c9) is a merge from main. All plugin code is unchanged from 32fde1f. The two blocking issues and three warnings from the previous review remain unaddressed.
Code Quality (70%)
The plugin itself is well-structured with solid shell scripting practices. Two convention violations keep the score down:
1. Settings key naming (❌ blocking): All multi-word settings keys use snake_case (proxy_host, proxy_port, master_key, config_path, remote_url, anthropic_pass_through) but .claude/rules/settings-key-naming.md explicitly requires camelCase. This affects the settings YAML, session-start.sh plugin_config() calls, README, and all 5 skill files. Keys should be: proxyHost, proxyPort, masterKey, configPath, remoteUrl, anthropicPassThrough.
2. Shared lib copies instead of symlinks (❌ blocking): Both plugins/poc-litellm-proxy/lib/plugin-config.sh and plugins/mise/lib/plugin-config.sh are regular files (mode 100755, 4400 bytes each) — not symlinks. Per .claude/rules/shared-libs.md: "Symlink into each plugin that needs it." All other shared libs in the repo follow this pattern.
Security (95%)
Strong practices throughout:
- Secret resolution uses
${!var_name:-}(indirect expansion) — noeval, no command injection vectors - Regex anchoring (
^\$\{...\}$) ensures only full env var references are matched - API keys never stored in plugin source
- Environment variables set via
CLAUDE_ENV_FILE(session-scoped, not persisted) - 1Password integration (
op://) for enterprise secret management
Simplicity (90%)
Code is straightforward and avoids over-engineering. Functions are small and focused. The case statement for mode handling is easy to follow. The config resolution chain is a clean pattern.
Confidence (95%)
Verified via git log that no plugin code changed since the last review (only a merge from main). Confirmed file types with ls -la (regular files, not symlinks). Cross-referenced all 16 existing review threads and their resolution states. All 5 previous reviews minimized as outdated.
Previous Review Status
| Previous Issue | Current Status |
|---|---|
safe-settings-write.sh copy vs symlink |
✅ Resolved — refactored to CLAUDE_ENV_FILE |
plugin-config.sh copy vs symlink |
❌ Still unaddressed |
| camelCase settings keys | ❌ Still unaddressed |
memory.jsonl stale observations |
|
write_env quoting concern |
|
| Docker image inspect perf | ⏳ Non-blocking, unchanged |
Recommended follow-ups (non-blocking):
- The Docker
image inspectcheck incheck_litellm_installed()could be slow if the daemon is unresponsive. Consider a timeout or caching if users report slow session starts. - Consider adding
yqtomise.tomlsince this plugin and the shared config lib depend on it (even though they degrade gracefully without it). - The existing
shared/lib/plugin-config-read.shalso provides config reading. Consider documenting the relationship or consolidating with the newplugin-config.sh.
There was a problem hiding this comment.
❌ Same DRY issue: this should be a symlink, not a copy.
This file is a byte-for-byte copy of shared/lib/plugin-config.sh (both 4400 bytes, same git blob 2a2502e). Per .claude/rules/shared-libs.md: "Symlink into each plugin that needs it."
All other shared libs in the repo use symlinks (e.g., safe-settings-write.sh → ../../../shared/lib/safe-settings-write.sh).
See also: same issue on poc-litellm-proxy/lib/plugin-config.sh
Fix:
rm plugins/mise/lib/plugin-config.sh
ln -s ../../../shared/lib/plugin-config.sh plugins/mise/lib/plugin-config.sh
What
Added a new
litellm-proxyClaude Code plugin that auto-detects and configures a LiteLLM proxy on session start. The plugin includes:session-start.sh) that detects running LiteLLM proxies (local or remote) and automatically configures Claude Code to route through themsetup-litellm: Install and start LiteLLM proxyconfigure-providers: Add/manage LLM providers (Anthropic, OpenAI, Gemini, Bedrock, Azure, etc.)configure-observability: Set up traces, logs, and metrics (Langfuse, OpenTelemetry, Datadog, Prometheus)configure-claude-code: Wire Claude Code to use the proxyconfigure-remote-proxy: Connect to remote proxies or Cloudflare AI Gatewaysafe-settings-write.sh) for atomic, concurrent-safe settings file updatesWhy
LiteLLM is a powerful AI gateway that enables:
This plugin makes it seamless for Claude Code users to leverage LiteLLM without manual configuration, while providing comprehensive guides for advanced setup scenarios.
How
The implementation follows the Claude Code plugin architecture:
ANTHROPIC_BASE_URLandANTHROPIC_AUTH_TOKENto~/.claude/settings.local.json${VAR_NAME}), 1Password references (op://vault/item/field), and literal valuesValidation steps
.claude-plugin/plugin.json, hooks, skills)Additional Context
This plugin enables the use case where users want to:
The plugin gracefully handles missing proxies (auto mode) and provides clear guidance through skills when setup is needed.
https://claude.ai/code/session_01KqUVPTGpmvGdPSu9ZeQxNe