A CLI for managing a constellation of related repositories as one cohesive developer workspace.
Status: usable — the core workspace, git, env, profile, and native-run surfaces are implemented and shipped on npm. Container execution, backing-service orchestration, secrets, and the dependency graph are the main outstanding items; see Implementation status below.
Modern product teams routinely span 5–50+ repositories: services, libraries, infra, data jobs, web apps. Onboarding and day-to-day work require chaining git, docker compose, multiple language toolchains, custom shell scripts, and tribal knowledge — and breaks the moment one repo is missing or misconfigured.
qavor is a single CLI that takes a developer from a fresh laptop to a running multi-service stack, and then makes routine multi-repo operations — clone, sync, status, commit, push, and any manifest-defined command (prepare, build, test, …) — first-class verbs.
qavor is a lean wrapper. It owns:
- the declarative manifest model,
- the cross-repo dependency graph,
- environment composition with explicit precedence,
- and the orchestration loop.
It shells out for everything else: git, docker / docker compose, and language toolchains (npm/pnpm, uv/pip, go, cargo, …).
It is not a CI/CD system, a Kubernetes replacement, a devcontainer, or a new container runtime / package manager.
Every YAML document carries a top-level kind: that selects its schema and orchestration semantics:
kind: workspaces— pointer file at the workspace root (generated byqavor init). Multi-repo workspaces only.kind: project— at the seed repo root; defines the workspace and is the single source of truth for the list of repos in it. Astandalone: trueproject with norepositories:declares that the repo holding it is the whole workspace (no pointer, noqavor initneeded).kind: service— a runnable application (how to build and execute an app), withnative,docker, anddocker-composeruntime blocks. This kind also covers externally provided backing deps (postgres, kafka, redis, …): a backing service typically runs viadocker composeand exposes anenv.publishcontract to its dependents. A repo may have zero, one, or many.kind: profile— reusable runtime + env bundle, referenced by service manifests (by local name or by a remote https / GitHub / git /file://source).
See docs/manifests.md for canonical examples and docs/schemas/ for the formal JSON Schemas.
Requires Node.js 26 or newer and pnpm for development.
# Global install from npm (published as `qavor`)
npm install -g qavor
qavor --help# From source
git clone https://github.com/rubenhak/qavor.git
cd qavor
pnpm install
pnpm build
node ./dist/index.js --helpPer-platform Single Executable Application (SEA) artifacts and a Homebrew tap are planned but not yet published; npm is the supported install path today.
qavor init <project-repo-url-or-path> # writes the workspaces pointer + .qavor/, clones the project repo
qavor doctor # verify toolchains, per-service check_installed
qavor git clone # clone every repo from the project manifest
qavor git status # aggregated repo state across all clones (live TUI)
qavor manifests # tree of every manifest discovered in the workspace
qavor commands # list manifest-defined commands across the workspace
qavor prepare # run runtime.native.prepare for services that declare it
qavor run # `run` is just a manifest command like any other
qavor update_libraries # any manifest command is runnable as `qavor <command>`
qavor env auth # resolved env with provenance for one service
qavor resolve-env --only auth --format export # sourceable env including require: depsFor a single-repo project (standalone: true), skip init/clone — run any command from inside the repo and qavor discover to scaffold service manifests.
All multi-repo verbs accept a --only <name...> selector. --json flips every command to NDJSON output on stdout; logs are always on stderr. Exit codes follow docs/exit-codes.md. Global --jobs N (or --serial / --parallel) tunes the default os.availableParallelism() concurrency for every fan-out.
Implemented
- Workspace bootstrap (
qavor init) from a local path or git URL; multi-repo and single-repo (standalone) layouts. - Manifest model for all four kinds (
workspaces,project,service,profile) with schema validation andfile:line:columndiagnostics (qavor validate,qavor manifests,qavor workspace info). - Repo discovery and scaffolding (
qavor discover). - Git fan-out:
clone,sync,status,commit,pushwith--only, bounded concurrency, and a live status TUI. - Dynamic manifest commands: every
runtime.native.<key>other thanenabled/check_installed/install(e.g.run,prepare,update_libraries,lint,test) is discovered and fanned out asqavor <command>;qavor commandslists them. qavor hard-codes no command names. - Env composition with provenance and precedence (
qavor env,qavor resolve-env), includingrequire:-dependency env and backing-serviceenv.publishcontract propagation, withexport/dotenvsourceable output. - Profiles: local + remote sources (https / GitHub / git /
file://, including whole-directory references), profile chaining, and$append/$prepend/$replace/$unsetstep-list merge directives (qavor resolve-manifest). - Declarative
compose:/docker:runtime steps (${VAR}-parametrized, healthcheck-gatedup), and a first-party service library of backing-service templates — postgresql, mysql, redisearch, kind — underlibrary/. qavor doctortoolchain + workspace preflight.--jsonon every command, documented exit codes, published to npm with provenance.
Not yet implemented
- Container execution for first-party apps (
--mode docker: image build/run conventions). Backing services bring themselves up via declarativecompose:/docker:steps instead. ${secret:...}interpolation and secret providers (reserved; fails closed today).- Built-in process supervision. qavor ships no
up/down/ps/logsverbs and does not daemonize or track PIDs; a long-running service is just a manifest command (qavor run) that runs in the foreground. Backgrounding/supervision is left to the command itself (nohup, a process manager,docker compose up -d, …). - Runtime dependency-graph orchestration: topological multi-service start, readiness probes /
waitFor. - Group / tag / state selectors (
--group,--tag,--dirty, …). qavor graph,qavor explain,qavor docs, branch/PR helpers, coordinated tagging, stash,clean, hot-reload, debug mode.- SEA per-platform binaries, Homebrew tap, curl installer.
docs/proposal.md— full product proposal, with per-requirement implementation status.docs/manifests.md— manifest reference and source of truth.docs/decisions.md— architectural decision records (ADRs).docs/mvp-tasks.md— MVP delivery record and forward roadmap.docs/exit-codes.md— CLI exit-code contract.
pnpm install
pnpm gen:types # regenerate manifest TS types from docs/schemas/
pnpm typecheck
pnpm lint # biome check
pnpm test # node:test + tsx, hermetic fixtures under testdata/
pnpm build # tsup → dist/index.js (ESM, Node ≥26)The CI gate is pnpm lint && pnpm test && pnpm gen:types:check && pnpm typecheck.
Apache-2.0. See LICENSE.