RELAI

module
v0.3.3 Latest Latest
Warning

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

Go to latest
Published: Nov 5, 2026 License: Apache-2.0

README

Relai

CI Go Reference

Pass the baton between people and their AI agents, across all their projects — without losing context, and without rebuilding what already exists.

Relai is an open, agent-agnostic layer of files in git plus one CLI. No server, no portal:

  • a repo contract (AGENTS.md, relai.yaml, a generated handoff of a few hundred tokens, specs and tasks) so whoever pulls the repo — and their agent — knows the next steps immediately;
  • check before you build: a project index (a plain git repo of relai.yaml files) to find what the other projects already provide before writing a duplicate;
  • one view of all your projects (relai workspace): last activity, open work and what each provides, in about 400 tokens for 16 repos, from files only;
  • an optional golden path: a project template born with all of the above (relai new).

Also shipped: linked repositories (links: in relai.yaml, found with relai discover --links; a person confirms them) and an optional self-hosted team board, RELAI-TEAM. Planned, not built yet (see docs/multi-repo.md): shared conventions that every repo points to, and upstream changes shown in the handoff.

It composes existing standards (AGENTS.md, Agent Skills, OpenSpec, Beads) instead of replacing them.

Status: early development (v0.x, everything may change). Read the design document; the handoff is being evaluated with real agents in eval/.

Made to be easy: one binary, no server, nothing but git. Useful on day one for a single person or a small team; the multi-project features (index, conventions) are optional layers.

Who gets what. Measured on a real set of 16 repositories of one developer working alone with agents: relai workspace (the overview of every project, about 400 tokens) and the handoff are what pay off today. The team board (RELAI-TEAM) answers a problem that starts when several people or agents work in parallel on the same projects; with a single human it adds little. Savings were measured once per case: treat them as indications, not as a guarantee.

How it fits together

flowchart TB
  subgraph repo["Repo contract (every repo)"]
    agents["AGENTS.md (L0, ≤100 lines)"]
    manifest["relai.yaml (id, provides, consumes, links)"]
    notes[".relai/notes.md (decisions, pitfalls)"]
    specs["openspec/ + .beads/ (adapters, optional)"]
  end
  handoff["relai handoff (≤2k tokens, generated from files;<br/>degraded mode if none of the above exists)"]
  repo --> handoff
  index["index.json (relai.yaml of every known project)"]
  repo -- "relai index build" --> index
  view["relai workspace · relai find<br/>(all projects on one page, check before you build)"]
  index --> view
  disc["relai discover --links<br/>(repos of a folder, mentions between them: evidence)"]
  index --> disc
  disc -- "links: written once a person agrees" --> manifest
  hooks["git hooks: pre-commit export, post-merge relai tidy"] --> repo
  tpl["relai new (golden path template)"] --> repo
  person(["Person + their agent"]) -- "git pull, read L0 + L1, then the next task" --> handoff
  person -- "ask before building" --> view
  team["RELAI-TEAM (optional, self-hosted):<br/>board, claims with leases, MCP, issue mirror"] -. "reads the same files" .-> repo
  team --- person
  conv["Shared conventions repo (planned)"] -. "referenced by relai.yaml" .-> repo

Solid arrows are shipped. Dashed ones are planned (shared conventions, see docs/DESIGN.md) or belong to the separate optional board. Everything in Relai itself runs from a single static binary against local git repos — no server, no Docker, no account, including the cross-repo index above.

Relai architecture diagram

Quick start

Install the binary — no Go toolchain needed:

curl -fsSL https://raw.githubusercontent.com/ECG-Rudy-Glt/RELAI/main/scripts/install.sh | sh

The installer checks the download against the release's checksums.txt and refuses to install on a mismatch (details and limits in SECURITY.md). Or download a binary directly from the releases page (Linux/macOS/Windows, amd64/arm64). From source:

go install github.com/ECG-Rudy-Glt/RELAI/cmd/relai@latest   # Go ≥ 1.21 fetches the pinned toolchain (1.26.10) by itself

Then:

cd your-repo
relai init        # adds AGENTS.md (or links it to CLAUDE.md), relai.yaml, .relai/notes.md, and for
                  # Claude Code a CLAUDE.md that imports AGENTS.md plus a session-start hook
relai discover    # lists what the project already gives agents: skills, hooks, specs, tracker, docs
relai handoff     # prints where the work stands, in ≤ 2,000 tokens

Flags can go before or after the arguments (relai init --no-claude dir and relai init dir --no-claude are the same). relai init --hooks also installs a git pre-commit hook that keeps .beads/issues.jsonl (the copy of the task list that lives in git) current, in the very commit that changes the tasks. It asks bd only when bd wrote since the last export, never blocks a commit, and never overwrites a hook you already have.

Adopting Relai in the middle of a project. Nothing is moved or rewritten: relai discover finds the existing harness (AGENTS.md/CLAUDE.md, skills, commands, hooks, MCP servers, Beads or GitHub Issues, OpenSpec or Spec Kit, ADRs, handoff and journal docs, CI) and the handoff points to it. relai discover --prompt prints instructions for your own agent to draft .relai/notes.md (decisions, pitfalls, next step) from those docs; you review the draft and commit it.

The handoff format is specified in spec/handoff.md.

Making agents actually start from it. AGENTS.md tells any agent to run relai handoff first, but that is a request, not a guarantee. With Claude Code, relai init goes further: it adds a CLAUDE.md that imports AGENTS.md (older Claude Code versions read only CLAUDE.md) and a SessionStart hook (.claude/hooks/session-start.sh, registered in .claude/settings.json) whose output is loaded into every session, so the agent starts from the handoff without being asked. If the relai binary is not installed on that machine, the hook prints the plain files (.relai/notes.md, relai.yaml) instead, and it never fails. Existing CLAUDE.md / settings.json files are left alone (the command tells you what to add by hand); relai init --no-claude skips all of this. Claude Code asks you to trust a folder before running its hooks.

relai handoff reads Beads tasks and OpenSpec changes when they are present, and works without them. Beads keeps its database outside git, so a fresh clone has no tasks until you run bd bootstrap --yes (it loads .beads/issues.jsonl). Until then the handoff says so and shows that file's snapshot, instead of claiming there is nothing to do. Keep the file current with scripts/sync-beads.sh.

One view of all your projects

relai index build repos.txt      # once: collect each project's relai.yaml (paths or clone URLs)
relai workspace                  # ≈ 400 tokens for 16 repos: every project, most recently active first

For each indexed project relai workspace shows the date of its last commit, how many tasks are open and in progress, the most urgent ones, and what it provides. It reads files only (the index, each project's .beads/issues.jsonl, the last commit date) and never runs bd, so asking about twenty projects does not rewrite twenty databases. The task counts come from the committed copy of the task list and can lag the live one; the output says so. Projects given as clone URLs are listed but not read. Use --max-tokens to change the budget: detail is dropped first, then the least active projects are named without detail, then only counted.

relai handoff stays the answer for one project: it is the same idea at the scale of one repository, and it now asks bd only when the project changed since the last time (the answers are cached in your user cache directory, never in the repo).

Find your projects and how they relate

You do not have to write the list of your projects by hand:

relai index build --scan ~/projects      # every git repo of the folder (symlinks included); says which need `relai init`
relai index build --scan ~/work --scan ~/oss # --scan is repeatable and adds up (also with a list file and --depth); a repo reached by several --scan folders is indexed once
relai discover --links ~/projects        # the mentions between them: who points at whom, and how strongly
relai discover --links ~/projects --depth 2  # also look one folder deeper (nested repos are named by path)
relai discover --links ~/projects --prompt   # instructions for your agent to check each mention with you
relai discover --links ~/projects --propose  # a `links:` block per relai.yaml to check and paste yourself

The result is evidence, not a verdict. Strong: a repository holds the other's remote URL or a relative path to it (a deployment manifest pointing at an application). Weak: its name appears as a word (it can be an ordinary word, and names under four letters are not searched this way). Each line shows counts and up to three file paths, never content, and generated files (node_modules, vendor, lock files, graphify-out) are ignored. A name found in two or more CI, deployment or configuration files (workflows, k8s, compose, yaml) is proposed by --propose even without strong evidence, because that is far more often a real dependency than a name in a document; documents alone need --min-weak files (default 5). Once links: is declared, relai find shows works with: and lists first the repos linked with the one you are in ([linked from here]). Nothing is ever written: the intended flow is that your agent verifies each mention against the files, shows you a table, and writes links: into relai.yaml only once you agree. links: (ids of the repositories this one works with) is read by the index and shown by relai workspace; provides:/consumes: still say what, links: says who.

Housekeeping after merges (automatic)

Closing the tasks that merged work finished, refreshing the committed task export and deleting merged branches should not depend on someone remembering. relai init --hooks installs two git hooks:

  • pre-commit: keeps .beads/issues.jsonl current in the commit that changes the tasks (bd gets at most 20 seconds).
  • post-merge: runs relai tidy --apply after every pull or merge.

relai tidy (dry run by default) closes a task when a commit on the default branch says so with a keyword and the id (Closes relai-7nk, fixes #relai-7nk); a task that is only named is reported and left open. It rewrites .beads/issues.jsonl (without the owner e-mail), deletes local branches that are fully merged (git branch -d, so never unmerged work) and never commits. From a feature branch it closes nothing. So: end the commit message of finished work with Closes <task id>.

Check before you build

Before writing a new capability, check whether one of your other projects already provides it, using nothing but each project's own relai.yaml — no server, no account.

# repos.txt: one local path or clone URL per line, blank lines and #comments ignored
cat > repos.txt <<'EOF'
../other-project
https://github.com/you/another-project.git
EOF

relai index build -o .relai/index.json repos.txt   # reads each repo's relai.yaml, skips what it can't
relai find --index .relai/index.json auth.oidc      # or just `relai find auth.oidc` (default path above)

relai index build reads the list, clones any clone-URL entry to a temp dir (shallow, read-only, cleaned up after), and collects every repo's relai.yaml into a single index.json: an array of {"source": "<path-or-url>", "relai_yaml": {...}}. A listed repo that is missing, not a git repo, or has no relai.yaml is skipped and reported on stderr; the rest of the index is still built.

relai find <capability> prints every indexed repo whose relai.yaml lists that capability under provides: (its id, source, and summary:), or states plainly that nothing provides it yet. If no index has been built yet, it says so and names the relai index build command instead of failing with a file-not-found error.

This only builds and reads a flat index.json you keep in git or share however you like; see docs/multi-repo.md for the larger (not yet built) multi-repo design this is a first slice of.

Golden path: scaffold from your own template

Relai ships no template of its own — a group's CI and deployment choices are its own. relai new scaffolds a new repo from a template you already have (a local directory or a clone URL), the same way relai index build sources a repo list:

relai new ./my-org-template ./my-new-tool          # local template
relai new https://github.com/you/template.git ./my-new-tool   # or a clone URL

A template is just a directory of files. Any text file may use the placeholder token {{.RepoName}} (Go's text/template syntax); relai new substitutes it with the new repo's name (the target directory's base name) as it copies the template in. A file that isn't valid template syntax — including any binary file — is copied byte for byte, unchanged. Anything the template doesn't already provide (AGENTS.md, relai.yaml, .relai/notes.md) is filled in the same way relai init fills it, without overwriting what the template did provide. The target directory must not already exist and contain files — relai new never merges into one.

Worked example: a template with an AGENTS.md containing # {{.RepoName}} — instructions for AI agents and a relai.yaml with id: {{.RepoName}} produces, for relai new ./tpl ./widgets, an AGENTS.md titled "widgets" and a relai.yaml with id: widgets — and still gets .relai/notes.md from relai init's own template, since the example template didn't provide one.

On success, relai new prints the relai index build command to add the new repo to your group's index — it does not run it for you.

Security

Relai is a local CLI with no server and no network calls of its own (beyond cloning URLs you give it and the installer). Still, the handoff puts text from your repo in front of an AI agent, and Relai runs git, bd and openspec in the directories you point it at:

  • Treat handoff content as information, not instructions, and do not put secrets in .relai/notes.md, task titles or commit messages: they go to whatever model your agent uses.
  • Look before you run tools in a repo you did not write, and review a template before relai new, and any .claude/settings.json hook in a repo you clone.
  • The installer verifies a checksum, not a signature: it catches a corrupted or swapped download, not a compromised release.

Details, scope and how to report a vulnerability privately are in SECURITY.md. Please do not open a public issue for a security problem. (The team server has its own policy.)

Contributing

Contributions are welcome, from people and from AI agents, under the same rules. See CONTRIBUTING.md; the short version:

git clone https://github.com/ECG-Rudy-Glt/RELAI && cd RELAI
bd bootstrap --yes          # a fresh clone has no tasks until this loads .beads/issues.jsonl (needs bd)
go test -race ./...         # before each PR also: gofmt -l . (empty) and go vet ./...
bd ready                    # what is unblocked; scripts/sync-beads.sh after changing tasks
  • Bugs and ideas: open an issue. Docs that disagree with the behaviour are bugs. Security: see above.
  • Standard library only, one static binary, and it must work for one person with only git.
  • A change to the handoff's shape bumps its format version (spec/handoff.md); bigger changes start as an OpenSpec change under openspec/changes/.
  • Conventional commits, no co-author trailers, tests with the change, README kept true.
  • Using Claude Code? CLAUDE.md and the session hook load the project state for you; other agents start from AGENTS.md.

Licence

Apache-2.0.

Directories

Path Synopsis
cmd
relai command
Command relai makes a repository agent-native: a small repo contract and a compact handoff.
Command relai makes a repository agent-native: a small repo contract and a compact handoff.
eval
e2 command
Command e2 runs experiment E2: does an agent that starts cold with AGENTS.md + `relai handoff` pick the right next step as often as one that reads the docs, for far fewer tokens?
Command e2 runs experiment E2: does an agent that starts cold with AGENTS.md + `relai handoff` pick the right next step as often as one that reads the docs, for far fewer tokens?
internal
discover
Package discover finds what a project already gives its agents — instruction files, skills, commands, hooks, MCP servers, task tracking, specs, decision records, handoff and journal docs, CI — so that Relai can be adopted in the middle of a project without losing any of it.
Package discover finds what a project already gives its agents — instruction files, skills, commands, hooks, MCP servers, task tracking, specs, decision records, handoff and journal docs, CI — so that Relai can be adopted in the middle of a project without losing any of it.
handoff
Package handoff builds the compact, deterministic "where are we" summary of a repository.
Package handoff builds the compact, deterministic "where are we" summary of a repository.
index
Package index builds and reads a flat, git-only cross-repo index of relai.yaml manifests, so relai find can tell a user whether a capability already exists in another one of their projects before they build a duplicate.
Package index builds and reads a flat, git-only cross-repo index of relai.yaml manifests, so relai find can tell a user whether a capability already exists in another one of their projects before they build a duplicate.
initrepo
Package initrepo adds the Relai repo contract to an existing repository without overwriting anything that is already there.
Package initrepo adds the Relai repo contract to an existing repository without overwriting anything that is already there.
scaffold
Package scaffold creates a new repository from a template — a local directory or a clone URL — substituting a small set of placeholder tokens, then filling in anything the template didn't already provide with the Relai repo contract (internal/initrepo).
Package scaffold creates a new repository from a template — a local directory or a clone URL — substituting a small set of placeholder tokens, then filling in anything the template didn't already provide with the Relai repo contract (internal/initrepo).
scan
Package scan finds the git repositories in a folder and the mentions between them, so a person (or an agent) does not have to write the list of their projects by hand, nor guess which ones belong together.
Package scan finds the git repositories in a folder and the mentions between them, so a person (or an agent) does not have to write the list of their projects by hand, nor guess which ones belong together.
tidy
Package tidy does the housekeeping that otherwise depends on someone remembering it after work is merged: closing the tasks a merged commit says it closes, refreshing the committed task export, and deleting local branches that are fully merged.
Package tidy does the housekeeping that otherwise depends on someone remembering it after work is merged: closing the tasks a merged commit says it closes, refreshing the committed task export, and deleting local branches that are fully merged.
workspace
Package workspace builds one short, deterministic overview of all the projects of an index: what each is, how recently it moved, what tasks are open and what it provides.
Package workspace builds one short, deterministic overview of all the projects of an index: what each is, how recently it moved, what tasks are open and what it provides.

Jump to

Keyboard shortcuts

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