essay

Why we drew the terminal as space

2026-08-18 · 6 min · Vibisual

A log tells you what happened, in order. A map tells you where everything is, right now. Agent runs need the second one.

A terminal is a good instrument for one worker. One cursor, one column of output, time running downward. When you were the one typing, that shape matched the work exactly.

Five agents break it. Output from unrelated tasks interleaves, the thing you care about scrolls away while you read something else, and the question you actually have — which one is stuck? — gets answered only by paging back through text that has already moved.

So we stopped printing the run and started drawing it. A node per agent, an edge per handoff, a child bubble per tool call. Position carries meaning, and state is a colour instead of a sentence you have to find.

The surprising part was not the map. It was that the same canvas turned out to be the right place to design the team: if a graph is how you read a run, a graph is also how you write one. Configuration and observation ended up being the same picture, seen at two different times.

vibisual {{ verBadge }}
{{ t.eyebrow }}

{{ t.h1a }} {{ t.h1em }}

{{ t.nameLine }}

{{ t.sub }}

{{ stat1 }} {{ t.st1 }} {{ stat2 }} {{ t.st2 }}
{{ stat3 }} {{ t.st3 }}
{{ stat4 }} {{ t.st4 }}
{{ t.canvasHint }} vibisual · canvas
{{ b.count }} {{ b.label }} {{ b.badge }}
{{ l.text }}
{{ g.text }}
{{ t.bubDblHint }}

{{ t.canvasCaption }}

IDE → ADE → VDE

{{ t.vdeLead }}

IDE {{ t.vde1 }} VS Code, Cursor
ADE {{ t.vde2 }} Warp
VDE {{ t.vde3 }} Vibisual

{{ t.whatTitle }}

01

{{ t.f1t }}

{{ t.f1b }}

SessionStart → node created · orchestrator UserPromptSubmit → "split the checkout refactor" PreToolUse Task → edge → api-builder PreToolUse Edit → bubble · routes/checkout.ts PostToolUse Bash → 41 passed
02

{{ t.f2t }}

{{ t.f2b }}

node · test-runnerunsaved
modelclaude-sonnet-4.6 toolsBash, Read, Grep rulesnever edit src/** in-edgeapi-builder → test-runner
03

{{ t.f3t }}

{{ t.f3b }}

stream files diff terminal
routes/checkout.ts - const total = items.reduce(sum) + const total = priceWithTax(items) + if (!total) throw new BadRequest() 2 files changed · saved to the agent's branch
walkthrough {{ t.videoTitle }} {{ t.videoSub }}

{{ t.instTitle }}

{{ t.instLead }}

{{ t.instWin }}
{{ f.name }}

{{ t.instWinBody }}

Releases →
{{ t.instSrc }}
$ git clone https://github.com/Vibisual/vibisual.git $ cd vibisual && pnpm install $ node scripts/runapp.mjs # pnpm build:win

{{ t.instSrcBody }}

Contributing →
{{ t.statusLabel }}

{{ t.statusBody }}

{{ t.secLabel }}

{{ t.secBody }}

{{ t.ctaTitle }}

{{ t.ctaSub }}

{{ ui.blog }}

{{ ui.blogTitle }}

{{ ui.blogLead }}

{{ art.date }}{{ art.tag }}{{ art.read }}

{{ art.title }}

{{ art.excerpt }}

{{ pa.v }}

{{ art.author }}
{{ ui.docs }}/{{ doc.g }}/{{ doc.title }}

{{ doc.title }}

{{ doc.lead }}

{{ ui.updated }} {{ doc.updated }}

{{ s.h }}

{{ pa.v }}

{{ c.v }}
{{ r.k }} {{ r.v }}
note

{{ s.note }}

{{ pick.title }} {{ t.ideWindowTag }}
{{ pick.label }} {{ pick.typeLabel }}
{{ pick.agentTabName }}
{{ tb.name }}
{{ ac.under }} {{ ac.badge }}
{{ pick.rootName }}
{{ tr.name }}
{{ pick.selPath }}
{{ as.you }} {{ ideAsk }}

{{ pick.body }}

{{ as.activity }} {{ pick.toolRun }} {{ tn.v }}
Read {{ pick.readTarget }}
{{ as.output }}
{{ pr.k }}{{ pr.v }}

{{ nt.head }}

{{ nt.body }}

{{ pick.runWord }} {{ ideAsk }}
All Model {{ pick.localModel }}
{{ dn.v }}
{{ as.follow }}
> {{ as.ph }} {{ as.run }}
{{ as.readOnly }}
{{ term.note }} {{ term.fontSize }}
{{ tl.a }}{{ tl.b }}
{{ pick.stBadge }} {{ pick.stState }} {{ pick.stModel }} {{ pick.stCtx }} {{ pick.stTok }} {{ pick.stAc }} {{ pick.stSess }}
{{ brain.title }} {{ brain.project }} {{ brain.howTo }}
{{ brain.search }} {{ bty.v }}
{{ sp.title }} {{ sp.hint }} {{ sp.count }}
{{ brain.topicsLabel }}
{{ tp.v }} {{ tp.n }}
{{ brain.axesTitle }} {{ brain.turnOff }}
{{ ax.t }} {{ ax.h }}

{{ brain.keepsData }}

{{ brain.docTitle }}

{{ brain.docPath }}

{{ bc.ti }}

{{ bc.typeName }} {{ bc.alwaysLabel }} {{ bc.needsLabel }} {{ bc.curLabel }} {{ bc.ckey }} {{ bc.ago }} {{ bc.help }}

{{ bc.needsText }}

{{ bc.stillValid }} {{ bc.markStale }}

{{ bc.body }}

{{ bc.file }}
{{ bc.detail }}

{{ t.ideAnnoLead }}

{{ an.n }} {{ an.h }}

{{ an.b }}

{{ an.k }}
{{ t.ideNextTag }} {{ t.ideNextBody }}