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

@ai-gui/plugin-resultset

v0.29.2

Published

Host-owned result tables for AIGUI: the numbers in an answer come from the query, not from the model retyping them.

Readme

@ai-gui/plugin-resultset

Host-owned result tables for AIGUI: the numbers in an answer come from the query, not from the model retyping them.

Why it exists

A model that reads 4624290 out of a tool result and types it into a sentence has introduced a transcription step that nothing checks — and transcription is exactly where a digit goes missing.

@ai-gui/plugin-evidence proves which query ran. It does not prove the number in the prose came from it. This plugin closes that gap from the other side: the host emits the rows verbatim, and the prompt tells the model to point at the table instead of copying out of it.

Install

pnpm add @ai-gui/plugin-resultset

Usage

import { AIRenderer } from "@ai-gui/react"
import { resultset, resultsetPromptSpec, serializeResultsetFence } from "@ai-gui/plugin-resultset"

<AIRenderer text={answer} plugins={[resultset()]} />

1. Append resultsetPromptSpec() to the system prompt:

Never emit a ```resultset fence. The application appends result tables from the rows it really returned.
Do not retype figures from a table into your prose. Refer to the table by id, e.g. [[result:by_region]], and describe what it shows.

2. Append the fence server-side, from the rows you actually got back:

const fence = serializeResultsetFence({
  id: "by_region",
  label: "Revenue by region",
  columns: result.columns,
  rows: result.rows,
  source: "warehouse",
  truncated: result.truncated,
})
return answer + "\n\n" + fence

The fence

```resultset
{"id":"by_city","label":"Orders by city",
 "columns":["city","orders","amount"],
 "rows":[["Shanghai",2104,4624290],["Beijing",1460,3011880]],
 "source":"shop","truncated":false}
```

| field | | |---|---| | columns / rows | required; every row must be exactly as wide as the header | | id | what the prose points at — [[result:by_city]] | | label | caption, usually the question this answers | | source | where it ran | | truncated | more rows existed than were returned |

A row that does not match the header is rejected, not padded. A misaligned table puts a number under the wrong column, which is worse than no table.

null renders as a distinct, muted null rather than an empty cell — "we have no value" and "the value is empty" are different findings.

Options

| option | default | | |---|---|---| | maxRows | 200 | rows rendered per table (hard cap 500) | | showId | false | print the id beside the caption, so prose references are traceable |

Numbers

Numeric cells are right-aligned, tabular-nums, and grouped: 4,624,290, never 4.62429e+06. The same figure either way — but only one can be compared with the number below it at a glance, which is the entire job of a column of numbers.

Rows beyond the cap, and truncated, are both stated in the footer. A table silently cut to its first page is a wrong answer that looks complete.

Streaming

Complete-gated, like plugin-chart and plugin-evidence. A table that grows a row at a time reads, mid-stream, as a table that is already finished: a reader who looks away at the wrong moment sees four rows where there were nine, and nothing tells them so.

Styling

resultsetCss is a plain string of the defaults; the markup carries data-aigui-resultset* attributes so you can ignore it entirely. Colours use color-mix against currentColor, so the table follows the surrounding theme.

License

MIT