# shipped components
| component | language | purpose |
|---|---|---|
| core | nim | conversation loop, supervisor, catalog, dispatch |
| session | nim | one conversation = one process — an ephemeral per-conversation runner that resumes from the store; killing one loses only the in-flight turn |
| bash | nim | shell access as a tool — approval-gated, process-tree cancellation on stopped turns, oversized output spilled to disk and paged with read |
| builder | nim | compiles agent-written source → binary |
| store | nim | document store over the bus (rev-based optimistic concurrency) — swappable engines behind one contract: barrel (default), SQLite and TiDB/MySQL, picked with NIF_STORE_BACKEND |
| plugins | nim | component ecosystem: topic search, niffler.json packages, install/update/remove — always built from source |
| skills | nim | Agent Skills discovery, progressive-disclosure loading, resources, managed install/remove, and skill_audit (unmerged on-disk inventory) |
| systemprompt | nim | the conversation constitution as a component — session runners ask svc.systemprompt.call once per conversation; replace it to replace the prompt |
| fetch | nim | bounded HTTP(S) retrieval with methods/headers/body, Trafilatura-first HTML extraction, pure-Nim fallback, and large-result file spill |
| edit | nim | the file tools — pageable read, batched read_many, exact-match edit with a guarded fallback cascade, atomic write, single-level undo; an unchanged full re-read returns a compact [unchanged] marker instead of re-dumping bytes (force or an offset/limit window opts out), edit refuses with E_STALE when the file changed since this conversation last saw it, and seen-state is tracked per (session, file); mutations approval-gated |
| grep | nim | ripgrep-backed content search and sorted repository file listing, with exact truncation markers |
| git | nim | read-only repo inspection — status/diff/log/show/blame, approval-free, fixed argv, path-scoped to the harness root; review_receipt — a local diff-fingerprint write/check pair for pre-push review handoff |
| observe | nim | live bus introspection — subject discovery, listen probes, request/reply traces, monitoring |
| logfile | nim | durable JSONL sink for ev.log.* — rotating logs, bounded search, retention |
| hooks | nim | operator shell commands on selected bus events (ev.session.turn, ev.log.>) — payload as JSON on stdin, observe-only, env-configured, off by default |
| models | go | models.dev provider/model catalog over the bus — offline seed, cached refresh, x-models-source plugin patches |
| provider | go | store-backed LLM provider registry — add/list/switch/active/remove/export/import, live backend switching, subscription OAuth logins with transparent token refresh; provider_models probes the provider's own /models for live model ids |
| llm | go | streaming OpenAI-compatible adapter (DeepSeek by default) — live ev.llm.token deltas, reasoning tokens, per-call cancellation |
| mcp | go | external MCP servers (Model Context Protocol) as bus components — store-backed registry with approval-gated mcp_add/mcp_edit/mcp_remove (every add/edit validated through one real connect), mcp_search over the official MCP Registry, and ${ENV} secret references resolved from the harness environment at connect time so tokens stay out of the store; a server's tools become ordinary catalog tools reachable through discover + invoke |
| mcp-bridge | go | one supervised process per MCP server (official Go SDK; stdio / streamable HTTP / SSE) — lazy sessions that idle out, a stdio guard so servers never outlive the harness, mid-flight cancellation, tool-contract drift persisted + bridge restarted so discovery stays truthful, prompts as slash commands, resources as one read tool, results over 64 KiB spilled to files |
| fabric | nim | programmable tool calling — the LLM writes a Nim program that owns the intra-turn control flow; typed wrappers with catalog pinning, a named program library, host-backed batch calls, approval manifests, and correlated ev.fabric.* lifecycle events — plus run-tested worked examples and a bundled reference doc that ship with the component |
| agent | nim | subagent sessions — synchronous agent_run delegates to a child runner with fresh context; durable background jobs (agent_spawn/status/wait/stop/steer) survive restarts; idle runners retire on their own |
| expert | nim | the advisory peer — follows one or more working sessions concurrently, LLM-judges bounded per-session observations (the judge prefix embeds the bundled niffler-tools/niffler-fabric/niffler-harness skills), delivers high-confidence steer as a marked message; silent by default, fail-closed |
| dialog | bash | a component in pure bash — dialog_show/dialog_ask desktop dialogs (zenity → notify-send → log fallback) spoken with only the nats CLI + jq, no SDK, no compile step |
| cli | nim | drive the harness from a script: catalog/wait/call/install — the CI front door for plugin repos; installs confirm against core's accepted catalog, not raw registration announcements |
| console | nim | bus viewer — renders every envelope on stdout (follow along in a second terminal) |
| nats | go | the bus server itself, built from source — components/nats compiles the official nats-server into var/bin/nats-server; core prefers that binary over a PATH install, so make build alone satisfies the bus dependency, and the bundled build runs with an 8 MiB payload cap (upstream default 1 MiB) so whole-conversation LLM requests fit |
| ui | go + svelte 5 | the desktop chat UI — sessions, streaming tokens, tool runs, approvals, model controls · Wails-hosted SPA, architecturally a NATS client |
| your tool | any | port the SDK — the envelope is the artifact (~200 lines) |
# status
- ✓ wire spec, envelope, Nim + Go + TypeScript SDKs
- ✓ supervisor, catalog, dispatch
- ✓ bash + builder + store + llm (streaming adapter)
- ✓ agent adds itself a tool end-to-end (live, with DeepSeek)
- ✓ persistence of shape across restarts
- ✓ session service + Wails SPA shell
- ✓ session runners — one conversation = one process
- ✓ approvals — terminal y/N, directed UI requests with ack + broadcast fallback, headless deny, resolved-event cleanup
- ✓ recover mode —
make recover - ✓ plugins — component ecosystem (discover, install, update, remove)
- ✓ skills — progressive discovery and loading of Agent Skills
- ✓ fetch — bounded web retrieval with Trafilatura-first text extraction
- ✓ edit — read/edit/write/undo file tools (hashline-edit extracted to the niffler-hashline plugin)
- ✓ grep + git — repository search and read-only Git inspection
- ✓ console + cli — follow and drive the bus from a terminal
- ✓ streaming — live
ev.session.tokendeltas in the UI - ✓ UI: components panel, tool-run view, light/dark theme, About dialog
- ✓ bus-contract test suite —
make test, isolated per-test NATS + temp root - ✓ tty admin shell — help/status/catalog/tools/sessions, no chat in the REPL
- ✓ observe + logfile — live bus introspection, durable rotating JSONL logs
- ✓ models — models.dev catalog over the bus, catalog-driven context windows
- ✓ provider — store-backed LLM provider registry, live switching
- ✓ UI-owned harness lifecycle — the desktop icon is the whole system: build once, the desktop UI autostarts core, the last interactive client stops it
- ✓ minimal boot profile —
--minimalstarts only store, bash, and llm while preserving skipped records - ✓ provider/model controls — stored providers, model selection, context meters, and live session status
- ✓ progressive tool discovery — immutable per-session direct tools, discover/invoke gateways, and Live Components exposure state
- ✓ fabric — programmable tool calling: LLM-written Nim programs in a VM-embedding executor, calling bus tools from inside the guest
- ✓ subagent sessions — delegated child runners with fresh context, summaries returned to the caller
- ✓ slash commands — declarative
niffler.jsonregistry for UIs, checkpointed in the store - ✓ thinking effort — per-conversation
reasoning_effort(ctrl+g), streamed reasoning rendering in the TUI - ✓ cancellation — per-call LLM cancel and the TUI's two-stage stop (ESC, ESC)
- ✓ UI + TUI localization — en/zh/zh-TW locales, CJK-safe truncation and editing
- ✓ session_info — the LLM introspects its own conversation: model, effort, context occupancy, message counts
- ✓ systemprompt as a component — the conversation constitution is replaceable over the bus
- ✓ bundled skills — the repo's skills/ tree ships with the harness as a shadowable, non-removable scope
- ✓ mid-turn steer — inject a message into a running turn (
svc.session.<id>.steer) - ✓ expert advisory peer — one LLM-judged advisor following one or more sessions concurrently: bounded observations, turn-bound steer, fail-closed silence
- ✓ subscription OAuth — ChatGPT Plus/Pro and Claude Pro/Max sign-in with transparent token refresh
- ✓ durable agent jobs —
agent_spawn/status/wait/stop/steerover store-backed records; real stop cancellation, lazy budgets, stale-job recovery - ✓ fabric typed mode — catalog-pinned typed wrappers, named program library, approval manifests with digest-keyed auto-approval, bounded batch calls
- ✓ batch effect declarations —
x-harness.effect: reads run concurrently, writes exclusively - ✓ lifecycle events + activity strip — correlated
ev.fabric.*/ev.agent.*on the bus, rendered live in the console and the desktop UI; artifact retention sweeps - ✓ SWE-bench Verified pilot — 10 sympy instances graded by the official Docker harness across niffler/pi/opencode; 2.3–2.9× fewer tokens per task
- ✓ bash hardening — process-tree cancellation for stopped turns; oversized output spills to a temp file and is paged with
read - ✓ subagent budgets — per-job
maxCalls/maxTokenscaps freeze into the child conversation - ✓ prompt-cache economics —
cacheHitTokens/cacheHitRatioon every session status event,⚡ NN% cachedper message in the UI - ✓ LLM auto-retry — transient failures (429/5xx/timeouts) retried with exponential backoff, announced per attempt
- ✓ parallel tool waves + process replicas — independent calls fan out; stateless components can run
replicas: N(grep ships ×4) - ✓ live model ids —
provider_modelsprobes the provider's own/models; ids merge into the catalog as anx-models-sourcepatch - ✓ prompt diet — lean baseprompt + trimmed tool descriptions, pure JSON Schema to the LLM (first prompt −31%, cache reads −35%)
- ✓ hooks + operator tools —
hooksruns shell commands on bus events (opt-in);prompt_preview,doctor,review_receipt,skill_auditfor inspection and handoff - ✓ dialog — a component in pure bash:
dialog_show/dialog_askdesktop dialogs via zenity/notify-send - ✓ store engines — barrel (default), SQLite and TiDB/MySQL behind NIF_STORE_BACKEND; one bus contract, identical tools
- ✓ bundled bus server —
make buildcompiles the official nats-server intovar/bin/nats-server; core prefers it over a PATH install - ✓ bundled skills niffler-tools + niffler-harness — which tool to reach for, and how to operate the running harness
- ✓ authoritative cli installs —
cli installconfirms registrations against core's accepted catalog, not raw registration announcements - ✓ one clone = one instance — the home bus is claimed only for this root (the catalog carries
root+gitHash), yielded loudly to a foreign core;NIF_NATS_SPAWN=1forces an isolated bus; parent-death cleanup so no child outlives its harness - ✓
make install/make uninstall— niffler, niffler-cli, niffler-console on PATH (+ the niffler-tui wrapper on request,WITH_TUI=1); only niffler-prefixed names, never component binaries, so PATH cannot shadow unix tools - ✓ bench expansion — DeepSWE (Datacurve) port (113 long-horizon tasks, 5 languages), the niffler-bench Docker job image, and a guided launcher; latest full matrix green across all lanes (340/340)
- ✓ 8 MiB bus payload — the bundled nats-server runs with a raised max_payload (upstream default 1 MiB), so chat requests carrying whole conversations fit large context windows
- ✓ external MCP servers — the mcp manager plus one supervised bridge per server: the server's tools, prompts and resources become catalog tools (prompts as slash commands); lazy sandboxed sessions, mid-flight cancellation, contract-drift restarts, ${ENV} secret references resolved from the harness environment, registry search, and an MCP manager panel in the web UI
- ✓ tool profiles + explicit discovery — named profiles resolve into a conversation's frozen direct toolset,
invoke {sticky: true}promotes a discovered tool durably, and/components,/discoverand/profile(plus the Components-panel filters) expose catalog state without an LLM turn - ✓ bench mid-tier tasks t18–t27 — ten spec-fidelity tasks targeting 2–10 min/cell added after the core 17 saturated; the launcher accepts task names and the verifier exec bit is fixed; first calibration niffler vs pi 20/20
- ✓ prompt economy round two — tool descriptions serialized once (
function.description),filesmoves on demand besidegrep: the frozen prompt prefix dropped 2479 → ~1540 tokens (−38%) - ✓ file-tool seen-state —
read/read_many/write/edittrack a per-(session, file) digest of the bytes the conversation last observed: unchanged full re-reads answer[unchanged],editrefusesE_STALEwhen the bytes changed since then - ✓ bench syn-large — first full27 run on Synthetic's GLM-5.3-Flash (thinking=low): both lanes 27/27 in round 1, avg 73 s niffler / 74 s pi per cell (
bench/reports/full27-syn-large-low-report.md) - ✓ bench fan-out tier — the suite is now full30 (t01–t30): three tasks whose mechanical work varies per item or carries oversized intermediates — package doc backfill across 27 files, 36 log files (~450 KB) rolled into a byte-exact summary.json, 24 modules migrated to a new API — where a single
sedfails and per-file turns burn the budget; bench-validated with syn-large, the high tier reaches for fabric
- ✗ Level 1 UI dynamism (x-ui schema hints)
- ✗ store FTS + vector memory (the TiDB engine landed; search comes later)