docs(readme,agents): updoot

Amolith created

Change summary

AGENTS.md | 230 +++++++++++++++++++++++++++++++++++++++++++++-----------
README.md |  98 +++++++++++++++++++----
2 files changed, 262 insertions(+), 66 deletions(-)

Detailed changes

AGENTS.md 🔗

@@ -13,7 +13,8 @@ This document helps AI agents work effectively with the synu codebase.
 **synu** is a universal wrapper for AI agents that tracks quota usage for [Synthetic](https://synthetic.new) API calls. It's written in Fish shell and provides:
 
 - Transparent quota tracking before/after agent execution
-- Agent-specific configuration system (e.g., model routing for Claude Code)
+- Agent-specific configuration system (model routing, API endpoints)
+- Persistent model preferences via cache file
 - Interactive model selection with `gum`
 - Passthrough mode for agents without special configuration
 
@@ -22,8 +23,13 @@ This document helps AI agents work effectively with the synu codebase.
 ```
 synu (main wrapper)
   ├─ _synu_get_quota (API quota fetching)
+  ├─ _synu_cache (model preference persistence)
   └─ _synu_agents/ (agent-specific configuration)
-      └─ claude.fish (Claude Code model configuration)
+      ├─ claude.fish  (Claude Code: env vars, multi-model)
+      ├─ opencode.fish (OpenCode: CLI args)
+      ├─ aider.fish    (Aider: env vars + CLI args)
+      ├─ llxprt.fish   (llxprt: CLI args only)
+      └─ qwen.fish     (Qwen Code: env vars)
 ```
 
 **Control Flow:**
@@ -32,12 +38,14 @@ synu (main wrapper)
 3. Parse agent-specific flags using `argparse` with `--ignore-unknown` for passthrough
 4. Configure agent environment (if agent has `_configure` function)
 5. Fetch initial quota from Synthetic API
-6. Execute agent with remaining arguments
-7. Fetch final quota and calculate/display session usage
+6. Execute agent with remaining arguments (plus any `_args` output)
+7. Clean up environment variables (if agent has `_env_vars` function)
+8. Fetch final quota and calculate/display session usage
 
 **Data Flow:**
 - Quota API → `_synu_get_quota` → space-separated "requests limit" string
 - Agent flags → `argparse` → `_flag_*` variables → agent `_configure` function
+- Cache file → `_synu_cache_get` → default model values
 - Interactive mode → `gum` + Synthetic API → model IDs → recursive `synu` call with flags
 
 ## File Structure
@@ -46,8 +54,13 @@ synu (main wrapper)
 ├── functions/
 │   ├── synu.fish              # Main wrapper function
 │   ├── _synu_get_quota.fish   # Private: Fetch quota from API
+│   ├── _synu_cache.fish       # Private: Model preference cache
 │   └── _synu_agents/
-│       └── claude.fish        # Claude Code agent configuration
+│       ├── claude.fish        # Claude Code agent configuration
+│       ├── opencode.fish      # OpenCode agent configuration
+│       ├── aider.fish         # Aider agent configuration
+│       ├── llxprt.fish        # llxprt agent configuration
+│       └── qwen.fish          # Qwen Code agent configuration
 ├── completions/
 │   └── synu.fish              # Shell completions
 ├── crush.json                 # LSP configuration (fish-lsp)
@@ -65,6 +78,7 @@ This is a Fish shell library with no build system. Key commands:
 # Source the function (from repo root)
 source functions/synu.fish
 source functions/_synu_get_quota.fish
+source functions/_synu_cache.fish
 
 # Check quota only
 synu
@@ -74,10 +88,14 @@ synu claude "What does this function do?"
 
 # Test interactive mode (requires gum)
 synu i claude "prompt"
+synu i opencode "prompt"
+synu i aider "prompt"
 
 # Test with model override flags
 synu claude --opus hf:some/model "prompt"
 synu claude --large hf:some/model "prompt"
+synu opencode --model hf:some/model "prompt"
+synu aider --model hf:some/model --editor-model hf:other/model "prompt"
 ```
 
 ### Installation Testing
@@ -95,7 +113,8 @@ fundle init
 # Validate Fish syntax
 fish -n functions/synu.fish
 fish -n functions/_synu_get_quota.fish
-fish -n functions/_synu_agents/claude.fish
+fish -n functions/_synu_cache.fish
+fish -n functions/_synu_agents/*.fish
 fish -n completions/synu.fish
 ```
 
@@ -110,12 +129,13 @@ The project includes `crush.json` configuring `fish-lsp` for Fish language suppo
 - **Indentation**: 4 spaces (no tabs)
 - **Variable naming**: `snake_case` with descriptive names
   - Private/local vars: `set -l var_name`
-  - Global vars: `set -g var_name` (agent defaults)
+  - Global vars: `set -g var_name` (agent defaults, selected models)
   - Exported vars: `set -gx VAR_NAME` (environment)
 - **Function naming**:
   - Public: `synu`
   - Private/helper: `_synu_*`
   - Agent-specific: `_synu_agent_<name>_<action>`
+  - Agent internal helpers: `_synu_<agent>_<helper>` (e.g., `_synu_claude_default`)
 - **Comments**: Use `#` for explanatory comments focusing on *why* not *what*
 - **Error handling**: Check `$status` after critical operations, return non-zero on errors
 - **Error output**: Use `>&2` for all error messages
@@ -123,30 +143,42 @@ The project includes `crush.json` configuring `fish-lsp` for Fish language suppo
 
 ### Agent Configuration Pattern
 
-Each agent definition in `functions/_synu_agents/<agent>.fish` can provide four functions:
+Each agent definition in `functions/_synu_agents/<agent>.fish` can provide five functions:
 
 1. **`_synu_agent_<name>_flags`** - Returns argparse flag specification (one per line)
    ```fish
    function _synu_agent_myagent_flags
-       echo "L/large="
-       echo "o/option="
+       echo "m/model="
+       echo "e/extra="
    end
    ```
 
-2. **`_synu_agent_<name>_configure`** - Sets environment variables before execution
+2. **`_synu_agent_<name>_configure`** - Sets environment variables and/or global state
    ```fish
    function _synu_agent_myagent_configure
-       argparse 'L/large=' 'o/option=' -- $argv
+       argparse 'm/model=' -- $argv
        or return 1
        
-       # Configure based on flags
-       if set -q _flag_large
-           set -gx AGENT_MODEL $_flag_large
+       # Configure based on flags (use cache or fallback for defaults)
+       set -g _synu_myagent_selected_model (_synu_myagent_default)
+       if set -q _flag_model
+           set -g _synu_myagent_selected_model $_flag_model
        end
+       
+       # Export env vars if agent uses them
+       set -gx AGENT_MODEL $_synu_myagent_selected_model
+   end
+   ```
+
+3. **`_synu_agent_<name>_args`** - Returns CLI arguments to inject (for agents that don't use env vars)
+   ```fish
+   function _synu_agent_myagent_args
+       echo --model
+       echo $_synu_myagent_selected_model
    end
    ```
 
-3. **`_synu_agent_<name>_env_vars`** - Returns list of environment variables to clean up after execution
+4. **`_synu_agent_<name>_env_vars`** - Returns list of environment variables to clean up after execution
    ```fish
    function _synu_agent_myagent_env_vars
        echo AGENT_MODEL
@@ -154,24 +186,70 @@ Each agent definition in `functions/_synu_agents/<agent>.fish` can provide four
    end
    ```
 
-4. **`_synu_agent_<name>_interactive`** - Implements interactive model selection
+5. **`_synu_agent_<name>_interactive`** - Implements interactive model selection
    ```fish
    function _synu_agent_myagent_interactive
        # Use gum to get user input
        set -l selection (gum choose "option1" "option2")
        or return 1
        
+       # Optionally save to cache
+       if gum confirm "Save as default?"
+           _synu_cache_set myagent model $selection
+       end
+       
        # Return flags to pass to main synu call
-       echo --option=$selection
+       echo --model=$selection
    end
    ```
 
+**Agent Configuration Patterns:**
+
+| Agent | Configuration Method | Notes |
+|-------|---------------------|-------|
+| claude | Environment variables | Multi-model (opus, sonnet, haiku, subagent) |
+| qwen | Environment variables | Single model |
+| aider | Env vars + CLI args | Env for API, CLI for models |
+| opencode | CLI args only | Uses `synthetic/` prefix in model |
+| llxprt | CLI args only | Needs --provider, --baseurl flags |
+
 **Important patterns:**
 - Agents without definitions work as passthrough (no special config)
 - Use `argparse --ignore-unknown` in main wrapper so agent-native flags pass through
 - Interactive functions return flags that trigger recursive `synu` call
 - Configure functions receive flags already parsed from `_flag_*` variables
 - Environment variables listed in `_env_vars` are automatically unset after agent exits
+- Use `_synu_cache_get`/`_synu_cache_set` for persistent model preferences
+
+### Cache System
+
+The cache stores model preferences in `$XDG_CONFIG_HOME/synu/models.conf` (or `~/.config/synu/models.conf`).
+
+**Format:**
+```
+# synu model preferences
+# Format: agent.slot = model_id
+
+claude.opus = hf:moonshotai/Kimi-K2-Thinking
+claude.sonnet = hf:MiniMaxAI/MiniMax-M2
+opencode.model = hf:MiniMaxAI/MiniMax-M2
+```
+
+**Functions:**
+- `_synu_cache_get agent slot` - Returns cached value or fails
+- `_synu_cache_set agent slot value` - Creates/updates cache entry
+
+**Pattern for using cache with fallbacks:**
+```fish
+function _synu_myagent_default --description "Get default model"
+    set -l cached (_synu_cache_get myagent model)
+    if test $status -eq 0
+        echo $cached
+    else
+        echo $_synu_myagent_fallback_model  # Hardcoded fallback
+    end
+end
+```
 
 ### API Integration
 
@@ -179,6 +257,7 @@ Each agent definition in `functions/_synu_agents/<agent>.fish` can provide four
 - Quota: `GET https://api.synthetic.new/v2/quotas`
 - Models: `GET https://api.synthetic.new/openai/v1/models`
 - Claude routing: `https://api.synthetic.new/anthropic`
+- OpenAI-compatible: `https://api.synthetic.new/openai/v1`
 
 **Authentication**: Bearer token via `Authorization: Bearer $SYNTHETIC_API_KEY`
 
@@ -194,7 +273,9 @@ Each agent definition in `functions/_synu_agents/<agent>.fish` can provide four
 
 2. **Flag variables after argparse**: After `argparse`, the `$argv` variable contains only non-flag arguments. Rebuild flag arguments from `_flag_*` variables to pass to configure function.
 
-3. **Preserve argument order**: When executing the agent with `command $agent $agent_args`, all original arguments (except synu-specific flags) must pass through unchanged.
+3. **Preserve argument order**: When executing the agent with `command $agent $extra_args $agent_args`, all original arguments (except synu-specific flags) must pass through unchanged.
+
+4. **The `_args` function output is inserted before user args**: This allows agent-specific flags to be set while still allowing user to pass additional flags.
 
 ### Quota Tracking Edge Cases
 
@@ -207,18 +288,27 @@ Each agent definition in `functions/_synu_agents/<agent>.fish` can provide four
 ### Environment Variable Scoping
 
 - Use `set -gx` for environment variables that need to be visible to child processes (the actual agent binary)
-- Agent defaults use `set -g` (global but not exported)
+- Agent defaults and selected models use `set -g` (global but not exported)
 - Local calculations use `set -l`
+- Environment variables are cleaned up after execution via `_env_vars`
 
 ### Interactive Mode Flow
 
 Interactive mode (`synu i <agent> [args...]`) works by:
 1. Calling agent's `_interactive` function to get flags
-2. Recursively calling `synu <agent> <flags> [args...]` (non-interactive)
-3. The recursive call then follows normal path with pre-parsed flags
+2. Optionally saving selections to cache (user prompted)
+3. Recursively calling `synu <agent> <flags> [args...]` (non-interactive)
+4. The recursive call then follows normal path with pre-parsed flags
 
 This means the `_configure` function must handle both direct flag input and flags from interactive mode identically.
 
+### Model ID Prefixes
+
+Different agents expect different model ID formats:
+- **opencode**: Prefix with `synthetic/` (e.g., `synthetic/hf:moonshotai/Kimi-K2`)
+- **aider**: Prefix with `openai/` (e.g., `openai/hf:moonshotai/Kimi-K2`)
+- **claude, qwen, llxprt**: Use raw model ID (e.g., `hf:moonshotai/Kimi-K2`)
+
 ### Fish-specific Considerations
 
 - **Status checks**: Always use `test $status -ne 0` immediately after command, as any subsequent command overwrites `$status`
@@ -226,6 +316,7 @@ This means the `_configure` function must handle both direct flag input and flag
 - **Command substitution**: Use `(command)` not `$(command)`
 - **String operations**: Use `string` builtin (`string split`, `string match`)
 - **No `local` keyword**: Use `set -l` for local scope
+- **Variable indirection**: Use `$$var_name` to get value of variable named by `$var_name`
 
 ## Testing Approach
 
@@ -234,15 +325,17 @@ This project has no automated test suite. Testing is manual:
 1. **Syntax validation**: Run `fish -n` on all `.fish` files
 2. **Quota tracking**: Run `synu` alone, check quota display with color
 3. **Passthrough**: Test with unknown agent (`synu echo "hello"`)
-4. **Agent config**: Test Claude with/without flags
-5. **Interactive mode**: Test `synu i claude` with gum installed
-6. **Error cases**: Test without `SYNTHETIC_API_KEY`, with invalid API key
+4. **Agent config**: Test each agent with/without flags
+5. **Interactive mode**: Test `synu i <agent>` with gum installed
+6. **Cache persistence**: Test that interactive selections save correctly
+7. **Error cases**: Test without `SYNTHETIC_API_KEY`, with invalid API key
 
 **When making changes:**
 - Validate syntax with `fish -n`
 - Source the function and test manually with different argument combinations
 - Check that exit status is preserved
 - Verify quota display shows correct before/after values
+- Test cache file creation and updates
 
 ## Common Tasks
 
@@ -250,17 +343,22 @@ This project has no automated test suite. Testing is manual:
 
 1. Create `functions/_synu_agents/<agent>.fish`
 2. Add SPDX header
-3. Define `_synu_agent_<agent>_flags` (return argparse flag specs)
-4. Define `_synu_agent_<agent>_configure` (set environment variables)
-5. Optionally define `_synu_agent_<agent>_interactive` (for `synu i <agent>`)
-6. Update `completions/synu.fish` to add the new agent to suggestions
-7. Test manually
+3. Source cache functions: `source (status dirname)/../_synu_cache.fish`
+4. Define fallback default: `set -g _synu_<agent>_fallback_model "hf:..."`
+5. Define `_synu_<agent>_default` helper (uses cache with fallback)
+6. Define `_synu_agent_<agent>_flags` (return argparse flag specs)
+7. Define `_synu_agent_<agent>_configure` (set state/env vars)
+8. Define `_synu_agent_<agent>_args` (if agent uses CLI args for model)
+9. Define `_synu_agent_<agent>_env_vars` (if agent uses env vars)
+10. Optionally define `_synu_agent_<agent>_interactive` (for `synu i <agent>`)
+11. Update `completions/synu.fish` to add the new agent to suggestions
+12. Test manually
 
 ### Modifying Quota Display
 
 Quota display logic is in two places:
-- **No args case**: lines 6-28 of `synu.fish`
-- **Post-execution**: lines 128-166 of `synu.fish`
+- **No args case**: `synu.fish` lines ~7-29
+- **Post-execution**: `synu.fish` lines ~162-180
 
 Both use the same color thresholds:
 - Green: < 33% used
@@ -279,19 +377,50 @@ _synu_get_quota
 # Test with curl directly
 curl -s -f -H "Authorization: Bearer $SYNTHETIC_API_KEY" \
     "https://api.synthetic.new/v2/quotas" | jq .
+
+# Test model listing
+curl -s -H "Authorization: Bearer $SYNTHETIC_API_KEY" \
+    "https://api.synthetic.new/openai/v1/models" | jq '.data[].name'
 ```
 
-### Understanding Model Configuration Flow (Claude)
+### Debugging Cache Issues
+
+```fish
+# Check cache file location
+echo $XDG_CONFIG_HOME/synu/models.conf
+# or
+echo ~/.config/synu/models.conf
+
+# View cache contents
+cat ~/.config/synu/models.conf
+
+# Test cache functions
+source functions/_synu_cache.fish
+_synu_cache_set test model hf:test/model
+_synu_cache_get test model
+```
 
+### Understanding Model Configuration Flow
+
+**Example: Claude with flag override**
 1. User runs: `synu claude --large hf:some/model "prompt"`
 2. `synu.fish` loads `functions/_synu_agents/claude.fish`
-3. Calls `_synu_agent_claude_flags` to get flag spec: `L/large=`, `o/opus=`, etc.
+3. Calls `_synu_agent_claude_flags` to get flag spec
 4. Parses with `argparse --ignore-unknown` → sets `_flag_large`
 5. Rebuilds flags for configure: `--large=hf:some/model`
 6. Calls `_synu_agent_claude_configure --large=hf:some/model`
-7. Configure sets `ANTHROPIC_DEFAULT_OPUS_MODEL`, `ANTHROPIC_DEFAULT_SONNET_MODEL`, etc.
-8. Executes `command claude "prompt"` with those environment variables
-9. Claude Code sees Synthetic models via env vars and uses them
+7. Configure sets opus/sonnet/subagent models from flag
+8. Exports `ANTHROPIC_*` environment variables
+9. Executes `command claude "prompt"` with those environment variables
+10. Claude Code sees Synthetic models via env vars and uses them
+11. After exit, env vars are cleaned up via `_env_vars`
+
+**Example: OpenCode with CLI args**
+1. User runs: `synu opencode "prompt"`
+2. `synu.fish` loads `functions/_synu_agents/opencode.fish`
+3. `_configure` sets `_synu_opencode_selected_model` from cache/fallback
+4. `_args` returns: `--model synthetic/hf:MiniMaxAI/MiniMax-M2`
+5. Executes: `command opencode -m "synthetic/hf:..." "prompt"`
 
 ## Commit Conventions
 
@@ -302,6 +431,7 @@ Use **Conventional Commits** with type and scope:
 **Scopes:**
 - `synu` - main wrapper function
 - `quota` - quota fetching/display
+- `cache` - model preference caching
 - `agents/<name>` - specific agent configuration (e.g., `agents/claude`)
 - `completions` - shell completions
 - `docs` - documentation
@@ -311,6 +441,7 @@ Use **Conventional Commits** with type and scope:
 feat(synu): add support for model override flags
 fix(quota): handle API errors gracefully
 feat(agents/claude): add interactive model selection
+feat(cache): implement persistent model preferences
 docs(readme): document interactive mode
 ```
 
@@ -338,26 +469,31 @@ Synthetic provides a unified API for multiple LLM providers with quota tracking.
 - **Graceful degradation**: If quota tracking fails, still run the agent
 - **Extensible**: Easy to add new agent configurations without modifying core wrapper
 - **Interactive when helpful**: Support both CLI flags and TUI selection
+- **Persistent preferences**: Save model selections for future sessions
+
+### Configured Agents
+
+Agents with specific configurations in `functions/_synu_agents/`:
 
-### Known Agents
+| Agent | Models | Configuration Method | Interactive |
+|-------|--------|---------------------|-------------|
+| claude | opus, sonnet, haiku, subagent | Environment variables | Yes |
+| opencode | single | CLI args | Yes |
+| aider | main, editor | Env + CLI args | Yes |
+| llxprt | single | CLI args | Yes |
+| qwen | single | Environment variables | Yes |
 
-Suggested in completions (may or may not have specific configurations):
-- `claude` - Claude Code (has configuration)
-- `crush` - Crush agent (passthrough)
-- `amp` - Amp agent (passthrough)
-- `octo` - Octo agent (passthrough)
-- `codex` - Codex agent (passthrough)
+Passthrough agents (no config, just quota tracking): crush, amp, octo, codex
 
-Any command can be wrapped, these are just suggestions for completion.
+Any command can be wrapped; the above are just agents with explicit configuration.
 
 ## Future Considerations
 
 Potential enhancements (not currently implemented):
-- Cache quota between rapid calls to reduce API hits
 - Support for other quota tracking APIs besides Synthetic
 - Agent-specific usage tracking/history
 - Budget warnings/limits
-- More agent configurations (crush, amp, etc.)
+- More agent configurations
 
 When implementing features, maintain the core principles:
 - Don't break passthrough mode

README.md 🔗

@@ -46,8 +46,10 @@ Use `synu` as a wrapper for any AI agent:
 # Check current quota
 synu
 
-# Use with claude (auto-configured for Synthetic)
+# Use with configured agents (auto-routed through Synthetic)
 synu claude "What does functions/synu.fish do?"
+synu opencode "Help me refactor this"
+synu aider "Fix the bug in main.go"
 
 # Use with other agents (passthrough with quota tracking)
 synu crush "Help me write code"
@@ -56,18 +58,36 @@ synu crush "Help me write code"
 synu [agent-name] [agent-args...]
 ```
 
-### Claude Code Configuration
+> **Note**: synu's configuration is ephemeral and non-invasive. Running `synu claude` routes requests through Synthetic, but running `claude` directly still uses Anthropic's API with your normal configuration. synu never modifies the agent's own config files.
 
-When using Claude Code through synu, the following models are configured by default:
+### Interactive Model Selection
 
-| Tier | Model |
-|------|-------|
+Use `synu i <agent>` to interactively select models using gum:
+
+```fish
+synu i claude "prompt"
+synu i opencode "prompt"
+synu i aider "prompt"
+```
+
+This presents a TUI to filter and select from available Synthetic models. You'll be prompted to save your selection as the default for future sessions.
+
+### Persistent Preferences
+
+Model selections made in interactive mode can be saved to `~/.config/synu/models.conf`. These become the new defaults until changed. Command-line flags always override saved preferences.
+
+## Configured Agents
+
+### Claude Code
+
+| Tier | Default Model |
+|------|---------------|
 | Opus | `hf:moonshotai/Kimi-K2-Thinking` |
 | Sonnet | `hf:MiniMaxAI/MiniMax-M2` |
 | Haiku | `hf:deepseek-ai/DeepSeek-V3.1-Terminus` |
 | Subagent | `hf:MiniMaxAI/MiniMax-M2` |
 
-#### Override Models with Flags
+**Override flags:**
 
 ```fish
 # Override specific models
@@ -81,41 +101,81 @@ synu claude --large hf:model "prompt"  # Sets Opus, Sonnet, and Subagent
 synu claude --light hf:model "prompt"  # Sets Haiku
 ```
 
-#### Interactive Model Selection
+### OpenCode
 
-Use `synu i <agent>` to interactively select models using gum:
+| Default Model |
+|---------------|
+| `hf:MiniMaxAI/MiniMax-M2` |
 
 ```fish
-synu i claude "prompt"
+synu opencode --model hf:other/model "prompt"
 ```
 
-This will present a TUI to choose between group or individual model selection, then let you filter and select from available Synthetic models.
+### Aider
+
+| Slot | Default Model |
+|------|---------------|
+| Main | `hf:MiniMaxAI/MiniMax-M2` |
+| Editor | (none - single model mode) |
 
-### How it works
+```fish
+# Single model mode
+synu aider --model hf:some/model "prompt"
+
+# Architect + editor mode (two models)
+synu aider --model hf:architect/model --editor-model hf:editor/model "prompt"
+```
+
+### llxprt
+
+| Default Model |
+|---------------|
+| `hf:MiniMaxAI/MiniMax-M2` |
+
+```fish
+synu llxprt --model hf:other/model "prompt"
+```
+
+### Qwen Code
+
+| Default Model |
+|---------------|
+| `hf:MiniMaxAI/MiniMax-M2` |
+
+```fish
+synu qwen --model hf:other/model "prompt"
+```
+
+## How it works
 
 `synu` works by:
 
-1. Loading agent-specific configuration if available (e.g., Claude Code model defaults)
+1. Loading agent-specific configuration if available
 2. Fetching initial quota from the Synthetic API before running the agent
-3. Executing the specified agent with all provided arguments
-4. Fetching final quota after the agent completes
-5. Calculating and displaying session usage
+3. Configuring the agent's environment/CLI args to route through Synthetic
+4. Executing the specified agent with all provided arguments
+5. Cleaning up environment variables after execution
+6. Fetching final quota and displaying session usage
 
-The quota tracking requires the `SYNTHETIC_API_KEY` environment variable to be set. Without it, `synu` will still work but will show a warning and skip quota tracking.
+The quota tracking requires the `SYNTHETIC_API_KEY` environment variable. Without it, `synu` will show a warning and skip quota tracking, but still attempt to run the agent.
 
 ### Adding Support for New Agents
 
 Agent definitions are stored in `functions/_synu_agents/`. Each agent file can define:
 
 - `_synu_agent_<name>_flags` - Returns argparse flag specification
-- `_synu_agent_<name>_configure` - Sets environment variables before execution
+- `_synu_agent_<name>_configure` - Sets environment variables/state before execution
+- `_synu_agent_<name>_args` - Returns CLI arguments to inject
+- `_synu_agent_<name>_env_vars` - Lists environment variables to clean up
 - `_synu_agent_<name>_interactive` - Implements interactive model selection
 
 Agents without definitions work as passthrough with quota tracking.
 
+See `AGENTS.md` for detailed implementation guidance.
+
 ## Shell completions
 
-Synu includes fish shell completions for better usability.
+Synu includes fish shell completions for configured agents and their flags.
 
 ## Contributions
 
@@ -144,4 +204,4 @@ See "How do Patch Requests work?" on [pr.pico.sh]'s home page for a more
 complete example workflow.
 
 [amolith/llm-projects]: https://pr.pico.sh/r/amolith/llm-projects
-[pr.pico.sh]: https://pr.pico.sh
+[pr.pico.sh]: https://pr.pico.sh