nversa
v0.1.21
Published
Agent-first task orchestration with a local CLI and web UI
Readme
nversa
nversa is an agent-first task orchestration tool for local-first workflows:
- a Next.js web UI + API for streams/tasks/dispatch
- a CLI (
nversa) for local startup and health checks - Node.js/TypeScript orchestration for agent turns (
src/cli/turn/, entrypoint:scripts/agent-turn.mjs)
Quickstart
Prerequisites
- Node.js 20+
- npm
sqlite3CLI (ships with macOS; install via your package manager on Linux)
Local development (SQLite — default)
npm ci
npm run build:cli
node dist/cli/index.js start # starts SQLite API on :3000 + worker loopnversa start automatically creates .nversa/local.db, initialises the schema,
and launches the SQLite-backed API server. No external database is required.
To also run the Next.js web UI (for the dashboard), start it on a separate port:
npm run dev -- --port 3001 # Next.js UI proxies /api/* to the SQLite API on :3000CLI usage (local package)
npm run build:cli
node dist/cli/index.js --help
node dist/cli/index.js init --target-dir ~/code
node dist/cli/index.js start --host 127.0.0.1 --port 3000
node dist/cli/index.js status --url http://127.0.0.1:3000
node dist/cli/index.js scm-poller --project <name> --loop --interval 300Local-only scope
nversa currently targets local-only operation (SQLite + local worker lane). Cloud/Postgres deployment paths are intentionally out of active scope.
nversa init now scaffolds local LLM integration files in the target directory:
.nversa.local.jsonskills/nversa-local/SKILL.mdCLAUDE.md
Global npm install
npm install -g nversa
nversa --helpFor local tarball testing before publish:
npm pack
npm install -g ./nversa-<version>.tgzBuild, lint, test
npm run lint
npm run test
npm run build:allCI
GitHub Actions workflow: .github/workflows/ci.yml
It runs:
npm cinpm run lintnpm run testnpm run build:clinpm run build- blocking Docker SQLite E2E harness (
scripts/docker-e2e.sh) withNVERSA_PROVIDER=mock
Docker SQLite E2E harness
The Docker harness validates local-only orchestration with a deterministic mock provider and a SQLite database file (no Postgres service).
Run:
scripts/docker-e2e.shWhat it does:
- Starts a single nversa container.
- Initializes local SQLite schema (
scripts/setup-sqlite-db.sh). - Packs and installs
nversaglobally inside the container. - Starts local SQLite API runtime and validates health (
nversa status). - Initializes
.nversa.local.jsonfor a test project. - Creates a local git repo and seeds one stream/task via API.
- Runs one
scripts/agent-turn.shiteration end-to-end withmockprovider. - Verifies task completion, mock artifact creation, git commit output, and SQLite task state.
Agent turn orchestrator
The orchestration loop (scripts/agent-turn.sh) has been migrated from bash
to TypeScript (src/cli/turn/). The bash script is now a thin compatibility
wrapper that delegates to scripts/agent-turn.mjs, which loads the compiled
code from dist/cli/turn/.
Entrypoints
| Path | Description |
|------|-------------|
| scripts/agent-turn.mjs | Node.js entrypoint (primary) |
| scripts/agent-turn.sh | Compatibility wrapper — calls agent-turn.mjs |
| scripts/agent-turn-legacy.sh | Original bash implementation (preserved for reference) |
Running a turn
npm run build:cli # compile TypeScript first
scripts/agent-turn.sh --project <name> # or: node scripts/agent-turn.mjs --project <name>agent-turn is the worker lane (next-task + heartbeat). SCM maintenance now runs in a dedicated poller lane:
scripts/scm-poller.sh --project <name> --loop --interval 300All original flags are preserved: --full, --loop, --speculative,
--timeout, --max-iterations, --poll-interval, --project/-p,
plus positional max_depth and max_agents.
nversa start can launch both lanes:
- worker lane:
--worker/--worker-poll-interval - SCM poller lane:
--scm-poller/--scm-poll-interval - per-PR poll cursors are persisted in
.nversa/scm-poll-state-<project>.json(override withNVERSA_SCM_POLL_STATE_FILE)
Architecture
The TypeScript implementation lives in src/cli/turn/:
| Module | Purpose |
|--------|---------|
| config.ts | Arg parsing + .nversa.local.json loading |
| sessions.ts | /tmp/nversa-sessions.json tracking |
| dispatch.ts | Pure task-selection functions (normal, full, speculative) |
| agent-turn.ts | Main orchestrator loop |
| index.ts | Re-exports + main() entry |
Provider execution still delegates to task-wrapper.sh and
run-intelligence-provider.sh via child processes (no Claude SDK dependency).
Provider run logs are persisted per invocation under
.nversa/logs/provider-runs/ (with latest-<task-short-id>.log symlinks for quick lookup).
Intelligence provider selection
Default behavior remains claude-code.
For local/CI runs you can select the deterministic mock provider:
NVERSA_PROVIDER=mock scripts/agent-turn.sh --project <name>You can also set provider in .nversa.local.json:
{
"defaults": {
"intelligence_provider": "mock"
}
}Stop and clean up:
docker compose -f docker-compose.e2e.yml down --volumes