
Security News
pnpm 11.5 Adds Support for Recognizing npm Staged Publishes
pnpm 11.5 now recognizes npm staged publish approvals in release metadata, preventing those releases from being mistaken for lower-trust package publishes.
opencode-forge
Advanced tools
OpenCode Forge - autonomous dev loops, plan storage, and sandboxing for OpenCode
Loops, plans, sandboxing, and code review for OpenCode AI agents
pnpm add opencode-forge
Add to your opencode.json to enable Forge’s server-side hooks, tools, and agents:
{
"plugin": ["opencode-forge@latest"]
}
For TUI features: Also add to your tui.json to enable the sidebar, plan viewer, execution dialog, and load-plan UI:
{
"$schema": "https://opencode.ai/tui.json",
"plugin": ["opencode-forge@latest"]
}
Forge ships two user-facing surfaces:
opencode.json. The package declares the server oc-plugin surface and exports ./server for the server entrypoint.tui.json. The package declares the tui oc-plugin surface and exports ./tui for the terminal UI entrypoint.The server plugin provides the core hooks, tools, agents, plan storage, loop orchestration, review persistence, and sandbox support. The TUI plugin layers on sidebar, plan viewer/editor, execution dialog, and load-plan UI.
Plan viewer showing the plan in rendered markdown format:

Execution flow dialog with mode and model selection:

Plan editor with raw text editing:

Load plans dialog showing archived plans:

New session, Execute here, and Loop launch paths for approved plansThe plugin bundles three user-facing agents plus a hidden auditor-loop variant used by loop audit sessions:
| Agent | Mode | Description |
|---|---|---|
| code | all | Primary coding agent. |
| architect | primary | Read-only planning agent. Researches the codebase, designs implementation plans, and caches them for user approval before execution. |
| auditor | subagent | Read-only code auditor for convention-aware reviews. Invoked via Task tool to review diffs, commits, branches, or PRs against stored conventions and decisions. |
| auditor-loop | primary, hidden | Internal audit agent used for loop-runner audit sessions. |
The auditor agent is a read-only subagent that cannot edit source files or execute plans. It is invoked by other agents via the Task tool to review code changes against stored project conventions and decisions.
Tool restrictions: The auditor cannot use the loop tool to prevent interference with active workflows.
The architect agent operates as a read-only planner with message-level reinforcement via the experimental.chat.messages.transform hook. Final plans are rendered once in the assistant response between <!-- forge-plan:start --> and <!-- forge-plan:end --> markers, then auto-captured into SQL before execution approval. After user approval via the question tool, execution is dispatched programmatically — no additional LLM calls are needed. The user can view and edit the cached plan from the sidebar or command palette before or during execution.
Session-scoped plan storage backed by SQL for managing implementation plans. Loop-associated plans are pruned with expired completed loops.
| Tool | Description |
|---|---|
plan-read | Retrieve the plan. Supports pagination with offset/limit and pattern search. |
section-read | Read a section plan and its status for the active loop session. Supports reading by index or defaulting to the lowest-index incomplete section. |
Review finding storage for persisting audit results across session rotations.
| Tool | Description |
|---|---|
review-write | Store a review finding with file, line, severity, and description. Auto-injects branch field. |
review-read | Retrieve review findings. Filter by file path or search by regex pattern. |
review-delete | Delete a review finding by file and line. |
Iterative development loops with automatic auditing. Loops always run in an isolated git worktree; Docker sandbox is used automatically when available.
| Tool | Description |
|---|---|
loop | Execute a plan using an iterative development loop in an isolated git worktree. Args: title required; plan, loopName, and hostSessionId optional. |
loop-cancel | Cancel an active loop by worktree name |
loop-status | List all active loops or get detailed status by worktree name. Supports restart to resume inactive loops. |
loop reads the current session's captured plan when plan is omitted. maxIterations, execution model, auditor model, and sandbox behavior come from configuration or the TUI execution dialog, not direct loop tool arguments.
| Command | Description | Agent |
|---|---|---|
/review | Run a code review on current changes | auditor (subtask) |
/loop | Start an iterative development loop in a worktree | code |
/loop-status | Check status of all active loops | code |
/loop-cancel | Cancel the active loop | code |
On first run, the plugin automatically copies the bundled config to your config directory:
XDG_CONFIG_HOME is set: $XDG_CONFIG_HOME/opencode/forge-config.jsonc~/.config/opencode/forge-config.jsoncNote: Configuration is stored at ~/.config/opencode/forge-config.jsonc unless XDG_CONFIG_HOME is set.
The plugin supports JSONC format, allowing comments with // and /* */.
You can edit this file to customize settings. The file is created only if it doesn't already exist.
~/.config/opencode/forge-config.jsonc or $XDG_CONFIG_HOME/opencode/forge-config.jsonc~/.local/share/opencode/forge or $XDG_DATA_HOME/opencode/forge~/.local/share/opencode/forge/logs/forge.logEnable logging.enabled to write logs to disk. To use the default log path, omit logging.file or set it to null (an empty string is not treated as a default). Set logging.debug for more verbose output.
{
// Data directory for plugin storage (SQL stores, logs)
// When empty, resolves to ~/.local/share/opencode/forge (or XDG_DATA_HOME equivalent)
"dataDir": "",
// Logging configuration
"logging": {
"enabled": false, // Enable file logging
"debug": false, // Enable debug-level output
"file": "" // Log file path (omit or set to null for default path)
},
// Session compaction settings
"compaction": {
"customPrompt": true, // Use custom compaction prompt for continuity
"maxContextTokens": 0 // Max tokens for context (0 = unlimited)
},
// Messages transform hook for read-only enforcement
"messagesTransform": {
"enabled": true, // Enable transform hook
"debug": false // Enable debug logging
},
// Model override for plan execution sessions (format: "provider/model")
"executionModel": "",
// Model override for the auditor agent (format: "provider/model")
"auditorModel": "",
// Iterative development loop settings
"loop": {
"enabled": true, // Enable iterative loops
"defaultMaxIterations": 15, // Max iterations (0 = unlimited)
"cleanupWorktree": false, // Auto-remove worktree on cancel
"stallTimeoutMs": 60000, // Stall detection timeout (60s)
"maxConsecutiveStalls": 5, // Consecutive stalls before termination (0 = disabled)
"worktreeLogging": { // Worktree loop completion logging
"enabled": false, // Enable completion logging
"directory": "" // Log directory (defaults to platform data dir)
}
},
// Sandbox configuration (optional; provisioned automatically when available)
"sandbox": {
"mode": "docker",
"image": "oc-forge-sandbox:latest"
},
// TUI sidebar widget configuration
"tui": {
"sidebar": true, // Show Forge sidebar in OpenCode TUI
"showVersion": true, // Show plugin version in sidebar title
"autoSavePlans": false, // Auto-save captured plans to disk under <dataDir>/plans/<projectId>/
"planArchiveTtlMs": 604800000, // TTL in ms for archived plans before pruning. 0 disables pruning.
"keybinds": { // Keyboard shortcut overrides
"viewPlan": "<leader>v", // View plan dialog
"loadPlan": "<leader>i" // Load archived plans dialog
}
},
// TTL in ms for completed/cancelled loops before cleanup. Default: 604800000 (7 days)
"completedLoopTtlMs": 604800000,
// Per-agent overrides (temperature range: 0.0 - 2.0)
// Keys are agent display names (e.g., "code", "architect", "auditor")
// "agents": {
// "architect": { "temperature": 0.0 },
// "auditor": { "temperature": 0.0 },
// "code": { "temperature": 0.7 }
// }
}
dataDir - Data directory for plugin storage (SQL stores, logs). When empty, resolves to ~/.local/share/opencode/forge (or XDG_DATA_HOME equivalent) (default: "")completedLoopTtlMs - TTL for completed/cancelled/errored/stalled loops before sweep (default: 604800000 / 7 days).executionModel - Model override for plan execution sessions, format: provider/model (e.g. anthropic/claude-sonnet-4-20250514). When set, plan execution (via the architect's approval flow or the TUI Execute panel) uses this model for the new Code session. When empty or omitted, OpenCode's default model is used (typically the model field from opencode.json). Recommended: Set this to a fast, cheap model (e.g. Haiku or MiniMax) and use a smart model (e.g. Opus) for the Architect session — planning needs reasoning, execution needs speed. This value is used as a fallback when no per-launch selection is made.auditorModel - Model override for the auditor agent (provider/model). When set, overrides the auditor agent's default model. When not set, uses platform default (default: ""). This value is used as a fallback when no per-launch selection is made.agents - Per-agent temperature overrides keyed by display name (e.g., "code", "architect", "auditor"). Temperature range: 0.0 - 2.0 (default: undefined)logging.enabled - Enable file logging (default: false)logging.debug - Enable debug-level log output (default: false)logging.file - Log file path. Omitted or null falls back to ~/.local/share/opencode/forge/logs/forge.log (default: ""). Setting to an empty string "" passes the empty string through and logging will fail silently. Logs remain in the data directory, only config has moved.When enabled, logs are written to the specified file with timestamps. The log file has a 10MB size limit with automatic rotation.
compaction.customPrompt - Use a custom compaction prompt optimized for session continuity (default: true)compaction.maxContextTokens - Maximum tokens for context during compaction (default: 0 / unlimited)messagesTransform.enabled - Enable the messages transform hook for Architect read-only enforcement (default: true)messagesTransform.debug - Enable debug logging for messages transform (default: false)loop.enabled - Enable iterative development loops (default: true)loop.defaultMaxIterations - Default max iterations for loops, 0 = unlimited (default: 15)loop.cleanupWorktree - Auto-remove worktree on cancel (default: false)loop.stallTimeoutMs - Watchdog stall detection timeout in milliseconds (default: 60000)loop.maxConsecutiveStalls - Number of consecutive stalls before the loop terminates with reason stall_timeout. Set to 0 to disable stall-based termination (default: 5).loop.worktreeLogging.enabled - Enable worktree loop completion logging (default: false)loop.worktreeLogging.directory - Directory for completion logs, defaults to platform data dir (default: "")sandbox.mode - Sandbox mode: "docker" (optional; Docker sandbox is provisioned automatically when available)sandbox.image - Docker image for sandbox containers (default: "oc-forge-sandbox:latest")sandbox.resources - Container resource limits mapped directly to docker run flags:
memory - Memory limit, e.g., '8g'. Maps to --memory.memorySwap - Memory+swap limit, e.g., '12g'. Maps to --memory-swap.cpus - Number of CPUs, e.g., '4', '2.5'. Maps to --cpus.shmSize - Shared memory size, e.g., '1g'. Maps to --shm-size.tui.sidebar - Show the forge sidebar widget in OpenCode TUI (default: true)tui.showVersion - Show plugin version number in the sidebar title (default: true)tui.autoSavePlans - Auto-save captured plans to disk under <dataDir>/plans/<projectId>/. Default: false.tui.planArchiveTtlMs - TTL in ms for archived plans before pruning. 0 disables pruning. Default: 604800000 (7 days).tui.keybinds.viewPlan - View plan dialog keybind. Default: <leader>v.tui.keybinds.loadPlan - Load archived plans dialog keybind. Default: <leader>i.The plugin includes a TUI sidebar widget and dialog system for viewing, editing, executing plans directly in the OpenCode terminal interface.
The sidebar provides quick access to plans and configuration:
<dataDir>/plans/<projectId>/· plan in collapsed sidebar headerWhen an architect session produces a plan, it is cached in the current session plan store. The plan is accessible from the sidebar (Load plan button) or the command palette (Forge: View plan). Missing plans show an informational toast.
The plan viewer dialog renders the full plan as GitHub-flavored markdown with syntax highlighting:
The Execute tab provides a comprehensive dialog for launching plans with full control over execution parameters:
Choose from three execution modes:
Two model selectors are available:
Execution Model:
config.executionModelAuditor Model:
config.auditorModel → config.executionModelYour selections are automatically saved in tui_preferences after launch:
The command palette registers two Forge commands:
Forge: View plan (<leader>v) — View cached plan for this sessionForge: Load plan (<leader>i) — Load an archived plan from diskWhen installed from the package, the TUI plugin loads automatically when added to your TUI config. The plugin is auto-detected via the ./tui export in package.json.
Add to your ~/.config/opencode/tui.json or project-level tui.json:
{
"$schema": "https://opencode.ai/tui.json",
"plugin": [
"opencode-forge"
]
}
The TUI provides a comprehensive model selection dialog when executing plans. The dialog features:
Models are displayed in priority order:
Each model shows:
anthropic/claude-sonnet-4-20250514)TUI options are configured in ~/.config/opencode/forge-config.jsonc under the tui key:
{
"tui": {
"sidebar": true,
"showVersion": true
}
}
Set sidebar to false to completely disable the widget.
For local development, reference the built TUI file directly:
{
"$schema": "https://opencode.ai/tui.json",
"plugin": [
"/path/to/opencode-forge/dist/tui.js"
]
}
Plan with a smart model, execute with a fast model. The architect agent researches the codebase and designs an implementation plan; the code agent implements it.
The architect is read-only and must output exactly one final plan between <!-- forge-plan:start --> and <!-- forge-plan:end --> markers. Forge auto-captures that marked plan into SQL storage for the current session.
The user can view the cached plan at any time from the sidebar (Load plan button) or the command palette (Forge: View plan). The plan viewer renders full GitHub-flavored markdown and supports inline editing — the user can modify the plan directly before approving.
After the architect presents a summary, the user chooses an execution mode from the execution dialog:
| Mode | When to choose it |
|---|---|
New session | Default for normal implementation |
Execute here | When preserving current context matters |
Loop | Safer autonomous iteration |
The dialog also lets you pick the execution model and auditor model at launch time. Those selections are remembered per project and pre-filled on later launches.
Execution is immediate — there are no additional LLM calls between approval and execution. The system intercepts the user's approval answer, reads the cached plan, and dispatches it programmatically to the code agent. The architect never processes the approval response.
Model selection follows this priority order:
For execution model:
config.executionModelFor auditor model:
config.auditorModelconfig.executionModelForge: View plan in the session where the architect produced it.logging.enabled to true, and optionally logging.debug for verbose output.The loop is an iterative development system that alternates between coding and auditing phases:
Each iteration runs in a fresh session to keep context small and prioritize speed. After each phase completes, the current session is destroyed and a new one is created. The original task prompt and any audit findings are re-injected into the new session as a continuation prompt, so no context is lost while keeping the window clean.
Audit findings survive session rotation via the review store. The auditor stores each bug and warning using review-write with file, line, severity, and description. At the start of each audit:
review-readreview-deleteLoops always run in an isolated git worktree. Sandbox is optional: when Docker is available and sandbox.mode = 'docker' is configured, a sandbox container is provisioned automatically; otherwise the loop runs in worktree-only mode. Changes are auto-committed and the worktree is removed on completion (branch preserved for later merge).
After each coding iteration, the auditor agent reviews changes against project conventions and stored review findings. Findings are persisted via review-write scoped to the loop's branch. Outstanding severity: 'bug' findings block completion — the loop terminates only when the auditor has run at least once and zero bug-severity findings remain.
A watchdog monitors loop activity. If no progress is detected within stallTimeoutMs (default: 60s), the current phase is re-triggered. After maxConsecutiveStalls consecutive stalls (default: 5), the loop terminates with reason stall_timeout. Use loop-status with restart to resume from the persisted section/iteration.
Loops use the following priority order for model selection:
executionModel — Global execution model fallbackThe auditor model follows a similar chain: dialog selection → auditorModel → executionModel → platform default.
When launching from the TUI dialog, your selection is remembered and pre-filled on subsequent launches. The dialog also allows selecting a separate model for the auditor phase.
On model errors during execution, automatic fallback to the default model kicks in.
git push is denied inside active loop sessionsquestion and loop are blocked to prevent recursive loops and keep execution autonomous/loop to start, /loop-cancel to cancelloop to start with parameters, loop-status for checking progress (with restart capability), loop-cancel to cancelThe loop terminates when any of these conditions is met:
maxIterations cap is exceeded (0 = unlimited).maxConsecutiveStalls consecutive stalls (default: 5). Use loop-status with restart to resume from the persisted section and iteration.Loops always run in an isolated git worktree. Sandbox is optional: when Docker is available and sandbox.mode = 'docker' is configured, a sandbox container is provisioned automatically; otherwise the loop runs in worktree-only mode.
Worktree loops can optionally register as OpenCode workspaces, letting you switch between them (and your main project) from the same TUI session without restarting or re-opening anything.
Workspace integration is host-gated, not config-gated. Forge uses opencode's builtin worktree workspace type, which is always available on hosts that expose the experimental workspace API (experimental_workspace on the plugin input, experimental.workspace on the SDK client).
No forge config option enables or disables this — the feature lights up automatically on supported hosts.
When a worktree loop starts on a supported host, forge:
experimental.workspace.create with type: "worktree" and branch: null to create a builtin worktree workspaceexperimental.workspace.warp to bind the session to that workspaceloops.workspace_id) so the TUI can route clicks on a loop into the correct workspaceThe adaptor's create and remove hooks are intentional no-ops — forge's loop system owns worktree lifecycle, not the workspace system. The adaptor only surfaces existing worktrees to the workspace UI.
If workspace creation or session binding fails at runtime (network error, API mismatch, unsupported host), the loop does not abort. Forge logs the failure, clears the workspace ID, and the loop continues as a regular (non-workspace) worktree loop. You lose workspace-based switching for that loop, but the loop itself runs to completion.
Run loop iterations inside an isolated Docker container. Three tools (bash, glob, grep) execute inside the container via docker exec, while read/write/edit operate on the host filesystem. Your project directory is bind-mounted at /workspace for instant file sharing.
1. Build the sandbox image:
docker build -t oc-forge-sandbox:latest container/
The image includes Node.js 24, pnpm, Bun, Python 3 + uv, ripgrep, git, and jq.
2. Configure the sandbox (~/.config/opencode/forge-config.jsonc):
{
"sandbox": {
"mode": "docker",
"image": "oc-forge-sandbox:latest"
}
}
3. Restart OpenCode.
Start a sandbox loop via the architect plan approval flow (select "Loop") or directly with the loop tool:
loop
Sandbox is optional. When Docker is available and configured, a sandbox container is provisioned automatically; otherwise the loop runs in worktree-only mode. The loop:
/workspacebash, glob, and grep tool calls into the container/workspace. No sync daemon, no file copying. Changes are visible instantly on both sides.bash, glob, and grep route through docker exec when a session belongs to a sandbox loop. The read/write/edit tools operate on the host filesystem directly (compatible with host LSP).forge-<worktreeName>.| Option | Default | Description |
|---|---|---|
sandbox.mode | "docker" | Sandbox mode (optional; Docker used when available) |
sandbox.image | "oc-forge-sandbox:latest" | Docker image to use for sandbox containers |
The container/Dockerfile is included in the project. To add project-specific tools (e.g., Go, Rust, additional language servers), edit the Dockerfile and rebuild:
docker build -t oc-forge-sandbox:latest container/
pnpm build # Compile TypeScript to dist/
pnpm test # Run tests
pnpm typecheck # Type check without emitting
The diagram below shows the overall flow of the Forge loop system — from plan capture through iterative coding/auditing phases with section advancement and session rotation.

MIT
FAQs
OpenCode Forge - autonomous dev loops, plan storage, and sandboxing for OpenCode
The npm package opencode-forge receives a total of 116 weekly downloads. As such, opencode-forge popularity was classified as not popular.
We found that opencode-forge demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
pnpm 11.5 now recognizes npm staged publish approvals in release metadata, preventing those releases from being mistaken for lower-trust package publishes.

Security News
Federal audit finds NIST lacked a plan to clear the NVD backlog, wasted funds on duplicate work, and delayed use of CISA data.

Research
/Security News
A mini Shai-Hulud campaign compromised Red Hat Cloud Services npm packages to steal developer and CI/CD secrets during installation.