Execution protocol
abtree is a durable behaviour tree engine. Executions bind a tree to a piece of work and persist as JSON documents in .abtree/executions/, with two state scopes:
$LOCAL— per-execution blackboard (read/write).$GLOBAL— world model (read-only).
Internal bookkeeping (cursor, retry counts, per-node status) lives in a runtime field on the execution document — invisible to abtree local read and not mutable via abtree local write. The engine owns it.
Strict
Never read tree files directly. All interaction goes through this CLI.
Routing
No arguments → execution list; resume an existing execution or pick a tree
<execution-id> → resume that execution
<tree-file-path> → create a new execution (remaining args = summary)
list → show all executionsCreate an execution
abtree execution create <path-to-tree-file> <summary>
abtree local write <execution> change_request "<request>"
abtree next <execution> ← begin execution loop<path-to-tree-file> is a literal absolute or relative path to a .json, .yaml, or .yml tree file. No slug lookup, no package.json inference — point at the file you want to run.
Drive the loop
Call abtree next <execution> to get the next request. Repeat until done.
Response: evaluate
{ "type": "evaluate", "name": "...", "expression": "..." }Procedure — do not skip steps:
Parse the expression. Identify every
$LOCAL.<path>and$GLOBAL.<path>it references.For each referenced path, call:
textabtree local read <execution> <path> (for $LOCAL refs) abtree global read <execution> <path> (for $GLOBAL refs)Record the actual returned value. Do not skip this step even if you wrote the value yourself one command ago.
Apply the expression's truth condition against those actual values and only those values. No inference from context, memory, or "obvious" assumptions.
Call
abtree eval <execution> true|false [--note "<one sentence>"].
Strict
Skipping step 2 corrupts the gate. The store is the source of truth, not your context. Even when the answer feels obvious, read it.
Optional: explain your decision. Pass --note "<one sentence>" (CLI) or note: (MCP) to record why you submitted what you did — name the values from $LOCAL / $GLOBAL that drove the call. The engine ignores the content; the note is recorded in execution.trace for later review of how the agent reasoned through the tree. Skip it on trivial transitions; include it whenever the choice was non-obvious.
Response: instruct
{ "type": "instruct", "name": "...", "instruction": "..." }Procedure:
- Read the instruction in full.
- Perform the work named. Use real tools — file I/O, web search, shell commands, sub-agents — as the instruction directs.
- Write any produced values to
$LOCALviaabtree local write. - Call
abtree submit <execution> success|failure|running [--note "<one sentence>"]. Userunningonly when waiting on something external (a human approval, a long-running tool). Do not userunningto skip an instruct.
Strict
Every value written to $LOCAL must come from an explicit source named in the instruction (a tool, a command, a $LOCAL/$GLOBAL path, or a literal fallback). If the source is ambiguous, call abtree submit <execution> failure. Do not infer, guess, or invent.
Optional: explain your decision. Pass --note "<one sentence>" (CLI) or note: (MCP) to record what you did and why you marked the action success/failure/running. The note is recorded in execution.trace for later review. A running note is especially useful — capture what you are waiting on. The same field is available on the protocol acknowledgement; a rejection note explains why you walked away from the tree.
Response: done or failure
{ "status": "done" }
{ "status": "failure" }Tree terminated. Report the outcome to the human.
Finding trees
Trees ship as installable node packages — browse Discover trees and bun add / pnpm add / npm install the ones you need, then run them by path to the file they expose, e.g.:
abtree execution create ./node_modules/@abtree/hello-world/main.json "<summary>"Project-local trees can live anywhere in the working tree; pass the path to their .json/.yaml/.yml file directly.
State commands
abtree local read <execution> [path] Read from $LOCAL
abtree local write <execution> <path> <val> Write to $LOCAL
abtree global read <execution> [path] Read from $GLOBALReporting (per action)
[execution-id] ✓ Action_Name → success|failure