{"_id":"@botfather/units-tools","_rev":"4-d758a2a6568f12430f0b565f03e3233f","name":"@botfather/units-tools","dist-tags":{"latest":"2.0.2"},"versions":{"1.0.0":{"name":"@botfather/units-tools","version":"1.0.0","license":"MIT","_id":"@botfather/units-tools@1.0.0","maintainers":[{"name":"botfather","email":"mohan.tushar.11@gmail.com"}],"homepage":"https://github.com/Botfather/units/tree/main/packages/units-tools","bugs":{"url":"https://github.com/Botfather/units/issues"},"bin":{"lint-ui":"lint-ui.mjs","format-ui":"format-ui.mjs","units-emit":"units-emit.mjs","units-lint":"units-lint.mjs","units-watch":"units-watch.mjs","units-format":"units-format.mjs","units-manifest":"units-manifest.mjs"},"dist":{"shasum":"b12c95510e60dd887970e76cb54d69837835af71","tarball":"https://registry.npmjs.org/@botfather/units-tools/-/units-tools-1.0.0.tgz","fileCount":9,"integrity":"sha512-HC/ZJZW6vQ4sVrbzFO8yZdX3iY5H2m6VpXzYLekqWbN227NoSfZ4Q/Je9zMuWJCFi8OMjApMtuiDVGBE2Wp7zg==","signatures":[{"sig":"MEUCIDi4p0H8rQHCC6UEj2Oq+acfd1AwM+1+RJ2a6TJ81MCxAiEA9EzzJLx1ubNkmmbshRbi6mkQ21fgEMomI6uyP7xqgkU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@botfather%2funits-tools@1.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":12321},"type":"module","_from":"file:botfather-units-tools-1.0.0.tgz","_npmUser":{"name":"botfather","email":"mohan.tushar.11@gmail.com"},"_resolved":"/tmp/602b941e88bfe4318e3f0242165fb906/botfather-units-tools-1.0.0.tgz","_integrity":"sha512-HC/ZJZW6vQ4sVrbzFO8yZdX3iY5H2m6VpXzYLekqWbN227NoSfZ4Q/Je9zMuWJCFi8OMjApMtuiDVGBE2Wp7zg==","repository":{"url":"git+https://github.com/Botfather/units.git","type":"git","directory":"packages/units-tools"},"_npmVersion":"10.8.2","description":"CLI tools for Units (.ui) formatting, linting, manifests, and watch.","directories":{},"_nodeVersion":"20.20.0","dependencies":{"@botfather/units":"1.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/units-tools_1.0.0_1772457774702_0.6374992287755337","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@botfather/units-tools","version":"2.0.0","license":"MIT","_id":"@botfather/units-tools@2.0.0","maintainers":[{"name":"botfather","email":"mohan.tushar.11@gmail.com"}],"homepage":"https://github.com/Botfather/units/tree/main/packages/units-tools","bugs":{"url":"https://github.com/Botfather/units/issues"},"bin":{"lint-ui":"lint-ui.mjs","format-ui":"format-ui.mjs","units-emit":"units-emit.mjs","units-lint":"units-lint.mjs","units-watch":"units-watch.mjs","units-format":"units-format.mjs","units-manifest":"units-manifest.mjs"},"dist":{"shasum":"2cda63fd95cbfe09f61acd8ec0257381c70fd158","tarball":"https://registry.npmjs.org/@botfather/units-tools/-/units-tools-2.0.0.tgz","fileCount":9,"integrity":"sha512-moLCjxE1OAVLGFFfe3GMcO3Sot4iThk1tCBT6yRw5Yegz3AnbGuPpkogKtj9p6u8MsG10IQKhKugeA5jYgVUrg==","signatures":[{"sig":"MEYCIQD81kN/Kn1LMRthww6ZEIfy9UrXn4Z9cH6DPnXMDRdVtAIhAJvVa8OUniN+97sJiAcnuQakTZDGQz6x0DIkkv7zLOuh","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@botfather%2funits-tools@2.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":12321},"type":"module","_from":"file:botfather-units-tools-2.0.0.tgz","_npmUser":{"name":"botfather","email":"mohan.tushar.11@gmail.com"},"_resolved":"/tmp/cec1713970f847b07bb84c2a815b900e/botfather-units-tools-2.0.0.tgz","_integrity":"sha512-moLCjxE1OAVLGFFfe3GMcO3Sot4iThk1tCBT6yRw5Yegz3AnbGuPpkogKtj9p6u8MsG10IQKhKugeA5jYgVUrg==","repository":{"url":"git+https://github.com/Botfather/units.git","type":"git","directory":"packages/units-tools"},"_npmVersion":"10.8.2","description":"CLI tools for Units (.ui) formatting, linting, manifests, and watch.","directories":{},"_nodeVersion":"20.20.0","dependencies":{"@botfather/units":"2.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/units-tools_2.0.0_1772462415041_0.425577964086427","host":"s3://npm-registry-packages-npm-production"}},"2.0.1":{"name":"@botfather/units-tools","version":"2.0.1","license":"MIT","_id":"@botfather/units-tools@2.0.1","maintainers":[{"name":"botfather","email":"mohan.tushar.11@gmail.com"}],"homepage":"https://github.com/Botfather/units/tree/main/packages/units-tools","bugs":{"url":"https://github.com/Botfather/units/issues"},"bin":{"lint-ui":"lint-ui.mjs","format-ui":"format-ui.mjs","units-emit":"units-emit.mjs","units-lint":"units-lint.mjs","units-watch":"units-watch.mjs","units-format":"units-format.mjs","units-verify":"units-verify.mjs","units-library":"units-library.mjs","units-manifest":"units-manifest.mjs","units-snapshot":"units-snapshot.mjs","units-transform":"units-transform.mjs","units-synthesize":"units-synthesize.mjs"},"dist":{"shasum":"b4cacf216c00bcdc4f88eb9970ee7d1af916cc27","tarball":"https://registry.npmjs.org/@botfather/units-tools/-/units-tools-2.0.1.tgz","fileCount":16,"integrity":"sha512-SBV96x1/dsHSAQmofhbuiwX/+EgAwlILQxqP5oQhE8leyNp97oUN4vEKEVrM2HDtHnbc3MU2zJ4+yX8EF54ujg==","signatures":[{"sig":"MEUCIQD+L3YQFM2OZSJvSq2BonCtbqXd+kdXQ3wJ7daT4TTqsgIgY3H5HFWqO6PqwimHTmlDaPn1TjhnIf1FQNblaSKlx9g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@botfather%2funits-tools@2.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":47957},"type":"module","_from":"file:botfather-units-tools-2.0.1.tgz","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4f853a51-0836-445a-89ae-a73523b93040"}},"_resolved":"/tmp/d2d489550c835bee7f1eb0845801cce7/botfather-units-tools-2.0.1.tgz","_integrity":"sha512-SBV96x1/dsHSAQmofhbuiwX/+EgAwlILQxqP5oQhE8leyNp97oUN4vEKEVrM2HDtHnbc3MU2zJ4+yX8EF54ujg==","repository":{"url":"git+https://github.com/Botfather/units.git","type":"git","directory":"packages/units-tools"},"_npmVersion":"11.17.0","description":"CLI tools for Units (.ui) formatting, linting, manifests, and watch.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"@botfather/units":"2.0.0","@botfather/units-ui-ir":"0.1.1","@botfather/units-dom-snapshot":"0.1.0","@botfather/units-react-adapter":"0.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/units-tools_2.0.1_1782204408315_0.3594094134461765","host":"s3://npm-registry-packages-npm-production"}},"2.0.2":{"name":"@botfather/units-tools","version":"2.0.2","description":"CLI tools for Units (.ui) formatting, linting, manifests, and watch.","license":"MIT","type":"module","repository":{"type":"git","url":"git+https://github.com/Botfather/units.git","directory":"packages/units-tools"},"homepage":"https://github.com/Botfather/units/tree/main/packages/units-tools","bugs":{"url":"https://github.com/Botfather/units/issues"},"bin":{"units-format":"units-format.mjs","units-lint":"units-lint.mjs","units-emit":"units-emit.mjs","units-manifest":"units-manifest.mjs","units-watch":"units-watch.mjs","units-snapshot":"units-snapshot.mjs","units-transform":"units-transform.mjs","units-verify":"units-verify.mjs","units-synthesize":"units-synthesize.mjs","units-library":"units-library.mjs","format-ui":"format-ui.mjs","lint-ui":"lint-ui.mjs"},"dependencies":{"@botfather/units":"2.0.1","@botfather/units-dom-snapshot":"0.1.0","@botfather/units-react-adapter":"0.1.1","@botfather/units-ui-ir":"0.1.1"},"publishConfig":{"access":"public"},"_id":"@botfather/units-tools@2.0.2","_integrity":"sha512-ktfTcR0TcYOqI6RYfVuddsAkZE0ZBFyE+pOMJ0GMxhAlPXKkJ9nB+7V6XIMTt4JU7GhvwWWrgmjmv+NcmPXbRg==","_resolved":"/tmp/d5a4840b79413103bf9e888ad58e609d/botfather-units-tools-2.0.2.tgz","_from":"file:botfather-units-tools-2.0.2.tgz","_nodeVersion":"24.16.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-ktfTcR0TcYOqI6RYfVuddsAkZE0ZBFyE+pOMJ0GMxhAlPXKkJ9nB+7V6XIMTt4JU7GhvwWWrgmjmv+NcmPXbRg==","shasum":"ba5b5c5f72a2b84a99dbc233de8a0b3891bb322c","tarball":"https://registry.npmjs.org/@botfather/units-tools/-/units-tools-2.0.2.tgz","fileCount":16,"unpackedSize":47957,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@botfather%2funits-tools@2.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEOtFj6i/TCQPcSCT+8eBFl5CqgPX3YbSvDioDfRra8bAiEAhvUEVGqOemYEHSFKC/39TgdhMDsIO2oQq73tKFtSx1I="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4f853a51-0836-445a-89ae-a73523b93040"}},"directories":{},"maintainers":[{"name":"botfather","email":"mohan.tushar.11@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/units-tools_2.0.2_1782219357235_0.6982535142718798"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-02T13:22:54.638Z","modified":"2026-06-23T12:55:57.664Z","1.0.0":"2026-03-02T13:22:54.831Z","2.0.0":"2026-03-02T14:40:15.186Z","2.0.1":"2026-06-23T08:46:48.456Z","2.0.2":"2026-06-23T12:55:57.368Z"},"bugs":{"url":"https://github.com/Botfather/units/issues"},"license":"MIT","homepage":"https://github.com/Botfather/units/tree/main/packages/units-tools","repository":{"type":"git","url":"git+https://github.com/Botfather/units.git","directory":"packages/units-tools"},"description":"CLI tools for Units (.ui) formatting, linting, manifests, and watch.","maintainers":[{"name":"botfather","email":"mohan.tushar.11@gmail.com"}],"readme":"# @botfather/units-tools\n\nCLI toolchain for working with Units `.ui` files. Covers the full developer workflow: format, lint, emit parse caches, generate manifest files for static imports, and watch a directory for changes.\n\n## What is it?\n\n`units-tools` provides a set of command-line tools that fit into your build pipeline alongside the Vite plugins. Use them to keep `.ui` files consistently formatted, catch syntax errors in CI, pre-build AST sidecars for faster Vite dev starts, and generate type-safe manifest files that collect all `.ui` files in a directory tree.\n\n## Installation\n\n```sh\nnpm install --save-dev @botfather/units-tools\n```\n\nAll binaries are available after installation. They automatically skip `node_modules`, `.git`, `dist`, `build`, `.vite`, and similar output directories.\n\n## Commands\n\n### `units-format` — Format `.ui` files\n\nReads each `.ui` file, runs the canonical formatter, and writes back only the files that changed.\n\n```sh\n# Format a single file\nunits-format src/components/Button.ui\n\n# Format all .ui files under a directory (recursive)\nunits-format src/\n```\n\nOutputs a count of changed files. Use in a pre-commit hook to keep diffs clean.\n\n> `format-ui` is an alias for `units-format` with identical behavior.\n\n---\n\n### `units-lint` — Check formatting in CI\n\nChecks that every `.ui` file is already canonically formatted. Exits non-zero if any file is not formatted, making it safe to use in CI pipelines.\n\n```sh\n# Lint specific paths\nunits-lint src/\n\n# Alias with no args: defaults to linting examples/ and packages/units-uikit-shadcn/\nlint-ui\n```\n\n> `lint-ui` is an alias wrapper around `units-lint`.\n> `lint-ui` defaults to `examples/` and `packages/units-uikit-shadcn/` when no args are provided.\n> `units-lint` itself requires one or more file/dir args.\n\n---\n\n### `units-emit` — Pre-build AST sidecar files\n\nParses each `.ui` file and writes a `<file>.ui.ast.json` sidecar next to it. These sidecars are used by `vite-plugin-units` as a parse cache (loaded when the sidecar is newer than the source file), speeding up Vite's cold start.\n\n```sh\nunits-emit src/\nunits-emit src/components/Button.ui\n```\n\nRun this as part of your build step or pre-dev script:\n\n```json\n{\n  \"scripts\": {\n    \"prebuild\": \"units-emit src/\",\n    \"predev\": \"units-emit src/\"\n  }\n}\n```\n\n---\n\n### `units-manifest` — Generate a static import manifest\n\nRecursively collects all `.ui` files under `rootDir` and generates a JavaScript file that imports every one and exports them as a named map. Component names are derived from filenames (without extension).\n\n```sh\nunits-manifest <rootDir> <outFile>\n\n# Example\nunits-manifest src/components src/components/manifest.js\n```\n\nGenerated output:\n\n```js\nimport Ast_0 from \"./Button.ui\";\nimport Ast_1 from \"./Card.ui\";\nimport Ast_2 from \"./Dialog.ui\";\n\nexport const uiManifest = {\n  \"Button\": Ast_0,\n  \"Card\": Ast_1,\n  \"Dialog\": Ast_2,\n};\n```\n\nImport `uiManifest` anywhere in your app to get a `Record<string, AST>` of all compiled components.\n\n---\n\n### `units-watch` — Watch and rebuild on changes\n\nWatches `rootDir` recursively. On any `.ui` file change, debounces 200 ms and re-runs `units-manifest` then `units-emit`. Handles `SIGINT` cleanly.\n\n```sh\nunits-watch <rootDir> <outFile>\n\n# Example\nunits-watch src/components src/components/manifest.js\n```\n\nUse this during development instead of relying solely on Vite's HMR when you need the manifest and sidecar files to stay up to date outside of Vite.\n\n---\n\n### `units-snapshot` — Capture a neutral UI tree from any web page\n\nRuns a Playwright browser session, snapshots the DOM into a neutral `UiNode` tree, and prints/writes JSON for downstream transform middleware.\n\n```sh\nunits-snapshot --url https://example.com --out snapshot.json\n```\n\nUseful options:\n- `--browser chromium|firefox|webkit`\n- `--root-selector body`\n- `--wait-until domcontentloaded`\n- `--max-depth 40`\n- `--prune-invisible true|false`\n- `--prune-offscreen true|false`\n- `--prune-layout-wrappers true|false`\n- `--include-style-summary true|false`\n- `--playwright-module playwright`\n\n---\n\n### `units-transform` — Execute a transform program on a host tree\n\nRuns a Units transform program (`Program (kind:'transform')`) against an input tree and outputs transformed IR + trace.\n\n```sh\nunits-transform --program transforms/dom-default.ui --input fixtures/dom-tree.json --source dom --out result.json\n```\n\nOptional outputs:\n- `--trace-out trace.json`\n- `--agent-out compact-agent-tree.json`\n- `--source` supports `dom`, `a11y`, `react`, `slack`, and `ir` (React input is normalized through `UiNode` IR first)\n- Output payload includes both `source_type` and `normalized_source_type` (for `react`, normalized source is `ir`; Slack aliases `block-kit`, `blockkit`, and `mrkdwn` normalize to `slack`)\n\n---\n\n### `units-verify` — Score + gate a transform output\n\nVerify either:\n- Program execution (`--program` + `--input`)\n- Existing before/after trees (`--before` + `--after`)\n\n```sh\nunits-verify --program transforms/dom-default.ui --input fixtures/dom-tree.json --source dom --out verify.json\n```\n\nCustom gates:\n- `--gate-action-recall`\n- `--gate-name-recall`\n- `--gate-text-f1`\n- `--source` supports `dom`, `a11y`, `react`, `slack`, and `ir`\n- Output payload includes both `source_type` and `normalized_source_type`\n\n---\n\n### `units-synthesize` — Iterative candidate refinement\n\nRuns synthesis rounds over a dataset, evaluates candidates with deterministic reward + gates, and optionally writes promoted programs into a verified library.\n\n```sh\nunits-synthesize --dataset bench/transform-dataset.json --seed-dir transforms/seed --rounds 2 --candidates 4 --library-dir .units/library --out synth.json\n```\n\nOptional model-assisted candidate generation:\n- `--model gpt-4.1-mini` (requires `OPENAI_API_KEY`)\n- `--candidate-file candidates.json`\n\n---\n\n### `units-library` — Inspect, promote, rollback verified programs\n\n```sh\nunits-library inspect --dir .units/library\nunits-library promote --dir .units/library --program transforms/dom-default.ui --scores verify.json\nunits-library rollback --dir .units/library --program-id dom-abc123def456\n```\n\n## Recommended workflow\n\n```sh\n# 1. Validate & normalize during development\nunits-format src/\n\n# 2. Pre-build caches for faster dev server startup\nunits-emit src/\n\n# 3. Generate the manifest for static imports\nunits-manifest src/components src/components/manifest.js\n\n# 4. Watch for changes (long-running dev process)\nunits-watch src/components src/components/manifest.js\n\n# 5. CI: fail if any file is not formatted\nunits-lint src/\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}