Skip to content

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:

https://treeviz.newlineages.com/?api=1

Use headless mode for render-only browser automation:

https://treeviz.newlineages.com/?mode=headless&api=1

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.

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() or describeCommand(id) when an exact command id or argument schema matters, and validate(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.search matches 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 read getDiagnostics() and the returned metrics. Use getDiagnostics({ 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.

References