nxsflow

The nxs open-source suite

The record your agents work from.

One binary, three products — flow, memory, and chat — on a single offline-first CRDT substrate. Agent-native, deterministic, convergent.

$ curl -fsSL https://nxsflow.com/nxs/install.sh | sh
macOS & Linux · Apple Silicon and x86-64 · signed, same-origin updatesnxsflow/nexus-flow

One binary, three products

What is inside the suite

One binary carries all three. Install it once; each workspace then activates only the products it actually needs.

nxf

flow

the record

Issues, epics and the dependencies between them. ready, blocked and next are derived from the graph on every query — never stored, so the work list cannot go stale.

nxm

memory

the knowledge

Durable project facts under stable keys — a fact is evolved in place instead of duplicated, and replayed into every session that needs it.

nxcIn the binary today — its guides follow with 1.0

chat

the conversation

Agent-to-agent messaging over the same change-log, so a team of agents coordinates without scraping each other's output.

See it work

next and blocked — derived, not stored

nxf — agent session
$ nxf next
0001  P1  open  [epic]  Payments revamp
0002  P1  open  [feature]  Design new checkout flow
    ↳ 0001 · Payments revamp

$ nxf blocked
0003  P2  open  [chore]  Migrate billing webhooks
    ↳ blocked by: 0002 (open)

$ nxf next --json[{"archived":null,"assignee":null,"belongs_to":null,"closed_at":null,"closing_comment":null,"completion_criterion":null,"created_at":"2026-06-23T00:00:00Z","defer_until":null,"deleted":null,"description":"Rework the payments stack for v2.","design":null,"due":null,"id":"ab12.0001","parent":null,"priority":"1","priority_label":"P1","status":"open","title":"Payments revamp","type":"epic","type_label":"epic","updated_at":"2026-06-23T00:00:00Z"},{"archived":null,"assignee":null,"belongs_to":"ab12.0001","closed_at":null,"closing_comment":null,"completion_criterion":null,"created_at":"2026-06-23T00:00:00Z","defer_until":null,"deleted":null,"description":"One-page checkout with saved cards.","design":null,"due":null,"id":"ab12.0002","parent":{"id":"ab12.0001","title":"Payments revamp","type":"epic","type_label":"epic"},"priority":"1","priority_label":"P1","status":"open","title":"Design new checkout flow","type":"feature","type_label":"feature","updated_at":"2026-06-23T00:00:00Z"}]
$ 

Real output captured from nxf and drift-guarded in CI: the ready work, the work the graph holds back, and the same query as --json.

Why it's built this way

An engine agents can trust

01

Offline-first by default

Everything lives in a local database, so reads and writes are instant and keep working when the network is gone.

02

Convergent CRDT sync

Each change is appended to a change-log, never overwritten. Concurrent edits from different devices merge without last-write-wins data loss.

03

Derived, never stored

ready, blocked, and next are computed deterministically from the dependency graph — so the work list is always consistent, never a stale cache.

04

Plugin-declared vocabulary

Item types, ranking, and presentation live in plugins — an issue tracker and a personal to-do ship in the box; you can declare your own.

05

--json everywhere

A deterministic, byte-stable machine surface on every command — the contract agents build on, and the measuring stick for the whole CLI.

06

One binary, one substrate

flow, memory, and chat share one local database, one sync, and one change-log — so an agent's plan, its memory, and its messages converge as one truth.

Changelog

What's new

0.66.0

2026-08-24
  • Added**`nxf next` reads like a list a person can scan — and can be cut without lying about it.** On a real terminal the ticket title is bold, the one field you actually look for and the one that used to weigh exactly as much as the id in front of it; the id and the `↳` epic line are muted; and the priority is coloured along a single ramp from Deep Ember through Ember and Flame down to graphite, so the weighting is visible without reading the label. The ramp maps the canonical priority ORDINAL rather than its name, so it is just as right under a plugin that calls its levels now/soon/later. `nxf next --limit <n>` shows only the head of the list and never cuts silently: a truncated list is headed `showing 15 of 180`, and under `--json` the flag wraps the records as `{"items": [...], "total": 180}`, so a consumer reads the true total instead of inferring it from the array's length. The limit applies last, after `--sort` and after `--label`, so a filtered list discloses how much of your filter you are seeing. Without `--limit` the command is unchanged and complete, and its `--json` payload is still the same bare array. Nothing else changes: `--json`, a pipe, CI and an agent's `prime` context still receive the same plain ASCII, byte for byte, with no escape sequences at all, and `NO_COLOR` / `TERM=dumb` keep the weight while dropping the colour.
  • Added**`nxm guide` — memory has documentation now.** Five guides, in English and German, shipped inside the binary and published to the docs page: an introduction, the core concepts (keys and auto-keys, category/reach/references, the retrieval rule that decides where a memory is read, reading order, the reversible tombstone), the complete command reference with every `--json` shape, the `memory_*` MCP tools and what `nxs prime` contributes, and how to bring an existing Claude memory store in. Until now `nxm` had `--help` and nothing else.
  • Added**`Engine::withdraw`** — an embedding app can take back a commission that is still parked behind the working copy, the same narrow case `nxc withdraw` covers. The seam already handed out `queue_position`/`queued_behind` on a send receipt ("not started, 3rd in line") with no call to answer them; this closes that.
  • Changed**A session can no longer end owing an answer without anybody noticing.** One that ends without answering its thread is given its turn back and reminded — once, naming the thread, both ways to end a turn, and any round it commissioned that is still open — before the sidecar posts anything in its name. Most answer then. One that is reminded and ends silent again is handed back as an escalation, so `escalated: true` on `nxc status` tells the caller that no result exists and somebody has to decide. An escalation is now recognisable in the text the receiving session reads FIRST, on all three paths it can travel (a channel's pass-through, a 1:1 resume, a quorum wake): what it is, that the working copy is held while it stands, and what is expected in return — the flag alone did not help, because an agent reads the message that woke it, not `nxc status`. And every session that owes a reply is told in its system prompt that its turn must end in exactly one of two ways, `nxc reply --thread <id> "<result>"` or `nxc reply --thread <id> --escalate "<what is in the way>"`; that obligation reaches even a persona declared `prime: false`, so a declaration cannot leave out the one rule the engine depends on.
  • Changed**The board says what it is waiting for.** `nxc status` gains two operation-level flags: `needs_decision` (somewhere under this root a task was handed back and nobody took it up — read it beside `awaiting_human`, which looks identical and means the opposite) and `holds_working_tree` (the working copy is held somewhere below, so you know whether to go looking at all). `nxc tick` now distinguishes a settled round whose only remaining blocker is a live session, reporting `waiting_for_a_session` instead of `not_due` — the difference matters, because nothing re-checks that one on a clock and this verb is the way out. And a round whose every commission was withdrawn no longer counts as an open operation: `nxc withdraw` discharges the thread you named as well, instead of leaving it waiting for a supervisor whose round had just been taken away.
  • Fixed**A step that claims the working copy exclusively now ends when its session's process ends, not when its reply arrives.** A member of a `flow: sequential` channel that answered and kept working used to let the next step start into the same checkout: measured in a real run, a coder replied at 00:16:33 and went on editing until 00:34:27, while the next step had been running since 00:16:36. Sessions now report their own end — `nxc session ended`, called by the agent sidecar's teardown, and `Engine::session_ended` for a host that runs its own runtime — and where that announcement never arrives, the worker's process check answers the next time anything asks. **Nothing re-checks it on a clock:** a channel's declared `timeout:` is a deadline for an *answer*, and a member that has replied has answered, so a lost announcement (a sidecar killed before its teardown, an older `nxc`, a host runtime that never wires `Engine::session_ended`) leaves the round waiting until somebody runs `nxc tick --thread <id>` — which now says exactly that instead of "nothing to do". That teardown is itself bounded now, a five-minute reminder round and a thirty-second timeout on every `nxc` call it makes, because it runs inside the very process whose exit an exclusive channel is waiting for: one call that never returns holds a checkout, not merely a process. Channels without an exclusive working-copy claim are unchanged.
  • Changed**For anyone embedding nexus-flow as a Rust library: this jump is purely additive — pin the new tag and change nothing.** Across the whole span the three consumed surfaces (`nexus-flow-facade`, `nexus-chat`, `nexus-memory`) only gained: `Engine::withdraw` takes back a commission still parked behind the working copy; `Engine::session_ended` lets a host that runs its own agent runtime announce a session's end, with `Worker::session_is_running` as the fallback answer where it never arrives; `StatusOperation` carries the two new operation-level flags; and flow's read layer gained `truncate_next` with its `NextPage` result, the one mechanism behind `nxf next --limit` and `prime`'s own truncation. Nothing was removed, renamed or re-typed — `cargo-semver-checks` confirms it against v0.63.0 for all three packages. The one thing worth wiring while you are here is `Engine::session_ended`: without it, a channel step that claims the working copy exclusively falls back to the process check and waits for someone to run `nxc tick`. Read the per-version entries on the releases page for the exact shape of each step.

0.63.0

2026-08-22
  • Added**`nxc` — your agents talk to each other.** This is the headline of everything since 0.35.0. You declare who your agents are and where they talk, in `<project-root>/.nxs-personas/`: one YAML per persona (prompt, model band, tools, who it may address) and a `channels.yaml` for the rooms they meet in. Then there are two verbs. `nxc send --to <persona|channel>` opens a conversation and starts whoever is on the other end; `nxc reply --thread <id>` answers one. Everything else — who is waiting, what was said, where an operation stands — is read, not typed.
  • Added**A channel is a declaration, and the declaration is the workflow.** Write down its members and it fans out to them; add `expects:` and it waits for a quorum; add `timeout:` and a silent member releases the round instead of holding it forever. `on_complete:` decides what the requester gets back — every answer as it stands, or one folded summary. `flow: sequential` turns the member list into an order, so a channel IS a workflow: same declaration, one step at a time. A channel can also be `public` — a project's front door, readable and addressable across project boundaries.
  • Added**`nxc status` — where an operation stands.** An operation is a thread tree now: your question, the round it opened, the round that round opened. `nxc status` reads that tree from its root down, across every channel border, and says per thread who still owes an answer, whether a window has run out, and which session is working on it. `awaiting_human` marks the one place a person has to act. Whoever opened an operation can also read every message in it, whatever channel an agent opened along the way.
  • Added**One chain per working copy.** A persona or channel that declares `working_tree: exclusive` gets sole use of the repository checkout and build directory for as long as its task runs; a second chain that would collide waits instead of running its build against the same target directory. The protection is derived, not repeated: declare it on the persona that builds, and every channel that persona is a declared member of counts as needing it too.
  • Added**Two things an agent may say besides an answer.** `nxc reply --escalate "<why>"` is "I cannot carry this out" — it ends the turn, is never folded into a summary, and travels one level up instead of dying at the round it was said in. And `nxc withdraw --thread <id>` takes back a commission that is still waiting for the working copy: nothing has started, so nothing is lost.
  • Added**Agent sessions leave a transcript, and it is bounded.** Every role session's normalized stream — assistant text, thinking, tool calls and their results, and any subagent activity — is readable with `nxc transcript show <session>`. Transcripts are device-local and never synced, and they are kept for 30 days after a session's last write, so they stop growing forever.
  • Added**Guides, offline, in the binary.** `nxc guide`, `nxm guide` and `nxf guide` each serve their block's own narrative documentation — what it is, what you type, what you declare, and what constrains it — with `nxs guide` reading the whole suite at once. No network, no browser. Every command shown in them is executed against the test corpus, so a guide cannot show an invocation that does not exist.
  • Added**Project memory is a file now.** `NEXUS_MEMORY.md` at the workspace root is a generated projection of the `nxm` store, so the context survives for a reader without nexus-flow installed — change it with `nxm remember` / `nxm forget`, never by hand, and `nxm doc --check` reports drift. Memories carry a category, a reach (this workspace or everywhere), the board items they are about and a reading order, and `nxs prime` hands them to a session in that order instead of alphabetically. `nxm migrate` moves a workspace off a hand-maintained `CLAUDE.md`.
  • Added**Sync runs by itself, and it can run on your own Postgres.** `nxs sync daemon` keeps every bound workspace in sync continuously instead of on demand, and `nxs sync bind` no longer needs `--create` or `--join` — run it with no flags and it derives the stream id deterministically. The `nxf-relay` in every release archive can now use a Postgres, Supabase included, so you can host the bus yourself.
  • Added**An application can embed all of this.** The chat engine's handle carries the role runtime, not just messaging: an app opens one handle for its lifetime and reads and writes through it, with the same derivations and the same rejections the command line has — a differential test compares the two seams byte for byte. A host can also bring its own agent runtime instead of the bundled one, which is how a remote or containerised executor docks on.
  • Changed**Declarations live in `.nxs-personas/` now**, not in `roles/`. Who your agents are and where they talk is one folder at the project root: one YAML per persona plus `channels.yaml`. Nothing reads the old folder any more.
  • Changed**`nxc` has one way to start a conversation and one way to answer it.** `send --to` opens a thread and always starts a fresh persona session; `reply --thread` posts into an existing one and continues the session it already has. The call decides, not the declaration. The per-call options that used to sit beside them — `--kind`, `--priority`, `--disposition`, `--model`, `--deadline` — are gone: what a message is, and how long a round may wait, is declared once on the channel rather than re-answered on every call.
  • Changed**The release notes answer "does this change the library contract?".** Every entry that touches a consumed surface carries an explicit `facade:` verdict — `changed` or `breaking` — and the notes render a dedicated Facade Contract section for it. An embedding consumer can decide re-review versus fast-track from the feed instead of from a diff.
  • Removed**The `nxc workflow` command group is gone, and so is the run engine behind it.** `workflow start`, `step done`, `status`, `list` and `liveness` no longer exist, and neither does the stored run record. A channel declares its flow now and `send --to <channel>` starts it; `nxc status` is where an operation's position is read. What has no successor is the step-liveness watchdog — a named loss, not an oversight.
  • Removed**A channel is a declaration now, or it is nothing.** The verbs that minted or addressed an undeclared channel are gone: `nxc ask` and the whole `nxc channels` group (`create`, `dm`, `join`, `leave`, `list`, `public`). Declare the channel and use `send --to <name>`; the declaration carries who is asked and what is expected, which is exactly what `ask --expect` and `channels create` used to say per call. The channel declaration key `member_session` is gone too — the call decides when a persona is continued.
  • Removed**The old delivery origin `nxf.nxsflow.com` is switched off for good.** Downloads, `install.sh` and `nxs self-update` all run against `https://nxsflow.com/nxs`. An installation that still points at the old host cannot update itself and has to be re-installed once from the current install command.
  • Fixed**Two processes on one workspace no longer lose each other's writes.** The logical clock two `nxs` invocations advance in parallel is now correct under concurrency, so a write made while another process was writing is not silently dropped. Ops can also no longer be written with a blank author: an unset actor is refused rather than recorded as nobody.
  • Fixed**A round now ends when it really ended.** The reply that completes a board is the one that actually completed it, a reply settles the turn it answers rather than the thread's whole life, and a step whose window ran out in the middle of an ordered flow no longer stalls everything behind it. A long-running agent no longer runs out of spawn depth just for holding a conversation, and a declared channel that finishes at the same moment its timer fires no longer starts two summarizers for one round.
  • Fixed**An agent session starts, stays single, and does not lose its answer.** On macOS every spawned persona session used to die at authentication; it now starts. One internal session runs exactly one process — a wake arriving while that session is still working is refused and reported instead of starting a second agent in the same working directory, where the two overwrote each other's edits. A session that dies at an error is machine-readably distinguishable from one that answered, and a failed transcript write no longer costs the turn.
  • Fixed**Sync finishes what it started.** A pull no longer ends a pass because a page came back empty or shorter than asked for — it ends when the relay says there is no more. A stream id containing `/`, `#` or `?` used to produce a 404 or a silently truncated id instead of syncing. And the relay now carries envelope fields it does not itself understand, so a newer client and an older relay keep working together.
  • Changed**For anyone embedding nexus-flow as a Rust library: this is a breaking jump, and it is one migration, not twenty-eight.** The chat engine's handle settled on a small, deliberate surface — seven reading verbs, two writing ones, and the role runtime flat beside them — and the per-call context now carries only who is calling. Declarations are read from the workspace folder rather than injected. Concretely, over this whole span: the worker seam changed shape, `Engine::ask`/`channel_open`/`role_trigger`/`role_resume`/`send`/`reply` and ten reads were removed or replaced, `RoleDecl.address_book` became an `Option`, `channel::declared_visibility` folded into `declared_policy`, and `timer::AtTimer` stopped being a unit struct. Pin by git tag, migrate once, and read the per-version entries on the releases page for the exact shape of each step.

0.35.0

2026-07-29
  • Added`nxf recap` — a recall view of what you finished most recently (newest close first, archived closes included), with `--limit` (default 10), `--since <date>`, and `--json`. The same recency view now also appears as a "Recently Closed" section in `nxf prime`, so a fresh session sees at a glance what was just completed. Distinct from `nxf closed` (the lane, archived excluded), which is unchanged. Facade: adds `read::recap()` (the shared recency query — full, uncapped records), the shared `read::truncate_notes` / `read::recap_note` note helpers, and a `recently_closed` field on `PrimeReport` (its `--json` gains a matching `recently_closed` array). The new `PrimeReport` field is a breaking change for exhaustive struct literals — an embedder constructing `PrimeReport` directly must add the field; reading it needs no change.
  • Added`nxs mcp install` now recognises **Amazon Quick** (the renamed Amazon Q Developer) as an install host, writing the shared `mcpServers` entry to its global config at `~/.aws/amazonq/mcp.json` — auto-detected like the other hosts, or targeted explicitly with `--host amazon-quick`. A **multi-workspace registry** (`~/.nexusflow/workspaces.toml`) lets an MCP host discover boards by name instead of path: `nxs mcp install --workspace <path>` registers the pinned workspace, the new `list_workspaces` tool (and the `nxs mcp workspaces` command) return the deterministic `{name, path}` list, and a host feeds a listed path back through any tool's per-call `workspace` override — selecting another board without knowing where it lives.
  • Added`nxc` gains the role runtime: `roles/*.yaml` declarations, `send --role`/`reply` that spawn a real Claude Agent SDK session (Node sidecar) as the consequence of a message, ambient caller resolution, an internal session-id map, and follow-up-question resume — so a role can ask back without the task running dead.
  • AddedAgent transcripts: what a role session actually did is now recorded and readable. Until now only a role's finished **messages** were kept — the reasoning, the tool calls and their results, and everything a delegated subagent did along the way were consumed and thrown away the moment the session ended, so a surprising answer could never be traced back to how it came about. Every role session's full agent transcript is now captured as it runs and stored durably: assistant text, each tool call with its result, and — the part that usually goes missing — the complete sub-timeline of every subagent the role spawned, nested under the step that spawned it. Read it back with `nxc transcript show <session>` as an indented timeline, or as JSON for tooling; the same view is available in-process to apps embedding nexus-chat. Transcripts stay on the machine that produced them (they describe a local session, so they are never synced to peers and never bloat the shared log), and a transcript flushed mid-run still shows everything it has rather than hiding partial evidence. Two long-form fields are shortened on the way in so one turn cannot dominate the record: a thinking block is kept up to 4000 characters and a tool result up to 8000, each ending in a marker naming how much was cut. Everything else — including a tool call's own input, however large — is stored whole. One honest limitation: the model's **extended thinking** is not part of the transcript yet. The recording side is built and will pick it up the moment it becomes available, but the Claude Agent SDK does not currently hand reasoning blocks to a program driving it the way nexus-chat does, so today a transcript shows what the agent did and said, not what it was reasoning.
  • ChangedA workspace can now declare **multiple named workflows** at once: alongside the legacy single `roles/workflow.yaml`, any number of additional workflows may live under `roles/workflows/*.yaml` (each file's own `name:` must be unique across the whole set). `nxc workflow start` gains a real `--name` selector: with exactly one workflow declared it stays optional and defaults to it, exactly as before; once more than one is declared, `--name` is required, and both an omitted name and an unknown one fail with a validation error listing every available name. `nxc prime`/`nxs prime` now lists every declared workflow under the plural `workflows` JSON key (replacing the old singular `workflow` key) and validates each one independently — a broken workflow is excluded from the roster rather than taking the whole session down, same as roles and channels already worked. A workspace with only the legacy `roles/workflow.yaml` and no `roles/workflows/` directory keeps working completely unchanged, with no `--name` flag required — this back-compat guarantee is covered by a dedicated regression test.
  • Added`nxf show <id>` now appends a loud, verbatim notice at the very end of its output when the item has parent(s): "This item has the following parents: <ids>. URGENT RECOMMENDATION: ALSO READ THESE ITEMS TO GET THE COMPLETE PICTURE!!!" — a nudge so an agent reading a child ticket also pulls the parent (often an epic) that carries the spec, global constraints, and design context the child assumes. Computed once in the engine/facade read layer (`ShowRecord::parents` + `parents_notice`), so the human `nxf show`, `--json` (`parents`/`parents_notice`, sparse — present only when the item has parent(s)), and every other consumer (MCP, embedders) render the identical text. Scoped to belongs-to/containment `parent` edges only, not `contributes_to`.
  • AddedRole Runtime v2: roles are automatically primed with correct `nxc` usage and their own job description, so a trigger message carries only the task, never the role prompt; `send --role <handle>` auto-opens the DM with a peer and mints a fresh session, no manual `channels dm` step; a role's own nested `send --role` reliably reaches the sidecar across multiple hops; a YAML-declared team workflow with per-transition validation prompts drives a PM/coder loop with no hard-coded orchestration; and a 4-role review quorum (general + code quality/test quality/ integrity) wakes the PM only once every reviewer has replied, via the existing thread-quorum machinery. Role sessions now also run with `settingSources: []` (SDK isolation hardening): a spawned role ignores the operator's/project's own `.claude/` plugin, skill, and hook configuration, so its behavior depends only on its own role YAML.
  • AddedRole Runtime v3: `nxc` becomes the orchestrator. A new declared **channel** primitive is typed group communication — who's expected to reply, whether replies stay visible only to the requester or to all members, and a one-shot timeout — and `nxc` now actually **fans out** a channel invocation to every declared member (minus the sender), closing the v2 gap where a role could only declare who should reply, never trigger them, which is what caused the "PM opens the board and waits forever" deadlock. A channel's completion either delivers the raw replies as-is (`pass_through`) or spawns an ephemeral synthesizer session that reads all the replies and posts one summarized verdict (`summarize`), so no role has to summarize a pile of replies by hand. On top of that sits an explicit **workflow orchestrator** (`nxc workflow start`/`step done`/`status`/ `tick`): a declared step graph with branching and looping transitions and a hard cycle cap, so a team's control flow is owned by `nxc` itself instead of being scattered as prose across role prompts; each step can resume a role's prior session or start a fresh one, so a role reappearing later in the same run picks up where it left off when the step calls for it. The example coding team (PM/coder/4-role review quorum) has been hardened with a per-reviewer merge verdict and anti-rubber-stamp review discipline. All of it was verified end-to-end with real (not mocked) Claude Agent SDK sessions. Hardened after an independent pre-PR review: `nxc workflow step done` now verifies the caller is actually the role bound to the run's current step (a `channel:`-target step can only complete via its own quorum/synthesis, never a direct call), the workflow-run return address is checked against the engine's own record of which thread it opened rather than trusted as a bare string, a declared `visibility: requester_only` channel is now genuinely enforced on `nxc threads show`/the embedding facade (it used to be validated and stored but never applied), the `summarize` synthesizer's prompt now delimits the untrusted collected replies and its outcome token is parsed from the last matching line, a stale reply can no longer re-advance an already-advanced run, and a malformed channel declaration (e.g. `summarize` with no `summary_prompt`) is now rejected at the point of use instead of silently degrading.
  • Added`nxf-relay` can now be pointed at DynamoDB as a durable storage backend, alongside the existing SQLite and Postgres options. Build with `--features dynamodb` and set `NXF_RELAY_BACKEND=dynamodb`; `NXF_RELAY_DDB_TABLE` / `NXF_RELAY_DDB_REGISTRY_TABLE` name the (externally provisioned) ops and prefix-registry tables — both default so nothing is strictly required — and `NXF_RELAY_DDB_ENDPOINT` / `NXF_RELAY_DDB_REGION` override the endpoint and region, e.g. for DynamoDB Local or a self-hosted setup.

0.30.0

2026-07-17
  • AddedEmbedding API: the long-lived engine handle now exposes `closed_value`, `deferred_value`, `archived_value`, and `blocked_value` — the `closed`/`deferred`/`archived`/`blocked` lanes as the same canonical `--json` records the CLI emits, each carrying the sparse plugin-`custom` map (and `blocked_value` its open `blockers` list). A new `custom_fields_bulk` returns the declared `custom` map for many ids in one read, for joining custom onto row sets the handle does not project itself (notably `prime`'s `next` list). In-process consumers can now mirror the full `--json` custom coverage without an N+1 per-item read.
  • Changed`nxf prime`'s "Finding work" command index now lists `nxf deferred` (open, unblocked work with a future defer date). The lane was documented only in the Core Rules prose, so an agent that scans the command index never saw it. The entry also surfaces the event-vs-date practice: defer needs a real date — to wait on an event or delivery, use a `WAIT:` chore that dependents depend on (see `nxf guide deferring-and-waiting`), not a placeholder defer date.
  • AddedRead surface: item `--json` records (`show`, `list`, `next`, and the `blocked`/`deferred`/`closed`/ `archived` lanes) now carry `created_at` and `updated_at`, derived from the op-log — present when the write stamped a timestamp. Worklog notes gain a `created_at` too (in `show --json` and `note list --json`), and the human `show`/`note list` views print each note's date. The canonical record keys are unchanged; the new fields ride additively, so a consumer that ignores them is unaffected.
  • Changed`nxf update <id> --set defer=` (an empty value) now CLEARS an optional field. Previously `defer=` and `due=` were rejected outright (the date validator refuses an empty value) and there was no unset, so the only way out of the deferred lane was to set a stale past date; `assignee=` was accepted but silently stored an empty string rather than clearing. Now `defer=`, `due=`, and `assignee=` all unset the field. Validated fields like `status`/`priority` still reject an empty value.
  • ChangedThe default install and self-update origin moved to the nxsflow.com brand domain: `install.sh`, `nxs self-update`, and the `@nexus-flow/mcp` npx runner now fetch signed artifacts from `https://nxsflow.com/nxs` (previously `https://nxf.nxsflow.com`). The `NXF_BASE_URL` override is unchanged, and every artifact is still verified fail-closed (sha256 + minisign) from the same origin it was resolved on. Nothing to do on upgrade — this release is published to both the old and the new delivery chains during the migration window, so already-installed clients update onto the new endpoint over their existing chain automatically.
  • Changed`next` now recommends finishing over starting. The ranked list is grouped into three tiers on top of the unchanged plugin ranking: first the started work you can close right now (an in-progress item whose children are all closed, or a claimed leaf), then each started epic as a header row with its open children grouped beneath it, and finally the general ready backlog. Within every tier your plugin's `next` policy still decides the order, so priorities are unchanged — only the grouping is new. Two long-standing annoyances go away with it: a finished-but-still-open epic no longer vanishes from the list, and the children of an epic you already started no longer scatter across the backlog. Started work is now **always** part of `next`, so the `--include-in-progress` flag is gone — drop it from scripts and aliases (`nxf next --include-in-progress` → `nxf next`). Use `--sort id` (or any explicit `--sort`) when you want the old flat, ungrouped order. `nxs prime` shows 15 instead of 7 recommendations, so a started epic with many children is not truncated mid-cluster. Embedding apps (facade contract, breaking): `read::next`, `Engine::next` and `Engine::next_value` drop their `include_in_progress` parameter — call them without it to get the same set, now tiered. The MCP `flow_next` tool drops the `include_in_progress` parameter too; an older client that still sends the field is tolerated (the field is ignored, not rejected). Each `next` row keeps its resolved `parent` join, so a board can group by the epic header row or by each child's `parent`.

0.27.0

2026-07-14
  • Changed`nxs mcp serve` with no `--workspace`/`--db` now defaults its auto-initialized board to a neutral, nxs-owned location (`com.nxsflow.nxs` under the platform data dir) instead of a specific consumer app's data home. The OSS server no longer assumes any consumer; a consumer that wants its own board installs its own `--workspace`-pinned MCP entry (and may import this board's data). If you relied on the previous default location, point the entry at it explicitly with `--workspace`.
  • AddedMore `--json` reads now carry the same additive fields the primary reads already do, for cross-verb agent consistency: `blocked` and `search` gain `priority_label`/`type_label`, `next`'s nested `parent` join gains `type_label`, and `blocked`/`deferred`/`closed`/`archived` plus `prime` now carry the sparse plugin `custom` field map (identical to `list`/`next`/`show`). Canonical fields are unchanged; all additions are additive and appear only where relevant.

In production

Powered by nexus-flow

Two products bundle the suite invisibly and put their own surface on top.

Get started

Install the suite

One artifact to install, verify, and update — signed and same-origin. Detects your platform and drops nxs (with nxf/nxm/nxc) on your PATH.

macOS (Apple Silicon) · macOS (Intel) · Linux (x86-64) · Linux (aarch64)

Documentation

Guides for the whole suite — getting started, core concepts, the command reference, plugins. The same documentation the CLI serves, so the two never drift apart.

Read the docs