Help us shape the future of Go! Take the 2026 Go Developer Survey

squad-opencode

module
v0.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2026 License: MIT

README

squad-opencode

CI Release

Human-led AI agent teams for OpenCode — implemented in Go.

One binary scaffolds a persistent team in your repo (.squad/) and OpenCode agents (.opencode/). You coordinate work; specialists (Lead, Frontend, Backend, Tester) run as OpenCode agents.

Inspired by bradygaster/squad (MIT). OpenCode-native port — not a Copilot fork.
Host API client: official opencode-sdk-go (github.com/sst/opencode-sdk-go).

Install

No Go toolchain. Download the archive for your OS from GitHub Releases and put squad-oc on your PATH. Assets are squad-oc_<version>_<os>_<arch>.zip (Windows) or .tar.gz (macOS/Linux).

# Scoop
scoop bucket add squad https://github.com/xeaser/squad-opencode
scoop install squad-oc

# Homebrew
brew tap xeaser/squad-opencode https://github.com/xeaser/squad-opencode
brew install squad-oc
# The tap ships a cask; existing formula installs migrate via tap_migrations.json.

# winget (from a clone of this repo)
winget install --manifest packaging/winget

squad-oc upgrade --self replaces the binary from the latest release.

Quick start

# 1. Install OpenCode + /connect a provider — https://opencode.ai/docs/

# 2. Install squad-oc from GitHub Releases (see Install above)

# 3. In your project
mkdir my-app && cd my-app && git init
squad-oc init --preset default
squad-oc doctor

# Interactive TUI (does not listen on :4096)
opencode
# Tab → squad agent → "Set up the team for …" → yes

# HTTP API: run auto-starts `opencode serve` on :4096 if nothing is there
squad-oc run -p "Summarize .squad/team.md"

Full walkthrough: docs/get-started.md

Also useful

What to commit

This repo dogfoods Squad on itself. After init + opening OpenCode:

Commit Do not commit
.squad/ team, charters, decisions, .gitignore .squad/comms/* (folder kept via .gitkeep)
.opencode/agents, skills, commands, .gitignore .opencode/node_modules/
opencode.json .opencode/package.json + lockfiles OpenCode generates

OpenCode creates .opencode/package.json (@opencode-ai/plugin) and runs an install on first launch. That is host runtime, not Squad source.

Commands

Command Role
`init [--preset default] [--description ] [--global] [--theme office none]`
upgrade [--dry-run] [--force] [--global] [--self] Refresh host templates; --self replaces this binary from GitHub Releases
doctor / heartbeat Health checks
status / cast Team table
brief [--json] Morning listing: team, PRs, tickets, last done, next, Ralph
cast --add <name> [--role <role>] [--model <provider/id>] Add a member and regenerate .opencode/agents
cast --model <name> <provider/id> Pin a member to an OpenCode model id
cast --model squad <provider/id> Pin the coordinator model
`cast --model <name -> -`
cast --remove <name> Remove a member and regenerate .opencode/agents
cast --theme office / none init --theme office (native @michael) or later cast --theme office (mention map; @lead gone)
recast Regenerate .opencode/agents from .squad/team.md
run -p <prompt> / --file <path> [--agent name] [--url] Prompt the OpenCode HTTP API as squad; auto-starts opencode serve on :4096 only
watch / triage / loop [--execute] [--interval minutes] [--once] [--health] [--url] [--overnight-start HH:MM] [--overnight-end HH:MM] [--label name] [--project N] [--column name] [--force] [--retry-label name] [--log-file path] [--verbose] [--notify-level all|important|none] [--state-backend memory|git-notes|orphan-branch] Issue triage (Ralph); --execute uses run; optional GitHub Project v2 + Status filter; skips issues with an open linked PR unless --force or --retry-label (default ralph-retry)
export [file] / import <file> [--with-host] JSON snapshot of .squad/ (optional host files)
externalize [--key name] / internalize Move this project's team out of the worktree
nap [--dry-run] [--deep] / scrub-emails [directory] Context and PII hygiene
upstream add <name> <path|git-url> / list / remove / sync Remember and pull extra agents/skills
pack <path|git-url> One-shot pull of extra agents/skills
`link <team-dir git-url>/link --sync/link --off`
update-check [--json] [--refresh] Prints up to date or update available vs GitHub latest tag
traces [--last N] [--json] [--export file] [--follow] Local spans plus OpenCode SQLite ingest (TUI/Web/serve); --export writes OTLP JSON; optional live push via OTEL_EXPORTER_OTLP_*
mcp apply / list / init Merge org .squad/mcp-config.json into opencode.json
marketplace add / list / remove / browse / install Register a skills pack and copy a plugin into .opencode/skills/
plugin install <name>@<marketplace> / list / uninstall <name> Named skill install; uninstall removes only .opencode/skills/<name>/
help / version Usage and version string

Layout

cmd/squad-oc/            # main → internal/cli
internal/cli/            # commands
internal/squad/          # init, upgrade, export, externalize, nap, scrub, templates
internal/opencodeclient/ # SDK + run (needs `opencode serve`)
internal/watch/          # issue triage (Ralph): health, overnight, backends
internal/githubissues/   # gh issue list
internal/share/          # upstream / pack / link
internal/traces/         # local JSONL spans + OTLP export
internal/opencodestore/  # read-only OpenCode SQLite (TUI ingest)
internal/selfupdate/     # upgrade --self
internal/updatecheck/
internal/version/
docs/

Architecture

squad-oc (Go)
  ├── embed templates → .squad / .opencode
  └── github.com/sst/opencode-sdk-go → opencode serve (:4096)

opencode (TUI) and opencode serve (HTTP API) are different. Only serve works with run and watch --execute.

run / watch --execute attach to an existing server, or start opencode serve --hostname 127.0.0.1 --port 4096 in this project. They never auto-start if --url or OPENCODE_BASE_URL is anything other than http://127.0.0.1:4096 / http://localhost:4096. The serve process is left running.

upgrade refreshes host templates (.opencode/). It never overwrites team memory (team.md, decisions, knowledge).

upgrade --self downloads the latest GitHub Release for this OS/arch and replaces the running binary. On Windows, if the exe is locked, it writes squad-oc.exe.new beside it (replaced on next start).

traces lists local spans from run and watch --execute, and ingests completed TUI/Web/serve turns from OpenCode SQLite (default $XDG_DATA_HOME/opencode/opencode.db or ~/.local/share/opencode/opencode.db on every OS, including Windows %USERPROFILE%\.local\share\opencode\opencode.db). Override with OPENCODE_DB or opencode_db in .squad/config.json. Dedup is by assistant messageId so a later TUI turn on a CLI session still ingests. --follow polls every 2s. --export file writes OTLP JSON any collector can ingest. Set OTEL_EXPORTER_OTLP_ENDPOINT (or OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) to push live during run / watch --execute and on ingest. Protocols: http/protobuf (default) and grpc via OTEL_EXPORTER_OTLP_PROTOCOL. Prompt/completion bodies always land in local JSONL; OTel message attributes only when OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT is on (default off). Langfuse groups turns by OpenCode ses_* (session.id). For in-process streaming, the official Langfuse OpenCode plugin is optional and separate; we do not install it. Aspire Dashboard remains a valid OTLP consumer, not a shipped squad-oc command.

Share extra agents (upstream / pack)

Your company keeps a security pack — extra OpenCode agents and a Designer charter — in a git repo or a folder on disk.

# One-shot: drop those files into *this* project
squad-oc pack https://github.com/acme/squad-security-pack.git
# or a local folder you already cloned
squad-oc pack ~/packs/security

# Remember it and pull again when the pack updates
squad-oc upstream add security https://github.com/acme/squad-security-pack.git
squad-oc upstream sync security     # next quarter: same command
squad-oc upstream list

pack / sync refresh .opencode/ (agents, skills, commands). New .squad/agents/<name>/ files are added only if missing. team.md, decisions, and existing knowledge are never overwritten.

A pack is just a directory that contains .opencode/ (or a bare agents/ / skills/ / commands/ tree). Optional .squad/agents/… stubs are fine.

Platform Lead, decisions, and knowledge live in one place. Billing and Checkout both use that team.

# once: a dedicated team folder (or any repo that already has .squad/)
mkdir -p ~/teams/platform && cd ~/teams/platform
git init && squad-oc init --preset default --description "Platform team"

cd ~/code/billing
squad-oc init --preset default
squad-oc link ~/teams/platform          # also accepts ~/teams/platform/.squad

cd ~/code/checkout
squad-oc init --preset default
squad-oc link ~/teams/platform

squad-oc status                         # both show the same members
# later
squad-oc link --off                     # this repo uses its local .squad/ again
# or, no local clone — cache lives in ~/.squad-oc/links/
squad-oc link https://github.com/acme/squad-platform.git
squad-oc link --sync                    # fetch updates
squad-oc link --off

link does not move files. Config stays in each repo; team.md / charters / decisions are read from the shared directory. Cannot combine with externalize (that moves this project's own team out of the worktree).

Change the cast (cast --add / cast --remove / recast)
squad-oc cast --add Designer --role Design
# appends Designer to team.md, writes charter/knowledge, regenerates .opencode/agents

squad-oc cast --remove Designer
# drops the member and regenerates .opencode/agents

# or edit .squad/team.md by hand, then:
squad-oc recast

OpenCode only sees agents that exist under .opencode/agents/. Recast is what makes a new row in team.md show up as @designer. It never touches squad.md (the coordinator).

Overnight watch
# poll and execute during the day; sleep 18:00–08:00 local
squad-oc watch --execute --interval 10 --overnight-start 18:00 --overnight-end 08:00

During the quiet window it does not call opencode serve. Stop anytime with touch .squad/ralph-stop.

watch --health prints the last ralph-status.json snapshot. --state-backend git-notes or orphan-branch persists that snapshot across restarts (default is the local file).

Non-goals

Original-Squad / Copilot-host pieces we are not building:

  • GitHub Copilot CLI / Copilot SDK
  • Interactive Ink/squad shell (use the OpenCode TUI)
  • Aspire / .NET dashboard (won’t ship; point any OTLP consumer at optional push or traces --export)

Develop

go test ./...
go build -o squad-oc ./cmd/squad-oc

Requires Go 1.26.6+. How to send a change: CONTRIBUTING.md.

License

MIT — see LICENSE.

Directories

Path Synopsis
cmd
squad-oc command
internal
cli
opencodestore
Package opencodestore reads OpenCode SQLite read-only for traces ingest.
Package opencodestore reads OpenCode SQLite read-only for traces ingest.
selfupdate
Package selfupdate downloads the latest GitHub release binary and replaces this executable.
Package selfupdate downloads the latest GitHub release binary and replaces this executable.
traces
Package traces stores local JSONL spans and exports OTLP JSON.
Package traces stores local JSONL spans and exports OTLP JSON.
watch
Package watch polls issues (Ralph): overnight windows, health snapshots, notify, escalation, and optional git state backends.
Package watch polls issues (Ralph): overnight windows, health snapshots, notify, escalation, and optional git state backends.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL