Minimal, secure-by-default agentic harness (Go). The library is the product API; protocol extensions and workflow packs are detachable modules. The Rust mowi sibling project is the TUI host over mow's RPC interface.
Embedder / tests ──┐
CLI (run/tty) ────┼──▶ mow.Engine ──▶ LLM HTTP (any compatible endpoint)
ext + packs ──────┘ (acp · mcp · goal · review · …)
Why mow: the core module has two runtime dependencies (pty, yaml) — no SDK, no framework; any OpenAI- or Anthropic-compatible endpoint over plain HTTP; extensions detach by removing a blank import; secure defaults (read-only tools, workspace path jail, out-of-band project trust). OpenTelemetry remains optional and never enters a library-only embed.
Version is the single line in
VERSION. Tagv$(cat VERSION)after bumping that file. Nix and GitHub Releases read the same file. RPC epoch is still"1"(unrelated to the tag). Themow/ext/ packs APIs may still change until 1.0.0.
import "github.com/subosito/mow"
eng, err := mow.New(mow.Options{
AllowWrite: false,
// ConfigPaths, SessionID, Continue, …
})
res, err := eng.Prompt(ctx, "list go files")
// res.Text, res.SessionIDOne-shot: mow.Run(ctx, prompt, opt). The engine is multi-turn — call
eng.Prompt again and history carries.
What the embed gives you beyond a one-liner:
- Custom transport / logging —
Options.HTTPClient(proxy, timeouts) andOptions.Logger(capture*slogwithout touching the global default). - Custom LLM backend —
Options.Provider(streaming, tool calls, and token usage all preserved), orOptions.Chatfor quick fakes. - Per-engine tools —
Options.Tools; two engines in one process can run different toolsets. - Events & tokens —
Options.OnEventfor the lifecycle stream;RunResult.Usage/loop.run.endfor provider-reported token totals. - Sessions —
eng.Sessions()lists resumable sessions;Options.SessionID/Continueresume one.
Full walkthrough with code: docs/embedding.md.
devenv shell -- just verify
devenv shell -- just build # → bin/mow (embeds VERSION)
# Nix (after first vendorHash fill):
# nix build # → ./result/bin/mow
# nix run . -- version
# Or with plain Go:
go build -o bin/mow ./cmd/mow
export OPENAI_BASE_URL=https://api.openai.com/v1
export OPENAI_API_KEY=sk-…
export OPENAI_MODEL=gpt-5-mini
# Or any OpenAI-compatible gateway:
# export OPENAI_BASE_URL=http://127.0.0.1:PORT/v1
# export OPENAI_API_KEY=…
./bin/mow run -p "Reply with exactly: hi"
./bin/mow tty
./bin/mow goal run --goal "Make CI green" # packs/goal — multi-step
./bin/mow review # packs/review — advisory review
./bin/mow sec --format sarif # advisory security review / SARIF
./bin/mow job # packs/job — interval jobs
./bin/mow acp # ext/acp — ACP agent
./bin/mow rpc # ext/rpc — JSON-lines
./bin/mow help # linked commands, dynamically
Pack-owned subcommands: stock binaries blank-import linked packs. Remove an
import (for example _ "github.com/subosito/mow/ext/acp") and its tools and
subcommand disappear from that binary and help.
Secure default tools: read, glob, grep. Power tools need
--allow-write / --allow-shell. Project .mow config/skills load only after
mow trust (stored out-of-band under $MOW_HOME, so a cloned repo cannot trust
itself), and never set credentials, endpoints, or power tools.
Three Go modules (go.work wires them for local dev). Full public/internal map:
docs/architecture.md.
| Path / module | Role |
|---|---|
mow.go + internal/ |
Public API re-export and implementation |
ext/ + cliutil/ + extcfg/ |
Core extensions, CLI helpers, extension config decode |
packs/ |
Optional packs: goal, review, ops, job |
packs/otel/ |
Nested OTLP module |
cmd/mow/ |
Sole full pack host (links ext + optional packs and OTEL) |
import (
"github.com/subosito/mow"
_ "github.com/subosito/mow/ext/mcp" // core protocol extension
_ "github.com/subosito/mow/packs/ops" // optional domain pack
)Import only github.com/subosito/mow for the Engine library. Add individual
ext/* or packs/* imports as needed. Import
github.com/subosito/mow/packs/otel only when OTLP auto-wiring is wanted.
Config: extensions.<pack> (see internal/config/mow.yaml.example).
Docs: docs/extensions.md.
| Doc | Contents |
|---|---|
| AGENTS.md | AI agents: build, spine, conventions |
| docs/architecture.md | Public/internal and module boundaries |
| docs/embedding.md | Embed in Go: options, events, custom tools/providers, hooks, sessions |
| docs/harness.md | Loop, tools, config |
| docs/review.md | Shared review workflow, --reviewer / --verifier, scope, formats, CI |
| docs/sec.md | Read-only security review and evidence model |
| packs/*/README.md, ext/*/README.md | Per-pack / per-extension one-pagers |
| docs/extensions.md | Core extensions, optional packs, ACP, MCP/LSP, media |
MIT