plugins/multimodel/skills/claudish-usage/SKILL.md
Routes Claudish between MCP tools (team, create_session for /team and /delegate) and the CLI for direct usage. Use when the user mentions claudish, OpenRouter, or external AI models.
npx skillsauth add madappgang/magus claudish-usageInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Version: 1.1.0 Purpose: Guide AI agents on how to use Claudish CLI to run Claude Code with OpenRouter models Status: Production Ready
In orchestration workflows, use claudish MCP tools — NOT Bash+CLI:
team MCP tool — run prompt across multiple models in parallelcreate_session MCP tool — start a single async sessionget_output — retrieve session outputsend_input — answer interactive questionsreport_error — report failuresMCP sessions run externally — no context window pollution.
For direct user-facing tasks outside orchestration workflows, the claudish CLI is the standard interface. See CLI sections below.
User Request
↓
Orchestration workflow (/team, /delegate, multi-model vote)? → YES → Use MCP tools
↓ NO
↓
Direct task (user says "use Grok to implement X")? → Use /delegate command (MCP-based)
↓
Direct CLI usage (user debugging, testing models)? → CLI is fine
All commands that use external models (/team, /delegate, /dev:fix, etc.) MUST resolve model names through this three-step chain before calling claudish.
Step 1: INTERPRET (Claude Code LLM)
User says anything → Claude infers which alias key they mean
"use Elon's model" → "grok"
"the Google one" → "gemini"
"fast coding model" → "grok" (fast_coding role)
"grok" → "grok" (exact match)
"gpt-5.4" → "gpt-5.4" (not an alias — pass through)
Step 2: RESOLVE (Magus alias table lookup)
ALIAS_TABLE[key] → full model ID
"grok" → "grok-4.20-beta"
"gemini" → "gemini"
"gpt-5.4" → not in table → pass through as-is
Step 3: ROUTE (Claudish)
Full model ID → correct provider API endpoint
"grok-4.20-beta" → xAI API
"gemini" → Google API
"gpt-5.4" → OpenAI API
shared/model-aliases.json → extract shortAliases object.claude/multimodel-team.json → extract customAliases object (may be absent)ALIAS_TABLE = { ...shortAliases, ...customAliases } — user overrides globalshared/model-aliases.json doesn't exist → tell user: "Run /update-models"For each model name after Step 1 interpretation:
ALIAS_TABLE[name] exists → use the mapped value"internal" is never sent to claudish — it means host Claude modelClaude Code uses its language understanding to map natural language to alias keys. The ALIAS_TABLE keys are the ONLY valid targets for interpretation. Examples:
| User says | Claude infers alias | Why |
|---|---|---|
| "grok" | "grok" | Exact alias match |
| "use gemini for this" | "gemini" | Direct name mention |
| "Elon's AI" / "xAI model" | "grok" | Company/person association |
| "Google's model" | "gemini" | Company association |
| "OpenAI's model" | "gpt" | Company association |
| "the cheap one" | Check roles.free_tier | Cost-based intent |
| "something fast for coding" | Check roles.fast_coding | Capability-based intent |
| "minimax-m2.7" | Not an alias → pass through | Already a full model ID |
When uncertain, list ALIAS_TABLE keys and ask the user to pick.
| Responsibility | Owner |
|---|---|
| Understanding user intent → alias key | Claude Code (LLM heuristic) |
| Alias key → full model ID | Magus (ALIAS_TABLE lookup) |
| User custom aliases | Magus (.claude/multimodel-team.json customAliases) |
| Full model ID → API endpoint | Claudish (provider routing) |
| API keys, vendor prefixes, fallbacks | Claudish |
customAliases always override global shortAliases on key conflictWhen user requests Claudish task, follow this process:
general-purpose agent if user declinesNote: In orchestration workflows, external models are invoked via claudish MCP tools (team, create_session). The agent is resolved by the orchestrator and set via Task tool for internal models. External models receive context through the vote prompt.
| Task Type | Recommended Agent | Alternatives | Notes |
|-----------|----------------------|--------------|-------|
| Investigation | dev:researcher | code-analysis:detective | For finding bugs, tracing issues |
| Code review | agentdev:reviewer | frontend:reviewer | Check if plugin has review agent |
| Architecture | dev:architect | frontend:architect | Design and planning tasks |
| Implementation | dev:developer | frontend:developer | Building features |
| Testing | dev:test-architect | — | Test strategy and coverage |
| Debugging | dev:debugger | — | Error analysis and tracing |
| Documentation | dev:researcher | — | Simple task, researcher works |
| UI/Design | dev:ui | frontend:designer | Visual and UX tasks |
Template response:
I notice you want to use [Model Name] for [task type].
RECOMMENDATION: Create a specialized [task type] agent with proxy mode support.
This would:
✅ Provide better task-specific guidance
✅ Reusable for future [task type] tasks
✅ Optimized prompting for [Model Name]
Options:
1. Create specialized agent (recommended) - takes 2-3 minutes
2. Use generic general-purpose agent - works but less optimized
3. Run directly in main context (NOT recommended - pollutes context)
Which would you prefer?
Frontend Plugin:
typescript-frontend-dev - Use for UI implementation with external modelsfrontend-architect - Use for architecture planning with external modelssenior-code-reviewer - Use for code review (can delegate to external models)test-architect - Use for test planning/implementationBun Backend Plugin:
backend-developer - Use for API implementation with external modelsapi-architect - Use for API design with external modelsCode Analysis Plugin:
codebase-detective - Use for investigation tasks with external modelsNo Plugin:
general-purpose - Default fallback for any taskExample 1: User says "use Grok to implement authentication"
Task: Code implementation (authentication)
Plugin: Bun Backend (if backend) or Frontend (if UI)
Decision:
1. Check for backend-developer or typescript-frontend-dev agent
2. Found backend-developer? → Use it with Grok proxy
3. Not found? → Offer to create custom auth agent
4. User declines? → Use general-purpose with file-based pattern
Example 2: User says "ask GPT-5 to review my API design"
Task: Code review (API design)
Plugin: Bun Backend
Decision:
1. Check for api-architect or senior-code-reviewer agent
2. Found? → Use it with GPT-5 proxy
3. Not found? → Use general-purpose with review instructions
4. Never run directly in main context
Example 3: User says "use Gemini to refactor this component"
Task: Refactoring (component)
Plugin: Frontend
Decision:
1. No specialized refactoring agent exists
2. Offer to create component-refactoring agent
3. User declines? → Use typescript-frontend-dev with proxy
4. Still no agent? → Use general-purpose with file-based pattern
When used with the /team command for multi-model blind voting:
External models are invoked via the team MCP tool:
claudish team(mode="run", path=SESSION_DIR, models=["grok", "gemini"],
input=VOTE_PROMPT, timeout=180, claude_flags=claudeFlags)
The team tool runs all models in parallel internally and returns structured per-model results.
The agent role is communicated through the vote prompt content.
Claudish is a CLI tool that allows running Claude Code with any OpenRouter model (Grok, GPT-5, MiniMax, Gemini, etc.) by proxying requests through a local Anthropic API-compatible server.
Key Principle: ALWAYS use Claudish through sub-agents with file-based instructions to avoid context window pollution.
Claudish (Claude-ish) is a proxy tool that:
Use Cases:
CRITICAL: Claudish supports MULTIPLE backends, not just OpenRouter. The model ID prefix determines which backend processes your request.
| Prefix | Backend | Required API Key | Example Model ID |
|--------|---------|------------------|------------------|
| (none) | OpenRouter | OPENROUTER_API_KEY | anthropic/claude-3.5-sonnet |
| or/ | OpenRouter (explicit) | OPENROUTER_API_KEY | google/gemini-3-pro-preview |
| g/ gemini/ google/ | Google Gemini Direct | GEMINI_API_KEY | g/gemini-2.0-flash |
| oai/ openai/ | OpenAI Direct | OPENAI_API_KEY | oai/gpt-4o |
| ollama/ ollama: | Ollama (local) | None | ollama/llama3.2 |
| lmstudio/ | LM Studio (local) | None | lmstudio/qwen2.5-coder |
| vllm/ | vLLM (local) | None | vllm/mistral-7b |
| mlx/ | MLX (local) | None | mlx/llama-3.2-3b |
| http://... | Custom endpoint | None | http://192.168.1.50:8000/model |
CRITICAL: Some OpenRouter model IDs START with prefixes that claudish interprets as direct API routing!
| Model ID | Claudish Routes To | Problem | Fix |
|----------|-------------------|---------|-----|
| google/gemini-3-pro-preview | Google Gemini Direct | Needs GEMINI_API_KEY, different API | Use gemini |
| gemini | Google Gemini Direct | Needs GEMINI_API_KEY, different API | Use gemini |
| gpt | OpenAI Direct | Needs OPENAI_API_KEY, different API | Use gpt |
| gpt | OpenAI Direct | Needs OPENAI_API_KEY, different API | Use gpt |
These OpenRouter model IDs are SAFE to use without the or/ prefix:
grok - No x-ai/ prefix in claudishanthropic/claude-3.5-sonnet - No anthropic/ prefix in claudishdeepseek/deepseek-chat - No deepseek/ prefix in claudishminimax - No minimax/ prefix in claudishqwen/qwen3-coder:free - No qwen/ prefix in claudishmistralai/devstral-2512:free - No mistralai/ prefix in claudishmoonshotai/kimi-k2-thinking - No moonshotai/ prefix in claudishor/ PrefixALWAYS use or/ prefix when:
google/, openai/, g/, oai/Examples:
# WRONG - Routes to Google Gemini Direct (needs GEMINI_API_KEY)
claudish --model google/gemini-3-pro-preview
# CORRECT - Use alias instead
claudish --model gemini
# SAFE - No collision (x-ai/ is not a routing prefix)
claudish --model grok
OPENROUTER_API_KEY environment variable)npm install -g claudish or bun install -g claudish# OpenRouter (required for most models)
export OPENROUTER_API_KEY='sk-or-v1-...'
# Google Gemini Direct (optional - for g/gemini/google/ prefixed models)
export GEMINI_API_KEY='AIza...'
# OpenAI Direct (optional - for oai/openai/ prefixed models)
export OPENAI_API_KEY='sk-...'
# Note: Ollama, LM Studio, vLLM, MLX backends don't need API keys
# Optional (but recommended)
export ANTHROPIC_API_KEY='sk-ant-api03-placeholder' # Prevents Claude Code dialog
# Optional - default model
export CLAUDISH_MODEL='grok' # or ANTHROPIC_MODEL
Get OpenRouter API Key:
# With npm (works everywhere)
npm install -g claudish
# With Bun (faster)
bun install -g claudish
# Verify installation
claudish --version
# Read the local model aliases file (synced from Firebase via /update-models)
cat shared/model-aliases.json
# Shows shortAliases (short names → full IDs), roles, teams, and knownModels sections
# Run /update-models to refresh from the queryPluginDefaults Firebase API
# Search available models (still works, fetches from OpenRouter API)
claudish --models gemini
claudish --models "grok code"
# Force update from OpenRouter API
claudish --models --force-update
Interactive Mode (default):
# Shows model selector, persistent session
claudish
Single-shot Mode:
# One task and exit (requires --model)
claudish --model grok "implement user authentication"
With stdin for large prompts:
# Read prompt from stdin (useful for git diffs, code review)
git diff | claudish --stdin --model gpt "Review these changes"
Top Models for Development (verified from OpenRouter):
grok - xAI's Grok (fast coding, visible reasoning)
gemini - Google's Gemini (state-of-the-art reasoning)
minimax - MiniMax M2 (high performance)
gpt - OpenAI's GPT-5 (advanced reasoning)
qwen/qwen3-vl-235b-a22b-instruct - Alibaba's Qwen (vision-language)
Get Latest Models:
# Read the authoritative model aliases file (primary source)
cat shared/model-aliases.json
# Search for specific models (fetches from OpenRouter API)
claudish --models grok
claudish --models "gemini flash"
# Force immediate update from OpenRouter
claudish --models --force-update
Simple task (direct prompt):
claudish --model grok "create button component"
Complex task (file-based with --stdin):
# Write instructions to file, pipe via --stdin
claudish --model grok --stdin < multi-phase-workflow.md
Note: The
--agentflag was removed in claudish v4.5.1. Agent specialization is now handled through the vote prompt content or Claude Code's own agent system.
Why: Running Claudish directly in main conversation pollutes context window with:
Solution: Use file-based sub-agent pattern
Step 1: Create instruction file
# /tmp/claudish-task-{timestamp}.md
## Task
Implement user authentication with JWT tokens
## Requirements
- Use bcrypt for password hashing
- Generate JWT with 24h expiration
- Add middleware for protected routes
## Deliverables
Write implementation to: /tmp/claudish-result-{timestamp}.md
## Output Format
```markdown
## Implementation
[code here]
## Files Created/Modified
- path/to/file1.ts
- path/to/file2.ts
## Tests
[test code if applicable]
## Notes
[any important notes]
**Step 2: Run Claudish with file instruction**
```bash
# Read instruction from file, write result to file
claudish --model grok --stdin < /tmp/claudish-task-{timestamp}.md > /tmp/claudish-result-{timestamp}.md
Step 3: Read result file and provide summary
// In your agent/command:
const result = await Read({ file_path: "/tmp/claudish-result-{timestamp}.md" });
// Parse result
const filesModified = extractFilesModified(result);
const summary = extractSummary(result);
// Provide short feedback to main agent
return `✅ Task completed. Modified ${filesModified.length} files. ${summary}`;
/**
* Example: Run code review with Grok via Claudish sub-agent
*/
async function runCodeReviewWithGrok(files: string[]) {
const timestamp = Date.now();
const instructionFile = `/tmp/claudish-review-instruction-${timestamp}.md`;
const resultFile = `/tmp/claudish-review-result-${timestamp}.md`;
// Step 1: Create instruction file
const instruction = `# Code Review Task
## Files to Review
${files.map(f => `- ${f}`).join('\n')}
## Review Criteria
- Code quality and maintainability
- Potential bugs or issues
- Performance considerations
- Security vulnerabilities
## Output Format
Write your review to: ${resultFile}
Use this format:
\`\`\`markdown
## Summary
[Brief overview]
## Issues Found
### Critical
- [issue 1]
### Medium
- [issue 2]
### Low
- [issue 3]
## Recommendations
- [recommendation 1]
## Files Reviewed
- [file 1]: [status]
\`\`\`
`;
await Write({ file_path: instructionFile, content: instruction });
// Step 2: Run Claudish with stdin
await Bash(`claudish --model grok --stdin < ${instructionFile}`);
// Step 3: Read result
const result = await Read({ file_path: resultFile });
// Step 4: Parse and return summary
const summary = extractSummary(result);
const issueCount = extractIssueCount(result);
// Step 5: Clean up temp files
await Bash(`rm ${instructionFile} ${resultFile}`);
// Step 6: Return concise feedback
return {
success: true,
summary,
issueCount,
fullReview: result // Available if needed, but not in main context
};
}
function extractSummary(review: string): string {
const match = review.match(/## Summary\s*\n(.*?)(?=\n##|$)/s);
return match ? match[1].trim() : "Review completed";
}
function extractIssueCount(review: string): { critical: number; medium: number; low: number } {
const critical = (review.match(/### Critical\s*\n(.*?)(?=\n###|$)/s)?.[1].match(/^-/gm) || []).length;
const medium = (review.match(/### Medium\s*\n(.*?)(?=\n###|$)/s)?.[1].match(/^-/gm) || []).length;
const low = (review.match(/### Low\s*\n(.*?)(?=\n###|$)/s)?.[1].match(/^-/gm) || []).length;
return { critical, medium, low };
}
When running Claudish from an agent, use the Task tool to create a sub-agent:
/**
* Example: Delegate implementation to Grok via Claudish
*/
async function implementFeatureWithGrok(featureDescription: string) {
// Use Task tool to create sub-agent
const result = await Task({
subagent_type: "general-purpose",
description: "Implement feature with Grok",
prompt: `
Use Claudish CLI to implement this feature with Grok model:
${featureDescription}
INSTRUCTIONS:
1. Search for available models:
claudish --models grok
2. Run implementation with Grok:
claudish --model grok "${featureDescription}"
3. Return ONLY:
- List of files created/modified
- Brief summary (2-3 sentences)
- Any errors encountered
DO NOT return the full conversation transcript or implementation details.
Keep your response under 500 tokens.
`
});
return result;
}
/**
* Example: Use file-based instruction pattern in sub-agent
*/
async function analyzeCodeWithGemini(codebasePath: string) {
const timestamp = Date.now();
const instructionFile = `/tmp/claudish-analyze-${timestamp}.md`;
const resultFile = `/tmp/claudish-analyze-result-${timestamp}.md`;
// Create instruction file
const instruction = `# Codebase Analysis Task
## Codebase Path
${codebasePath}
## Analysis Required
- Architecture overview
- Key patterns used
- Potential improvements
- Security considerations
## Output
Write analysis to: ${resultFile}
Keep analysis concise (under 1000 words).
`;
await Write({ file_path: instructionFile, content: instruction });
// Delegate to sub-agent
const result = await Task({
subagent_type: "general-purpose",
description: "Analyze codebase with Gemini",
prompt: `
Use Claudish to analyze codebase with Gemini model.
Instruction file: ${instructionFile}
Result file: ${resultFile}
STEPS:
1. Read instruction file: ${instructionFile}
2. Run: claudish --model gemini --stdin < ${instructionFile}
3. Wait for completion
4. Read result file: ${resultFile}
5. Return ONLY a 2-3 sentence summary
DO NOT include the full analysis in your response.
The full analysis is in ${resultFile} if needed.
`
});
// Read full result if needed
const fullAnalysis = await Read({ file_path: resultFile });
// Clean up
await Bash(`rm ${instructionFile} ${resultFile}`);
return {
summary: result,
fullAnalysis
};
}
/**
* Example: Run same task with multiple models and compare
*/
async function compareModels(task: string, models: string[]) {
const results = [];
for (const model of models) {
const timestamp = Date.now();
const resultFile = `/tmp/claudish-${model.replace('/', '-')}-${timestamp}.md`;
// Run task with each model
await Task({
subagent_type: "general-purpose",
description: `Run task with ${model}`,
prompt: `
Use Claudish to run this task with ${model}:
${task}
STEPS:
1. Run: claudish --model ${model} --json "${task}"
2. Parse JSON output
3. Return ONLY:
- Cost (from total_cost_usd)
- Duration (from duration_ms)
- Token usage (from usage.input_tokens and usage.output_tokens)
- Brief quality assessment (1-2 sentences)
DO NOT return full output.
`
});
results.push({
model,
resultFile
});
}
return results;
}
# Fast, agentic coding with visible reasoning
claudish --model grok "add error handling to api routes"
# Advanced reasoning for complex tasks
claudish --model gpt "refactor authentication system to use OAuth2"
# Vision-language model for UI tasks
claudish --model qwen/qwen3-vl-235b-a22b-instruct "implement dashboard from figma design"
# State-of-the-art reasoning for thorough review
git diff | claudish --stdin --model gemini "Review these changes for bugs and improvements"
# Run same task with multiple models
for model in "grok" "gemini" "gpt"; do
echo "=== Testing with $model ==="
claudish --model "$model" "find security vulnerabilities in auth.ts"
done
| Flag | Description | Example |
|------|-------------|---------|
| --model <model> | OpenRouter model to use | --model grok |
| --stdin | Read prompt from stdin | git diff \| claudish --stdin --model grok |
| --models | List all models or search | claudish --models or claudish --models gemini |
| --top-models | ~~Show top recommended models~~ (deprecated — use shared/model-aliases.json) | cat shared/model-aliases.json |
| --json | JSON output (implies --quiet) | claudish --json "task" |
| --help-ai | Print AI agent usage guide | claudish --help-ai |
| Flag | Description | Default |
|------|-------------|---------|
| --interactive / -i | Interactive mode | Auto (no prompt = interactive) |
| --quiet / -q | Suppress log messages | Quiet in single-shot |
| --verbose / -v | Show log messages | Verbose in interactive |
| --debug / -d | Enable debug logging to file | Disabled |
| --port <port> | Proxy server port | Random (3000-9000) |
| --no-auto-approve | Require permission prompts | Auto-approve enabled |
| --dangerous | Disable sandbox | Disabled |
| --monitor | Proxy to real Anthropic API (debug) | Disabled |
| --force-update | Force refresh model cache | Auto (>2 days) |
Quiet Mode (default in single-shot)
claudish --model grok "task"
# Clean output, no [claudish] logs
Verbose Mode
claudish --verbose "task"
# Shows all [claudish] logs for debugging
JSON Mode
claudish --json "task"
# Structured output: {result, cost, usage, duration}
Claudish automatically tracks costs in the status line:
directory • model-id • $cost • ctx%
Example:
my-project • grok • $0.12 • 67%
Shows:
JSON Output Cost:
claudish --json "task" | jq '.total_cost_usd'
# Output: 0.068
Error:
Error: OPENROUTER_API_KEY environment variable is required
Fix:
export OPENROUTER_API_KEY='sk-or-v1-...'
# Or add to ~/.zshrc or ~/.bashrc
Error:
command not found: claudish
Fix:
npm install -g claudish
# Or: bun install -g claudish
Error:
Model 'invalid/model' not found
Fix:
# Check available models in the aliases file
cat shared/model-aliases.json
# Or search via OpenRouter API
claudish --models
# Use valid model ID
claudish --model grok "task"
Error:
OpenRouter API error: 401 Unauthorized
Fix:
Error:
Error: Port 3000 already in use
Fix:
# Let Claudish pick random port (default)
claudish --model grok "task"
# Or specify different port
claudish --port 8080 --model grok "task"
Why: Avoids context window pollution
How:
# Write instruction to file
echo "Implement feature X" > /tmp/task.md
# Run with stdin
claudish --stdin --model grok < /tmp/task.md > /tmp/result.md
# Read result
cat /tmp/result.md
Fast Coding: grok
Complex Reasoning: gemini or gpt
Vision/UI: qwen/qwen3-vl-235b-a22b-instruct
Why: Structured output, easier parsing
How:
RESULT=$(claudish --json "task" | jq -r '.result')
COST=$(claudish --json "task" | jq -r '.total_cost_usd')
Why: Keeps main conversation context clean
How:
await Task({
subagent_type: "general-purpose",
description: "Task with Claudish",
prompt: "Use claudish --model grok '...' and return summary only"
});
Why: Get latest model recommendations
How:
# Run /update-models command to sync from Firebase queryPluginDefaults API
# This writes to shared/model-aliases.json
# Then read the authoritative list:
cat shared/model-aliases.json
# Search for specific models via OpenRouter (supplemental)
claudish --models deepseek
# Force update from OpenRouter now
claudish --models --force-update
Why: Avoid command line length limits
How:
git diff | claudish --stdin --model grok "Review changes"
This is the #1 mistake. Never do this unless user explicitly requests it.
WRONG - Destroys context window:
// ❌ NEVER DO THIS - Pollutes main context with 10K+ tokens
await Bash("claudish --model grok 'implement feature'");
// ❌ NEVER DO THIS - Full conversation in main context
await Bash("claudish --model gemini 'review code'");
// ❌ NEVER DO THIS - Even with --json, output is huge
const result = await Bash("claudish --json --model gpt-5 'refactor'");
RIGHT - Always use sub-agents:
// ✅ ALWAYS DO THIS - Delegate to sub-agent
const result = await Task({
subagent_type: "general-purpose", // or specific agent
description: "Implement feature with Grok",
prompt: `
Use Claudish to implement the feature with Grok model.
CRITICAL INSTRUCTIONS:
1. Create instruction file: /tmp/claudish-task-${Date.now()}.md
2. Write detailed task requirements to file
3. Run: claudish --model grok --stdin < /tmp/claudish-task-*.md
4. Read result file and return ONLY a 2-3 sentence summary
DO NOT return full implementation or conversation.
Keep response under 300 tokens.
`
});
// ✅ Even better - Use specialized agent if available
const result = await Task({
subagent_type: "backend-developer", // or frontend-dev, etc.
description: "Implement with external model",
prompt: `
Use Claudish with grok model to implement authentication.
Follow file-based instruction pattern.
Return summary only.
`
});
When you CAN run directly (rare exceptions):
// ✅ Only when user explicitly requests
// User: "Run claudish directly in main context for debugging"
if (userExplicitlyRequestedDirect) {
await Bash("claudish --model grok 'task'");
}
Wrong:
# Always using default model
claudish "any task"
Right:
# Choose appropriate model
claudish --model grok "quick fix"
claudish --model gemini "complex analysis"
Wrong:
OUTPUT=$(claudish --model grok "task")
COST=$(echo "$OUTPUT" | grep cost | awk '{print $2}')
Right:
# Use JSON output
COST=$(claudish --json --model grok "task" | jq -r '.total_cost_usd')
Wrong:
const MODELS = ["grok", "gpt"];
Right:
// Read from the authoritative model aliases file
const aliases = JSON.parse(await Bun.file("shared/model-aliases.json").text());
const models = Object.keys(aliases.knownModels);
Problem: User provides a custom model ID that's not in shared/model-aliases.json
Wrong (rejecting custom models):
const availableModels = ["grok", "gpt"];
const userModel = "custom/provider/model-123";
if (!availableModels.includes(userModel)) {
throw new Error("Model not in my shortlist"); // ❌ DON'T DO THIS
}
Right (accept any valid model ID):
// Claudish accepts ANY valid OpenRouter model ID, even if not in shared/model-aliases.json
const userModel = "custom/provider/model-123";
// Validate it's a non-empty string with provider format
if (!userModel.includes("/")) {
console.warn("Model should be in format: provider/model-name");
}
// Use it directly - Claudish will validate with OpenRouter
await Bash(`claudish --model ${userModel} "task"`);
Why: Users may have access to:
Always accept user-provided model IDs unless they're clearly invalid (empty, wrong format).
Scenario: User says "use my custom model X" and expects it to be remembered
Solution 1: Environment Variable (Recommended)
// Set for the session
process.env.CLAUDISH_MODEL = userPreferredModel;
// Or set permanently in user's shell profile
await Bash(`echo 'export CLAUDISH_MODEL="${userPreferredModel}"' >> ~/.zshrc`);
Solution 2: Session Cache
// Store in a temporary session file
const sessionFile = "/tmp/claudish-user-preferences.json";
const prefs = {
preferredModel: userPreferredModel,
lastUsed: new Date().toISOString()
};
await Write({ file_path: sessionFile, content: JSON.stringify(prefs, null, 2) });
// Load in subsequent commands
const { stdout } = await Read({ file_path: sessionFile });
const prefs = JSON.parse(stdout);
const model = prefs.preferredModel || defaultModel;
Solution 3: Prompt Once, Remember for Session
// In a multi-step workflow, ask once
if (!process.env.CLAUDISH_MODEL) {
const aliases = JSON.parse(await Bun.file("shared/model-aliases.json").text());
const models = Object.entries(aliases.knownModels).map(([id, info]) => ({ id, ...(info as object) }));
const response = await AskUserQuestion({
question: "Select model (or enter custom model ID):",
options: models.map((m) => ({ label: m.id, value: m.id })).concat([
{ label: "Enter custom model...", value: "custom" }
])
});
if (response === "custom") {
const customModel = await AskUserQuestion({
question: "Enter OpenRouter model ID (format: provider/model):"
});
process.env.CLAUDISH_MODEL = customModel;
} else {
process.env.CLAUDISH_MODEL = response;
}
}
// Use the selected model for all subsequent calls
const model = process.env.CLAUDISH_MODEL;
await Bash(`claudish --model ${model} "task 1"`);
await Bash(`claudish --model ${model} "task 2"`);
Guidance for Agents:
shared/model-aliases.json contains curated model recommendations (run /update-models to refresh)In orchestration workflows, use MCP tools with proper error handling:
// Use create_session and react to channel events
create_session(model="grok", prompt=TASK, timeout_seconds=300)
// On "failed" channel event → STOP and REPORT
// "Grok failed: {error content}. Options: (1) Retry, (2) Different model, (3) Skip, (4) Cancel"
// On "completed" → get_output(session_id)
❌ NEVER do silent fallback:
// ❌ WRONG — silently substitutes a different model on failure
// If create_session fails for Gemini, don't silently run with embedded Claude instead
// ALWAYS report the failure and let the user decide
/**
* Agent: code-reviewer (using Claudish with multiple models)
*/
async function reviewCodeWithMultipleModels(files: string[]) {
const models = [
"grok", // Fast initial scan
"gemini", // Deep analysis
"gpt" // Final validation
];
const reviews = [];
for (const model of models) {
const timestamp = Date.now();
const instructionFile = `/tmp/review-${model.replace('/', '-')}-${timestamp}.md`;
const resultFile = `/tmp/review-result-${model.replace('/', '-')}-${timestamp}.md`;
// Create instruction
const instruction = createReviewInstruction(files, resultFile);
await Write({ file_path: instructionFile, content: instruction });
// Run review with model
await Bash(`claudish --model ${model} --stdin < ${instructionFile}`);
// Read result
const result = await Read({ file_path: resultFile });
// Extract summary
reviews.push({
model,
summary: extractSummary(result),
issueCount: extractIssueCount(result)
});
// Clean up
await Bash(`rm ${instructionFile} ${resultFile}`);
}
return reviews;
}
/**
* Command: /implement-with-model
* Usage: /implement-with-model "feature description"
*/
async function implementWithModel(featureDescription: string) {
// Step 1: Get available models from the authoritative aliases file
const aliases = JSON.parse(await Bun.file("shared/model-aliases.json").text());
const models = Object.entries(aliases.knownModels).map(([id, info]) => ({ id, ...(info as object) }));
// Step 2: Let user select model
const selectedModel = await promptUserForModel(models);
// Step 3: Create instruction file
const timestamp = Date.now();
const instructionFile = `/tmp/implement-${timestamp}.md`;
const resultFile = `/tmp/implement-result-${timestamp}.md`;
const instruction = `# Feature Implementation
## Description
${featureDescription}
## Requirements
- Write clean, maintainable code
- Add comprehensive tests
- Include error handling
- Follow project conventions
## Output
Write implementation details to: ${resultFile}
Include:
- Files created/modified
- Code snippets
- Test coverage
- Documentation updates
`;
await Write({ file_path: instructionFile, content: instruction });
// Step 4: Run implementation
await Bash(`claudish --model ${selectedModel} --stdin < ${instructionFile}`);
// Step 5: Read and present results
const result = await Read({ file_path: resultFile });
// Step 6: Clean up
await Bash(`rm ${instructionFile} ${resultFile}`);
return result;
}
Symptoms: Claudish takes long time to respond
Solutions:
grok or minimaxSymptoms: Unexpected API costs
Solutions:
shared/model-aliases.json or with claudish --models)--cost-trackerclaudish --json "task" | jq '.total_cost_usd'Symptoms: Error about token limits
Solutions:
Symptoms: "Model not found" error
Solutions:
claudish --models --force-updateDocumentation:
claudish --help-aiExternal Links:
npm install -g claudishVersion Information:
claudish --version
Get Help:
claudish --help # CLI usage
claudish --help-ai # AI agent usage guide
Maintained by: MadAppGang Last Updated: November 25, 2025 Skill Version: 1.1.0
testing
A test skill for validation testing. Use when testing skill parsing and validation logic.
tools
--- name: bad-skill description: This skill has invalid YAML in frontmatter allowed-tools: [invalid, array, syntax prerequisites: not-an-array --- # Bad Skill This skill has malformed frontmatter that should fail parsing. The YAML has: - Unclosed array bracket - Wrong type for prerequisites (should be array, not string)
development
Sync model aliases from the curated Firebase database. Fetches default model assignments, short aliases, team compositions, and known model metadata from the claudish API. Run this to get fresh model recommendations.
tools
Release one or more Magus plugins to the distribution repos (magus, magus-alpha, magus-marketing). Handles version inference from git history, marketplace.json updates, tagging, and force-push to lean dist repos. Use whenever the user says "release kanban", "release the dev plugin", "cut a new version of gtd", "bump kanban to 1.7", or hands you a batch like "release kanban and gtd". Also use for multi-plugin releases and for checking what a release would contain before committing.