Skip to content

run

Terminal window
holocron run <task> [job] [-- <passthrough>]

holocron run test runs your tests. You don’t tell it whether the repo uses turbo, pnpm, npm, or which test runner — it works that out.

Task Runs
test vitest run --coverage
typecheck tsc --noEmit
lint the resolved linter set — see below
build tsdown / vite build / rollup -c / tsc -b — whichever config the repo has
audit its sub-jobs — see Sub-jobs
sync holocron sync
wiki holocron sync-wiki

The task set matches the CI workflow names. Adding a task is a one-line change in the CLI — every repo gets it.

0. task === "lint" (no job) → the resolved linter set (see below)
J. a job is given → the task's <job> sub-runner (unknown job → exit 1)
1. turbo.json defines the task → turbo run <task> (monorepo root)
2. package.json has a <task> script (and it isn't `holocron run …`)
→ <detected pm> run <task>
3. the task registry has a local runner
→ <tool> <args> <org-flags> (e.g. --coverage)
4. the task is a container of sub-jobs (`audit`)
→ run each job in declared order
5. known task, nothing to run → "no <task> task for this repo", exit 0
6. unknown task → error, exit 1

An explicit package.json script always wins over the registry default — if you wrote "lint": "biome check", that’s what runs. Likewise a repo-level "audit" script wins over the built-in sub-jobs.

Some tasks are a bundle of smaller jobs. audit is the one that matters today:

holocron run … Runs
audit bundle-size nothing locally — bundle stats upload is CI-only
audit knip knip
audit performance lhci autorun, when the repo has a lighthouse.config
audit (no job) each of the above, in that order

A sub-job whose tool isn’t installed (knip, lhci) or that has no local equivalent (bundle-size) is skipped with a note — CI enforces it regardless. --required turns “can’t run this here” into a failure. holocron run audit frobnicate lists the known jobs and exits 1.

lint doesn’t map to a single command — it runs the resolved linter set (the lint task’s linters list in holocron.config, else auto-detected from the config files present plus the org always-on set). Locally:

  • the eslint slot goes through the normal resolution above — turbo run lint at a monorepo root (cache kept), else the lint script, else eslint .
  • every other linter (prettier --check ., yamllint, actionlint, …) runs its own binary when it’s in node_modules/.bin or on PATH
  • a linter whose binary isn’t found is flagged with an install hint (! actionlint — actionlint not on PATH. brew install actionlint); one with no local equivalent prints · <name> (CI only). CI enforces them regardless.
  • the exit code is the worst of the lot
$ holocron run lint
→ turbo run lint
→ prettier --check .
→ yamllint .
! actionlint — actionlint not on PATH. brew install actionlint (enforced in CI)
· commitlint (CI only)
· git-merge-conflict-markers (CI only)

Install the missing binaries (brew install actionlint gitleaks yamllint …) to run the full CI set locally.

Option Description
--dry-run Print the resolved command without running it
--required Exit 1 (instead of 0) if this repo has no such task
--filter <pkg> turbo --filter=<pkg> passthrough (monorepo)
-- <args> Everything after -- is forwarded to the tool / turbo / script

See also holocron ci — run every required check at once.

Terminal window
holocron run test # vitest run --coverage (or turbo run test at a root)
holocron run test -- --watch # forward --watch to vitest
holocron run build --dry-run # show what would run
holocron run e2e --required # fail if the repo has no e2e task
holocron run test -- --filter web # passthrough turbo's --filter at a monorepo root
holocron run audit # every audit sub-job in order
holocron run audit performance # just Lighthouse CI

At a turbo root, holocron run test is turbo run test — turbo’s cache and dependency graph are untouched. Inside a package, it runs the tool directly. turbo.json doesn’t change.