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

zot

package module
v0.17.0 Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2026 License: MIT Imports: 13 Imported by: 0

README

zot-icon-dark

zot

Hand it a software task and get back finished, tested code. zot is an automated software factory in a single binary - an autonomous coding harness that plans, edits, runs, and verifies until the work is done.

About 11 MiB. One binary, with no hosted engine and no telemetry.

zot demo

The point

zot is not another coding agent you sit with and steer prompt by prompt. Its reason to exist is fully autonomous software work: give it a goal, walk away, and come back to a finished result. It will sometimes fall short of that ideal, especially while it is 0.x, but the ideal is the design constraint. We are not building workflows or features that contradict it.

If what you want is an interactive coding agent, use Codex, Claude Code, Cursor, or one of the other excellent tools built for that way of working.

What you get

zot takes work orders, not prompts. A work order is a small YAML file: the durable objective, the acceptance criteria that define "done", and the constraints the work must hold to. Write one, hand it over, and walk away:

zot new "add rate limiting to the API, with tests"
# wrote .zot/orders/add-rate-limiting-to-the-api-with-tests.yaml - edit its
# acceptance criteria, then:
zot

zot reads the repo, writes and edits the code, runs the build and the tests, and fixes what it broke - on its own, from that one order to a recorded outcome. When it stops you have a changed working tree and a full session log of every step it took. No chat loop, no approving each edit: one order in, finished work out.

Orders are files, so they compose. A bare zot runs the project's whole book - each order as its own run, in sequence, stopping at the first that does not end in success - and the ledger skips the ones already done, so you write an order and type zot again. Naming order files runs exactly those, from any path. A project's orders and the receipts of what has been run from them live together under .zot/, and both halves point wherever you like - see the book.

They also stream: zot --watch keeps zot up and runs every *.yaml order that lands in the folder as it arrives - a drop-box factory. See watch mode.

zot new scaffolds at three levels of help, all landing in the same reviewable file: bare zot new writes the blank form, zot new "objective" fills the objective in, and zot new --draft "objective" additionally has the configured model propose the acceptance criteria and constraints - as a draft for you to edit, never as a contract it signed itself. A draft is not a blind guess: it runs as a small read-only run through the same engine, surveying the working tree - the build files, the test setup - so the criteria it proposes name the project's real commands and files.

zotui

The release also includes zotui, a browser command center for operating zot as reusable workers. Choose a repository, environment, provider and model, give the worker its mission, then launch runs on demand or on a schedule and follow their output and history from the browser. Workers can run in disposable local Docker containers or on configured remote compute.

https://github.com/user-attachments/assets/304b4f32-c634-4936-a1ec-66bdd792bd66

zotui keeps the same autonomy boundary: it dispatches and observes complete runs; it does not turn zot into a chat-driven coding agent. See Configuring zotui for setup and deployment.

Why zot exists

Most coding tools optimize the conversation between a developer and an agent. zot optimizes the production run: it drives the whole job from one brief, without a follow-up prompt at every step and without a hosted engine.

It talks straight to a model provider over the OpenAI-compatible API - OpenAI, Anthropic, Groq, Mistral, DeepSeek, OpenRouter, a local Ollama, or anything else that speaks the same API - so all you need is a provider key. No account beyond the provider's own, and nothing is sent anywhere except the provider you configure.

Quickstart

Grab a prebuilt binary from the releases page - no toolchain required:

VERSION=vX.Y.Z; OS=linux ARCH=amd64      # e.g. darwin/arm64 on Apple Silicon
curl -L "https://github.com/openzot/openzot/releases/download/${VERSION}/zot-${VERSION}-${OS}-${ARCH}.tar.gz" | tar xz
mv "zot-${VERSION}-${OS}-${ARCH}"/{zot,zotui} ~/.local/bin/   # or any directory on your PATH

zot defaults to the zai provider running glm-5.2. Export a key and give it a job:

export ZAI_API_KEY="…"
zot new "add input validation to the signup handler and a test"
zot

Any OpenAI-compatible provider works - --provider anthropic --model claude-5-sonnet, a local --provider ollama, gateways, or a custom endpoint; see docs/providers.md. To build from source or run the container image, see docs/development.md and docs/docker.md.

How it works

The harness is zot's own, in the agent package:

  • agent.ExecuteWithTools runs the model in a loop - it calls tools, sees the results, and goes again - until it records an outcome (success / failure) or a budget or guard stops it.
  • agent.DefaultTools() gives it the toolbox: read, write, list and shell for the work, plus plan and progress to structure and narrate it. agent.DefaultToolsFor(agent.ToolOptions{Vision: true}) adds view, which shows the model an image file rather than describing one - offered only to a model that can actually see, which zot takes from its catalogue and the operator's config.

That package is importable, so the same engine drives more than coding: Rook, an AI bug-hunting and security-audit agent, is built on it with its own toolset and skills.

What sits under that is the part worth knowing about:

  • Thread assembly fits the conversation to the model's context window, newest-first, keeping tool calls paired with their results.
  • Context strategy decides what happens as that window fills. compact (the default) summarises the older history into a checkpoint with a model call, so a long run keeps a condensed memory of its early turns instead of losing them; truncate simply drops the oldest messages to fit. A checkpoint is preserved verbatim and never re-summarised, and an outright provider rejection falls back to a no-model summary and retries. Configurable - see configs/zot.example.yaml.
  • Loop detection notices when the agent has stopped making progress - four overlapping heuristics, because the obvious one (repeated messages) silently misses reasoning models, which interleave a thought between every tool call.
  • Settle mode ends a run when the agent records an outcome, not when its prose happens to sound final. An answer containing "task completed" is not an ending. Note the boundary, though: settle mode checks that the agent declared done, not that the work is done. The agent verifies its own work by running the tests (its instructions tell it to); zot does not yet independently gate the outcome on a check of its own.
  • Session logs record every run to disk as it happens, so a run nobody watched is still answerable afterwards - and so it can be picked up again with --resume (see docs/configuration.md).

zot itself is a read-only Bubble Tea viewer over that run - it renders the event stream into a scrollable log and has no text input, because the run is autonomous.

Sub-agents and coordination

zot has no native sub-agent primitive, by design. There is no spawn, no built-in supervisor, no fixed orchestration graph baked into the engine - and that absence is deliberate, not a gap waiting to be filled. A fixed hierarchy would decide, in advance, how work should be divided for every task; most tasks do not divide the way the framework guessed.

What the engine gives instead is the raw capability, and it lets the agent decide how to use it:

  • An agent can call into itself. It has a shell tool, so it can invoke zot again - a fresh run with its own brief, its own working directory, its own budget - and read back the result. Delegating a self-contained piece of work to a clean context is a shell command, not a special API. Direct instructions in your AGENTS.md, or a skill, are what tell it when that is worth doing.
  • Agent-to-agent communication is left open, too. zot does not prescribe a message bus or a protocol. Two runs coordinate through whatever they already share - the filesystem (a scratch file, a work queue as a directory of tasks), a git branch, an HTTP endpoint, a channel daemon. The mechanism is a choice the task makes, not one the engine imposes.

The intent is that the agents themselves figure out how to organise and communicate, from the task in front of them, the context in the repository, and any guidance a relevant skill supplies. Encode the pattern you want - a map/reduce fan-out, a reviewer that re-runs the worker, a pipeline of single-purpose runs - as a skill (<name>/SKILL.md), and it becomes available exactly when the model judges it relevant, without changing the engine. Orchestration is content, not framework.

⚠️ Safety

zot is fully autonomous and has real file-write and shell-exec access from --dir. The flag changes the process working directory; it is not a filesystem sandbox. Absolute paths and shell commands retain all permissions of the zot process. Point it at a scratch directory or a disposable git checkout you are happy for it to change - not your home directory.

Configured provider credentials are resolved into zot's in-memory configuration and then removed from the process environment before the agent starts, so its shell commands do not inherit those API keys. Other secrets already present in the environment or readable from disk remain accessible to those commands.

The published container image is the practical way to bound this: the agent can only touch the volume you mounted, and docker run gives you the rest of the levers (read-only root, dropped capabilities, resource limits) in one place.

Status

zot is 0.x: functional and in active use, with improvements landing release to release. Until 1.0 the CLI flags, config, and behavior may still change between versions - pin a version and skim the changelog before upgrading.

Documentation

Ecosystem

Project Role
Rook A fully automated offensive security harness
Pion A defensive AI security harness for automatic mornitoring, and incident prevention
Pantalk Connect coding agents to the chat platforms people already use
MCPShim Turn MCP servers and HTTP APIs into standard CLI commands
crmkit Give agents a shared CRM and system of record over HTTP or MCP

Documentation

Overview

Package zot is the embeddable core of the zot automated software factory. It turns a work order - a durable objective, rendered to a task - into an agentic run - plan, act, observe, exit - and renders the run in a read-only terminal UI.

The agentic loop is zot's own (see the agent package): thread assembly, compaction, loop detection and the tool-call cycle all run locally, against any OpenAI-compatible provider. zot needs no account and no hosted engine.

The standalone binary is cmd/zot; an embedding program can import this package and call Run directly while zot's internals stay internal.

Index

Constants

View Source
const DefaultInstructions = baseInstructions + "\n\n" + nonInteractiveContract

DefaultInstructions is the system prompt handed to the agent when the configuration does not override it. It establishes the fully-autonomous, no-questions-asked contract: zot has no input channel, so the agent must never wait for the user.

The opening and the "act, don't narrate" rule imitate the batch-mode prompt of the engine zot was derived from: a run is a non-interactive background session whose deliverable is the changed working tree, not prose, and which ends only by recording an outcome with a terminal tool.

It is assembled rather than written out because its closing half is not the caller's to drop - see nonInteractiveContract.

Variables

View Source
var ExampleConfigYAML []byte

ExampleConfigYAML is the commented starter config baked into the binary, used by `zot config` to seed ~/.config/zot/config.yaml when it does not exist yet.

Functions

func DefaultConfigPath

func DefaultConfigPath() string

DefaultConfigPath is the default config file location.

func LoadProjectContext

func LoadProjectContext(cfg *Config, dirs ...string) error

LoadProjectContext augments cfg with on-disk context discovered under the given directories, searched in order (typically the config directory first, then the working directory):

  • <dir>/AGENTS.md - appended to the agent instructions
  • <dir>/skills/ - loaded via the SDK and added as a "skills" feature

Missing files and directories are ignored, and duplicate directories are searched once. AGENTS.md content augments (never replaces) the base instructions.

func NewClient added in v0.13.0

func NewClient(cfg Config) (*agent.Client, error)

NewClient resolves the configuration into a provider-backed client, for engine work outside the main run path - the read-only survey that drafts a work order's acceptance criteria, say. A run of record never takes this path: it goes through Run or RunWith, which render, log, and record an outcome.

func Run

func Run(ctx context.Context, cfg Config, task string) error

Run executes one autonomous coding task, rendering the agent's activity in the read-only TUI. The agent's file and shell tools operate on the current working directory, so callers should chdir into the target project first. Run blocks until the user quits the viewer or the program errors.

func RunWith

func RunWith(ctx context.Context, cfg Config, task string, options RunOptions) error

RunWith is Run with session recording and resume.

func Version

func Version() string

Version reports the build version of the linked zot core.

Types

type Config

type Config = config.Config

Config is the fully-resolved zot configuration. Load it with Load; its Validate method enforces the same checks the standalone binary runs.

func Load

func Load(path string) (Config, error)

Load reads configuration, layering defaults < file < env. A missing default file is fine (env vars alone can configure zot).

type RunOptions

type RunOptions struct {
	// SessionDir is where the run's log is written. Empty disables recording.
	SessionDir string

	// Resume seeds the conversation from an earlier session, so a run that ran
	// out of budget or died overnight continues rather than starting again.
	Resume *session.Session

	// OnSession is called once the log is open, with its path. Used to tell the
	// operator where the record is before the run takes over the screen.
	OnSession func(path string)

	// BatchIndex and BatchSize place this run in a batch - order 2 of 5 - so
	// the viewer can show how much of the queue is left. Zero for a run that is
	// not part of a batch.
	BatchIndex int
	BatchSize  int

	// Title is a short label for the work, shown in the viewer instead of the
	// task text. A work order's title, or one derived from its file name;
	// empty falls back to the task. It is presentation only and never reaches
	// the model - the objective is the contract, a title is a label.
	Title string

	// QuitOnDone closes the viewer as soon as the run ends instead of holding
	// the final screen. Set for the intermediate orders of a batch, where a
	// held screen would stall the orders behind it until a keypress nobody
	// unattended will make; the batch's last order still holds for review.
	QuitOnDone bool
}

RunOptions configures a run beyond the configuration itself.

Directories

Path Synopsis
Package agent runs autonomous, tool-using conversations against any OpenAI-compatible model provider.
Package agent runs autonomous, tool-using conversations against any OpenAI-compatible model provider.
cmd
zot command
Command zot is an automated software factory you watch, not drive.
Command zot is an automated software factory you watch, not drive.
zotui command
Command zotui serves the browser command center over the zot engine.
Command zotui serves the browser command center over the zot engine.
Package configs embeds the example configuration files baked into the binaries, used to seed a user's config on first run.
Package configs embeds the example configuration files baked into the binaries, used to seed a user's config on first run.
internal
buildinfo
Package buildinfo reports which kind of binary this is.
Package buildinfo reports which kind of binary this is.
catalogue
Package catalogue records what the engine needs to know about a model before it calls one: how much context it has, how much of that it may spend on the answer, and whether it can use tools or emits a reasoning channel.
Package catalogue records what the engine needs to know about a model before it calls one: how much context it has, how much of that it may spend on the answer, and whether it can use tools or emits a reasoning channel.
compaction
Package compaction condenses a conversation that has outgrown the model's context window.
Package compaction condenses a conversation that has outgrown the model's context window.
config
Package config loads zot's configuration, layering built-in defaults, an optional YAML file, and environment variables (defaults < file < env).
Package config loads zot's configuration, layering built-in defaults, an optional YAML file, and environment variables (defaults < file < env).
imaging
Package imaging recognises image files and prepares them to be shown to a model.
Package imaging recognises image files and prepares them to be shown to a model.
loop
Package loop runs the agentic conversation: call the model, execute the tools it asks for, feed the results back, repeat until the task settles.
Package loop runs the agentic conversation: call the model, execute the tools it asks for, feed the results back, repeat until the task settles.
order
Package order defines the work order: the document a zot run is dispatched from.
Package order defines the work order: the document a zot run is dispatched from.
provider
Package provider talks to OpenAI-compatible chat-completions endpoints.
Package provider talks to OpenAI-compatible chat-completions endpoints.
session
Package session records a run to disk so it can be inspected afterwards and picked up again.
Package session records a run to disk so it can be inspected afterwards and picked up again.
thread
Package thread assembles conversation threads that fit a model's context window, and detects when an agent has stopped making progress.
Package thread assembles conversation threads that fit a model's context window, and detects when an agent has stopped making progress.
tokenizer
Package tokenizer estimates the token cost of model input.
Package tokenizer estimates the token cost of model input.
version
Package version provides build-time version information and update checking for the zot binary.
Package version provides build-time version information and update checking for the zot binary.
watch
Package watch keeps a running zot pointed at a folder - or at a glob naming the orders in one - so work orders are dispatched as they arrive.
Package watch keeps a running zot pointed at a folder - or at a glob naming the orders in one - so work orders are dispatched as they arrive.
zotui/app
Package app implements the command center's worker and run lifecycle.
Package app implements the command center's worker and run lifecycle.
zotui/compute
Package compute abstracts the providers that turn a resolved environment into a running remote computer.
Package compute abstracts the providers that turn a resolved environment into a running remote computer.
zotui/compute/docker
Package docker provides local zotui compute using Docker containers.
Package docker provides local zotui compute using Docker containers.
zotui/compute/vercel
Package vercel provides remote zotui compute using Vercel Sandbox.
Package vercel provides remote zotui compute using Vercel Sandbox.
zotui/config
Package config defines the zotui configuration: the repository connections, compute providers, models, environments that bind compute to an image and env vars, and the store that tracks workers and their runs.
Package config defines the zotui configuration: the repository connections, compute providers, models, environments that bind compute to an image and env vars, and the store that tracks workers and their runs.
zotui/dispatch
Package dispatch executes a worker run on a remote sandbox.
Package dispatch executes a worker run on a remote sandbox.
zotui/ghapp
Package ghapp mints short-lived, repository-scoped GitHub App installation tokens.
Package ghapp mints short-lived, repository-scoped GitHub App installation tokens.
zotui/repo
Package repo abstracts repository connections: where workers get their code and how zotui mints per-run credentials for it.
Package repo abstracts repository connections: where workers get their code and how zotui mints per-run credentials for it.
zotui/repo/github
Package github exposes explicitly configured public GitHub repositories.
Package github exposes explicitly configured public GitHub repositories.
zotui/repo/local
Package local exposes an explicitly configured local checkout without manufacturing a remote credential.
Package local exposes an explicitly configured local checkout without manufacturing a remote credential.
zotui/store
Package store persists workers, their runs, and run output.
Package store persists workers, their runs, and run output.
zotui/web
Package web serves the zot command center and its JSON API.
Package web serves the zot command center and its JSON API.
zotui/worker
Package worker provides the platform-specific Zot executable deployed by the command center into each sandbox.
Package worker provides the platform-specific Zot executable deployed by the command center into each sandbox.
Package tui renders the read-only terminal view of an autonomous agent run.
Package tui renders the read-only terminal view of an autonomous agent run.

Jump to

Keyboard shortcuts

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