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-gravity

v0.40.0

Published

Gravity and collision figures for AIGUI — orbits, binaries, comets and colliding discs, integrated from the conditions the model states.

Readme

@ai-gui/plugin-gravity

Gravity and collision figures for AIGUI. The model states masses, orbits and speeds; the trails, the orbital speeds, the periods and the collisions are computed.

Install

pnpm add @ai-gui/plugin-gravity

No runtime dependency beyond @ai-gui/core. The output is SVG, animated in the browser and complete as a still.

Usage

import { gravity } from "@ai-gui/plugin-gravity"
import { buildSystemPrompt } from "@ai-gui/core"

<AIRenderer plugins={[gravity()]} />

// The model has no prior for this block, so the spec is what makes it usable at all.
const system = buildSystemPrompt({ registry, plugins: [gravity()], locale: "zh-CN" })

The model then emits:

近日点 0.6 AU、偏心率 0.9 的彗星,远日点在 11.4 AU。

```gravity
{
  "units": "astronomical",
  "bodies": [
    { "id": "太阳", "mass": 1 },
    { "id": "彗星", "mass": 0, "orbit": { "around": "太阳", "distance": 0.6, "eccentricity": 0.9 } }
  ],
  "duration": 25,
  "caption": "彗星轨道"
}
```

Why the protocol looks like this

Conditions, never results. A model asked for Earth's orbital speed answers 29.78 km/s from memory, in the wrong units half the time, and a figure drawn from that number is a spiral. Given orbit: { around, distance } the speed is derived from the condition, and the line under the figure — speed, period, energy drift — is computed from the same numbers the trails are drawn from, so it cannot disagree with the picture.

A unit system, not a G. astronomical is AU, years and solar masses, where G is 4π² exactly and "Earth at 1 AU" comes out as one year without anyone typing 5.97e24. si is for questions already in metres and kilograms. toy is unitless with G = 1, or any value — G = 0 is a plain collision table.

An integrator, not an engine. Kick-drift-kick leapfrog with a step that adapts to the closest pair. It is symplectic, so the energy error oscillates instead of growing: Earth is still at 1 AU after twenty orbits, to a few parts per million. A step cap ends a run that would otherwise never finish (two point masses falling into each other) and the line under the figure says so.

Collisions decided by radii. merge coalesces two touching bodies, conserving mass and momentum; bounce is an elastic impulse along the line of centres, conserving momentum and kinetic energy. Either rule requires a radius on every body, because without one the rule is a promise the figure cannot keep. The step also shrinks so a fast disc cannot tunnel through a small one.

Supported

| | | | --- | --- | | Units | astronomical, si, toy (with optional G) | | Bodies | mass (0 is a test particle), position + velocity, or orbit (around, distance as periapsis, eccentricity, angle, direction); radius, color, fixed | | Collisions | none, merge, bounce | | Under the figure | orbital speed and period per orbiting body, each collision with its time, the energy drift, and whether the step cap ended the run |

Not in this version, and the prompt spec tells the model to explain them in prose or use another block: three-dimensional orbits, relativistic effects, tides and non-point bodies, air resistance. Projectiles and free fall near the ground, and head-on one-dimensional collisions, belong in @ai-gui/plugin-motion, whose closed forms give exact numbers.

Options

  • width?: number, height?: number — figure size in CSS pixels, default 640 × 400.
  • maxBodies?: number — refuse a scene with more bodies than this, default 12.
  • maxSteps?: number — step cap, default 200 000.
  • maxSourceBytes?: number — refuse a fence larger than this before parsing it, default 16 KiB.
  • animate?: booleanfalse draws every scene as a still; default true. The animation only moves the bodies along trails that are already drawn, so a still, a screenshot, or a reader who prefers reduced motion sees the whole story.

theme is honoured, so a figure on a dark page is drawn for one.

See the root README for the full plugin list.