Agent automation¶
When a script or coding agent needs to build, inspect, or export a
phylogenetic visualization, use the hosted TreeViz API. Through
window.__treeviz, it exposes command schemas, diagnostics, render
diagnostics, layout metrics, and session state, along with SVG and PNG
export.
Install the skill¶
Clone the public repository and copy the whole treeviz-agent directory into
the agent's personal skills folder:
git clone --depth 1 https://github.com/fmschulz/treeviz.git
# Claude Code: personal skills folder
mkdir -p ~/.claude/skills
cp -R treeviz/.agents/skills/treeviz-agent ~/.claude/skills/
# Codex: personal skills folder
mkdir -p ~/.codex/skills
cp -R treeviz/.agents/skills/treeviz-agent ~/.codex/skills/
Claude Code also reads project skills from .claude/skills/<name>/. Codex
reads $CODEX_HOME/skills (default ~/.codex/skills) and repo-level
.agents/skills. Restart the agent after installing. To update, pull the clone
and copy the directory again.
The skill works through window.__treeviz in the hosted page, so the agent
needs a way to drive a browser, for example Playwright, agent-browser, or
Claude in Chrome.
Runtime¶
Open the browser app with the API enabled:
Use headless mode for render-only browser automation:
The hosted agent API page links the runtime, command schema, session schema, and example manifest.
Use the public skill¶
The installable skill is the complete
treeviz-agent directory
in the public repository. It contains the entry file, task-specific references,
and helper scripts. Download or sync the whole directory; SKILL.md refers to
the adjacent files.
- Read
SKILL.md - Open the raw entry file
- Browse the Browser API reference
- Inspect the live command schema
- Inspect the live session schema
- List hosted examples
The public skill uses the hosted app. It does not include the browser build or frontend source.
The hosted examples are described in Examples.
Restore the hosted example¶
const api = window.__treeviz
const response = await fetch('/examples/example-1-mirusviricota/session.treeviz.json')
if (!response.ok) throw new Error(`session request failed: ${response.status}`)
const snapshot = await response.json()
await api.execute('session.restore', { snapshot })
await api.whenSettled()
The session's default saved view applies during restore. Add
skipAutoApplyDefault: true only to keep the document's current view.
Standard sequence¶
const api = window.__treeviz
await api.execute('session.import-tree', {
source: '(A,B,(C,D));',
name: 'example.nwk',
format: 'newick'
})
const metadataText = [
'id\tgroup\tvalue',
'A\talpha\t1.2',
'B\talpha\t0.8',
'C\tbeta\t2.1',
'D\tbeta\t1.6'
].join('\n')
const plan = api.planMetadataImport(metadataText, 'tsv', 'color by group and value')
if (!plan) throw new Error('metadata planning failed')
await api.execute('session.import-metadata', {
source: metadataText,
format: 'tsv',
rowKeyColumn: plan.suggestedBinding.rowKeyColumn,
flags: plan.suggestedBinding.flags,
leafIdentifierSource: plan.suggestedBinding.leafIdentifierSource
})
await api.applyTrackRecommendations(plan.recommendedTracks)
await api.execute('view.set-layout', {
layout: 'circular',
circularOpeningAngle: 90,
circularOpeningAutoFit: true,
circularRotation: 45,
circularOpeningColor: '#ffffff',
circularInteriorColor: '#ffffff'
})
await api.execute('view.set-tip-alignment', { alignment: 'label' })
const saved = await api.execute('view.save', { name: 'Circular view' })
if (!saved.ok) throw new Error(saved.error.message)
await api.execute('view.apply', { id: saved.value.id })
const { metrics, renderDiagnostics } = await api.whenSettled()
const diagnostics = api.getDiagnostics()
if (diagnostics.some((item) => item.level === 'error')) {
throw new Error('TreeViz diagnostics contain errors')
}
const { dataUrl, width, height } = await api.exportImage({ scale: 2 })
Await each command, then await api.whenSettled() before reading metrics or
exporting. It resolves once fonts are loaded and the rendered frame matches the
latest edit, and returns the layout metrics and render diagnostics for that
frame. Check diagnostics after each batch. See
Wait for the render and
Export an image.
Practical rules¶
- Load or restore a session before metadata, tracks, or styling.
- Read
commands()ordescribeCommand(id)when an exact command id or argument schema matters, andvalidate(id, args)to check a call without running it. - Call
planMetadataImport(...)before importing metadata from text. - Get stable keys with
findNodes(...)by name, regex, or metadata value. It matches every node;view.searchmatches only leaves and collapsed clades. - Group related edits with
executeBatch(...)so a failed step rolls back the whole batch. await api.whenSettled()after each visual change, then readgetDiagnostics()and the returned metrics. UsegetDiagnostics({ since })to see what one batch added.- Read
describeFigure()for a compact summary of the current figure. - Put legends and attribute display names in the session document before
session.restore; no command edits them. - Export the figure with
exportImage()after the final layout change and inspect it before reporting that the figure is ready. - Save durable work as
.treeviz.json.
Command arguments, track options, legends, connections, and node marks are documented in the Browser API reference. Styling recipes are in Tree styling.
Check the layout¶
Read getLayoutMetrics() after the latest visual change. Start with
contentOccupancyX, contentOccupancyY, labelsClipped, labelCollisions,
labelsVisible, labelsCulled, trackDensity, and p75BranchPx.
For circular and radial layouts, occupancy is measured against the shorter
viewport side because the figure is round. Metrics describe the current camera.
Labels keep their screen size above zoom 1, so the fitted view and a 2x view can
have different labelsVisible and labelsCulled counts. Zoom, await
whenSettled(), and read the returned metrics again.
Radial figures with collapsed wedges also report wedge overlap counts; see Layout QA pattern.
Inspect the final exported SVG, PNG, or PDF before reporting that a figure is ready.