AI News HubLIVE
In-site rewrite6 min read

Nika – Intent as Code for AI Workflows

Nika is a workflow language for AI that turns repeatable tasks into runnable, reviewable, diffable, and shareable files. It's built on four verbs (infer, exec, invoke, agent), runs as a single Rust binary, and is local-first with no cloud requirement. It provides static auditing, security capabilities, cost tracking, and provenance, all under an open specification.

SourceHacker News AIAuthor: ThibautMelen

Uh oh!

There was an error while loading. Please reload this page.

Notifications You must be signed in to change notification settings

Fork 1

Star 20

BranchesTags

Open more actions menu

Folders and files

NameName

Last commit message

Last commit date

Latest commit

History

1,255 Commits

1,255 Commits

.agents/plugins

.agents/plugins

.cargo

.cargo

.claude-plugin

.claude-plugin

.claude

.claude

.github

.github

crates

crates

docs

docs

examples

examples

fuzz

fuzz

media

media

scripts

scripts

.gitignore

.gitignore

AGENTS.md

AGENTS.md

CHANGELOG.md

CHANGELOG.md

CITATIONS.md

CITATIONS.md

CLAUDE.md

CLAUDE.md

CODE_OF_CONDUCT.md

CODE_OF_CONDUCT.md

CONTRIBUTING.md

CONTRIBUTING.md

Cargo.lock

Cargo.lock

Cargo.toml

Cargo.toml

DIAMOND.md

DIAMOND.md

LICENSE

LICENSE

README.md

README.md

ROADMAP.md

ROADMAP.md

SECURITY.md

SECURITY.md

cliff.toml

cliff.toml

clippy.toml

clippy.toml

deny.toml

deny.toml

lefthook.yml

lefthook.yml

llms.txt

llms.txt

rust-toolchain.toml

rust-toolchain.toml

typos.toml

typos.toml

Repository files navigation

Intent as Code. The workflow language for AI: one file, 4 verbs, one binary.

Useful AI work shouldn't disappear into chats. Nika turns repeatable AI work into files you can run, review, diff and share. If you do the same AI task twice, make it a workflow.

A Nika workflow is just a file: readable, portable, verifiable. It runs locally, on whichever LLM you choose, with no cloud required. The language is an open Apache-2.0 spec; this repo is the reference engine, a single Rust binary (AGPL-3.0). The way SQL pairs with PostgreSQL, or the Dockerfile with Docker.

Does it run today?

Yes.

brew install supernovae-st/tap/nika # or: curl -LsSf https://nika.sh/install.sh | sh nika examples run 01-hello --model mock/echo # zero setup: no key, no model server nika examples run 01-hello --model ollama/qwen3.5:4b # got Ollama? the same run, real + local

Nika audits a workflow before a single token is spent (plan, cost ceiling, secret flows, types, tool args), then runs it:

$ nika check brief.nika.yaml ✔ PLAN 2 wave(s) · 2 task(s) · max parallelism 1 ✔ SECRETS no information-flow escapes ✔ TYPES every deep output reference fits its declared shape ✔ TOOLS every nika: tool names a canonical builtin ✔ ARGS every invoke arg key is declared + every required arg is present ✔ SCHEMA every authored schema: is satisfiable ✔ clean — audited before a single token was spent

$ nika run brief.nika.yaml 🦋 nika · daily-brief · 2 tasks ✔ fetch_notes exec · cat ✔ brief infer · ollama/llama3.2:3b ── 2/2 done · $0.000 · elapsed 16.2s ───────────────────────────

What a workflow looks like

review.nika.yaml: read a PR diff, judge its risk, comment only when it's high.

nika: v1 workflow: pr-risk-review model: ollama/qwen3.5:9b # local by default. swap to any provider

tasks:

  • id: diff # exec: a read-only shell command

exec: command: "git diff origin/main...HEAD" capture: structured

  • id: assess # infer: structured LLM judgment

with: { patch: ${{ tasks.diff.output.stdout }} } infer: prompt: "Risk-assess this diff (secrets, breaking changes, missing tests). Be terse.\n${{ with.patch }}" schema: type: object required: [risk] properties: risk: { type: string, enum: [low, medium, high] }

  • id: comment # invoke: the only write, gated on the verdict

when: ${{ tasks.assess.output.risk == 'high' }} invoke: tool: "mcp:github/pr-comment" args: { body: ${{ tasks.assess.output }} }

Check before it runs

nika check is a static audit. It catches broken references, missing dependencies, schema and permission problems before any model is called — and when something is off, it points at the exact fix:

The two fixtures behind this capture live in scripts/media/fixtures/, gated in both directions by scripts/media/validate-media.sh: the broken one must keep failing nika check, the fixed one must stay clean.

The same audit holds the workflow's declared blast radius. A permits: block makes the file itself the security boundary — hosts, paths, programs, tools, all default-deny once declared. A task that reaches beyond it is caught statically, with the machine-applicable fix, before anything runs:

And failure handling is part of the file, not an ops runbook. When a task dies, on_error: recover: degrades to a declared fallback — the run completes, and the output says what it is:

Images are workflow citizens

nika:image_generate renders through the same discipline as everything else — a declared permits: boundary gates every save, the run ledger meters real spend, and provenance is structural, not a promise:

Local-first — provider: local speaks the OpenAI-images wire any self-hosted server exposes (LocalAI · Ollama · stable-diffusion.cpp · SGLang · vLLM-Omni). The base URL is engine config, never workflow data. Clouds when you choose: openai · gemini · xai — and mock renders real, decodable PNG files offline for CI.

Provenance survives cp — every saved PNG carries a nika tEXt chunk (tool · engine · provider · model · prompt · seed), the practice ComfyUI and InvokeAI standardized and no other workflow engine ships. The sidecar manifest adds sha256, resolved request and timing.

Honesty is enforced — magic bytes beat declared MIME types, lossy provider mappings warn loudly, a provider returning fewer images than asked is a visible count_shortfall:, result URLs are never fetched, and base64 never rides workflow outputs — assets, not blobs.

Real spend in the ledger — a render's exact cost (xAI bills in ticks) lands on the task line and the run total, the same honest-spend channel infer: uses.

Daily commands

nika inspect flow.nika.yaml # anatomy · tasks · waves · cost floor nika check flow.nika.yaml # the audit · exit 0 clean · 2 findings nika explain NIKA-VAR-001 # any code · cause · category · fix-form nika run flow.nika.yaml --var topic=rust # launch inputs · repeatable nika test flow.nika.yaml --update # pin the golden · then nika test = offline CI nika run flow.nika.yaml --task hero # regenerate ONE task + its upstream cone nika run flow.nika.yaml --resume .nika/traces/.ndjson # skip journaled successes nika run flow.nika.yaml --resume --answer approve=true # re-arm a paused gate nika trace show .nika/traces/.ndjson # re-render any past run nika doctor --ping # are the local servers actually listening?

Every run writes its own journal to .nika/traces/ (opt out per run with --no-trace-file, globally with NIKA_NO_TRACE_FILE) — --resume and nika trace read it directly. A paused run exits 4 (a blocking nika:prompt journals its question); cache hits on resume are always visible — nothing is skipped silently.

Pick a workflow

The binary embeds a versioned pack of runnable examples. Browse with nika examples list, read one with nika examples show , preview any of them with --model ollama/qwen3.5:4b (or offline with --model mock/echo):

I want to… Run For

Review a PR before merging examples/pr-risk-review.nika.yaml developers

Turn meeting notes into owned actions nika examples run showcase/t1-meeting-actions everyone

Digest a week of standups nika examples run showcase/t1-standup-digest teams

Draft release notes from commits nika examples run showcase/t2-release-notes maintainers

Triage a support inbox nika examples run showcase/t2-support-triage support · ops

Chase unpaid invoices politely nika examples run showcase/t2-invoice-chaser founders

Track competitors weekly nika examples run showcase/t3-competitor-radar founders

Screen resumes against a role nika examples run showcase/t3-resume-screener hiring

Build a Monday operating brief nika examples run showcase/t4-ceo-monday-brief founders

The full gallery (27 workflows + 6 templates) lives in examples/: foundation patterns, business showcases, and the skeletons nika new --from instantiates.

Shared workflows live on nika-registry — every entry pinned to a full commit + sha256 and re-proven by CI (the conformance oracle + this engine's static certificate: exec · tools · cost, visible before anything runs). nika add is on the roadmap; today the registry's get.py does resolve → verify → audit in one command.

The model

Four verbs, and nothing else. A small core that composes into arbitrary real-world workflows. The Unix and SQL discipline of "small surface, large composition."

Verb What it does

infer Call an LLM. Any provider, local or hosted

exec Run a shell command

invoke Call a tool or MCP server (an HTTP fetch, GitHub, a builtin…)

agent Run an autonomous loop with tools, until the task is done

Everything sits under one frozen, versioned envelope, nika: v1, that won't break. Three properties hold across every workflow:

Provider-agnostic, local-first. Local Ollama or LM Studio, or any API. Your workflow doesn't change when the model does.

Safe by construction. A read-XOR-write capability model. A step that reads cannot silently write; every effect is explicit and gated.

Reproducible. The file and its execution trace are an auditable, re-runnable record.

flowchart LR F["workflow.nika.yaml portable · readable · verifiable"] --> E["nika single Rust binary"] E -->|infer| L["LLMs Ollama · LM Studio · any API"] E -->|exec| S["shell"] E -->|invoke| T["tools · MCP"] E -->|agent| A["autonomous loop"]

Loading

Dependencies make every workflow a graph: independent tasks run in parallel, an agent step fans out, joins wait for every branch — and the whole plan is known, costed and audited before execution starts:

Why Nika

The closest analogues aren't products. They're standards. SQL. The Dockerfile. A portable specification with a reference engine. The language is the contribution, not a product to sell.

As AI agents start acting on the real world, the interface where they act can't be free text (too vague) or raw code (too risky). It has to be a verifiable action language: one an AI writes, a human reviews and approves, and a machine runs deterministically. Kept open and sovereign, not locked inside one vendor's cloud.

What no existing workflow tool offers together: a single Rust binary · portable declarative YAML · local-first · read-XOR-write capability security · AGPL · no cloud required · bring-your-own-LLM.

Status

Nika is built in the open.

The language (the nika: v1 envelope and its four verbs) is stable and won't break. The engine is a strict, modular Rust workspace. The latest tagged public release is v0.91.0; main moves immediately to the next -dev version after each release so local contributor binaries cannot be confused with Homebrew assets. The 1.0.0 launch remains gated by the release checklist, not by a date. The code, the spec, and the example workflows are all readable, and development happens on main in the open.

The nika: v1 language envelope is frozen forever. It is a separate axis from the engine version. Every release is complete for its declared scope; no half-features parked behind a future version.

Get started

Install (macOS · Linux):

Homebrew (macOS · Linux): on your PATH immediately

brew install supernovae-st/tap/nika nika --version

…or, without Homebrew: the install script. It downloads the verified release

binary into ~/.nika/bin and prints the single PATH line to add to your shell

profile (then reopen the terminal, or source it, and nika --version works).

curl -LsSf https://nika.sh/install.sh | sh

Prefer a guided page? Every install path, step by step: nika.sh/install.

Fully manual / air-gapped? Download the platform tarball + SHA256SUMS from the latest release, verify with sha256sum -c SHA256SUMS --ignore-missing, then move nika onto your PATH.

Your first workflow runs with zero setup: no model, no API key:

cat > hello.nika.yaml points each client's MCP config at the engine — idempotent, and it

[truncated for AI cost control]