Skip to content
Moku
@moku-labs/ai pages

cli

The moku bin: seven commands, the project config and an exit-code contract.

On this page

What it does

The package ships the moku bin. It loads the project config, calls createApp, start, app.cli.dispatch(argv) and stop, then exits with the returned code.

Commands

CommandWhat it does
moku new [name]Writes <name>.moku.yaml and its JSON Schema. Default name: build. Refuses to overwrite.
moku validate [glob]Compiles every match. Offline, no keys.
moku estimate [glob]Cost per task and provider, and the total. No key needed.
moku run [glob]Runs the matches, with live progress, then exports the done artifacts.
moku export [runId]Copies a run's artifacts to named files. Default: the newest run.
moku status [runId]One snapshot, or a poll each second. Safe from a second process.
moku compose "<prompt>"Generates a build file.
FlagOnDescription
--max-cost <usd>runThe budget ceiling. A bad value exits 3.
--dry-runrunPlans and prints the estimate.
--out <dir>run, exportExport folder. Default out.
--flatrun, exportNo <build>/ folder.
--followstatusPolls until the run ends.
--emit build|scriptcomposeThe output format. Default build.
--out <path>composeThe file to write. Default: stdout.
--config <path>allThe project config to load.
a session
moku compose "narrate a sunset in 3 languages" --out sunset.moku.yaml
moku validate
moku estimate
moku run --max-cost 5 --out assets/audio
moku status --follow

Exit codes

Cli.EXIT_CODES holds these names.

CodeNameMeaning
0okSuccess.
1failureA failed run, or any uncaught error.
2validationAn invalid build file.
3usageA bad command, flag or config.
4pausedCtrl-C drained to a clean pause.
5budgetStop--max-cost was reached.

Project config

The bin looks in the working directory for moku.config.ts, .mts, .js and .mjs, in this order. The first file wins. --config <path> wins over the search. With no file, the defaults apply.

moku.config.ts
import { defineConfig } from "@moku-labs/ai";

export default defineConfig({
  pluginConfigs: {
    ark: { region: "cn" },
    fal: { upload: "data-uri" },
    runner: { maxAttempts: 5 }
  }
});

The default export goes to createApp as it is. Only plugins and pluginConfigs are allowed. defineConfig returns its argument and types it. Node 24 strips the types of a .ts file, and Bun loads it.

A config that does not load prints [ai] Could not load <path>. and the reason, then exits 3.

Config

pluginConfigs.cli.

OptionTypeDefaultDescription
plainbooleanfalsePlain output. Also on when stdout is not a TTY or NO_COLOR is set.

API

Mounted at app.cli, reachable with ctx.require(cliPlugin).

MethodSignatureDescription
dispatch(argv: string[]) => Promise<number>Runs one command and returns its exit code. It does not exit the process.
commands() => CommandTreeThe commands and flags as data.
bin.ts
import { app } from "./app";

await app.start();
const code = await app.cli.dispatch(["estimate", "**/*.moku.yaml"]);
await app.stop();
process.exit(code);

Events

Emits

None.

Listens to

None.

Depends on

runner, buildfile, compose.