builder

package module
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Aug 11, 2026 License: MIT Imports: 30 Imported by: 0

README

builder

A togo plugin that gives a project an autonomous agent fleet — and a blueprint you scaffold new projects from.

A bug report becomes an issue on a kanban board. A triage agent classifies it. An orchestrator claims it under a fenced database lease and delegates it to a specialist from a fleet you generated by handing over a plan. That agent runs as a real Claude Code session in an isolated workspace on a real git branch and writes a verdict; the runner, never the agent, derives the facts, runs the gates and opens the PR.

Around that loop: a project brain with provenance, scheduled ingestion sources, a secrets vault, chat, an MCP server and a terminal.

Quickstart

npx create-togo-builder@latest acme     # no Go, no togo installed
togo builder new acme                   # via togo's external command dispatch
togo-builder new acme                   # standalone binary

togo-builder doctor                     # 20 preflight probes before you rely on it

Minimum environment — copy .env.example to .env:

DATABASE_URL=postgres://localhost:5432/builder_dev?sslmode=disable
BUILDER_VAULT_KEY=$(openssl rand -base64 32)   # required; fatal at boot if missing
BUILDER_ADMIN_EMAIL=you@example.com

The agent loop stays off until BUILDER_RUNNER=1. It spends money.

The two ways to run it

In-process plugin

builder registers into the product's own togo kernel and is served by the product's binary. In the reference host ../builder-dev/, that is port 3000 for the dashboard dev server and port 8080 for the API.

togo install togo-framework/builder

Simple, and wrong for what builder is for: it lives inside the process it observes, so a rebuild, a deploy or a panic takes the issue board down with the product.

docs/run-in-process.md

Standalone daemon

builderd/ is builder as its own binary, on port 8099, with its own database (builder_standalone). It serves the SDK shell and iframes the product, so it stays up while the product is rebuilt, deployed or broken. That is its entire purpose.

cd builderd && ./run.sh
curl -s http://localhost:8099/api/health
# {"status":"ok","service":"builderd"}

The dashboard is compiled into the binary and served at http://localhost:8099/builder/ — nothing needs to be checked out or built for it to work, and / redirects there. BUILDER_WEB_DIR is an optional override for developing the dashboard itself.

run.sh resolves BUILDER_VAULT_KEY and AUTH_SECRET from builder-dev/.env and rebuilds the binary.

The service field is what distinguishes the daemon from the product — 8099 is not a reserved port, and a 200 there proves nothing on its own.

docs/run-standalone.md

Documentation

Start at docs/README.md — it routes you to one file in one hop.

architecture.md The eight providers, the package map, the claim mechanism
run-in-process.md Plugin mode
run-standalone.md The builderd daemon, the shell, multiple targets
agent-runs-tmux.md Watching a live run: tmux attach -t builder-issue-<n>-<attempt>
custom-apps.md Adding a screen without editing builder
brain.md The project brain — and how good recall really is
sources.md github, rss, slack, crawl, whatsapp, sql
environment.md Every BUILDER_* variable, with the file that reads it
http-api.md The route map
cli.md togo-builder new | app | doctor | seed | version
troubleshooting.md The five failures that cost real debugging time

Six providers, one install target

togo install togo-framework/builder resolves exactly one togo.plugin.yaml, so builder ships as one repo and one module — but registers independent kernel providers (vault, brain, notify, issues, fleet, orchestrator, sources, apps). Each is disableable today and extractable to its own repo tomorrow:

BUILDER_DISABLE=vault,brain togo serve

One repo per provider on day one would mean as many release pipelines and a cross-repo version graph before anything ran.

Custom apps

builder's ten screens are not the limit. A custom app is an eleventh, added by dropping a directory into apps/ — a manifest and an ES module, discovered at boot. No file in builder names it.

togo-builder app new changelog --title "Changelog" --title-ar "سجل التغييرات"
togo-builder app new metrics --go      # …plus a Go backend that registers via init()
togo-builder app list                  # what would load, and what was rejected

A fleet agent does not need the CLI. list_apps and create_app on the agents MCP server are the same generator reachable from inside a run, so an agent that decides mid-issue the product needs a screen adds one itself and sees it live without a restart. Not on the feedback server — an app ships code the dashboard executes, and the token you wire into a shared editor must not be able to do that.

One broken app costs exactly one tile: a malformed manifest, a missing module or an Init that errors is recorded and skipped, and GET /api/builder/apps/_health says which app and why. An extension point that could take builder down would break the one promise the SDK makes.

docs/custom-apps.md · contract in blueprint/_claude/skills/custom-app/SKILL.md

Development

go build ./...
go test ./internal/... ./customapps/

builderd/ is a nested module and does not yet build from a bare clone — its go.mod carries replace directives pointing at sibling checkouts, because the togo plugins it depends on (auth, auth-dev, db-postgres, realtime) are not published yet. It builds in a workspace that has them side by side. The in-process plugin build is unaffected.

Two things worth knowing before you extend this

Never pass --bare to Claude Code here. It refuses OAuth entirely and accepts only an API key, so it is incompatible with the subscription auth the preflight verifies.

A client-side hook is not a merge gate. guard-merge-gate.sh constrains the agent's own shell, not the GitHub API. The real control is branch protection with required review and required status checks — the hook is defence in depth.

License

MIT

Documentation

Overview

Package builder is the togo day-0 agentic development harness: a feedback widget, an issue plane, an orchestrator that claims issues under a fenced database lease and delegates them to a fleet of Claude Code agents, per-agent memory, and an audited secret vault.

On `togo install togo-framework/builder` this package is blank-imported into the host app, so init() registers the providers with the kernel.

Six providers register independently so each can be disabled at boot (BUILDER_DISABLE=vault,brain) and extracted to its own repo later without touching the others. That property — independently disableable today, independently extractable tomorrow — is why they are separate providers rather than one monolithic Provide().

Index

Constants

View Source
const (
	ProviderVault        = "builder.vault"        // no deps; secrets other providers read
	ProviderBrain        = "builder.brain"        // reads vault for driver tokens
	ProviderIssues       = "builder.issues"       // the issue plane + HTTP surface
	ProviderFleet        = "builder.fleet"        // agent registry + .claude/ sync
	ProviderOrchestrator = "builder.orchestrator" // claim/lease/route/triage
	ProviderNotify       = "builder.notify"       // realtime + push + sound
	ProviderSources      = "builder.sources"      // scheduled ingestion into the brain
	ProviderApps         = "builder.apps"         // user-supplied screens, discovered at boot
	ProviderWeb          = "builder.web"          // the dashboard itself, from the embedded bundle
)

Provider names. Each is a separate kernel provider with its own priority so boot order is explicit rather than emergent.

View Source
const BlueprintVersion = "0.1.0"

BlueprintVersion is stamped into a generated project's togo.yaml so `togo-builder blueprint upgrade` knows which template the project came from and which migrations it has already seen.

It is deliberately separate from Version: the plugin can be patched without changing what a fresh scaffold produces, and a blueprint can change without forcing every installed app to upgrade the plugin.

View Source
const Name = "builder"

Name is the plugin's stable identifier.

View Source
const WebMount = "/builder"

WebMount is where the dashboard lives, in every build that serves it.

ONE prefix, and not one of the screens' own names. The routes are /issues, /agents, /chat, /vault, /terminal — words a host application is entirely likely to have already used, and whose handlers its own router would answer first. Mounting each at the root of somebody else's product is a collision waiting to happen and, in the case of a Next.js or SPA host, a guaranteed 404: the host serves its own index for /issues and the builder's router never sees the request.

/builder is claimed once, is unlikely to be taken, and reads as what it is. It matches vite's `base` in web/vite.config.ts — the asset URLs in the built index.html are stamped with the same prefix, so this constant and the bundle cannot disagree.

Variables

View Source
var Version = "dev"

Version is the plugin module version. Set by the release build via -ldflags "-X github.com/togo-framework/builder.Version=$TAG"; "dev" locally.

Functions

func AssetFiles

func AssetFiles() (fs.FS, error)

AssetFiles returns the asset tree rooted at "/", ready for http.FileServer.

func SDKFiles

func SDKFiles() (fs.FS, error)

SDKFiles returns the bundle rooted at "/", ready for http.FileServer.

func WebFiles added in v0.2.0

func WebFiles() (fs.FS, error)

WebFiles returns the built dashboard rooted at "/", ready for http.FileServer.

Types

This section is empty.

Directories

Path Synopsis
Package blueprint carries the project template as an embedded filesystem.
Package blueprint carries the project template as an embedded filesystem.
_project/internal/plugins
Locally-developed plugins, blank-imported so their init() registers with the kernel.
Locally-developed plugins, blank-imported so their init() registers with the kernel.
cmd
togo-builder command
Command togo-builder scaffolds and operates builder projects.
Command togo-builder scaffolds and operates builder projects.
Package customapps is builder's custom-app extension point: a way to add a screen to the builder — a tile in the SDK launcher and a route of its own — without editing builder's source.
Package customapps is builder's custom-app extension point: a way to add a screen to the builder — a tile in the SDK launcher and a route of its own — without editing builder's source.
internal
authz
Package authz supplies the permission check that togo's auth plugin does not.
Package authz supplies the permission check that togo's auth plugin does not.
brain
Package brain gives each agent its own memory.
Package brain gives each agent its own memory.
chat
Package chat is the advisory surface: pick an agent and talk to it.
Package chat is the advisory surface: pick an agent and talk to it.
db/seeders
Package seeders creates the rows a fresh project cannot boot usefully without.
Package seeders creates the rows a fresh project cannot boot usefully without.
docs
Package docs is the project's reference library: the files a person would hand a new engineer, made available to the fleet.
Package docs is the project's reference library: the files a person would hand a new engineer, made available to the fleet.
fleet
Package fleet turns an operator's plan into a working agent team.
Package fleet turns an operator's plan into a working agent team.
issues
Package issues owns the issue plane: the public feedback ingress the SDK posts to, and the per-route listing it reads back.
Package issues owns the issue plane: the public feedback ingress the SDK posts to, and the per-route listing it reads back.
mcp
Package mcp exposes the builder over the Model Context Protocol, so an agent running anywhere — Claude Code, Codex, any MCP client — can read the issue board and talk to this fleet and its memory.
Package mcp exposes the builder over the Model Context Protocol, so an agent running anywhere — Claude Code, Codex, any MCP client — can read the issue board and talk to this fleet and its memory.
notify
Package notify pushes agent events to a logged-in admin in real time.
Package notify pushes agent events to a logged-in admin in real time.
orchestrator
Package orchestrator owns the agent loop: it triages incoming reports, claims work under a fenced database lease, and delegates it.
Package orchestrator owns the agent loop: it triages incoming reports, claims work under a fenced database lease, and delegates it.
runner
Package runner owns everything that executes outside the app process: the Claude Code session, the git worktree, the gates, and the preflight that proves the environment can run any of it.
Package runner owns everything that executes outside the app process: the Claude Code session, the git worktree, the gates, and the preflight that proves the environment can run any of it.
scaffold
Package scaffold renders a new builder project.
Package scaffold renders a new builder project.
setup
Package setup owns the welcome wizard.
Package setup owns the welcome wizard.
skills
Package skills owns the skill catalogue: the reusable instruction files that agents load by name.
Package skills owns the skill catalogue: the reusable instruction files that agents load by name.
sources
Package sources runs saved read-only queries against real databases on a schedule and retains the rendered result as project memory.
Package sources runs saved read-only queries against real databases on a schedule and retains the rendered result as project memory.
term
Package term gives the dashboard a real terminal, attached to a tmux session on the machine the builder runs on.
Package term gives the dashboard a real terminal, attached to a tmux session on the machine the builder runs on.
vault
Package vault stores the credentials agents need, encrypted at rest, with every reveal audited.
Package vault stores the credentials agents need, encrypted at rest, with every reveal audited.

Jump to

Keyboard shortcuts

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