Application distribution packer built with MoonBit

| You call | You get back | Shape |
|---|---|---|
| @LunaPack.pack(dir, pkg, opts) | the package, written | Unit (the manifest is in the file) |
| @LunaPack.bundle(exe, out, dirs, opts, launcher) | the self-extracting single file | Unit |
| @LunaPack.unpack(pkg, dest, run_scripts, key) | the tree, extracted and verified | Unit |
| @LunaPack.verify(pkg, key) | whether every entry is intact | Bool |
| @LunaPack.read_package_manifest(pkg) | the manifest of a package | Manifest |
| @LunaPack.probe_archive(path) | the offset of the archive and its manifest | (Int64, Manifest)? |
| @LunaPack.verify_extracted_dir(pkg, dir) | whether the files in dir still match the package | Bool |
| @LunaPack.new_pack_options(...) | the options of a package | PackOptions |
| @LunaPack.new_script(platform, body) | an install script | Script |
| @LunaPack.recover_encryption(info, key, passphrase) | the key of a sealed package | PackageKey |
| @LunaPack.x25519_public_key(secret) | the public key of a secret key | Bytes |
| @LunaPack.ed25519_public_key(seed) | the public key of a signing seed | Bytes |
| @LunaPack.ed25519_sign(seed, message) | a signature of a message | Bytes |
| @LunaPack.ed25519_verify(public, message, signature) | whether a signature holds | Bool |
| @LunaPack.public_key_pair(secret) | the two public keys of a secret key | PublicKeyPair |
| @LunaPack.ed25519_seed(secret) | the signing seed of a secret key | Bytes |
| @LunaPack.save_public_key_pair(path, encryption, signing) | the public key file of a pair | Unit |
| @LunaPack.load_public_key(path) | the encryption public key of a file | Bytes |
| @LunaPack.load_signing_public_key(path) | the signing public key of a file | Bytes |
| @LunaPack.sign_package(pkg, secret) | the signature of a package | PackageSignature |
| @LunaPack.verify_package_signature(pkg, sig, public) | whether the signature holds | Bool |
| @LunaPack.verify_package_digest(pkg, digest) | whether the package has that digest | Bool |
| @LunaPack.manifest_digest(offset, length, bytes) | the digest of a manifest | Bytes |
| @LunaPack.manifest_mac(key, offset, length, bytes) | the MAC of a manifest | Bytes |
moon add riantr/LunaPack@0.1.14import {
"riantr/LunaPack@0.1.14",
}///|
import {
"riantr/LunaPack" @lib,
}///|
import {
"riantr/LunaPack" @lp,
}| Package | Kind | Native | Wasm |
|---|---|---|---|
| riantr/LunaPack | library and executable | yes | yes |
| Asset | Platform |
|---|---|
| lunapack-windows-x86_64.exe | Windows |
| lunapack-linux-x86_64 | Linux |
| lunapack-macos-aarch64 | macOS (Apple Silicon) |
| lunapack.wasm | WebAssembly, for moonx |
| lunapack.core | the compiled package the WebAssembly module needs |
moon login # once
moon publish --dry-run # validate
moon publish # publish riantr/LunaPack
moonx riantr/LunaPack@latest --input-exe=... --output-exe=... --Files=...myapp.exe = [ LunaPack launcher ] + [ archive: myapp.exe, res/app.cfg, ... ]$ ./myapp.exe
LunaPack: starting D:/apps/.lunapack/9c445884d23653fb/myapp.exe# A bundle for Windows, made with the launcher of the release.
lunapack bundle -i ./myapp.exe -o ./myapp.exe \
--Files=./build --launcher ./lunapack-windows-x86_64.exeThe bundle is self-extracting when the launcher is a native LunaPack binary. The one that runs on this machine is used by default, so a native LunaPack always produces a self-extracting file. A bundle produced through moonx runs on WebAssembly and has no native binary of its own, so it needs one named with --launcher — see above.Without one, moonx still writes a file that holds the whole payload, and that file does not start on its own: starting it runs the bundled program with none of its files unpacked next to it, which for most programs means it fails at once. The two files look identical from the outside — same name, same size, a whole payload inside — so the last line that the command prints says which of the two was made, and it also goes to stderr. A bundle that is only meant to carry a payload can be unpacked with lunapack unpack; a bundle that is meant to be started needs the launcher.
$ ./myapp.exe --version
myapp 2.6.0
$ echo $?
0$ lunapack --input-exe=./myapp.exe --output-exe=./myapp.exe --Files=./build
md5 6b1b1e1f0a2c3d4e5f60718293a4b5c6 myapp.exe
...
scanned 392 files
bundled 392 files -> ./myapp.exe (icon copied)
output md5 0f1e2d3c4b5a69788796a5b4c3d2e1f0 myapp.exelunapack verify myapp.exe
lunapack info myapp.exe
lunapack unpack -i myapp.exe -o ./out+--------------------+ offset 0
| magic "APPKGD02" | 8 bytes
+--------------------+ offset 8
| entry payloads | stored back to back, raw, gzip, lz4 or sealed
+--------------------+
| integrity block | 40 bytes, or 72 for a sealed package
+--------------------+
| manifest (UTF-8 |
| JSON) |
+--------------------+
| magic "APPKGD02" | 8 bytes
| manifest offset | 8 bytes, little-endian int64
| manifest length | 8 bytes, little-endian int64
+--------------------+ end of file{
"format_version": 6,
"name": "myapp",
"version": "1.4.0",
"os": "linux",
"arch": "x86_64",
"checksum_algo": "sha256",
"compression": "auto",
"created_at": "2026-11-04T04:10:20Z",
"main_program": "myapp.exe",
"pre_install": { "platform": "posix", "body": "#!/bin/sh\n..." },
"post_install": null,
"entries": [
{
"path": "res/app.cfg",
"mode": 420,
"size": 22500,
"stored_size": 913,
"codec": "gzip",
"checksum": "0a77c24c45d0c61f906862c4706f5dd739166985e8fc5c6344dadd9220507b28",
"md5": "1520e796ba25554696b3cef6e913cc90",
"offset": 8
}
]
}| Layer | What it is | What it stops |
|---|---|---|
| SHA-256 of every entry | in the manifest | a payload that was changed or corrupted |
| MD5 of every entry | in the manifest | the same, by a second and independent algorithm |
| SHA-256 of the manifest | in the integrity block | a manifest that was changed in place, a truncated write |
| HMAC-SHA512 of the manifest | in the integrity block of a sealed package | a manifest that was rewritten by whoever holds the file |
| The cache is checked on every start | in the launcher | a payload that was changed after it was unpacked |
| The program is checked before it runs | in the launcher | a program that was changed between the check and the start |
| The cache is read back after it arrives | in the launcher | a payload that only part of a move delivered |
| A damaged package is refused | everywhere | a package that was cut short being taken for something else |
| The paths of the entries are checked | everywhere | a path that writes outside the destination |
| The package is written in one piece | everywhere | a target that is half a package after a crash |
| The checksum is computed twice | in every checker | a fault in the machine that computes it |
| The signature of the host | next to the package | a package that was rewritten from top to bottom |
# The host signs the package with its secret key.
lunapack sign myapp.appkg --secret-key host.key --output myapp.appkg.sig
# Whoever holds the public key checks the signature.
lunapack verify myapp.appkg --signature myapp.appkg.sig --public-key host.publunapack verify myapp.appkg --expected-sha256 <the digest the host published>lunapack-public-key v1
x25519 751d2616ba1be8341b35f6cf2d73978e2cccecd1decd0f898b421a99618bc35f
ed25519 a8414c851959a5449aad50fe53b9d976028fd3122248cf87331bd0e0a8ea526e| Method | What it does |
|---|---|
| none | store the files as they are |
| gzip | gzip every entry |
| lz4 | LZ4 every entry |
| auto | gzip every entry, but keep the raw bytes when gzip would make the entry bigger (the default) |
| gzip | LZ4 | |
|---|---|---|
| packing | 39 s | 16 s |
| unpacking | 21 s | 19 s |
| size of the package | 139 MB | 175 MB |
| Method | What it does |
|---|---|
| x25519 | the package is sealed to the owner of a public key; only the owner of the secret key can open it |
| passphrase | the package is sealed with a passphrase |
# Make a pair of keys. The public key goes to the machine that seals the
# packages, the secret key to the machine that opens them.
lunapack keygen --public-key recipient.pub --secret-key recipient.key
# Seal a package to the owner of the public key.
lunapack pack -i ./app -o app.appkg \
--encryption-method x25519 --public-key recipient.pub
# Open it again with the secret key.
lunapack unpack -i app.appkg -o ./out --secret-key recipient.key
# Or with a passphrase.
lunapack pack -i ./app -o app.appkg \
--encryption-method passphrase --passphrase-file passphrase.txt
lunapack unpack -i app.appkg -o ./out --passphrase-file passphrase.txtlunapack-public-key v1
x25519 751d2616ba1be8341b35f6cf2d73978e2cccecd1decd0f898b421a99618bc35f
ed25519 a8414c851959a5449aad50fe53b9d976028fd3122248cf87331bd0e0a8ea526elunapack keygen --public-key recipient.pub --secret-key recipient.key \
--passphrase-file passphrase.txt| Extension | Target platform |
|---|---|
| .cmd, .bat, .ps1 | windows |
| .sh | posix (Linux + macOS) |
| anything else | any |
moonx riantr/LunaPack@latest \
--input-exe=[input-exe-path] \
--output-exe=[output-exe-path] \
--Files=[Pack-Folder]| Flag | Meaning |
|---|---|
| --input-exe | the application executable to distribute |
| --output-exe | the produced single-file bundle |
| --Files | folder of files to bundle with it (repeatable) |
moonx riantr/LunaPack@latest \
--input-file="x64/Release/App.exe" \
--output-file="App.exe" \
--Files="x64/Release"lunapack pack -i <input_dir> -o <output.appkg> [options]
lunapack bundle -i <exe> -o <output.exe> [--Files <dir>]... [options]
lunapack unpack -i <package> -o <dest_dir> [--skip-scripts]
lunapack verify <package> [--extracted <dir>]
lunapack sign <package> --secret-key <file> [--output <file>]
lunapack info <package>
lunapack keygen --public-key <file> --secret-key <file>lunapack verify myapp.exe --extracted .lunapack\b7e21c9f4d0a8356lunapack sign myapp.appkg --secret-key host.key --output myapp.appkg.siglunapack-signature v1
algorithm ed25519
package 0f2a... <- the SHA-256 of the package
manifest 8c41... <- the SHA-256 of the manifest
signature 3b90... <- the Ed25519 signature of the twoverify: OK (392 files)
verify: OK (392 files in .lunapack/b7e21c9f4d0a8356)
VERIFY OKverify: OK (392 files)
verify: md5 mismatch for appsettings.json: expected 86ff00ef... got 3ddcb685...
verify: FAILED (392 files checked)
VERIFY FAILEDmoon build --release
# -> _build/native/release/build/LunaPack.exe (every platform)| Option | Meaning |
|---|---|
| --input-file <path> | another name for --input-exe |
| --output-file <path> | another name for --output-exe |
| --name <name> | package name (default: input dir / exe name) |
| --version <ver> | package version (default: 0.1.0) |
| --os <os> | target OS tag (default: detected) |
| --arch <arch> | target arch tag (default: detected) |
| --pre-install <file> | script executed before extraction |
| --post-install <file> | script executed after extraction |
| --compression-method <m> | none, gzip, lz4 or auto (default: auto) |
| --launcher <file> | the launcher of the single file (default: this one) |
| --encryption-method <m> | x25519 or passphrase (default: none) |
| --public-key <file> | the public key of the recipient, or of the host that signed the package |
| --secret-key <file> | the secret key of the recipient |
| --passphrase-file <file> | the file that holds the passphrase |
| --passphrase <text> | the passphrase itself (visible in the process list) |
| --skip-scripts | unpack without running the install scripts |
| --extracted <dir> | with verify: also check the files already in <dir> |
| --signature <file> | with verify or unpack: the signature the host published |
| --expected-sha256 <hex> | with verify or unpack: the digest the host published |
| --output <file> | with sign: where the signature is written |
# Bundle an application and its resources into one self-extracting file.
lunapack --input-exe=./build/myapp \
--output-exe=./dist/myapp \
--Files=./build
# Or produce a plain archive instead.
lunapack pack -i ./myapp -o myapp.appkg \
--name myapp --version 1.4.0 \
--pre-install setup.sh --post-install setup.sh
lunapack verify myapp.appkg
lunapack unpack -i myapp.appkg -o /opt/myapp md5 6f5902ac237024bdd0c176cb93063dc4 a.txt
md5 3db2050fcf84bb631dcae417d3db518c sub/b.txt
scanned 2 files
packed 2 files -> myapp.appkg
output md5 63da650c906fe3ab1446b121a4edd4ca myapp.appkgunpacked 2 files -> /opt/myapp
md5 6f5902ac237024bdd0c176cb93063dc4 a.txt
md5 3db2050fcf84bb631dcae417d3db518c sub/b.txt
verified 2 files, 0 mismatcheslunapack ^
--input-exe="D:/src/App/bin/Release/net10.0-windows/App.exe" ^
--output-exe="D:/dist/App.exe" ^
--Files="D:/src/App/bin/Release/net10.0-windows"| Gate | What it checks |
|---|---|
| moon fmt --check | that the source is formatted the way the toolchain formats it |
| moon check --target native / --target wasm | that the module type-checks on both backends it claims |
| moon test --target native | the format, the compression, the encryption, the primitives |
| moon build --release --target native / --target wasm | that the binary and the WebAssembly module are produced |
| moon info + git diff --exit-code -- '*.mbti' | that the published interface is not stale |
| bash scripts/test_linux.sh | the round trip the unit tests do not cover |
| Guard that was removed | The test that went red |
|---|---|
| the SHA-256 of the manifest | a package whose manifest was changed is refused |
| the MAC of the manifest | a sealed package whose manifest was changed is refused |
| the check of the cache | the cache is only used again when it holds what the package carries |
| the check of the program | the program of a bundle is checked before it is started |
| the refusal of a damaged package | a damaged package is not taken for a file that is not a package |
| the write in one piece | a pack that fails leaves the target alone |
| the comparison of the two checksums | a checksum that is not the same twice is refused |
| the check of the signature | a signature does not hold for another public key |
| the check of the paths | a path that walks out of the destination is refused |
| the signing key of a pair | the signing key of a pair checks a signature made with it |
| the separation of the two roles | the two roles of a pair are separated |
| the cleanup of the archive of a refused bundle | a refused bundle leaves nothing behind |
| the warning that tells the two kinds of bundle apart | the two kinds of bundle are told apart |
| the read-back of the cache after it arrives | a cache that does not hold the payload is not handed out |
| the ownership of the console | the console of the terminal is not taken away |
moon add riantr/LunaPacklunapack bundle -i ./build/myapp -o ./dist/myapp --Files ./build
./dist/myapp --versionlunapack pack -i ./myapp -o myapp.appkg
lunapack verify myapp.appkg
lunapack unpack -i myapp.appkg -o /opt/myappmoon test # 131 tests
moon build --release --target native # the binary
moon build --release --target wasm # the WebAssembly module///|
async fn main {
// A plain archive: a directory, compressed per entry, checksummed per entry.
let opts = @lp.new_pack_options(
"myapp", // the name of the package
"1.4.0", // the version of the package
"linux", // the os tag
"x86_64", // the arch tag
None, // the pre-install script
None, // the post-install script
"auto", // the compression
)
@lp.pack("./myapp", "myapp.appkg", opts)
// The same application as a single self-extracting file. The launcher is the
// running program itself, and the main program is recorded by the bundle.
@lp.bundle("./build/myapp", "./dist/myapp", ["./build"], opts, "")
// Read the manifest back, and check the package.
let m = @lp.read_package_manifest("myapp.appkg")
let ok = @lp.verify("myapp.appkg", None)
@lp.unpack("myapp.appkg", "/opt/myapp", true, None)
}///|
async fn main {
match @lp.probe_archive("./dist/myapp") {
Some((offset, manifest)) => {
println("the archive starts at " + offset.to_string())
println("it holds " + manifest.entries.length().to_string() + " entries")
}
None => println("this file carries no LunaPack archive")
}
}///|
async fn main {
let m = @lp.read_package_manifest("secret.appkg")
match m.encryption {
Some(info) => {
let key = @lp.recover_encryption(info, "recipient.key", "")
@lp.unpack("secret.appkg", "./out", true, Some(key))
}
None => ()
}
}| Gate | Catches |
|---|---|
| moon fmt --check | a source file that is not formatted the way the toolchain formats it — a diff the next contributor would have to make |
| moon check --target native / --target wasm | a package that does not type-check on one of the two backends it claims to support |
| moon test --target native | a change in the format, the compression, the encryption or one of the primitives — every one of them is checked against a vector or against the reference implementation |
| moon info + git diff --exit-code -- '*.mbti' | a published interface that is stale: a symbol changed and the .mbti was not regenerated |
| bash scripts/test_linux.sh | a round trip the unit tests do not cover — the install scripts, the permission bits, the corruption detection, the bundle as a byte-identical round trip |
| the tag check of the release workflow | a tag that disagrees with the version in moon.mod, which would publish a module that is not the tree it was cut from |
pub struct Encryption {
method_name : String
recipient : String
ephemeral : String
salt : String
iterations : Int
key_check : String
}pub struct EncryptionOptions {
method_name : String
public_key : String
passphrase : String
iterations : Int
}pub struct Entry {
path : String
mode : Int
size : Int64
stored_size : Int64
codec : String
checksum : String
md5 : String
offset : Int64
}pub struct Manifest {
format_version : Int
name : String
version : String
os : String
arch : String
checksum_algo : String
compression : String
created_at : String
main_program : String
pre_install : Script?
post_install : Script?
encryption : Encryption?
entries : Array[Entry]
}pub struct PackOptions {
name : String
version : String
os : String
arch : String
pre_install : Script?
post_install : Script?
compression : String
main_program : String
encryption : EncryptionOptions?
}pub struct PackageKey {
master : Bytes
salt : Bytes
}pub struct PackageSignature {
package_digest : String
manifest_digest : String
signature : String
}pub struct PeFile {
data : Bytes
sections : Array[(Int64, Int64, Int64, Int64)]
resource_rva : Int64
resource_size : Int64
}pub struct Poly1305 {
r0 : UInt64
r1 : UInt64
r2 : UInt64
r3 : UInt64
r4 : UInt64
s0 : UInt64
s1 : UInt64
s2 : UInt64
s3 : UInt64
h0 : UInt64
h1 : UInt64
h2 : UInt64
h3 : UInt64
h4 : UInt64
buffer : Array[Byte]
}pub struct PublicKeyPair {
encryption : Bytes
signing : Bytes
}pub struct Script {
platform : String
body : String
}pub struct SealedPackage {
shared : Bytes
ephemeral : Bytes
recipient : Bytes
salt : Bytes
}let FORMAT_VERSION : Intlet GZIP_LEVEL : Intlet INTEGRITY_BLOCK_BYTES : Intlet INTEGRITY_BLOCK_BYTES_ENCRYPTED : Intlet INTEGRITY_DIGEST_BYTES : Intlet INTEGRITY_MAC_BYTES : Intlet INTEGRITY_MARKER : Stringlet INTEGRITY_MARKER_BYTES : Intlet INTEGRITY_MARKER_ENCRYPTED : Stringlet KEY_HEADER_BYTES : Intlet KEY_SALT_BYTES : Intlet MAGIC : Stringlet METHOD_PASSPHRASE : Stringlet METHOD_X25519 : Stringlet PASSPHRASE_ITERATIONS : Intlet PE_SUBSYSTEM_OFFSET : Int64let PUBLIC_KEY_ENCRYPTION : Stringlet PUBLIC_KEY_SIGNING : Stringasync fn bundle(input_exe : String, output_exe : String, file_dirs : Array[String], opts : PackOptions, launcher : String) -> Unitfn bytes_concat(a : Bytes, b : Bytes) -> Bytesfn chacha20_xor(key : Bytes, nonce : Bytes, counter : UInt, data : BytesView) -> Bytesfn chacha20poly1305_open(key : Bytes, nonce : Bytes, sealed_data : BytesView, aad : BytesView) -> Bytes?fn chacha20poly1305_seal(key : Bytes, nonce : Bytes, plaintext : BytesView, aad : BytesView) -> Bytesfn compress_with(data : Bytes, codec_name : String) -> (Bytes, String)fn compute_key_check(shared : Bytes, recipient : Bytes, ephemeral : Bytes, salt : Bytes) -> Bytesasync fn copy_icon(source_exe : String, target_exe : String) -> Boolfn current_exe_path() -> String?fn default_arch() -> Stringfn dirname(p : String) -> Stringfn ed25519_public_key(secret : Bytes) -> Bytes raisefn ed25519_seed(secret : Bytes) -> Bytesfn ed25519_sign(secret : Bytes, message : Bytes) -> Bytes raisefn ed25519_verify(public : Bytes, message : Bytes, signature : Bytes) -> Bool raiseasync fn ensure_parent_dir(path : String) -> Unitasync fn file_md5_hex(path : String) -> Stringfn gzip_decompress(data : Bytes) -> Bytesfn hex_to_bytes(text : String) -> Bytes?fn hkdf_expand_sha512(prk : Bytes, info : Bytes, length : Int) -> Bytesfn hkdf_extract_sha512(salt : Bytes, ikm : Bytes) -> Bytesfn hkdf_sha512(ikm : Bytes, salt : Bytes, info : Bytes, length : Int) -> Bytesfn hmac_sha512(key : Bytes, data : Bytes) -> Bytesfn host_platform() -> Stringfn i64_to_le8(v : Int64) -> Bytesfn integrity_block(moff : Int64, mlen : Int64, mbytes : Bytes) -> Bytes raisefn integrity_block_encrypted(key : PackageKey, moff : Int64, mlen : Int64, mbytes : Bytes) -> Bytes raisefn is_all_zero(data : Bytes) -> Boolfn is_integrity_block(block : Bytes) -> Boolfn is_integrity_block_encrypted(block : Bytes) -> Boolfn is_native_target() -> Boolasync fn is_protected_key_file(path : String) -> Boolfn iso8601_utc(epoch_millis : UInt64) -> Stringfn le8_to_i64(b : Bytes, start : Int) -> Int64async fn load_public_key(path : String) -> Bytesasync fn load_secret_key(path : String, passphrase : String) -> Bytesasync fn load_signing_public_key(path : String) -> Bytesfn lz4_compress_frame(data : Bytes) -> Bytesfn lz4_decompress_frame(src : Bytes, size : Int) -> Bytesfn magic_bytes() -> Bytesfn manifest_digest(moff : Int64, mlen : Int64, mbytes : Bytes) -> Bytes raisefn md5_hex_of_string(s : String) -> Stringfn new_encryption(method_name : String, recipient : String, ephemeral : String, salt : String, iterations : Int, key_check : String) -> Encryptionfn new_encryption_options(method_name : String, public_key : String, passphrase : String, iterations : Int) -> EncryptionOptionsfn new_pack_options(name : String, version : String, os : String, arch : String, pre_install : Script?, post_install : Script?, compression : String) -> PackOptionsfn new_package_signature(package_digest : String, manifest_digest : String, signature : String) -> PackageSignaturefn new_sealed_package(shared : Bytes, ephemeral : Bytes, recipient : Bytes, salt : Bytes) -> SealedPackagefn norm_sep(p : String) -> Stringfn not_self_extracting_message(output : String) -> Stringasync fn package_manifest_digest(pkg : String) -> Stringfn package_tag_of(text : String) -> Stringfn passphrase_secret(passphrase : String, salt : Bytes, iterations : Int) -> Bytesfn pbkdf2_sha512(password : Bytes, salt : Bytes, iterations : Int, length : Int) -> Bytesfn pe_subsystem(data : Bytes) -> Intasync fn pe_subsystem_of(path : String) -> Intfn poly1305(key : Bytes, data : BytesView) -> Bytesasync fn recover_encryption(info : Encryption, secret_key : String, passphrase : String) -> PackageKeyfn redundant_md5(data : Bytes) -> String raisefn redundant_sha256(data : Bytes) -> String raiseasync fn remove_dir(path : String) -> Unitfn report_md5(path : String, digest : String) -> Unitasync fn report_output_md5(path : String) -> Unitasync fn run_install_script(platform : String, kind : String, script : Script, dest : String) -> Intasync fn save_public_key(path : String, public_key : Bytes) -> Unitasync fn save_public_key_pair(path : String, encryption : Bytes, signing : Bytes) -> Unitasync fn save_secret_key(path : String, secret_key : Bytes, passphrase : String) -> Unitasync fn save_secret_key_raw(path : String, secret_key : Bytes) -> Unitfn script_applies(script_platform : String, host : String) -> Boolfn script_file_name(platform : String, kind : String) -> Stringfn script_platform_of(path : String) -> Stringasync fn set_pe_subsystem(path : String, subsystem : Int) -> Boolasync fn set_permissions(platform : String, path : String, mode : Int) -> Unitfn sha256_hex(data : Bytes) -> Stringfn sha256_hex_of_string(s : String) -> Stringfn sha512_hex(data : Bytes) -> Stringfn shared_with_secret_key(secret : Bytes, ephemeral : Bytes) -> Bytesfn string_to_utf8_bytes(s : String) -> Bytesfn truncate_bytes(data : Bytes, count : Int) -> Bytesasync fn try_launch_self_extracting() -> Boolfn utf8_bytes_to_string(bs : Bytes) -> Stringasync fn verify_extracted_dir(pkg : String, dir : String) -> Boolasync fn verify_package_digest(path : String, expected : String) -> Boolfn with_defaults(opts : PackOptions, name : String, version : String, os : String, arch : String) -> PackOptionsfn x25519(scalar : Bytes, point : Bytes) -> Bytesfn x25519_public_key(scalar : Bytes) -> Bytesfn xxhash32(data : Bytes, start : Int, end : Int, seed : UInt) -> UInt