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

@horu2day/pure-cad-cli

v0.1.1

Published

Headless pure-cad CLI — AutoCAD-style accoremgd analog. Self-contained QuickJS-WASM core; no source code dependency.

Downloads

126

Readme

@horu2day/pure-cad-cli

Headless pure-cad CLI. AutoCAD accoremgd.dll analog — drives the full CAD engine in a QuickJS-WASM sandbox, without exposing source code or a GUI.

Pipes natural-language → script → DXF/DWG for AI agents (Claude Code, Antigravity, GPT, ...).


Install

Public npm package. No token or .npmrc needed — Node.js 20+ only.

# Permanent install
npm i -g @horu2day/pure-cad-cli

# One-shot
npx @horu2day/pure-cad-cli new --output empty.dxf

CLI

pure-cad run    --script s.js [--input base.dwg] --output out.dwg
pure-cad query  --input drawing.dwg
pure-cad export --input file.dwg --output file.dxf
pure-cad new    --output empty.dwg

All commands print one JSON line to stdout. Errors → stderr with { ok:false, error, code }.

Exit 0 = success, 1 = failure.


Script API (inside --script files)

cad.cmd(NAME, ...args) feeds the arguments to the command's prompts in order. A command that still wants input after the last argument draws nothing, so the argument count matters — see Warnings.

// Drawing
cad.cmd('LINE', '0,0', '100,100'); cad.confirm();     // points…, then confirm
cad.cmd('CIRCLE', '50,50', '25');                     // center, radius
cad.cmd('ARC',    '0,0', '50,50', '100,0');           // start, mid, end
cad.cmd('RECT',   '0,0', '100,50');                   // 2 diagonal corners
cad.cmd('PLINE',  '0,0', '100,0', '100,100', 'C');    // points…, 'C' closes
cad.cmd('POLYGON', '6', '50,50', 'I', '30');          // sides, center, I/C, radius
cad.cmd('ELLIPSE', '50,50', '100,50', '0.5');         // center, major-end, ratio ≤ 1
cad.cmd('TEXT',   '10,10', '5', '0', 'Hello');        // pt, height, ROTATION, string
cad.cmd('MTEXT',  '10,10', '90,60', 'Multi-line');    // 2 corners, string

// Modify — these select first. Pick with 'L' (last) or 'ALL', close the
// selection with cad.confirm(), then answer the rest with cad.input().
cad.cmd('MOVE',   'L'); cad.confirm(); cad.input('0,0'); cad.input('50,50');
cad.cmd('COPY',   'L'); cad.confirm(); cad.input('0,0'); cad.input('100,0'); cad.confirm();
cad.cmd('ROTATE', 'L'); cad.confirm(); cad.input('0,0'); cad.input('45');
cad.cmd('SCALE',  'L'); cad.confirm(); cad.input('0,0'); cad.input('2');
cad.cmd('MIRROR', 'L'); cad.confirm(); cad.input('0,0'); cad.input('0,100'); cad.input('N');
cad.cmd('ERASE',  'L'); cad.confirm();
cad.cmd('OFFSET', 'L'); cad.confirm(); cad.input('5');        // or a point on the side
cad.cmd('HATCH',  'L'); cad.confirm(); cad.input('ANSI31');   // boundary must be closed

// Dimensions
cad.cmd('DIMLINEAR', '0,0', '100,0', '50,-15');
cad.dim.radius('50,50', 30, '85,80');
cad.dim.angular('0,0', '100,0', '0,100', '40,40');

// History
cad.history.beginGroup(); /* ... */ cad.history.endGroup();
cad.history.undo();

// Inspect
cad.doc.entities();
cad.doc.summary();

Warnings

run returns a warnings array (also printed to stderr as [warn] …) naming every command that ended without drawing:

{"ok":true,"output":"out/plan.dxf","entityCount":3,
 "warnings":["TEXT: cancelled by the next command while still waiting for input after 3 argument(s) — nothing was drawn. Check the argument list for this command."]}

An agent should treat a non-empty warnings as a failed script and fix the argument list — ok:true only means the file was written.

Full reference: see docs/ai/SYSTEM_PROMPT.md in the parent repo.


Architecture

┌─ Host (Node.js)
│  bin/pure-cad.js → src/index.js → src/commands/{run,query,export,new}.js
│    └─ fs.readFileSync / fs.writeFileSync (file I/O)
│    └─ src/wasm-parse.js → io/pkg-node WASM  ← DWG parsing (host-side, Rust)
│       ↓  DWG: parseResult JSON injected   ·   DXF: base64 bytes
└─ Guest VM (QuickJS-WASM, sandboxed)
   └─ dist/core.bundle.js
      ├─ CadDocument, HistoryManager, CommandBridge
      ├─ commands/* (LINE, CIRCLE, MOVE, DIM*, ...)
      └─ io/DxfReader, DxfWriter, DwgWriter (pure JS) — no JS DWG reader

No source code escape: Core JS lives inside the WASM-backed VM. CLI binary contains only the bundle and a thin host shim.

Source protection (W-5)

The DWG reverse-engineering algorithm (multi-version read: 2004+ LZ77, 2007+ Reed–Solomon, bitstream decode, handle resolution) is not shipped as plaintext. DWG files are parsed host-side by the compiled Rust WASM parser (io/pkg-node), and only the resulting parseResult (JSON) is injected into the VM. The Core bundle keeps the JS DXF reader (a public, documented format) and the DWG/DXF writers, but carries no JS DWG reader.

Two build-time gates enforce this (npm run build):

  • build/build-core.mjs — an esbuild guard that fails the build if any DWG-reader module (DwgReader, io/internal/{entities,tables,structure,compression,header}, ObjectMap/HandleResolver, BitReader, LcgXorMask/ReedSolomon) is re-imported into the bundle. Writer shared primitives (BitWriter, Crc, EntityCommon) stay allowed.
  • build/guard-bundle.mjs — greps the built bundle for reader symbols and fails if any leak.

Scope (honest boundary): this seals the reader algorithm. R2000 write knowledge remains reconstructible from the bundled DwgWriter until that writer is ported to Rust (roadmap item T-1). Loud-fail: a DWG the Rust parser cannot read surfaces WASM_PARSE_FAILED — there is no silent JS fallback.

Requires the local Rust build io/pkg-node (npm run io:build:node at the repo root) present alongside the package during DWG operations.


License

UNLICENSED — internal use only.