AGPL-3.0-or-later · forever.

the standard library

nika:wait

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
core6 tools

control flow and run-stream primitives

  1. nika:assertcore1 required

    Fail-fast guard: fail the task when condition is false (else no-op).

    condition*
    booleanthe resolved boolean to check
    message
    stringfailure message
  2. Mark the current agent loop complete (the loop-completion sentinel · agent loops only).

    result
    optional final value (any JSON)
  3. nika:emitcore1 required

    Emit a custom machine event for subscribers/journal (distinct from log).

    event_type*
    string^[a-z][a-z0-9_.-]*$
    payload
    any JSON value
  4. nika:logcore1 required

    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)
  5. nika:promptcore1 required

    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
  6. 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
file5 tools

workspace files — read, write, search (permits.fs-gated)

  1. nika:editfile3 required

    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
  2. nika:globfile1 required

    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
  3. nika:grepfile1 required

    Recursive regex search · returns {path,line,match} sorted by (path,line).

    pattern*
    stringRE2-class regex
    path
    stringroot to search (default .)
    case_insensitive
    boolean
  4. nika:readfile1 required

    Read a file · returns its text (or opaque bytes with binary: true).

    path*
    stringfile path
    binary
    booleanreturn opaque bytes (default false)
  5. nika:writefile2 required

    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
data8 tools

pure JSON/data transforms — no I/O

  1. nika:convertdata3 required

    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)
  2. nika:datedata1 required

    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)
  3. nika:hashdata1 required

    Content hashing · blake3 (default) | sha256 | sha512 · hex (default) or base64.

    content*
    stringthe content to hash
    algo
    stringblake3 | sha256 | sha512
    encoding
    stringhex | base64
  4. nika:jqdata1 required

    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)
  5. nika:json_diffdata2 required

    JSON diff · returns an RFC 6902 JSON Patch.

    before*
    the original value
    after*
    the new value
  6. nika:json_merge_patchdata2 required

    RFC 7396 merge patch (null deletes a key) over a target object.

    target*
    object
    patch*
    object
  7. Generate a UUID · v7 (default · sortable) or v4 (random).

    version
    stringv7 (default) | v4
  8. nika:validatedata2 required

    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
network2 tools

network egress (permits.net-gated)

  1. 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)
  2. nika:notifynetwork2 required

    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)
introspection2 tools

the workflow looking at itself

  1. nika:composeintrospection1 required

    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
  2. nika:inspectintrospection1 required

    Introspect the running workflow · view: cost | records | dag_info | threads.

    view*
    stringcost | records | dag_info | threads
media4 tools

images, audio, charts — assets, not blobs

  1. nika:chartmedia3 required

    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
  2. nika:image_fxmedia3 required

    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
  3. nika:image_generatemedia2 required

    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)
  4. nika:tts_generatemedia2 required

    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 →