How to work on dx in a clone. The contributing guide covers how a change gets in.
run-run/: run-run.cli/is@rrlab/cli, the kernel and therrcommand. Each*-plugin/wraps one tool, and each*-config/is a preset that a plugin installs.run-run/CLAUDE.mdcovers the architecture: the plugin contract and how to add or change a plugin.vland/: vland.cli/is@variablelab/vland, andtemplates/holds the projectsvland initstarts from.shared/:@variablelab/clibuddyand@variablelab/loggy, the internal packages the CLIs depend on.decisions/: the architecture decisions, one file each.docs/: this guide and the contributing guide.
The workspace is pnpm, the tasks run through Turborepo, and tsdown builds each package that has a build step.
mise pins Node 24, pnpm and usage in mise.toml, locked in mise.lock. It also puts node_modules/.bin on the PATH, so rr and vland run by name.
git clone git@github.com:withvariablelab/dx.git
cd dx
mise install
pnpm installpnpm install also installs the git hooks, through lefthook.
The published packages declare engines.node as >=22.18.0, except @rrlab/biome-config and @rrlab/ts-config, which hold only JSON presets and declare none. mise.floor.toml pins that floor, and MISE_ENV=floor runs the repo on it, as CI does:
MISE_ENV=floor mise install
MISE_ENV=floor mise exec -- pnpm testTo raise the floor, change mise.floor.toml and every engines.node together, then run MISE_ENV=floor mise lock.
pnpm build # build every package
pnpm test # build, then run every package's tests
pnpm rr check # format, lint and type check, with the repo's own rr
pnpm rr jsc --fix # apply Biome's fixes
pnpm tscheck # rr tsc in each package with a tscheck script
pnpm --filter @rrlab/cli test # one package's testspnpm test:unit and pnpm test:integration run one kind of test. Unit tests live in src/**/__tests__/, and integration tests in test/integration/.
In the repo, pnpm rr and pnpm vland, or rr and vland with mise, run each CLI from its src/, so an edit shows up without a build.
- On each pull request to
main: CI runspnpm install --frozen-lockfile,pnpm rr check,pnpm testandpnpm build, once on the Node floor inmise.floor.tomland once on the version inmise.toml. The requiredTestcheck passes when both do. Workflow audit runs zizmor on every workflow in the repo, including those the vland templates generate. - Git hooks (lefthook, in
lefthook/turborepo.yml): on commit,rr jscheck --fix-stagedon the staged files and, when TypeScript changed,tscheckon the changed packages and their dependents; on push, the tests of the affected packages. - Every Monday:
pnpm auditon the lockfile, which keeps an issue labeleddependency-auditopen while it finds known vulnerabilities (Dependency audit).
A pull request from a feat/* or fix/* branch, or with the preview label, publishes each package it changes, and the packages that depend on them, to npm under the pr-<number> tag, once the tests pass. vland-bot comments the published versions on the pull request. To try a preview, install the package with that tag:
pnpm add -D @rrlab/cli@pr-123For a @rrlab/*-plugin package, rr plugins add takes the same @<tag> suffix and passes it on to the plugin's @rrlab/*-config sibling, falling back to latest for a sibling the preview didn't publish:
rr plugins add biome@pr-123run-run/cli/CLI.md and vland/cli/CLI.md are generated, so don't edit them by hand. The cli docs workflow builds each CLI, which writes dist/cli.usage.kdl, and runs usage generate markdown on it. To see the result locally:
pnpm --filter ./run-run/cli build
usage generate markdown --file run-run/cli/dist/cli.usage.kdl --out-file run-run/cli/CLI.md --replace-pre-with-code-fencesEach vland/templates/*/mise.lock is generated by mise lock. After changing a template's mise.toml, run mise lock in that template's directory and commit both files together: vland init fetches the templates from main, and the CI it generates runs mise install --locked, which fails on a tool the lock is missing.