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

@damarals/insert-maker

v0.2.0

Published

Agent-guided board game insert design and fabrication toolkit

Downloads

476

Readme

Insert Maker

Insert Maker is an agent-guided toolkit for designing and fabricating board-game inserts. One repository ships the agent skill and the v0 Node.js runtime: a structured CLI, a project-scoped local server, and a read-only React viewer.

This repository is under active 0.x development. The current solver handles one or more independently dimensioned folded trays with single, grid, or corner arrangements of stacked, loose, or nested components. It packs every tray into the box floor, settles physical components in-process when needed, then publishes a canonical 3D scene, a reusable solved layout, and a dimensioned A4 cut-and-fold PDF that may use continuation pages.

Requirements

  • Node.js 24 or newer
  • npm 11 or newer

No Python runtime, browser automation, database, daemon, or globally active project is required.

Clean-computer workflow

Start with Node.js 24 and npm 11, then install the runtime and the repository skill as two explicit products:

npm install -g @damarals/insert-maker
npx skills add damarals/insert-maker --skill insert-maker -g

Open Claude Code or Codex and ask it to use the insert-maker skill. Give it the game, the physical measurements you already have, and a concrete destination such as /absolute/path/to/project. The agent creates that folder and writes a real spec.toml; there is no initializer or empty scaffold.

For example: “Use the insert-maker skill to design an insert for Quartz in /absolute/path/to/project. Ask only for physical measurements or design intent that you cannot infer safely.”

The agent then records decisions and drives the structured runtime with the same explicit project path on every command:

insert-maker note /absolute/path/to/project --actor agent --message "Initial design intent captured from the user"
insert-maker validate /absolute/path/to/project
insert-maker solve /absolute/path/to/project
insert-maker status /absolute/path/to/project
insert-maker serve /absolute/path/to/project

serve stays attached to its foreground terminal session. The agent reports the URL from the structured started event and keeps that session alive while the user views the project; it does not launch a browser. Specification edits, validation, solves, and status checks can continue in other command sessions. The viewer updates from the project files and remains read-only.

The iteration is complete when status reports a fresh layout, no unresolved typed bottleneck remains, floor and vertical use have been reviewed, and the fabrication plan at /absolute/path/to/project/corte.pdf matches the intended design. The agent uses CLI state and canonical geometry for its own evaluation; no visual capture or approval gate is part of the v0 workflow.

Manual updates

Runtime and skill updates remain separate and user-initiated. Rerun both commands when you choose to update:

npm install -g @damarals/insert-maker
npx skills add damarals/insert-maker --skill insert-maker -g

Project folders

Commands accept an optional project folder and otherwise use the current directory. A project begins with a hand-authored spec.toml; Insert Maker does not create a hidden registry or scaffold. The folder is the complete portable contract: copy or move it to another computer, point the same commands at its new path, and its durable intent, observations, and journal move with it. No database, daemon, or machine-global project record is involved.

[project]
game = "Quartz"
edition = "Retail edition"

[material]
thickness = 2
cutting_tolerance = 1
cutting_grid = 5
tape_per_face = 0.1

[box]
length = 268
width = 184
height = 68

[[top_layer]]
name = "Board and rulebook"
thickness = 11

[[tray]]
name = "Cards"
arrangement = "single"

[[tray.compartment]]
name = "Deck"

[[tray.compartment.component]]
name = "Sleeved cards"
quantity = 65
length = 91
width = 66
height = 0.45
shape = "box"
accommodation = "stack"

[[tray]]
name = "Tokens"
arrangement = "single"

[[tray.compartment]]
name = "Token well"

[[tray.compartment.component]]
name = "Wooden cubes"
quantity = 20
length = 25
width = 25
height = 2
shape = "box"
accommodation = "stack"

Authoring and construction contracts

The canonical specification reference documents every v0 field, default, and constraint for single, grid, corner, stacked, loose, and nested designs. The complete example above is intentionally the only schema example in this README so the two documents do not drift independently.

The solved layout is the canonical construction state. It records each folded bottom and wall, straight or folded divider, joint, lid, access cutout, compartment, component pose, tray footprint, and orientation. The viewer scene and corte.pdf are projections of that same state; neither reconstructs geometry independently.

Automatic physics and packing

When no compatible observation exists, solve runs multiple deterministic Rapier experiments directly in the Node process. Compatibility is based on component shape, quantity, dimensions, accommodation, compartment dimensions, and obstacle geometry; display-name changes do not invalidate an observation. The representative experiment records world-AABB pile heights, dispersion, spill factor, seed, and one settled pose per item. The published scene uses those poses directly.

Tray tape-fit envelopes are packed at integer 0.1 mm resolution. Tray dimensions round up, box dimensions round down, and each tray may remain unrotated or rotate by 90 degrees. The published layout records every position and orientation, verifies containment and non-overlap, and reports useful height, reserved top-layer height, occupied floor, free floor, and coverage.

The complete v0 file vocabulary is:

| File | Role | Behavior | | --- | --- | --- | | spec.toml | Durable design intention | Parsed and validated before every solve | | medidas.json | Durable physical observations | Validated, reused by semantic geometry, and recalibrated automatically | | layout.json | Regenerable solved layout | Canonical geometry, scene, semantic input fingerprint, and PDF digest | | log.jsonl | Append-only project journal | Attributed notes, successful solves, and typed bottlenecks | | corte.pdf | Regenerable vector cut plan | Potentially scaled A4 cut, score, fold, label, and dimension reference |

corte.pdf is a dimensioned fabrication reference, not a paper template. The printed numeric dimensions are authoritative. Never trace or cut material from an assumed page or printed scale; transfer the labeled measurements to the material and verify them before cutting. A tray's folded blank, lid, and divider parts may move onto continuation pages when they do not fit legibly together. The actual PDF page count is persisted in layout.json under artifacts.cutPdf.pages.

validate, status, and serve are read-only. note appends one journal event. solve publishes medidas.json when needed together with layout.json and corte.pdf as one coherent generation, then records the successful solve in log.jsonl. Failed calibration never leaks partial observations. A failed physical solve records its bottleneck without replacing the last valid generation.

Commands

validate [project]

Parses and validates spec.toml without running physics or producing artifacts. Standard output contains exactly one JSON record:

{"command":"validate","ok":true,"project":{"path":"/work/quartz","name":"Quartz"},"specification":{"valid":true}}

An invalid project is also structured and identifies field paths:

{"command":"validate","ok":false,"project":{"path":"/work/quartz","name":"quartz"},"specification":{"valid":false,"issues":[{"path":"box.height","message":"Too small: expected number to be >0"}]}}

solve [project]

Normalizes the specification, resolves and packs every tray, projects the 3D and fabrication views, and publishes both artifacts. Progress is JSONL so an agent can observe the operation without a separate --json mode:

insert-maker solve /work/quartz

The event order for a successful solve that can reuse every observation is:

started → normalized → solved → projected → completed

If calibration is required, one or more bounded rounds appear between normalization and solution:

started → normalized → measuring → measured → solved → projected → completed

Every event carries the command, outcome, and project identity. For example:

{"command":"solve","event":"started","ok":true,"project":{"path":"/work/quartz","name":"Quartz"}}

The completed event contains the full published layout. Invalid specifications emit one typed invalid event and do not publish partial artifacts.

Height, floor-packing, and empty-compartment failures end with a typed bottleneck event and exit code 4:

{"command":"solve","event":"bottleneck","ok":false,"project":{"path":"/work/quartz","name":"Quartz"},"bottleneck":{"kind":"floor-packing","element":{"kind":"tray","id":"tray-1","name":"Tokens"},"axis":"width","amount":0.1,"unit":"mm","message":"Packing the trays in one row needs 0.1 mm more box width"}}

The event identifies the responsible domain element and a concrete axis expansion that makes a row packing feasible. It is also appended to log.jsonl; it is not reported as an unexpected exception and does not overwrite an existing layout.json or corte.pdf.

The solver first uses binpackingjs, then a deterministic bounded exact fallback when the heuristic misses. If that fallback reaches its search budget without proving fit or rejection, it reports a typed packing-search-limit bottleneck with the consumed search-step count instead of turning resource exhaustion into an unexpected failure.

note [project] --actor user|agent --message <text>

Appends one attributed decision to the durable project journal and returns the exact persisted event. The project path remains optional for human use:

insert-maker note /work/quartz \
  --actor agent \
  --message "Reserve the top layer for rulebooks"
{"command":"note","ok":true,"project":{"path":"/work/quartz","name":"Quartz"},"event":{"id":"a7ded28a-43dc-45c3-903f-c73f56f50992","timestamp":"2026-08-22T15:00:00.000Z","kind":"note","actor":"agent","message":"Reserve the top layer for rulebooks"}}

Every line has a stable UUID, ISO timestamp, event kind, actor, and message. Insert Maker appends a complete JSON record in one operation and never rewrites earlier lines. A malformed existing event is rejected when project state is read rather than silently omitted or repaired.

status [project]

Reads the current project state without requiring a server and without changing file contents or timestamps. It reports specification validity, file presence, layout freshness, the latest bottleneck separately from preserved output, and the journal:

{"command":"status","ok":true,"project":{"path":"/work/quartz","name":"Quartz"},"specification":{"valid":true},"files":{"spec.toml":true,"medidas.json":false,"layout.json":false,"log.jsonl":false,"corte.pdf":false},"layout":{"state":"missing"},"latestBottleneck":null,"journal":[]}

status exits successfully when a specification is invalid because invalidity is inspectable project state that an agent can repair.

Layout state is deterministic:

  • missing: no committed layout.json exists.
  • fresh: the normalized intent fingerprint and PDF SHA-256 digest still match.
  • stale: a previous layout is preserved, but semantic input changed, the current specification is invalid, or the PDF is missing or does not match its digest.

The fingerprint payload contains normalized design intent and compatible physical observations; stack-only trays currently contribute no measurement observations. TOML comments, whitespace, and key order do not change it, while a real dimension or design edit does. layout.value remains available when stale so an agent can inspect the previous solution, but it must not be treated as current.

serve [project]

Starts one foreground Hono server for exactly one project. It binds to 127.0.0.1, tries port 4747, and advances until it finds an available port. Its first standard output line is a JSONL startup event:

{"command":"serve","event":"started","ok":true,"project":{"path":"/work/quartz","name":"Quartz"},"host":"127.0.0.1","port":4747,"url":"http://127.0.0.1:4747"}

The URL serves the bundled read-only viewer, GET /api/state, the root-relative GET /api/events SSE stream, and GET /artifacts/corte.pdf. The permanent viewer workbench includes the orbitable Scene with visibility controls and compartment inspection, an aggregate resolved-measurement ruler, the Cut plan PDF, bottlenecks, and the project journal. Preserved stale geometry stays visible behind an explicit not-current notice. A PDF is served only when its digest matches layout.json. One project watcher and event hub fan validated initial state and later project changes to every connected viewer. The command does not open a browser. Keep the terminal session open while using the viewer and press Ctrl+C to stop it. Starting another project creates an independent process on the next available port; it never switches the first process to a different folder.

Process contract

  • Standard output is machine-readable JSON by default.
  • Progressive operations such as serve emit JSONL.
  • Diagnostics and command usage go to standard error.
  • Commands do not prompt interactively.

| Exit code | Meaning | | ---: | --- | | 0 | Successful command | | 1 | Unexpected runtime failure | | 2 | Invalid invocation | | 3 | Invalid project | | 4 | Typed physical bottleneck |

Release

The package version is 0.2.0. A release is initiated only by pushing the matching stable tag, such as v0.2.0; ordinary branch pushes never publish. Before creating a tag, run the same release-candidate gate locally:

npm ci
npm run typecheck
npm test
npm run build
node scripts/verify-release.mjs v0.2.0

The full test suite packs the package, installs it globally under an isolated prefix, exercises the CLI and bundled static viewer, solves the canonical project, and checks the skill layout. This proves the candidate before any publication tag exists.

One-time npm bootstrap

npm requires a package to exist before a trusted publisher can be assigned to it. Once release.yml is on the default branch, use an npm account with package write access and account-level 2FA to publish the disposable 0.0.0 bootstrap. The script builds the project, stages only the package files allowlist, and changes only the staged package version:

npm install --global [email protected]
npm login
node scripts/pack-bootstrap.mjs /tmp/insert-maker-bootstrap
npm publish /tmp/insert-maker-bootstrap/damarals-insert-maker-0.0.0.tgz --access public --dry-run
npm publish /tmp/insert-maker-bootstrap/damarals-insert-maker-0.0.0.tgz --access public
npm trust github @damarals/insert-maker --file release.yml --repo damarals/insert-maker --allow-publish
npm trust list @damarals/insert-maker

This authenticated publication happens once and does not use a GitHub Actions secret or create a release tag. After the trust relationship is visible, normal releases are tag-only:

git tag v0.2.0
git push origin v0.2.0

The npm package must have one GitHub Actions trusted publisher with these exact fields:

| Field | Value | | --- | --- | | Organization or user | damarals | | Repository | insert-maker | | Workflow filename | release.yml | | Environment | none | | Allowed action | npm publish |

The tag-only workflow uses GitHub OIDC and stores no npm publication token. A read-only job installs exact dependencies, runs every gate, packs and dry-runs the exact tarball, then hands it off with a digest. Only the second, dependency-free job receives npm and GitHub publication authority. It verifies the handoff, stages a draft GitHub release, publishes the package with public access, then publishes the matching GitHub release. A retry verifies both the registry SHA-512 and any existing release asset before continuing, so interrupted cross-service publication cannot replace a different artifact. Repository-level immutable releases then lock the published tag and asset.

The development repository remains private. npm Trusted Publishing still works for a public package from a private repository, but npm does not generate provenance for private source repositories. See the npm Trusted Publishing documentation.

Development

Use Node.js 24 or newer for every command:

npm install
npm run typecheck
npm test
npm run build

npm run build is the single build entry point for the Node runtime and Vite viewer. Vitest is the only test runner. npm pack automatically performs a clean build before creating the tarball.