Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# AGENTS.md

## Project Context

NVIDIA NemoClaw runs OpenClaw AI assistants inside hardened OpenShell sandboxes with NVIDIA Nemotron inference. This file provides agent-specific guidance for working on this codebase.

## Quick Reference

| Task | Command |
|------|---------|
| Install all deps | `npm install && cd nemoclaw && npm install && npm run build && cd .. && cd nemoclaw-blueprint && uv sync && cd ..` |
| Run all tests | `npm test` |
| Run plugin tests | `cd nemoclaw && npm test` |
| Run all linters | `make check` |
| Type-check CLI | `npm run typecheck:cli` |
| Build plugin | `cd nemoclaw && npm run build` |
| Build docs | `make docs` |

## Key Architecture Decisions

### Dual-Language Stack

- **CLI and plugin**: JavaScript (CJS in `bin/`, ESM in `test/`) and TypeScript (`nemoclaw/src/`)
- **Blueprint**: YAML configuration (`nemoclaw-blueprint/`)
- **Docs**: Sphinx/MyST Markdown
- **Tooling scripts**: Bash and Python

The `bin/` directory uses CommonJS intentionally — it's the CLI entry point that must work without a build step. The `nemoclaw/` plugin uses TypeScript and requires compilation.

### Testing Strategy

Tests are organized into three Vitest projects defined in `vitest.config.ts`:

1. **`cli`** — `test/**/*.test.{js,ts}` — integration tests for CLI behavior
2. **`plugin`** — `nemoclaw/src/**/*.test.ts` — unit tests co-located with source
3. **`e2e-brev`** — `test/e2e/brev-e2e.test.js` — cloud E2E (requires `BREV_API_TOKEN`)

When writing tests:

- Root-level tests (`test/`) use ESM imports
- Plugin tests use TypeScript and are co-located with their source files
- Mock external dependencies; don't call real NVIDIA APIs in unit tests
- E2E tests run on ephemeral Brev cloud instances

### Security Model

NemoClaw isolates agents inside OpenShell sandboxes with:

- Network policies (`nemoclaw-blueprint/policies/`) controlling egress
- Credential sanitization to prevent leaks
- SSRF validation (`nemoclaw/src/blueprint/ssrf.ts`)
- Docker capability drops and process limits

Security-sensitive code paths require extra test coverage.

## Working with This Repo

### Before Making Changes

1. Read `CONTRIBUTING.md` for the full contributor guide
2. Run `make check` to verify your environment is set up correctly
3. Check that `npm test` passes before starting

### Common Patterns

**Adding a CLI command:**

- Entry point: `bin/nemoclaw.js` (routes to `bin/lib/` modules)
- Keep `bin/lib/` modules as CommonJS
- Add tests in `test/`

**Adding a plugin feature:**

- Source: `nemoclaw/src/`
- Co-locate tests as `*.test.ts`
- Build with `cd nemoclaw && npm run build`

**Adding a network policy preset:**

- Add YAML to `nemoclaw-blueprint/policies/presets/`
- Follow existing preset structure (see `slack.yaml`, `discord.yaml`)

**Updating docs:**

- Edit under `docs/` (never `.agents/skills/docs/`)
- Regenerate skills: `python scripts/docs-to-skills.py docs/ .agents/skills/docs/ --prefix nemoclaw`
- Preview: `make docs-live`

### Gotchas

- `npm install` at root triggers `prek install` which sets up git hooks. If hooks fail, check that `core.hooksPath` is unset: `git config --unset core.hooksPath`
- The `nemoclaw/` subdirectory has its own `package.json`, `node_modules/`, and ESLint config — it's a separate npm project
- SPDX headers are auto-inserted by pre-commit hooks; don't worry about adding them manually
- Coverage thresholds are ratcheted in `ci/coverage-threshold.json` — new code should not decrease coverage
- The `.claude/skills` symlink points to `.agents/skills` — both paths resolve to the same content
139 changes: 139 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# CLAUDE.md

## Project Overview

NVIDIA NemoClaw is an open-source reference stack for running [OpenClaw](https://openclaw.ai) always-on assistants inside [NVIDIA OpenShell](https://github.com/NVIDIA/OpenShell) sandboxes with NVIDIA inference (Nemotron). It provides CLI tooling, a blueprint for sandbox orchestration, and security hardening.

**Status:** Alpha (March 2026+). Interfaces may change without notice.

## Architecture

| Path | Language | Purpose |
|------|----------|---------|
| `bin/` | JavaScript (CJS) | CLI entry point (`nemoclaw.js`) and library modules |
| `bin/lib/` | JavaScript (CJS) | Core CLI logic: onboard, credentials, inference, policies, preflight, runner |
| `nemoclaw/` | TypeScript | Plugin project (Commander CLI extension for OpenClaw) |
| `nemoclaw/src/blueprint/` | TypeScript | Runner, snapshot, SSRF validation, state management |
| `nemoclaw/src/commands/` | TypeScript | Slash commands, migration state |
| `nemoclaw/src/onboard/` | TypeScript | Onboarding config |
| `nemoclaw-blueprint/` | YAML | Blueprint definition and network policies |
| `scripts/` | Bash/JS/TS | Install helpers, setup, automation, E2E tooling |
| `test/` | JavaScript (ESM) | Root-level integration tests (Vitest) |
| `test/e2e/` | Bash/JS | End-to-end tests (Brev cloud instances) |
| `docs/` | Markdown (MyST) | User-facing docs (Sphinx) |
| `k8s/` | YAML | Kubernetes deployment manifests |

## Development Commands

```bash
# Install dependencies
npm install # root deps (OpenClaw + CLI)
cd nemoclaw && npm install && npm run build && cd .. # TypeScript plugin
cd nemoclaw-blueprint && uv sync && cd .. # Python deps

# Build
cd nemoclaw && npm run build # compile TypeScript plugin
cd nemoclaw && npm run dev # watch mode

# Test
npm test # root-level tests (Vitest)
cd nemoclaw && npm test # plugin unit tests (Vitest)

# Lint / check
make check # all linters via prek (pre-commit hooks)
npx prek run --all-files # same as make check
npm run typecheck:cli # type-check CLI (bin/, scripts/)

# Format
make format # auto-format TypeScript

# Docs
make docs # build docs (Sphinx/MyST)
make docs-live # serve locally with auto-rebuild
```

## Test Structure

- **Root tests** (`test/*.test.js`): Integration tests run via Vitest (ESM)
- **Plugin tests** (`nemoclaw/src/**/*.test.ts`): Unit tests co-located with source
- **E2E tests** (`test/e2e/`): Cloud-based E2E on Brev instances, triggered only when `BREV_API_TOKEN` is set

Vitest config (`vitest.config.ts`) defines three projects: `cli`, `plugin`, and `e2e-brev`.

## Code Style and Conventions

### Commit Messages

Conventional Commits required. Enforced by commitlint via prek `commit-msg` hook.

```text
<type>(<scope>): <description>
```

Types: `feat`, `fix`, `docs`, `chore`, `refactor`, `test`, `ci`, `perf`, `merge`

### SPDX Headers

Every source file must include an SPDX license header. The pre-commit hook auto-inserts them:

```javascript
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
```

For shell scripts use `#` comments. For Markdown use HTML comments.

### JavaScript

- `bin/` and `scripts/`: **CommonJS** (`require`/`module.exports`), Node.js 22.16+
- `test/`: **ESM** (`import`/`export`)
- ESLint config in `eslint.config.mjs`
- Cyclomatic complexity limit: 20 (ratcheting down to 15)
- Unused vars pattern: prefix with `_`

### TypeScript

- Plugin code in `nemoclaw/src/` with its own ESLint config
- CLI type-checking via `tsconfig.cli.json`
- Plugin type-checking via `nemoclaw/tsconfig.json`

### Shell Scripts

- ShellCheck enforced (`.shellcheckrc` at root)
- `shfmt` for formatting
- All scripts must have shebangs and be executable

### No External Project Links

Do not add links to third-party code repositories, community collections, or unofficial resources. Links to official tool documentation (Node.js, Python, uv) are acceptable.

## Git Hooks (prek)

All hooks managed by [prek](https://prek.j178.dev/) (installed via `npm install`):

| Hook | What runs |
|------|-----------|
| **pre-commit** | File fixers, formatters, linters, Vitest (plugin) |
| **commit-msg** | commitlint (Conventional Commits) |
| **pre-push** | TypeScript type check (tsc --noEmit for plugin, JS, CLI) |

## Documentation

- Source of truth: `docs/` directory
- `.agents/skills/docs/` is **autogenerated** — never edit directly
- After changing docs, regenerate skills:

```bash
python scripts/docs-to-skills.py docs/ .agents/skills/docs/ --prefix nemoclaw
```

- Follow style guide in `docs/CONTRIBUTING.md`

## PR Requirements

- Create feature branch from `main`
- Run `make check` and `npm test` before submitting
- Follow PR template (`.github/PULL_REQUEST_TEMPLATE.md`)
- Update docs for any user-facing behavior changes
- No secrets, API keys, or credentials committed
- Limit open PRs to fewer than 10
Loading