mooncat-flow
v0.1.8
Published
Minimal project scaffolding + Dagu CLI passthrough + runtime helper. Bundles the dagu binary so `npm i @mooncat/flow` is self-contained. Not a workflow engine.
Readme
mooncat-flow
Minimal project scaffolding + Dagu CLI passthrough + runtime helper for Dagu flow projects.
Not a workflow engine. Dagu runs the flows. mooncat-flow only configures directories, scaffolds projects, and bridges to the dagu CLI.
Bundled with dagu — install once, works out of the box
@mooncat/flow depends on @dagucloud/dagu,
which installs the platform-correct dagu binary automatically. So npm i
@mooncat/flow is self-contained — no separate global dagu install is
required. mooncat-flow dagu ... resolves the bundled binary first, falling
back to dagu on PATH only if present.
Commands
mooncat-flow init <name> # scaffold a complete Dagu flow project
mooncat-flow dagu <args..> # strict passthrough to the dagu CLI
mooncat-flow doctor # check dagu / node / shell / config
mooncat-flow skills install # install bundled skills into ~/.agents/skillsIt deliberately does NOT define run / retry / status / history /
server / scheduler / step / checkpoint / install / package.
Those belong to Dagu (run/status/history via dagu) or to later versions.
Bundled skills
mooncat-flow skills install copies three skills into ~/.agents/skills/
so coding agents (pi, Claude Code, ...) can pick them up:
dagu— official Dagu YAML authoring reference (vendored)mooncat-flow-rule— 9 hard rules for mooncat-flow projectsmooncat-flow-sop— standard loop: spec → build → diagnose
mooncat-flow skills # install all
mooncat-flow skills --only dagu # install just one
mooncat-flow skills --force # overwrite existing
mooncat-flow skills --list # list bundled skill namesOverride the target with AGENT_SKILLS_DIR.
Core principle
A flow is a standard Dagu project. It MUST be runnable by raw
dagu startonceDAGU_*env vars are set — mooncat-flow only configures them for you.
mooncat-flow never wraps, rewrites, or swallows Dagu arguments. mooncat-flow
dagu <args...> is byte-for-byte equivalent to dagu <args...>.
Quick start
# install globally (pulls the dagu binary for your platform)
npm install -g @mooncat/flow
# create a project, then run it — no other setup needed
mooncat-flow init my-flow
cd my-flow
mooncat-flow dagu validate hello.yaml
mooncat-flow dagu start hello -- message=world
mooncat-flow dagu status hellomooncat-flow dagu ... reads mooncat-flow.config.json from the project root
and translates it into the four DAGU_* env vars (explicit env always wins).
Two layers, one connection
mooncat-flow.config.json -> DAGU_* (set by `mooncat-flow dagu ...`)
|
v
Dagu runs a step, injects DAG_RUN_* / DAGU_OUTPUT_FILE
|
v
step scripts + runtime helper (read DAG_RUN_* ONLY)- Project config (
mooncat-flow.config.json): the ONLY config — four Dagu dirs plus optionalenvPassthrough/envPassthroughPrefixes. mooncat-flow translates it toDAGU_HOME/DAGU_DAGS_DIR/DAGU_LOG_DIR/DAGU_ARTIFACT_DIRandDAGU_ENV_PASSTHROUGH(_PREFIXES). Dagu does NOT inherit the parent process env by default; declare which vars your steps need (e.g. credentials) once here and they reach every step without per-stepenv:blocks in dag.yaml. - Runtime helper (
@mooncat/flow/runtime, or the bundled_mooncat_runtime.py): reads ONLYDAG_RUN_WORK_DIR/DAG_RUN_ARTIFACTS_DIR/DAGU_OUTPUT_FILE. It NEVER reads the project config — the two layers meet only through Dagu's environment variables.
What a project looks like
my-flow/
mooncat-flow.config.json # the ONLY config: four Dagu dirs
flows/ # DAG files + steps
hello.yaml
steps/
hello.sh # shell step
hello.py # python step (uses _mooncat_runtime.py)
_mooncat_runtime.py # local runtime helper (reads DAG_RUN_*)
README.md
.gitignoreSee templates/basic.
Runtime helper API (inside steps)
import { currentRuntime } from "@mooncat/flow/runtime";
const ctx = currentRuntime();
ctx.work("tmp.json"); // path under DAG_RUN_WORK_DIR
ctx.saveArtifact("r.json", {});// arbitrary asset (text/bytes) under DAG_RUN_ARTIFACTS_DIR
ctx.copyArtifact(localFile); // copy a real file (xlsx/png/...) into artifacts
ctx.output("count", 3); // small key=value -> DAGU_OUTPUT_FILE
ctx.log("done");Artifacts are arbitrary file assets (json, markdown, html, csv, images, xlsx, zip) — browsable in the Dagu Web UI. Don't reduce them to path strings.
Why no engine?
Dagu already covers running, queuing, stopping, retrying, status, history, validation, dry-run, server, scheduler, worker, context, profile, sync, and cleanup. Re-implementing those would only lose Dagu's params, context, profile, run-id, queue, and remote-server capabilities. So mooncat-flow does the things Dagu doesn't: scaffold projects, configure directories, and give step scripts a thin convenience layer.
