Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
2ecf894
feat: add rothnic namespace and OpenCode module
claude Nov 19, 2025
f0e75f4
docs: enhance profile and OpenCode module documentation
claude Nov 19, 2025
fbfda13
feat: add Coder Tasks support to OpenCode module
claude Nov 19, 2025
a8ad0f2
fix: correct task_app_id output construction
claude Nov 19, 2025
240ae1b
fix: remove task_app_id output - agentapi handles tasks internally
claude Nov 19, 2025
ce86151
fix: use OpenCode ACP mode for agentapi integration
claude Nov 19, 2025
256d71b
fix: remove non-existent 'acp' subcommand from OpenCode
claude Nov 19, 2025
37dfc9d
revert: restore 'opencode acp' command - acp subcommand exists
claude Nov 19, 2025
5ea4096
fix: run opencode TUI directly, not acp subcommand
claude Nov 19, 2025
fba1824
fix: automatically install Node.js if not present
claude Nov 19, 2025
2cc8aa5
fix: install OpenCode to user directory without sudo
claude Nov 19, 2025
965c7f2
fix: use OpenCode ACP mode for agentapi integration
claude Nov 20, 2025
9df216e
fix: use correct OpenCode integration per agentapi PR #79
claude Nov 20, 2025
fb32699
fix: use opencode acp mode for stdio communication
claude Nov 20, 2025
5cf6e65
fix: configure GitHub Copilot via auth.json, remove unsupported --pro…
claude Nov 20, 2025
8a6a029
fix: use opencode TUI mode, not acp mode for agentapi
claude Nov 20, 2025
57e13df
fix: configure auth.json in start script, not install script
claude Nov 20, 2025
44f08ca
feat: add opencode_auth_config variable for pre-configured authentica…
claude Nov 20, 2025
e452779
docs: rewrite README with concise authentication guide
claude Nov 20, 2025
e651da3
fix: prevent chmod failures from marking workspace unhealthy
claude Nov 20, 2025
5d8541d
fix: add retry logic for apt operations to handle transient failures
claude Nov 20, 2025
1b70cc4
refactor: use nodejs module instead of installing Node.js directly
claude Nov 21, 2025
99eacef
refactor: replace nodejs module with NVM-based installation and pnpm
claude Nov 21, 2025
46da014
fix: add wait loop for OpenCode installation before starting server
claude Nov 21, 2025
5a809ce
debug: add comprehensive validation and debug logging for startup
claude Nov 21, 2025
8065bb5
fix: use wrapper script to preserve environment for agentapi subprocess
claude Nov 21, 2025
e5d08dd
refactor: follow codex module pattern for install/start separation
claude Nov 21, 2025
e778aef
fix: use npm instead of pnpm, follow codex pattern exactly
claude Nov 21, 2025
0f83fc9
fix: use NVM for Node.js but install opencode to ~/.local/bin
claude Nov 21, 2025
b870304
fix: background agentapi server and match codex pattern exactly
claude Nov 21, 2025
a1009fc
refactor: switch to curl installer, remove all Node.js/NVM complexity
claude Nov 21, 2025
7841fd6
refactor: use Node.js tarball instead of curl/apt/nvm
claude Nov 21, 2025
8e5cc8f
docs: update rothnic namespace and opencode module documentation
nroth-dealnews Nov 23, 2025
161b852
fix: use standard terminal dimensions for opencode TUI
nroth-dealnews Nov 23, 2025
d688c48
feat(opencode): add MCP servers and model configuration support
nroth-dealnews Nov 24, 2025
572d8bf
test(opencode): add MCP and model configuration tests, simplify Quick…
nroth-dealnews Nov 24, 2025
be8a20f
Clean up provider configuration and remove misleading env vars
nroth-dealnews Nov 24, 2025
d6c79cc
Fix MCP server format to match OpenCode documentation
nroth-dealnews Nov 25, 2025
d07daaf
Update README with subdomain wildcard DNS requirement
nroth-dealnews Nov 25, 2025
cae8e16
Add OpenCode icon and minimal agent task example
nroth-dealnews Nov 25, 2025
632df50
Update minimal agent task example to match Coder template structure
nroth-dealnews Nov 25, 2025
6b2a915
Fix install.sh: Use HOME as fallback instead of /workspaces
nroth-dealnews Nov 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .icons/opencode.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions bun.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"name": "registry",
Expand Down
Binary file added registry/rothnic/.images/avatar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions registry/rothnic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
display_name: "Nick Roth"
bio: "Product leader and engineer focused on end-to-end product delivery and agentic AI systems. Based in Huntsville, AL."
avatar: "./.images/avatar.png"
github: "rothnic"
linkedin: "http://www.linkedin.com/in/nicholasleeroth/"
website: "https://www.nickroth.com"
status: "community"
---

# Nick Roth

Product manager and engineer with 14 years of experience leading product strategy, engineering delivery, and platform initiatives. I focus on end-to-end product ownership—from discovery and design through implementation, deployment, and iterative improvement. My current work centers on building self-learning, agentic systems that automate content and operational workflows while keeping humans in the loop for quality and governance.

## Expertise

- **Product Leadership:** Cross-functional product strategy, roadmapping, team leadership, vendor and stakeholder management.
- **Agentic Systems & Automation:** Designing and delivering self-learning agent pipelines, human-in-the-loop workflows, and production-ready automation for content and operations.
- **Platform Delivery & Modernization:** Architecture, procurement, migrations, and shipping reliable systems from prototype to production.
- **Growth & Experimentation:** SEO-led content strategy, A/B testing, experimentation frameworks, and monetization optimization.
- **Systems Engineering:** Requirements, architecture, and integration across complex systems.

## Modules

- [opencode](./modules/opencode/) - Execute AI-driven coding tasks and agentic workflows directly within Coder workspaces using OpenCode.
316 changes: 316 additions & 0 deletions registry/rothnic/modules/opencode/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,316 @@
---
display_name: OpenCode
description: AI-powered terminal coding agent with support for GitHub Copilot, Anthropic, and OpenAI
icon: ../../../../.icons/opencode.png
maintainer_github: rothnic
verified: false
tags: [agent, ai, opencode, coding-assistant, copilot, terminal]
---

# OpenCode

Integrate [OpenCode.ai](https://opencode.ai/) - an AI coding agent that executes tasks in your terminal and reports progress to Coder's task system via [AgentAPI](https://github.com/coder/agentapi). Supports GitHub Copilot, Anthropic Claude, OpenAI, and other providers.

## Quick Start

**Basic setup:**

```tf
module "opencode" {
source = "registry.coder.com/rothnic/opencode/coder"
agent_id = coder_agent.main.id
workdir = "/home/coder"
}
```

**With Coder Tasks (recommended for AI workspaces):**

```tf
data "coder_task" "me" {}

module "opencode" {
source = "registry.coder.com/rothnic/opencode/coder"
agent_id = coder_agent.main.id
workdir = "/home/coder"

ai_prompt = data.coder_task.me.prompt
report_tasks = true
}
```

**With model and MCP servers:**

```tf
module "opencode" {
source = "registry.coder.com/rothnic/opencode/coder"
agent_id = coder_agent.main.id
workdir = "/home/coder"

opencode_model = "claude-3.7-sonnet"
mcp_servers = jsonencode({
filesystem = {
type = "local"
command = ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/home/coder"]
}
})
}
```

## Authentication

OpenCode supports many AI providers (GitHub Copilot, Anthropic Claude, OpenAI, etc.). Authentication is managed via `~/.local/share/opencode/auth.json`, created by running `opencode auth login`.

### GitHub Copilot

GitHub Copilot requires OAuth device flow authentication - you cannot use standard GitHub tokens.

**Option 1: Pre-configured auth (recommended for automation)**

Generate auth on your local machine, then embed in your template:

```bash
# On your local machine
npm install -g opencode-ai
opencode auth login # Select "GitHub Copilot", complete device flow
cat ~/.local/share/opencode/auth.json # Copy this content
```

Create `opencode-auth.json` in your template directory, then reference it:

```tf
module "opencode" {
source = "registry.coder.com/rothnic/opencode/coder"
agent_id = coder_agent.main.id
workdir = "/workspaces"
opencode_auth_config = file("${path.module}/opencode-auth.json")
}
```

**Option 2: Manual login per workspace**

Users run `opencode auth login` inside the workspace. Auth persists across restarts.

### Other Providers (Claude, OpenAI, etc.)

For Anthropic, OpenAI, DeepSeek, Groq, and [other providers](https://opencode.ai/docs/providers/):

1. Users run `opencode auth login` in the workspace
2. Select their provider and enter API key
3. Credentials persist in `~/.local/share/opencode/auth.json`

Or provide API keys via environment variables (see provider docs).

**Note:** The `opencode_provider` variable is for documentation only - it doesn't configure OpenCode. Provider selection happens via `opencode auth login`.

## Configuration

### Core Variables

| Variable | Description | Default | Required |
| ---------- | ------------------------------ | ------- | -------- |
| `agent_id` | Coder agent ID | - | Yes |
| `workdir` | Working directory for OpenCode | - | Yes |

### Authentication & Provider

| Variable | Description | Default |
| ---------------------- | -------------------------------------------------------------------------------------- | ----------- |
| `opencode_auth_config` | Pre-configured auth.json content (for GitHub Copilot or any provider) | `""` |
| `opencode_provider` | Intended provider (documentation only - actual provider set via `opencode auth login`) | `"copilot"` |
| `github_token` | GitHub token for git operations (not AI provider auth) | `""` |
| `external_auth_id` | Coder external auth provider ID for git operations | `"github"` |

### Task Integration

| Variable | Description | Default |
| ---------------- | ----------------------------------------------------- | --------------- |
| `ai_prompt` | Initial task prompt (use `data.coder_task.me.prompt`) | `""` |
| `system_prompt` | Custom system prompt for the AI | Built-in prompt |
| `report_tasks` | Enable task reporting to Coder UI | `true` |
| `resume_session` | Auto-resume latest session on restart | `true` |

### Installation & Versioning

| Variable | Description | Default |
| ------------------ | ----------------------------------------------- | ----------- |
| `opencode_version` | OpenCode version (`latest` or specific version) | `"latest"` |
| `install_method` | Installation method (`npm` recommended) | `"npm"` |
| `install_agentapi` | Install AgentAPI | `true` |
| `agentapi_version` | AgentAPI version | `"v0.10.0"` |

### UI & Apps

| Variable | Description | Default |
| ---------------------- | -------------------------------------------------------------------------- | ---------------------- |
| `web_app_display_name` | Display name in Coder UI | `"OpenCode"` |
| `order` | App position in UI | `null` |
| `group` | App group name | `null` |
| `icon` | App icon path | `"/icon/opencode.png"` |
| `subdomain` | Use subdomain for app access (requires [wildcard DNS][wildcard-dns-setup]) | `false` |
| `cli_app` | Create CLI app entry | `false` |

[wildcard-dns-setup]: https://coder.com/docs/admin/setup#wildcard-access-url

### Model & MCP Configuration

| Variable | Description | Default |
| ---------------- | ------------------------------------------------------------------------------------ | ------- |
| `opencode_model` | Model to use (e.g., `claude-3.7-sonnet`, `gpt-4o`). If empty, uses provider default. | `""` |
| `mcp_servers` | MCP servers configuration as JSON string (see example below) | `""` |

**MCP Servers Example:**

OpenCode uses `type: "local"` for local MCP servers with `command` as an array (including all arguments):

```tf
module "opencode" {
source = "registry.coder.com/rothnic/opencode/coder"
agent_id = coder_agent.main.id
workdir = "/workspaces"

opencode_model = "claude-3.7-sonnet"

mcp_servers = jsonencode({
filesystem = {
type = "local"
command = ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/workspaces"]
}
github = {
type = "local"
command = ["npx", "-y", "@modelcontextprotocol/server-github"]
environment = {
GITHUB_TOKEN = var.github_token
}
}
})
}
```

For remote MCP servers, use `type: "remote"` with a `url`:

```tf
mcp_servers = jsonencode({
context7 = {
type = "remote"
url = "https://mcp.context7.com/mcp"
}
})
```

See [OpenCode MCP documentation](https://opencode.ai/docs/mcp-servers/) for more details.

### Advanced

| Variable | Description | Default |
| --------------------- | ------------------------------------------------------------------- | ------- |
| `opencode_config` | Full custom OpenCode config (JSON). Overrides other config options. | `""` |
| `pre_install_script` | Script to run before install | `null` |
| `post_install_script` | Script to run after install | `null` |

See [main.tf](./main.tf) for complete variable definitions.

## Features

- 🤖 Multiple AI providers (Copilot, Claude, GPT)
- 🔧 MCP servers configuration support
- 🎯 Model selection per deployment
- 📊 Task reporting to Coder UI
- 💾 Session persistence
- 🔐 Flexible authentication
- 🚀 Node.js tarball installation (no apt/nvm)
- 📌 Version pinning support via `opencode_version`
- 💾 Shared Node.js cache across workspaces

## Complete Template Example

Here's a lightweight template for Coder task execution:

```tf
terraform {
required_providers {
coder = {
source = "coder/coder"
}
docker = {
source = "kreuzwerker/docker"
}
}
}

provider "docker" {}

data "coder_workspace" "me" {}
data "coder_workspace_owner" "me" {}

# Task data source - provides prompts from Coder Tasks UI
data "coder_task" "me" {}

resource "coder_agent" "main" {
arch = "amd64"
os = "linux"

startup_script = <<-EOT
set -e
mkdir -p /workspaces
EOT

env = {
GIT_AUTHOR_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name)
GIT_AUTHOR_EMAIL = data.coder_workspace_owner.me.email
GIT_COMMITTER_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name)
GIT_COMMITTER_EMAIL = data.coder_workspace_owner.me.email
}
}

# OpenCode AI coding agent
module "opencode" {
source = "registry.coder.com/rothnic/opencode/coder"
agent_id = coder_agent.main.id
workdir = "/workspaces"

# Pre-configured authentication (from 'opencode auth login' output)
opencode_auth_config = file("${path.module}/opencode-auth.json")

# Pass task prompt from Coder Tasks UI
ai_prompt = data.coder_task.me.prompt

# Enable task reporting for Coder UI integration
report_tasks = true

# Use subdomain for better app routing (requires wildcard DNS)
# subdomain = true

# Display settings
order = 1
web_app_display_name = "OpenCode AI"
}

resource "docker_container" "workspace" {
count = data.coder_workspace.me.start_count
image = "codercom/enterprise-base:ubuntu"
name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}"

entrypoint = ["sh", "-c", coder_agent.main.init_script]
env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"]
}
```

## Prerequisites

- None - Node.js 20 is automatically installed via tarball

## Notes

- **Node.js installation**: Installed via tarball (not apt/nvm) to `/workspaces/.coder-tools` for reliability and workspace portability
- **OpenCode installation**: Installed via `npm install -g opencode-ai@{version}`
- **Caching**: Node.js and npm cache shared across workspaces in `/workspaces/.coder-tools`
- **Version pinning**: Use `opencode_version` variable to lock to specific versions
- **TUI limitations**: Some interactive features (slash commands, menus) may have limitations through AgentAPI
- **Subdomain access**: For production, use `subdomain = true` with [wildcard access URL](https://coder.com/docs/admin/setup#wildcard-access-url)
- **Task reporting**: When `report_tasks = true`, the module automatically configures system prompts for granular task status updates

## Resources

- [OpenCode Documentation](https://opencode.ai/docs/)
- [OpenCode GitHub](https://github.com/opencode-ai/opencode)
- [AgentAPI](https://github.com/coder/agentapi)
Loading