Maturity: Draft. How the WolvenKit command-line tool behaves as XF Studio runs it: what a release contains, what it needs to start, how it reports success and failure, and what uncook writes. Observed with the official 8.17.4 and 9.0.1 console releases on Windows 11 with game 2.31. The WolvenKit GUI, the Blender add-on and conversion round trips are not covered yet (WolvenKit 9 round trip holds the round-trip evidence).
Releases and identity
| Question | Answer | Grade and evidence |
|---|---|---|
| Which asset is the CLI? | WolvenKit.Console-<version>.zip on the GitHub release. GitHub publishes a SHA-256 digest per asset from 8.17.0 onwards (none for 8.16.1 and older). | resource release API, 25 Sep 2026 |
| What is inside? | A flat folder: WolvenKit.CLI.exe (a .NET apphost, 165,888 bytes in 9.0.1), WolvenKit.CLI.dll (the managed entry point), WolvenKit.CLI.runtimeconfig.json, about 90 dependency DLLs, lib/ (texconv, DirectXTex), opus-tools/, Resources/. 9.0.1: 99 files, 93,614,085 bytes; stored or deflated entries only, no ZIP64. | resource 9.0.1 archive, pinned in wolvenkit-release.ts |
| How is the version read without running it? | The PE version resource of WolvenKit.CLI.exe and .dll (9.0.1.0, 8.17.4.0); --version prints 9.0.1 in about 0.1 s. | resource wolvenkit-cli.ts wolvenKitIdentity |
| Which commands does it offer? | archive, extract/unbundle, uncook (extract-and-export), import, export, pack, build, convert, conflicts, hash, oodle, settings, wwise, cr2w; identical lists in 8.17.4 and 9.0.1. | [runtime of the tool] --help output |
Runtime prerequisite
The console release is framework-dependent: its runtimeconfig names Microsoft.NETCore.App 10.0.0 in 9.0.1 and 8.0.0 in 8.17.4, with no rollForward, so the default Minor policy applies: any installed 10.x (respectively 8.x) release runtime satisfies it, never a pre-release and never another major. resource runtimeconfig files; source .NET host roll-forward rules (learn.microsoft.com, .NET version selection).
The apphost finds .NET in this order: DOTNET_, then DOTNET_ (used exclusively when set, even if empty of runtimes), then the registered location HKLM\ (32-bit registry view), then %ProgramFiles%\, and looks for shared/. source .NET host probing design; [runtime of the tool] with DOTNET_ pointing at an empty folder, 9.0.1 printed You must install .NET to run this application., .NET location: Not found, listed the searched locations and exited with 131 (the low byte of the host error, not the full 0x80008083). No dialog appears for the console apphost. Implemented in dotnet-runtime.ts and isRuntimeMissing.
Success and failure
- Exit code is not enough.
uncookexits 0 when some requested resources fail to export, so callers must check the files they expected. [runtime of the tool] 8.17.4/9.0.1; see PREV-01 in the code-health ledger. Unhandled exceptionin the output means failure even with exit 0; a bad-rregex, for example, raisesRegexParseException(the pattern is a .NET regex over backslash depot paths, so every backslash must be escaped). [runtime of the tool]convert son a resource it can't serialise logsInvalid in wolven rttiandConvertToTextas errors, writes an empty (0-byte).jsonbeside the file and still exits 0; readers must parse the JSON, not trust its presence.unbundlewith--hashexits 0 when the hash is found, and exited 160 when the archive path did not exist. [runtime of the tool] 9.0.1, 25 September 2026, on a mod's.appwhosecastShadowsfield is aBoolwhere 9.0.1 expectsshadowsShadowCastingMode.- Folder
importexits 3 even when every file imported; success isImported N/with N > 0. [runtime of the tool] (Build adapter rule since Experiment 005.)N file(s) - The one runner that applies these rules is
wolvenkit-cli.ts; consumers map its typed errors. Synchronous callers (the independent package verifier, through the injectedverifier-wolvenkit.ts) use its blocking formrunWolvenKitSync, which applies the same policy but cannot be cancelled. The character resolver's fetcher and the grading-LUT host use it too: every fetcher on one resolver cache folder runs its batches one at a time in a uniquemkdtempbatch folder, shares in-flight resources (single-flight), and writes a lasting.failedmarker (versioned; older markers are ignored and removed) only whenconvertfinished cleanly with the extracted file intact and still produced no JSON. Cached JSON is keyed by the WolvenKit identity as well as the archive, and a marker records the identity that failed and counts only for it, so a WolvenKit update extracts again. The archive-index cache is written atomically and trusted only when it holds the entry count the archive's own index declares. The grading-LUT host keeps the opened installation between retries, retries only transient failures (time limit, missing .NET, a process that could not start, a disk error) with doubling backoff and a cap, and treats a WolvenKit exit code on the same archive, entry and WolvenKit as lasting.
What uncook writes
With -u --uext png --mesh-export-type MeshOnly -gp <game> over archive/ and a regex naming the resources: a .mesh yields the raw file, <name>.glb and <name>.Material.json (every material resolved through its .mi chain), plus the textures and multilayer setups those materials use; a .morphtarget yields the raw file and <name>.morphtarget.glb. The head mesh and morph target of the female player head came from basegame_ in 2.31. [runtime of the tool] 9.0.1, 25 Sep 2026; preview export method.
Whether a depot path exists at all is answered from the archives' RDAR indexes (FNV-1a 64 of the sanitized path), not from WolvenKit's output: reading every content index takes about 35 ms. source mod loading, rdar-index-fs.ts.
The native reader replaces most launches. XF Studio's own reader decodes archives and CR2W resources through the game's own Oodle library, in a worker. It reproduces WolvenKit's extracted bytes and the resolver's JSON, including resources that WolvenKit refuses to serialize (the mistyped castShadows above). The resolver reads through it first and runs WolvenKit only for what it doesn't answer: a cold resolve of the reference save needed no launches instead of 23 (mod loading §6). Textures and meshes for the preview still come from WolvenKit's exports. Format and evidence: archive and resource formats.
Open questions
- Does WolvenKit write anything beside itself or under the user profile at runtime (logs, settings, an Oodle DLL copied from the game)? Extra files in XF Studio's managed folder are tolerated, but not yet inventoried.
- Does the CLI need write access to its own folder? XF Studio's copy lives in user data, so this is untested in a read-only location.
- How does the Linux console release (
WolvenKit.ConsoleLinux) differ, if XF Studio ever supports another platform?