Skip to content

Runtimes

nubos-pilot ships one source tree, one install payload, and a runtime-adapter layer that currently supports fourteen host CLIs. The same workflows and agents work in every supported runtime.

Supported runtimes

First-class runtimes (full adapter + managed-markdown):

RuntimeidLocal install pathManaged Markdown
Claude Codeclaude.claude/nubos-pilotCLAUDE.md
Codexcodex.codex/nubos-pilotAGENTS.md
Geminigemini.gemini/nubos-pilotGEMINI.md
OpenCodeopencode.opencode/nubos-pilotAGENTS.md

Additional runtimes (selectable via --agent <id>):

RuntimeidLocal install pathManaged Markdown
Antigravityantigravity.agent/nubos-pilotAGENTS.md
Augmentaugment.augment/nubos-pilotAGENTS.md
Clinecline./.clinerules-nubos-pilot.clinerules
CodeBuddycodebuddy.codebuddy/nubos-pilotAGENTS.md
Copilotcopilot.github/nubos-pilotcopilot-instructions.md
Cursorcursor.cursor/nubos-pilotrules/nubos-pilot.mdc
Kilokilo.kilo/nubos-pilotAGENTS.md
Qwen Codeqwen.qwen/nubos-pilotAGENTS.md
Traetrae.trae/nubos-pilotAGENTS.md
Windsurfwindsurf.windsurf/.windsurf-nubos-pilot.windsurfrules

Total: 14 runtimes.

The tables above are regenerated from lib/install/runtimes-registry.cjs by scripts/generate-docs.cjs. The list is closed: adding a runtime requires an adapter that implements the contract enforced by _contract.test.cjs, plus an entry in the registry.

Detection

detect({ cwd }) resolves the active runtime in priority order:

  1. .nubos-pilot/config.json — if runtime is set and known, win.
  2. Live envlib/askuser.getRuntime() introspects the host process (e.g. environment markers Claude Code, Codex etc. set).
  3. Fallbackcodex (source: 'default').

The source field on the result tells you which path won — useful for np:doctor diagnostics.

What an adapter does

Adapters encapsulate runtime-specific concerns:

  • Slash-command syntax — how the host CLI registers a np:* command.
  • Question/answer transport — askUser over the host's prompt UI.
  • Tool surface — which built-in tools (Read, Write, Bash, …) are exposed and under what names.
  • Hook lifecycle (where supported).

Anything that would be runtime-specific in workflow Markdown or agent frontmatter is forbidden; it lives here, in the per-runtime adapter file. This is the seam that keeps ADR-0001 (no daemon) and the portability story honest.

Per-runtime payload directories

Each runtime installs its payload into its own directory, named in the localDir field of lib/install/runtimes-registry.cjs: .claude/nubos-pilot for Claude Code, .codex/nubos-pilot for Codex, .gemini/nubos-pilot for Gemini, .opencode/nubos-pilot for OpenCode (see the Local install path column in the tables above). The payloads do not share a directory.

The managed-block instructions live in a separate file per runtime: CLAUDE.md for Claude Code, AGENTS.md for Codex and OpenCode, GEMINI.md for Gemini. The installer auto-generates AGENTS.md / GEMINI.md from CLAUDE.md (via lib/install/agents-md.cjs) when they are absent.

Command surface per runtime

Where the workflows and agent roles land — and how you invoke them — depends on what the host CLI actually reads:

RuntimeWorkflowsAgent rolesInvocation
Claude Code.claude/commands/np/.claude/agents//np:plan-phase 1
OpenCode.opencode/command/np/.opencode/agent//np:plan-phase 1
Codex.codex/skills/np-*/SKILL.md.codex/agents/np-*.toml$np-plan-phase 1
all othersnone; drive the backend directly (below)

Codex

Codex has two extension surfaces and they mean different things, so nubos-pilot uses both.

Workflows are skills. Codex reads custom prompts only from $CODEX_HOME/prompts — user-global, not shareable through the repository, and deprecated by OpenAI in favour of skills. Skills are project-scoped under .codex/skills/, so the 36 workflows render there via lib/install/codex-skills.cjs. One difference from Claude Code is real and each generated SKILL.md says it outright: invocation is $name, not /name/np:plan-phase becomes $np-plan-phase 1, and /skills lists what is installed. A leading / on a skill name is not recognised by Codex.

Agent roles are subagents. The 21 loop roles render to .codex/agents/np-*.toml via lib/install/codex-agents.cjs — the project-scoped half of the directory pair Codex scans (the other being ~/.codex/agents/). Each file carries the three fields Codex requires: name, description and developer_instructions. This is what gives the loop its isolation on Codex: a spawned subagent runs in its own thread, so np-critic does not share context with the np-executor output it reviews. Delegation is requested in the prompt ("spawn one agent per slice"); the parent caps concurrency with agents.max_threads (default 6) and nesting with agents.max_depth (default 1) in config.toml — raise max_threads if you run a wide Critic-Schwarm.

model and sandbox_mode are deliberately not written. nubos-pilot addresses models by tier (sonnet, opus) while Codex resolves them by profile, so emitting one would pin a model the user did not choose; a subagent inherits the parent session instead. The tier is preserved as reference text inside the instructions.

np:doctor validates both surfaces: it resolves each role at the path its runtime actually uses (.toml for Codex, .md elsewhere) and spot-checks the core workflows (new-project, plan-phase, execute-phase, verify-work), reporting workflow-commands-dir-missing / workflow-command-missing with that runtime's own invocation syntax in the hint.

Runtimes without a command surface

The remaining eleven runtimes get the payload, the managed markdown and the state directory, but no installed command or agent files — their host CLIs have nowhere to put them. The workflows are still usable: every one of them is a documented sequence over np-tools.cjs, which is runtime-independent.

bash
node .nubos-pilot/bin/np-tools.cjs doctor
node .nubos-pilot/bin/np-tools.cjs state
node .nubos-pilot/bin/np-tools.cjs new-project --apply answers.json

The full command list is in CLI Commands. What you do not get without a command surface is the orchestration — the planner/critic/verifier loop is driven by the workflow Markdown, and if the runtime cannot load it, you are driving those steps yourself.

OpenCode

OpenCode also gets a default opencode.json written at the project root if none exists:

json
{
  "$schema": "https://opencode.ai/config.json",
  "agent": {
    "paths": [".claude/agents/"]
  }
}

Runtime-specific config repair

The installer does one runtime-specific repair: if ~/.codex/config.toml contains the well-known trapped [features] table, it rewrites the section in place via lib/install/codex-toml.cjs. The repair is idempotent and logged on stderr.