the standard library
nika:done
Everything callable is a tool under invoke: — and the engine ships its own. One closed nika: namespace, no plugin store to audit: these tools version with the spec and pass the same review as your file. Machines read the same vocabulary at /tools/catalog.json; the contract lives in spec 06 · stdlib.
- 27builtinsone namespace
- 6familiescore → media
- 38required argscheck teaches
- 8mcp toolsthe other lane
control flow and run-stream primitives
Fail-fast guard: fail the task when condition is false (else no-op).
- condition*
booleanthe resolved boolean to check- message
stringfailure message
- nika:donecore
Mark the current agent loop complete (the loop-completion sentinel · agent loops only).
- result
- optional final value (any JSON)
Emit a custom machine event for subscribers/journal (distinct from log).
- event_type*
string^[a-z][a-z0-9_.-]*$- payload
- any JSON value
Emit a human-readable diagnostic log line to the run stream (best-effort · never fails).
- level
stringdebug | info | warn | error (default info)- message*
stringthe log message- data
- optional structured context (any JSON)
Ask a human (confirm|input|choice). Blocks until answered; uses default when headless.
- mode
stringconfirm (default) | input | choice- message*
stringthe question- choices
arraychoice mode only- default
- fallback when no human can answer
- nika:waitcore
Pause: relative duration (e.g. "30s") XOR absolute until (ISO 8601). Exactly one.
- duration
stringGo-duration string · relative- until
stringISO 8601 timestamp · absolute- timeout
stringoptional cap for absolute wait
workspace files — read, write, search (permits.fs-gated)
In-place literal find/replace (all occurrences · count caps it). NOT regex.
- path*
stringfile to edit- find*
stringthe literal string to find- replace*
stringthe replacement- count
integercap replacements
Glob match · returns paths sorted lexicographically.
- pattern*
stringe.g. ./src/**/*.rs- exclude
- a glob pattern or a list of them to drop from the result
Recursive regex search · returns {path,line,match} sorted by (path,line).
- pattern*
stringRE2-class regex- path
stringroot to search (default .)- case_insensitive
boolean
Read a file · returns its text (or opaque bytes with binary: true).
- path*
stringfile path- binary
booleanreturn opaque bytes (default false)
Write a file · returns the path. overwrite defaults true · create_dirs defaults false.
- path*
stringdestination path- content*
stringthe content to write- overwrite
boolean- create_dirs
boolean
pure JSON/data transforms — no I/O
Convert between json·yaml·toml·csv (from/to · identity rejected).
- input*
- the data (string for text formats)
- from*
stringjson|yaml|toml|csv- to*
stringjson|yaml|toml|csv- has_header
booleanCSV only (default true)- formula_guard
booleanCSV only · prefix formula-triggering cells (=+-@) with ' against spreadsheet injection · default false (alters data)
Timestamp arithmetic · op-discriminated (now|add|subtract|format|parse|diff) · strftime grammar · ISO 8601 out.
- op*
stringnow | add | subtract | format | parse | diff- tz
stringIANA timezone (now · default UTC)- base
stringISO 8601 base (add/subtract)- duration
stringISO 8601 span like PT1h (add/subtract)- input
stringthe timestamp to render (format) or the text to read (parse)- format
stringstrftime grammar e.g. %Y-%m-%d (format/parse)- start
stringISO 8601 (diff)- end
stringISO 8601 (diff)- unit
stringseconds (default) | milliseconds | minutes | hours | days | weeks (diff)
Content hashing · blake3 (default) | sha256 | sha512 · hex (default) or base64.
- content*
stringthe content to hash- algo
stringblake3 | sha256 | sha512- encoding
stringhex | base64
Run a jq expression over input · THE data-transform language (map·filter·select·reshape). Emits exactly one value.
- expression*
stringthe jq program- input
- any JSON value (or an array for multi-input ops)
JSON diff · returns an RFC 6902 JSON Patch.
- before*
- the original value
- after*
- the new value
RFC 7396 merge patch (null deletes a key) over a target object.
- target*
object- patch*
object
- nika:uuiddata
Generate a UUID · v7 (default · sortable) or v4 (random).
- version
stringv7 (default) | v4
Validate data against a JSON Schema · returns {valid, errors} (invalid data is a report, not a failure).
- data*
- the value (or a YAML string with format: yaml)
- schema*
- a JSON Schema
- format
stringjson (default) | yaml
network egress (permits.net-gated)
- nika:fetchnetwork
HTTP request + content extraction · returns the extracted body (non-2xx is an error). SSRF-defended.
- url
stringthe URL- method
stringGET (default) | POST | PUT | DELETE | PATCH | HEAD- headers
objectstring map · auth rides here: { x-api-key: "${{ secrets.KEY }}" }- body
- request body (objects auto-JSON) · at most one of body/form/multipart
- form
objectapplication/x-www-form-urlencoded scalar fields · POST/PUT/PATCH only- multipart
arraymultipart/form-data parts · {name, value} text or {name, path, filename?, content_type?} file (path is permits.fs.read-gated · ≤32 MiB total) · POST/PUT/PATCH only- traverse
objectbounded same-origin crawl · { max_pages: 1..=25 (required), respect_robots?: bool (default true) } · GET only · excludes mode/selector/jq/body/form/multipart · emits { url, page_count, pages[], assets } page digests- mode
stringmarkdown (default) | article | text | selector | jq | metadata | links | feed | sitemap | raw- selector
stringCSS selector (mode: selector only)- jq
stringa jq expression (mode: jq only · the one data language)
Send a notification · v0.1 engines support the webhook channel.
- channel
stringwebhook (v0.1) | slack | email | discord | sms (gated)- target*
stringthe webhook URL- message*
stringthe alert text- severity
stringinfo (default) | warn | error- data
- optional structured context (any JSON · rides the payload beside the message)
the workflow looking at itself
Statically check a Nika workflow draft you wrote · returns the full `nika check` verdict as JSON (conformance + secret-flow + permits + the termination/cost certificate) · NEVER executes it. Iterate until valid, then deliver the draft. Agent loops only.
- workflow_yaml*
stringthe complete workflow YAML draft
Introspect the running workflow · view: cost | records | dag_info | threads.
- view*
stringcost | records | dag_info | threads
images, audio, charts — assets, not blobs
Render a DETERMINISTIC chart artifact from rows + a semantic spec (bar | line | area_band | scatter | heatmap) — byte-identical SVG saved at `out`, sha256 in outputs (the trace-chain receipt) · optional Vega-Lite sibling via compile_to. Pure compute + one permit-gated write: no network, no clock, re-runs are idempotent.
- data*
stringrows · array of flat objects (strings + numbers) · or { path: <json file> }- semantics
objectfield → usd | duration_ms | tokens | count | delta | percent | timestamp | category (drives formatting + palettes · delta ⇒ diverging anchored 0)- chart*
object{ type, x, y, y_lo?, y_hi? (area_band bounds), y2? (actual overlay), color? (series split · heatmap value), title?, width?, height? } — x/y/… are field names- out*
stringartifact path ending .svg (fs-permit gated · parents created · idempotent)- compile_to
stringvega_lite — also writes the .vl.json sibling next to the svg
Apply deterministic artistic effects to a PNG (dither · palette · duotone · pixelate · halftone · grain · vignette · chromatic_aberration · scanlines · glitch · ascii) — byte-identical forever for identical input+args; the recipe rides the artifact (tEXt) and outputs carry path + sha256, bytes never inline.
- input*
stringsource PNG path (read · permit-gated fs.read · PNG v1: produce upstream via image_generate format png)- out*
stringoutput artifact path (.png · .txt/.ans for ascii text/ansi emits) — rides the declared permits.fs boundary- ops*
arrayordered single-key op maps · resize{width,height,filter} · crop{x,y,width,height} · levels{brightness,contrast} · grayscale · palette_map{palette} · dither{mode,palette} · duotone{dark,light} · pixelate{block} · halftone{cell,angle} · grain{intensity} · vignette{strength} · chromatic_aberration{shift} · scanlines{strength,period} · glitch{line_shift,channel_shift,blocks} · ascii{cols,emit} (ascii must be last)- seed
integerstochastic-op seed (grain · glitch) · default 0 · the seed IS the style
Generate image assets (local compat servers · openai gpt-image-2 · gemini gemini-3.1-flash-image · xai grok-imagine-image · mock for offline runs) — saves files under output_dir and returns paths + dimensions + sha256 (+ a provenance manifest); image bytes never ride outputs.
- provider
stringlocal | openai | gemini | xai | mock (inferred from model: when omitted · local is never inferred)- model
stringprovider model id · defaults: stablediffusion (local · LocalAI convention) · gpt-image-2 · gemini-3.1-flash-image · grok-imagine-image · mock-image-1- prompt*
stringthe creative brief the provider renders- mode
stringgenerate (default · text→image) | edit (source image(s) + instruction)- image
stringmode:edit · one source image PATH (read · permit-gated fs.read)- images
stringmode:edit · source image PATHS (multi-ref · capped per provider)- mask
stringmode:edit · optional pixel-mask PATH (openai/local only · refused elsewhere)- n
integervariant count 1..=10 (gemini runs n sequential calls)- aspect_ratio
string1:1 | 16:9 | 9:16 | 4:3 | 3:4 | 3:2 | 2:3 | 21:9- size
stringexact WIDTHxHEIGHT (gpt-image-2 arbitrary /16 sizes · gemini folds to a size class) or auto — an exact size wins over aspect_ratio- quality
stringauto (default) | low | medium | high | ultra (folds to high on openai · model-tier on gemini)- format
stringpng (default) | jpeg | webp — magic bytes are the authority on what lands- compression
integer0..=100 · jpeg/webp only (openai output_compression)- background
stringauto (default) | transparent (needs png/webp and a supporting model) | opaque- seed
integergemini best-effort · openai has no seed (warned + dropped)- reference_images
arraymedia roadmap — rejected loudly in V1- provider_options
objectvetted pass-through · openai {moderation, user} · gemini {thinking_level, image_size} · xai {user, resolution}- output_dir*
stringdirectory the assets land in (rides the declared permits.fs boundary)- filename_prefix
stringfilename stem (else metadata.page_slug, else `image`) — sanitized, traversal-free- save
booleanV1 contract: stays true — assets land on disk, never inline- manifest
booleanwrite the provenance manifest JSON beside the assets (default true)- metadata
objectfree provenance fields (campaign · page_slug · locale …) echoed to output + manifest- timeout_ms
integerper-request deadline · default 180000 · 1000..=600000- debug
booleanecho the sanitized raw provider response (base64 stripped)
Synthesize speech audio (local compat servers · openai gpt-4o-mini-tts · elevenlabs · mock for offline runs) — saves ONE audio file under output_dir and returns path + format + sha256 + duration (+ a provenance manifest); audio bytes never ride outputs.
- provider
stringlocal | openai | elevenlabs | mock (inferred from model: when omitted · local is never inferred)- model
stringprovider model id · defaults: tts-1 (local · LocalAI convention) · gpt-4o-mini-tts · eleven_multilingual_v2 · mock-tts-1- text*
stringthe text to speak · ≤4096 chars (fan long scripts out with for_each)- voice
stringprovider voice · defaults: alloy (openai/local) · Rachel's id (elevenlabs) · sine (mock)- format
stringmp3 | wav | auto (default · provider-native · the saved extension follows the bytes)- speed
number0.25..=4.0 (openai/local · warned-dropped elsewhere)- output_dir*
stringdirectory the audio lands in (created if missing · fs-permit gated)- filename_prefix
stringfilename stem (default: metadata.page_slug, else `speech`)- manifest
booleanwrite the sidecar provenance manifest (default true)- metadata
objectfree-form provenance echoed into output + manifest- timeout_ms
integerper-request cap · default 120000 (local 300000) · max 600000
A missing required arg is a nika check finding before anything runs — the engine teaches its own vocabulary. Try one in the playground, or install and ask the binary itself: nika tools. Read the spec →