Driving braids from an agent

Every command that reports something takes --json with whole IDs, so Claude Code can search its own past conversations and branch from the turn it finds.

The shape of it

--json prints one object to stdout and nothing else. IDs are whole, never the shortened form the screens show, so a result can be fed straight into the next command. Errors go to stderr and the exit status is 1.

braids search "fork direction birth time" --limit 1 --json
{
  "query": "fork direction birth time",
  "hits": [
    {
      "of": "conversation",
      "lane": "46360382-7b08-436a-a8db-e0a30768c83a",
      "lane_title": "Agent observability and branching conversations",
      "project": "braids",
      "message": "be0e8453-7b94-4c86-87ba-7909c3354ae0",
      "turn": 491,
      "kind": "text",
      "role": "user",
      "snippet": "...",
      "at": "2026-09-04T10:13:01+02:00"
    }
  ]
}

A hit of "of": "memory" carries name and path instead of a turn. One of "of": "artifact" carries the path of the file whose name matched.

The loop that makes it useful

# 1. find the moment
braids search "the lock is held across a network call" --limit 1 --json

# 2. branch from the turn that came back
braids branch --lane 46360382 --at 491 --name "narrow the lock" --json

# 3. carry on there
claude --resume <the id branch printed>

That is the whole trick: search returns a lane and a turn, branch takes a lane and a turn, and the branch is a conversation the harness can resume. An agent can go back to the exact moment a decision was made and take the other road, without disturbing the conversation it is having now.

Where did this file come from

braids explain internal/core/index/index.go --json

This joins two things braids and git each half know: git knows when a file changed, braids knows what was being said in that directory at the time. For each commit it names the conversations that were live in the window before it, how many turns they had, and the last thing actually said, with the whole lane id so the next command can use it.

It does not claim the conversation caused the commit, and neither should anything reading it. What it offers is where to look, which is the honest thing braids can compute without reading a word of meaning.

Sessions that ran above the repository

A working directory answers this outright when the session ran inside the repository. It does not when several checkouts sit in one workspace and the session was opened at the top of it: that directory is equally close to all of them, so taking it at its word would offer the same conversations as evidence about every repository in the workspace.

Those sessions count only if they named the file, which is both narrower and nearer to what you asked. In --json, matched says which of the two placed each conversation and names_the_file counts the mentions. The second is the weaker of the two, and the text output marks it as such rather than quietly mixing them.

The skill

braids carries a Claude Code skill that teaches all of this, and installs it for you:

braids skill --install     # into ~/.claude/skills/braids
braids skill               # what is installed, and whether it is current
braids skill --show        # print it instead
braids skill --remove

It says when to reach for braids and, as importantly, when not to: searching history on every question is slow and usually beside the point. Three situations only, which are the user referring to earlier work, the user asking why something is the way it is, and Claude about to propose something that may already have been tried.

A test reads that skill and checks every command and flag in it against the program, because a skill lives in somebody's ~/.claude/skills where nothing here can fix it if it drifts.

As a Claude Code plugin

The skill and the hooks together install from inside Claude Code, without running braids skill --install or braids hooks --install yourself:

/plugin marketplace add Ashes47/braids
/plugin install braids

It cannot install the binary. Do that first, or Claude is simply told braids is not here: the skill's first instruction is to check, so nothing guesses. The plugin's hooks run braids hook from your PATH rather than an absolute path, because a plugin cannot know where a binary it did not install ended up. With no braids on PATH those hooks do nothing, which was tested rather than assumed: a session with a hook whose command is missing runs normally and exits cleanly.

If you have already run braids skill --install, installing the plugin gives you the same instructions twice, loaded as braids and braids:braids. Nothing in Claude Code says so, because from its side they are two skills that happen to agree, so braids says it instead: braids skill and braids doctor both report it and name the two ways out. Keep the plugin and run braids skill --remove, or keep the hand-installed one and uninstall the plugin.

The plugin ships a copy of the skill, because a plugin is a directory and the binary embeds its own. Two copies of anything drift, so the copy is generated by make plugin and a test fails when somebody edits one and not the other. This repository has been bitten by that twice.

Check before you rely on it

braids hooks --json    # .reporting says whether waiting states are trustworthy
braids lanes --json    # every conversation, with whole IDs and resume commands
braids agents --lane 46360382 --json
braids work --lane 46360382 --json
braids memories --json

braids index before a search in a long-running agent. Reads never create or migrate the index, so an agent that has never indexed gets told to, rather than getting an empty answer that looks like a real one.

Exit status

StatusWhen
0it worked, or you asked for help
1anything else, with the reason on stderr

A mistyped command names the one you probably meant and exits 1.