Skip to content

n-dx 0.8.0 — Find your way ​

All six packages move 0.7.2 → 0.8.0.

Status: the release lane is complete; two gate items remain — see Release gate.

What changed ​

One container for project state ​

State lived in three root dot-directories (.rex/, .hench/, .sourcevision/) and five loose .n-dx* files. 0.8.0 introduces a single .ndx/ container and one resolver, resolveLayout in @n-dx/llm-client, that decides which layout a project is on: a .ndx/ directory selects the new one, its absence the legacy one. An un-migrated project is not misconfigured and nothing warns.

  • ndx init writes the .ndx/ layout for new projects.
  • ndx migrate-layout moves an existing project when the operator chooses: snapshot, git mv the tracked paths so history follows, move the untracked state, rewrite the .gitignore/.gitattributes blocks, verify — or restore.
  • The per-user directory becomes ~/.ndx/ with NDX_HOME as the override; ~/.n-dx/ and N_DX_HOME are still read as fallbacks.
  • .mcp.json stays at the repository root (the vendor CLIs read it there) and task claims stay in the git common directory.

A reorganised dashboard ​

Views are now stages. Analysis opens on the isometric codebase map, with stat tiles and a collapsible Next Steps panel beneath it; Plan opens on a one-row Smart Add bar; Terrain and Architecture are tabbed sections; Home leads with a next-step panel. Stage pages fit any viewport, phones included.

Scattered settings views were consolidated onto a shared frame with an explicit Save, an unsaved-changes indicator and a leave prompt:

PageReplaces
Robot Wrangler (/robot-wrangler)LLM Provider
Workflow (/workflow)work settings, CLI timeouts, templates
Project (/project)analyze/plan settings, feature flags, Notion, integrations

Robot Wrangler reports what ndx work will actually run — vendor, provider, model, and which setting supplied it — and says why when that combination would be refused. Model fields are dropdowns over a live catalog read from the vendor's models API when a key resolves, with a built-in fallback otherwise.

The breadcrumb links back to the hub and, with two or more projects registered, switches between them. The hub chooser has a stable address at /hub.

Live ​

A new Live tab watches every running hench run and long job across all worktrees of a repository, including runs started from a terminal. /live/task/:taskId gives a running task its own page: elapsed time, turn, tokens and tokens per second, model and heartbeat, each progress event as it is written, and Copy link, Mark stuck and Stop. A machine strip shows agent slots, free memory against the hub floor, worktree count and spend. The 5-minute stuck-run rule now lives in one place, so the bottom bar, runs health, audit and Live agree.

Security ​

Loopback is shared by every account on a machine, and a checkout can carry execution config of its own. 0.8.0 addresses both:

  • Per-user token. ndx start creates <ndx home>/auth.token (owner-only) and the hub, dashboard and preview servers require it on every request and WebSocket handshake — as Authorization: Bearer, X-Ndx-Token, or the ndx_token cookie the printed URL sets once. HTTP MCP registrations need the header. --no-auth or web.auth: false turns it off.
  • Repository trust. Until you accept a checkout's execution config (ndx trust accept), runs use the default guard — the repository can tighten it but not widen it — and bypassPermissions is lowered to acceptEdits. ndx init ends with a review of what the checkout shipped; unattended inits never trust automatically. The dashboard shows a strip until it is accepted.
  • Credential redaction. Run records and logs are redacted before they are persisted or shown, and child processes the agent starts get an environment stripped of credential-shaped variables (guard.env.allow / guard.env.deny adjust it).
  • The Host header is validated on every hub, dashboard and preview request.

Models ​

Claude defaults have changed. The standard tier — and the default when no model is configured — is now claude-sonnet-5-5; the heavy tier and the review model are claude-opus-5-5. The opus alias resolves to claude-opus-5-5 and fable to claude-fable-5-1. All three have 1M context and list pricing, so budget preflight, ndx usage and the spend views price them as known.

llm.effort is now actually sent on Claude API requests as output_config.effort; it was parsed but never sent. claude-opus-5-5 defaults to high so the move from Opus 5 keeps its reasoning depth. Effort is never sent to a model that rejects it.

If an older Claude Code release rejects the new model ids on CLI-provider runs, upgrade it or pin the previous model with ndx config llm.claude.model claude-sonnet-5 . (and llm.tiers.claude.heavy / llm.claude.reviewModel for the heavy tier and review).

Per-vendor agent models ​

hench.model is deprecated and ignored. ndx work resolves its model from --model, then hench.models.<vendor>, then the llm.* fields.

Claude settings resolve per field ​

The legacy top-level claude.* keys now resolve against llm.claude.* one field at a time, through a single implementation shared by the CLI, the dashboard and the footer. The fallback used to be block-level, so a modern llm.claude block holding one field discarded every legacy field beside it — a project that set claude.api_key once and later pinned llm.claude.model silently lost the key. Writes go to llm.claude.* only; existing claude.* values stay where they are and are still read until 1.0.0.

Command transparency ​

Every ndx command declares its effects — what it reads and writes, which phases call a model and how often, what network it touches, how long it takes. ndx help --effects --format=json prints the declarations and GET /api/commands/manifest serves them.

Interactive analyze, plan and recommend print a preflight banner from those declarations before the command starts — with a pause the operator can shorten (NDX_PREFLIGHT_PAUSE_MS) or skip (--yes) — and a run summary afterwards: files written, calls, tokens, cost. Cost appears only when it is known; an unpriced model or a provider that reported no usage shows "not recorded" rather than $0.00.

PRD storage ​

rex tree-diff --json diffs two PRD trees; rex ready marks items ready when they have an automated or metric requirement and no open blocker; items carry an assignee and ndx work --mine respects it. Whole-tree PRD rewrites are refused off the default branch without --allow-on-branch.

New configuration keys ​

Seven keys are new — absent from the 0.7.2 schema, not merely unlisted:

KeyWhat it does
web.authRequire the per-user dashboard token on the hub, dashboard and preview servers. On unless set to false.
hench.models.<vendor>Agent-only model for claude, codex, google or local. Set in .n-dx.json (.ndx/config.json on the new layout) or from Robot Wrangler, not through hench config.
hench.guard.env.allowCredential-shaped environment variables to pass through to child processes anyway.
hench.guard.env.denyAdditional environment variables to strip from child processes.
hench.batchMaxAgeHoursHow old a batch session may get before it is retired.
hench.batchMaxIdleHoursHow long a batch session may sit idle before it is retired.
hench.guard.memoryMonitor.spawnThresholdMemory headroom below which the guard stops spawning.

hench.model still parses, so existing configs keep loading, but it is ignored.

A further 32 keys became visible without becoming new: hench config listed 21 at 0.7.2 and lists 56 now. The schema already accepted them — they worked if you hand-edited the config file, and were invisible if you did not.

Redirects ​

Every path merged into a stage stays a registered view and redirects to it. The table lives in packages/web/src/shared/view-routing.ts as VIEW_ALIASES.

Old pathRedirects to
overviewanalyze
rex-dashboardwork
llm-providerrobot-wrangler
hench-config, cli-timeouts, hench-templatesworkflow
project-settings, feature-toggles, notion-config, integrationsproject

An alias fires only when its target is valid for that viewer: a rex-scoped standalone viewer has no work stage, so rex-dashboard keeps rendering as its own page there rather than redirecting nowhere.

Dependencies ​

The dependency audit is clean on the release tree — zero findings at every severity. Transitive packages are held at safe floors through pnpm.overrides in the root package.json.

Release gate ​

  • [x] Lane A — A1 through A8 and A6b merged.
  • [x] Dashboard navigation and settings — B4 (#456), B5 (#458), B6a (#469), B6b (#482), the breadcrumb work (#471) and the icons (#506) merged.
  • [x] Documents, navigation contract and wireframe comparison — B7 (#508).
  • [ ] The flaky ci child-cleanup e2e test, deferred until all A and B PRs are in.
  • [ ] After publish: confirm one git tag and one GitHub release per package.

Verified for this note ​

Measured on the merged tree at #508, not carried forward from an earlier draft:

  • 120 changesets, 0 problems — every one scoped, every one with a real body; 177 patch entries and 6 minor.
  • changeset status computes to minor for all six packages.
  • The redirect table is read from VIEW_ALIASES, and the new-key list is a schema diff against the @n-dx/core@0.7.2 tag — neither from changeset prose.

Released under the Elastic License 2.0.