Driving it from an agent
Show the whole prompt
Clone https://github.com/INTENTIUS/behold and get me looking at a live
infrastructure graph in my browser.
I want the bundled demo. It needs Docker and no cloud account. Install what
it needs and start it, then tell me the URL.
Walk me through what I am looking at: what the colours mean, and how I make a
resource change colour while I watch.
When Docker is not running, say so. Show me the source graph on its own
instead.
For anything past the demo, read https://intentius.io/behold/llms.txt and
https://intentius.io/behold/using/agents/.
Never deploy with the Deploy button, `POST /api/apply` or `POST /api/ci/dispatch`. Gate approvals stay mine as well (`/api/ops/:name/signal/:gate`, `/api/workspace/gates/approve`, `/api/operator/approve/:op/:gate`). Op runs (`/api/ops/:name/run`) and rollbacks (`/api/rollback`) are mine too. Leave `--auto-sync` off, and keep a `behold preview` or `--public` serve read-only.The SPA has no private channel: everything it shows rides plain JSON over HTTP, so an agent or a script can drive the same server headless. Start one and curl it:
npx @intentius/behold serve <chant-project-dir> # or preview / democurl -s http://localhost:4600/api | jqGET /api is the front door. It lists the routes with a one-line description each, the server’s version, and a link to the full contract.
The read loop
Section titled “The read loop”- observe.
GET /api/graphreturns{ ir, svg, meta }. Every node inir.nodescarriesid,kind,lexicon,attrs, andsourceLoc. Drift status, when present, isattrs._status:good= managed,warn= foreign,accent= pending,neutral= unobserved,runtime= runtime child. - focus. Narrow with query params:
?detail=0..3,?components=1,?logical=1,?lens=blast:<id>&down=1,?lens=lexicon:aws, plus theenv/stack/tier/targetaxes the UI’s Scope tab exposes. - go deeper. With an
?env=:/api/overlayis the live entity overlay,/api/diffslices per-node observed state / drift / field ownership,/api/reconcilesummarizes the pending change set./api/substratesreports substrate readiness, and/api/events(SSE) pusheschanged/op/apply/prso you re-pull only when something moved. - inspect. A node’s
sourceLoc.fileis the typed source that declared it. To change the estate, edit there: chant is the source of truth, not behold. Provenance rides on the node too:attrs._release(the recorded deploy: run id, origin, commit, digest, actor, approver),attrs._carve(the Terraform address a carved entity came from), and on a Helm chartattrs._renderDrift.identity(whether the running release was deployed from this project’s render).
A directory that is not a chant project gets a structured {code: "no-project", error, remedy} from /api/graph. Every other precondition failure (lint, not-installed, tier, eval) takes the same shape, so an agent branches on code instead of parsing prose.
Over MCP: behold mcp
Section titled “Over MCP: behold mcp”behold mcp is a stdio MCP server for a coding agent that wants to show the person what it found. chant answers and behold draws: capabilities returns chant’s capability catalog, ask returns chant’s answer to an estate question, and show and shot draw it.
Read capabilities first. It is chant’s capability catalog (chant search --capabilities --json, chant#4375), and it says which cap: questions this estate can be asked: each capability’s name, what it means, its parameters, the search term that asks it (cap:internet-reachable(22), ->[cap=network]), the questions it answers, what it does not evaluate, its rule, and whether each lexicon supplies it. Then ask with that term.
claude mcp add behold -- npx @intentius/behold mcp <project-dir>| Tool | What it does | Arguments |
|---|---|---|
capabilities |
Returns chant’s capability catalog, the read contract’s capabilities document, verbatim (chant search --capabilities --json on one project or a Terraform folder, chant workspace search --capabilities --json on a declared workspace), through GET /api/capabilities. Needs chant 0.124.46 or newer. |
none |
ask |
Returns chant’s search document for the query, verbatim (chant workspace search on a declared workspace, chant search --json on one project or a Terraform folder), with link to the view that draws it and drawn: false added. Never moves the tab. |
query, env, snapshot, plan, countBy, show |
show |
Moves the person’s open behold tab to a view through POST /api/view. The tab says an agent moved it and keeps the view it left one Back away. With no tab open it answers the link to hand the person. |
query, env, snapshot, plan, countBy, member, zoom, focus, node |
shot |
Returns a PNG of a view as MCP image content, then a text block with the link, through GET /api/shot. |
the same, plus width and height |
query is chant’s search grammar, unchanged. env reads that environment live (chant search --live --env <env>), snapshot with env replays a recorded snapshot (latest, or a ref chant lists), and --explain is always on, for the near-misses behold draws. No tool takes --check-live, --check-snapshot, --ambient, --src or --fail-on-drift, and at is refused: in chant’s read contract it is a git revision. The tab and the PNG light the query’s matches, draw the edges on their paths and dim the rest; a cap: match’s path is the hops in its path’s because, one entry per capability it relied on, and those are drawn too; with no matches the whole graph is dimmed and the near-misses outlined. Without a query, shot frames the view’s own node or focus.
countBy (kind, module or attr:<name>) is chant’s --count-by: ask returns chant’s groups and total, and the tab and the PNG light each group’s cards and label the group with its count; the query may then be empty, to count the whole estate. plan: true answers at the plan depth (chant reads a saved terraform plan of each root), so attr:planAction=replace with show: "planActions,planReplacePaths,planActionReason" says what a change replaces and why, and the cards carry the plan facts. A bare Terraform folder needs no env for it; a chant project does. plan with snapshot is refused, naming both.
The server is a client of a running serve’s HTTP API and holds no query or view logic of its own. It finds the serve through --url or --port when given, then through a per-user registry under the OS temp directory (<tmpdir>/behold/serves/<pid>.json, holding {url, pid, projectDir, version, startedAt}), which every behold serve writes at start and removes at exit, then at http://127.0.0.1:4600. Nothing is written in the project. Before a tool uses a serve it reads GET /api/project. If that serve serves another project, show refuses and names both. With no serve running, show refuses with the command that starts one, and capabilities, ask and shot start behold in their own process for the call.
Every argument is listed and any other is refused, a credential-named one by name. A refusal comes back with isError and the route’s {error, code, remedy}. The server will not start with a tool whose name says it would deploy, apply, approve, run an Op, roll back or write, and a call to such a tool is refused. show changes what the tab draws and nothing else; shot writes no file.
The act loop, delegated and never direct
Section titled “The act loop, delegated and never direct”behold performs no cloud write of its own. The mutating endpoints trigger Ops the project committed: POST /api/apply?env=&component=, POST /api/ops/:name/run, POST /api/ops/:name/signal/:gate, POST /api/rollback?to=. All are guarded (one write at a time), gated where the Op declares a gate, and locked out entirely in preview and static modes. An environment its member’s chant.config.ts designates to a forge (an executor on the environment entry, read through chant) answers those with 409 executor-forge; its one deploy is POST /api/ci/dispatch?env=, through the operator’s gh, followed on the dial, with GET /api/ci/run the persisted record and POST /api/ci/readopt the re-follow after a restart. For build, lint, lifecycle diff and op status, prefer chant’s own MCP tools over shelling.
The contract
Section titled “The contract”The canonical version of this guide ships inside the npm package and lives at AGENTS.md. Hand it to your agent verbatim.