Guidance for AI coding assistants (Claude Code, Gemini CLI, and other agentic tools) working in this repository.
Human contributors: start with CONTRIBUTING.md instead. This file adds no policy of its own — it orients an agent and routes it to the canonical docs below.
CLAUDE.md and GEMINI.md exist only so that tools which look for a vendor-specific
filename find this file. They contain a single import line and no content. Support for
another tool is one more one-line file; no assistant gets privileged instructions.
Read the relevant document before working in that area rather than inferring conventions from surrounding code. Do not restate their contents here — these files are the source of truth and this one goes stale if it duplicates them.
| Topic | Document |
|---|---|
| Contribution process, branching, merging, code standards, commit format | CONTRIBUTING.md |
| Public plugin-authoring API reference | API.md |
| Test strategy, coverage, CI troubleshooting | TESTING.md |
| Writing and running Playwright tests, fixtures, CI architecture | e2e/README.md |
| Security policy and vulnerability reporting | SECURITY.md |
| Release process and notable-change policy | docs/src/process/release.md |
| Common coding pitfalls (clean code, function design, Vue and API usage) | docs/src/process/common-coding-pitfalls.md |
Agents should disclose their involvement in contributions. Use an Assisted-by: commit
trailer naming the tool, for example:
Assisted-by: Claude Code
Do not flag issues that npm run lint already catches — ESLint, Prettier, and cspell run
in CI. Spend review effort on what automated checks cannot verify: API compatibility for
third-party plugin authors, test coverage of the changed code path, and adherence to the
conventions in CONTRIBUTING.md that no linter enforces.
Node version is pinned via .nvmrc (nvm use). Install with npm install.
npm start— dev server at http://localhost:8080 (webpack dev config)npm run start:prod— prod webpack confignpm run build— production build plus TS declarations (dist/types)npm run clean— removesdist,node_modules,coverage,html-test-results, and e2e test-results/nyc output. This is a full reset;npm installis required afterward.
npm run lint— runslint:js+lint:vue+lint:spellingnpm run lint:fix— auto-fix JS/Vue lint issues
npm test— full suite, headless Chromenpm run test:debug—KARMA_DEBUG=true, runs in a real Chrome window for interactive debugging- Specs are colocated with source and named
*Spec.js(src/foo/Bar.js→src/foo/BarSpec.js). Karma auto-discovers anything matching that pattern undersrc/. - To run a single spec or suite, temporarily prefix the relevant
describe/itwithf(Jasmine's "focused" variant), thennpm test. Remove it before committing.
- Run
npx playwright installfirst to fetch the browser builds pinned by this Playwright version. A stale or partial~/Library/Caches/ms-playwrightfrom another project fails withExecutable doesn't existeven though some Chromium is cached. npm run test:e2e:ci— the standard functional suite (excludes@couchdband@generatedatatagged tests)npm run test:e2e:local— config meant for local iterationnpm run test:e2e:watch— Playwright UI mode- Single test by name:
npx playwright test --config=e2e/playwright-ci.config.js --project=chrome --grep "<test name>" npm run test:e2e:couchdb— tests tagged@couchdb, needs a CouchDB persistence backend, run with--workers=1npm run test:e2e:visual:ci/:full— Percy.io visual regression, a no-op without aPERCY_TOKENnpm run test:e2e:a11y— accessibility checks (axe + Playwright)npm run test:e2e:checksnapshots/test:e2e:updatesnapshots— pixel snapshot tests. These are discouraged (see e2e/README.md) and must run inside the official Playwright Docker image to match CI.
Open MCT is a browser-based mission control framework built by NASA Ames for visualizing and interacting with telemetry data. It is a plugin-based single-page application: nearly the entire built-in feature set (plots, imagery, display layouts, tables, notifications) is implemented as plugins registered through the same public API available to third-party integrators.
openmct.js instantiates a singleton MCT (extends EventEmitter) and exports it as the
default and as window.openmct. The MCT constructor wires up the core APIs as properties
on itself (this.telemetry, this.objects, this.composition, this.time, this.types,
this.actions, this.user, this.editor, this.router, and more — see src/MCT.js for
the full list) and installs a set of always-on plugins. An application then calls
openmct.install(plugin) for anything else it wants, and finally
openmct.start(domElement) to mount the Vue app (src/ui/layout/AppLayout.vue) and start
routing.
Almost everything is a plugin: a factory function returning an install(openmct) function.
For example src/plugins/clock/plugin.js exports ClockPlugin(options) →
function install(openmct) { ... }. Plugins register against the registries and APIs on
the openmct instance (openmct.types.addType(...),
openmct.objectViews.addProvider(...), openmct.composition.addPolicy(...)) rather than
being wired in centrally. src/plugins/plugins.js is the master export of built-in plugins
(as openmct.plugins.X), most of which are opt-in. A handful are installed unconditionally
in the MCT constructor; those are core, not optional.
- API.md is the canonical reference for the public plugin-authoring API. Consult
it before changing any signature under
src/api/. Those are contracts for external plugin authors, not just internal callers, and changes require senior developer approval. TypeScript declarations are generated (emitDeclarationOnly) fromsrc/api/**/*.jsonly, pertsconfig.json. - Generated code must follow docs/src/process/common-coding-pitfalls.md in addition to the standards in CONTRIBUTING.md.
- Deviating from any documented convention requires two-party agreement between author and reviewer.