
Security News
Re-Enabled GitHub Actions Expose Thousands of Repositories to Mini Shai-Hulud
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.
> **This is an internal package of [`@n-dx/core`](https://www.npmjs.com/package/@n-dx/core).** Install `@n-dx/core` instead — it includes this package and registers all CLI commands.
This is an internal package of
@n-dx/core. Install@n-dx/coreinstead — it includes this package and registers all CLI commands.
PRD management and implementation workflow CLI. Rex maintains a structured product requirements document as a tree of epics, features, tasks, and subtasks, then exposes that tree to both humans (CLI) and AI agents (MCP server) so work gets tracked from planning through completion.
npm install -g @n-dx/core
# or
pnpm add -g @n-dx/core
# or
yarn global add @n-dx/core
rex init myproject
rex add epic myproject --title="Authentication"
# note the ID printed, e.g. abc-123
rex add feature myproject --title="Login UI" --parent=abc-123 --priority=high
rex status myproject
rex next myproject
rex init [dir]Create .rex/ in the target directory with skeleton config, empty PRD, execution log, and default workflow.
rex init # current directory
rex init /path/to/project
Idempotent -- re-running on an existing project is safe.
rex add <level> [dir]Add an item to the PRD. Level is one of epic, feature, task, subtask.
rex add epic --title="Payments"
rex add feature --title="Checkout Flow" --parent=<epic-id> --priority=high
rex add task --title="Validate card" --parent=<feature-id> --description="Luhn check"
Features require an epic parent, tasks require a feature parent, subtasks require a task parent.
Flags: --title (required), --parent=<id>, --description, --priority=<critical|high|medium|low>, --status=<pending|in_progress|completed|deferred|blocked>, --format=json
When you use smart add (rex add "..." or rex add --file=...) and accepted proposal nodes match existing PRD items, rex shows:
Duplicate matches were detected in the selected proposals.
Choose action: c=cancel / m=merge with existing / p=proceed anyway
Duplicate action (c/m/p):
Cancel flow:
rex add "Add OAuth callback handler" .
# Duplicate action (c/m/p): c
# -> Cancelled. No items were created.
Merge flow:
rex add "Improve OAuth callback handling and retry behavior" .
# Duplicate action (c/m/p): m
# -> Matched existing items are updated
# -> Only non-duplicate nodes are created
Proceed anyway flow:
rex add "Add OAuth callback handler" .
# Duplicate action (c/m/p): p
# -> Duplicate nodes are still created
# -> New duplicate-created items persist override metadata
Input safety: empty or invalid duplicate action input defaults to cancel.
When you choose p (proceed anyway), each force-created duplicate item gets an overrideMarker object in .rex/prd.json.
When you choose m (merge), matched existing items record mergedProposals entries in .rex/prd.json.
Where this appears:
rex status tree output shows [override: <reason>] next to items that have overrideMarker.rex status --format=json includes:
overrideMarker fields on affected itemsoverrideMarkers summary block (totalItems, overrideCreated, normalOrMerged, items)rex update <id> [dir]Update an existing item.
rex update <id> --status=completed
rex update <id> --priority=critical --title="New title"
Flags: --status, --priority, --title, --description, --format=json
rex status [dir]Print the PRD tree with status icons and completion stats.
PRD: My Project
○ Authentication [high] [1/3]
○ Login UI [high]
● Validate email
○ Handle errors
○ Password reset
◐ Dashboard [0/2]
◐ Charts
○ Export
2 completed, 1 in progress, 4 pending — 28% complete (2/7)
Icons: ○ pending, ◐ in progress, ● completed, ◌ deferred, ⊘ blocked.
Flags: --format=json outputs the full PRDDocument.
rex next [dir]Print the next actionable task. Searches depth-first by priority, skipping completed/deferred/blocked items and items with unresolved blockedBy dependencies.
Authentication → Login UI →
[task] Validate email (abc-123) [pending] [high]
Luhn check on card number
Acceptance criteria:
- Rejects invalid card numbers
- Accepts valid Visa/MC/Amex
Flags: --format=json
rex validate [dir]Check PRD integrity: schema validation, version check, DAG validation (duplicate IDs, self-references, orphan blockedBy, cycles).
rex validate myproject
Exits with code 1 on failure. --format=json for structured output.
rex recommend [dir]Get SourceVision-based recommendations. Requires a .sourcevision/ directory from a prior SourceVision analysis.
rex recommend myproject
rex recommend --accept myproject # add recommendations to PRD
Flags: --accept, --format=json
rex analyze [dir]Scan the project's test files, documentation, and SourceVision data to propose PRD items. Reconciles against existing items to avoid duplicates.
rex analyze myproject # full scan
rex analyze --lite myproject # filename-only, skip content parsing
rex analyze --accept myproject # add proposals to PRD
rex analyze --format=json myproject
Scanners:
*.test.*, *.spec.*, __tests__/ files. Full mode parses describe/it/test blocks. Lite mode uses filenames only.*.md, *.txt, *.json, *.yaml. Extracts headings, bullets, title/name fields..sourcevision/zones.json, inventory.json, imports.json.Flags: --lite, --accept, --format=json
rex export [dir] / rex import-bundle [dir]Carry the PRD between machines as a single JSON bundle, without sharing the repo or configuring a remote adapter.
rex export --out=./prd-bundle.json myproject # write the bundle
rex import-bundle --in=./prd-bundle.json other # merge it into another project
rex import-bundle --in=./prd-bundle.json --replace --yes other
The bundle preserves item ids, hierarchy, level, status, priority, description, acceptance criteria, tags, blockedBy edges, source, and attribution metadata, and carries the PRD SCHEMA_VERSION so a bundle written by a newer rex is refused rather than imported partially.
It is a transport artifact, not storage: it must be written outside .rex/ entirely, and nothing in rex reads it as a PRD backend. Import rebuilds the folder tree through the normal store write path inside store.withTransaction, so it holds the PRD lock and cannot interleave with another writer.
--merge (the default) is additive — local items keep their content and placement, new bundle items are grafted on, and ids that already exist with differing content are reported rather than overwritten. --replace discards the local tree and requires confirmation, or --yes when not attached to a terminal.
Named import-bundle because rex import is an alias for rex analyze. From the orchestrator these are ndx prd export and ndx prd import (ndx export is the unrelated static-dashboard exporter).
Flags: --out=<path> (export), --in=<path> (import), --item=<id-or-slug> (export), --replace, --yes, --format=json
--item=<id-or-slug> scopes the bundle to one epic, feature or task, so a single initiative can be carried between machines without the rest of the PRD:
rex export --item=checkout-overhaul --out=./checkout.json myproject
The scope is a closure, not a filter — a filtered subtree is not importable. The named item arrives with every descendant beneath it (including the subtask sections inside a task), with the transitive blockedBy closure so a task blocked by an item in another epic brings that item along, and with the ancestor containers of everything selected so import reconstructs the subtree at its original depth rather than re-parenting it to the root. Ancestors are pulled for closure-selected items too, so a blocker from another epic brings its own chain of containers.
Blockers are carried without their own descendants: a blocker is needed as a dependency target, not as a body of work, and expanding it downward would make a scoped export unbounded in practice.
Every blockedBy id in a scoped bundle resolves to an item in the same bundle. An edge whose target is missing from the source PRD — already broken before the export — is dropped rather than carried, and reported with the item that held it.
Because a closure can reach well past what was asked for, the summary counts the requested subtree and the closure's contribution separately, and --format=json reports the same breakdown under a scope key.
--format=narrative renders the same PRD as prose Markdown, for a stakeholder rather than a machine:
rex export --format=narrative --out=./prd.md myproject
rex export --format=narrative --item=checkout-overhaul --out=./checkout.md myproject
rex export --format=narrative --include-completed --out=./retro.md myproject
Epics become sections with a goal and a rationale, features become described capabilities, and acceptance criteria become sentences under a "How we'll know it's done" heading. Dependencies read as sequencing prose ("This follows on from …") rather than id lists. No item ids, folder slugs or raw status and priority values are emitted anywhere in the document — a uuid pasted into a description is resolved to the title it names, or dropped.
Finished and deleted work is left out by default; --include-completed keeps finished items for a retrospective-style document, and deleted items stay out regardless. --item=<id-or-slug> narrows the document to one subtree, resolved exactly as for a scoped bundle: an item id, its exact title, its folder path, or the directory name from .rex/prd_tree/; an ambiguous reference lists the candidates instead of guessing. Prose has no dependency edges, so the narrative scope is the subtree alone — the blockedBy closure applies to bundles only.
Narrative output is one-way. It cannot be imported back —
rex import-bundlereads the JSON bundle only. Export the bundle whenever the PRD has to make a round trip.
Flags: --format=narrative, --out=<path>, --item=<id-or-slug>, --include-completed
rex mcp [dir]Start an MCP (Model Context Protocol) server on stdio. This is how AI agents interact with rex programmatically.
The MCP server exposes seventeen tools and three resources.
| Tool | Description |
|---|---|
get_prd_status | PRD title, overall stats, per-epic breakdown |
get_next_task | Next actionable task with parent chain |
update_task_status | Change item status (id, status) |
add_item | Create a new PRD item with full metadata |
get_item | Get item details and parent chain by ID |
edit_item | Edit item content (title, description, priority, tags) |
move_item | Reparent an item in the PRD tree |
merge_items | Consolidate duplicate sibling items |
get_recommendations | SourceVision-based recommendations |
verify_criteria | Map acceptance criteria to test files |
reorganize | Detect and fix structural issues |
health | PRD structure health score |
facets | List configured facets with distribution |
sync_with_remote | Sync with a remote adapter (e.g. Notion) |
get_token_usage | Roll up hench run token totals per PRD item |
append_log | Write to the execution log |
get_capabilities | Schema version, adapter info, feature flags |
| URI | Content |
|---|---|
rex://prd | Full PRDDocument as JSON |
rex://workflow | Workflow instructions (markdown) |
rex://log | Last 50 execution log entries |
Items form a tree: epic > feature > task > subtask. Each item has:
| Field | Type | Required |
|---|---|---|
id | string (UUID) | yes |
title | string | yes |
status | pending | in_progress | completed | failing | deferred | blocked | deleted | yes |
level | epic | feature | task | subtask | yes |
description | string | no |
acceptanceCriteria | string[] | no |
priority | critical | high | medium | low | no |
tags | string[] | no |
source | string | no |
blockedBy | string[] (item IDs) | no |
branch | string | no |
sourceFile | string | no |
children | PRDItem[] | no |
The PRD document wraps items in:
{
"schema": "rex/v1",
"title": "Project Name",
"items": [ ... ]
}
See docs/prd-markdown-schema.md for the full list of rex/v1 fields (timestamps, work intervals, token usage, resolution metadata, structured requirements, provenance markers, and passthrough).
The PRD lives in .rex/prd_tree/ — a folder tree of plain Markdown files, one
directory per epic/feature/task, each containing an index.md. Subtasks are
sections inside their parent task's index.md.
This is the sole writable PRD surface. No rex command, MCP tool, or
rex update writes prd.md or prd.json; earlier versions dual-wrote a
.rex/prd.md + .rex/prd.json pair, and that is no longer the case.
Each index.md carries YAML front-matter with the item's structured fields and
a generated child table:
---
id: "021e305b-d4d2-43cf-b90d-137dd203f1de"
level: "epic"
title: "CLI & Developer Tools"
status: "completed"
source: "smart-add"
---
## Children
| Title | Status |
|-------|--------|
| [Pre-Execution Confirmation Prompt](./pre-execution-confirmation-4899a4/index.md) | completed |
Because every item is plain Markdown, git diff, blame, and code review work
without custom tooling. Hand-editing is supported — keep the id field intact.
docs/architecture/prd-folder-tree-schema.mddocs/guide/prd-storage.md.rex/prd_tree/Projects created before the folder tree may still have .rex/prd.md (flat
Markdown, the rex/v1 schema documented in
docs/prd-markdown-schema.md) or .rex/prd.json.
Convert with:
rex migrate-to-folder-tree .
The command reads prd.md, falls back to branch-scoped prd_*_*.md files and
then prd.json, writes the tree, and offers to delete the legacy sources. It is
idempotent — re-running on an already-migrated project is a no-op. Every
PRD-touching command also calls ensureLegacyPrdMigrated() on entry, so an
un-migrated project is converted on first use rather than failing.
.rex/
config.json Project configuration
prd_tree/ PRD folder tree (sole writable PRD surface)
archive.json Pruned/reshaped item archive
execution-log.jsonl Append-only structured log (current)
execution-log.1.jsonl Rotated backup (older entries)
workflow.md Agent workflow instructions
The execution log (execution-log.jsonl) uses automatic size-based rotation to prevent unbounded growth.
| Parameter | Value | Notes |
|---|---|---|
| Max file size | 1 MB (1,048,576 bytes) | Checked before each append |
| Max file count | 2 | Current log + one backup |
| Rotation trigger | Pre-append size check | If current log >= 1 MB, rotate before writing |
| Max entry detail | 2,000 characters | Longer detail fields are truncated with ... |
How rotation works:
appendLog call, the current log file size is checked.execution-log.jsonl is renamed to execution-log.1.jsonl (overwriting any previous backup).execution-log.jsonl.Which file is authoritative?
execution-log.jsonl is always the current, authoritative log. It contains the most recent entries and is the only file read by readLog() and the rex://log MCP resource. execution-log.1.jsonl is a backup of older entries kept for manual inspection only — it is not read by any rex API.
These values are hardcoded in FileStore (src/store/file-adapter.ts), not configurable via config.json.
When hench (the autonomous agent) commits work on a PRD task, it appends structured git trailers to the commit message that link the commit back to the PRD context. These trailers are compatible with git interpret-trailers and render as clickable links on GitHub.
feat: update authentication flow
N-DX-Status: task-abc-123 in_progress → completed
N-DX: claude/claude-opus-4-7 · run 550e8400-e29b-41d4-a716-446655440000
N-DX-Item: https://dashboard.example.com/#/rex/item/task-abc-123
| Trailer | Purpose | When present |
|---|---|---|
N-DX-Status | Task status transition (if status changed) | When the commit marks a task as completed |
N-DX | Authorship audit: vendor, model, and run ID | Always (identifies the agent that created the commit) |
N-DX-Item | Dashboard permalink to the PRD task | Always (when task ID is available) |
The dashboard base URL for the N-DX-Item trailer is resolved from .n-dx.json:
{
"web": {
"publicUrl": "https://dashboard.example.com"
}
}
When web.publicUrl is not configured, defaults to http://localhost:3117 (the standard local development server URL).
The full URL is constructed as: <publicUrl>/#/rex/item/<taskId>
If web.publicUrl is misconfigured or unreachable:
N-DX-Item trailer is still emitted with the configured URLRex ships with an opinionated workflow for AI agents:
get_next_task -- if nothing, report complete and exitupdate_task_status to mark completeappend_log with decisions and issuesOne task per execution, no exceptions.
npm install
npm run build # tsc
npm test # vitest
npm run dev # tsc --watch
npm run validate # typecheck + test
ISC
FAQs
> **This is an internal package of [`@n-dx/core`](https://www.npmjs.com/package/@n-dx/core).** Install `@n-dx/core` instead — it includes this package and registers all CLI commands.
The npm package @n-dx/rex receives a total of 40 weekly downloads. As such, @n-dx/rex popularity was classified as not popular.
We found that @n-dx/rex demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.

Security News
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.

Research
/Security News
A malicious Firefox extension fetches its payload after installation to evade detection, steal Google session cookies, and automate account takeover.

Research
/Security News
The compromise affects MemTensor's MemOS, an open source memory framework for large language models (LLMs) and AI agents. Both npm package @memtensor/memos-cloud-openclaw-plugin and the PyPI package MemoryOS are compromised. They drop cross-platform Go binaries that exfiltrate developer secrets.