Skip to content

rokartur/opencode-forgecode

 
 

Repository files navigation

super-mega-logo

opencode-forgecode

The all-in-one OpenCode plugin for autonomous development workflows.

Iterative loops · Multi-agent orchestration · Code graph · Sandboxed execution · Smart harness

npm License: MIT Tests


What is this?

opencode-forgecode is a single plugin for OpenCode that gives your AI agents the ability to plan, execute, review, and iterate — autonomously. It combines two systems into one cohesive runtime:

Forge Iterative development loops with git worktree isolation, session-scoped plans, code-graph indexing, Docker/Firejail/Bubblewrap sandboxing, background tasks, and a TUI sidebar
Harness Summary-frame compaction, output truncation, doom-loop detection, pending-todo reminders, undo snapshots, and the multi-agent system (9 specialized agents)

Both systems share the same plugin entrypoint — no conflicts over hooks, no duplicate compaction, no fighting for tool.execute.*.


Quick Start

1. Install

npm add opencode-forgecode

2. Configure OpenCode

opencode.json:

{
	"$schema": "https://opencode.ai/config.json",
	"plugin": ["opencode-forgecode@latest"],
	"compaction": { "auto": true, "prune": true },
	"agent": {
		"forge": { "model": "anthropic/claude-opus-4.7" },
		"muse": { "model": "openai/gpt-5.4" },
		"sage": { "model": "openai/gpt-5.4-mini" }
	}
}

3. Enable TUI sidebar (optional)

~/.config/opencode/tui.json:

{
	"$schema": "https://opencode.ai/tui.json",
	"plugin": ["opencode-forgecode@latest"]
}

4. Done

On first run the plugin auto-creates ~/.config/opencode/forge-config.jsonc with sensible defaults. Run oc-forgecode doctor to verify everything is wired correctly.


Agents

The plugin ships 9 specialized agents, all registered automatically on load:

Core Trinity

Agent Role Mode Description
forge Coder primary Graph-first code discovery, read/write/bash access, harness-aware. The workhorse.
muse Planner primary Strategic planning with KV-backed plan store. All file edits denied. Two-step approval flow before any execution.
sage Reviewer subagent Dual-mode: code review on diffs/PRs or deep research on architecture. Read-only, temp 0.0.

Extended Agents

Agent Role Description
explore Explorer Parallel codebase discovery — optimized for broad, open-ended questions
oracle Q&A Short, precise answers to specific codebase questions
librarian Researcher Information retrieval using read-only tools
prometheus Generator Scaffolding, boilerplate, migrations, templates
metis Meta-agent Analyzes context and recommends which agent to use next
caveman Efficiency mode Cuts ~75% output tokens while keeping technical substance

Agents can call each other via bg_spawn (Sisyphus-style delegation) or the tool_supported agent-as-tool pattern.


Tools

📝 Plan & Review

Tool Description
plan-write Store a plan skeleton (auto-keyed to plan:{sessionID}, 7-day TTL, 8 KB soft cap)
plan-append Append a section to the stored plan (for incremental, timeout-safe writes)
plan-edit Find-and-replace within the stored plan (supports replace_all / occurrence)
plan-read Retrieve plan with pagination and pattern search
plan-execute Launch plan execution as a new forge session
review-write Store review findings (file, line, severity, description)
review-read Query findings by file path or regex
review-delete Remove a finding by file and line

🔁 Loops

Tool Description
loop Run an iterative dev loop. worktree: true for git worktree isolation
loop-status List active loops or get details by name. restart to resume
loop-cancel Cancel a running loop

🕸️ Code Graph

Tool Description
graph-status Check indexing status or trigger a re-scan
graph-query File-level: top_files, file_deps, file_dependents, cochanges, blast_radius, packages, file_symbols
graph-symbols Symbol-level: find, search, signature, callers, callees, blast_radius, call_cycles
graph-analyze Quality: unused_exports, duplication, near_duplicates

🔧 Editing & Undo

Tool Description
patch Hash-anchored LINE#HASH replacements — resilient to concurrent edits
multi_patch Atomic multi-replacement on a single file (tempfile + rename)
fs_undo Restore from automatic pre-edit snapshots

🧠 Code Intelligence

Tool Description
lsp_diagnostics Fetch diagnostics from language servers
lsp_hover Get type info and docs for a symbol
lsp_references Find all references to a symbol
lsp_definition Jump to definition
lsp_code_actions Get available code actions
lsp_rename Rename a symbol across the project
ast_search Structural code search via ast-grep patterns
ast_rewrite Structural code rewrites via ast-grep
sem_search Semantic search with embeddings (OpenAI / fastembed / Voyage)
code-stats Language / LOC summary via tokeisccrg fallback

⚡ Background Tasks

Tool Description
bg_spawn Launch an agent as a background task
bg_status Check status of background tasks
bg_wait Wait for a background task to complete
bg_cancel Cancel a running background task

Slash Commands

Command Description Agent
/review Run a code review on current changes sage
/loop Start an iterative development loop forge
/loop-status Check status of all active loops forge
/loop-cancel Cancel the active loop forge

CLI

oc-forgecode <command> [options]
Command Description
doctor Validate config, DB, sandbox, and runtime health
upgrade Check for and install plugin updates
stats Display session and loop statistics
status [name] Detailed loop status (iterations, tokens, phase)
cancel <name> Cancel and clean up a worktree loop
restart <name> Resume a cancelled/failed loop
graph status Show graph indexing state
graph scan Trigger a full graph re-scan
graph list List all cached graph indexes
graph remove <target> Remove a specific graph cache
graph cleanup --days <n> Clean up caches older than N days
ci Headless loop execution for CI/CD pipelines
mcp MCP server management

Global flags: --project, -p <name> · --dir, -d <path> · --db-path <path> · --help, -h


Architecture

┌──────────────────────────────────────────────────────────┐
│                    OpenCode Host                         │
│                                                          │
│  opencode.json ──► plugin: ["opencode-forgecode@latest"] │
└──────────────┬───────────────────────────────────────────┘
               │
               ▼
┌───────────────────────────────────────────────────────────┐
│              opencode-forgecode plugin                    │
│                                                           │
│  ┌──────────────────┐  ┌──────────────────────────────┐   │
│  │  9 Agents        │  │  Hooks Pipeline              │   │
│  │  forge·muse·sage │  │  chat.message                │   │
│  │  explore·oracle  │  │  tool.execute.before/after   │   │
│  │  librarian       │  │  event                       │   │
│  │  prometheus      │  │  permission.ask              │   │
│  │  metis·caveman   │  │  session.compacting          │   │
│  └──────────────────┘  │  messages.transform          │   │
│                        └──────────────────────────────┘   │
│  ┌──────────────────┐  ┌──────────────────────────────┐   │
│  │  Services        │  │  Runtime                     │   │
│  │  KV Store        │  │  Budget Enforcer             │   │
│  │  Loop Service    │  │  Session Recovery            │   │
│  │  Graph Service   │  │  Telemetry Collector         │   │
│  │  Sandbox Manager │  │  Intent Router               │   │
│  │  LSP Pool        │  │  Restricted Shell            │   │
│  │  Background Mgr  │  │  Skill Loader                │   │
│  │  MCP Registry    │  │  Context Injection           │   │
│  │  Host Tools (rg) │  │  Search Renderer             │   │
│  └──────────────────┘  └──────────────────────────────┘   │
│                                                           │
│  ┌────────────────────────────────────────────────────┐   │
│  │  Storage: SQLite (KV + Graph + Telemetry)          │   │
│  │  ~/.local/share/opencode/forge/                    │   │
│  └────────────────────────────────────────────────────┘   │
└───────────────────────────────────────────────────────────┘

Key Design Decisions

  • Leader/Follower graph — Multiple plugin instances (e.g., across worktrees) coordinate via a lock file + Unix domain socket IPC. Only the leader writes; followers read over RPC.
  • Soft-fail everywhere — If the DB can't open, the plugin falls back to in-memory KV. If the graph can't initialize, tools gracefully report "unavailable". Nothing crashes the session.
  • Per-agent budgetsAgentBudgetEnforcer tracks turns, tokens, requests, and tool failures per agent with configurable warnstop policies.
  • Session recoverySessionRecoveryManager handles context-overflow, timeouts, and overload errors with automatic retry and model fallback chains.
  • Host-side fast tools — When rg (ripgrep) is available, grep/glob tool calls are intercepted before reaching the sandbox and served via ripgrep with submatch-windowed, grouped output — reducing token usage and latency.

Configuration

The plugin config lives at ~/.config/opencode/forge-config.jsonc (JSONC format — comments allowed).

Essential Settings

{
	// Storage (empty = ~/.local/share/opencode/forge)
	"dataDir": "",

	// Logging
	"logging": { "enabled": false, "debug": false },

	// Graph indexing
	"graph": {
		"enabled": true,
		"autoScan": true, // Scan on startup
		"watch": true, // Watch for file changes
		"debounceMs": 100,
	},

	// Iterative loops
	"loop": {
		"enabled": true,
		"defaultMaxIterations": 15,
		"defaultAudit": true,
		"cleanupWorktree": false,
		"stallTimeoutMs": 60000,
	},

	// Sandbox (off | docker | sandbox-exec | bubblewrap | firejail)
	"sandbox": { "mode": "off", "image": "oc-forge-sandbox:latest" },

	// Harness (doom-loop, truncation, snapshots, compaction)
	"harness": {
		"enabled": true,
		"doomLoopThreshold": 3,
		"pendingTodosReminder": true,
		"snapshots": true,
		"compaction": true,
		"hashAnchoredPatch": true,
		"truncation": { "enabled": true },
	},
}

Advanced Settings

Per-agent budgets
{
	"agents": {
		"forge": {
			"budget": {
				"maxTurns": 50,
				"maxTokensPerSession": 500000,
				"maxToolFailuresPerTurn": 5,
			},
		},
	},
}
Fallback models
{
	"agents": {
		"forge": {
			"fallbackModels": [
				{ "provider": "anthropic", "model": "claude-sonnet-4" },
				{ "provider": "openai", "model": "gpt-5.4-mini" },
			],
		},
	},
}
Restricted shell
{
	"restrictedShell": {
		"enabled": true,
		"dangerousPatterns": ["rm -rf /", ":(){ :|:& };:"],
		"allowlist": ["npm test", "bun test", "make"],
	},
}
Context injection
{
	"contextInjection": {
		"enabled": true,
		"rules": [
			{
				"pattern": "**/*.test.ts",
				"content": "Follow the testing conventions in TESTING.md",
				"priority": 10,
			},
		],
	},
}
Skill loader
{
	"skills": {
		"enabled": true,
		"directories": [".opencode/skills", "~/.config/opencode/skills"],
	},
}
LSP integration
{
	"lsp": {
		"enabled": true,
		"servers": {
			"typescript": { "command": "typescript-language-server", "args": ["--stdio"] },
			"python": { "command": "pylsp" },
		},
	},
}
Host-side fast tools (ripgrep)
{
	"host": {
		// When true and `rg` is on PATH, intercept grep/glob tool calls
		// and serve them via ripgrep with grouped, submatch-windowed output.
		// Defaults to true.
		"fastGrep": true,
	},
}
Background tasks
{
	"background": {
		"enabled": true,
		"maxConcurrent": 5,
		"perModelLimit": 2,
		"pollIntervalMs": 3000,
		"idleTimeoutMs": 10000,
	},
}
Telemetry (local-only, opt-in)
{
	"telemetry": {
		"enabled": true, // SQLite-backed, never leaves your machine
	},
}
Built-in MCPs
{
	"mcp": {
		"websearch": { "provider": "tavily", "apiKey": "tvly-..." },
		"context7": { "apiKey": "..." },
		"grepApp": { "enabled": true },
	},
}

All Config Options Reference

Section Key Default Description
dataDir ~/.local/share/opencode/forge Plugin data directory
defaultKvTtlMs 604800000 (7d) Default TTL for KV entries
logging enabled / debug / file false / false / auto File-based logging
graph enabled / autoScan / watch / debounceMs true / true / true / 100 Code graph indexing
loop enabled / defaultMaxIterations / defaultAudit / cleanupWorktree / stallTimeoutMs / minAudits true / 15 / true / false / 60000 / 1 Loop execution
sandbox mode / image "off" / "oc-forge-sandbox:latest" Sandboxed execution
harness enabled / doomLoopThreshold / pendingTodosReminder / snapshots / compaction / hashAnchoredPatch true / 3 / true / true / true / true Harness runtime
harness.truncation enabled true Output truncation (shell 200+200 lines @ 500 chars/line, search 200 lines @ 400 chars/line, fetch 40K chars)
compaction customPrompt / maxContextTokens true / 0 Summary-frame compaction fallback
messagesTransform enabled / debug true / false Message pipeline
host fastGrep true Intercept grep/glob via ripgrep when rg is on PATH

Harness Features

Doom-Loop Detection

Tracks tool call signatures per session. When it detects 3+ consecutive identical or cyclic patterns, it injects a reminder via tui.appendPrompt asking the agent to change strategy.

Output Truncation

Automatically trims long tool output in tool.execute.after:

  • Shell/bash: 200 lines head + 200 lines tail, 500 chars/line max
  • Search/grep: 200 lines max, 400 chars/line max (with per-file match distribution banner)
  • Web fetch: 40,000 chars max

Summary-Frame Compaction

Overrides experimental.session.compacting with an intelligent summary frame that preserves key context, decisions, and in-progress state. Falls back to a custom compaction prompt when no cached messages are available.

Undo Snapshots

Before every write / edit / multi_patch / patch, the harness snapshots the file at:

<dataDir>/snapshots/<sessionId>/<timestamp>-<fileTag>.bak

Restore with:

fs_undo file="src/foo.ts"            # latest snapshot
fs_undo file="src/foo.ts" steps=3    # 3 versions back

Pending-Todos Reminder

Tracks todo.updated events. When a session goes idle with pending or in-progress todos, appends a reminder with the outstanding items.

Host-Side Fast Tools

When rg (ripgrep) is on PATH, the plugin intercepts grep and glob tool calls before they reach the sandbox and serves them via ripgrep. This provides:

  • Submatch-windowed output — only ±30 chars around each match are returned, dramatically reducing token consumption on large files
  • Grouped results — matches are grouped by file with a per-file match distribution banner
  • Automatic fallback — if rg isn't available or a sandbox is active, calls pass through to the default implementation

Disable with "host": { "fastGrep": false } in forge-config.jsonc.


Plugin Compatibility

Plugin Status Notes
opencode-forgecode This plugin Owns compaction, hooks, agents, tools
@plannotator/opencode ✅ Compatible Planning layer complements forge plans
opencode-forge (upstream) Do not stack Already included — running both doubles hooks and graph scans
@tarquinen/opencode-dcp ⚠️ Optional Safe as upstream pruning layer. Let forgecode own final compaction

Rule of thumb: opencode-forgecode must own the final experimental.session.compacting prompt. If using DCP, treat it as proactive pruning only.


GitHub Actions / CI

Use the built-in CI mode for headless loop execution in pipelines:

- name: Run forge loop
  run: npx oc-forgecode ci --task "Fix failing tests" --output json

Supports --output json|markdown|text and automatic PR comment posting.


Development

bun install
bun run typecheck        # TypeScript type checking
bun run lint             # Linting
bun test                 # 756+ tests
bun run build            # Emit dist/

License

MIT

About

The all-in-one OpenCode plugin for autonomous development workflows

Resources

License

Stars

Watchers

Forks

Contributors

No contributors

Languages

  • TypeScript 100.0%