@yeshwanthyk/coding-agent
v0.3.19
Published
Terminal-native coding agent with multi-provider support, extensible tooling, and LSP integration.
Readme
Marvin
Terminal-native coding agent with multi-provider support, extensible tooling, and LSP integration.
Install
# npm (recommended)
npm install -g @yeshwanthyk/coding-agent
# bun
bun add -g @yeshwanthyk/coding-agent
# From source
cd apps/coding-agent && bun run build
export PATH="$PATH:/path/to/marvin-agent/apps/coding-agent/dist"
# or: ln -s /path/to/marvin-agent/apps/coding-agent/dist/marvin ~/.local/bin/marvinQuick Start
# Run with TUI
marvin
# Or with prompt
marvin "explain this codebase"
# Headless mode (JSON output)
marvin --headless "fix the types"Providers
| Provider | Auth | Notes |
|----------|------|-------|
| Anthropic | ANTHROPIC_API_KEY or OAuth | Pro/Max plans via OAuth flow |
| OpenAI | OPENAI_API_KEY | GPT-4o, o1, o3 |
| Google | GOOGLE_API_KEY | Gemini models |
| Codex | OAuth | bun run codex-auth |
| OpenRouter | OPENROUTER_API_KEY | Multi-provider gateway |
| Groq | GROQ_API_KEY | Fast inference |
| xAI | XAI_API_KEY | Grok models |
| Mistral | MISTRAL_API_KEY | Mistral models |
| Cerebras | CEREBRAS_API_KEY | Quick inference |
Configuration
Config lives in ~/.config/marvin/:
~/.config/marvin/
├── config.json # provider, model, theme, thinking, lsp settings
├── agents.md # global AGENTS.md instructions
├── agents/ # subagent definitions
├── commands/ # custom slash commands
├── hooks/ # lifecycle hooks
├── tools/ # custom tools
├── sessions/ # session persistence (per cwd)
└── codex-tokens.json # codex OAuth tokensconfig.json
{
"provider": "anthropic",
"model": "claude-sonnet-4-20250514",
"thinking": "high",
"theme": "catppuccin",
"editor": "code --wait",
"lsp": { "enabled": true, "autoInstall": true }
}Editor config (used by /editor):
"editor": "code --wait""editor": { "command": "wezterm", "args": ["start", "--cwd", "{cwd}", "--", "nvim"] }Use the object form when command/args include spaces. Defaults to nvim when unset. /editor writes a temp file, suspends the TUI, then restores the prompt with the edited contents when the editor exits. The editor runs with cwd set to the current working directory; include {cwd} if your editor needs it. For GUI editors, add --wait so /editor blocks until the file closes.
AGENTS.md
Loaded from (first found):
~/.config/marvin/agents.md~/.codex/agents.md~/.claude/CLAUDE.md
Project-level (merged with global):
./AGENTS.md./CLAUDE.md
CLI Options
marvin [prompt]
Options:
--provider <name> Provider (anthropic, openai, google, codex, openrouter, groq, xai, mistral, cerebras)
--model <id> Model id or comma-separated list (Ctrl+P to cycle)
--thinking <level> off | minimal | low | medium | high | xhigh
--continue, -c Continue most recent session
--resume, -r Pick session to resume
--headless JSON output, no TUI
--config <path> Custom config.json path
--config-dir <path> Custom config directoryKeybindings
| Key | Action |
|-----|--------|
| Enter | Send message |
| Ctrl+C | Clear input / double to exit |
| Esc | Abort current request / dismiss autocomplete |
| Ctrl+P | Cycle through model list |
| Ctrl+L | Clear screen |
| Ctrl+N/P | Autocomplete navigation |
| Tab | Accept autocomplete |
Shell Mode
Prefix input with ! for quick shell commands:
! ls -la— Run command, show output!! git status— Run command and inject output into context
Slash Commands
| Command | Description |
|---------|-------------|
| /model [provider] <id> | Switch model |
| /thinking <level> | Set thinking level |
| /theme [name] | Switch theme (30+ built-in) |
| /editor | Open configured editor |
| /compact [instructions] | Compress context |
| /status | Show session status |
| /steer <text> | Interrupt current run with steering instructions |
| /followup <text> | Queue follow-up text for delivery once idle |
| /conceal | Toggle markdown syntax hiding |
| /diffwrap | Toggle diff word-wrap |
| /abort | Abort in-flight request |
| /clear | Clear chat + reset agent |
| /exit, /quit | Exit |
Custom commands: ~/.config/marvin/commands/*.md
# ~/.config/marvin/commands/review.md
Review the following code for bugs, security issues, and improvements.
$ARGUMENTSUsage: /review src/index.ts
Tools
Built-in (base-tools)
- read — Read files (text + images)
- write — Write/create files
- edit — Surgical text replacement
- bash — Execute shell commands
Subagent
Delegate tasks to specialized agents with isolated context.
# Define agents in ~/.config/marvin/agents/*.md
# Or project-level: .marvin/agents/*.mdAgent definition:
---
name: reviewer
description: Code review specialist
model: claude-sonnet-4-20250514
---
You are a code reviewer. Focus on correctness, security, and maintainability.Modes:
- Single:
{ agent: "name", task: "..." } - Parallel:
{ tasks: [{ agent, task }, ...] } - Chain:
{ chain: [{ agent, task: "... {previous} ..." }, ...] }
Custom Tools
// ~/.config/marvin/tools/my-tool.ts
import { Type } from "@sinclair/typebox"
export default function(api: { cwd: string; exec: Function }) {
return {
name: "my_tool",
description: "Does something useful",
parameters: Type.Object({
input: Type.String({ description: "Input value" })
}),
async execute(toolCallId: string, params: { input: string }) {
return {
content: [{ type: "text", text: `Result: ${params.input}` }],
details: { /* structured data for UI */ }
}
}
}
}Custom tools can include:
renderCall(args, theme)— Custom call renderingrenderResult(result, opts, theme)— Custom result renderingonSession(event)— Session lifecycle hookdispose()— Cleanup on exit
Hooks
Lifecycle hooks for automation and integrations.
// ~/.config/marvin/hooks/my-hook.ts
import type { HookAPI } from "@yeshwanthyk/coding-agent"
export default function(marvin: HookAPI) {
marvin.on("app.start", async (event, ctx) => {
// App initialized
})
marvin.on("tool.execute.before", async (event, ctx) => {
// Block or modify tool execution
if (event.toolName === "bash" && event.input.command?.includes("rm -rf")) {
return { block: true, reason: "Dangerous command blocked" }
}
})
marvin.on("tool.execute.after", async (event, ctx) => {
// Modify tool results
return { content: event.content }
})
marvin.on("agent.end", async (event, ctx) => {
// Agent loop completed
})
}Available events:
app.start— Config loaded, before agent startssession.start,session.resume,session.clearagent.start,agent.endturn.start,turn.endtool.execute.before,tool.execute.after
Helpers:
marvin.steer(text)/marvin.followUp(text)— delivery-aware sugar (interrupt vs queue automatically)marvin.sendUserMessage(text, { deliverAs })— explicit steering vs follow-up controlctx.isIdle()— true when the agent is not currently streaming or running tools
See examples/hooks/steer-followup.ts for a reference hook that exposes /focus and /queue commands.
Hook context provides:
ctx.exec(command, args, options)— Run shell commandsctx.cwd— Current working directoryctx.configDir— Config directory path
LSP Integration
Language servers spawn automatically per file type. Diagnostics are injected into tool results after edit/write/bash operations.
// config.json
{
"lsp": {
"enabled": true,
"autoInstall": true
}
}Supported: TypeScript/JavaScript (auto-installed), with registry for more.
Custom LSP config: ~/.config/marvin/lsp/
Themes
30+ built-in themes:
marvin (default), aura, ayu, catppuccin, catppuccin-macchiato, cobalt2,
dracula, everforest, flexoki, github, gruvbox, kanagawa, lucent-orng,
material, matrix, mercury, monokai, nightowl, nord, one-dark, opencode,
orng, palenight, rosepine, solarized, synthwave84, tokyonight, vercel,
vesper, zenburnSwitch: /theme <name> or set in config.json.
Sessions
Sessions persist per working directory in ~/.config/marvin/sessions/.
-c, --continue— Resume most recent session-r, --resume— Pick from session list
Sessions store: metadata, messages, tool results (JSONL format).
Headless Mode
For scripting and subagent invocations:
marvin --headless "fix the types" | jq .Output:
{
"ok": true,
"provider": "anthropic",
"model": "claude-sonnet-4-20250514",
"prompt": "fix the types",
"assistant": "I've fixed the type errors..."
}What's NOT Included
Intentionally omitted for simplicity:
- MCP — No Model Context Protocol
- Permission gating — No approval prompts for tool use
- Plan mode — No separate planning phase
- Built-in todos — No task tracking
- Background tasks — No async task queue
Development
# Install deps
bun install
# Run dev
bun run marvin
# Typecheck
bun run typecheck
# Test
bun run test
# Build binary
cd apps/coding-agent && bun run buildArchitecture
apps/coding-agent/ # Main CLI app
packages/
├── ai/ # LLM provider abstraction
├── agent/ # Agent-core state management
├── base-tools/ # read, write, edit, bash
├── lsp/ # Language server integration
└── open-tui/ # Terminal UI framework (SolidJS + OpenTUI)