Overview · Install

Install Nio.

One curl-piped-shell command installs Nio on every agent CLI you have. Auto-detect your installed agents, or pick one explicitly. macOS, Linux, or WSL.

Pick a platform

Auto-detect (recommended)

  • Node.js ≥ 18, curl, and unzip or python3
  • At least one supported agent CLI installed (Claude Code, Codex, OpenClaw, or Hermes)

The default mode. The installer scans $HOME for the four agent CLI directories — .claude, .codex, .openclaw, .hermes — and runs the matching per-platform setup for every one it finds.

curl -fsSL https://core0-io.github.io/nio/install.sh | bash

If no agent CLI is detected, the installer exits with a clear error pointing at this page so you can pick a tab and pass --platform NAME explicitly.

Onboarding with a shared config

If an operator handed you a pre-tuned nio.yaml (e.g. an org-wide external_analyser endpoint + collector setup), pass it at install time and skip the manual copy-into-~/.nio step:

curl -fsSL https://core0-io.github.io/nio/install.sh | bash -s -- --config /path/to/nio.yaml

The flag works on every form of the installer — auto-detect, per-platform (--platform claude-code --config ...), and the post-clone ./setup.sh --config .... NIO_CONFIG=/path/to/nio.yaml is honoured as a fallback when the flag isn't given.

Before touching disk, Nio runs the full /nio doctor probe suite against the incoming file (schema validation + external_analyser reachability + LLM key sanity). If any probe fails, the install aborts and your live config is not modified. On a clean pass, the previous ~/.nio/config.yaml is preserved as config.yaml.bak.<ISO-stamp> — keep multiple stamps to roll back manually.

File must be local

The --config argument is a path on your machine — not a URL. Download the file first. The path is resolved to absolute at the top of install.sh so the extracted setup.sh (running from /tmp/nio-install-XXXXXX/) can still find it.

Mutually exclusive with --reset-to-defaults

You can't use --config <path> and --reset-to-defaults in the same invocation — operationally that would mean "wipe the config then immediately overwrite it from the file," which is just --config. setup.sh refuses the combination and exits non-zero.

Claude Code

  • Claude Code CLI installed and claude on PATH
  • Node.js ≥ 18, curl, and unzip or python3
curl -fsSL https://core0-io.github.io/nio/install.sh | bash -s -- --platform claude-code

What setup.sh does

Registers the nio marketplace with Claude Code (claude plugin marketplace add), installs the plugin (claude plugin install nio@nio), syncs scripts and PreToolUse / SessionStart hooks into the Claude Code plugin cache, and writes ~/.nio/config.yaml from defaults.

Verify

  1. Open a fresh Claude Code session — hooks load on the next session, not the one in flight.
  2. Type /nio config show in chat. The current protection level prints.
  3. Try /nio scan ., then /nio report.
If /nio isn't available

Re-run the one-liner — Nio's setup.sh re-registers the marketplace idempotently. The path bound to the marketplace updates if the unzip directory moved.

Codex CLI

  • Codex CLI 0.128.0 — the only end-to-end-verified version. On macOS: brew install --cask codex.
  • Node.js ≥ 18, curl, and unzip or python3
curl -fsSL https://core0-io.github.io/nio/install.sh | bash -s -- --platform codex

What setup.sh does

Codex 0.128 has no codex plugin install command, so setup.sh performs a full nuke + cp install: wipes and rewrites ~/.codex/plugins/cache/nio/nio/<version>/ from the unzipped source, generates a Codex-valid marketplace catalog under ~/.nio/codex-marketplace/, and edits ~/.codex/config.toml to register the marketplace, enable the plugin, and set codex_hooks = true + plugin_hooks = true under [features].

Verify

  1. Open a fresh Codex session.
  2. codex "$nio config show" — current protection level prints.
  3. codex "$nio scan .", then codex "$nio report".
Caveat

plugin_hooks is still under-development in Codex 0.128, but it's the only feature flag that lets plugin-bundled hooks.json fire. Codex also doesn't support custom slash commands — use $nio as the explicit skill trigger.

OpenClaw

  • OpenClaw (ClawHub) CLI installed and openclaw on PATH
  • Node.js ≥ 18, curl, and unzip or python3
curl -fsSL https://core0-io.github.io/nio/install.sh | bash -s -- --platform openclaw

What setup.sh does

Registers the bundled plugin (plugin/plugin.js) with OpenClaw, mirrors the /nio skill directory so the slash command appears in the skill list, and writes ~/.nio/config.yaml from defaults.

Verify

  1. Open OpenClaw — /nio appears in the skill list.
  2. /nio config show/nio scan ./nio report.
Caveat — no interactive confirm

OpenClaw doesn't expose an interactive "do you want to run this?" prompt. When the guard decides confirm, the confirm_action fallback fires (default: allow + warning in the audit log). For headless / CI environments, set it to deny in ~/.nio/config.yaml.

Hermes

  • Hermes Agent installed; shell-hook subsystem from upstream PR #13296 is required
  • Node.js ≥ 18, curl, and unzip or python3
curl -fsSL https://core0-io.github.io/nio/install.sh | bash -s -- --platform hermes

What setup.sh does

Merges seven shell-hook entries (pre_tool_call, post_tool_call, pre_llm_call, post_llm_call, on_session_start, on_session_end, subagent_stop) into ~/.hermes/config.yaml, drops the /nio Python plugin into ~/.hermes/plugins/nio/, appends "nio" to plugins.enabled, and writes ~/.nio/config.yaml.

Verify

  1. hermes hooks doctor — expect "Checking 7 configured shell hook(s)…", all green.
  2. Restart any running gateway: hermes gateway run --replace.
  3. Send /nio config show in any Hermes channel — bot replies, no LLM in the loop.
Caveat — consent allowlist

Hermes refuses to fire unknown shell hooks until you consent. The interactive prompt at the end of setup.sh handles this — it reads from /dev/tty, so the prompt still fires under curl … | bash. For non-TTY runs (CI, Docker -d, systemd, nohup with </dev/null), pass --accept-hooks through the one-liner, or set HERMES_ACCEPT_HOOKS=1 before running. The allowlist is keyed on the exact command string, so any path change (move, upgrade, new machine) requires re-approval.

After install

  1. Edit ~/.nio/config.yaml: set guard.protection_level, optional collector.endpoint for OTLP export.
  2. Start a new agent session so the hooks load (if you have a long-running daemon like hermes gateway, restart it).
  3. The audit log is at ~/.nio/audit.jsonl. Read recent entries via /nio report (or $nio report on Codex).
  4. Full config field reference: Configuration.
Nio guarding its own install

If Nio is already running on one agent and you re-invoke the one-liner to add another, the guard may surface a confirm prompt — curl … | bash matches one of the high-severity scan patterns. That's expected; allow it. The protection level controls the behaviour: balanced asks, strict denies, permissive allows.

Upgrade

Re-run the install one-liner — setup.sh is idempotent and picks up the latest release. To pin a specific tag, set NIO_VERSION first:

NIO_VERSION=v2.4.3 bash -c "$(curl -fsSL https://core0-io.github.io/nio/install.sh)"

After a release that changed the config schema, append --reset-to-defaults to overwrite ~/.nio/config.yaml with the new bundled template:

curl -fsSL https://core0-io.github.io/nio/install.sh | bash -s -- --reset-to-defaults
Heads up — --reset-to-defaults wipes your customisations

--reset-to-defaults replaces your existing config.yaml with the upgraded template, so any tuned fields (allowed commands, permitted tools, collector endpoint, scoring weights, …) are gone and have to be reapplied on top of the new defaults. Back the file up first if you're not sure what you customised: cp ~/.nio/config.yaml ~/.nio/config.yaml.bak.

To roll a new operator-tuned config in the same upgrade step, pass --config /path/to/new.yaml instead — the previous file is automatically preserved as config.yaml.bak.<ISO-stamp> and the install aborts if /nio doctor flags any issue:

curl -fsSL https://core0-io.github.io/nio/install.sh | bash -s -- --config /path/to/new.yaml

Uninstall

curl -fsSL https://core0-io.github.io/nio/install.sh | bash -s -- --uninstall

Removes Nio from every detected agent CLI. Add --platform NAME to limit scope.

Custom install paths

If you've moved an agent CLI's home directory (via CLAUDE_CONFIG_DIR, CODEX_HOME, OPENCLAW_STATE_DIR, or manually), thread the override past the installer's bash -s -- boundary — everything after -- forwards to the matching setup.sh:

curl -fsSL https://core0-io.github.io/nio/install.sh | bash -s -- --platform claude-code --cc-home /path/to/.claude

Available flags: --cc-home, --codex-home, --openclaw-home, --hermes-home, --config <path>, --reset-to-defaults. Resolution order in each platform's setup.sh: flag > env var > default ($HOME/.<plat>). See Onboarding with a shared config above for what --config does.

Manual install or from source

The one-liner is just orchestration: it downloads the per-platform release zip, runs its setup.sh, and cleans up. To install a release manually, grab a zip from the Releases page, extract it (unzip, or python3 -m zipfile -e if unzip isn't installed), then cd into the directory and run ./setup.sh — or ./setup.sh --config /path/to/nio.yaml to apply an operator-provided config in the same step (doctor-gated). To install from a local checkout for development, see the Development section in the README.