Nika
DAG workflow runner for AI tasks with MCP integration.
┌─────────────────────────────────────────────────────────────────────┐
│ YAML Workflow → DAG Validation → Parallel Execution → Results │
│ │
│ Verbs: infer | exec | fetch | invoke | agent │
│ │
│ Features: for_each parallelism | MCP tools | TUI | Observability │
└─────────────────────────────────────────────────────────────────────┘
Quick Start
# Run a workflow
# Validate without executing
# Interactive TUI
Installation
# From source
# Binary location
v0.27.0 Features
- Language Improvements
exec.env- Environment variable injection for exec tasksfetch.json- Auto-serialize JSON body (sets Content-Type automatically)inputs.xxxreferences - Access workflow inputs inuse:blocks$inputsbinding - for_each accepts$inputs.itemsexpressions
- TUI Panels Module - TaskListPanel, TaskBoxFlow, BrowserPanel
- New Task Status -
TaskStatus::QueuedandTaskStatus::Skippedvariants - 6,086 tests passing (full regression coverage)
v0.22.0+ Features
- 4-View TUI Architecture - Studio, Runner, Chat, Settings
- Two-Phase IR - Raw AST → Analyzed AST pipeline
- spn Daemon Integration - Unified secret management
v0.15.0 Features
- Security Hardening: Shell-Free Execution (BREAKING)
exec:now defaults toshell: falsefor security- Command parsing via shlex (no shell injection)
- New error code:
NIKA-053 BlockedCommand
# Default: shell-free (v0.15.0) - id: safe_exec exec: "echo 'Hello World'" # Parsed via shlex # Opt-in shell mode for pipes/redirects - id: pipeline exec: command: "cat file.txt | grep pattern" shell: true - Infer LLM Control Parity -
temperature,system,max_tokenssupport- id: creative infer: prompt: "Generate tagline" temperature: 0.9 system: "You are a marketing expert" max_tokens: 100 - Gemini Provider (7th provider) -
RigProvider::gemini(), full streaming - File Tools (5 new builtin) -
nika:read,nika:write,nika:edit,nika:glob,nika:grep - 11 builtin tools total (6 core + 5 file)
Features
context: File Loading (v0.14+)
Load external files at workflow start:
schema: nika/workflow@0.9
context:
files:
brand: ./context/brand-guidelines.md
data: ./context/config.json
templates: ./context/*.yaml
session: .nika/sessions/previous.json
tasks:
- id: generate
infer: |
Using brand guidelines: {{context.files.brand}}
With data: {{context.files.data}}
include: DAG Fusion (v0.14+)
Merge tasks from external workflows:
schema: nika/workflow@0.9
include:
- path: ./partials/setup.nika.yaml
prefix: setup_
- path: ./partials/teardown.nika.yaml
prefix: teardown_
tasks:
- id: main_task
infer: "Main workflow logic"
depends_on:
flows:
- source: main_task
target: teardown_cleanup
Parallel for_each (v0.3+)
Execute tasks in parallel with for_each:
tasks:
- id: generate_all
for_each:
as: locale
invoke:
mcp: novanet
tool: novanet_generate
params:
entity: "qr-code"
locale: "{{use.locale}}"
Each iteration runs via tokio::spawn for true concurrency.
Agent with Tools
Autonomous multi-turn execution with MCP tools:
tasks:
- id: analysis
agent:
prompt: |
Analyze "qr-code" using NovaNet tools.
Use novanet_describe and novanet_traverse.
Say "DONE" when complete.
mcp:
- novanet
max_turns: 8
stop_conditions:
- "DONE"
Semantic Verbs
| Verb | Purpose | Example |
|---|---|---|
infer: |
LLM generation | infer: "Summarize this" |
exec: |
Shell command | exec: { command: "echo hello" } |
fetch: |
HTTP request | fetch: { url: "https://..." } |
invoke: |
MCP tool call | invoke: { mcp: novanet, tool: novanet_generate } |
agent: |
Autonomous loop | agent: { prompt: "...", mcp: [...] } |
MCP Integration
Nika connects to MCP servers for tool calling:
schema: "nika/workflow@0.9"
provider: claude
mcp:
novanet:
command: cargo
args:
env:
NOVANET_MCP_NEO4J_URI: bolt://localhost:7687
Examples
| Example | Description |
|---|---|
v09-context-loading.nika.yaml |
context: field demo (v0.14+) |
v03-parallel-locales.nika.yaml |
Parallel generation for 5 locales |
v03-agent-with-tools.nika.yaml |
Agent-driven competitive analysis |
v05-lazy-bindings.nika.yaml |
Lazy bindings with defaults |
v05-spawn-agent.nika.yaml |
Nested agent spawning |
invoke-novanet.nika.yaml |
Basic MCP invoke |
agent-novanet.nika.yaml |
Agent with NovaNet tools |
Architecture
src/
├── ast/ # YAML → Rust structs
├── dag/ # DAG validation
├── runtime/ # Execution engine
│ ├── executor.rs # Task dispatch (5 verbs + for_each)
│ ├── runner.rs # Workflow orchestration
│ ├── context_loader.rs # context: file loading
│ ├── include_loader.rs # include: DAG fusion
│ └── rig_agent_loop.rs # RigAgentLoop with rig::AgentBuilder
├── mcp/ # MCP client (rmcp v0.16)
├── provider/ # rig-core provider (RigProvider wrapper)
├── event/ # Observability (22 event types)
├── binding/ # Data flow ({{use.alias}}, {{context.files.*}})
└── tui/ # Terminal UI (6 views, 39 widgets)
Commands
# Workflow execution
# Interactive modes
# Trace inspection
Testing
Test Breakdown (v0.27.0)
- 6,086 tests passing
- Zero clippy warnings
- Schema @0.11 validation in CI
ARMADA Quality System
Every contribution passes through the 10-station ARMADA checkpoint:
╔═══════════════════════════════════════════════════════════════════════════════╗
║ 🏴☠️ ARMADA — 10 QUALITY STATIONS ║
╠═══════════════════════════════════════════════════════════════════════════════╣
║ Station 1: 🔧 Format | Station 6: 🔒 Security ║
║ Station 2: 📎 Lint | Station 7: 📐 Schema Validation (v0.1-v0.9) ║
║ Station 3: 🧪 Tests | Station 8: 🧠 Claude AI ║
║ Station 4: 📊 Coverage | Station 9: 📝 Conventional ║
║ Station 5: 📖 Docs | Station 10: ⚓ Version Lock ║
╚═══════════════════════════════════════════════════════════════════════════════╝
Captain's Orders: Nika will NEVER be version 1.0.0. See CONTRIBUTING.md.
License
AGPL-3.0-or-later