From e92d730d2cc5e18c9bbf01691b974803165ea413 Mon Sep 17 00:00:00 2001 From: euxaristia <25621994+euxaristia@users.noreply.github.com> Date: Fri, 10 Jul 2026 02:28:21 -0400 Subject: [PATCH 1/6] docs: add Go code quality & security checks and bump Go version to 1.26+ --- AGENTS.md | 12 ++++++++++++ README.md | 25 +++++++++++++++++++++++-- README_ZH.md | 4 ++-- docs/INSTALL.md | 4 ++-- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 25c139876..2cd6aeec1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -331,3 +331,15 @@ That's it. Run `zero` from the repo root and the agent has the team's full instr - [docs/SPECIALISTS.md](docs/SPECIALISTS.md) — full specialist manifest spec. - [docs/STREAM_JSON_PROTOCOL.md](docs/STREAM_JSON_PROTOCOL.md) — `zero exec` I/O contract. - [docs/INSTALL.md](docs/INSTALL.md) — install from source or release. + +## 10. Repository Guidelines for coding agents + +If you are an AI coding agent executing tasks in this repository, you **MUST** run all Go code quality and security checks before committing code or completing your task: + +1. **Formatting**: Run `go fmt ./...` (or `make fmt`) to format code. +2. **Vetting**: Run `go vet ./...` (or `make vet`) to check for common mistakes. +3. **Linting**: Run `golangci-lint run` to inspect code style and quality. +4. **Vulnerability Scanning**: Run `govulncheck ./...` to check for security vulnerabilities. + +If any of these tools (`golangci-lint` or `govulncheck`) are not installed or are unavailable in the path when you attempt to run them, do not ignore the check. You must prompt the user with instructions to install them (e.g., `go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest` or `go install golang.org/x/vuln/cmd/govulncheck@latest`) and ask for confirmation/action before proceeding. + diff --git a/README.md b/README.md index 769f5e989..584223160 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@

license - Go 1.25+ + Go 1.26+ 25+ providers
English | 中文 @@ -75,7 +75,7 @@ irm https://raw.githubusercontent.com/Gitlawb/zero/main/scripts/install.ps1 | ie ### From source -Source builds require Go 1.25+. +Source builds require Go 1.26+. ```bash git clone https://github.com/Gitlawb/zero.git @@ -320,6 +320,27 @@ go run ./cmd/zero-release smoke go run ./cmd/zero-perf-bench ``` +### Code Quality and Security Checks + +Before committing any changes, run all Go code quality and security checks: + +1. **Formatting**: Run `go fmt ./...` (or `make fmt`). +2. **Vetting**: Run `go vet ./...` (or `make vet`). +3. **Linting**: Run `golangci-lint run`. +4. **Vulnerability Scan**: Run `govulncheck ./...`. + +If `golangci-lint` or `govulncheck` are not installed, install them with: + +```bash +# Install golangci-lint +go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest + +# Install govulncheck +go install golang.org/x/vuln/cmd/govulncheck@latest +``` + +### Cross-Compile Examples + Cross-compile examples: ```bash diff --git a/README_ZH.md b/README_ZH.md index ccc932780..51ad388ef 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -6,7 +6,7 @@

license - Go 1.25+ + Go 1.26+ 25+ providers
English | 中文 @@ -56,7 +56,7 @@ irm https://raw.githubusercontent.com/Gitlawb/zero/main/scripts/install.ps1 | ie ### 从源码构建 -源码构建需要 Go 1.25+。 +源码构建需要 Go 1.26+。 ```bash git clone https://github.com/Gitlawb/zero.git diff --git a/docs/INSTALL.md b/docs/INSTALL.md index f2fea45b0..f6a391b98 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -4,7 +4,7 @@ Zero is distributed as: - an npm package, `@gitlawb/zero` - release archives on GitHub Releases -- source builds with Go 1.25+ +- source builds with Go 1.26+ The install scripts download a platform-specific release archive and require a published GitHub Release for the requested version. The npm package is @@ -125,7 +125,7 @@ Build a local binary: go build -o zero ./cmd/zero ``` -Source builds require Go 1.25+. +Source builds require Go 1.26+. ### Sandbox Helpers For Source Builds From 0fac5a181735f26d63ffade512c123d3ab0a951c Mon Sep 17 00:00:00 2001 From: euxaristia <25621994+euxaristia@users.noreply.github.com> Date: Fri, 10 Jul 2026 02:43:38 -0400 Subject: [PATCH 2/6] docs: address CodeRabbit review comments and use pinned versions and Go 1.26.5+ --- AGENTS.md | 10 +++++----- README.md | 16 ++++++++-------- README_ZH.md | 4 ++-- docs/INSTALL.md | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 2cd6aeec1..e1e670184 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -336,10 +336,10 @@ That's it. Run `zero` from the repo root and the agent has the team's full instr If you are an AI coding agent executing tasks in this repository, you **MUST** run all Go code quality and security checks before committing code or completing your task: -1. **Formatting**: Run `go fmt ./...` (or `make fmt`) to format code. -2. **Vetting**: Run `go vet ./...` (or `make vet`) to check for common mistakes. -3. **Linting**: Run `golangci-lint run` to inspect code style and quality. -4. **Vulnerability Scanning**: Run `govulncheck ./...` to check for security vulnerabilities. +1. **Format & Vet**: Run `go fmt ./...` and `go vet ./...`. +2. **Lint**: Run `go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2 run --enable-only unused,ineffassign,staticcheck ./...`. +3. **Security**: Run `go run golang.org/x/vuln/cmd/govulncheck@v1.3.0 ./...`. + +If any check fails or cannot be run, do not ignore it. Prompt the user for instructions or setup assistance before proceeding. -If any of these tools (`golangci-lint` or `govulncheck`) are not installed or are unavailable in the path when you attempt to run them, do not ignore the check. You must prompt the user with instructions to install them (e.g., `go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest` or `go install golang.org/x/vuln/cmd/govulncheck@latest`) and ask for confirmation/action before proceeding. diff --git a/README.md b/README.md index 584223160..337de2dad 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@

license - Go 1.26+ + Go 1.26.5+ 25+ providers
English | 中文 @@ -75,7 +75,7 @@ irm https://raw.githubusercontent.com/Gitlawb/zero/main/scripts/install.ps1 | ie ### From source -Source builds require Go 1.26+. +Source builds require Go 1.26.5+. ```bash git clone https://github.com/Gitlawb/zero.git @@ -322,21 +322,21 @@ go run ./cmd/zero-perf-bench ### Code Quality and Security Checks -Before committing any changes, run all Go code quality and security checks: +Before committing any changes, ensure all Go code quality and security checks pass. Pinned `go run` commands matching CI constraints can be used directly without prior installation: 1. **Formatting**: Run `go fmt ./...` (or `make fmt`). 2. **Vetting**: Run `go vet ./...` (or `make vet`). -3. **Linting**: Run `golangci-lint run`. -4. **Vulnerability Scan**: Run `govulncheck ./...`. +3. **Linting**: Run `go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2 run --enable-only unused,ineffassign,staticcheck ./...`. +4. **Vulnerability Scan**: Run `go run golang.org/x/vuln/cmd/govulncheck@v1.3.0 ./...`. -If `golangci-lint` or `govulncheck` are not installed, install them with: +If you prefer to install these tools globally on your path, you can run: ```bash # Install golangci-lint -go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest +go install github.com/golangci/golangci-lint/cmd/golangci-lint@v2.12.2 # Install govulncheck -go install golang.org/x/vuln/cmd/govulncheck@latest +go install golang.org/x/vuln/cmd/govulncheck@v1.3.0 ``` ### Cross-Compile Examples diff --git a/README_ZH.md b/README_ZH.md index 51ad388ef..e02d56284 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -6,7 +6,7 @@

license - Go 1.26+ + Go 1.26.5+ 25+ providers
English | 中文 @@ -56,7 +56,7 @@ irm https://raw.githubusercontent.com/Gitlawb/zero/main/scripts/install.ps1 | ie ### 从源码构建 -源码构建需要 Go 1.26+。 +源码构建需要 Go 1.26.5+。 ```bash git clone https://github.com/Gitlawb/zero.git diff --git a/docs/INSTALL.md b/docs/INSTALL.md index f6a391b98..b65a0493f 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -4,7 +4,7 @@ Zero is distributed as: - an npm package, `@gitlawb/zero` - release archives on GitHub Releases -- source builds with Go 1.26+ +- source builds with Go 1.26.5+ The install scripts download a platform-specific release archive and require a published GitHub Release for the requested version. The npm package is @@ -125,7 +125,7 @@ Build a local binary: go build -o zero ./cmd/zero ``` -Source builds require Go 1.26+. +Source builds require Go 1.26.5+. ### Sandbox Helpers For Source Builds From 322b0d24bae1c6678a6656be064fcdc3762585f4 Mon Sep 17 00:00:00 2001 From: euxaristia <25621994+euxaristia@users.noreply.github.com> Date: Fri, 10 Jul 2026 12:23:39 -0400 Subject: [PATCH 3/6] docs: remove trailing blank lines at end of AGENTS.md --- AGENTS.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index e1e670184..2ff6d6396 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -341,5 +341,3 @@ If you are an AI coding agent executing tasks in this repository, you **MUST** r 3. **Security**: Run `go run golang.org/x/vuln/cmd/govulncheck@v1.3.0 ./...`. If any check fails or cannot be run, do not ignore it. Prompt the user for instructions or setup assistance before proceeding. - - From 831257bcadb3fa4349a3eab8b392dc42ab01f611 Mon Sep 17 00:00:00 2001 From: euxaristia <25621994+euxaristia@users.noreply.github.com> Date: Sat, 11 Jul 2026 08:41:51 -0400 Subject: [PATCH 4/6] docs: add missing /v2/ segment to golangci-lint install path The go install command pointed at the v1 module path (golangci-lint/cmd/golangci-lint), which does not resolve for v2.12.2. The go run invocation earlier in the same section already had the correct v2 path. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 337de2dad..47be384cc 100644 --- a/README.md +++ b/README.md @@ -333,7 +333,7 @@ If you prefer to install these tools globally on your path, you can run: ```bash # Install golangci-lint -go install github.com/golangci/golangci-lint/cmd/golangci-lint@v2.12.2 +go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2 # Install govulncheck go install golang.org/x/vuln/cmd/govulncheck@v1.3.0 From b588f0576ab9650d1d55295fbae06a324805d610 Mon Sep 17 00:00:00 2001 From: euxaristia <25621994+euxaristia@users.noreply.github.com> Date: Sat, 11 Jul 2026 13:08:33 -0400 Subject: [PATCH 5/6] docs: trim AGENTS.md below 8 KiB guideline and clean up README cross-compile header --- AGENTS.md | 327 +--------------------------------------------- README.md | 2 - docs/EXTENDING.md | 327 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 332 insertions(+), 324 deletions(-) create mode 100644 docs/EXTENDING.md diff --git a/AGENTS.md b/AGENTS.md index 2ff6d6396..35b775f6a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,338 +1,21 @@ --- -description: Extending Zero — how to write AGENTS.md files, custom specialists, skills, hooks, MCP servers, and plugins for the open-source CLI coding agent. +description: Project guidelines for the open-source CLI coding agent (zero) repository. globs: "*.go, *.js, *.md, *.json, *.toml, *.yaml, *.yml" alwaysApply: false --- -# Extending Zero +# Repository Conventions for Zero -Zero is an open-source terminal coding agent. Out of the box it does the obvious things — read, edit, run, search — but the design point of the project is that **every surface is configurable**. This document is the user-facing guide for that configuration. +This file outlines the project conventions and repository guidelines for coding agents when working on the `zero` repository. For the general guide on how to extend Zero (write specialist sub-agents, hooks, plugins, MCP, skills), see [docs/EXTENDING.md](docs/EXTENDING.md). -If you only want to *use* Zero, the [README](README.md) is enough. This page is for the other three jobs: - -1. Tell the agent about *your* project (drop an `AGENTS.md` in your repo). -2. Add new specialist sub-agents. -3. Wire Zero into the rest of your toolchain (MCP, skills, hooks, plugins). - -## 1. Drop a project `AGENTS.md` - -When Zero starts in a directory, it looks for project-level instructions and injects them into the system prompt. The lookup walks from your current working directory **up to the nearest git root** and reads the first matching file at each level — general rules at the repo root, more specific rules in sub-trees. Files are labeled with their directory in the prompt (e.g. `## Project guidelines (services/api/AGENTS.md)`). - -Accepted file names, in priority order at each level: - -| Path | Notes | -| --- | --- | -| `./AGENTS.md` | The classic spot — committed to your repo, shared with the team. | -| `./ZERO.md` | Brand-specific alias. Same format, lower priority. | -| `./.zero/AGENTS.md` | Project-local, hidden, gitignored. Personal notes that stay out of git. | - -Matching is **case-insensitive** on the basename, so `AGENTS.md`, `Agents.md`, and `agents.md` resolve to the same file on Windows and macOS. The git-tracked filename in this repo is `AGENTS.md` — keep that on case-sensitive filesystems (Linux, the WSL filesystem, or a CI runner) to match what the loader looks for. - -Both files use the same format. YAML frontmatter is optional; the markdown body is loaded as instructions for the agent. Zero reads the file once at session start, so changes take effect on the next `zero` launch — not mid-session. - -```markdown -# Project conventions for +## 1. Project Conventions - Build with `make`, not `go build` directly. - Tests live next to the source file (`foo_test.go` next to `foo.go`). - Run `make lint` before opening a PR. - Never edit files under `third_party/` — those are vendored. -``` - -Tips: - -- Keep each file under ~8 KiB. Zero caps the **total** across all matched files at 32 KiB; everything past the cap is dropped. -- Re-state rules in the imperative voice: "Run `make lint`", not "you should consider running the linter". -- Don't put secrets, model IDs, or environment-specific paths in `AGENTS.md`. Use `config.json` for those. -- In a monorepo, drop a narrower `AGENTS.md` in each sub-tree (e.g. `services/api/AGENTS.md`). Zero picks those up automatically when you launch from inside the sub-tree. -- A YAML frontmatter block (`---\n...\n---`) at the top is preserved verbatim in the injected prompt but is not parsed for `globs:` or `alwaysApply:` scoping today — keep the body self-contained. - -### Personal guidelines, across every project - -For preferences that follow *you*, not a specific repo (tone, tooling habits, workflow), drop a `ZERO.md` in your user config directory: `~/.config/zero/ZERO.md` on Linux/macOS, `%AppData%\Roaming\zero\ZERO.md` on Windows — the same directory as `config.json` and your personal specialists. Same format and 8 KiB cap as the project files above, and the same case-insensitive basename match. - -This file is injected as its own `## User guidelines` section, before the project's `AGENTS.md`/`ZERO.md`, and is labeled as personal preference in the prompt: project guidelines are the later, more specific instruction and take precedence over it when the two conflict. - -## 2. Custom specialists - -Specialists are Zero's sub-agents. Three scopes, in priority order: - -| Scope | Path | Shared? | -| --- | --- | --- | -| Built-in | compiled into Zero | yes — `worker`, `explorer`, `code-review` | -| User | `~/.config/zero/specialists/*.md` | no — your machine only | -| Project | `./.zero/specialists/*.md` | yes — the repo team | - -Project overrides user overrides built-in when names collide. - -A specialist is a markdown manifest with frontmatter and a system prompt: - -```markdown ---- -description: Reviews API changes for breaking-change risk and missing tests. -tools: read-only,plan ---- - -You review API changes. For every changed hunk in `internal/api/` or any file -that ends in `_api.go`: - -1. Confirm the public signature is backward-compatible, or note the breaking - change explicitly with the migration path. -2. Confirm a corresponding test exists in `internal/api/*_test.go` and that - the new behaviour is exercised. -3. Flag any new exported symbol without a doc comment. - -Reply with one JSON object per finding: `{"file", "line", "severity", "message", "fix"}`. -``` - -CLI management (the prompt is passed inline via `--prompt`): - -```bash -zero specialist list -zero specialist show api-reviewer -zero specialist create api-reviewer \ - --project \ - --description "Reviews API changes" \ - --tools read-only,plan \ - --prompt "$(cat api-reviewer.md)" -zero specialist edit api-reviewer --project -zero specialist delete api-reviewer --project -zero specialist path # prints the resolved specialists directory -``` - -The full format spec (frontmatter fields, tool scopes, prompt conventions) is in [`docs/SPECIALISTS.md`](docs/SPECIALISTS.md). - -> **Roadmap.** An in-UI specialist manager (create / edit / delete / preview) is on the backlog. Today you use the `zero specialist` CLI subcommands above. - -## 3. Skills - -Skills are markdown instruction packs the agent can pull in on demand. Each skill is a directory containing a `SKILL.md`. Skills are **user-level only** in this version — there's no project-scoped skill directory yet, so anything you want shared with the team goes in `AGENTS.md` (section 1) or as a hook (section 4). - -Discovery root: `$ZERO_SKILLS_DIR` → `$XDG_DATA_HOME/zero/skills` → `~/.local/share/zero/skills/`. A missing directory is fine — Zero just reports "no skills". - -``` -~/.local/share/zero/skills/ - run-benchmarks/ - SKILL.md - write-changelog/ - SKILL.md -``` - -`SKILL.md` format: - -```markdown ---- -description: Run the project's benchmark suite and summarize the deltas. ---- - -# Run benchmarks - -1. `make bench` — captures the wall-clock and RSS before and after. -2. `benchstat before.txt after.txt` — diffs the two. -3. Report any regression > 5% with the function name and the previous value. -``` - -Only `name` and `description` are recognized in the frontmatter today. The `name` defaults to the directory name. Within a single skills root, duplicate names are resolved by lexicographic directory order. During an agent run, Zero loads the default skills directory before plugin skill roots; earlier roots win name collisions silently. Plugin-declared skills (section 6) are merged into the active agent run at plugin activation time, so bundled skills appear in the available skills list and can be loaded with the `skill` tool. - -The `skill` core tool lets the agent load any discovered skill by name. - -## 4. Hooks - -Hooks fire shell commands on lifecycle events. Configure them in JSON: - -- User: `~/.config/zero/hooks.json` -- Project: `./.zero/hooks.json` - -```json -{ - "enabled": true, - "hooks": [ - { - "id": "block-rm-rf", - "event": "beforeTool", - "matcher": "bash", - "command": "/usr/local/bin/zero-hook-block-rmrf.sh", - "enabled": true - }, - { - "id": "log-session", - "event": "sessionStart", - "command": "/usr/local/bin/zero-hook-log.sh", - "enabled": true - } - ] -} -``` - -The `args` array (when present) is passed verbatim to `exec.CommandContext`. The actual hook payload — event name, matcher, tool call id, tool name, tool input, tool output, status — is delivered to the command as **JSON on stdin**, not via `${...}` substitution. A typical handler reads stdin and decides what to do: - -```bash -#!/usr/bin/env bash -# /usr/local/bin/zero-hook-block-rmrf.sh -set -euo pipefail -payload="$(cat)" -if printf '%s' "$payload" | grep -q '"input":"[^"]*rm[[:space:]]+-rf'; then - echo "refusing rm -rf" >&2 - exit 1 -fi -``` - -Events the agent emits (in dispatch order): - -| Event | Fires when | Matcher allowed? | -| --- | --- | --- | -| `beforeTool` | A tool is about to run | yes (tool name) | -| `afterTool` | A tool just returned | yes (tool name) | -| `sessionStart` | A session begins | no | -| `sessionEnd` | A session ends | no | -| `specialistStart` | A sub-agent is spawned | yes (specialist name) | -| `specialistStop` | A sub-agent ends | yes (specialist name) | - -A hook's exit code decides what happens next: `0` continues, non-zero blocks the tool call (`beforeTool`) or surfaces an error (`afterTool`). Hook execution is recorded in the audit log; the audit is reachable from the agent's view of past actions, not from a dedicated `zero doctor` check. - -> **Roadmap.** An in-UI hooks manager is on the backlog. Today you edit the JSON directly. - -## 5. MCP — Model Context Protocol - -Zero is both an **MCP client** (it can call external MCP servers) and an **MCP server** (other agents can call its tools). - -### As a client — configure MCP servers in `config.json` - -```json -{ - "mcp": { - "servers": { - "docs": { - "type": "stdio", - "command": "docs-mcp", - "args": ["--port", "7777"] - }, - "github": { - "type": "http", - "url": "https://api.example.com/mcp", - "headers": { "Authorization": "Bearer YOUR_TOKEN_HERE" } - } - } - } -} -``` - -Manage via CLI: - -```bash -zero mcp add docs --type stdio -- docs-mcp --port 7777 -zero mcp add github --type http --url https://api.example.com/mcp \ - --header "Authorization=Bearer YOUR_TOKEN_HERE" -zero mcp list -zero mcp check docs -zero mcp remove github -zero mcp oauth login github -``` - -Servers are merged from user and project configs (project wins on conflicts). Token-bearing values in `config.json` are sent verbatim — there is no `${env:...}` expansion — so prefer one of: - -- A wrapper script that sources the secret and execs the real command. -- A `--header` value produced by command substitution (`"Authorization=Bearer $(print-token)"`) in a private shell config that you keep out of git. -- A secret manager that injects the env var your MCP server reads on its own (the `command` and `args` then run inside that environment). - -Project MCP config remains supported for shared team servers, but a project layer -that changes an existing server's target (`url`, `command`, or `args`) does not -inherit user credentials. Clear or replace `headers`, `env`, or `oauth` explicitly, -or use a new server name. OAuth tokens are bound to the resolved server identity, -so changing a server target can require `zero mcp oauth login ` again. -OAuth server names ending in `.<32 hex chars>` are reserved for token storage. - -### As a server — expose Zero's tools to another agent - -```bash -zero serve --mcp -``` - -The server speaks MCP over stdio. Configure it from the receiving side as a `stdio` server whose command is `zero serve --mcp`. - -## 6. Plugins - -A plugin is a self-contained directory that bundles tools, hooks, and skills for one capability. Plugins live at: - -- User: `~/.config/zero/plugins//` -- Project: `./.zero/plugins//` - -Each plugin has a `plugin.json` manifest: - -```json -{ - "id": "github-pr-review", - "name": "GitHub PR Review", - "description": "Adds review tools for GitHub PRs.", - "version": "1.0.0", - "tools": [ - { "name": "list_prs", "command": "./tools/list_prs.sh" } - ], - "hooks": [ - { "name": "pre-merge-check", "event": "beforeTool", "command": "./hooks/pre-merge.sh" } - ], - "skills": [ - { "path": "./skills/review-checklist/SKILL.md" } - ] -} -``` - -Install and manage: - -```bash -zero plugins add ./github-pr-review # copy into ~/.config/zero/plugins/ or ./.zero/plugins/ -zero plugins list -zero plugins remove github-pr-review # alias: rm -``` - -A plugin is enabled by being present in the plugins directory and disabled by removing it (or by the user setting `"enabled": false` in its `plugin.json`). Plugins are not enabled or disabled by a CLI subcommand today. - -Plugin commands run with the plugin directory as their working directory. Use relative paths; the loader resolves them at activation time. - -> **Roadmap.** An in-UI plugins manager (browse, install, enable / disable) is on the backlog. Today you use the `zero plugins` CLI subcommands above. - -## 7. Configuration locations - -Three layers, applied in order (later layers override earlier ones): - -| Layer | Path | Notes | -| --- | --- | --- | -| Built-in defaults | compiled in | Lowest priority. | -| User config | `~/.config/zero/config.json` | Your machine. Never committed. | -| Project config | `./.zero/config.json` | The repo. Committed (or not, your call). | -| CLI flags | `--model`, `--mode`, ... | Highest priority, per-invocation. | -| Environment | `ZERO_*` | Provider commands, secrets, skills dir override. | - -The user config holds things that should follow the user across projects (default provider, default model, theme). The project config holds things the team agreed on (provider catalog, sandbox policies, model restrictions). - -The sandbox `additionalWriteRoots` key is **ignored in project config** by design — a checked-out repo cannot widen its own sandbox. Set it in the user config or pass `--add-dir` per-invocation. - -## 8. End-to-end example - -A team that wants every contributor's Zero to behave the same way commits: - -- `AGENTS.md` — project conventions, build commands, do-not-edit lists. -- `.zero/config.json` — provider catalog, default model, allowed tools. -- `.zero/specialists/api-reviewer.md` — the team's PR-review specialist. -- `.zero/hooks.json` — block `rm -rf` and `git push --force` on `beforeTool`. -- `.zero/plugins/internal-tooling/` — a plugin that adds the team's internal CLI tools to the agent's toolset. - -Each contributor adds only: - -- `~/.config/zero/config.json` — their personal API keys, theme, default mode. -- `~/.config/zero/ZERO.md` — personal preferences that follow them across every project (see section 1). -- `~/.local/share/zero/skills/` — personal skills they keep across projects. - -That's it. Run `zero` from the repo root and the agent has the team's full instruction set, every contributor's personal setup, and nothing else. - -## 9. Reference - -- [README](README.md) — install, quickstart, command reference. -- [docs/SPECIALISTS.md](docs/SPECIALISTS.md) — full specialist manifest spec. -- [docs/STREAM_JSON_PROTOCOL.md](docs/STREAM_JSON_PROTOCOL.md) — `zero exec` I/O contract. -- [docs/INSTALL.md](docs/INSTALL.md) — install from source or release. -## 10. Repository Guidelines for coding agents +## 2. Guidelines for Coding Agents If you are an AI coding agent executing tasks in this repository, you **MUST** run all Go code quality and security checks before committing code or completing your task: diff --git a/README.md b/README.md index 47be384cc..7f3240251 100644 --- a/README.md +++ b/README.md @@ -341,8 +341,6 @@ go install golang.org/x/vuln/cmd/govulncheck@v1.3.0 ### Cross-Compile Examples -Cross-compile examples: - ```bash go run ./cmd/zero-release build --goos linux --goarch amd64 go run ./cmd/zero-release build --goos windows --goarch amd64 --output dist/zero.exe diff --git a/docs/EXTENDING.md b/docs/EXTENDING.md new file mode 100644 index 000000000..36dbf5c6d --- /dev/null +++ b/docs/EXTENDING.md @@ -0,0 +1,327 @@ +# Extending Zero + +Zero is an open-source terminal coding agent. Out of the box it does the obvious things — read, edit, run, search — but the design point of the project is that **every surface is configurable**. This document is the user-facing guide for that configuration. + +If you only want to *use* Zero, the [README](README.md) is enough. This page is for the other three jobs: + +1. Tell the agent about *your* project (drop an `AGENTS.md` in your repo). +2. Add new specialist sub-agents. +3. Wire Zero into the rest of your toolchain (MCP, skills, hooks, plugins). + +## 1. Drop a project `AGENTS.md` + +When Zero starts in a directory, it looks for project-level instructions and injects them into the system prompt. The lookup walks from your current working directory **up to the nearest git root** and reads the first matching file at each level — general rules at the repo root, more specific rules in sub-trees. Files are labeled with their directory in the prompt (e.g. `## Project guidelines (services/api/AGENTS.md)`). + +Accepted file names, in priority order at each level: + +| Path | Notes | +| --- | --- | +| `./AGENTS.md` | The classic spot — committed to your repo, shared with the team. | +| `./ZERO.md` | Brand-specific alias. Same format, lower priority. | +| `./.zero/AGENTS.md` | Project-local, hidden, gitignored. Personal notes that stay out of git. | + +Matching is **case-insensitive** on the basename, so `AGENTS.md`, `Agents.md`, and `agents.md` resolve to the same file on Windows and macOS. The git-tracked filename in this repo is `AGENTS.md` — keep that on case-sensitive filesystems (Linux, the WSL filesystem, or a CI runner) to match what the loader looks for. + +Both files use the same format. YAML frontmatter is optional; the markdown body is loaded as instructions for the agent. Zero reads the file once at session start, so changes take effect on the next `zero` launch — not mid-session. + +```markdown +# Project conventions for + +- Build with `make`, not `go build` directly. +- Tests live next to the source file (`foo_test.go` next to `foo.go`). +- Run `make lint` before opening a PR. +- Never edit files under `third_party/` — those are vendored. +``` + +Tips: + +- Keep each file under ~8 KiB. Zero caps the **total** across all matched files at 32 KiB; everything past the cap is dropped. +- Re-state rules in the imperative voice: "Run `make lint`", not "you should consider running the linter". +- Don't put secrets, model IDs, or environment-specific paths in `AGENTS.md`. Use `config.json` for those. +- In a monorepo, drop a narrower `AGENTS.md` in each sub-tree (e.g. `services/api/AGENTS.md`). Zero picks those up automatically when you launch from inside the sub-tree. +- A YAML frontmatter block (`---\n...\n---`) at the top is preserved verbatim in the injected prompt but is not parsed for `globs:` or `alwaysApply:` scoping today — keep the body self-contained. + +### Personal guidelines, across every project + +For preferences that follow *you*, not a specific repo (tone, tooling habits, workflow), drop a `ZERO.md` in your user config directory: `~/.config/zero/ZERO.md` on Linux/macOS, `%AppData%\Roaming\zero\ZERO.md` on Windows — the same directory as `config.json` and your personal specialists. Same format and 8 KiB cap as the project files above, and the same case-insensitive basename match. + +This file is injected as its own `## User guidelines` section, before the project's `AGENTS.md`/`ZERO.md`, and is labeled as personal preference in the prompt: project guidelines are the later, more specific instruction and take precedence over it when the two conflict. + +## 2. Custom specialists + +Specialists are Zero's sub-agents. Three scopes, in priority order: + +| Scope | Path | Shared? | +| --- | --- | --- | +| Built-in | compiled into Zero | yes — `worker`, `explorer`, `code-review` | +| User | `~/.config/zero/specialists/*.md` | no — your machine only | +| Project | `./.zero/specialists/*.md` | yes — the repo team | + +Project overrides user overrides built-in when names collide. + +A specialist is a markdown manifest with frontmatter and a system prompt: + +```markdown +--- +description: Reviews API changes for breaking-change risk and missing tests. +tools: read-only,plan +--- + +You review API changes. For every changed hunk in `internal/api/` or any file +that ends in `_api.go`: + +1. Confirm the public signature is backward-compatible, or note the breaking + change explicitly with the migration path. +2. Confirm a corresponding test exists in `internal/api/*_test.go` and that + the new behaviour is exercised. +3. Flag any new exported symbol without a doc comment. + +Reply with one JSON object per finding: `{"file", "line", "severity", "message", "fix"}`. +``` + +CLI management (the prompt is passed inline via `--prompt`): + +```bash +zero specialist list +zero specialist show api-reviewer +zero specialist create api-reviewer \ + --project \ + --description "Reviews API changes" \ + --tools read-only,plan \ + --prompt "$(cat api-reviewer.md)" +zero specialist edit api-reviewer --project +zero specialist delete api-reviewer --project +zero specialist path # prints the resolved specialists directory +``` + +The full format spec (frontmatter fields, tool scopes, prompt conventions) is in [`docs/SPECIALISTS.md`](docs/SPECIALISTS.md). + +> **Roadmap.** An in-UI specialist manager (create / edit / delete / preview) is on the backlog. Today you use the `zero specialist` CLI subcommands above. + +## 3. Skills + +Skills are markdown instruction packs the agent can pull in on demand. Each skill is a directory containing a `SKILL.md`. Skills are **user-level only** in this version — there's no project-scoped skill directory yet, so anything you want shared with the team goes in `AGENTS.md` (section 1) or as a hook (section 4). + +Discovery root: `$ZERO_SKILLS_DIR` → `$XDG_DATA_HOME/zero/skills` → `~/.local/share/zero/skills/`. A missing directory is fine — Zero just reports "no skills". + +``` +~/.local/share/zero/skills/ + run-benchmarks/ + SKILL.md + write-changelog/ + SKILL.md +``` + +`SKILL.md` format: + +```markdown +--- +description: Run the project's benchmark suite and summarize the deltas. +--- + +# Run benchmarks + +1. `make bench` — captures the wall-clock and RSS before and after. +2. `benchstat before.txt after.txt` — diffs the two. +3. Report any regression > 5% with the function name and the previous value. +``` + +Only `name` and `description` are recognized in the frontmatter today. The `name` defaults to the directory name. Within a single skills root, duplicate names are resolved by lexicographic directory order. During an agent run, Zero loads the default skills directory before plugin skill roots; earlier roots win name collisions silently. Plugin-declared skills (section 6) are merged into the active agent run at plugin activation time, so bundled skills appear in the available skills list and can be loaded with the `skill` tool. + +The `skill` core tool lets the agent load any discovered skill by name. + +## 4. Hooks + +Hooks fire shell commands on lifecycle events. Configure them in JSON: + +- User: `~/.config/zero/hooks.json` +- Project: `./.zero/hooks.json` + +```json +{ + "enabled": true, + "hooks": [ + { + "id": "block-rm-rf", + "event": "beforeTool", + "matcher": "bash", + "command": "/usr/local/bin/zero-hook-block-rmrf.sh", + "enabled": true + }, + { + "id": "log-session", + "event": "sessionStart", + "command": "/usr/local/bin/zero-hook-log.sh", + "enabled": true + } + ] +} +``` + +The `args` array (when present) is passed verbatim to `exec.CommandContext`. The actual hook payload — event name, matcher, tool call id, tool name, tool input, tool output, status — is delivered to the command as **JSON on stdin**, not via `${...}` substitution. A typical handler reads stdin and decides what to do: + +```bash +#!/usr/bin/env bash +# /usr/local/bin/zero-hook-block-rmrf.sh +set -euo pipefail +payload="$(cat)" +if printf '%s' "$payload" | grep -q '"input":"[^"]*rm[[:space:]]+-rf'; then + echo "refusing rm -rf" >&2 + exit 1 +fi +``` + +Events the agent emits (in dispatch order): + +| Event | Fires when | Matcher allowed? | +| --- | --- | --- | +| `beforeTool` | A tool is about to run | yes (tool name) | +| `afterTool` | A tool just returned | yes (tool name) | +| `sessionStart` | A session begins | no | +| `sessionEnd` | A session ends | no | +| `specialistStart` | A sub-agent is spawned | yes (specialist name) | +| `specialistStop` | A sub-agent ends | yes (specialist name) | + +A hook's exit code decides what happens next: `0` continues, non-zero blocks the tool call (`beforeTool`) or surfaces an error (`afterTool`). Hook execution is recorded in the audit log; the audit is reachable from the agent's view of past actions, not from a dedicated `zero doctor` check. + +> **Roadmap.** An in-UI hooks manager is on the backlog. Today you edit the JSON directly. + +## 5. MCP — Model Context Protocol + +Zero is both an **MCP client** (it can call external MCP servers) and an **MCP server** (other agents can call its tools). + +### As a client — configure MCP servers in `config.json` + +```json +{ + "mcp": { + "servers": { + "docs": { + "type": "stdio", + "command": "docs-mcp", + "args": ["--port", "7777"] + }, + "github": { + "type": "http", + "url": "https://api.example.com/mcp", + "headers": { "Authorization": "Bearer YOUR_TOKEN_HERE" } + } + } + } +} +``` + +Manage via CLI: + +```bash +zero mcp add docs --type stdio -- docs-mcp --port 7777 +zero mcp add github --type http --url https://api.example.com/mcp \ + --header "Authorization=Bearer YOUR_TOKEN_HERE" +zero mcp list +zero mcp check docs +zero mcp remove github +zero mcp oauth login github +``` + +Servers are merged from user and project configs (project wins on conflicts). Token-bearing values in `config.json` are sent verbatim — there is no `${env:...}` expansion — so prefer one of: + +- A wrapper script that sources the secret and execs the real command. +- A `--header` value produced by command substitution (`"Authorization=Bearer $(print-token)"`) in a private shell config that you keep out of git. +- A secret manager that injects the env var your MCP server reads on its own (the `command` and `args` then run inside that environment). + +Project MCP config remains supported for shared team servers, but a project layer +that changes an existing server's target (`url`, `command`, or `args`) does not +inherit user credentials. Clear or replace `headers`, `env`, or `oauth` explicitly, +or use a new server name. OAuth tokens are bound to the resolved server identity, +so changing a server target can require `zero mcp oauth login ` again. +OAuth server names ending in `.<32 hex chars>` are reserved for token storage. + +### As a server — expose Zero's tools to another agent + +```bash +zero serve --mcp +``` + +The server speaks MCP over stdio. Configure it from the receiving side as a `stdio` server whose command is `zero serve --mcp`. + +## 6. Plugins + +A plugin is a self-contained directory that bundles tools, hooks, and skills for one capability. Plugins live at: + +- User: `~/.config/zero/plugins//` +- Project: `./.zero/plugins//` + +Each plugin has a `plugin.json` manifest: + +```json +{ + "id": "github-pr-review", + "name": "GitHub PR Review", + "description": "Adds review tools for GitHub PRs.", + "version": "1.0.0", + "tools": [ + { "name": "list_prs", "command": "./tools/list_prs.sh" } + ], + "hooks": [ + { "name": "pre-merge-check", "event": "beforeTool", "command": "./hooks/pre-merge.sh" } + ], + "skills": [ + { "path": "./skills/review-checklist/SKILL.md" } + ] +} +``` + +Install and manage: + +```bash +zero plugins add ./github-pr-review # copy into ~/.config/zero/plugins/ or ./.zero/plugins/ +zero plugins list +zero plugins remove github-pr-review # alias: rm +``` + +A plugin is enabled by being present in the plugins directory and disabled by removing it (or by the user setting `"enabled": false` in its `plugin.json`). Plugins are not enabled or disabled by a CLI subcommand today. + +Plugin commands run with the plugin directory as their working directory. Use relative paths; the loader resolves them at activation time. + +> **Roadmap.** An in-UI plugins manager (browse, install, enable / disable) is on the backlog. Today you use the `zero plugins` CLI subcommands above. + +## 7. Configuration locations + +Three layers, applied in order (later layers override earlier ones): + +| Layer | Path | Notes | +| --- | --- | --- | +| Built-in defaults | compiled in | Lowest priority. | +| User config | `~/.config/zero/config.json` | Your machine. Never committed. | +| Project config | `./.zero/config.json` | The repo. Committed (or not, your call). | +| CLI flags | `--model`, `--mode`, ... | Highest priority, per-invocation. | +| Environment | `ZERO_*` | Provider commands, secrets, skills dir override. | + +The user config holds things that should follow the user across projects (default provider, default model, theme). The project config holds things the team agreed on (provider catalog, sandbox policies, model restrictions). + +The sandbox `additionalWriteRoots` key is **ignored in project config** by design — a checked-out repo cannot widen its own sandbox. Set it in the user config or pass `--add-dir` per-invocation. + +## 8. End-to-end example + +A team that wants every contributor's Zero to behave the same way commits: + +- `AGENTS.md` — project conventions, build commands, do-not-edit lists. +- `.zero/config.json` — provider catalog, default model, allowed tools. +- `.zero/specialists/api-reviewer.md` — the team's PR-review specialist. +- `.zero/hooks.json` — block `rm -rf` and `git push --force` on `beforeTool`. +- `.zero/plugins/internal-tooling/` — a plugin that adds the team's internal CLI tools to the agent's toolset. + +Each contributor adds only: + +- `~/.config/zero/config.json` — their personal API keys, theme, default mode. +- `~/.config/zero/ZERO.md` — personal preferences that follow them across every project (see section 1). +- `~/.local/share/zero/skills/` — personal skills they keep across projects. + +That's it. Run `zero` from the repo root and the agent has the team's full instruction set, every contributor's personal setup, and nothing else. + +## 9. Reference + +- [README](README.md) — install, quickstart, command reference. +- [docs/SPECIALISTS.md](docs/SPECIALISTS.md) — full specialist manifest spec. +- [docs/STREAM_JSON_PROTOCOL.md](docs/STREAM_JSON_PROTOCOL.md) — `zero exec` I/O contract. +- [docs/INSTALL.md](docs/INSTALL.md) — install from source or release. From 8ff0c87c01b603da8677a1782282036e9241fab4 Mon Sep 17 00:00:00 2001 From: euxaristia <25621994+euxaristia@users.noreply.github.com> Date: Sat, 11 Jul 2026 13:22:07 -0400 Subject: [PATCH 6/6] docs: address CodeRabbit review feedback on extending guide --- docs/EXTENDING.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/EXTENDING.md b/docs/EXTENDING.md index 36dbf5c6d..5c76d1cc6 100644 --- a/docs/EXTENDING.md +++ b/docs/EXTENDING.md @@ -2,7 +2,7 @@ Zero is an open-source terminal coding agent. Out of the box it does the obvious things — read, edit, run, search — but the design point of the project is that **every surface is configurable**. This document is the user-facing guide for that configuration. -If you only want to *use* Zero, the [README](README.md) is enough. This page is for the other three jobs: +If you only want to *use* Zero, the [README](../README.md) is enough. This page is for the other three jobs: 1. Tell the agent about *your* project (drop an `AGENTS.md` in your repo). 2. Add new specialist sub-agents. @@ -43,7 +43,7 @@ Tips: ### Personal guidelines, across every project -For preferences that follow *you*, not a specific repo (tone, tooling habits, workflow), drop a `ZERO.md` in your user config directory: `~/.config/zero/ZERO.md` on Linux/macOS, `%AppData%\Roaming\zero\ZERO.md` on Windows — the same directory as `config.json` and your personal specialists. Same format and 8 KiB cap as the project files above, and the same case-insensitive basename match. +For preferences that follow *you*, not a specific repo (tone, tooling habits, workflow), drop a `ZERO.md` in your user config directory: `~/.config/zero/ZERO.md` on Linux/macOS, `%AppData%\zero\ZERO.md` on Windows — the same directory as `config.json` and your personal specialists. Same format and 8 KiB cap as the project files above, and the same case-insensitive basename match. This file is injected as its own `## User guidelines` section, before the project's `AGENTS.md`/`ZERO.md`, and is labeled as personal preference in the prompt: project guidelines are the later, more specific instruction and take precedence over it when the two conflict. @@ -94,17 +94,17 @@ zero specialist delete api-reviewer --project zero specialist path # prints the resolved specialists directory ``` -The full format spec (frontmatter fields, tool scopes, prompt conventions) is in [`docs/SPECIALISTS.md`](docs/SPECIALISTS.md). +The full format spec (frontmatter fields, tool scopes, prompt conventions) is in [`docs/SPECIALISTS.md`](SPECIALISTS.md). > **Roadmap.** An in-UI specialist manager (create / edit / delete / preview) is on the backlog. Today you use the `zero specialist` CLI subcommands above. ## 3. Skills -Skills are markdown instruction packs the agent can pull in on demand. Each skill is a directory containing a `SKILL.md`. Skills are **user-level only** in this version — there's no project-scoped skill directory yet, so anything you want shared with the team goes in `AGENTS.md` (section 1) or as a hook (section 4). +Skills are markdown instruction packs the agent can pull in on demand. Each skill is a directory containing a `SKILL.md`. Standalone project skill directories are not supported in this version (shared project-wide skills must go in `AGENTS.md` or as a hook). However, project plugins (section 6) may bundle skills, which are merged into the active run. Discovery root: `$ZERO_SKILLS_DIR` → `$XDG_DATA_HOME/zero/skills` → `~/.local/share/zero/skills/`. A missing directory is fine — Zero just reports "no skills". -``` +```text ~/.local/share/zero/skills/ run-benchmarks/ SKILL.md @@ -287,15 +287,15 @@ Plugin commands run with the plugin directory as their working directory. Use re ## 7. Configuration locations -Three layers, applied in order (later layers override earlier ones): +Five configuration sources, in precedence order (later sources override earlier ones): -| Layer | Path | Notes | +| Source | Path / Key | Notes | | --- | --- | --- | | Built-in defaults | compiled in | Lowest priority. | | User config | `~/.config/zero/config.json` | Your machine. Never committed. | | Project config | `./.zero/config.json` | The repo. Committed (or not, your call). | -| CLI flags | `--model`, `--mode`, ... | Highest priority, per-invocation. | | Environment | `ZERO_*` | Provider commands, secrets, skills dir override. | +| CLI flags | `--model`, `--mode`, ... | Highest priority, per-invocation. | The user config holds things that should follow the user across projects (default provider, default model, theme). The project config holds things the team agreed on (provider catalog, sandbox policies, model restrictions). @@ -308,7 +308,7 @@ A team that wants every contributor's Zero to behave the same way commits: - `AGENTS.md` — project conventions, build commands, do-not-edit lists. - `.zero/config.json` — provider catalog, default model, allowed tools. - `.zero/specialists/api-reviewer.md` — the team's PR-review specialist. -- `.zero/hooks.json` — block `rm -rf` and `git push --force` on `beforeTool`. +- `.zero/hooks.json` — block `rm -rf` on `beforeTool`. - `.zero/plugins/internal-tooling/` — a plugin that adds the team's internal CLI tools to the agent's toolset. Each contributor adds only: @@ -321,7 +321,7 @@ That's it. Run `zero` from the repo root and the agent has the team's full instr ## 9. Reference -- [README](README.md) — install, quickstart, command reference. -- [docs/SPECIALISTS.md](docs/SPECIALISTS.md) — full specialist manifest spec. -- [docs/STREAM_JSON_PROTOCOL.md](docs/STREAM_JSON_PROTOCOL.md) — `zero exec` I/O contract. -- [docs/INSTALL.md](docs/INSTALL.md) — install from source or release. +- [README](../README.md) — install, quickstart, command reference. +- [docs/SPECIALISTS.md](SPECIALISTS.md) — full specialist manifest spec. +- [docs/STREAM_JSON_PROTOCOL.md](STREAM_JSON_PROTOCOL.md) — `zero exec` I/O contract. +- [docs/INSTALL.md](INSTALL.md) — install from source or release.