HELIX Docs
CLI & AI toolsCommand reference

helix vehicle

Validate and preview a Universal Vehicle before Package publication

CLI version 0.1.27-helix3.551. Run helix vehicle --help for the text your installed build prints.

helix vehicle

Validate and preview a Universal Vehicle before Package publication

helix vehicle <command>

helix vehicle validate

Validate a vehicle package (and optionally its GLB) against the engine contract, the backend pin rules and the publish budgets. Exit 0 = no errors, 1 = errors, 2 = unreadable input

helix vehicle validate [options] <vehicle-package.json>
ArgumentRequiredDescription
vehicle-package.jsonyesthe vehicle package JSON that will be sealed in the Vehicle Package
OptionDescription
--glb <model.glb>also check the model: wheel nodes and pivots, frame orientation, budgets, articulation nodes, the lamp nodes (one per light function, each with its own emissive material), and the add-on host manifest (asset.extras.HELIX_vehicle)
--no-simulateskip the offline drive (by default a package with targets is driven by the platform's own engine instrument and every figure outside its tolerance is an ERROR)
--cabinwith --glb: also run the offline cabin check (helix vehicle cabin-check): every declared seat's H-point, head, knee, shin, foot, rear footwell and tunnel clearance as the engine runtime fits it; a FAIL is an ERROR
--offlinedrive with the last cached engine runtime; never fetch
--api-url <url>API whose engine runtime drives the car (default: this CLI's environment)
--jsonprint the machine-readable report

helix vehicle preview

Render a vehicle that is not published yet in the real HELIX runtime (headless) and measure it: ride height against groundToBodyOrigin, wheels on their hubs, arch clearance, rolling radius, steering, doors, seats. Run it BEFORE the first mint, which locks groundToBodyOrigin. Every car preview also writes the fixed appearance poses (poses/pose.front|side|rear|top|front34|rear34|cockpit.jpg and poses.jpg) to compare with reference photos, and the GAUNTLET INSPECTION SET as small contact sheets under <out>/inspection/ (8 angles day and night, each lamp lit, every wheel, every panel open, EVERY seat occupied from first person, side glass, over the shoulder and windscreen, the driver steering left/centre/right, and still-hands frames), with blocking occupant asserts (posture, hands on the rim while steering and following it, 9 and 3, still fingers and hands). Read every sheet. --item <id> with no car directory and no --addon inspects a PUBLISHED car as the runtime serves it (re-checking a listed car against the current gates). With --addon <dir> it previews unpublished vehicle ADD-ONS instead: each add-on directory (the layout vehicle addon check|publish reads) is fitted to the candidate car, or to a published car (--item <id>, no car directory) by the engine's own fold, and the DRAWN geometry is measured in world space against its anchor (wheels within 1 cm of each hub, socket-framed parts on their socket, host-framed parts at their authored position, inside the car, not at its origin; a tune-only add-on has its ops read back from the live tuning). Nothing is uploaded or recorded. Exit 0 = every blocking check passed, 1 = a check failed, 2 = could not measure

helix vehicle preview [options] [dir-or-package.json]
ArgumentRequiredDescription
dir-or-package.jsonnoa directory holding vehicle-package.json + model.glb (the Vehicle Package source layout), or the package JSON itself; omit with --addon to fit to a published car (--item)
OptionDescription
--glb <model.glb>the model (default: model.glb, or the one .glb, beside the package)
--addon <dir>an UNPUBLISHED add-on directory (addon.json + model.glb) to fit to the car and measure; repeatable
--item <id>with --addon and no car directory: the published vehicle to fit the add-ons to (default: the proxy item)
--tolerance-cm <cm>with --addon: how far a drawn part may sit from its anchor (default: wheels 1 cm, socket-framed and host-framed parts 3 cm)
--out <dir>frames, contact-sheet.jpg, bundle.json and preview.json go here (default: <dir>/.helix-preview)
--proxy-item <id>a published vehicle the QA account can Try Now; the runtime loads it and the candidate replaces its car (and its slot board is what --addon fits to)
--occupantskept for old scripts: occupants are ON by default (every seat occupied, posture, hands while steering, still fingers, cabin fit)
--no-occupantsskip seating occupants (a quick iteration run only: an inspection without every seat occupied is not a gate result)
--no-inspectionskip the gauntlet inspection set (8 angles day and night, each lamp lit) and its contact sheets (iteration only)
--reference-paint <#rrggbb>the reference body paint colour, the median of the body-paint pixels in the reference photos: renders the body paint alone from six cameras in the Try Now daylight (the world's own sun, exposure, tone mapping and lights) and fails on hue, saturation, lightness or highlight wash. White/silver/grey/black are judged on tint and lightness instead of hue
--paint-tolerance <deg>maximum circular hue distance (degrees) the rendered body may sit from a chromatic --reference-paint (default 12)
--reference-wheel <image>a close-up photo of the real wheel, face-on or nearly: renders the candidate's front-left wheel square-on and fails vehicle.wheels.design.* on spoke count and centre cap (a different finish fails, a neighbouring one warns). The photo's wheel is read from the image centre unless --reference-wheel-crop says where it is
--reference-wheel-spokes <n>declare the real wheel's spoke count (overrides the count read from the photo; use it for an oblique or tight photo)
--reference-wheel-finish <finish>declare the real wheel's finish: silver, chrome, gunmetal, black, bronze, gold or coloured (overrides the finish read from the photo)
--reference-wheel-cap <yes|no>declare whether the real wheel has a centre cap (overrides the photo)
--reference-wheel-crop <cx,cy,r>where the wheel sits in the photo, as fractions: centre x of the width, centre y of the height, tyre outer radius of the shorter side (default 0.5,0.5,0.45)
--storage-state <file>Playwright storageState of a signed-in QA account (default: sign in with helix login, or $HELIX_VQA_STORAGE_STATE)
--chrome <path>Chromium executable (default: Playwright Chromium / Chrome for Testing, headless; the macOS system Chrome is refused)
--api-url <url>platform API base URL
--web-url <url>website base URL (default: the site that serves --api-url)
--jsonprint the machine-readable summary (also written to <out>/preview.json)

helix vehicle recheck-listed

Re-judge LISTED vehicles against today's gates. A listed car is never re-judged when a gate is added, so its visual-QA record can predate the gate that would fail it (the F40 was listed before the posture and hands-while-steering asserts existed). For each car this reads the passing record of its current version and names every current blocking gate it never ran (STALE) or failed (FAIL). With --rerun it renders each car again now (vehicle preview --item: every seat occupied, the full inspection set and its contact sheets) and reports that verdict. Agents updating a car must run this on it. Exit 0 = every car current and (with --rerun) passing, 1 = a car needs action, 2 = could not run

helix vehicle recheck-listed [options] [itemIds...]
ArgumentRequiredDescription
itemIds...novehicle item ids (default: every listed vehicle in the marketplace catalogue, or one creator's with --creator)
OptionDescription
--creator <userId>only this creator's listed vehicles
--rerunrender each car again now with today's gates (several minutes per car, one browser at a time)
--out <dir>with --rerun: where each car's inspection goes (default ./.helix-recheck)
--storage-state <file>Playwright storageState of a signed-in QA account (default: sign in with helix login)
--chrome <path>Chromium executable (headless)
--api-url <url>platform API base URL
--web-url <url>website base URL
--jsonprint the rows as JSON

helix vehicle simulate

Drive a vehicle package offline with the platform's OWN engine instrument (the runtime ^0.3 serves today: Rapier, land solver v2, the code players run) and judge it: 0-100 km/h, 0-60 mph, quarter mile, top speed (converged or not), 100-0 km/h and 60-0 mph braking, skidpad lateral g, turbo lag, gears used and the rest pose. Every figure is compared with the package's own targets (and --spec): error = (simulated - target) / target, PASS iff |error| <= tolerance. The runtime is fetched once per version and cached by sha under ~/.helix/cache/engine-runtime; offline, the last cached runtime is used and labelled. TURBO LAG: with boostTorqueCoef 0 the solver adds no boost torque, so a turbo car whose curve is the full-boost dyno curve pulls with no lag; author lag by derating the torque curve below spool, then check turbo lag here (docs/vehicle-simulate.md). KEYBOARD LAUNCH: it also launches the car the way a keyboard player does (W 0->1 in one tick, A/D taps with 100 ms reactions holding a lane; the platform does not ramp a digital throttle, and a land-v2 car has traction control only if its package authors simulation.land.tractionControl — modelled here exactly as live) and nudges the yaw hands-off at 20/40/60/100 km/h and as each upshift re-engages: keyboard 0-100 vs the instrument, wheelspin per gear, post-shift yaw/heading/sideslip, lane offset. A nudge that grows into a spin FAILS "not drivable on a keyboard". Exit 0 = every compared figure passes and the keyboard launch does not FAIL, 1 = a figure is out of tolerance, the rest pose is wrong or the car is not drivable on a keyboard, 2 = could not simulate

helix vehicle simulate [options] [dir-or-package.json]
ArgumentRequiredDescription
dir-or-package.jsonnoa vehicle package directory (vehicle-package.json), the package JSON, or a saved item read
OptionDescription
--item <id>simulate a PUBLISHED vehicle item's stored package (public read) instead of a local file
--spec <file>extra targets: a package / {targets}, or a reference spec (perf.0_100_kmh_s, perf.braking_100_0_m, perf.braking_70mph_0_m, perf.skidpad_g, perf.turbo_lag_s … as {value, tol_pct})
--offlineuse the last cached engine runtime; never fetch
--runtime <file-or-url>drive with this runtime bundle instead of the served one (a candidate engine build)
--range <range>engine range to resolve (default ^0.3)
--api-url <url>API to resolve the runtime (and --item) from (default: this CLI's environment)
--no-keyboard-launchskip the keyboard launch and its hands-off yaw probe
--jsonprint the machine-readable report

helix vehicle cabin-check

Judge every seat of a car's cabin OFFLINE in seconds (no browser, no sign-in): the engine runtime's own cabin fit plus the canonical seated legs measured against every triangle of the body. Per declared seat, any seat count (2, 2+2, 4, 5, 7): the H-point above the floor, how far the runtime had to move the seat, head clearance to the roof's inner surface, knee clearance to the seat back ahead, shin and foot clearance, the legs against the seat ahead and against the tunnel / console, the rear footwell under the front seats (free height over the foot, depth ahead of the cushion), the driver's legs against the wheel, and any limb inside the body. Each row is PASS / WARN / FAIL with numbers. Iterate with this, then confirm with helix vehicle preview <dir> --occupants (which now boards and seats every seat). The runtime is fetched once per version and cached under ~/.helix/cache/engine-runtime; offline, the last cached runtime is used and labelled. Exit 0 = no FAIL, 1 = a FAIL, 2 = could not run

helix vehicle cabin-check [options] [dir-or-package.json]
ArgumentRequiredDescription
dir-or-package.jsonnoa vehicle package directory (vehicle-package.json + model.glb), or the package JSON beside its model
OptionDescription
--glb <model.glb>the model (default: model.glb, or the one .glb, beside the package)
--item <id>check a PUBLISHED vehicle item's stored package and drawn model (public reads) instead of a local directory
--offlineuse the last cached engine runtime; never fetch
--runtime <file-or-url>use this runtime bundle instead of the served one (a candidate engine build)
--range <range>engine range to resolve (default ^0.3)
--api-url <url>API to resolve the runtime (and --item) from (default: this CLI's environment)
--jsonprint the machine-readable report

helix vehicle audio-check

Prove every sound a vehicle declares will actually play: each engine-ladder rung and slot sample the runtime selects must resolve (a local WAV beside the package before publish, or HTTP 200 with the exact declared bytes and sha256 after), be PCM WAV, and be audible (not silence). It also measures what each sound is made of: clipping, DC offset, a resampled-copy ladder rung, one fixed formant stack or fixed tone shared by every rung, near-duplicate sounds across roles (shift up = shift down, an exhaust rung = an engine rung), a rev-limiter clip too long to stutter (the runtime re-fires it every 60 ms), and an exactly periodic synthetic horn (each reported with its measured value and a fix). Pass a package directory / package JSON for the pre-seal check, or a published vehicle item id for the read-back check. Exit 0 = every sample plays

helix vehicle audio-check [options] <dir|package.json|item-id>
ArgumentRequiredDescription
dir|package.json|item-idyespackage directory or file (pre-seal), or a published vehicle item UUID (read-back)
OptionDescription
--reference <clip>a recording of the REAL car to compare the idle voice with: a WAV (or anything ffmpeg reads) of the engine idling; slot=clip compares that slot instead (e.g. horn=horn.wav, startup=start.wav). Repeat for several clips (the median is used). Spectral centroid and firing roughness are measured identically on both sides; WARN beyond 2.5x, error beyond 10x (field recordings differ by 2-4x between takes of one car) (default [])
--jsonprint the machine-readable report

helix vehicle audio-import

Take a car's sounds from the sim mod that carries them — never synthesised. Reads a BeamNG mod (folder or .zip: its own engine/exhaust sfxBlend2D ladders, every sound its selected parts name — starter, shutdown, afterfire, turbo whine and blow-off, gearbox whine, shift levers, door latches, horn and soundscape, beam sounds — and the recordings it ships), an Assetto Corsa / ACC car (folder or its sfx .bank: the FMOD engine event becomes the rpm ladder, row 0 off-throttle and row 1 on-throttle, exterior preferred; horn, doors, gears, turbo, backfire, limiter, skid, wheel and transmission events become slots) or a bare FMOD .bank. With --beamng-root the BeamNG install's stock FMOD banks resolve every stock event a mod names, and fill what the car does not name with what the game itself plays (tyres, impacts, doors, shift, suspension). Writes <out>/audio/*.wav (16-bit PCM; malformed WAV headers repaired, sample bytes untouched) and <out>/audio.json — the package audio block (bank + all 31 slots) with provenance { kind, sim, mod, modUrl?, sourceFile, sourceSha256, event?, extractor } on every slot, bank sample and blend — plus <out>/audio-import.json. A slot no source provides stays EMPTY with the reason (for a stock event: exactly which). --map merges several sources (one mod's ladder, another mod's horn, an AC car's doors). Exit 1 when a slot or the engine ladder is left without a recording

helix vehicle audio-import [options] <source>
ArgumentRequiredDescription
sourceyesa BeamNG mod folder or .zip, an Assetto Corsa car folder (content/cars/<car>), or an FMOD .bank
OptionDescription
--out <dir>output folder (audio/ + audio.json + audio-import.json) (required)
--sim <sim>beamng | ac | auto (default "auto")
--vehicle <id>the BeamNG vehicle folder (vehicles/<id>) when the mod has several
--config <file.pc>the BeamNG configuration whose selected parts name the sounds (default: the vehicle's default .pc)
--map <slot-map.json>merge sources per slot: { sources: { id: { path, sim: beamng|ac|beamng-base|recording, vehicle?, config?, modUrl? } }, slots: { <slot>: { source?, sample?|field?|event?|file?, blend? (ladders), trim?: { startS, endS }, concat?: [pick, ...], notFitted?|absent: "not-fitted" + reason } }, ladder: { source, blend?, exhaustBlend?, rpm: { sample: rpm }, prefer, nativeRungs }, cylinders, strokes, crankLayout, bankId, modUrl, engineGainDb, exhaustGainDb, minLoadMix, maxLoadMix, muffling } (docs/vehicle-audio-import.md)
--beamng-root <dir>the BeamNG.drive install (its content/art_sound.zip FMOD banks and content/vehicles/common.zip); default $HELIX_BEAMNG_ROOT
--cylinders <n>the RECORDED engine's cylinder count (the ladder pitch model); required for an Assetto Corsa car
--prefer <side>exterior | interior engine recordings (Assetto Corsa engine_ext / engine_int) (default "exterior")
--ac-native-rungskeep only FMOD engine samples the bank places at their recorded pitch (no auto-pitch re-rate)
--mod-url <url>where the mod was downloaded from (recorded in provenance.modUrl)
--base-package <vehicle-package.json>an existing package (file, its directory, or an audio.json) whose audio mix to keep: engineGainDb, exhaustGainDb, minLoadMix, maxLoadMix, muffling (else the mod's soundConfig, else the engine's defaults; --map values win)
--jsonprint the machine-readable result

helix vehicle addon

Check vehicle add-ons (wheels, kits, exhausts, tune parts)

helix vehicle addon <command>

helix vehicle addon check

Prove an add-on will fit and land where it should BEFORE paying for it: the local fits/ops contract, the model's helixMeshFrame anchoring (a socket-frame part centred on its mount), per host — a vehicle, wheel origins at the hubs, hide targets present, hide grants on the board — tunable paths the part requires exposed on the host surface, the backend's own fit dry run (POST /universal-items/validate-fit: how many hosts it actually fits), the web customizer's meshless guard on the exact definition publish would seal (a part with no model.glb must be a verified tune-only/sound-only definition, or the customizer refuses to equip it: ADDON_CUSTOMIZER_REFUSES), and — for tune ops — the DRIVE EFFECT on each host, measured with the live runtime's own physics and add-on fold (0-100, top speed, quarter mile, skidpad g and roll, full- and part-pedal stops, handbrake), each op judged on a figure it can move; an op that changes nothing or cancels another is reported. Directory: addon.json { title, fits, ops, ... } + model.glb (none for a tune-only part: ECU, gearbox, brakes, sway bars, coilovers, tyre compound — every op a tune). Exit 0 = fits every named host and does something. PUBLISHED mode (no directory, public reads, no sign-in): --item <addOnItemId> (repeatable) reads the Item's exact Package pin, the public manifest and, for a meshless part, its root, and runs exactly what the web customizer runs; --host <vehicleItemId> does that for every add-on on the car's rail. Exit 1 = the customizer would refuse a part, with its message

helix vehicle addon check [options] [dir]
ArgumentRequiredDescription
dirnothe add-on directory (omit with --item / --host)
OptionDescription
--glb <file>the add-on model, when the directory holds more than one .glb
--no-measureskip the drive-effect measurement (it downloads the live runtime and runs its physics, ~1-5 s per host)
--item <id>PUBLISHED mode: an add-on Item id to check the way the web customizer reads it (repeatable) (default [])
--host <id>PUBLISHED mode: a vehicle Item id; checks every add-on on its rail (repeatable) (default [])
--api-url <url>platform API base URL for --item / --host (default "https://api.helixgame.com")
--jsonprint the machine-readable report

helix vehicle addon publish

Publish a vehicle add-on directory: the full vehicle addon check (drive effect measured), upload the model, seal a public addon Package (root: the helix.vehicle-addon-definition/1 JSON; a tune-only part seals no model), make the add-on Item from that exact Version, and read it back: pinned, the backend fit lists every host, every host's add-on rail lists it. No offer is opened. A CHANGED part is a new Version of the SAME Item: --package-version <semver> with --item <id> (or in the directory that first published it) seals a staged Version and moves the Item to it (the visual check is advisory and never gates the move; re-run the same command to retry one the server refused); sealing a version name that already holds different bytes is refused. --dry-run also runs the seal-side validation (provenance.source <= 256 chars, contentRating, Package shape, version clash). Resumable from <dir>/.helix-publish/ledger.json. Exit 0 = published and verified, 1 = a check or read-back failed, 2 = could not run

helix vehicle addon publish [options] <dir>
ArgumentRequiredDescription
diryesthe add-on directory (addon.json + model.glb; no model for a tune-only part)
OptionDescription
--glb <file>the add-on model, when the directory holds more than one .glb
--content-rating <rating>creator-attested rating: everyone, teen, mature or adult (or addon.json contentRating)
--package-version <semver>the Package Version to seal (default addon.json version, else 1.0.0); with --item, the NEW version of that part (the CLI's own --version flag is taken, so this one is spelled like vehicle publish and item set-version)
--item <id>publish a NEW VERSION of this existing add-on Item instead of minting one (needs --package-version)
--reason <text>with --item: the version move reason (1-500 chars, audited; default names the version)
--out <dir>ledger, definition, descriptor and receipts (default <dir>/.helix-publish)
--no-measureskip the drive-effect measurement
--dry-runrun the check and the seal-side validation only; nothing is uploaded
--jsonprint the machine-readable result

helix vehicle publish

Publish a vehicle package directory: validate (package, GLB, host manifest, audio), upload the model and samples, seal a public Vehicle Package whose root pins them, make the vehicle Item from that exact Version, and read it back (pin, package identity, mesh pin, every audio URL, and the host board: hostKind vehicle, sockets, tunable paths). Resumable from <dir>/.helix-publish/ledger.json. With --item: seal a STAGED new Version of that car and move it (the visual check is advisory and never gates the move). Directory: vehicle-package.json + model.glb (asset.extras.HELIX_vehicle with sockets) + WAVs; optional publish.json { title, description, tags, version, contentRating, provenance, hostGrantExtensions }. Exit 0 = published and verified, 1 = a check or read-back failed, 2 = could not run

helix vehicle publish [options] <dir>
ArgumentRequiredDescription
diryesthe vehicle package directory
OptionDescription
--glb <file>the drawn model, when the directory holds more than one .glb
--title <title>Item and Package title (default: publish.json title, else the package displayName)
--description <text>Item description
--tags <a,b,c>Item tags
--content-rating <rating>creator-attested rating for a new Item: everyone, teen, mature or adult (or publish.json contentRating)
--package-version <semver>the Package Version to seal (default 1.0.0; required with --item)
--item <id>publish a NEW VERSION of this existing vehicle Item instead of minting one
--reason <text>with --item: the version move reason (1-500 chars, audited)
--out <dir>ledger, sealed root, descriptor and receipts (default <dir>/.helix-publish)
--no-simulateskip the drive (by default a package with targets is driven by the platform's engine instrument, exactly as vehicle validate, and every figure outside its tolerance refuses the publish)
--offlinedrive with the last cached engine runtime; never fetch
--dry-runvalidate, check audio and run the seal-side validation (provenance.source <= 256 chars, contentRating, Package shape, title/tag limits); nothing is uploaded
--jsonprint the machine-readable result

helix vehicle pull

Rebuild a publishable COPY of a live vehicle: read the Item's sealed Vehicle Package Version and write vehicle-package.json (the exact sealed root), audio/<file> for every sound it pins, model.glb plus model-<renditionId>.glb for every served mesh rendition, a publish.json carrying the Item fields (the legacy "general" rating is written as "everyone"; a rating that is not one of everyone|teen|mature|adult needs --content-rating) and a pull.json recording where each byte came from. Nothing is uploaded and no ledger is written, so the copy mints a NEW Item instead of resuming against the live one: pull into a new directory, then helix vehicle publish <dir>. Exit 0 = pulled, 1 = nothing written, 2 = could not run

helix vehicle pull [options] <item-id> <dir>
ArgumentRequiredDescription
item-idyesthe published vehicle Item to copy
diryesa NEW directory to write the copy into (must not exist, or be empty)
OptionDescription
--package-version <semver>pull this Version instead of the Item's current pin (a car's history is copyable too)
--content-rating <rating>the rating to write for the COPY: everyone, teen, mature or adult (default: the Item's own, mapped)
--jsonprint the machine-readable result

On this page