Custom Commands
import { palette, type Command } from "@f0rbit/forge";import { z } from "zod";
const give_coins: Command<readonly [number]> = { name: "give_coins", desc: "add N coins to the score", args: z.tuple([z.number().int().nonnegative()]), run: ([n], ctx) => { const s = ctx.res.get(score_r); if (!s.ok) return { ok: false, error: { kind: "runtime", message: "no score" } }; s.value.value += n; return { ok: true, value: `+${n} coins` }; },};
p.register(give_coins);run may be sync or async; the palette awaits it either way. Args go through coerce_arg first (numeric strings become numbers, true/false become booleans), then through the Zod schema.
CommandError cases:
type CommandError = | { kind: "unknown_command"; name: string } | { kind: "parse"; message: string } | { kind: "validation"; issues: readonly string[] } | { kind: "runtime"; message: string };