@geoffai/coder
v1.0.0
Published
A terminal-based AI coding agent.
Maintainers
Readme
🚀 Geoff Coder
A terminal-based AI coding agent built with Bun.js featuring an agentic loop with tool call support. This agent can read files, write code, execute commands, and iterate on tasks autonomously.
Features
- Agentic Loop: Autonomous task execution with tool calling
- System Reminders: Context-aware reminders injected at key points (inspired by Claude Code)
- OpenAI-Compatible API: Works with any OpenAI-compatible inference API
- Containerized: Docker support for isolated execution
- Tool Suite: File operations, shell commands, code search, diff application
- Streaming Support: Real-time response streaming for verbose mode
Architecture
The system is built around patterns observed in production coding agents like Claude Code, Cline, and OpenCode:
┌─────────────────────────────────────────────────────────────┐
│ CLI Interface │
├─────────────────────────────────────────────────────────────┤
│ Agent Loop │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Message │───▶│ LLM Call │───▶│ Tool │ │
│ │ History │ │ (Stream) │ │ Execution │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ▲ │ │
│ │ ┌─────────────┐ │ │
│ └─────────│ System │◀────────────┘ │
│ │ Reminders │ │
│ └─────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Tool Registry │
│ read_file │ write_file │ execute_command │ search_files │
│ apply_diff │ list_files │ task_complete │
└─────────────────────────────────────────────────────────────┘Key Components
Agent Loop (
src/agent/loop.ts): The core execution engine that:- Manages conversation history
- Calls the LLM with tool definitions
- Handles tool call responses
- Injects system reminders at appropriate times
- Iterates until task completion
System Reminders (
src/prompts/system.ts): Context-aware prompts injected at:- Pre-user message (task focus)
- Post-tool result (verification reminders)
- Context refresh (iteration warnings)
- Task boundaries (completion prompts)
Tool Registry (
src/tools/registry.ts): Extensible tool system with:- File read/write operations
- Shell command execution
- Code search (grep)
- Diff application for surgical edits
- Task completion signaling
API Client (
src/agent/api-client.ts): OpenAI-compatible client with:- Streaming support
- Tool call accumulation
- Error handling and retries
Installation
Prerequisites
- Bun v1.0+
- An OpenAI-compatible API key
Local Installation
# Clone or download the project
cd geoff-coder
# Install dependencies
bun install
# Set your API key
export OPENAI_API_KEY="your-api-key"
# Run the agent
bun run src/index.ts "Create a hello world Express server"Docker Installation
# Build the image
docker build -t geoff-coder .
# Run interactively
docker run -it --rm \
-e OPENAI_API_KEY="your-api-key" \
-v $(pwd)/workspace:/workspace \
geoff-coder
# Or use docker-compose
export OPENAI_API_KEY="your-api-key"
docker compose upUsage
Single Task Mode
# Execute a single task
bun run src/index.ts "Create a REST API with Express"
# With verbose output
bun run src/index.ts -v "Fix the bug in auth.ts"
# With custom model
bun run src/index.ts -m "gpt-4-turbo" "Write tests for utils"Interactive Mode
# Start interactive REPL
bun run src/index.ts -i
# In the REPL
>>> Create a new React component for user profiles
>>> Add validation to the form
>>> exitWith Local LLM (Ollama)
# Using Ollama
bun run src/index.ts \
-u "http://localhost:11434/v1" \
-m "llama3" \
-k "not-needed" \
"Explain this codebase"
# Or with docker-compose
docker compose --profile local upCLI Options
Usage: bun run src/index.ts [options] [prompt]
Options:
-h, --help Show help message
-v, --verbose Enable verbose output
-i, --interactive Run in interactive mode (REPL)
-m, --model <model> Model to use (default: gpt-4o)
-u, --base-url <url> API base URL
-k, --api-key <key> API key
-d, --dir <path> Working directory
--max-iterations <n> Maximum loop iterations (default: 20)
--max-tokens <n> Maximum tokens per response (default: 4096)
-t, --temperature <n> Temperature (default: 0.7)Environment Variables
OPENAI_API_KEY # Required: Your API key
OPENAI_BASE_URL # Optional: API endpoint (default: https://api.openai.com/v1)
OPENAI_MODEL # Optional: Model name (default: gpt-4o)Customization
Adding Custom Tools
Extend the tool registry in src/tools/registry.ts:
// Add to toolDefinitions array
{
type: "function",
function: {
name: "my_custom_tool",
description: "Description of what this tool does",
parameters: {
type: "object",
properties: {
param1: { type: "string", description: "Parameter description" }
},
required: ["param1"]
}
}
}
// Add handler in createToolRegistry function
handlers.set("my_custom_tool", async (args): Promise<ToolResult> => {
// Implementation
return { success: true, output: "Result" }
})Adding System Reminders
Extend the reminders in src/prompts/system.ts:
systemReminders.push({
id: "my_reminder",
content: "<system-reminder>Your reminder text</system-reminder>",
injectionPoint: "post_tool_result",
priority: 5,
condition: (state) => state.iteration > 3
})Project-Specific Instructions
Create an AGENTS.md file in your project root with custom instructions that will be loaded by the agent.
How It Works
The Agentic Loop
- User Input: User provides a task description
- System Prompt: Base instructions + system reminders are assembled
- LLM Call: Request sent to the model with tool definitions
- Response Processing:
- If tool calls: Execute tools, add results to history, continue loop
- If text only: Check for completion indicators
- Iteration: Loop continues until:
task_completetool is called- Max iterations reached
- No more tool calls and response looks complete
System Reminders (Key Innovation)
Inspired by Claude Code's <system-reminder> pattern, reminders are injected:
- Pre-user message: Focus on task, avoid unnecessary changes
- Post-tool result: Verify changes after file operations
- Context refresh: Warning after many iterations
- Task boundary: Prompt to use
task_complete
This helps maintain agent focus and prevents drift in long-running tasks.
Comparison with Similar Tools
| Feature | This Agent | Claude Code | Cline | OpenCode | |---------|-----------|-------------|-------|----------| | Open Source | ✅ | ❌ | ✅ | ✅ | | Provider Agnostic | ✅ | ❌ | ✅ | ✅ | | System Reminders | ✅ | ✅ | ❌ | ❌ | | Containerized | ✅ | ❌ | ❌ | ❌ | | Runtime | Bun | Node | Node | Go/Bun | | IDE Integration | ❌ | ✅ | ✅ | ❌ |
Development
# Run in development mode (with auto-reload)
bun --watch run src/index.ts -i
# Type check
bun run tsc --noEmit
# Build for distribution
bun build src/index.ts --outdir dist --target bunLicense
MIT
Acknowledgments
Architecture patterns inspired by:
- Claude Code - System reminder injection pattern
- Cline - Tool definitions and agentic loop
- OpenCode - CLI design and provider abstraction
- OpenAI Codex CLI - Agent loop implementation
