CLI
The dh command-line tool compiles, validates, and watches your pallets. For workspace configuration, see Workspace.
Commands
Section titled “Commands”| Command | Description |
|---|---|
dh | Launch interactive mode (default if no command given) |
dh interactive | Launch interactive mode (explicit) |
dh build | Compile all pallets |
dh watch | Watch for changes and auto-compile |
dh validate | Validate pallets without writing output |
dh clean | Clear the .dh/ cache directory |
dh init | Initialize a new workspace |
dh info <file> | Show metadata from a compiled .pallet file |
dh help | Show available commands |
Interactive Mode
Section titled “Interactive Mode”Running dh with no arguments (or dh interactive) launches an interactive menu where you can choose what to do: build, watch, validate, clean, and more. This is the recommended way to use the CLI for day-to-day work.
| Flag | Short | Works with | Description |
|---|---|---|---|
--verbose | -v | build, watch, validate, clean | Show detailed output (Blender logs, file-level progress) |
--clean | -c | build, watch | Clear cache before building |
--plain | all commands | Force non-interactive, plain-text output (no prompts, no ANSI/colors/spinners) |
Example:
dh build --verbose --cleanNon-Interactive Use (CI / agents)
Section titled “Non-Interactive Use (CI / agents)”dh is safe to run unattended — from a script, CI pipeline, or an automation agent — with no terminal attached.
Detection: the CLI automatically treats a run as non-interactive when stdin or stdout is redirected/piped, or when the terminal itself reports no interactive capability. You can also force this mode explicitly with --plain, regardless of how stdio is connected.
Behavior in non-interactive mode:
-
No prompts, ever. Any code path that would normally prompt (e.g. asking for a Blender path) instead fails fast with a plain-text error naming the missing config key and how to fix it, then exits non-zero. For example, if
blenderPathis missing fromdh-config.jsonc:Error: blenderPath is not set. Add "blenderPath": "C:\path\to\blender.exe" to dh-config.jsonc. -
No live/ANSI rendering. Colors, spinners, and other interactive rendering are suppressed; output is informative plain text.
-
dh watchskips its interactive keypress controls (Space/Enter/R/C/Q) and simply runs until interrupted withCtrl+C. -
Exit codes are consistent everywhere:
0on success, non-zero on any failure (validation errors, missing config, exceptions).
Watch Mode
Section titled “Watch Mode”dh watch monitors your Source/ directory and recompiles when files change.
Debounce: waits for changes to settle before compiling (default: 1000ms, configurable via watchDebounceMs).
Manual controls:
| Key | Action |
|---|---|
Space, Enter, R, C | Trigger manual compile |
Q, Ctrl+C | Exit watch mode |
Inspecting Pallets
Section titled “Inspecting Pallets”dh info displays metadata embedded in compiled .pallet files:
dh info Pallets/io.mltn.avatars.mltn-mayu.palletOutput:
io.mltn.avatars.mltn-mayu.pallet╭──────────────────┬─────────────────────────────────────╮│ Property │ Value │├──────────────────┼─────────────────────────────────────┤│ ID │ io.mltn.avatars.mltn-mayu ││ Name │ mltn Mayu ││ Version │ 0.0.1 ││ Author │ mltn ││ Built │ 2026-02-05 10:30:00 -08:00 ││ DH Version │ 0.1.0 ││ Files │ 42 ││ Size │ 2.4 MB ││ Uncompressed │ 3.1 MB ││ Dependencies │ tech.azuki.avatars.mayu ^3.0.0 ││ Tags │ avatar, character │╰──────────────────┴─────────────────────────────────────╯If no file is specified, dh info shows info for all pallets in the build directory.
Build Output
Section titled “Build Output”Success
Section titled “Success”Building io.mltn.avatars.mltn-mayu... ✓ Parsing definitions ✓ Validating references ✓ Processing textures ✓ Converting models ✓ Bundling assets ✓ Writing output
Build succeeded in 1.2sFailure
Section titled “Failure”Building io.mltn.avatars.mltn-mayu... ✓ Parsing definitions ✗ Validating references
Error in io.mltn.avatars.mltn-mayu/avatar.dh-avatar:12:5 Missing required property 'name' in material definition
10 | "materials": { 11 | "body": { > 12 | "diffuseTexture": "textures/body.png" | ^ 13 | } 14 | }
Build failed with 1 errorBuild Pipeline
Section titled “Build Pipeline”What dh build does under the hood:
- Parse — Read all JSONC/
.dh-*definition files - Validate — Check schemas, references, types, inheritance chains
- Process textures — Channel packing, extraction, and resize from
dh.texturedefinitions and@channelreferences - Convert models — FBX → GLB via Blender (cached by content hash)
- Bundle — LZ4-compress assets into the output pallet
- Output — Write compiled
.palletfile toPallets/