ZeroRoot Docs
Coding agent

Set up the coding agent

Install the zerocool plugin into opencode. Enroll the host once in a browser. Spend the one-time bootstrap token on the first start. Then run unattended.

This page takes you from an empty workstation to an enrolled coding agent. Steps 2 and 3 need a person. Every start after that needs nobody.

Prerequisites

ToolWhy
opencodeThe editor the plugin extends. See opencode.ai to install it.
gibsonSign in and mint the bootstrap token. See Install.
Node 22 or later, and pnpm 10Build the plugin. The repo pins the pnpm version.
A Gibson tenant you are a member ofIf your account is not an active member, enrollment fails.
An LLM provider configured on that tenantCompletions route through the harness to the tenant's provider. Without a provider, enrollment still succeeds, but the first prompt returns a 500. See Configuration & troubleshooting.

Self-hosted install? Where this page shows https://api.zeroroot.ai, use your platform's API host, for example https://api.<your-domain>. The flow is otherwise identical.

1. Install the plugin

Build the plugin from source:

git clone https://github.com/zeroroot-ai/zerocool-plugins.git
cd zerocool-plugins
pnpm install
pnpm build

Then point opencode at the build. opencode loads any TypeScript file in .opencode/plugin/ in your project. A one-line re-export is enough. Use the absolute path to your clone:

mkdir -p .opencode/plugin
cat > .opencode/plugin/zerocool.ts <<'EOF'
export { GibsonPlugin } from "/absolute/path/to/zerocool-plugins/packages/opencode-gibson/dist/index.js"
EOF

If you want the plugin in every project, put the same file in ~/.config/opencode/plugin/ instead. It then loads in every opencode session. While you evaluate the plugin, prefer the project-level file.

2. Sign in as yourself

gibson login --gibson-url https://api.zeroroot.ai

The CLI prints a URL and a short code, for example PXJT-TJDQ.

  1. Open the URL.
  2. Sign in.
  3. Confirm the code.

This is the OAuth 2.0 device flow, the same one Getting started uses.

3. Mint the one-time token

gibson agent enroll --name zerocool

The command prints a bootstrap token. The CLI shows the token once. The token expires in 24 hours. The first check-in consumes it. Copy it now.

4. First start, with the token

Start opencode once with the token in the environment:

GIBSON_PLATFORM_URL=https://api.zeroroot.ai \
GIBSON_BOOTSTRAP_TOKEN=<token from step 3> \
opencode

On success, stderr shows:

[zerocool] Gibson connected via first check-in (component_scope=...); provider "gibson" auto-configured at http://127.0.0.1:8787 ...
[zerocool] Host key written to /home/you/.zerocool/host.key. The bootstrap token is spent ...
[zerocool] N Gibson tool(s) registered

The full lines also tell you to select a gibson/<slot> model and to unset GIBSON_BOOTSTRAP_TOKEN. Do both. The model selection routes completions through the harness. The token is now useless.

5. Every start after

Remove the token. It is spent.

GIBSON_PLATFORM_URL=https://api.zeroroot.ai opencode

Now stderr says connected via the registered host key. That is the unattended path. You use it from here on.

The plugin reads the host key file to decide which path to take. It does not read the environment for this decision. If ~/.zerocool/host.key exists, the plugin ignores GIBSON_BOOTSTRAP_TOKEN completely. The check-in rejects a one-time token replayed on every start anyway. A replayed token would also keep a spent credential in your environment forever.

What the first check-in does

StepWhat happens
HandshakeThe plugin exchanges the bootstrap token for a capability grant and registers zerocool as a component of your tenant.
Host keyThe plugin writes a persistent key to ~/.zerocool/host.key. The key identifies this install.
HeartbeatThe component reports itself as live for as long as the session runs.
ShimA local OpenAI-compatible endpoint starts on port 8787 and forwards to the harness.
ProviderThe plugin adds a gibson provider to the opencode config at load time. You configure nothing.
DiscoveryThe plugin reads the tenant registry once and registers each Gibson tool as an opencode tool.

Tool discovery runs once, at load. opencode reads the tool list as a static set. A tool registered in your tenant mid-session does not reach the model. After you enroll new tools, restart opencode.

On this page