Skip to main content

Under constructionStatus: Building. Being built now. Parts may run; the whole is not finished.

Every project’s status →

01.09Task graph viewer

Vox Canvas: a browser task graph viewer

Vox Canvas is AR Labs' keyboard-driven browser canvas for its task graph: a tree to move through, a panel for each task, and Taskgraph's status map in place.

On this page
  1. What it is for
  2. Moving around a large tree
  3. Selection, focus and the keyboard
  4. What opening a task shows
  5. How status is shown
  6. The map inside Canvas
  7. Staying in step with the data
  8. Decisions and what they replaced
  9. What exists today
  10. How it was built

Vox Canvas is a browser application, built by AR Labs, for moving around our task graph (all tracked tasks and the dependencies between them) with the keyboard. It draws the tasks as a tree on a canvas you can pan and zoom, opens any task in a side panel, and switches in place to a status map of one branch drawn by Taskgraph. It reads live tasks from Beads, Steve Yegge's open-source issue tracker for coding agents, and runs on the machine that holds them. It is the browser part of VOX OS, our design for an operating layer over the work of AI agents (language models run in a loop with tools).

What it is for

In Beads each task is a bead: an issue with a parent, children, a status and dependency edges to other beads. Our beads form one tree of goals, projects and tasks, several hundred of them. Taskgraph draws one branch at a time as a static page, and VOX Torch shows the same answers in a terminal. Canvas is for moving across the whole tree: find a branch, see its shape, open a task, follow a dependency to its neighbour, fix a title, and step back out without losing your place.

Moving around a large tree

The tree runs left to right, parent to children, as cards coloured by each task's state. Focus mode (f) is the main tool for size: it hides everything except the selected task's ancestors and its whole subtree, so a branch of thirty tasks can be read without the other four hundred. Closed work is hidden by default and a brings it back.

Vox Canvas in focus mode: a row of ancestor cards leading to the selected Taskgraph epic, ringed, with a column of its child tasks to the right, coloured by state.
Focus mode on Taskgraph's own branch: the ancestors on the left, the selected epic ringed, its tasks in a column to the right.

Depth is set per task as well as for the whole view. 1 to 9 show that many layers beneath the selected card, 0 collapses it, and [ and ] show one layer fewer or more; a card with hidden children shows how many. / opens a search over titles and IDs, and choosing a result clears only the filters that were hiding it. Every jump is recorded, so Ctrl-O and Ctrl-I step back and forward through where you have been, as in the vim editor.

The search box over the canvas, filtering tasks by the word "taskgraph", one result highlighted, with keys to move and select shown beneath.
Search jumps to a task anywhere in the tree and reveals it if a filter was hiding it.

Selection, focus and the keyboard

There is one selection at a time, drawn as a dark ring. h moves to the parent, l to the first child, j and k to the next and previous sibling. With follow mode on (g) the camera pans to each new selection; Enter switches between a close view of the selected card and the whole tree. w and v cycle through the tasks currently being built and the tasks under review, so work in progress can be found without searching for it.

? opens a help dialog generated from the same tables the keys are bound from, so it cannot drift from what the keys do. A click also selects, scroll zooms and Shift with scroll pans.

The help dialog's keyboard shortcuts: navigation keys including jumplist and vim-style moves, view-mode keys for map, follow, focus and closed work, and tree controls for depth and order.
The help dialog lists every key, built from the same tables that bind them.

What opening a task shows

The side panel (Tab shows or hides it) loads the whole bead each time the selection changes: status, priority and type, description, the tasks it depends on and blocks, acceptance criteria, design and notes, links to its spec and pull request, and its metadata, which includes its stage in our coding pipeline (the route every code change takes: spec, test-first build, second-model review, a person's merge). Each dependency is a link: clicking it selects that task. On the canvas, the beads joined to the selection by a blocking edge get a thinner coloured ring, so cross-branch dependencies show only when they are relevant.

A selected task card ringed in dark ink, the card it depends on ringed in purple, and the side panel showing the task's description, its two dependencies and its acceptance criteria.
A selected task, the task blocking it ringed, and the panel with its description, dependencies and acceptance criteria.

Title, description and notes are edited in the panel; a save shows at once and is undone with a message if Beads refuses it. i opens a status picker. s opens the task's spec file and p its pull request, and m closes a task whose pull request has merged.

How status is shown

Each card's fill and border are its phase in Taskgraph's palette: NEXT, waiting on you, being worked, being planned, ready, later, done, deferred and not assessed, the same colours as Taskgraph's own maps. A slow pulse marks a card that is being worked or waiting on a person. Light and dark themes follow the system, and t overrides it.

On the map, every phase comes from Taskgraph. The tree still uses Canvas's own rules from status, pipeline stage and the children's state, mapped onto the same looks, until Taskgraph adds a command that reports a phase for every bead under a root.

The map inside Canvas

With a task focused, d turns the canvas into Taskgraph's map of that branch, and d again returns to the tree with the same task selected. The server runs Taskgraph's layout command and Canvas draws exactly what its JSON says, with a strip beneath for where the work stands, what happens in order, decisions waiting for a person, and beads nobody has sequenced. In map mode the direction keys move across columns and between lanes, and n jumps to the step marked NEXT.

Vox Canvas in map mode: lanes of numbered, coloured task cards right of a vertical NOW line, and a strip below listing where the work stands, what happens in order and what is not assessed.
Map mode on the same branch: Taskgraph's order and phases, drawn as cards you can select and move between.
The same map in the dark theme: phase colours on a near-black ground.
The dark theme keeps every phase colour distinguishable.

If Taskgraph cannot answer, Canvas names the reason (for example not installed, timed out, unreadable output, or a contract version it does not know) and how to get back to the tree, instead of showing an empty map.

Staying in step with the data

Canvas reloads when asked (r), when a mode is entered and after its own writes; it does not poll or watch files. Its decision record gives the reason: a single user knows when the data has changed, and a viewer with no background timers costs nothing while open, at the price of a badge that can be stale until the next refresh. The map is never cached.

Decisions and what they replaced

  • A viewer with an editing panel. The canvas never re-parents tasks; structure stays with the agents and people who own the graph.
  • Dependencies on demand. Even five to ten crossing edges make a left-to-right tree hard to read, so cross-branch dependencies show when a task is selected rather than all the time.
  • The dependency view, twice replaced. The first version re-ranked the tree in place by dependency order. Testing it in a browser showed three faults: one horizontal axis meant both "is part of" and "must come before", it ignored focus and drew the whole store, and the second mode bred bugs across the canvas code. A dedicated page with its own rank-column layout followed. Both were replaced by Taskgraph's map, drawn as a second layout of one shared canvas engine, which answers all three faults.
  • One colour per task. For a time the map coloured a card by Canvas's own state and showed Taskgraph's phase as a chip, so one task could appear in two colours. Canvas now wears Taskgraph's whole look, and the fill is the phase.
  • Never write pipeline state. Canvas shows a task's pipeline stage but never edits it.

What exists today

Built and in use against live data: the tree with focus, depth, search, the jumplist and panel editing; map mode with Taskgraph's maps; light and dark themes; and a sessions mode that lists the Claude Code sessions running on the machine, each with a status badge. Designed and not built: resuming or starting an agent session from the canvas, transcript previews, saved views in a sidebar, and creating a task from the canvas, whose key draws a placeholder card that is not yet saved. The Voice button is reserved for a later spoken interface and does nothing yet. Canvas is a desktop tool with no layout for phone screens, it is local-only with no sign-in, and its source is not yet public.

How it was built

FIG. 01
flowchart LR
  U["Browser: tree, map, sessions"]
  S["Express server"]
  BD["bd command-line tool"]
  B[("Beads task graph")]
  TG["Taskgraph layout JSON"]
  CR["Claude Code session records"]
  U -->|"HTTP /api"| S
  S --> BD --> B
  S --> TG --> B
  S --> CR

The client is TypeScript with React 18, React Flow, Zustand and Dagre. A small Express server reads and writes Beads by running the bd command-line tool, so Canvas depends only on Beads' published interface. One canvas engine holds the camera, zoom, panel, refresh and shared keys, and each mode is a layout provider that supplies positions and its own extra keys; a test keeps the engine from branching on which layout it holds. A contract test keeps Canvas's copy of Taskgraph's JSON types identical to Taskgraph's published contract, and another forbids colour values outside the shared palette. The project records its decisions as architecture decision records, 42 of them so far.

Taskgraph reads Beads, git and the manifest and feeds its SVG map, VOX Torch and Vox Canvas; Torch and Canvas also read Beads and session records; the goal map reads a sweep of agent sessions. Three views of the task graph, and the goal map, and where each reads from. Beads, the task graph, is read through the bd command-line tool. Taskgraph, a read-only command-line tool, reads Beads together with git, GitHub and the pipeline manifest, and derives each item's phase, the order of work, the next action and every point that waits for a person. It draws its own SVG map and prints versioned JSON that VOX Torch (terminal) and Vox Canvas (browser) draw from, so all three show one interpretation. Torch and Canvas also read Beads directly and read agent session records; Canvas can edit a bead's fields, never its pipeline state. The goal map does not read the task graph: a background sweep agent reads the session records of Claude Code, Codex and the resident agents, and the goal map places that work around the month's goal and priorities. Three views of the task graph, and the goal map TASKGRAPH WORKS OUT THE STATE ONCE · THE TERMINAL, THE BROWSER AND ITS OWN MAP DRAW THE SAME ANSWER FIGURE TASK-GRAPH VIEWS DRAWN BY AR LABS SHEET 1 / 1 Agent session records [Claude Code, Codex, resident] Taskgraph map [SVG] Timeline with a NOW line VOX Torch [Terminal · Python, Textual] Portfolio, thread, kanban, needs-you, agents Taskgraph [CLI · read-only] Derives phase, order, NEXT and human stops; prints versioned JSON Vox Canvas [Browser · React Flow] Tree, map and agent modes Beads [via bd CLI] git, GitHub [+ manifest] Sweep agent [Background agent] Writes what each session works on and waits for Goal map [Interactive page] Projects on a spiral around the month's goal; agents as moons The goal map does not read the task graph. It places agents on priorities from a sweep of their sessions. KEY Taskgraph's one interpretation Task data, through bd Agent session data draws status JSON layout JSON reads reads reads directly reads edits fields (never pipeline state) agents screen agent mode reads sweep JSON
Vox Canvas reads and edits Beads, but draws order and status from Taskgraph.