Skip to content

CLI Commands

Every subcommand exposed by np-tools.cjs, mirrored from bin/np-tools/_commands.cjs (the canonical registry).

Dispatch has two layers:

  • init <workflow> — orchestrator workflows. Calls a registered handler in bin/np-tools/<name>.cjs (plan-milestone, execute-milestone, discuss-phase, new-project, …). An unknown init workflow returns unknown-init-workflow with exit code 1.
  • Top-level commands — utility and leaf commands (commit-task, checkpoint, metrics, doctor, …).

Output is JSON; payloads above 16 KB are spilled to .nubos-pilot/.tmp/init-<workflow>-<pid>-<rand>.json and the path emitted as @file:<path>.

Commands by category

Planning

CommandDescription
agent-skillsPrint agent_skills config for a given subagent
archive-projectMove current .nubos-pilot/ project to archive/<slug>-<YYYYMMDD>/ (status|do|list|read)
derive-tierAdvisory: derive a suggested executor tier (haiku|sonnet|opus) from a task's observable signals (files_modified + risk keywords). Decider stays the planner. ADR-0013.
discuss-phaseAdaptive milestone-context interview (writes M<NNN>-CONTEXT.md)
discuss-projectAdaptive project-context interview (writes PROJECT.md decisions)
new-milestoneAppend a new milestone (M<NNN>) to an existing project
new-projectGreenfield project init (PROJECT.md + REQUIREMENTS.md + M001 milestone)
phase-metaRead roadmap.yaml phase fields as JSON (supports --field NAME and --length for arrays)
plan-lintMechanical Trust-Layer linter for PLAN.md (verify-command + parallel-race + over-specification + pattern-claim). ADR-0019, ADR-0032
plan-milestonePlan a milestone: scaffolds slices + tasks
propose-milestonesRe-plan all not-yet-done milestones: AI proposes add/update/remove from PROJECT.md + REQUIREMENTS.md
research-phaseMilestone-level research (WebFetch + MCP; offline fallback)
researcher-reconcileResearcher-swarm reconciliation (ADR-0018). Verbs: parse-spawn --file | prepare <N> | gate <N>. Reads per-spawn outputs, applies reasoning-trace classification, surfaces contested decisions, hard-gates on agreement_score / contested_count.
rollupDerive slice + milestone status from task states and sync roadmap.yaml. Usage: rollup [<N>|all] | rollup inspect <N>. Never writes a terminal milestone status — that stays with verify-work.
update-phase-metaUpdate roadmap.yaml phase fields (name/goal/requirements/success_criteria) via JSON patch

Execution

CommandDescription
add-testsPersist VERIFICATION Pass-cases as node:test UAT (Sentinel-preserving)
checkpointPer-task crash-safety checkpoint CRUD (start/transition/touch/show)
commit-taskAtomic per-task git commit via lib/git.cjs
execute-milestoneWave-based milestone execution — slice by slice, tasks parallel within a slice
learning-logPersist a learning to the local store (or MCP adapter when configured)
learningsStop-hook continuous-learning capture (ADR-0010). Verbs: capture (rate-limited; spawns headless np-learnings-extractor over the turn diff) | reset (clears stop-streak) | run-extract (background worker). Gated by learnings.auto_capture.
loop-audit-tool-useRecord/read the tool-use audit per spawn (Completeness Rule 9 mechanical check)
loop-evaluateRun evaluateLoop over critic outputs JSON; emit next_action + findings + routing
loop-preflightPer-task pre-flight cache lookup (ADR-0010 Step 1) — short-circuits the Researcher-Schwarm on hit
loop-run-roundDrive the per-task Nubosloop state machine — phases: preflight | post-executor | post-critics | commit | stuck
loop-state-readRead the per-task Nubosloop state from the checkpoint (round, last_action, findings)
loop-state-recordAtomically merge a partial Nubosloop state update into the task checkpoint
loop-stuckMark a task as stuck (writes loop-state + flips checkpoint status to stuck)
parkMark task status parked (lifecycle CRUD)
pause-workStamp STATE.session.stopped_at + resume_file for explicit handoff
reset-sliceDiscard in-flight task: restore working tree from HEAD, drop checkpoint, clear STATE.current_task
resume-workClassify session state (resume | orphan | clean) from STATE + checkpoints
skill-auditSkill-bar consultation audit (counterpart to the Rule-9 search audit). Verbs: expect --task --skills (orchestrator records injected skills) | ack --task --skill (executor stamps a consulted skill) | findings --task [--round] (list unmet bars). An unconsulted injected skill becomes a skill-bar-unconsulted finding that routes back to the executor.
skipMark task status skipped (lifecycle CRUD)
slice-planEvaluate conditional slice edges for a milestone (ADR-0028). Verbs: plan <N> | lint. Decisions are three-valued — run | skip | wait — because a slice whose predecessor merely has not finished is waiting, not skipped. An unresolvable condition is an error, never a run. Requires roadmap schema_version 3 for any slice carrying a when.
spawn-headlessSpawn an agent as a headless claude -p subprocess (ADR-0010 §L6); writes stdout to --output-path and returns exit code
spawn-offhostRun an agent routed to an openai-compat provider (Ollama/OpenAI/Grok) as a one-shot tool-use loop (ADR-0021). Args: --agent --task|--task-file [--allow-bash] [--read-only]. Preflights the endpoint, records metrics.
task-verify-cmdPrint the executable <verify> command lines of a task plan (one per line, or --json). The orchestrator runs these in execute-phase Step 4.
undoRevert every task commit of a milestone or slice via git revert (no history rewrite)
undo-taskRevert a single task commit and reset task status to pending
unparkReturn a parked task to pending (lifecycle CRUD)
verify-reliabilitypass@k reliability: fold k verify-run exit codes into pass@1/pass@k/flaky + an aggregate exit code (pass^k) for loop-run-round. Opt-in via loop.verify_runs.
verify-workTwo-pass goal-backward verification (milestone-level VERIFICATION.md)
worktree-createCreate an isolated git worktree for a slice (branch np/<mid>-<sid> off current HEAD) under .nubos-pilot/worktrees/
worktree-ff-mergeFast-forward merge a slice branch back to its base (fails hard on non-FF)
worktree-listList all nubos-pilot-managed slice worktrees (np/<mid>-<sid> only) as JSON
worktree-removeRemove a slice worktree + delete its branch (--force / --keep-branch)

Review

CommandDescription
close-projectAggregate verification of every milestone; writes PROJECT-SUMMARY.md + sets project_status=completed
gate-candidatesCluster failed/reverted learnings into recurring failure classes worth encoding as a mechanical gate instead of a prompt instruction
output-lintMechanical output-artifact linter (frontmatter + body + cross-field invariants). Verbs: check | prompt | list. Schemas in lib/schemas/. Hard-gates verify-work, validate-phase. ADR-0017
pressure-evalBehavioural compliance harness (ADR-0024). Verbs: lint | list | coverage | prompt | evaluate | report. Scores an agent response against a pressure fixture that stacks >=3 pressures and forces a discrete choice; a pass requires the compliant choice AND a citation of the rule. Offline verbs never call a model — report is the model-swap regression gate.
scanNative dependency, secret and misconfiguration scanner (ADR-0031). Verbs: all | inventory | advisory | secrets | misconfig | license | sbom | db-status. Deterministic, offline, no model call. --json for machine output, --fail-on high|critical to gate a CI step.
securityIn-session security review hook backend (ADR-0020). Verbs: session-start | baseline | scan | review | commit | run-review. Reads the Claude Code hook payload via --stdin; non-blocking, report-once, independent reviewer spawn.

Capture

CommandDescription
add-todoCapture a pending todo to .nubos-pilot/todos/pending/ + increment STATE count
handoff-listList handoffs (JSON array); filter with --for AGENT, --milestone M<NNN>, --status STATUS, --global
handoff-readRead a single handoff by id (returns frontmatter + body as JSON)
handoff-statusUpdate a handoff status (open|read|acted|archived)
handoff-writeWrite an agent-to-agent handoff note (milestone-scoped by default, global without --milestone)
memory-addAdd a single record to vector memory (--type, --title, --body / --body-file, optional --tags / --provenance / --phase / --id / --skip-if-disabled)
memory-indexBulk-index records into vector memory (--records JSON or --records-file JSONL). Opt-in via memory.enabled=true. ADR-0014
messages-archiveMove an inbox message to archive/; refuses request+expects_reply without prior response
messages-inboxList unread messages addressed to an agent (filterable by --kind, --since, --task)
messages-sendSend addressed inter-agent message (request|response|notify) to .nubos-pilot/messages/inbox/<to>/. ADR-0015
messages-threadPrint full reply-chain for a message id (causal order)
resume-docSession handoff document (ADR-0025). Verbs: write | lint | read | status | ack | learnings. Six-section re-entry brief written at a session boundary; failed_approaches is mandatory because it is the one section git cannot reconstruct. status returns gate none|blocked|clear — resume-work refuses code work while blocked. Refuses secret values; variable names are fine.
simplify-debtEconomy-debt ledger CRUD — record deferred simplifications so "later" does not become "never". Verbs: add --file --line --category --note | list [--status open|resolved|all] [--json] | resolve <id>. Categories mirror the four Economy critic routes; manual twin of /np:simplify-review.
state-incrIncrement a whitelisted STATE.md counter (e.g. pending_todos) under withFileLock

Install

CommandDescription
doctor16-check install-integrity scan (--fix for auto-safe fixes). Exit 1 on error-severity findings.
isolationExecution isolation tiers (ADR-0029). Verbs: status | describe <tier> | probe | wrap -- <cmd>. Three tiers: direct (none — the agent holds whatever the host CLI grants), worktree (version isolation only, ADR-0008; rights unchanged), container (rights isolation; project mounted, no network by default). A configured tier is never silently downgraded — an unusable container runtime refuses instead of falling back.
scan-codebaseInitial deep codebase inventory → .nubos-pilot/codebase/ skill docs
update-docsRefresh stale module docs after code changes
workspace-scanScan a workspace and emit inventory JSON (full result or --summary shape for /np:new-project)

Utility

CommandDescription
acpAgent Client Protocol groundwork (ADR-0030). Verbs: status | initialize-request | negotiate. JSON-RPC 2.0 vocabulary, newline-delimited framing and the initialize handshake, with version negotiation that refuses an unsupported MAJOR rather than guessing. Stage is groundwork: no transport is wired into the spawn path and every client capability is off, because declaring one before its handler exists makes the agent wait on a reply that never comes.
askuserCapability-layer prompt wrapper (reads spec JSON, returns chosen label)
commitAtomic git commit wrapper with gitignore-guard
config-getRead value from .nubos-pilot/config.json by dotted key path
context-statsAggregated context-budget stats (file counts + bytes per group, knowledge-index size)
dashboardOne-shot console dashboard of milestones, slices, and tasks. Read-only; flags: --json, --no-color
detect-runtimePrint detected runtime id (claude, codex, gemini, …) — reads config.json ∨ env ∨ default
detect-stackPrint detected project stacks + their lint/typecheck commands — SSOT for stack-aware verification
economy-modeResolve the Economy axis level (off|lite|full|ultra) from agents.economy (legacy agents.economy_critic honoured; default lite). Prints the mode, or --json for {mode,prevention,critic,ultra} gate flags. Single source for the execute-phase economy gate.
elision-benchMeasure elision compression: deterministic fidelity (ratio + critical-line preservation + byte-exact reversibility) over a fixture corpus; --with-model adds answer-equivalence (raw vs compressed). --size <small|medium|large> runs a scaled corpus with a deterministic --holdout control group (--max-cases N) and an estimated token saving (--price-per-mtok <p> [--currency EUR] adds a cost estimate). --json, --tier <name>
elision-getRetrieve the original text behind a ⟦elided:<hash>⟧ compression marker. Reversible context compression (ADR-Elision). Positional <hash> or --hash; --json for envelope
generate-slugSlugify text via lib/layout.cjs.slugify
graph-impactQuery the module dependency graph (.graph.json from np:scan-codebase): impact (transitive dependents), dependencies, cluster, cycle membership. Flags: --module <id> | --path <relpath> | --cycles
helpList available commands
initDispatcher init payload for workflows
knowledge-indexBuild BM25-light index over .nubos-pilot/**/*.md → .nubos-pilot/state/knowledge-index.json
knowledge-searchQuery the knowledge index; returns top-N JSON hits (rel_path + lines + score + preview). Inside a Nubosloop task pass --task <id> AND --agent <name> to record Rule 9 audit evidence; evidence is credited per agent, so omitting --agent leaves the audit unsatisfied
knowledge-statsPrint knowledge-index size + grouping (auto-builds if missing)
lang-directivePrint workflow language directive from config.response_language (SSOT)
learning-listList learnings sorted by occurrence (most-used first)
learning-matchQuery the learnings store for cached patterns matching a free-text query
loop-metricsAggregate Nubosloop telemetry across all checkpoints (commits, stuck, route distribution)
memory-queryQuery vector memory by text; returns top-k JSON hits with score + record. Filter by --type, --phase, --tags
memory-rebuildForce full re-embed from records.jsonl; required after embedding-model change. ADR-0014
memory-statsPrint vector-memory stats (count, dim, model, schema_version, created_at)
metricsRecord JSONL metrics entry (record | now | start-timestamp | end-timestamp)
otlp-exportExport the milestone/slice/task/agent-spawn hierarchy as an OTLP span tree (ADR-0026). Verbs: dry-run | write --out | send | stats. Emits OTLP/HTTP JSON for Langfuse, an OpenTelemetry collector, or any OTLP backend — no bundled client, no daemon, no dependency. Span ids are derived from unit ids so a re-export updates one trace. send requires telemetry.otlp.enabled.
render-templateRender a shipped template by name with --vars JSON (or --vars-file PATH)
render-todoRender slice TODO.md rollup (checkbox view of task statuses) for a slice full-id
resolve-modelResolve agent/tier to model alias or id (Tier×Profile matrix)
roadmap-graphRender roadmap.yaml as a dependency graph in Mermaid or Graphviz DOT (ADR-0027). Flags: --format mermaid|dot, --level milestone|slice|task, --direction TD|LR, --milestone N, --markdown, --out, --json. Draws milestone depends_on, task depends_on, and the serial slice order the executor enforces but roadmap.yaml only implies. Read-only — no verb writes roadmap.yaml.
session-aggregateAggregate session metrics under withFileLock; reads pointer .last-session unless --since overrides
session-pointer-writeAtomic write of .nubos-pilot/reports/.last-session under withFileLock (ISO-8601 UTC)
session-snapshot-readPrint last session snapshot as JSON
session-snapshot-writeCapture session snapshot (current_task + recent commits + open handoffs) for resume
statePrint the current project state snapshot
state-dirPrint project-state directory (.nubos-pilot) or a validated subdir via --subdir NAME
statsAggregated project stats — json | bar | markdown (markdown labels follow config.response_language)
template-pathPrint absolute path to a package-shipped template by name (e.g. VALIDATION, milestone/CONTEXT)
text-modePrint whether text mode is active (config.workflow.text_mode ∨ CLAUDECODE)
thread-resumeBump a thread markdown on resume (status OPEN→IN_PROGRESS, refresh last_resumed) via atomic write

The tables above are regenerated from bin/np-tools/_commands.cjs by scripts/generate-docs.cjs. To add a command, append an entry to that registry; the doc table picks it up on the next run.

Registry descriptions are one-line summaries. Where a command needs more detail, the dedicated reference or workflow page is authoritative. For example, np:doctor lists all 12 integrity checks.

Milestone status: who writes what

Milestone and slice status in roadmap.yaml have exactly two writers, and the split is deliberate.

TransitionWritten byTrigger
milestone pendingin-progressexecute-milestone init, and the rollupexecution starts; any task leaves pending
slice pendingin-progressdonerollup (lib/rollup.cjs)derived from the task states on disk
milestone → verified / failed / deferredverify-work onlySC verdicts in M<NNN>-VERIFICATION.md

The rollup never sets a terminal milestone status. Terminal means "verification ran", so deriving it from task completion would let a milestone read as finished with nothing behind it — precisely what close-project's blocker gate exists to catch. A milestone whose slices are all done therefore stays in-progress until /np:verify-work classifies its success criteria; np-tools doctor surfaces that state as milestone-ready-for-verification.

The rollup runs on every task transition (hooked into setTaskStatus, so it covers commit-task, skip, park, unpark, undo, undo-task alike) and is idempotent. It is non-fatal: if roadmap.yaml cannot be written, the task transition still stands and the mismatch is logged. Repair drift with:

bash
np-tools.cjs rollup <N>          # one milestone
np-tools.cjs rollup all          # every milestone
np-tools.cjs rollup inspect <N>  # report without writing

How task states map to a slice

Task states in the sliceSlice status
all done / skipped (any mix)done — a skipped task leaves no work behind, so an all-skipped slice completes with zero work done
any in-progress, done, skipped or parked presentin-progress
all pendingpending
any PLAN.md missing or without a statusnever done — an unreadable task blocks completion rather than being ignored

parked deliberately holds a slice open, so a fully parked slice reads in-progress indefinitely; doctor surfaces that as slice-fully-parked rather than the status vocabulary growing a "blocked" value.

The slice set comes from what roadmap.yaml declares, not from what exists on disk — a milestone declaring S001..S003 with only S001 scaffolded is not verification-ready.

FindingMeaning
slice-status-driftpersisted slice status is behind the tasks on disk → np-tools rollup <N>
milestone-status-driftroadmap.yaml, M<NNN>-META.json and the SC verdicts disagree → verify-work sync-roadmap
milestone-ready-for-verificationevery slice is done, no VERIFICATION.md yet → /np:verify-work <N>
milestone-terminal-with-open-workmilestone claims a terminal status while work reopened → the verification it points at is stale
task-plan-unreadabletask directories exist whose PLAN.md is missing or has no status
slice-fully-parkedevery task in a slice is parked, so the slice can never complete on its own

Closing and archiving a project

close-project close runs the whole closing sequence in the only order that works — summary, then project_status, then (optionally) archive, because the archiver moves PROJECT-SUMMARY.md and needs it written first.

bash
np-tools.cjs close-project close [--archive] [--force] [--carry-over a,b | --no-carry-over] [--allow-unknown]
FlagEffect
--archiveArchive immediately after closing. Without it the project is closed but stays live.
--forceClose past unresolved blockers. Recorded as forced: true plus the real blockers_at_archive in ARCHIVE.json — a forced close is never reported as a clean one.
--carry-over a,b / --no-carry-overWhich paths are copied back out of the archive for the successor. Defaults to knowledge/learnings.json + knowledge/solutions.
--allow-unknownArchive despite unclassified state entries, listing them in the manifest as skipped_unknown.

Both close and mark-completed refuse with close-project-blocked unless --force was given, writing nothing on refusal. Unknown flags and flags missing their value are rejected rather than ignored, so a typo cannot silently skip the archive.

A recorded project_status: completed authorizes archiving but no longer masks blockers: completion.complete stays blocker-based and honest, while the separate completion.archivable carries the authorization. A forced close is therefore still visible as forced: true plus the real blockers_at_archive in ARCHIVE.json.

Exit code on a failed archive. If closing succeeds but archiving fails, the command writes its full payload (closed: true, archived: false, archive_error) to stdout and exits non-zero. The close stands; only the archive is missing, and archive-project do picks up from there. Do not read the non-zero exit as a failed close.

What archiving moves

lib/archive.cjs classifies every top-level entry under .nubos-pilot/ into exactly one of two frozen lists, and refuses with archive-unknown-state-artifact on anything it does not recognise — an allowlist alone silently leaves new artefacts behind, which is how project-specific data used to leak into successor projects.

Entries
Archived (project content)PROJECT.md, PROJECT-SUMMARY.md, REQUIREMENTS.md, RULES.md, ROADMAP.md, STATE.md, roadmap.yaml, milestones/, phases/, codebase/, references/, metrics/, notes/, checkpoints/, economy-debt/, messages/, threads/, handoffs/, todos/, reports/, knowledge/, session/
Preserved (tool runtime, survives into the successor)config.json, security-rules.json, prose-auth.json, archive/, state/, worktrees/, memory/, bin/, agents/, templates/, backups/, audit/, elision/, run/, plus every dot-entry

Adding a new top-level artefact means adding it to one of the two lists; a test asserts that every state-dir path the source creates is classified, so an unclassified one fails the suite rather than leaking at archive time.

User-facing workflow aliases

Three slash-commands preserve older naming for continuity. They dispatch to milestone-scoped init commands:

User-facingDelegates toNotes
/np:plan-phase <N>init plan-milestone init <N> + scaffolder"phase" = milestone in the command name
/np:execute-phase <N> [--verify-work]init execute-milestone init <N> [--verify-work] + per-task dispatchslice-by-slice, tasks parallel within slice; --verify-work chains /np:verify-work <N> on success
/np:validate-phase <N>Nyquist auditor → M<NNN>-VALIDATION.md
/np:close-projectinit close-project + askuser blocker gateproject-level aggregate verification; writes PROJECT-SUMMARY.md and flips project_status: completed
/np:architect-phase <N>spawns np-architectM<NNN>-ARCHITECTURE.mdoptional, between research and planning
/np:knowledge "<query>"wraps knowledge-index + knowledge-searchlocal full-text search over project markdown
/np:context-statswraps context-statslocalized markdown snapshot of the knowledge index