@nifrajs/coding-agent
v5.4.0
Published
Standalone, extensible Nifra coding-agent host and CLI.
Maintainers
Readme
@nifrajs/coding-agent
Standalone, extensible Nifra coding-agent host and CLI.
The package provides nifra-agent in interactive, one-shot, JSON, and local
loopback RPC modes. It adds sessions, checkpoints, bounded compaction,
transactional TypeScript extensions, self-healing repair stages, workflows,
bounded subagents, and Nifra verification descriptors without changing Nifra's
framework runtime.
Extensions can register bounded workflows that are listed and run through the authenticated RPC surface. Capability manifests, project workspace policies, optional isolated-worktree leases, and a pre-activation syntax gate keep those customizations explicit and replaceable.
bunx nifra-agent --backend pi
bunx nifra-agent --backend pi --message "run the checks and explain failures"
bunx nifra-agent --backend pi --verify-after-turn check --max-repair-attempts 2
bunx nifra-agent --backend replay --replay ./session-events.jsonl --jsonWhen --verify-after-turn is enabled, a failed gate becomes a bounded repair turn: the host sends the failure diagnostics back to the agent, runs the gate again, and stops on success or after the configured attempt cap. Use --max-repair-attempts 0 for observe-only verification.
For embedding, use CodingAgentHost or CodingAgentRpcServer. The host keeps
live event queues bounded, filters verification subprocess environments, and
requires explicit local RPC authorization. Install this package only when an
application wants the agent product.
RPC failures return actionable bounded error messages by default. For a trusted
loopback debugger, set exposeErrorStacks: true (or pass
--expose-error-stacks to nifra-agent --rpc) to include bounded exception
stacks. This option is rejected for remote binding.
Each turn.send SSE frame carries id: <seq>. By default a client that disconnects cancels its
turn. With resumableTurns: true the turn keeps running: a client that comes back calls
turn.attach with { afterSeq } (or a Last-Event-ID header) to read the frames it missed and
follow the rest. A cursor older than the held frames (replayEvents, default 1024; replayBytes,
default 8 MiB) answers 409 resync_required, so read session.events instead; a second
turn.send while one runs answers 409 turn_running; and a turn no client has followed for
detachedTimeoutMs (default 2 minutes) is cancelled.
An approval, or a coding tool's question to the person, is denied once it has waited 5 minutes.
Pass approvals: { timeoutMs } to CodingAgentHost or CodingAgentRpcServer for up to 24 h, or
timeoutMs: "never" to keep it until it is answered, cancelled, its turn ends, or the session
closes; maxPending (default 32) still bounds how many can wait. NifraBackend has its own
approvalTimeoutMs, taking the same values, and the host denies in the backend whatever its broker
denies, so the shorter of the two applies. A never-expiring approval reports expiresAt as
APPROVAL_NEVER_EXPIRES_AT, which survives JSON and stays later than any Date.now().
nifra-agent loads .nifra/extensions/** from --cwd only when started with
--extensions. An extension module's top-level code runs as soon as it is
imported, before its declared capabilities are checked, so pass the flag only
for a repository you trust.
IsolatedExtensionWorker is an opt-in process-backed crash-containment seam for
extensions. It is not a hostile-code sandbox; use OS-level isolation before
loading code you do not trust.
NifraBackend is a small provider port for a future native backend. It accepts
an injected model implementation and bounded tools without importing a provider
SDK. The conversation it sends the model is capped by maxHistoryChars (default
1 MiB): past it, whole earlier turns are dropped, oldest first, and the current
turn is always sent in full. maxMessageChars (default 64 KiB) caps the message send accepts and
maxReplyChars (default 1 MiB) the model's reply; a reply longer than one event's text arrives as
consecutive assistant.message events, and a tool's event shows a bounded copy of its input while
the tool runs with all of it. ReplayBackend and readReplayEvents provide deterministic protocol
replays for CI and Workbench regression tests.
At-least-once run dispatch
@nifrajs/coding-agent/orchestration also exports an evidence-only run dispatch port and an adapter
over @nifrajs/jobs. Dispatch is at-least-once: a lease may be delivered again after worker loss or
lease expiry. Every logical node attempt receives a stable idempotency key derived from the plan,
run, node, and attempt boundary. Effects must provide a matching proof before recovery can settle a
completed boundary; an unproven post-effect failure is dead-lettered rather than guessed safe.
createMemoryRunDispatchStore() is disposable single-process test infrastructure. It makes no
durability, hosted-worker, retention, tenant-authorization, or exactly-once guarantee. Durable
operated adapters implement the exported RunDispatchStore and DurableDispatchAdapter ports in
their own data layer, including authorization, row policy, retention, reconciliation, and worker
health. The public package does not store prompts, model output, tool arguments, or job payloads in
its dispatch evidence.
Legacy FileSessionStore files remain supported for explicit local compatibility. Use
nifra-agent --migrate-session <id> --migrate-from <legacy-dir> --migrate-to <evidence-dir> to
create a separately validated, evidence-only target. The source is left untouched and the command
does not switch an active configuration pointer: after reviewing its report, point the host at the
new directory yourself. FileSessionStore reads the migrated rows as content-free entries whose
type is the stable event code, and new appends continue the sequence. To roll back, point it at the legacy directory again and remove the new
target; a failed or interrupted migration leaves the active choice unchanged.
For AI agents, see LLM.md and the full corpus
../../llms-full.txt.
