AGENTS.md
Project Overview
synclaude.fish is a Fish shell wrapper for the claude CLI that routes requests through Synthetic.new's API. It enables using alternative AI models through the Claude CLI by proxying requests through Synthetic's Anthropic-compatible endpoint.
Key Functionality
- Configurable model defaults for each Claude tier with persistent caching
- Provides interactive TUI for model selection using
gum - Supports group-based (
--heavy/--medium/--light) and individual model overrides - Displays session API usage and remaining quota after each run
synclaude ushows current quota usage- Wraps
claudeCLI completely - all unknown flags pass through
Default Models (Fallbacks)
- Opus:
hf:moonshotai/Kimi-K2-Thinking - Sonnet:
hf:zai-org/GLM-4.6 - Haiku:
hf:deepseek-ai/DeepSeek-V3.1-Terminus - Sub-agent:
hf:zai-org/GLM-4.6
Architecture
Control Flow:
- Usage mode (
synclaude u):- Fetches and displays current quota usage with colored badge
- Interactive mode (
synclaude i):- Fetches available models from Synthetic API
- Prompts user to choose Groups vs Individual models
- Prompts for which groups/models to override
- Shows current defaults in filter headers
- Offers to save selections as new defaults
- Recursively calls
synclaudewith generated flags
- Flag-based mode (default):
- Parses custom flags with
argparse --ignore-unknown - Loads defaults from cache (or fallbacks)
- Applies group then individual overrides
- Sets environment variables for Anthropic endpoint
- Fetches initial quota from Synthetic API
- Executes
command claude $argv - Fetches final quota and displays usage stats with badge-style color-coding
- Parses custom flags with
Key Design Patterns:
- Caching: Persistent model preferences stored in
~/.config/synclaude/models.conf - Override precedence: Individual flags override group flags, which override cached/fallback defaults
- Error propagation: Uses
or returnthroughout to exit on command failures
Common Gotchas
argparse --ignore-unknownis critical: Without it, unknown flags would error instead of passing through toclaude- Recursive call must use function name, not alias:
synclaudenotcommand synclaude- this works because Fish functions can recursively invoke themselves _flag_*variable naming:argparsecreates variables from flag names with_flag_prefix - must use exact names- Model ID vs Model Name: Interactive mode fetches model names for display but must extract model IDs for API use
- jq requires argument quoting: In jq, use
--arg name "$var"then$namein filter - don't interpolate directly into filter string - Quota check timing: Initial quota fetch happens before
clauderuns to calculate session usage. If it fails, script continues anyway mathprecision: Use-s0for integer output to avoid decimal points in quota percentages- Local exports don't persist:
set -lxvariables only exist in function scope - won't affect parent shell - Cache file location: Respects
XDG_CONFIG_HOMEif set, otherwise defaults to~/.config/synclaude/