One agent loop.Every step in view.

NAH is a small TypeScript runtime and CLI. Bring an AI SDK model, follow streamed tool calls, and set clear limits on what the agent can do.

Get started
Open source · Node.js 20.6+ · AI SDK v5 See how it works

[01 // THE LOOP]

A model call. A tool call. A clear next step.

NAH owns the loop around the model: one streamed response per step, real tool execution, then an explicit check against the run limits.

max 32 steps by defaulttyped async eventsabortable
How the loop works
example event stream
illustrative

HarnessRun HarnessEvent stream

Consume events while the run is in progress. The final promise returns the text, stop reason, usage, and transcript.

01

run-start

stepBudget · tokenBudget

02

step-start

step: 1

03

tool-call

toolName · input · call ID

04

tool-result

capped output · isError

05

step-finish

cumulative usage

finish.reasonfinish.usageresult.messages
explicit loop · streamed events your runtime

[02 // TOOLS & PERMISSIONS]

A small toolset. Boundaries you can set.

Six focused tools cover the coding loop. Read operations stay available; mutating operations can pause for approval or be disabled.

Default coding tools

read · list · grep · edit · write · bash

YOU SET THE POLICY
01 / 03

Inspect

read · list · grep

Find context with bounded file reads, directory listings, and content search.

bounded output
02 / 03

Change

edit · write

Require read-before-write by default. Gate changes with an approval callback.

bounded output
03 / 03

Execute

bash · optional

Run workspace commands with a timeout. Disable bash when a task should stay read-only.

bounded output
read/list/grep ungatededit/write/bash callback-gated · CLI defaults to ask
askreadonlyyolo

[03 // CONTROL]

Native to your terminal. A runtime you can compose.

The CLI and TypeScript SDK are the product. Run in your project, choose a supported model provider, and consume the same explicit event stream.

local workspace · optional Blaxel sandbox
~/projects/atlas — nah
src/agent.ts
import { runAgent, buildSystemPrompt,
createCodingTools } from "@astracollab/not-another-harness";
import { createNodeEnvironment } from
"@astracollab/not-another-harness/node";

const run = runAgent({
model, // AI SDK v5 LanguageModel
prompt: "fix the session refresh edge case",
system: buildSystemPrompt({ cwdLabel: process.cwd() }),
tools: createCodingTools(
createNodeEnvironment(process.cwd()),
),
maxSteps: 32,
});

for await (const event of run.events) {
console.log(event.type, event);
}

$ nah --permissions ask "fix the session refresh edge case"

› tool: read src/auth/session.ts

› streamed response · step 1

! edit src/auth/session.ts — allow? [y/N/a]

Changes wait for your approval.

NAH · Node.js 20.6+ · AI SDK v5CLI + TypeScript SDK
[04 // RUN IT YOUR WAY]

Keep the loop small.
Keep control yours.

Install the CLI for a ready-to-use terminal workflow, or compose the TypeScript runtime into your own application.

Quickstart