research-visualizer
GitHub将Agent-Native Research Artifact(ARA)渲染为交互式HTML或提供本地实时预览。支持步骤轨迹地图、详细钻取及依赖图展示。提供导出模式生成便携文件,以及Live模式通过CLI进行验证和热重载查看,仅读取不修改数据。
触发场景
安装
npx skills add ARA-Labs/Agent-Native-Research-Artifact --skill research-visualizer -g -y
SKILL.md
Frontmatter
{
"name": "research-visualizer",
"metadata": {
"tags": [
"research",
"visualization",
"trajectory",
"exploration-tree",
"html",
"ara-cli",
"validation",
"live-reload"
],
"author": "ara-commons",
"version": "1.1.0",
"category": "research-tooling"
},
"description": "Research Visualizer. Renders an existing Agent-Native Research Artifact (ARA) into ONE\nself-contained, interactive HTML file showing the AI scientist's step-by-step research process:\na clickable process map of the exploration tree (branches and dead ends included) on the left,\nand a per-step drill-down on the right — what the step did (its narrative written in plain language a\nperson can follow), why (the linked claim), the real result (verbatim grounded numbers + inline figures\n+ tables), and the code\/artifact pointer.\nRead-only consumer of the artifact — it never changes how research is done.\nWhen the ARA carries them, it also surfaces (each optional, only when present) the related-work\ndependency graph, the problem framing, a concepts glossary with in-text term popovers, and the\nsolution recipes — reached from header disclosures without leaving the process map.\nAccepts either an existing ARA or raw research input (a paper, repo, run logs, or notes); when the\ninput is not yet an ARA it is compiled into one first, then visualized.\nAlso fronts the official `ara` Rust CLI (github.com\/ARA-Labs\/ara-cli) as a second, live mode:\n`ara check` validates\/lints the artifact deterministically, and `ara serve` renders it as a\nlocal live-reloading viewer with zero LLM calls at view time — for the edit loop and CI gating,\nwhile the portable HTML export remains the shareable\/publishable output.\n\nTRIGGERS: visualize, visualizer, trajectory view, render the ARA, see the steps, step-by-step view,\nprocess map, replay the trajectory, watch the agent work, drill into steps,\nvisualize a paper, visualize a repo, visualize a run,\nara serve, live view, local viewer, watch the ara, live-reload, serve the artifact locally,\nvalidate the ara, lint the ara, ara check, check my ara, is this a valid ara, does this ara pass ci,\nview without an llm, deterministic view, browse ara examples, ara hub mode\n",
"allowed-tools": "Read, Write, Edit, Glob, Grep, Bash(python3 *|base64 *|find *|ls *|open *|ara *|which *|curl *|lsof *|pkill *|brew *|cargo *|sleep *)",
"argument-hint": "[ara-dir] [--output <path>] | [--serve [--port <n>] [--hub --ara-root <dir>]] [--check [--fix] [--strict]]"
}
Research Visualizer
You show an ARA. You are a read-only consumer: you read the artifact and emit a view; you never edit the ARA. There are two modes, and one routing decision:
- Export mode (default) — you render the ARA into a single portable HTML file: narrated steps,
verbatim evidence, inline figures, and the enrichment overlays. This is the shareable/publishable
output (
submit-arapublishes exactly this file). The rest of this document below "What you produce" is this mode. - Live mode — you drive the official
arabinary (github.com/ARA-Labs/ara-cli):ara checkto validate/lint,ara servefor a local live-reloading viewer with zero LLM calls at view time. Reach for it when the user is mid-edit and wants the view to track saves, wants a validation/CI answer ("does this still pass"), or asks for any of its triggers by name. It renders the ARA's structured fields deterministically but does not (yet) author narrative, inline figure exhibits, or per-node concept/code chips — when the user wants those, or a file they can send to someone, that's export mode. If genuinely unsure which the user wants, ask.
Live mode
- Resolve
<ara-dir>(or, for--hub, an--ara-rootwhose immediate subdirectories are each an ARA, e.g. this repo'sexamples/). which ara→ if missing, followreferences/ara-install.md(Homebrew first, Cargo fallback; never install without the user's confirmation). If present, check the version against the repo's CI pin per the same file — flag an older binary, don't silently upgrade.ara check <dir>first (add--strictto fail on warnings;--jsonfor machine-readable output). Clean → continue. Fixable issues and the user wants them fixed →ara check <dir> --fix, re-check, report what changed — never hand-edit the artifact to satisfy the linter. Notrace/exploration_tree.yamlat all → it's raw research input; route to thecompilerskill first, same as export mode's precondition.ara serve <dir> --port <port>(orara serve --hub --ara-root <dir> --port <port>) in the background; default port 8080, pick another if bound (lsof -i :<port>). Confirm withcurl -s -o /dev/null -w '%{http_code}'→ 200, and read the bound URL from the process's own stdout line rather than assuming.- Report the URL and open it for the user. Edits under
<dir>live-reload (add--pollonly for filesystems where the watcher misses changes). The server keeps running — tell the user how to stop it (e.g.pkill -f "ara serve") so it isn't silently orphaned. If they're new to the viewer, surface the relevant bits ofreferences/ara-serve-ux.md.
Export mode
You operate as a first-class agent — use your native tools directly. The heavy rendering logic is
already written in references/trajectory-template.html; you do NOT rewrite it. Your job is to
parse the ARA into one ARA_DATA JSON object, inline the figures, and inject that object into the
template's data slot.
What you produce
One self-contained file, default <ara-dir>/trajectory.html (override with --output):
- All data, tables, and figures (base64) inlined — no server, no network, no CDN. Double-click to open.
- Built by populating the canonical scaffold, so every generated view is structurally consistent.
v1 boundaries (do not exceed)
- Post-hoc visualization of a finished/in-progress ARA. No live/real-time mode.
- Self-contained from the ARA directory alone. Do NOT open or inline anything outside the ARA dir.
src/artifacts.mdrun-store pointers and nodesource_refs(external journalfile:line) are shown as pointers/chips, not resolved. (External resolution is a planned future extension — out of scope.) - Single ARA. No cross-ARA comparison.
Pipeline
- Args. Resolve
<ara-dir>(default: the ARA in the current working context / most-recently referenced). Resolve--output(default<ara-dir>/trajectory.html). 1b. Precondition — the input must be an ARA; if it is not, compile it first. Decide with one observable test: does the resolved input expose a parseabletrace/exploration_tree.yaml(≥1 node) — directly, or as a standard ARA directory layout?- It is an ARA → continue to Validate unchanged.
- It is not an ARA — the input is raw research material (a paper/PDF, a code repository, a
run/log directory, notes, or any directory with no exploration tree) → invoke the
compilerskill on that input to produce an ARA, then set<ara-dir>to the compiler's output artifact and continue. Do not hand-roll an ARA yourself; the compiler is the only path that builds one. Default--outputto<compiled-ara-dir>/trajectory.htmlunless the user set it. Only if the compiler still yields no exploration tree does the Validate step's "no process" message apply.
- Validate — the exploration tree is the ONLY hard requirement. Confirm
trace/exploration_tree.yamlexists and parses to ≥1 node; if not (and the precondition's compile step has already run), tell the user there is no process to show (this replaces the oldPAPER.md"is-this-an-ARA?" guard). Everything else —PAPER.md,logic/,src/,evidence/, and the four enrichment layers — is optional enrichment: glob whatever is present. IfPAPER.mdis absent, synthesize a minimalmeta(title from a tree-leveltitle:or the dir name; emptyabstracthides the disclosure). This is the raw-trajectory path: the skill produces a useful step-by-step view from just the tree (a raw agent run), not only a fully-compiled ARA — seereferences/parsing.md§7. - Parse the trace into normalized nodes. The field conventions vary across ARAs — follow
references/parsing.mdexactly (handlestree:vsroot:, generic vs type-named fields,evidence:routing,isolated,also_depends_on). Every node must yield atitle+body. - Parse the hub layers — each only when present (all optional now):
logic/claims.md(the binding hub when it exists),logic/experiments.md,evidence/README.md(figure/table ↔ claim reverse index),src/artifacts.md,logic/solution/*. A missing layer simply contributes nothing; the node still renders from its owntitle/body/thinking. Also parse the four OPTIONAL enrichment layers when present, perreferences/parsing.md§8:logic/problem.md→context,logic/concepts.md→glossary(+ build thelexicon),logic/related_work.md→dependencies,logic/solution/*.md→recipes(role-classify by content, not filename). A missing file/dir omits its key entirely. Reproduce statements/deltas/definitions/relations/ headings/quotes/cells verbatim. - Build each node's drill-down. When
logic/claims.mdexists, follow the claim-hub chain inreferences/binding.md(node →evidence:[C##]→ claims → {Sources quotes, figures/tables, experiments, artifact pointers}). When it does not, the drill-down is just the node's own narrative (thinking/body) — every claim/result/verified block is empty and omitted. 5b. Bind the enrichment layers per the "four enrichment layers" section ofreferences/binding.md: buildclaimIds/nodeByClaim/conceptNames/rwIds; resolve everyrefs[].target(drop danglers, never link off-ARA); derive each node'sbuilt_on/rejected_here(dependency→claim→node, bucketed byrelation_norm),concepts(whole-word name-match), andrecipe_refs(recipe→claim→node); mark cross-agent entries. All per-node enrichment fields default[]. 5c. Write each step's narrative as plain language (same layout, human words). The trace's notes are written for an agent; rendered as-is they read like a log and a person can't follow what happened or why it mattered. For each node, write its narrative —thinking, andbodyif used — in plain language a reader who has NOT seen the ARA can follow: your own words, translating the trace's agent-facing deliberation, not a verbatim paste; expand jargon on first use and state the point, not the log line. This changes ONLY the prose that fills the existing reasoning block — keep every block and the layout exactly as they are. Stay grounded: introduce no number, name, or claim that is not already in that node, and keep claimStatements,Sourcesquotes and table numbers verbatim in the why/result blocks — those are the receipts. - Inline figures. For each referenced figure that has a real raster (
evidence/figures/*.png), base64-encode it and put thedata:URI infigures[].img. Use Bash, e.g.python3 -c "import base64,sys;print('data:image/png;base64,'+base64.b64encode(open(sys.argv[1],'rb').read()).decode())" <path>. For data-only figure markdown (no raster), render its data table instead (as atables[]entry). Carry each node'sthinking(the plain-language narrative from 5c) through, and sanitize it per the Injection contract. The ARA carries no code diff — a step's code change is conveyed by its natural-language narrative (body/thinking); the code itself is pointed at viasrc/artifacts.md. - Assemble
ARA_DATA(exact schema inreferences/binding.md) and inject it: replace ONLY the JSON between/* __ARA_DATA_BEGIN__ */and/* __ARA_DATA_END__ */in the<script id="ara-data">block of a copy of the template. Write the result to the output path. Includecontext/glossary/dependencies/recipesand the per-nodebuilt_on/rejected_here/recipe_refs/conceptsonly when their sources exist — omit absent keys entirely (no empty stubs). A payload omitting all of them stays byte-compatible with the v1.0 schema. - Report the output path. Optionally open it (
open <path>on macOS). Print a one-line summary (node count, dead ends, figures inlined, which of the four enrichment overlays were emitted with their term/dependency/recipe counts, danglers dropped, any pointers left unresolved).
Injection contract (critical)
- The injected payload MUST be valid JSON (it is read with
JSON.parse). The template strips only the two named marker comments before parsing, so the payload is otherwise pure JSON. - It must not contain the literal substring
</script>, nor the literal marker strings/* __ARA_DATA_BEGIN__ *///* __ARA_DATA_END__ */. Escape any<in inlined markdown/text as<(or<) — this also neutralizes</script>. (A bare*/inside a string value is harmless toJSON.parse; only the exact marker strings would be stripped.) - Do not touch anything else in the template — only the bytes between the two markers.
- After writing, re-validate: the file still parses (the embedded JSON loads). If a figure pushed the
file very large, apply the size guards in
references/binding.md(truncate logs/tables, keep figures).
Faithfulness (hard rules)
- Speak human in the narrative, quote the evidence. A node's narrative (
thinking/body) is plain language — your own words, a grounded translation (5c), not a verbatim paste. Everything that is evidence — claimStatements,Sourcesquotes, table cells/numbers, relations, definitions — is reproduced verbatim in the why/result/overlay blocks. The narrative explains; the receipts prove. A narrative that states a number absent from the node fails; so does an evidence block that paraphrases. - Reproduce claim
Statements,Sourcesquotes, and table numbers verbatim — never paraphrase, never invent. Missing data → set the field empty/omit (the viewer shows "No …"); never fabricate. - Provenance,
support_level, andstatusare shown only if present in the source; do not guess. - Dead-end nodes and
isolatedsubtrees must be carried through faithfully — they are the most valuable things to display, not noise to drop. - For the enrichment layers: relation strings, definitions, constraint headings, and footprint citations
are reproduced verbatim; relation enums are open (compound
bounds / refutes/ transitionextends → quarantinedkept as written;relation_normis for color only). Never normalize a heading or invent a typed sub-field. Arefs[].targetis set only on real in-ARA resolution; dangling refs are flagged, never silently corrected or dropped.built_on/concepts/"used by" name-matches are best-effort hints (marked "inferred"), never asserted as facts.
Verify
Live mode — run against whatever ARA(s) are on hand and confirm:
which aramissing → install instructions offered perreferences/ara-install.md, nothing installed without asking.ara checkon a clean ARA →0 error(s), 0 warning(s); on a non-ARA directory → clear missing-trace/exploration_tree.yamlerror and you route tocompilerrather than serving it.ara serve <dir> --port <p>comes up,curlreturns 200 at the logged URL, and touching a file under<dir>is reflected without restarting;--hubserves the index at/and each artifact at/a/<id>/. The server is left running only with the user told how to stop it.
Export mode — run on any ARA and confirm these properties — no named fixtures required:
- Opens by double-click: no server, no network, no console errors.
- Full process map: nesting, branches, dead ends marked, any
isolatedsubtree boxed,depends_onchips. - Drill-down renders whichever blocks are present (what / why / result-with-inline-figure / how-verified /
code-or-pointer), correctly under both field dialects in
references/parsing.md. - Verbatim quotes/numbers; nothing fabricated; self-contained from the ARA dir (no needed external refs).
- Re-running reproduces the same structure (data differs only as the ARA differs).
- Enrichment layers: a layer's header button appears only when its source exists; an ARA with none of
the four layers renders identically to v1.0 (no layer bar, no node chips). Open each emitted overlay and
confirm verbatim relations/definitions/recipe cells, ungrounded/dangling/cross-agent markers, and that
the
built_on/rejected_herechips + the⊕/⊘map marker deep-link into Dependencies. Glossary popovers fire on body terms; inline$LaTeX$renders with no network. - Degradation: a
minimal-artifact(onlyproblem.md) shows only the Context button, others absent, popovers off, per-node chips empty, zero console errors. - Compile-first (non-ARA input): pointing the skill at raw research material with no exploration
tree (a paper, a repo, a run/log dir) triggers the
compilerskill first, then visualizes the resulting ARA — the output is identical to running the compiler then the visualizer by hand. - Raw trajectory (the decoupled path): a tree-only ARA — just
trace/exploration_tree.yaml, noPAPER.md, nologic/, noevidence/— still renders the full process map + each step's narrative (thinking/body), with no layer bar and no claim/result/verified blocks, zero console errors. This is a first-class supported input, not a failure mode.
Cover the variant axes with whatever ARAs you have: both root forms (tree:/root:), both field
dialects (generic / type-named), figures present as real raster vs. data-markdown-only, src/ as a
pointer index vs. transcribed code, and an isolated subtree if any artifact has one.
版本历史
-
126662e
当前 2026-07-30 23:01
重构技能:将ara-cli-viewer合并至research-visualizer作为Live模式。新增ara CLI的验证(lint/check)和本地实时重载服务功能,统一入口。
- 4f82e50 2026-07-05 09:18


