Quick start
From an empty folder to named artifacts on disk, with a cost estimate and a budget.
A voice line and a translation
-
Install.
@moku-labs/coreand@moku-labs/commonare peer dependencies. Keep one copy of each in the project. Node 24 or newer and Bun are supported.install mkdir my-assets && cd my-assets bun init -y bun add @moku-labs/ai @moku-labs/core @moku-labs/common
-
Scaffold a build file.
moku newwriteshello.moku.yamland the JSON Schema that gives your editor autocomplete.scaffold bunx moku new hello -
Declare what should exist. Each item names a task and its input.
provideris optional: without it the task's default provider runs.hello.moku.yaml version: 1 name: hello items: - id: greeting task: voiceover input: text: "Hello, world!" voice: "21m00Tcm4TlvDq8ikWAM" - id: greeting-es task: translate provider: openai input: text: "Hello, world!" targetLang: es -
Validate and estimate. Neither command needs a key or spends money.
check bunx moku validate bunx moku estimate
-
Add the keys. Export them, or put them in
.env.localin the working directory. The shell wins over the file. These two items needELEVENLABS_API_KEYandOPENAI_API_KEY. -
Run under a ceiling. The budget gate refuses an item that would cross
--max-cost. Ctrl-C drains to a clean pause.run bunx moku run --max-cost 1 -
Run it again. Finished items have an artifact key, so a second run reuses them at no cost. Change one item and only that item is billed.
Files land under out/<build name>/, named by the item id: out/hello/greeting.mp3 here.
The same build from code
createApp gives you every plugin. app.start() opens the journal, and app.stop() closes it.
import { createApp } from "@moku-labs/ai";
const app = createApp({});
await app.start();
const { lines, totalUsd } = await app.runner.estimate({ files: "hello.moku.yaml" });
console.log(lines, totalUsd);
const result = await app.runner.run({ files: "hello.moku.yaml", maxCostUsd: totalUsd * 1.2 });
console.log(result.status, result.totals);
await app.runner.export({ runId: result.runId, outDir: "out" });
await app.stop();statusisdone,failed,pausedorbudget-stopped. It does not reject on a provider error.moku runexports by itself. From code you callexport.
Where things are kept
| Path | What it holds |
|---|---|
.moku/journal.db | The SQLite ledger: runs, items, attempts, costs, hashes. No prompts. |
.moku/store/ | The artifact bytes, named by their sha256. |
.moku/build.schema.json | The JSON Schema moku new writes for the editor. |
out/ | Named copies of the artifacts. Safe to delete: moku export writes them again. |
Add .moku/ and out/ to .gitignore.
Next
- How it works: the pipeline, retries and the budget gate.
- buildfile:
$ref,$file,defaultsanditemsFrom. - cli: every command and exit code.