@illumify/cli
v0.6.3
Published
Scaffold, preview, build and deploy Illumify vibe-coded pages
Readme
illumify
The CLI for Illumify vibe-coded pages: scaffold a project, link it to a storefront site, preview it against a real environment, build it, upload it.
illumify new my-shop --env <env> --api-host <url> [--website <slug> --company <id>]
illumify link --slug <site-slug> --company <id>
illumify dev
illumify build
illumify screenshot
illumify upload
illumify skills get app | data | deployA project produces an immutable theme, named by a hash of its own content, and uploads it for a
storefront site that already exists in the ERP. The CLI never creates a site and never chooses a slug, so
a project scaffolded without --website cannot upload until illumify link records which one — the
command says so when it finishes. The first upload also records its --display-name in that
environment's illumify.link.json entry. Later uploads reuse it unless a new flag or a file edit
chooses another logical theme.
Uploading is not publishing, and no command here can publish. An upload writes immutable content; which theme a site serves is an assignment an administrator moves in the ERP, and nothing here moves one.
It can still change a live site, and both sentences matter. A theme is a name holding immutable
revisions, and an assignment points at the theme with an optional revision pin. Unpinned — the default —
it serves the newest revision on every request, so uploading into a theme a site already serves is
visible to shoppers at once. illumify upload says which of the two happened, every time; read that
line rather than assuming either answer. It also opens a ten-minute hosted preview, which is the safe
version of "let me see it" when the theme is not assigned anywhere yet.
Installing it
The npm release contains a small root launcher and exactly one optional, platform-filtered binary
package. On macOS, Linux and Windows, npm installs the matching package and npx illumify resolves it
without a download hook:
npx illumify --versionLinux packages target glibc (gnu). npm cannot distinguish libc, so an Alpine/musl x64 install may
receive the linux-x64 package; starting it fails with an explicit glibc; Alpine/musl is unsupported
hint. Use a glibc-compatible runtime or a checkout build. There is deliberately no postinstall download
fallback.
The release workflow is manually triggered and dry-runs by default. It publishes all five platform
packages before both root names (illumify and @illumify/cli), so neither launcher is published
while its optional dependencies are missing. Publishing is intentionally not performed from this checkout.
Live skills
The CLI carries scaffold templates, while skills get fetches its instructions live from
ToneMeUp/cli-skills. That repository is the sole content gate for those instructions: tag it at a
breaking change when older binaries must stay aligned, and use main for deliberate edits that should
reach customers immediately.
The version is stored once, in Cargo.toml
A release is a one-line bump:
npm run set-version 0.4.4Cargo.toml is the only file that holds the number, because the binary already takes its version
from there and nothing can change that — env!("CARGO_PKG_VERSION") is compiled in, so if any other
copy disagreed, the value illumify --version prints would still be Cargo's. Making it the source
removes the disagreement rather than ranking it.
Everything else is derived from it by bin/sync-version.js: Cargo.lock's own entry, package.json's
version, and the five optionalDependencies pins. CI then generates each platform manifest from the
root version, so the platform packages are never a copy either.
npm cannot read a version from anywhere but package.json, so that one literal has to exist. It is
generated and asserted rather than maintained — cargo test fails if it drifts from Cargo.toml
(distribution::tests::the_npm_manifest_is_derived_from_the_crate_version), and the release workflow
runs npm run check-version on its first job, before the build matrix spends a macOS runner. Run
npm run sync-version after editing Cargo.toml by hand.
npm version is not the bump and refuses: it writes package.json first, which would make the
generated file the one a person edits and leave npm tagging a number no file agrees with. It restores
package.json and points at set-version instead.
Installing from a checkout
The CLI is published, but this checkout can still be linked onto PATH for development:
cargo build --release
npm link
illumify --versioncargo build --release is enough after that — do not relink
The shim npm link installs resolves target/release/illumify, not target/debug. So a rebuild
picks up your change and no relink is needed — but only if you built the profile it actually reads.
This is worth stating because the natural assumption is the opposite, and getting it wrong is
expensive in a specific way: cargo build alone leaves target/release holding an older binary, so
illumify on PATH keeps running the old one. A flag you just added looks absent, and nothing tells
you that you are measuring a stale build. That cost two rounds of reporting a feature as missing
before anyone noticed which binary was running.
illumify --version prints the version and the path of the binary answering, for exactly this
reason. When something you just changed appears not to exist, read that line first.
The lookup order is in bin/illumify.js: ILLUMIFY_BINARY overrides everything, then a per-platform
package, then target/release and target/debug beside the checkout, then the binaries/ copy that
prepack stages into a tarball.
Development
cargo test # everything, including the guards described below
cargo clippy --all-targets
cargo fmtillumify dev --fixtures facilities serves three known-customer cart destinations over one fully
priced, facility-neutral catalogue. The in-process cart and checkout enforce the runtime write guard
and support compound destination lines, shared stock, repricing, checkout, and finalization scenarios
without a link, credential, or network.
Some tests shell out to node — the ones that evaluate a scaffolded illumify.config.ts through the
real loader — and skip themselves when it is absent.
Guards worth knowing about before you edit
Several tests exist to stop a specific failure that has already happened once. They will look over-specified until you know which:
| Guard | Stops |
| --- | --- |
| scaffold::the_default_template_decides_nothing_about_what_to_build | The scaffold acquiring pages again, which turns our guess into the customer's requirement |
| scaffold::the_reference_document_is_short_and_briefs_nobody | AGENTS.md growing past a word budget, or telling an agent what to build |
| scaffold::the_scaffold_puts_the_instructions_where_an_agent_looks | CLAUDE.md gaining content of its own instead of importing AGENTS.md, and the removed singular AGENT.md being restored as a fix |
| scaffold::no_scaffolded_file_names_an_environment_or_a_host | Shipping a scaffold that silently reads a live environment nobody chose |
| scaffold::no_scaffolded_file_offers_a_place_to_put_a_credential | An empty KEY= line inviting an agent to fill it |
| shipped::nothing_we_ship_carries_another_customers_data | Real slugs, hosts and ids reaching documentation and templates |
| sdk::refuses_a_tarball_carrying_our_internal_documents | Our internal briefs reaching a customer's node_modules — which happened |
| distribution::every_flag_the_onboarding_command_passes_is_one_illumify_new_accepts | A flag rename breaking the command the panel hardcodes |
| onboarding::the_review_copy_in_the_repositorys_document_matches_what_we_print | ONBOARDING-STARTER-PROMPT.md drifting from the real prompt |
| skills::no_skill_carries_a_symbol_from_the_retired_platform | A retired symbol — window.__ILLUMIFY__, cart.addItem, context.basePath — surviving in text a customer's agent implements from |
| skills::the_data_skill_states_the_constraints_that_decide_designs | The CSP, the absent product images, the indistinguishable 404 and the available OR going unstated, each of which decides a design |
| onboarding::the_retired_access_mode_vocabulary_is_gone_from_both_forms | The storefront access mode coming back into the starter prompt or the panel's --json payload |
package.json's files list is a whitelist for the same reason: this repository's root holds
internal documents, and only bin/illumify.js and this README are meant to leave it. Platform binaries
leave through their separately generated optional packages.
Where the decisions are written down
AGENTS.md in this repository is the brief for working on the CLI itself. It points at the decision
map, which is the source of truth and is not to be reopened.
