npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

agent-folio

v0.7.0

Published

Local-first, zero-server reports for coding-agent work

Downloads

513

Readme

Folio

Folio turns substantial coding-agent output into durable, readable HTML reports you can review like code. It is local-first and server-free: one CLI command stores source and metadata, generates one standalone HTML file, and opens it in your browser.

Select report text, add anchored comments in the right review rail, then copy structured Markdown back into your coding agent. No daemon, browser extension, cloud account, or network connection participates in that loop.

Folio architecture report with table-of-contents navigation, download controls, and an anchored comment in the review rail

Install

Folio is distributed as source through npm and requires Bun 1.3 or newer. Run it without installing:

bunx agent-folio --help

npx uses the same npm package and works when bun is already on PATH:

npx agent-folio --help

Install the command globally if preferred:

bun add --global agent-folio
folio --help

Remove it with bun remove --global agent-folio. The npm package executes the TypeScript source directly with Bun; it does not download or build a platform bundle. Node-only execution is not currently supported because Folio uses Bun's SQLite and HTTP runtime APIs.

Standalone executables remain available as an optional installation. Download the archive for your OS and CPU from the GitHub release, verify it against SHA256SUMS, extract it, and place the executable on PATH. macOS and Linux users can install an extracted binary with:

install -m 755 folio-darwin-arm64 ~/.local/bin/folio

Use the matching filename for your platform. Release assets cover macOS, Linux, and Windows on arm64 and x64, and include SHA256SUMS.

The macOS downloads are not notarized. If Gatekeeper quarantines one, review the downloaded file and approve it in System Settings → Privacy & Security before running it.

To compile and install a standalone binary from a checkout:

bun install
bun run build:install

build:install runs an optional repository-local scripts/postinstall.sh after replacing the binary. The hook is Git-ignored so each user can define local service startup or other machine-specific work. It receives FOLIO_BIN and FOLIO_BIN_DIR; a missing hook is a successful no-op. Pass --no-postinstall to skip it explicitly.

This builds a standalone executable at ~/.local/bin/folio. It does not edit shell profiles. Use --bin-dir <directory> for another location or --force to replace an existing binary:

bun run scripts/install.ts --bin-dir ~/.local/bin --force

Quick start

folio create examples/auth-investigation.mdoc

Report opens as standalone file:// HTML.

Select text → Comment → write feedback → Copy All Comments.

Use --no-open for automation:

bun run src/cli.ts create examples/auth-investigation.mdoc --no-open --json

Folio Markdoc

Reports use strict Folio Markdoc v1: YAML frontmatter, one leading summary, ordinary Markdown, and a small semantic tag set.

---
schema: folio/v1
title: Refresh investigation
kind: investigation
tags: [authentication]
---

{% summary %}
Concurrent refreshes can exchange one token twice.
{% /summary %}

## Finding

{% finding title="Refresh race" severity="high" confidence="high" %}
Two requests enter the refresh path concurrently.
{% /finding %}

Generate a skeleton or concise syntax guide:

folio template investigation
folio format

Raw HTML, arbitrary tags, unsafe links, H1 headings, nested semantic blocks, and normal Markdown images are rejected.

File links and media artifacts

Reference source files with paths relative to Git root. Folio turns them into local links and preserves evidence locations in exported feedback:

The race starts in {% file path="src/auth/session.ts" lines="84-117" /%}.

Attach image or video artifacts from testing with the dedicated media tag:

{% media path="artifacts/fixed-page.png" alt="Fixed page in Chrome" caption="Acceptance result" /%}

{% media path="artifacts/interaction.mp4" kind="video" caption="Interaction recording" /%}

Media bytes are embedded as data URLs. Copying only report.html keeps images, videos, styling, annotation UI, and export logic intact. Media and file paths must be Git-root-relative; symlinked media may not escape the repository.

Flint charts

Models can add semantic Flint chart specs directly to reports. Folio validates each spec, compiles it through Flint's Plotly backend, and embeds both the compiled figure and Plotly runtime into chart-bearing HTML. Charts stay interactive without a server or network connection.

{% chart alt="Requests by month" caption="Monthly request volume" %}

```flint
{
  "data": { "values": [{ "month": "Jan", "requests": 120 }, { "month": "Feb", "requests": 180 }] },
  "semantic_types": { "month": "Month", "requests": "Count" },
  "chart_spec": {
    "chartType": "Bar Chart",
    "encodings": { "x": "month", "y": "requests" }
  }
}
```

{% /chart %}

Charts require useful alt text and one fenced flint JSON object. Only inline data.values is allowed; Folio never fetches chart data or reads paths named by a model. Encoded fields must exist in the rows and have semantic types. Limits are 5,000 rows, 100 fields, and 512 KiB per chart.

Browser review

Each paragraph, heading, list item, blockquote, and code block has a deterministic annotation anchor. Selections stay inside one block and may not overlap existing comments.

Comments appear in a right-side review rail and support add, edit, delete, clear, and best-effort localStorage persistence. If storage is unavailable, current-tab review still works. Copy All Comments writes document-ordered Markdown containing report context, quoted text, section, optional evidence path, and feedback. Clipboard failure opens a manual-copy dialog. Download Comments.md exports identical Markdown.

An agent can opt a report into direct feedback dispatch by passing an exact-session command that reads the generated Markdown from stdin:

folio create report.mdoc --callback-command 'workmux send folio'
folio create report.mdoc --callback-command 'codex exec resume 01234567-89ab-cdef-0123-456789abcdef -'
folio serve

The bundled Folio skill checks workmux list --json first and otherwise uses the exact CODEX_THREAD_ID; it never targets “latest”. Workmux sends to the live pane. Direct Codex starts an explicit non-interactive continuation of that session.

Open the report through http://127.0.0.1:7331, add comments, then choose Send Callback to Agent beside Copy All Comments. Folio shows the exact command and comment count for confirmation before running it. Callback commands are stored only in the local catalog, never in immutable report artifacts, metadata files, or shared HTML. They run only through a loopback archive server, from the report repository when available, with feedback on stdin rather than interpolated into the command.

The table of contents navigates report headings. Night Owl is the default palette; theme selection supports system, light, and dark modes. Source files use locally bundled MicroLighter grammars. Timestamps use the viewer's locale. HTML and PDF exports omit review controls and absolute local links. Markdown exports flatten semantic blocks into ordinary Markdown while retaining their values and repository-relative file labels.

Comments never enter SQLite and are not synchronized. A new report revision gets a new report ID and separate browser review state.

CLI

folio create <file|-> [--stdin] [--no-open] [--json] [--supersedes <id>] [--callback-command <command>]
folio validate <file|-> [--json]
folio template <kind>
folio format
folio list [--repo <key>] [--kind <kind>] [--limit <n>] [--json]
folio show <id> [--source] [--json]
folio export <id> <--md|--html|--pdf> [--out <directory>]
folio open <id|latest>
folio path
folio serve [--portless] [--host 127.0.0.1] [--port 7331]
folio skill install [--target <skills-directory>] [--data-dir <directory>] [--force] [--json]
folio completion <bash|zsh|fish>
folio --version

Pass --data-dir <directory> to any command that reads or writes the catalog. It has precedence over FOLIO_HOME; relative paths resolve from the current directory.

Folio loads optional UI overrides from <data-directory>/settings.json. Copy the packaged settings.json to that location and change any subset of the light or dark palette. Colors must use six- or eight-digit hex notation; unknown keys fail fast instead of becoming CSS.

create validates before writing, collects local Git metadata, writes report artifacts atomically, and inserts catalog metadata. --callback-command stores an optional command in the catalog without placing it in report artifacts. HTML opens by default only in an interactive terminal; --json, --no-open, CI, and redirected output skip implicit opening. Browser-opening failure does not discard or fail report creation.

export prints Markdown to stdout when --md is used without --out. Markdown with --out, HTML, and PDF are written as out/<report-id>.<format> by default; pass --out <directory> to choose another directory. PDF export uses a locally installed Chrome, Chromium, or Edge executable; set FOLIO_CHROME_BIN when automatic discovery cannot find it.

Unknown options fail. Use -- before a path beginning with -. Set FOLIO_DEBUG=1 to include a stack trace for unexpected failures. Generate basic shell completion with, for example, folio completion zsh.

Storage

Folio resolves its data directory in this order:

  1. FOLIO_HOME
  2. $XDG_DATA_HOME/folio
  3. ~/.local/share/folio
folio.sqlite
reports/<report-id>/
  report.mdoc
  report.html
  meta.json

SQLite uses foreign keys and WAL mode. Reports are immutable. meta.json duplicates important catalog metadata so artifact directories remain understandable without SQLite. Folio never writes generated reports into your Git repository.

Optional archive

The review workflow does not require a server. folio serve adds an archive, repository source viewer, and opt-in callback delivery:

folio serve
# http://127.0.0.1:7331

For a stable local URL, run the archive through bundled Portless:

folio serve --portless
# https://folio.localhost

Portless starts its local proxy and gives Folio an available loopback port, avoiding fixed-port collisions. On first launch, macOS or Linux may request administrator access to trust its local CA and bind HTTPS port 443. --portless cannot be combined with --port; without --portless, explicit --host and --port flags still override HOST and PORT.

The archive lists known Git repositories in a right-side panel with report counts. Repositories with multiple recorded branches expand to branch filters. Repository, branch, clickable tag, search, and report-type filters preserve one another. New reports appear through SSE without reloading the page.

Served reports use the current review shell, so older immutable artifacts gain current navigation and controls without being rewritten on disk. Back to all reports stays above the table of contents in the sticky sidebar. Referenced repository files open in a Night Owl syntax-highlighted viewer with JetBrains Mono, line-aware comments, and the shared theme switcher. Source access is limited to files referenced by the report and contained inside the repository root.

Callback execution and source viewing are loopback-only. Each served callback gets an unguessable server-lifetime token, rejects concurrent and oversized requests, and has a 30-second timeout. A non-loopback host requires explicit --allow-network; callbacks and repository links remain disabled, served metadata omits the absolute repository root, and repository links are removed.

Coding-agent skill

Repo includes compact skill at skills/folio-report. Install it into Codex skill discovery:

folio skill install

Without a global install:

bunx agent-folio skill install

The command installs into $CODEX_HOME/skills/folio-report, or ~/.codex/skills/folio-report when CODEX_HOME is unset. Use --target <skills-directory> for another agent skill directory. Existing modified content is preserved unless you explicitly pass --force.

For coding-agent sandboxes that cannot write to the normal user-data directory, configure a writable report root while installing the skill:

folio skill install --data-dir .folio --force

The installer records this value in the skill's small runtime reference. The skill then passes --data-dir .folio whenever it invokes Folio. Relative paths are repository-local; add .folio/ to that repository's ignore rules if you use this layout. An absolute writable path can instead provide one shared catalog.

Then invoke $folio-report, or let it trigger for substantial work products. Skill uses progressive disclosure: short workflow in SKILL.md, full format details in references/format.md, and CLI-generated templates for common report kinds.

For substantial work in an existing repository, the skill first uses folio list --json, folio show <id> --json, and folio export <id> --md to recover relevant prior insights. Historical reports remain context rather than current truth, so the agent verifies drift-prone claims against the repository before relying on them.

Development

bun run typecheck
bun test
bun run check
bun run test:package
bun run build:binary
bun run build:install

Tests isolate FOLIO_HOME; they never touch your real catalog.

bun run build:release cross-compiles the six optional release executables into dist/. GitHub Actions checks Linux, macOS, and Windows, smoke-tests the packed npm command, bundles executables with license notices, generates SHA-256 checksums, publishes the npm package with provenance, and creates a GitHub release when a matching version tag is pushed:

bun run release -- 0.3.0 --dry-run
bun run release -- 0.3.0

The release command requires a clean main synchronized with origin/main, the srsatt Git/GitHub identity, a matching package.json version and changelog section, and a version tag that does not exist. It runs all local gates, creates an annotated tag without rewriting commits, pushes the tag, and watches the release workflow. Use --skip-gates only when the same commit was already verified; CI always reruns the gates. Before the first release, configure srsatt/folio as a trusted publisher for agent-folio on npm. A manual workflow run builds the same downloadable archives as workflow artifacts without creating a GitHub release or publishing npm.

Security model

Report input is untrusted text. Folio allowlists tags and attributes, rejects raw HTML and unsafe URLs, HTML-escapes report content, and writes comment content only through DOM text APIs. Generated HTML contains no remote scripts, stylesheets, fonts, analytics, telemetry, uploads, or background processes. Media is read locally once and embedded. Repository links require an explicit click. Optional callbacks require a loopback server, an explicit stored command, a per-server token, and browser confirmation showing the exact command; comment text is passed only on stdin.

MVP limits

  • Text selections cannot cross blocks or overlap.
  • Review state is browser-local and differs between file:// and archive HTTP origins.
  • Direct callbacks require opening the report through loopback folio serve; standalone files retain copy/download feedback only.
  • Media embedding increases HTML size, especially for video.
  • Repository links target local absolute file:// paths generated at creation time, so they may not work after moving HTML to another machine.
  • No collaboration, comment threads, syncing, report editing, full-text search, generated DOCX files, AI calls, MCP, or GitHub/GitLab API integration. PDF export requires a locally installed Chromium-family browser.

See Folio.md for complete product specification.