The research-to-report workflow.
Give it a topic. It runs a real research pass — decomposing the question, sending parallel agents after sources, auditing what came back, then synthesizing a decision-grade report — and publishes the result as a designed, self-contained HTML document in a library you host yourself.
Fieldpacket is agent-driven. Your coding agent (Claude Code, Codex, …) is the engine: it does the research and designs each report. There is no API key and no LLM SDK — it runs on the agent subscription you already have. The TypeScript CLI is the deterministic half: index, serve, PDF, verify.
topic
│ /deep-dive decompose → parallel research agents → audit → synthesize
▼
report.md
│ publish-report build (house design brief) → adversarial polish → publish
▼
reports/<slug>.html + meta/<slug>.json
│ fieldpacket index
▼
your library ──▶ fieldpacket serve ──▶ fieldpacket pdf
A published report — the stamped hero leads with the single most useful finding, then KPI stamps, ticket metadata, and a sticky numbered TOC:
Further down: comparison matrices, verdict cards, and itemized figures with dotted leaders — components chosen to fit the content, not decoration.
Your library — live search, tag chips with counts, and a cards/compact/list density toggle, all client-side and working with JavaScript off:
The same report at 390px. Wide comparison tables stay usable instead of overflowing, because the polish pass rejects any report where they don't:
Every image above is generated from the real report in examples/
by scripts/screenshots.mjs — nothing is mocked up.
The deep-dive skill is the front end, and it does the heavy lifting:
- Scopes the work. Picks a tier — Focused (5–7 subtopics, 40–60 sources), Standard (7–9, 60–80), or Comprehensive (9–12, 80–100+) — from the breadth and maturity of the topic.
- Decomposes before searching. Distinct angles: current state, technical depth, comparisons, real-world usage, hard data, limitations and criticism, economics, ecosystem, future direction.
- Researches in parallel. One agent per subtopic, each running broad searches, deep-reading 5–8 primary sources, then follow-up searches to close gaps — returning findings, data points, contrarian views, and annotated sources.
- Audits the raw material. Source count and quality, contradictions between agents, duplicate authoritative sources, thin subtopics — with supplementary agents run where it's short.
- Synthesizes by theme, not by subtopic. Cross-referenced, every claim cited inline, comparison tables, an uncertainty ledger where sources disagree.
The output is a 4,000–10,000+ word markdown report with 40–100+ cited sources.
The publish-report workflow turns that markdown into a field packet —
a single self-contained HTML file built to be used as a reference document, not
skimmed as an article:
- Build — renders it against a house design brief: stamped hero with the headline finding, KPI stamp grid, ticket metadata, numbered sticky TOC, comparison matrices, "best for / avoid if" panels, itemized figure lists, grouped source audit trail.
- Polish — a second agent adversarially critiques and fixes the HTML in place: tables usable at 360px, every row and citation preserved against the source markdown, AA contrast, reduced motion, print CSS.
- Publish — rebuilds the library index and verifies the result.
The visual quality bar, including the rejection criteria, is
docs/visual-standard.md. See
examples/ for a real report produced by this pipeline: 7,800
words in, a 111KB packet out, 67 sources.
- Node.js 24+ — the CLI runs TypeScript directly via native type stripping. No build step, no runtime dependencies.
- A coding agent — Claude Code, Codex, or anything that reads
AGENTS.md. - Optional: Chrome + puppeteer-core for PDF export.
git clone https://github.com/buddyh/fieldpacket.git
cd fieldpacket
./install.shThat links the skills into ~/.claude/skills, the workflows into
~/.claude/workflows, and creates your library at ~/fieldpacket. Re-run it
after pulling. Put the CLI on your PATH:
echo 'export PATH="$PWD/bin:$PATH"' >> ~/.zshrc && exec zshYou brief your agent the way you'd brief a researcher — the more you say about what you actually care about, the better the report. In a Claude Code session:
I want a deep dive on carbon steel pans for a home cook. I care about induction compatibility, how much seasoning babysitting they really need, and whether the expensive ones are meaningfully better than a $40 Lodge. Skip anything that reads like an affiliate listicle — I want real sources and I want to know where they disagree. Use the fieldpacket deep-dive workflow, and publish it to my library when it's done.
The agent scopes the tier, shows you the subtopic plan, runs the parallel research, synthesizes the report, then hands it to the publish workflow. You stay in the loop — adjust the angles, push back on the plan, ask for another section, all in the same conversation.
Short prompts work too (/deep-dive carbon steel pans), you just get to steer
less. Or drive the publish workflow directly against markdown you already have:
Workflow({ name: 'publish-report', args: {
srcMd: '~/fieldpacket/source/carbon-steel-pans.md',
slug: 'carbon-steel-pans',
title: 'Carbon Steel Pans: A Deep-Dive Buying Guide',
tags: ['cookware', 'buying guide']
}})Then read it:
fieldpacket serve # http://127.0.0.1:8110| Command | What it does |
|---|---|
fieldpacket init |
Create the library root |
fieldpacket index |
Rebuild index.html from meta/*.json |
fieldpacket serve [port] |
Serve the library (default 8110, loopback) |
fieldpacket list |
List published reports, newest first |
fieldpacket verify [slug] |
Check the library, or one report, is well formed |
fieldpacket pdf <slug> [width] |
Render a faithful single-page PDF |
fieldpacket doctor |
Check the environment |
fieldpacket root |
Print the resolved library root |
$FIELDPACKET_ROOT/ default: ~/fieldpacket
├── source/<slug>.md the research markdown
├── reports/<slug>.html the published field packet
├── meta/<slug>.json sidecar: slug,title,subtitle,date,tags,summary,sources,method
├── pdf/ rendered PDFs
└── index.html the browsable library
index.html, reports/, and meta/ are plain static files — upload them to
any static host if you'd rather not self-serve. Keep source/ and pdf/
private unless you mean to publish them.
| Variable | Purpose |
|---|---|
FIELDPACKET_ROOT |
Library root (default ~/fieldpacket) |
FIELDPACKET_TITLE |
Masthead heading for the index |
FIELDPACKET_TAGLINE |
Masthead lede for the index |
FIELDPACKET_PDF_DIR |
Where PDFs are written (default <root>/pdf) |
FIELDPACKET_CHROME |
Chrome/Chromium binary for PDF export |
AGENTS.md How an agent should drive this repo
bin/ The CLI entry point (Node 24 guard + dispatch)
docs/ The visual standard — the bar reports are held to
examples/ A real report: source markdown, published packet, sidecar
skills/ deep-dive (research) and fieldpacket (publish/operate)
src/ index builder, static server, PDF renderer, CLI
tests/ Test suite for the deterministic half
workflows/ publish-report (build→polish→publish) and report-to-pdf
npm install # dev tooling only; the CLI itself has no dependencies
npm run typecheck
npm testMIT



