diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..6780a87f6 --- /dev/null +++ b/AGENTS.md @@ -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 diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..2e55b43fb --- /dev/null +++ b/CLAUDE.md @@ -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 +(): +``` + +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