nemo-helix / web
AGENTS.md138 starsChanged 20 days agoApache-2.0View on GitHub
Cursor/Claude skills for this monorepo live under web/.agents/skills/ (for example unit-test, e2e-test, feature-flags, ux-guidelines, visual-dev, test-coverage-improvement). The kaizen-ui skill is not committed — it is synced from the @nvidia/foundations-react-core design system package on pnpm install (root sync-skills script) and is gitignored. To refresh it after upgrading the package, run pnpm sync-skills from web/. packages/sdk/generated/<service>/ is regenerated per service into one file per OpenAPI tag (e.g. generated/platform/files.ts, generated/agents/agents.ts) — not a single api.ts. Import a hook from its specific tag file:
- Installs packages
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,774 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository18 other files it gives its agents.
- AGENTS.mdAGENTS.md
- docs/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- web/CLAUDE.mdCLAUDE.md
- .cursor/rules/dot-files.mdcCursor rule
- .cursor/rules/nemo-helix.mdcCursor rule
- .cursor/rules/uv.mdcCursor rule
- .cursor/rules/writing-docs.mdcCursor rule
- add-studio-feature-flagSkill
- contributor-create-prSkill
- create-release-notesSkill
- data-designer-skill-refreshSkill
- data-designer-version-bumpSkill
- nhx-cliSkill
- release-test-scopeSkill
- studio-devSkill
- nemo-data-designer-pluginSkill
- nemo-evals-pluginSkill
The file
Show its rules and text
We split this AGENTS.md into the rules it gives an agent
19 rules. About 0 are common, 13 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈13
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 34
Use import type { A } when every specifier is a type.
- Distinctive: line 66
Use pnpm exclusively — never npm or yarn
- Very specific: line 67
Run frontend commands from web/, not from repo root
- Very specific: line 94
Use one of these patterns from web/:
- Distinctive: line 105
If a package defines these scripts, CI will pick them up automatically.
- Very specific: line 112
Prefer interface over type for object shapes and contracts
- Very specific: line 113
Use type for unions, intersections, and computed types
- Distinctive: line 115
Use type assertions sparingly — prefer type guards and narrowing
- Distinctive: line 125
Use descriptive property names with clear types
- Very specific: line 127
Use readonly for immutable properties
- Distinctive: line 131
Prefer arrow functions for short, pure functions
- Distinctive: line 132
Use function declarations for hoisted functions and methods
- Distinctive: line 133
Keep functions small and focused (Single Responsibility Principle)
- Distinctive: line 134
Use explicit return types for public APIs and complex functions
- Distinctive: line 138
Use Result types or discriminated unions for predictable errors
- Distinctive: line 144
Use named exports over default exports
- Distinctive: line 145
Use absolute imports via tsconfig path mapping (never relative)
- Distinctive: line 158
Use generic components for reusable UI patterns
- Distinctive: line 159
Use discriminated unions for variant props
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
<!-- SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. --><!-- SPDX-License-Identifier: Apache-2.0 -->Studio Agent Instructions
Project Context
- NeMo Studio — React + TypeScript monorepo for the NeMo Helix UI
- Tech Stack: React 18, TypeScript, Vite, Vitest, Playwright, pnpm workspaces
- Uses KUI (Kaizen UI) React components, TanStack Query
Agent skills
Cursor/Claude skills for this monorepo live under web/.agents/skills/ (for example unit-test, e2e-test, feature-flags, ux-guidelines, visual-dev, test-coverage-improvement).
The kaizen-ui skill is not committed — it is synced from the @nvidia/foundations-react-core design system package on pnpm install (root sync-skills script) and is gitignored. To refresh it after upgrading the package, run pnpm sync-skills from web/.
Package Overview
- packages/studio — Main React frontend application
- packages/common — Shared code between UI and service
- packages/sdk — Generated API clients and types
- packages/sandbox — Development tools
- packages/storybook — Component stories and documentation
- packages/scripts — Build scripts and utilities
Import Path Rules
- Never use relative imports. This applies to sibling files in the same directory too. Always use the absolute alias path — even
./useSomethingor./typesshould be written as@studio/components/Foo/useSomethingor@nemo/common/src/utils/types. ESLint (no-restricted-importsineslint.config.js) enforces this as an error incommonandstudio. - Import path mappings:
@studio/→packages/studio/src/(inside the studio package)@nemo/common/→packages/common/src/@nemo/sdk→packages/sdk/
- Use
import type { A }when every specifier is a type. When a module supplies both values and types, mark the types inline in one import (import { memo, type FC } from 'react') —no-duplicate-importsrejects a separateimport typeline. ESLint (consistent-type-imports,no-import-type-side-effects) enforces both andpnpm lint:fixapplies them.
Importing the generated SDK
packages/sdk/generated/<service>/ is regenerated per service into one file per
OpenAPI tag (e.g. generated/platform/files.ts, generated/agents/agents.ts) —
not a single api.ts. Import a hook from its specific tag file:
import { useFilesDeleteFileset } from '@nemo/sdk/generated/platform/files';- Never
import * as sdk from '@nemo/sdk/generated/<service>/index'(or the old.../api'path — it no longer exists) just to reach one or two hooks. That barrel re-exports the entire service and defeats the point of the per-tag split; it exists only for the two call sites that genuinely need the whole surface (packages/studio/src/plugins/PluginRenderer.tsxandplugins/types.ts'sPluginSdk). - You don't know which tag file a hook lives in ahead of time — grep
packages/sdk/generated/<service>/*.tsforexport const <hookName>, or let your editor's auto-import resolve it. vi.mock('@nemo/sdk/generated/<service>/api', ...)from before this split no longer resolves. Mock the specific tag file(s) the test actually imports from; if a test's mocked hooks span more than one tag file, that's multiplevi.mock()calls, one per file — don't merge them back into a single call against a nonexistent path.- The generated tree is gitignored and gets rebuilt by
pnpm gen:<service>/pnpm gen:all(seepackages/sdk/package.json) — file layout can shift on regeneration if the OpenAPI spec's tags change.
Package Management
- Use pnpm exclusively — never npm or yarn
- Run frontend commands from
web/, not from repo root - Node.js and pnpm come from the root Flox environment. Run
flox -q activatefor interactive work; Corepack provides the repository-pinned pnpm. - Install dependencies:
pnpm add <package> - Run scripts:
pnpm <script-name>
Bumping a shared singleton also means bumping the plugins
Everything in VENDOR_IMPORT_MAP (packages/studio/vite.config.ts) is served to
plugin bundles from Studio's vendor build, so plugins must leave it external and
never ship their own copy:
| Shared | In the plugin's package.json? |
react, react-dom, react-router, @nvidia/foundations-react-core, @tanstack/react-query | Yes — versions must match the catalog: block |
@nemo/common (Studio's shared UI) | No — unpublished, has no catalog entry, and must not be added as a dependency. Externalized in the plugin's vite.config.ts; types come from paths in its tsconfig.json |
Plugin web dirs are standalone pnpm roots and cannot reference the
catalog: block, so they restate the versions by hand. When you change one of
those catalog entries, update the matching dependencies in every
plugins/*/web/package.json in the same change — otherwise a plugin keeps
typechecking against the old version while Studio serves the new one, and
nothing fails until it breaks at runtime. See
plugins/example-plugin/web/AGENTS.md.
Running Tests Locally
- Never invoke
vitestdirectly (e.g.pnpm vitest --run). Always go through a package'stestscript so env/config (e.g.NODE_OPTIONS=--max-old-space-size=10240instudio) is applied. - Use one of these patterns from
web/:- Whole package:
pnpm --filter <package-name> test(e.g.pnpm --filter nemo-studio-ui test,pnpm --filter @nemo/common test) - Targeted file:
pnpm --filter <package-name> test path/to/file.test.tsx
- Whole package:
CI Scripts Convention
CI automatically discovers and runs specific scripts from each package's package.json. To opt a package into CI checks, add these scripts:
test:ci— Runs tests in CI. Use this for CI-specific config like coverage, reporters, and non-watch mode (e.g.,vitest run --coverage).typecheck— Runs type checking (tsc --noEmit). The same script runs locally and in CI — no separatetypecheck:cineeded.
If a package defines these scripts, CI will pick them up automatically. No additional CI yaml configuration is required.
TypeScript Standards
Type Safety
- Never use
any— useunknownand type guards instead - Prefer
interfaceovertypefor object shapes and contracts - Use
typefor unions, intersections, and computed types - Implement strict null checks and handle undefined/null explicitly
- Use type assertions sparingly — prefer type guards and narrowing
Naming Conventions
camelCasefor variables, functions, and methodsPascalCasefor classes, interfaces, types, and React componentsSCREAMING_SNAKE_CASEfor constants and environment variables
Interface and Type Definitions
- Use descriptive property names with clear types
- Mark optional properties with
?and provide defaults when appropriate - Use
readonlyfor immutable properties
Functions
- Prefer arrow functions for short, pure functions
- Use function declarations for hoisted functions and methods
- Keep functions small and focused (Single Responsibility Principle)
- Use explicit return types for public APIs and complex functions
Error Handling
- Use Result types or discriminated unions for predictable errors
- Throw exceptions only for truly exceptional circumstances
- Implement proper error boundaries in React components
Imports and Exports
- Use named exports over default exports
- Use absolute imports via tsconfig path mapping (never relative)
- Never hand-sort imports — run
pnpm lint:fixfromweb/and leave the result alone.import/orderruns as an error (eslint.config.js) withgroups: [['builtin', 'external'], 'internal', ['parent', 'sibling', 'index']]andalphabetize: { order: 'asc' }. The@nemo/@nvidia/@studioaliases resolve as external, so they share a single alphabetized group withreact,lucide-reactand friends — which sortsreactnear the end. That reads backwards if you expect "third-party first, ours second", but it is the rule's output, and reordering fails CI's--max-warnings 0.
React Patterns
- Define explicit props interfaces for all components
- Use generic components for reusable UI patterns
- Use discriminated unions for variant props
Code Organization
- One class or main function per file
- Co-locate related types with their implementations
- Organize by feature/domain, not by technical layer
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

