A code-first, strongly-typed build automation system for Deno & TypeScript.
Note
Built with AI. Much of Zuke β code, tests, and docs β was written with AI assistance, then reviewed, type-checked, and tested in CI. Sharing how it was made so you know what you're getting.
Zuke lets you define builds as a TypeScript class. Each target is a class
field declared with a fluent API; targets reference each other by this.x (not
strings), forming a dependency graph that Zuke resolves and runs in topological
order. Inspired by NUKE for .NET.
- Runtime: Deno
- Packages:
jsr:@zuke/coreplus 30+ typed tool wrappers and a genericjsr:@zuke/cmdfallback (raw shell viajsr:@zuke/core/shell) β see Packages for the full matrix with published versions - Build file:
zuke.tsin your project root - Zero runtime dependencies
class MyBuild extends Build {
compile = target()
.dependsOn(this.clean, this.restore)
.executes(async () => {
await DenoTasks.check((s) => s.paths("mod.ts"));
});
}- Typed, refactor-safe dependencies. You wire targets together with
this.clean, not"clean". Rename a target and every reference moves with it; a typo is a compile error, not a runtime surprise. - Just TypeScript. Your build logic is ordinary async functions with full editor support β no YAML, no bespoke DSL.
- Ergonomic shell. The
$tagged template runs processes with sane defaults (throw on failure, capture output) and is injection-safe. - Small and explicit. A tiny core: discover targets, build a graph, sort, run. No magic, no plugins to learn (yet).
- Code-first CI. Declare your pipeline in the build with
cicd({ provider: "github" })β the provider is the only required field β and Zuke generates GitHub Actions, GitLab CI, or Azure Pipelines YAML, regenerating it whenever the build runs (and verifying it on CI).
You need Deno installed. The fastest start is the
@zuke/cli tool β install it once, then scaffold a starter zuke.ts, the
./zuke launchers, and a deno.json task into any directory:
deno install -A -g -n zuke jsr:@zuke/cli # once
zuke setup # in your project
./zuke # run the buildSee Getting started for the full walkthrough
(scaffolding, the ./zuke launcher, a first build, and GitHub Actions output).
Note
All packages publish to JSR from CI via release-please
and OIDC (see RELEASING.md). The npm scope @zuke is not
controlled by this project β install from JSR, not npm.
Zuke ships as a JSR workspace: a tiny core plus a typed wrapper per tool. Every package is versioned and published independently β the badges below track the latest release on JSR.
Looking for the exact API (humans and agents)? Don't guess and don't shell out β every tool is a typed wrapper. The complete, typed surface of every package is in
llms-full.txt(one file), summarised inllms.txt; for a single package rundeno doc jsr:@zuke/<package>. See alsoAGENTS.md.
| Package | Version |
|---|---|
@zuke/core |
|
@zuke/cli |
|
@zuke/cmd |
|
@zuke/deno |
|
@zuke/docs |
|
@zuke/npm |
|
@zuke/security |
All tool wrappers (30+ packages)
Zuke ships typed wrappers for the major AI coding CLIs, so you can fold a model into a build the same way you'd run a linter or a test β as a typed target with refactor-safe dependencies.
| Package | CLI | Flagship task |
|---|---|---|
@zuke/claude |
Claude Code (claude) |
run (headless --print) |
@zuke/codex |
OpenAI Codex (codex) |
exec (headless) |
@zuke/gemini |
Gemini CLI (gemini) |
run (headless --prompt) |
Each runs the CLI non-interactively so it fits CI: drive a prompt, pick a
model, constrain the tool set, and capture the response (request JSON for
machine-readable output). Arguments stay a discrete argv array end-to-end β
never a concatenated shell string β so command construction is injection-free,
and API keys ride through the shared .env(...) chainer, backed by a
parameter().secret() build input that Zuke masks in CI output.
import { Build, parameter, target } from "jsr:@zuke/core";
import { ClaudeTasks } from "jsr:@zuke/claude";
class MyBuild extends Build {
apiKey = parameter("Anthropic API key").secret();
review = target()
.dependsOn(this.test)
.executes(async () => {
const out = await ClaudeTasks.run((s) =>
s.prompt("Review the staged diff for bugs in one paragraph")
.model("sonnet")
.allowedTools("Read", "Grep")
.outputFormat("json")
.env({ ANTHROPIC_API_KEY: this.apiKey.value })
);
console.log(out.stdout);
});
}The mcp (and config/extensions) tasks are flexible command builders for
each CLI's matching subcommand group β handy for provisioning MCP servers in CI.
See Tools for the full task matrix.
Beyond driving the coding CLIs, @zuke/ai makes a
model a first-class citizen of the build graph, two ways:
- AI code review β a reviewer reads the diff, returns a structured assessment (score, severity, findings), writes it to the job summary and the pull request, and breaks the build when the risk crosses a threshold you choose. The output is a typed verdict, not a blob of prose.
- Self-healing builds β attach a fixer to any target with
.recoverWith(...). When the target fails,aiFixerdiagnoses it from the error output and the diff and (diagnose-only default) posts a committable, Copilot-style inline suggestion to the PR. Opt into.autoApply()/.commitFixes()and it fixes the working tree, commits, and re-runs the real command to verify β a fix only counts when the build actually goes green β posting an overview of what it changed instead of a suggestion. - Agent delegation β for open-ended fixes,
agentFixerhands the failure to a coding agent you inject (Claude Code, Codex, Gemini CLI) which edits files itself; one generic fixer, agent chosen at the call site. - Cost controls β a shared
budget(...)caps spend across every reviewer and fixer by an exact token count (no stale price tables; a USD cap is opt-in with your own rates),aiCache(...)reuses a prior response for an identical call, andsuppressions(...)lets you dismiss a false positive by its stable ID so it never fails the build again.
test = target()
.executes(() => DenoTasks.test((s) => s.allowAll()))
// On failure: diagnose, post a committable suggestion, optionally heal.
.recoverWith(aiFixer((f) => f.provider("openai").apiKey(this.key)));Apply a fixer to every target by overriding recoverWith() on the build.
Safe by default (provider + key only): the fixer writes no files and just
diagnoses. Edits are gated behind a path allowlist, a file cap, and local-only
defaults, and nothing is committed unless you ask. See
AI code review and
Self-healing builds.
Zuke ships agent skills so AI coding assistants set up and author builds the
right way β using the typed *Tasks wrappers instead of guessing the API or
shelling out. Two skills, authored once as portable
SKILL.md folders under skills/:
| Skill | Use it to |
|---|---|
zuke-setup |
Scaffold Zuke into a project (zuke setup, the ./zuke launcher, a first build). |
zuke-write-build |
Write or edit a zuke.ts β add targets, wire dependencies, call tool wrappers, generate CI. |
The skills are packaged as a Claude Code plugin distributed from this repo's marketplace. In Claude Code:
/plugin marketplace add zuke-build/zuke
/plugin install zuke@zuke
That makes zuke-setup and zuke-write-build available β they trigger
automatically when you ask Claude to add Zuke to a project or write a build, and
can be invoked explicitly as /zuke:zuke-setup and /zuke:zuke-write-build.
The
SKILL.mdcontent is harness-agnostic (the open Agent Skills standard); the Claude marketplace is just one adapter over the sharedskills/source. Installation for other harnesses (Codex, OpenCode, β¦) is coming later.
Full documentation lives in docs/:
- Getting started β install, scaffold, the launcher, and a first build.
- Core concepts β the build/target/graph model and execution semantics.
- Parameters β typed build inputs from flags and env
vars (
parameter(),this.x.value). - Authoring API β
target(),Build,run(), code-first CI generation (cicd()), and gotchas. - Shell wrapper (
$) β ergonomic, injection-safe process execution. - Paths (
absolutePath) β the fluent path type. - Tools β the typed tool-wrapper packages and their tasks.
- AI code review β gate the build on a structured LLM
assessment of the diff (
@zuke/ai). - Self-healing builds β diagnose and fix failing
targets with
recoverWithandaiFixer, including Copilot-style suggestions. - Extending Zuke β the plugin contract: lifecycle plugins, tool wrappers, and reusable target bundles.
- Using Zuke in a Node/npm project β drive a Node build with Deno.
- CLI reference β commands and flags.
- Programmatic API β drive Zuke from your own code.
deno task test # run the suite
deno task cov # run with coverage + enforce the 95% gate
deno task cov:report # print a per-file coverage table
deno task check # type-check
deno task fmt # format (fmt:check to verify only)
deno task lint # lint
deno task spell # spell-check (cspell)
deno task ci # everything CI runs: fmt:check, lint, spell, check, covCI runs deno task ci on every push and pull request (see
.github/workflows/ci.yml).
Contributions are welcome! Start with CONTRIBUTING.md for
the full workflow, and please be mindful of our
Code of Conduct.
- Read
CLAUDE.mdfor the coding standards (strict typing, noany/as, 95%+ coverage, hermetic tests). - Run
deno task cibefore opening a PR β it must be green. - Add tests in the same change as the code they cover.
- Keep commits small and descriptive; update docs when behaviour changes.
As a build tool that runs in other people's pipelines, Zuke treats supply-chain
integrity as a first-class concern: zero runtime dependencies, injection-free
Deno.Command execution, OIDC trusted publishing with provenance,
least-privilege and SHA-pinned CI, a frozen lockfile, and continuous scanning.
Scanning runs as a typed Zuke target β deno task zuke security drives zizmor,
actionlint, and gitleaks through @zuke/security (which
also wraps osv-scanner, semgrep, and Trivy) β alongside CodeQL and OpenSSF
Scorecard for the Security tab.
See SECURITY.md for the full posture and how to report a
vulnerability.
MIT β see LICENSE.
Zuke stands on the shoulders of giants:
- NUKE and its creator Matthias Koch β the code-first, strongly-typed build model that inspired Zuke. If you build for .NET, use NUKE; Zuke is an homage to its ideas in the Deno/TypeScript world.
- Spectre.Console and its creator Patrik Svensson β the .NET console library
whose markup, themes, and rich widgets (rules, panels, tables) inspired the
output model of
@zuke/console. - Deno β the runtime and toolchain (test runner, formatter, linter, type-checker, coverage) that makes a zero-dependency, hermetic build tool possible.
- JSR β modern, TypeScript-native package distribution.
- Every author of the tools Zuke wraps β Docker, Kubernetes, Terraform, Vite, Playwright, and the rest of the matrix above.
Questions, ideas, or just want to say hi? Open an issue, or reach out:
If Zuke is useful to you, consider starring the repo β it helps others find the project. β