{"owner":"nasa","repo":"openmct","hasSkills":true,"totalSkillsCount":13,"totalTokensCount":7712,"categories":["root-instruction","claude-rule","plugin-manifest"],"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md","CLAUDE.md","src/plugins/URLIndicatorPlugin/README.md","src/plugins/autoflow/README.md","src/plugins/filters/README.md","src/plugins/myItems/README.md","src/plugins/performanceIndicator/README.md","src/plugins/persistence/couch/README.md","src/plugins/plan/README.md","src/plugins/plot/README.md","src/plugins/staticRootPlugin/README.md","src/plugins/summaryWidget/README.md","src/plugins/userIndicator/README.md"],"skills":{"AGENTS.md":"# AGENTS.md\n\nGuidance for AI coding assistants (Claude Code, Gemini CLI, and other agentic tools)\nworking in this repository.\n\n**Human contributors:** start with [CONTRIBUTING.md](CONTRIBUTING.md) instead. This file\nadds no policy of its own — it orients an agent and routes it to the canonical docs below.\n\n`CLAUDE.md` and `GEMINI.md` exist only so that tools which look for a vendor-specific\nfilename find this file. They contain a single import line and no content. Support for\nanother tool is one more one-line file; no assistant gets privileged instructions.\n\n## Where the canonical docs live\n\nRead the relevant document before working in that area rather than inferring conventions\nfrom surrounding code. Do not restate their contents here — these files are the source of\ntruth and this one goes stale if it duplicates them.\n\n| Topic | Document |\n| --- | --- |\n| Contribution process, branching, merging, code standards, commit format | [CONTRIBUTING.md](CONTRIBUTING.md) |\n| Public plugin-authoring API reference | [API.md](API.md) |\n| Test strategy, coverage, CI troubleshooting | [TESTING.md](TESTING.md) |\n| Writing and running Playwright tests, fixtures, CI architecture | [e2e/README.md](e2e/README.md) |\n| Security policy and vulnerability reporting | [SECURITY.md](SECURITY.md) |\n| Release process and notable-change policy | [docs/src/process/release.md](docs/src/process/release.md) |\n| Common coding pitfalls (clean code, function design, Vue and API usage) | [docs/src/process/common-coding-pitfalls.md](docs/src/process/common-coding-pitfalls.md) |\n\n## Attribution\n\nAgents should disclose their involvement in contributions. Use an `Assisted-by:` commit\ntrailer naming the tool, for example:\n\n```text\nAssisted-by: Claude Code\n```\n\n## Review scope\n\nDo not flag issues that `npm run lint` already catches — ESLint, Prettier, and cspell run\nin CI. Spend review effort on what automated checks cannot verify: API compatibility for\nthird-party plugin authors, test coverage of the changed code path, and adherence to the\nconventions in CONTRIBUTING.md that no linter enforces.\n\n## Commands\n\nNode version is pinned via `.nvmrc` (`nvm use`). Install with `npm install`.\n\n### Build and run\n\n- `npm start` — dev server at http://localhost:8080 (webpack dev config)\n- `npm run start:prod` — prod webpack config\n- `npm run build` — production build plus TS declarations (`dist/types`)\n- `npm run clean` — removes `dist`, `node_modules`, `coverage`, `html-test-results`, and\n  e2e test-results/nyc output. This is a full reset; `npm install` is required afterward.\n\n### Lint and format\n\n- `npm run lint` — runs `lint:js` + `lint:vue` + `lint:spelling`\n- `npm run lint:fix` — auto-fix JS/Vue lint issues\n\n### Unit tests (Jasmine + Karma)\n\n- `npm test` — full suite, headless Chrome\n- `npm run test:debug` — `KARMA_DEBUG=true`, runs in a real Chrome window for interactive\n  debugging\n- Specs are colocated with source and named `*Spec.js` (`src/foo/Bar.js` →\n  `src/foo/BarSpec.js`). Karma auto-discovers anything matching that pattern under `src/`.\n- To run a single spec or suite, temporarily prefix the relevant `describe`/`it` with `f`\n  (Jasmine's \"focused\" variant), then `npm test`. Remove it before committing.\n\n### e2e, visual, and performance tests (Playwright, in the `e2e/` workspace)\n\n- Run `npx playwright install` first to fetch the browser builds pinned by this Playwright\n  version. A stale or partial `~/Library/Caches/ms-playwright` from another project fails\n  with `Executable doesn't exist` even though *some* Chromium is cached.\n- `npm run test:e2e:ci` — the standard functional suite (excludes `@couchdb` and\n  `@generatedata` tagged tests)\n- `npm run test:e2e:local` — config meant for local iteration\n- `npm run test:e2e:watch` — Playwright UI mode\n- Single test by name:\n  `npx playwright test --config=e2e/playwright-ci.config.js --project=chrome --grep \"<test name>\"`\n- `npm run test:e2e:couchdb` — tests tagged `@couchdb`, needs a CouchDB persistence\n  backend, run with `--workers=1`\n- `npm run test:e2e:visual:ci` / `:full` — Percy.io visual regression, a no-op without a\n  `PERCY_TOKEN`\n- `npm run test:e2e:a11y` — accessibility checks (axe + Playwright)\n- `npm run test:e2e:checksnapshots` / `test:e2e:updatesnapshots` — pixel snapshot tests.\n  These are discouraged (see [e2e/README.md](e2e/README.md)) and must run inside the\n  official Playwright Docker image to match CI.\n\n## Architecture\n\nOpen MCT is a browser-based mission control framework built by NASA Ames for visualizing\nand interacting with telemetry data. It is a plugin-based single-page application: nearly\nthe entire built-in feature set (plots, imagery, display layouts, tables, notifications)\nis implemented as plugins registered through the same public API available to third-party\nintegrators.\n\n### Bootstrapping (`src/MCT.js`, `openmct.js`)\n\n`openmct.js` instantiates a singleton `MCT` (extends `EventEmitter`) and exports it as the\ndefault and as `window.openmct`. The `MCT` constructor wires up the core APIs as properties\non itself (`this.telemetry`, `this.objects`, `this.composition`, `this.time`, `this.types`,\n`this.actions`, `this.user`, `this.editor`, `this.router`, and more — see `src/MCT.js` for\nthe full list) and installs a set of always-on plugins. An application then calls\n`openmct.install(plugin)` for anything else it wants, and finally\n`openmct.start(domElement)` to mount the Vue app (`src/ui/layout/AppLayout.vue`) and start\nrouting.\n\n### Plugin pattern\n\nAlmost everything is a plugin: a factory function returning an `install(openmct)` function.\nFor example `src/plugins/clock/plugin.js` exports `ClockPlugin(options)` →\n`function install(openmct) { ... }`. Plugins register against the registries and APIs on\nthe `openmct` instance (`openmct.types.addType(...)`,\n`openmct.objectViews.addProvider(...)`, `openmct.composition.addPolicy(...)`) rather than\nbeing wired in centrally. `src/plugins/plugins.js` is the master export of built-in plugins\n(as `openmct.plugins.X`), most of which are opt-in. A handful are installed unconditionally\nin the `MCT` constructor; those are core, not optional.\n\n## Rules\n\n- [API.md](API.md) is the canonical reference for the public plugin-authoring API. Consult\n  it before changing any signature under `src/api/`. Those are contracts for external\n  plugin authors, not just internal callers, and changes require senior developer\n  approval. TypeScript declarations are generated (`emitDeclarationOnly`) from\n  `src/api/**/*.js` only, per `tsconfig.json`.\n- Generated code must follow\n  [docs/src/process/common-coding-pitfalls.md](docs/src/process/common-coding-pitfalls.md)\n  in addition to the standards in [CONTRIBUTING.md](CONTRIBUTING.md).\n- Deviating from any documented convention requires two-party agreement between author\n  and reviewer.\n","CLAUDE.md":"- @AGENTS.md\n","src/plugins/URLIndicatorPlugin/README.md":"# URL Indicator\nAdds an indicator which shows the availability of a URL, with success based on receipt of a 200 HTTP code. Can be used \nfor monitoring the availability of web services.\n\n## Installation\n```js\nopenmct.install(openmct.plugins.URLIndicator({\n  url: 'http://localhost:8080',\n    iconClass: 'check',\n    interval: 10000,\n    label: 'Localhost'\n })\n);\n```\n\n## Options\n* __url__: URL to indicate the status of\n* __iconClass__: Icon to show in the status bar, defaults to icon-database. See the [Style Guide](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home/glyphs?view=styleguide.glyphs) for more icon options.\n* __interval__: Interval between checking the connection, defaults to 10000\n* __label__: Name showing up as text in the status bar, defaults to url\n\n","src/plugins/autoflow/README.md":"# Autoflow View\n\nThis plugin provides the Autoflow View for domain objects in Open MCT. This view allows users to visualize the latest \nvalues of a collection of telemetry points in a condensed list.\n\n## Installation\n``` js\n    openmct.install(openmct.plugins.AutoflowView({\n        type: \"telemetry.fixed\"\n    }));\n```\n\n## Options\n* `type`: The object type to add the Autoflow View to. Currently supports a single value. If not provided, will make the \nAutoflow view available for all objects (which is probably not what you want).\n","src/plugins/filters/README.md":"\n# Server side filtering in Open MCT\n\n## Introduction\n\nIn Open MCT, filters can be constructed to filter out telemetry data on the server side. This is useful for reducing the amount of data that needs to be sent to the client. For example, in [Open MCT for MCWS](https://github.com/NASA-AMMOS/openmct-mcws/blob/e8846d325cc3f659d8ad58d1d24efaafbe2b6bb7/src/constants.js#L115), they can be used to filter realtime data from recorded data. In the [Open MCT YAMCS plugin](https://github.com/akhenry/openmct-yamcs/blob/9c4ed03e23848db3215fdb6a988ba34b445a3989/src/providers/events.js#L44), we can use them to filter incoming event data by severity.\n\n## Installing the filter plugin\n\nYou'll need to install the filter plugin first. For example:\n\n```js\nopenmct.install(openmct.plugins.Filters(['telemetry.plot.overlay', 'table']));\n```\n\nwill install the filters plugin and have it apply to overlay plots and tables. You can see an example of this in the [Open MCT YAMCS plugin](https://github.com/akhenry/openmct-yamcs/blob/9c4ed03e23848db3215fdb6a988ba34b445a3989/example/index.js#L58).\n\n## Defining a filter\n\nTo define a filter, you'll need to add a new `filter` property to the domain object's `telemetry` metadata underneath the `values` array. For example, if you have a domain object with a `telemetry` metadata that looks like this:\n\n```js\n{\n    key: 'fruit',\n    name: 'Types of fruit',\n    filters: [{\n        singleSelectionThreshold: true,\n        comparator: 'equals',\n        possibleValues: [\n            { label: 'Apple', value: 'apple' },\n            { label: 'Banana', value: 'banana' },\n            { label: 'Orange', value: 'orange' }\n        ]\n    }]\n}\n```\n\nThis will define a filter that allows an operator to choose one (due to `singleSelectionThreshold` being `true`) of the three possible values. The `comparator` property defines how the filter will be applied to the telemetry data.\nSetting `singleSelectionThreshold` to `false` will render the `possibleValues` as a series of checkboxes. Removing the `possibleValues` property will render the filter as a text box, allowing the operator to enter a value to filter on.\n\nNote that how the filter is interpreted is ultimately decided by the individual telemetry providers.\n\n## Implementing a filter in a telemetry provider\n\nImplementing a filter requires two parts:\n\n- First, one needs to add the filter implementation to the [subscribe](https://github.com/nasa/openmct/blob/5df7971438acb9e8b933edda2aed432b1b8bb27d/src/api/telemetry/TelemetryAPI.js#L366) method in your telemetry provider. The filter will be passed to you in the `options` argument. You can either add the filter to your telemetry subscription request, or filter manually as new messages appears. An example of the latter is [shown in the YAMCS plugin for Open MCT](https://github.com/akhenry/openmct-yamcs/blob/9c4ed03e23848db3215fdb6a988ba34b445a3989/src/providers/events.js#L95).\n\n- Second, one needs to add the filter implementation to the [request](https://github.com/nasa/openmct/blob/5df7971438acb9e8b933edda2aed432b1b8bb27d/src/api/telemetry/TelemetryAPI.js#L318) method in your telemetry provider. The filter again will be passed to you in the `options` argument. You can either add the filter to your telemetry request, or filter manually after the request is made. An example of the former is [shown in the YAMCS plugin for Open MCT](https://github.com/akhenry/openmct-yamcs/blob/9c4ed03e23848db3215fdb6a988ba34b445a3989/src/providers/historical-telemetry-provider.js#L171).\n\n## Using filters\n\nIf you installed the plugin to have it apply to `table`, create a Telemetry Table in Open MCT and drag your telemetry object that contains the filter to it. Then click \"Edit\", and notice the \"Filter\" tab in the inspector. It allows operator to either select a \"Global Filter\", or a regular filter. The \"Global Filter\" will apply for all telemetry objects in the table, while the regular filter will only apply to the telemetry object that it is defined on.","src/plugins/myItems/README.md":"# My Items plugin\nDefines top-level folder named \"My Items\" to store user-created items. Enabled by default, this can be disabled in a read-only deployment with no user-editable objects.\n\n## Installation\n```js\nopenmct.install(openmct.plugins.MyItems());\n```\n\n## Options\nWhen installing, the plugin can take several options:\n\n- `name`: The label of the root object. Defaults to \"My Items\"\n  - Example: `'Apple Items'`\n\n- `namespace`: The namespace to create the root object in. Defaults to the empty string `''`\n  - Example: `'apple-namespace'`\n\n- `priority`: The optional priority to install this plugin. Defaults to `openmct.priority.LOW`\n  - Example: `'openmct.priority.LOW'`\n\nE.g., to install with a custom name and namespace, you could use:\n\n\n```js\nopenmct.install(openmct.plugins.MyItems('Apple Items', 'apple-namespace'));\n```","src/plugins/performanceIndicator/README.md":"# URL Indicator\nAdds an indicator which shows the number of frames that the browser is able to render per second. This is a useful proxy for the maximum number of updates that any telemetry display can perform per second. This may be useful during performance testing, but probably should not be enabled by default. \n\nThis indicator adds adds about 3% points to CPU usage in the Chrome task manager.\n\n## Installation\n```js\nopenmct.install(openmct.plugins.PerformanceIndicator());\n```","src/plugins/persistence/couch/README.md":"\n# Installing CouchDB\n\n## Introduction\n\nThese instructions are for setting up CouchDB for a **development** environment. For a production environment, we recommend running Open MCT behind a proxy server (e.g., Nginx or Apache), and securing the CouchDB server properly:\n<https://docs.couchdb.org/en/main/intro/security.html>\n\n## Docker Quickstart\n\nThe following process is the preferred way of using CouchDB as it is automatic and closely resembles a production environment.\n\nRequirement:\nGet docker compose (or recent version of docker) installed on your machine. We recommend [Docker Desktop](https://www.docker.com/products/docker-desktop/)\n\n1. Open a terminal to this current working directory (`cd openmct/src/plugins/persistence/couch`)\n2. Create and start the `couchdb` container:\n\n```sh\ndocker compose -f ./couchdb-compose.yaml up --detach\n```\n\n3. Copy `.env.ci` file to file named `.env.local`\n4. (Optional) Change the values of `.env.local` if desired\n5. Set the environment variables in bash by sourcing the env file\n\n```sh\nexport $(cat .env.local | xargs)\n```\n\n6. Execute the configuration script:\n\n```sh\nsh ./setup-couchdb.sh\n```\n\n7. `cd` to the workspace root directory (the same directory as `index.html`)\n8. Update `index.html` to use the CouchDB plugin as persistence store:\n\n```sh\nsh ./src/plugins/persistence/couch/replace-localstorage-with-couchdb-indexhtml.sh\n```\n\n9. ✅ Done!\n\nOpen MCT will now use your local CouchDB container as its persistence store. Access the CouchDB instance manager by visiting <http://localhost:5984/_utils>.\n\n### Removing CouchDB Container completely\n\nTo completely remove the CouchDB container and volumes:\n\n```sh\ndocker stop couch-couchdb-1;docker rm couch-couchdb-1;docker volume rm couch_couchdb\n```\n\n## macOS\n\nWe highly recommend using the CouchDB `docker compose` method of installation, though it is still possible to install CouchDB through other means.\n\n### Installing CouchDB\n\n1. Install CouchDB using: `brew install couchdb`.\n2. Edit `/usr/local/etc/local.ini` and add the following settings:\n\n  ```ini\n  [admins]\n  admin = youradminpassword\n  ```\n\n  And set the server up for single node:\n\n  ```ini\n  [couchdb]\n  single_node=true\n  ```\n\n  Enable CORS\n\n  ```ini\n  [chttpd]\n  enable_cors = true\n  [cors]\n  origins = http://localhost:8080\n  ```\n\n### Installing CouchDB without admin privileges to your computer\n\nIf `brew` is not available on your mac machine, you'll need to get the CouchDB installed using the official sourcefiles.\n\n1. Install CouchDB following these instructions: <https://docs.brew.sh/Installation#untar-anywhere>.\n1. Edit `local.ini` in Homebrew's `/etc/` directory as directed above in the 'Installing with admin privileges to your computer' section.\n\n## Other Operating Systems\n\nFollow the installation instructions from the CouchDB installation guide: <https://docs.couchdb.org/en/stable/install/index.html>\n\n# Configuring CouchDB\n\n## Configuration script\n\nThe simplest way to config a CouchDB instance is to use our provided tooling:\n\n1. Copy `.env.ci` file to file named `.env.local`\n2. Set the environment variables in bash by sourcing the env file\n\n```sh\nexport $(cat .env.local | xargs)\n```\n\n3. Execute the configuration script:\n\n```sh\nsh ./setup-couchdb.sh\n```\n\n## Manual Configuration\n\n1. Start CouchDB by running: `couchdb`.\n2. Add the `_global_changes` database using `curl` (note the `youradminpassword` should be changed to what you set above 👆): `curl -X PUT http://admin:youradminpassword@127.0.0.1:5984/_global_changes`\n3. Navigate to <http://localhost:5984/_utils>\n4. Create a database called `openmct`\n5. Navigate to <http://127.0.0.1:5984/_utils/#/database/openmct/permissions>\n6. Remove permission restrictions in CouchDB from Open MCT by deleting `_admin` roles for both `Admin` and `Member`.\n\n## Document Sizes\n\nCouchDB has size limits on both its internal documents, and its httpd interface. If dealing with larger documents in Open MCT (e.g., users adding images to notebook entries), you may to increase this limit. To do this, add the following to the two sections:\n\n```ini\n  [couchdb]\n  max_document_size = 4294967296 ; approx 4 GB\n  \n  [chttpd]\n  max_http_request_size = 4294967296 ; approx 4 GB\n```\n  \nIf not present, add them under proper sections. The values are in bytes, and can be adjusted to whatever is appropriate for your use case.\n\n# Configuring Open MCT to use CouchDB\n\n## Configuration script\n\nThe simplest way to config a CouchDB instance is to use our provided tooling:\n\n1. `cd` to the workspace root directory (the same directory as `index.html`)\n2. Update `index.html` to use the CouchDB plugin as persistence store:\n\n```sh\nsh ./src/plugins/persistence/couch/replace-localstorage-with-couchdb-indexhtml.sh\n```\n\n## Manual Configuration\n\n1. Edit `openmct/index.html` comment out the following line:\n\n  ```js\n  openmct.install(openmct.plugins.LocalStorage());\n  ```\n\n  Add a line to install the CouchDB plugin for Open MCT:\n\n  ```js\n  openmct.install(\n        openmct.plugins.CouchDB({\n          databases: [\n            {\n              url: 'http://localhost:5984/openmct',\n              namespace: '',\n              additionalNamespaces: [],\n              readOnly: false,\n              useDesignDocuments: false,\n              indicator: true\n            }\n          ]\n        })\n      );\n  ```\n\n### Configuration Options for OpenMCT\n\nWhen installing the CouchDB plugin for OpenMCT, you can specify a list of databases with configuration options for each. Here's a breakdown of the available options for each database:\n\n- `url`: The URL to the CouchDB instance, specifying the protocol, hostname, and port as needed.\n  - Example: `'http://localhost:5984/openmct'`\n\n- `namespace`: The namespace associated with this database.\n  - Example: `'openmct-sandbox'`\n\n- `additionalNamespaces`: Other namespaces that this plugin should respond to requests for.\n  - Example: `['apple-namespace', 'pear-namespace']`\n\n- `readOnly`: A boolean indicating whether the database should be treated as read-only. If set to `true`, OpenMCT will not attempt to write to this database.\n  - Example: `false`\n\n- `useDesignDocuments`: Indicates whether design documents should be used to speed up annotation search.\n  - Example: `false`\n\n- `indicator`: A boolean to specify whether an indicator should show the status of this CouchDB connection in the OpenMCT interface.\n  - Example: `true`\n\nNote: If using the `exampleTags` plugin with non-blank namespaces, you'll need to configure it point to a writable database. For example:\n\n```js\nopenmct.install(\n        openmct.plugins.example.ExampleTags({ namespaceToSaveAnnotations: 'openmct-sandbox' })\n      );\n```\n\nNote: If using the `MyItems` plugin, be sure to configure a root for each writable namespace. E.g., if you have two namespaces called `apple-namespace` and `pear-namespace`:\n\n```js\n      openmct.install(openmct.plugins.MyItems('Apple Items', 'apple-namespace'));\n      openmct.install(openmct.plugins.MyItems('Pear Items', 'pear-namespace'));\n```\n\nThis will create a root object with the id of `mine` in both namespaces upon load if not already created.\n\n# Validating a successful Installation\n\n1. Start Open MCT by running `npm start` in the `openmct` path.\n2. Navigate to <http://localhost:8080/> and create a random object in Open MCT (e.g., a 'Clock') and save.\n3. Navigate to: <http://127.0.0.1:5984/_utils/#database/openmct/_all_docs>\n4. Look at the 'JSON' tab and ensure you can see the specific object you created above.\n5. All done! 🏆\n\n# Maintenance\n\nOne can delete annotations by running inside this directory (i.e., `src/plugins/persistence/couch`):\n\n```sh\nnpm run deleteAnnotations:openmct:PIXEL_SPATIAL\n```\n\nwill delete all image tags.\n\n```sh\nnpm run deleteAnnotations:openmct \n```\n\nwill delete all tags.\n\n```sh\nnpm run deleteAnnotations:openmct -- --help\n```\n\nwill print help options.\n\n# Search Performance\n\nFor large Open MCT installations, it may be helpful to add additional CouchDB capabilities to bear to improve performance.\n\n## Indexing\n\nIndexing the `model.type` field in CouchDB can benefit the performance of queries significantly, particularly if there are a large number of documents in the database. An index can accelerate annotation searches by reducing the number of documents that the database needs to examine.\n\nTo create an index for `model.type`, you can use the following payload [using the API](https://docs.couchdb.org/en/stable/api/database/find.html#post--db-_index):\n\n```json\n{\n  \"index\": {\n    \"fields\": [\"model.type\", \"model.tags\"]\n  },\n  \"name\": \"type_tags_index\",\n  \"type\": \"json\"\n}\n```\n\nThis instructs CouchDB to create an index on the `model.type` field and the `model.tags` field. Once this index is created, queries that include a selector on `model.type` and `model.tags` (like when searching for tags) can use this index to retrieve results faster.\n\nYou can find more detailed information about indexing in CouchDB in the [official documentation](https://docs.couchdb.org/en/stable/api/database/find.html#db-index).\n\n## Design Documents\n\nWe can also add a design document [through the API](https://docs.couchdb.org/en/stable/api/ddoc/common.html#put--db-_design-ddoc) for retrieving domain objects for specific tags:\n\n```json\n{\n  \"_id\": \"_design/annotation_tags_index\",\n  \"views\": {\n    \"by_tags\": {\n      \"map\": \"function (doc) { if (doc.model && doc.model.type === 'annotation' && doc.model.tags) { doc.model.tags.forEach(function (tag) { emit(tag, doc._id); }); } }\"\n    }\n  }\n}\n```\n\nand can be retrieved by issuing a `GET` to <http://localhost:5984/openmct/_design/annotation_tags_index/_view/by_tags?keys=[\"TAG_ID_TO_SEARCH_FOR\"]&include_docs=true>\nwhere `TAG_ID_TO_SEARCH_FOR` is the tag UUID we're looking for.\n\nand for targets:\n\n```javascript\n{\n  \"_id\": \"_design/annotation_keystring_index\",\n  \"views\": {\n    \"by_keystring\": {\n      \"map\": \"function (doc) { if (doc.model && doc.model.type === 'annotation' && doc.model.targets) { doc.model.targets.forEach(function(target) { if(target.keyString) { emit(target.keyString, doc._id); } }); } }\"\n    }\n  }\n}\n```\n\nand can be retrieved by issuing a `GET` to <http://localhost:5984/openmct/_design/annotation_keystring_index/_view/by_keystring?keys=[\"KEY_STRING_TO_SEARCH_FOR\"]&include_docs=true>\nwhere `KEY_STRING_TO_SEARCH_FOR` is the UUID we're looking for.\n\nTo enable them in Open MCT, we need to configure the plugin `useDesignDocuments` like so:\n\n  ```js\n  openmct.install(openmct.plugins.CouchDB({url: \"http://localhost:5984/openmct\", useDesignDocuments: true}));\n  ```\n","src/plugins/plan/README.md":"# Plan view and domain objects\nPlans provide a view for a list of activities grouped by categories.\n\n## Plan category and activity JSON format\nThe JSON format for a plan consists of categories/groups and a list of activities for each category.\nActivity properties include:\n* name: Name of the activity\n* start: Timestamps in milliseconds\n* end: Timestamps in milliseconds\n* type: Matches the name of the category it is in\n* color: Background color for the activity\n* textColor: Color of the name text for the activity\n* The format of the json file is as follows:\n\n```json\n{\n    \"TEST_GROUP\": [{\n    \"name\": \"Event 1 with a really long name\",\n    \"start\": 1665323197000,\n    \"end\": 1665344921000,\n    \"type\": \"TEST_GROUP\",\n    \"color\": \"orange\",\n    \"textColor\": \"white\"\n    }],\n    \"GROUP_2\": [{\n    \"name\": \"Event 2\",\n    \"start\": 1665409597000,\n    \"end\": 1665456252000,\n    \"type\": \"GROUP_2\",\n    \"color\": \"red\",\n    \"textColor\": \"white\"\n    }]\n}\n```\n\n## Plans using JSON file uploads\nPlan domain objects can be created by uploading a JSON file with the format above to render categories and activities.\n\n## Using Domain Objects directly\nIf uploading a JSON is not desired, it is possible to visualize domain objects of type 'plan'.\nThe standard model is as follows: \n```javascript\n{\n    identifier: {\n        namespace: \"\"\n        key: \"test-plan\"\n    }\n    name:\"A plan object\",\n    type:\"plan\",\n    location:\"ROOT\",\n    selectFile: {\n        body: {\n            SOME_CATEGORY: [{\n                    name: \"An activity\",\n                    start: 1665323197000,\n                    end: 1665323197100,\n                    type: \"SOME_CATEGORY\"\n                }\n            ],\n            ANOTHER_CATEGORY: [{\n                    name: \"An activity\",\n                    start: 1665323197000,\n                    end: 1665323197100,\n                    type: \"ANOTHER_CATEGORY\"\n                }\n            ]\n        }\n    }\n}\n```\n\nIf your data has non-standard keys for `start, end, type and activities` properties, use the `sourceMap` property mapping.\n```javascript\n{\n    identifier: {\n        namespace: \"\"\n        key: \"another-test-plan\"\n    }\n    name:\"Another plan object\",\n    type:\"plan\",\n    location:\"ROOT\",\n    sourceMap: {\n        start: 'start_time',\n        end: 'end_time',\n        activities: 'items',\n        groupId: 'category'\n    },\n    selectFile: {\n        body: {\n            items: [\n                {\n                    name: \"An activity\",\n                    start_time: 1665323197000,\n                    end_time: 1665323197100,\n                    category: \"SOME_CATEGORY\"\n                },\n                {\n                    name: \"Another activity\",\n                    start_time: 1665323198000,\n                    end_time: 1665323198100,\n                    category: \"ANOTHER_CATEGORY\"\n                }\n            ]\n        }\n    }\n}\n```\n\n## Rendering categories and activities:\nThe algorithm to render categories and activities on a canvas is as follows:\n* Each category gets a swimlane.\n* Activities within a category are rendered within it's swimlane.\n* Render each activity on a given row if it's duration+label do not overlap (start/end times) with an existing activity on that row.\n* Move to the next available row within a swimlane if there is overlap\n* Labels for a given activity will be rendered within it's duration slot if it fits in that rectangular space.\n* Labels that do not fit within an activity's duration slot are rendered outside, to the right of the duration slot.\n\n","src/plugins/plot/README.md":"# Plot Plugin\n\nEnables plot visualization of telemetry data. This plugin adds a plot view that is available from the view switcher for \nall telemetry objects. Two user createable objects are also added by this plugin, for Overlay and Stacked Plots. \nTelemetry objects can be added to Overlay and Stacked Plots via drag and drop.\n\n## Installation\n``` js\nopenmct.install(openmct.plugins.Plot());\n```","src/plugins/staticRootPlugin/README.md":"# Static Root Plugin\n\nThis plugin takes an object tree as JSON and exposes it as a non-editable root level tree. This can be useful if you \nhave static non-editable content that you wish to expose, such as a standard set of displays that should not be edited \n(but which can be copied and then modified if desired).\n\nAny object tree in Open MCT can be exported as JSON after installing the \n[Import/Export plugin](../../../platform/import-export/README.md).\n\n## Installation\n``` js\nopenmct.install(openmct.plugins.StaticRootPlugin({ namespace: 'mission', exportUrl: 'data/static-objects.json' }));\n```\n\n## Parameters\nThe StaticRootPlugin takes two parameters:\n1. __namespace__: This should be a name that uniquely identifies this collection of objects.\n2. __exportUrl__: The file that the static tree should be exposed from. This will need to be a path that is reachable by a web \nbrowser, ie not a path on the local file system.","src/plugins/summaryWidget/README.md":"# Summary Widget Plugin\nSummary widgets can be used to provide visual indication of state based on telemetry data. They allow rules to be \ndefined that can then be used to change the appearance of the summary widget element based on data. For example, a \nsummary widget could be defined that is green when a temperature reading is between `0` and `100` centigrade, red when \nit's above `100`, and orange when it's below `0`.\n\n## Installation\n```js\nopenmct.install(openmct.plugins.SummaryWidget());\n```","src/plugins/userIndicator/README.md":"# User Indicator\n\nThis plugin provides a user indicator for the top status bar that displays user information as\ndefined by a User Provider. A User Provider must be registered as a prerequisite for this plugin.\n\nIf the User Provider supports role-based access control, the user indicator will display the user's\ncurrent role and, if the user has multiple roles, allow the user to switch between them.\n\n## Usage\n\nTo use this plugin, first register a custom User Provider with the `openmct` API, or install the example\nUser Provider plugin:\n\n```javascript\nopenmct.install(openmct.plugins.example.ExampleUser());\n```\n\nThen, install the User Indicator plugin:\n\n```javascript\nopenmct.install(openmct.plugins.UserIndicator());\n```\n\n## Configuration\n\nThe User Indicator plugin does not require any configuration itself.\n\n## Mission Status\n\n\"Mission Status\" is a feature that is used to indicate the current state of a mission with regards to\none or more \"Mission Actions\". A mission action defines a verb that may be, for example, a task \nfor a spacecraft (such as \"Drive\" or \"Imagery\"), a change in the state of a ground system, or any \nother event that is relevant to the mission. Example states for a mission action might include\n\"Go\" or \"No Go\", indicating whether a particular action is currently cleared for execution.\n\nA user with the appropriate permissions may set the mission status by clicking on either the\nUser Indicator itself, or the \"Mission Status\" button next to the User Indicator. This will\nopen a dialog that allows the user to set the status of each mission action.\n\n### Provider Configuration\n\nIn order to use the Mission Status feature, a registered User Provider must define the following\nmethods:\n\n* `canSetMissionStatus`: A method that returns a boolean indicating whether the current user has\n  permission to set the mission status.\n* `getPossibleMissionActions`: A method that returns an array of mission actions that the user\n  may set the status of. Each mission action should have a `key` and a `name` property.\n* `getPossibleMissionActionStatuses`: A method that returns an array of `MissionStatusOption` objects,\n  which define the possible statuses for each mission action.\n* `getStatusForMissionAction`: A method that returns the current status for a given mission action.\n* `setStatusForMissionAction`: A method that sets the status for a given mission action.\n\nThe [Example User Provider](../../../example/exampleUser/ExampleUserProvider.js) provides an example\nimplementation of these methods.\n"},"files":{"AGENTS.md":"# AGENTS.md\n\nGuidance for AI coding assistants (Claude Code, Gemini CLI, and other agentic tools)\nworking in this repository.\n\n**Human contributors:** start with [CONTRIBUTING.md](CONTRIBUTING.md) instead. This file\nadds no policy of its own — it orients an agent and routes it to the canonical docs below.\n\n`CLAUDE.md` and `GEMINI.md` exist only so that tools which look for a vendor-specific\nfilename find this file. They contain a single import line and no content. Support for\nanother tool is one more one-line file; no assistant gets privileged instructions.\n\n## Where the canonical docs live\n\nRead the relevant document before working in that area rather than inferring conventions\nfrom surrounding code. Do not restate their contents here — these files are the source of\ntruth and this one goes stale if it duplicates them.\n\n| Topic | Document |\n| --- | --- |\n| Contribution process, branching, merging, code standards, commit format | [CONTRIBUTING.md](CONTRIBUTING.md) |\n| Public plugin-authoring API reference | [API.md](API.md) |\n| Test strategy, coverage, CI troubleshooting | [TESTING.md](TESTING.md) |\n| Writing and running Playwright tests, fixtures, CI architecture | [e2e/README.md](e2e/README.md) |\n| Security policy and vulnerability reporting | [SECURITY.md](SECURITY.md) |\n| Release process and notable-change policy | [docs/src/process/release.md](docs/src/process/release.md) |\n| Common coding pitfalls (clean code, function design, Vue and API usage) | [docs/src/process/common-coding-pitfalls.md](docs/src/process/common-coding-pitfalls.md) |\n\n## Attribution\n\nAgents should disclose their involvement in contributions. Use an `Assisted-by:` commit\ntrailer naming the tool, for example:\n\n```text\nAssisted-by: Claude Code\n```\n\n## Review scope\n\nDo not flag issues that `npm run lint` already catches — ESLint, Prettier, and cspell run\nin CI. Spend review effort on what automated checks cannot verify: API compatibility for\nthird-party plugin authors, test coverage of the changed code path, and adherence to the\nconventions in CONTRIBUTING.md that no linter enforces.\n\n## Commands\n\nNode version is pinned via `.nvmrc` (`nvm use`). Install with `npm install`.\n\n### Build and run\n\n- `npm start` — dev server at http://localhost:8080 (webpack dev config)\n- `npm run start:prod` — prod webpack config\n- `npm run build` — production build plus TS declarations (`dist/types`)\n- `npm run clean` — removes `dist`, `node_modules`, `coverage`, `html-test-results`, and\n  e2e test-results/nyc output. This is a full reset; `npm install` is required afterward.\n\n### Lint and format\n\n- `npm run lint` — runs `lint:js` + `lint:vue` + `lint:spelling`\n- `npm run lint:fix` — auto-fix JS/Vue lint issues\n\n### Unit tests (Jasmine + Karma)\n\n- `npm test` — full suite, headless Chrome\n- `npm run test:debug` — `KARMA_DEBUG=true`, runs in a real Chrome window for interactive\n  debugging\n- Specs are colocated with source and named `*Spec.js` (`src/foo/Bar.js` →\n  `src/foo/BarSpec.js`). Karma auto-discovers anything matching that pattern under `src/`.\n- To run a single spec or suite, temporarily prefix the relevant `describe`/`it` with `f`\n  (Jasmine's \"focused\" variant), then `npm test`. Remove it before committing.\n\n### e2e, visual, and performance tests (Playwright, in the `e2e/` workspace)\n\n- Run `npx playwright install` first to fetch the browser builds pinned by this Playwright\n  version. A stale or partial `~/Library/Caches/ms-playwright` from another project fails\n  with `Executable doesn't exist` even though *some* Chromium is cached.\n- `npm run test:e2e:ci` — the standard functional suite (excludes `@couchdb` and\n  `@generatedata` tagged tests)\n- `npm run test:e2e:local` — config meant for local iteration\n- `npm run test:e2e:watch` — Playwright UI mode\n- Single test by name:\n  `npx playwright test --config=e2e/playwright-ci.config.js --project=chrome --grep \"<test name>\"`\n- `npm run test:e2e:couchdb` — tests tagged `@couchdb`, needs a CouchDB persistence\n  backend, run with `--workers=1`\n- `npm run test:e2e:visual:ci` / `:full` — Percy.io visual regression, a no-op without a\n  `PERCY_TOKEN`\n- `npm run test:e2e:a11y` — accessibility checks (axe + Playwright)\n- `npm run test:e2e:checksnapshots` / `test:e2e:updatesnapshots` — pixel snapshot tests.\n  These are discouraged (see [e2e/README.md](e2e/README.md)) and must run inside the\n  official Playwright Docker image to match CI.\n\n## Architecture\n\nOpen MCT is a browser-based mission control framework built by NASA Ames for visualizing\nand interacting with telemetry data. It is a plugin-based single-page application: nearly\nthe entire built-in feature set (plots, imagery, display layouts, tables, notifications)\nis implemented as plugins registered through the same public API available to third-party\nintegrators.\n\n### Bootstrapping (`src/MCT.js`, `openmct.js`)\n\n`openmct.js` instantiates a singleton `MCT` (extends `EventEmitter`) and exports it as the\ndefault and as `window.openmct`. The `MCT` constructor wires up the core APIs as properties\non itself (`this.telemetry`, `this.objects`, `this.composition`, `this.time`, `this.types`,\n`this.actions`, `this.user`, `this.editor`, `this.router`, and more — see `src/MCT.js` for\nthe full list) and installs a set of always-on plugins. An application then calls\n`openmct.install(plugin)` for anything else it wants, and finally\n`openmct.start(domElement)` to mount the Vue app (`src/ui/layout/AppLayout.vue`) and start\nrouting.\n\n### Plugin pattern\n\nAlmost everything is a plugin: a factory function returning an `install(openmct)` function.\nFor example `src/plugins/clock/plugin.js` exports `ClockPlugin(options)` →\n`function install(openmct) { ... }`. Plugins register against the registries and APIs on\nthe `openmct` instance (`openmct.types.addType(...)`,\n`openmct.objectViews.addProvider(...)`, `openmct.composition.addPolicy(...)`) rather than\nbeing wired in centrally. `src/plugins/plugins.js` is the master export of built-in plugins\n(as `openmct.plugins.X`), most of which are opt-in. A handful are installed unconditionally\nin the `MCT` constructor; those are core, not optional.\n\n## Rules\n\n- [API.md](API.md) is the canonical reference for the public plugin-authoring API. Consult\n  it before changing any signature under `src/api/`. Those are contracts for external\n  plugin authors, not just internal callers, and changes require senior developer\n  approval. TypeScript declarations are generated (`emitDeclarationOnly`) from\n  `src/api/**/*.js` only, per `tsconfig.json`.\n- Generated code must follow\n  [docs/src/process/common-coding-pitfalls.md](docs/src/process/common-coding-pitfalls.md)\n  in addition to the standards in [CONTRIBUTING.md](CONTRIBUTING.md).\n- Deviating from any documented convention requires two-party agreement between author\n  and reviewer.\n","CLAUDE.md":"- @AGENTS.md\n","src/plugins/URLIndicatorPlugin/README.md":"# URL Indicator\nAdds an indicator which shows the availability of a URL, with success based on receipt of a 200 HTTP code. Can be used \nfor monitoring the availability of web services.\n\n## Installation\n```js\nopenmct.install(openmct.plugins.URLIndicator({\n  url: 'http://localhost:8080',\n    iconClass: 'check',\n    interval: 10000,\n    label: 'Localhost'\n })\n);\n```\n\n## Options\n* __url__: URL to indicate the status of\n* __iconClass__: Icon to show in the status bar, defaults to icon-database. See the [Style Guide](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home/glyphs?view=styleguide.glyphs) for more icon options.\n* __interval__: Interval between checking the connection, defaults to 10000\n* __label__: Name showing up as text in the status bar, defaults to url\n\n","src/plugins/autoflow/README.md":"# Autoflow View\n\nThis plugin provides the Autoflow View for domain objects in Open MCT. This view allows users to visualize the latest \nvalues of a collection of telemetry points in a condensed list.\n\n## Installation\n``` js\n    openmct.install(openmct.plugins.AutoflowView({\n        type: \"telemetry.fixed\"\n    }));\n```\n\n## Options\n* `type`: The object type to add the Autoflow View to. Currently supports a single value. If not provided, will make the \nAutoflow view available for all objects (which is probably not what you want).\n","src/plugins/filters/README.md":"\n# Server side filtering in Open MCT\n\n## Introduction\n\nIn Open MCT, filters can be constructed to filter out telemetry data on the server side. This is useful for reducing the amount of data that needs to be sent to the client. For example, in [Open MCT for MCWS](https://github.com/NASA-AMMOS/openmct-mcws/blob/e8846d325cc3f659d8ad58d1d24efaafbe2b6bb7/src/constants.js#L115), they can be used to filter realtime data from recorded data. In the [Open MCT YAMCS plugin](https://github.com/akhenry/openmct-yamcs/blob/9c4ed03e23848db3215fdb6a988ba34b445a3989/src/providers/events.js#L44), we can use them to filter incoming event data by severity.\n\n## Installing the filter plugin\n\nYou'll need to install the filter plugin first. For example:\n\n```js\nopenmct.install(openmct.plugins.Filters(['telemetry.plot.overlay', 'table']));\n```\n\nwill install the filters plugin and have it apply to overlay plots and tables. You can see an example of this in the [Open MCT YAMCS plugin](https://github.com/akhenry/openmct-yamcs/blob/9c4ed03e23848db3215fdb6a988ba34b445a3989/example/index.js#L58).\n\n## Defining a filter\n\nTo define a filter, you'll need to add a new `filter` property to the domain object's `telemetry` metadata underneath the `values` array. For example, if you have a domain object with a `telemetry` metadata that looks like this:\n\n```js\n{\n    key: 'fruit',\n    name: 'Types of fruit',\n    filters: [{\n        singleSelectionThreshold: true,\n        comparator: 'equals',\n        possibleValues: [\n            { label: 'Apple', value: 'apple' },\n            { label: 'Banana', value: 'banana' },\n            { label: 'Orange', value: 'orange' }\n        ]\n    }]\n}\n```\n\nThis will define a filter that allows an operator to choose one (due to `singleSelectionThreshold` being `true`) of the three possible values. The `comparator` property defines how the filter will be applied to the telemetry data.\nSetting `singleSelectionThreshold` to `false` will render the `possibleValues` as a series of checkboxes. Removing the `possibleValues` property will render the filter as a text box, allowing the operator to enter a value to filter on.\n\nNote that how the filter is interpreted is ultimately decided by the individual telemetry providers.\n\n## Implementing a filter in a telemetry provider\n\nImplementing a filter requires two parts:\n\n- First, one needs to add the filter implementation to the [subscribe](https://github.com/nasa/openmct/blob/5df7971438acb9e8b933edda2aed432b1b8bb27d/src/api/telemetry/TelemetryAPI.js#L366) method in your telemetry provider. The filter will be passed to you in the `options` argument. You can either add the filter to your telemetry subscription request, or filter manually as new messages appears. An example of the latter is [shown in the YAMCS plugin for Open MCT](https://github.com/akhenry/openmct-yamcs/blob/9c4ed03e23848db3215fdb6a988ba34b445a3989/src/providers/events.js#L95).\n\n- Second, one needs to add the filter implementation to the [request](https://github.com/nasa/openmct/blob/5df7971438acb9e8b933edda2aed432b1b8bb27d/src/api/telemetry/TelemetryAPI.js#L318) method in your telemetry provider. The filter again will be passed to you in the `options` argument. You can either add the filter to your telemetry request, or filter manually after the request is made. An example of the former is [shown in the YAMCS plugin for Open MCT](https://github.com/akhenry/openmct-yamcs/blob/9c4ed03e23848db3215fdb6a988ba34b445a3989/src/providers/historical-telemetry-provider.js#L171).\n\n## Using filters\n\nIf you installed the plugin to have it apply to `table`, create a Telemetry Table in Open MCT and drag your telemetry object that contains the filter to it. Then click \"Edit\", and notice the \"Filter\" tab in the inspector. It allows operator to either select a \"Global Filter\", or a regular filter. The \"Global Filter\" will apply for all telemetry objects in the table, while the regular filter will only apply to the telemetry object that it is defined on.","src/plugins/myItems/README.md":"# My Items plugin\nDefines top-level folder named \"My Items\" to store user-created items. Enabled by default, this can be disabled in a read-only deployment with no user-editable objects.\n\n## Installation\n```js\nopenmct.install(openmct.plugins.MyItems());\n```\n\n## Options\nWhen installing, the plugin can take several options:\n\n- `name`: The label of the root object. Defaults to \"My Items\"\n  - Example: `'Apple Items'`\n\n- `namespace`: The namespace to create the root object in. Defaults to the empty string `''`\n  - Example: `'apple-namespace'`\n\n- `priority`: The optional priority to install this plugin. Defaults to `openmct.priority.LOW`\n  - Example: `'openmct.priority.LOW'`\n\nE.g., to install with a custom name and namespace, you could use:\n\n\n```js\nopenmct.install(openmct.plugins.MyItems('Apple Items', 'apple-namespace'));\n```","src/plugins/performanceIndicator/README.md":"# URL Indicator\nAdds an indicator which shows the number of frames that the browser is able to render per second. This is a useful proxy for the maximum number of updates that any telemetry display can perform per second. This may be useful during performance testing, but probably should not be enabled by default. \n\nThis indicator adds adds about 3% points to CPU usage in the Chrome task manager.\n\n## Installation\n```js\nopenmct.install(openmct.plugins.PerformanceIndicator());\n```","src/plugins/persistence/couch/README.md":"\n# Installing CouchDB\n\n## Introduction\n\nThese instructions are for setting up CouchDB for a **development** environment. For a production environment, we recommend running Open MCT behind a proxy server (e.g., Nginx or Apache), and securing the CouchDB server properly:\n<https://docs.couchdb.org/en/main/intro/security.html>\n\n## Docker Quickstart\n\nThe following process is the preferred way of using CouchDB as it is automatic and closely resembles a production environment.\n\nRequirement:\nGet docker compose (or recent version of docker) installed on your machine. We recommend [Docker Desktop](https://www.docker.com/products/docker-desktop/)\n\n1. Open a terminal to this current working directory (`cd openmct/src/plugins/persistence/couch`)\n2. Create and start the `couchdb` container:\n\n```sh\ndocker compose -f ./couchdb-compose.yaml up --detach\n```\n\n3. Copy `.env.ci` file to file named `.env.local`\n4. (Optional) Change the values of `.env.local` if desired\n5. Set the environment variables in bash by sourcing the env file\n\n```sh\nexport $(cat .env.local | xargs)\n```\n\n6. Execute the configuration script:\n\n```sh\nsh ./setup-couchdb.sh\n```\n\n7. `cd` to the workspace root directory (the same directory as `index.html`)\n8. Update `index.html` to use the CouchDB plugin as persistence store:\n\n```sh\nsh ./src/plugins/persistence/couch/replace-localstorage-with-couchdb-indexhtml.sh\n```\n\n9. ✅ Done!\n\nOpen MCT will now use your local CouchDB container as its persistence store. Access the CouchDB instance manager by visiting <http://localhost:5984/_utils>.\n\n### Removing CouchDB Container completely\n\nTo completely remove the CouchDB container and volumes:\n\n```sh\ndocker stop couch-couchdb-1;docker rm couch-couchdb-1;docker volume rm couch_couchdb\n```\n\n## macOS\n\nWe highly recommend using the CouchDB `docker compose` method of installation, though it is still possible to install CouchDB through other means.\n\n### Installing CouchDB\n\n1. Install CouchDB using: `brew install couchdb`.\n2. Edit `/usr/local/etc/local.ini` and add the following settings:\n\n  ```ini\n  [admins]\n  admin = youradminpassword\n  ```\n\n  And set the server up for single node:\n\n  ```ini\n  [couchdb]\n  single_node=true\n  ```\n\n  Enable CORS\n\n  ```ini\n  [chttpd]\n  enable_cors = true\n  [cors]\n  origins = http://localhost:8080\n  ```\n\n### Installing CouchDB without admin privileges to your computer\n\nIf `brew` is not available on your mac machine, you'll need to get the CouchDB installed using the official sourcefiles.\n\n1. Install CouchDB following these instructions: <https://docs.brew.sh/Installation#untar-anywhere>.\n1. Edit `local.ini` in Homebrew's `/etc/` directory as directed above in the 'Installing with admin privileges to your computer' section.\n\n## Other Operating Systems\n\nFollow the installation instructions from the CouchDB installation guide: <https://docs.couchdb.org/en/stable/install/index.html>\n\n# Configuring CouchDB\n\n## Configuration script\n\nThe simplest way to config a CouchDB instance is to use our provided tooling:\n\n1. Copy `.env.ci` file to file named `.env.local`\n2. Set the environment variables in bash by sourcing the env file\n\n```sh\nexport $(cat .env.local | xargs)\n```\n\n3. Execute the configuration script:\n\n```sh\nsh ./setup-couchdb.sh\n```\n\n## Manual Configuration\n\n1. Start CouchDB by running: `couchdb`.\n2. Add the `_global_changes` database using `curl` (note the `youradminpassword` should be changed to what you set above 👆): `curl -X PUT http://admin:youradminpassword@127.0.0.1:5984/_global_changes`\n3. Navigate to <http://localhost:5984/_utils>\n4. Create a database called `openmct`\n5. Navigate to <http://127.0.0.1:5984/_utils/#/database/openmct/permissions>\n6. Remove permission restrictions in CouchDB from Open MCT by deleting `_admin` roles for both `Admin` and `Member`.\n\n## Document Sizes\n\nCouchDB has size limits on both its internal documents, and its httpd interface. If dealing with larger documents in Open MCT (e.g., users adding images to notebook entries), you may to increase this limit. To do this, add the following to the two sections:\n\n```ini\n  [couchdb]\n  max_document_size = 4294967296 ; approx 4 GB\n  \n  [chttpd]\n  max_http_request_size = 4294967296 ; approx 4 GB\n```\n  \nIf not present, add them under proper sections. The values are in bytes, and can be adjusted to whatever is appropriate for your use case.\n\n# Configuring Open MCT to use CouchDB\n\n## Configuration script\n\nThe simplest way to config a CouchDB instance is to use our provided tooling:\n\n1. `cd` to the workspace root directory (the same directory as `index.html`)\n2. Update `index.html` to use the CouchDB plugin as persistence store:\n\n```sh\nsh ./src/plugins/persistence/couch/replace-localstorage-with-couchdb-indexhtml.sh\n```\n\n## Manual Configuration\n\n1. Edit `openmct/index.html` comment out the following line:\n\n  ```js\n  openmct.install(openmct.plugins.LocalStorage());\n  ```\n\n  Add a line to install the CouchDB plugin for Open MCT:\n\n  ```js\n  openmct.install(\n        openmct.plugins.CouchDB({\n          databases: [\n            {\n              url: 'http://localhost:5984/openmct',\n              namespace: '',\n              additionalNamespaces: [],\n              readOnly: false,\n              useDesignDocuments: false,\n              indicator: true\n            }\n          ]\n        })\n      );\n  ```\n\n### Configuration Options for OpenMCT\n\nWhen installing the CouchDB plugin for OpenMCT, you can specify a list of databases with configuration options for each. Here's a breakdown of the available options for each database:\n\n- `url`: The URL to the CouchDB instance, specifying the protocol, hostname, and port as needed.\n  - Example: `'http://localhost:5984/openmct'`\n\n- `namespace`: The namespace associated with this database.\n  - Example: `'openmct-sandbox'`\n\n- `additionalNamespaces`: Other namespaces that this plugin should respond to requests for.\n  - Example: `['apple-namespace', 'pear-namespace']`\n\n- `readOnly`: A boolean indicating whether the database should be treated as read-only. If set to `true`, OpenMCT will not attempt to write to this database.\n  - Example: `false`\n\n- `useDesignDocuments`: Indicates whether design documents should be used to speed up annotation search.\n  - Example: `false`\n\n- `indicator`: A boolean to specify whether an indicator should show the status of this CouchDB connection in the OpenMCT interface.\n  - Example: `true`\n\nNote: If using the `exampleTags` plugin with non-blank namespaces, you'll need to configure it point to a writable database. For example:\n\n```js\nopenmct.install(\n        openmct.plugins.example.ExampleTags({ namespaceToSaveAnnotations: 'openmct-sandbox' })\n      );\n```\n\nNote: If using the `MyItems` plugin, be sure to configure a root for each writable namespace. E.g., if you have two namespaces called `apple-namespace` and `pear-namespace`:\n\n```js\n      openmct.install(openmct.plugins.MyItems('Apple Items', 'apple-namespace'));\n      openmct.install(openmct.plugins.MyItems('Pear Items', 'pear-namespace'));\n```\n\nThis will create a root object with the id of `mine` in both namespaces upon load if not already created.\n\n# Validating a successful Installation\n\n1. Start Open MCT by running `npm start` in the `openmct` path.\n2. Navigate to <http://localhost:8080/> and create a random object in Open MCT (e.g., a 'Clock') and save.\n3. Navigate to: <http://127.0.0.1:5984/_utils/#database/openmct/_all_docs>\n4. Look at the 'JSON' tab and ensure you can see the specific object you created above.\n5. All done! 🏆\n\n# Maintenance\n\nOne can delete annotations by running inside this directory (i.e., `src/plugins/persistence/couch`):\n\n```sh\nnpm run deleteAnnotations:openmct:PIXEL_SPATIAL\n```\n\nwill delete all image tags.\n\n```sh\nnpm run deleteAnnotations:openmct \n```\n\nwill delete all tags.\n\n```sh\nnpm run deleteAnnotations:openmct -- --help\n```\n\nwill print help options.\n\n# Search Performance\n\nFor large Open MCT installations, it may be helpful to add additional CouchDB capabilities to bear to improve performance.\n\n## Indexing\n\nIndexing the `model.type` field in CouchDB can benefit the performance of queries significantly, particularly if there are a large number of documents in the database. An index can accelerate annotation searches by reducing the number of documents that the database needs to examine.\n\nTo create an index for `model.type`, you can use the following payload [using the API](https://docs.couchdb.org/en/stable/api/database/find.html#post--db-_index):\n\n```json\n{\n  \"index\": {\n    \"fields\": [\"model.type\", \"model.tags\"]\n  },\n  \"name\": \"type_tags_index\",\n  \"type\": \"json\"\n}\n```\n\nThis instructs CouchDB to create an index on the `model.type` field and the `model.tags` field. Once this index is created, queries that include a selector on `model.type` and `model.tags` (like when searching for tags) can use this index to retrieve results faster.\n\nYou can find more detailed information about indexing in CouchDB in the [official documentation](https://docs.couchdb.org/en/stable/api/database/find.html#db-index).\n\n## Design Documents\n\nWe can also add a design document [through the API](https://docs.couchdb.org/en/stable/api/ddoc/common.html#put--db-_design-ddoc) for retrieving domain objects for specific tags:\n\n```json\n{\n  \"_id\": \"_design/annotation_tags_index\",\n  \"views\": {\n    \"by_tags\": {\n      \"map\": \"function (doc) { if (doc.model && doc.model.type === 'annotation' && doc.model.tags) { doc.model.tags.forEach(function (tag) { emit(tag, doc._id); }); } }\"\n    }\n  }\n}\n```\n\nand can be retrieved by issuing a `GET` to <http://localhost:5984/openmct/_design/annotation_tags_index/_view/by_tags?keys=[\"TAG_ID_TO_SEARCH_FOR\"]&include_docs=true>\nwhere `TAG_ID_TO_SEARCH_FOR` is the tag UUID we're looking for.\n\nand for targets:\n\n```javascript\n{\n  \"_id\": \"_design/annotation_keystring_index\",\n  \"views\": {\n    \"by_keystring\": {\n      \"map\": \"function (doc) { if (doc.model && doc.model.type === 'annotation' && doc.model.targets) { doc.model.targets.forEach(function(target) { if(target.keyString) { emit(target.keyString, doc._id); } }); } }\"\n    }\n  }\n}\n```\n\nand can be retrieved by issuing a `GET` to <http://localhost:5984/openmct/_design/annotation_keystring_index/_view/by_keystring?keys=[\"KEY_STRING_TO_SEARCH_FOR\"]&include_docs=true>\nwhere `KEY_STRING_TO_SEARCH_FOR` is the UUID we're looking for.\n\nTo enable them in Open MCT, we need to configure the plugin `useDesignDocuments` like so:\n\n  ```js\n  openmct.install(openmct.plugins.CouchDB({url: \"http://localhost:5984/openmct\", useDesignDocuments: true}));\n  ```\n","src/plugins/plan/README.md":"# Plan view and domain objects\nPlans provide a view for a list of activities grouped by categories.\n\n## Plan category and activity JSON format\nThe JSON format for a plan consists of categories/groups and a list of activities for each category.\nActivity properties include:\n* name: Name of the activity\n* start: Timestamps in milliseconds\n* end: Timestamps in milliseconds\n* type: Matches the name of the category it is in\n* color: Background color for the activity\n* textColor: Color of the name text for the activity\n* The format of the json file is as follows:\n\n```json\n{\n    \"TEST_GROUP\": [{\n    \"name\": \"Event 1 with a really long name\",\n    \"start\": 1665323197000,\n    \"end\": 1665344921000,\n    \"type\": \"TEST_GROUP\",\n    \"color\": \"orange\",\n    \"textColor\": \"white\"\n    }],\n    \"GROUP_2\": [{\n    \"name\": \"Event 2\",\n    \"start\": 1665409597000,\n    \"end\": 1665456252000,\n    \"type\": \"GROUP_2\",\n    \"color\": \"red\",\n    \"textColor\": \"white\"\n    }]\n}\n```\n\n## Plans using JSON file uploads\nPlan domain objects can be created by uploading a JSON file with the format above to render categories and activities.\n\n## Using Domain Objects directly\nIf uploading a JSON is not desired, it is possible to visualize domain objects of type 'plan'.\nThe standard model is as follows: \n```javascript\n{\n    identifier: {\n        namespace: \"\"\n        key: \"test-plan\"\n    }\n    name:\"A plan object\",\n    type:\"plan\",\n    location:\"ROOT\",\n    selectFile: {\n        body: {\n            SOME_CATEGORY: [{\n                    name: \"An activity\",\n                    start: 1665323197000,\n                    end: 1665323197100,\n                    type: \"SOME_CATEGORY\"\n                }\n            ],\n            ANOTHER_CATEGORY: [{\n                    name: \"An activity\",\n                    start: 1665323197000,\n                    end: 1665323197100,\n                    type: \"ANOTHER_CATEGORY\"\n                }\n            ]\n        }\n    }\n}\n```\n\nIf your data has non-standard keys for `start, end, type and activities` properties, use the `sourceMap` property mapping.\n```javascript\n{\n    identifier: {\n        namespace: \"\"\n        key: \"another-test-plan\"\n    }\n    name:\"Another plan object\",\n    type:\"plan\",\n    location:\"ROOT\",\n    sourceMap: {\n        start: 'start_time',\n        end: 'end_time',\n        activities: 'items',\n        groupId: 'category'\n    },\n    selectFile: {\n        body: {\n            items: [\n                {\n                    name: \"An activity\",\n                    start_time: 1665323197000,\n                    end_time: 1665323197100,\n                    category: \"SOME_CATEGORY\"\n                },\n                {\n                    name: \"Another activity\",\n                    start_time: 1665323198000,\n                    end_time: 1665323198100,\n                    category: \"ANOTHER_CATEGORY\"\n                }\n            ]\n        }\n    }\n}\n```\n\n## Rendering categories and activities:\nThe algorithm to render categories and activities on a canvas is as follows:\n* Each category gets a swimlane.\n* Activities within a category are rendered within it's swimlane.\n* Render each activity on a given row if it's duration+label do not overlap (start/end times) with an existing activity on that row.\n* Move to the next available row within a swimlane if there is overlap\n* Labels for a given activity will be rendered within it's duration slot if it fits in that rectangular space.\n* Labels that do not fit within an activity's duration slot are rendered outside, to the right of the duration slot.\n\n","src/plugins/plot/README.md":"# Plot Plugin\n\nEnables plot visualization of telemetry data. This plugin adds a plot view that is available from the view switcher for \nall telemetry objects. Two user createable objects are also added by this plugin, for Overlay and Stacked Plots. \nTelemetry objects can be added to Overlay and Stacked Plots via drag and drop.\n\n## Installation\n``` js\nopenmct.install(openmct.plugins.Plot());\n```","src/plugins/staticRootPlugin/README.md":"# Static Root Plugin\n\nThis plugin takes an object tree as JSON and exposes it as a non-editable root level tree. This can be useful if you \nhave static non-editable content that you wish to expose, such as a standard set of displays that should not be edited \n(but which can be copied and then modified if desired).\n\nAny object tree in Open MCT can be exported as JSON after installing the \n[Import/Export plugin](../../../platform/import-export/README.md).\n\n## Installation\n``` js\nopenmct.install(openmct.plugins.StaticRootPlugin({ namespace: 'mission', exportUrl: 'data/static-objects.json' }));\n```\n\n## Parameters\nThe StaticRootPlugin takes two parameters:\n1. __namespace__: This should be a name that uniquely identifies this collection of objects.\n2. __exportUrl__: The file that the static tree should be exposed from. This will need to be a path that is reachable by a web \nbrowser, ie not a path on the local file system.","src/plugins/summaryWidget/README.md":"# Summary Widget Plugin\nSummary widgets can be used to provide visual indication of state based on telemetry data. They allow rules to be \ndefined that can then be used to change the appearance of the summary widget element based on data. For example, a \nsummary widget could be defined that is green when a temperature reading is between `0` and `100` centigrade, red when \nit's above `100`, and orange when it's below `0`.\n\n## Installation\n```js\nopenmct.install(openmct.plugins.SummaryWidget());\n```","src/plugins/userIndicator/README.md":"# User Indicator\n\nThis plugin provides a user indicator for the top status bar that displays user information as\ndefined by a User Provider. A User Provider must be registered as a prerequisite for this plugin.\n\nIf the User Provider supports role-based access control, the user indicator will display the user's\ncurrent role and, if the user has multiple roles, allow the user to switch between them.\n\n## Usage\n\nTo use this plugin, first register a custom User Provider with the `openmct` API, or install the example\nUser Provider plugin:\n\n```javascript\nopenmct.install(openmct.plugins.example.ExampleUser());\n```\n\nThen, install the User Indicator plugin:\n\n```javascript\nopenmct.install(openmct.plugins.UserIndicator());\n```\n\n## Configuration\n\nThe User Indicator plugin does not require any configuration itself.\n\n## Mission Status\n\n\"Mission Status\" is a feature that is used to indicate the current state of a mission with regards to\none or more \"Mission Actions\". A mission action defines a verb that may be, for example, a task \nfor a spacecraft (such as \"Drive\" or \"Imagery\"), a change in the state of a ground system, or any \nother event that is relevant to the mission. Example states for a mission action might include\n\"Go\" or \"No Go\", indicating whether a particular action is currently cleared for execution.\n\nA user with the appropriate permissions may set the mission status by clicking on either the\nUser Indicator itself, or the \"Mission Status\" button next to the User Indicator. This will\nopen a dialog that allows the user to set the status of each mission action.\n\n### Provider Configuration\n\nIn order to use the Mission Status feature, a registered User Provider must define the following\nmethods:\n\n* `canSetMissionStatus`: A method that returns a boolean indicating whether the current user has\n  permission to set the mission status.\n* `getPossibleMissionActions`: A method that returns an array of mission actions that the user\n  may set the status of. Each mission action should have a `key` and a `name` property.\n* `getPossibleMissionActionStatuses`: A method that returns an array of `MissionStatusOption` objects,\n  which define the possible statuses for each mission action.\n* `getStatusForMissionAction`: A method that returns the current status for a given mission action.\n* `setStatusForMissionAction`: A method that sets the status for a given mission action.\n\nThe [Example User Provider](../../../example/exampleUser/ExampleUserProvider.js) provides an example\nimplementation of these methods.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/nasa/openmct/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AGENTS.md\n\nGuidance for AI coding assistants (Claude Code, Gemini CLI, and other agentic tools)\nworking in this repository.\n\n**Human contributors:** start with [CONTRIBUTING.md](CONTRIBUTING.md) instead. This file\nadds no policy of its own — it orients an agent and routes it to the canonical docs below.\n\n`CLAUDE.md` and `GEMINI.md` exist only so that tools which look for a vendor-specific\nfilename find this file. They contain a single import line and no content. Support for\nanother tool is one more one-line file; no assistant gets privileged instructions.\n\n## Where the canonical docs live\n\nRead the relevant document before working in that area rather than inferring conventions\nfrom surrounding code. Do not restate their contents here — these files are the source of\ntruth and this one goes stale if it duplicates them.\n\n| Topic | Document |\n| --- | --- |\n| Contribution process, branching, merging, code standards, commit format | [CONTRIBUTING.md](CONTRIBUTING.md) |\n| Public plugin-authoring API reference | [API.md](API.md) |\n| Test strategy, coverage, CI troubleshooting | [TESTING.md](TESTING.md) |\n| Writing and running Playwright tests, fixtures, CI architecture | [e2e/README.md](e2e/README.md) |\n| Security policy and vulnerability reporting | [SECURITY.md](SECURITY.md) |\n| Release process and notable-change policy | [docs/src/process/release.md](docs/src/process/release.md) |\n| Common coding pitfalls (clean code, function design, Vue and API usage) | [docs/src/process/common-coding-pitfalls.md](docs/src/process/common-coding-pitfalls.md) |\n\n## Attribution\n\nAgents should disclose their involvement in contributions. Use an `Assisted-by:` commit\ntrailer naming the tool, for example:\n\n```text\nAssisted-by: Claude Code\n```\n\n## Review scope\n\nDo not flag issues that `npm run lint` already catches — ESLint, Prettier, and cspell run\nin CI. Spend review effort on what automated checks cannot verify: API compatibility for\nthird-party plugin authors, test coverage of the changed code path, and adherence to the\nconventions in CONTRIBUTING.md that no linter enforces.\n\n## Commands\n\nNode version is pinned via `.nvmrc` (`nvm use`). Install with `npm install`.\n\n### Build and run\n\n- `npm start` — dev server at http://localhost:8080 (webpack dev config)\n- `npm run start:prod` — prod webpack config\n- `npm run build` — production build plus TS declarations (`dist/types`)\n- `npm run clean` — removes `dist`, `node_modules`, `coverage`, `html-test-results`, and\n  e2e test-results/nyc output. This is a full reset; `npm install` is required afterward.\n\n### Lint and format\n\n- `npm run lint` — runs `lint:js` + `lint:vue` + `lint:spelling`\n- `npm run lint:fix` — auto-fix JS/Vue lint issues\n\n### Unit tests (Jasmine + Karma)\n\n- `npm test` — full suite, headless Chrome\n- `npm run test:debug` — `KARMA_DEBUG=true`, runs in a real Chrome window for interactive\n  debugging\n- Specs are colocated with source and named `*Spec.js` (`src/foo/Bar.js` →\n  `src/foo/BarSpec.js`). Karma auto-discovers anything matching that pattern under `src/`.\n- To run a single spec or suite, temporarily prefix the relevant `describe`/`it` with `f`\n  (Jasmine's \"focused\" variant), then `npm test`. Remove it before committing.\n\n### e2e, visual, and performance tests (Playwright, in the `e2e/` workspace)\n\n- Run `npx playwright install` first to fetch the browser builds pinned by this Playwright\n  version. A stale or partial `~/Library/Caches/ms-playwright` from another project fails\n  with `Executable doesn't exist` even though *some* Chromium is cached.\n- `npm run test:e2e:ci` — the standard functional suite (excludes `@couchdb` and\n  `@generatedata` tagged tests)\n- `npm run test:e2e:local` — config meant for local iteration\n- `npm run test:e2e:watch` — Playwright UI mode\n- Single test by name:\n  `npx playwright test --config=e2e/playwright-ci.config.js --project=chrome --grep \"<test name>\"`\n- `npm run test:e2e:couchdb` — tests tagged `@couchdb`, needs a CouchDB persistence\n  backend, run with `--workers=1`\n- `npm run test:e2e:visual:ci` / `:full` — Percy.io visual regression, a no-op without a\n  `PERCY_TOKEN`\n- `npm run test:e2e:a11y` — accessibility checks (axe + Playwright)\n- `npm run test:e2e:checksnapshots` / `test:e2e:updatesnapshots` — pixel snapshot tests.\n  These are discouraged (see [e2e/README.md](e2e/README.md)) and must run inside the\n  official Playwright Docker image to match CI.\n\n## Architecture\n\nOpen MCT is a browser-based mission control framework built by NASA Ames for visualizing\nand interacting with telemetry data. It is a plugin-based single-page application: nearly\nthe entire built-in feature set (plots, imagery, display layouts, tables, notifications)\nis implemented as plugins registered through the same public API available to third-party\nintegrators.\n\n### Bootstrapping (`src/MCT.js`, `openmct.js`)\n\n`openmct.js` instantiates a singleton `MCT` (extends `EventEmitter`) and exports it as the\ndefault and as `window.openmct`. The `MCT` constructor wires up the core APIs as properties\non itself (`this.telemetry`, `this.objects`, `this.composition`, `this.time`, `this.types`,\n`this.actions`, `this.user`, `this.editor`, `this.router`, and more — see `src/MCT.js` for\nthe full list) and installs a set of always-on plugins. An application then calls\n`openmct.install(plugin)` for anything else it wants, and finally\n`openmct.start(domElement)` to mount the Vue app (`src/ui/layout/AppLayout.vue`) and start\nrouting.\n\n### Plugin pattern\n\nAlmost everything is a plugin: a factory function returning an `install(openmct)` function.\nFor example `src/plugins/clock/plugin.js` exports `ClockPlugin(options)` →\n`function install(openmct) { ... }`. Plugins register against the registries and APIs on\nthe `openmct` instance (`openmct.types.addType(...)`,\n`openmct.objectViews.addProvider(...)`, `openmct.composition.addPolicy(...)`) rather than\nbeing wired in centrally. `src/plugins/plugins.js` is the master export of built-in plugins\n(as `openmct.plugins.X`), most of which are opt-in. A handful are installed unconditionally\nin the `MCT` constructor; those are core, not optional.\n\n## Rules\n\n- [API.md](API.md) is the canonical reference for the public plugin-authoring API. Consult\n  it before changing any signature under `src/api/`. Those are contracts for external\n  plugin authors, not just internal callers, and changes require senior developer\n  approval. TypeScript declarations are generated (`emitDeclarationOnly`) from\n  `src/api/**/*.js` only, per `tsconfig.json`.\n- Generated code must follow\n  [docs/src/process/common-coding-pitfalls.md](docs/src/process/common-coding-pitfalls.md)\n  in addition to the standards in [CONTRIBUTING.md](CONTRIBUTING.md).\n- Deviating from any documented convention requires two-party agreement between author\n  and reviewer.\n","isInternal":false,"tokens":1713,"sizeBytes":6860},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/nasa/openmct/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"- @AGENTS.md\n","isInternal":false,"tokens":6,"sizeBytes":13},{"name":"README.md","path":"src/plugins/autoflow/README.md","rawUrl":"https://raw.githubusercontent.com/nasa/openmct/HEAD/src/plugins/autoflow/README.md","title":"autoflow Documentation","category":"plugin-manifest","format":"markdown","content":"# Autoflow View\n\nThis plugin provides the Autoflow View for domain objects in Open MCT. This view allows users to visualize the latest \nvalues of a collection of telemetry points in a condensed list.\n\n## Installation\n``` js\n    openmct.install(openmct.plugins.AutoflowView({\n        type: \"telemetry.fixed\"\n    }));\n```\n\n## Options\n* `type`: The object type to add the Autoflow View to. Currently supports a single value. If not provided, will make the \nAutoflow view available for all objects (which is probably not what you want).\n","isInternal":false,"tokens":123,"sizeBytes":533},{"name":"README.md","path":"src/plugins/filters/README.md","rawUrl":"https://raw.githubusercontent.com/nasa/openmct/HEAD/src/plugins/filters/README.md","title":"filters Documentation","category":"plugin-manifest","format":"markdown","content":"\n# Server side filtering in Open MCT\n\n## Introduction\n\nIn Open MCT, filters can be constructed to filter out telemetry data on the server side. This is useful for reducing the amount of data that needs to be sent to the client. For example, in [Open MCT for MCWS](https://github.com/NASA-AMMOS/openmct-mcws/blob/e8846d325cc3f659d8ad58d1d24efaafbe2b6bb7/src/constants.js#L115), they can be used to filter realtime data from recorded data. In the [Open MCT YAMCS plugin](https://github.com/akhenry/openmct-yamcs/blob/9c4ed03e23848db3215fdb6a988ba34b445a3989/src/providers/events.js#L44), we can use them to filter incoming event data by severity.\n\n## Installing the filter plugin\n\nYou'll need to install the filter plugin first. For example:\n\n```js\nopenmct.install(openmct.plugins.Filters(['telemetry.plot.overlay', 'table']));\n```\n\nwill install the filters plugin and have it apply to overlay plots and tables. You can see an example of this in the [Open MCT YAMCS plugin](https://github.com/akhenry/openmct-yamcs/blob/9c4ed03e23848db3215fdb6a988ba34b445a3989/example/index.js#L58).\n\n## Defining a filter\n\nTo define a filter, you'll need to add a new `filter` property to the domain object's `telemetry` metadata underneath the `values` array. For example, if you have a domain object with a `telemetry` metadata that looks like this:\n\n```js\n{\n    key: 'fruit',\n    name: 'Types of fruit',\n    filters: [{\n        singleSelectionThreshold: true,\n        comparator: 'equals',\n        possibleValues: [\n            { label: 'Apple', value: 'apple' },\n            { label: 'Banana', value: 'banana' },\n            { label: 'Orange', value: 'orange' }\n        ]\n    }]\n}\n```\n\nThis will define a filter that allows an operator to choose one (due to `singleSelectionThreshold` being `true`) of the three possible values. The `comparator` property defines how the filter will be applied to the telemetry data.\nSetting `singleSelectionThreshold` to `false` will render the `possibleValues` as a series of checkboxes. Removing the `possibleValues` property will render the filter as a text box, allowing the operator to enter a value to filter on.\n\nNote that how the filter is interpreted is ultimately decided by the individual telemetry providers.\n\n## Implementing a filter in a telemetry provider\n\nImplementing a filter requires two parts:\n\n- First, one needs to add the filter implementation to the [subscribe](https://github.com/nasa/openmct/blob/5df7971438acb9e8b933edda2aed432b1b8bb27d/src/api/telemetry/TelemetryAPI.js#L366) method in your telemetry provider. The filter will be passed to you in the `options` argument. You can either add the filter to your telemetry subscription request, or filter manually as new messages appears. An example of the latter is [shown in the YAMCS plugin for Open MCT](https://github.com/akhenry/openmct-yamcs/blob/9c4ed03e23848db3215fdb6a988ba34b445a3989/src/providers/events.js#L95).\n\n- Second, one needs to add the filter implementation to the [request](https://github.com/nasa/openmct/blob/5df7971438acb9e8b933edda2aed432b1b8bb27d/src/api/telemetry/TelemetryAPI.js#L318) method in your telemetry provider. The filter again will be passed to you in the `options` argument. You can either add the filter to your telemetry request, or filter manually after the request is made. An example of the former is [shown in the YAMCS plugin for Open MCT](https://github.com/akhenry/openmct-yamcs/blob/9c4ed03e23848db3215fdb6a988ba34b445a3989/src/providers/historical-telemetry-provider.js#L171).\n\n## Using filters\n\nIf you installed the plugin to have it apply to `table`, create a Telemetry Table in Open MCT and drag your telemetry object that contains the filter to it. Then click \"Edit\", and notice the \"Filter\" tab in the inspector. It allows operator to either select a \"Global Filter\", or a regular filter. The \"Global Filter\" will apply for all telemetry objects in the table, while the regular filter will only apply to the telemetry object that it is defined on.","isInternal":false,"tokens":1034,"sizeBytes":3997},{"name":"README.md","path":"src/plugins/myItems/README.md","rawUrl":"https://raw.githubusercontent.com/nasa/openmct/HEAD/src/plugins/myItems/README.md","title":"myItems Documentation","category":"plugin-manifest","format":"markdown","content":"# My Items plugin\nDefines top-level folder named \"My Items\" to store user-created items. Enabled by default, this can be disabled in a read-only deployment with no user-editable objects.\n\n## Installation\n```js\nopenmct.install(openmct.plugins.MyItems());\n```\n\n## Options\nWhen installing, the plugin can take several options:\n\n- `name`: The label of the root object. Defaults to \"My Items\"\n  - Example: `'Apple Items'`\n\n- `namespace`: The namespace to create the root object in. Defaults to the empty string `''`\n  - Example: `'apple-namespace'`\n\n- `priority`: The optional priority to install this plugin. Defaults to `openmct.priority.LOW`\n  - Example: `'openmct.priority.LOW'`\n\nE.g., to install with a custom name and namespace, you could use:\n\n\n```js\nopenmct.install(openmct.plugins.MyItems('Apple Items', 'apple-namespace'));\n```","isInternal":false,"tokens":203,"sizeBytes":832},{"name":"README.md","path":"src/plugins/performanceIndicator/README.md","rawUrl":"https://raw.githubusercontent.com/nasa/openmct/HEAD/src/plugins/performanceIndicator/README.md","title":"performanceIndicator Documentation","category":"plugin-manifest","format":"markdown","content":"# URL Indicator\nAdds an indicator which shows the number of frames that the browser is able to render per second. This is a useful proxy for the maximum number of updates that any telemetry display can perform per second. This may be useful during performance testing, but probably should not be enabled by default. \n\nThis indicator adds adds about 3% points to CPU usage in the Chrome task manager.\n\n## Installation\n```js\nopenmct.install(openmct.plugins.PerformanceIndicator());\n```","isInternal":false,"tokens":98,"sizeBytes":483},{"name":"README.md","path":"src/plugins/persistence/couch/README.md","rawUrl":"https://raw.githubusercontent.com/nasa/openmct/HEAD/src/plugins/persistence/couch/README.md","title":"couch Documentation","category":"plugin-manifest","format":"markdown","content":"\n# Installing CouchDB\n\n## Introduction\n\nThese instructions are for setting up CouchDB for a **development** environment. For a production environment, we recommend running Open MCT behind a proxy server (e.g., Nginx or Apache), and securing the CouchDB server properly:\n<https://docs.couchdb.org/en/main/intro/security.html>\n\n## Docker Quickstart\n\nThe following process is the preferred way of using CouchDB as it is automatic and closely resembles a production environment.\n\nRequirement:\nGet docker compose (or recent version of docker) installed on your machine. We recommend [Docker Desktop](https://www.docker.com/products/docker-desktop/)\n\n1. Open a terminal to this current working directory (`cd openmct/src/plugins/persistence/couch`)\n2. Create and start the `couchdb` container:\n\n```sh\ndocker compose -f ./couchdb-compose.yaml up --detach\n```\n\n3. Copy `.env.ci` file to file named `.env.local`\n4. (Optional) Change the values of `.env.local` if desired\n5. Set the environment variables in bash by sourcing the env file\n\n```sh\nexport $(cat .env.local | xargs)\n```\n\n6. Execute the configuration script:\n\n```sh\nsh ./setup-couchdb.sh\n```\n\n7. `cd` to the workspace root directory (the same directory as `index.html`)\n8. Update `index.html` to use the CouchDB plugin as persistence store:\n\n```sh\nsh ./src/plugins/persistence/couch/replace-localstorage-with-couchdb-indexhtml.sh\n```\n\n9. ✅ Done!\n\nOpen MCT will now use your local CouchDB container as its persistence store. Access the CouchDB instance manager by visiting <http://localhost:5984/_utils>.\n\n### Removing CouchDB Container completely\n\nTo completely remove the CouchDB container and volumes:\n\n```sh\ndocker stop couch-couchdb-1;docker rm couch-couchdb-1;docker volume rm couch_couchdb\n```\n\n## macOS\n\nWe highly recommend using the CouchDB `docker compose` method of installation, though it is still possible to install CouchDB through other means.\n\n### Installing CouchDB\n\n1. Install CouchDB using: `brew install couchdb`.\n2. Edit `/usr/local/etc/local.ini` and add the following settings:\n\n  ```ini\n  [admins]\n  admin = youradminpassword\n  ```\n\n  And set the server up for single node:\n\n  ```ini\n  [couchdb]\n  single_node=true\n  ```\n\n  Enable CORS\n\n  ```ini\n  [chttpd]\n  enable_cors = true\n  [cors]\n  origins = http://localhost:8080\n  ```\n\n### Installing CouchDB without admin privileges to your computer\n\nIf `brew` is not available on your mac machine, you'll need to get the CouchDB installed using the official sourcefiles.\n\n1. Install CouchDB following these instructions: <https://docs.brew.sh/Installation#untar-anywhere>.\n1. Edit `local.ini` in Homebrew's `/etc/` directory as directed above in the 'Installing with admin privileges to your computer' section.\n\n## Other Operating Systems\n\nFollow the installation instructions from the CouchDB installation guide: <https://docs.couchdb.org/en/stable/install/index.html>\n\n# Configuring CouchDB\n\n## Configuration script\n\nThe simplest way to config a CouchDB instance is to use our provided tooling:\n\n1. Copy `.env.ci` file to file named `.env.local`\n2. Set the environment variables in bash by sourcing the env file\n\n```sh\nexport $(cat .env.local | xargs)\n```\n\n3. Execute the configuration script:\n\n```sh\nsh ./setup-couchdb.sh\n```\n\n## Manual Configuration\n\n1. Start CouchDB by running: `couchdb`.\n2. Add the `_global_changes` database using `curl` (note the `youradminpassword` should be changed to what you set above 👆): `curl -X PUT http://admin:youradminpassword@127.0.0.1:5984/_global_changes`\n3. Navigate to <http://localhost:5984/_utils>\n4. Create a database called `openmct`\n5. Navigate to <http://127.0.0.1:5984/_utils/#/database/openmct/permissions>\n6. Remove permission restrictions in CouchDB from Open MCT by deleting `_admin` roles for both `Admin` and `Member`.\n\n## Document Sizes\n\nCouchDB has size limits on both its internal documents, and its httpd interface. If dealing with larger documents in Open MCT (e.g., users adding images to notebook entries), you may to increase this limit. To do this, add the following to the two sections:\n\n```ini\n  [couchdb]\n  max_document_size = 4294967296 ; approx 4 GB\n  \n  [chttpd]\n  max_http_request_size = 4294967296 ; approx 4 GB\n```\n  \nIf not present, add them under proper sections. The values are in bytes, and can be adjusted to whatever is appropriate for your use case.\n\n# Configuring Open MCT to use CouchDB\n\n## Configuration script\n\nThe simplest way to config a CouchDB instance is to use our provided tooling:\n\n1. `cd` to the workspace root directory (the same directory as `index.html`)\n2. Update `index.html` to use the CouchDB plugin as persistence store:\n\n```sh\nsh ./src/plugins/persistence/couch/replace-localstorage-with-couchdb-indexhtml.sh\n```\n\n## Manual Configuration\n\n1. Edit `openmct/index.html` comment out the following line:\n\n  ```js\n  openmct.install(openmct.plugins.LocalStorage());\n  ```\n\n  Add a line to install the CouchDB plugin for Open MCT:\n\n  ```js\n  openmct.install(\n        openmct.plugins.CouchDB({\n          databases: [\n            {\n              url: 'http://localhost:5984/openmct',\n              namespace: '',\n              additionalNamespaces: [],\n              readOnly: false,\n              useDesignDocuments: false,\n              indicator: true\n            }\n          ]\n        })\n      );\n  ```\n\n### Configuration Options for OpenMCT\n\nWhen installing the CouchDB plugin for OpenMCT, you can specify a list of databases with configuration options for each. Here's a breakdown of the available options for each database:\n\n- `url`: The URL to the CouchDB instance, specifying the protocol, hostname, and port as needed.\n  - Example: `'http://localhost:5984/openmct'`\n\n- `namespace`: The namespace associated with this database.\n  - Example: `'openmct-sandbox'`\n\n- `additionalNamespaces`: Other namespaces that this plugin should respond to requests for.\n  - Example: `['apple-namespace', 'pear-namespace']`\n\n- `readOnly`: A boolean indicating whether the database should be treated as read-only. If set to `true`, OpenMCT will not attempt to write to this database.\n  - Example: `false`\n\n- `useDesignDocuments`: Indicates whether design documents should be used to speed up annotation search.\n  - Example: `false`\n\n- `indicator`: A boolean to specify whether an indicator should show the status of this CouchDB connection in the OpenMCT interface.\n  - Example: `true`\n\nNote: If using the `exampleTags` plugin with non-blank namespaces, you'll need to configure it point to a writable database. For example:\n\n```js\nopenmct.install(\n        openmct.plugins.example.ExampleTags({ namespaceToSaveAnnotations: 'openmct-sandbox' })\n      );\n```\n\nNote: If using the `MyItems` plugin, be sure to configure a root for each writable namespace. E.g., if you have two namespaces called `apple-namespace` and `pear-namespace`:\n\n```js\n      openmct.install(openmct.plugins.MyItems('Apple Items', 'apple-namespace'));\n      openmct.install(openmct.plugins.MyItems('Pear Items', 'pear-namespace'));\n```\n\nThis will create a root object with the id of `mine` in both namespaces upon load if not already created.\n\n# Validating a successful Installation\n\n1. Start Open MCT by running `npm start` in the `openmct` path.\n2. Navigate to <http://localhost:8080/> and create a random object in Open MCT (e.g., a 'Clock') and save.\n3. Navigate to: <http://127.0.0.1:5984/_utils/#database/openmct/_all_docs>\n4. Look at the 'JSON' tab and ensure you can see the specific object you created above.\n5. All done! 🏆\n\n# Maintenance\n\nOne can delete annotations by running inside this directory (i.e., `src/plugins/persistence/couch`):\n\n```sh\nnpm run deleteAnnotations:openmct:PIXEL_SPATIAL\n```\n\nwill delete all image tags.\n\n```sh\nnpm run deleteAnnotations:openmct \n```\n\nwill delete all tags.\n\n```sh\nnpm run deleteAnnotations:openmct -- --help\n```\n\nwill print help options.\n\n# Search Performance\n\nFor large Open MCT installations, it may be helpful to add additional CouchDB capabilities to bear to improve performance.\n\n## Indexing\n\nIndexing the `model.type` field in CouchDB can benefit the performance of queries significantly, particularly if there are a large number of documents in the database. An index can accelerate annotation searches by reducing the number of documents that the database needs to examine.\n\nTo create an index for `model.type`, you can use the following payload [using the API](https://docs.couchdb.org/en/stable/api/database/find.html#post--db-_index):\n\n```json\n{\n  \"index\": {\n    \"fields\": [\"model.type\", \"model.tags\"]\n  },\n  \"name\": \"type_tags_index\",\n  \"type\": \"json\"\n}\n```\n\nThis instructs CouchDB to create an index on the `model.type` field and the `model.tags` field. Once this index is created, queries that include a selector on `model.type` and `model.tags` (like when searching for tags) can use this index to retrieve results faster.\n\nYou can find more detailed information about indexing in CouchDB in the [official documentation](https://docs.couchdb.org/en/stable/api/database/find.html#db-index).\n\n## Design Documents\n\nWe can also add a design document [through the API](https://docs.couchdb.org/en/stable/api/ddoc/common.html#put--db-_design-ddoc) for retrieving domain objects for specific tags:\n\n```json\n{\n  \"_id\": \"_design/annotation_tags_index\",\n  \"views\": {\n    \"by_tags\": {\n      \"map\": \"function (doc) { if (doc.model && doc.model.type === 'annotation' && doc.model.tags) { doc.model.tags.forEach(function (tag) { emit(tag, doc._id); }); } }\"\n    }\n  }\n}\n```\n\nand can be retrieved by issuing a `GET` to <http://localhost:5984/openmct/_design/annotation_tags_index/_view/by_tags?keys=[\"TAG_ID_TO_SEARCH_FOR\"]&include_docs=true>\nwhere `TAG_ID_TO_SEARCH_FOR` is the tag UUID we're looking for.\n\nand for targets:\n\n```javascript\n{\n  \"_id\": \"_design/annotation_keystring_index\",\n  \"views\": {\n    \"by_keystring\": {\n      \"map\": \"function (doc) { if (doc.model && doc.model.type === 'annotation' && doc.model.targets) { doc.model.targets.forEach(function(target) { if(target.keyString) { emit(target.keyString, doc._id); } }); } }\"\n    }\n  }\n}\n```\n\nand can be retrieved by issuing a `GET` to <http://localhost:5984/openmct/_design/annotation_keystring_index/_view/by_keystring?keys=[\"KEY_STRING_TO_SEARCH_FOR\"]&include_docs=true>\nwhere `KEY_STRING_TO_SEARCH_FOR` is the UUID we're looking for.\n\nTo enable them in Open MCT, we need to configure the plugin `useDesignDocuments` like so:\n\n  ```js\n  openmct.install(openmct.plugins.CouchDB({url: \"http://localhost:5984/openmct\", useDesignDocuments: true}));\n  ```\n","isInternal":false,"tokens":2601,"sizeBytes":10547},{"name":"README.md","path":"src/plugins/plan/README.md","rawUrl":"https://raw.githubusercontent.com/nasa/openmct/HEAD/src/plugins/plan/README.md","title":"plan Documentation","category":"plugin-manifest","format":"markdown","content":"# Plan view and domain objects\nPlans provide a view for a list of activities grouped by categories.\n\n## Plan category and activity JSON format\nThe JSON format for a plan consists of categories/groups and a list of activities for each category.\nActivity properties include:\n* name: Name of the activity\n* start: Timestamps in milliseconds\n* end: Timestamps in milliseconds\n* type: Matches the name of the category it is in\n* color: Background color for the activity\n* textColor: Color of the name text for the activity\n* The format of the json file is as follows:\n\n```json\n{\n    \"TEST_GROUP\": [{\n    \"name\": \"Event 1 with a really long name\",\n    \"start\": 1665323197000,\n    \"end\": 1665344921000,\n    \"type\": \"TEST_GROUP\",\n    \"color\": \"orange\",\n    \"textColor\": \"white\"\n    }],\n    \"GROUP_2\": [{\n    \"name\": \"Event 2\",\n    \"start\": 1665409597000,\n    \"end\": 1665456252000,\n    \"type\": \"GROUP_2\",\n    \"color\": \"red\",\n    \"textColor\": \"white\"\n    }]\n}\n```\n\n## Plans using JSON file uploads\nPlan domain objects can be created by uploading a JSON file with the format above to render categories and activities.\n\n## Using Domain Objects directly\nIf uploading a JSON is not desired, it is possible to visualize domain objects of type 'plan'.\nThe standard model is as follows: \n```javascript\n{\n    identifier: {\n        namespace: \"\"\n        key: \"test-plan\"\n    }\n    name:\"A plan object\",\n    type:\"plan\",\n    location:\"ROOT\",\n    selectFile: {\n        body: {\n            SOME_CATEGORY: [{\n                    name: \"An activity\",\n                    start: 1665323197000,\n                    end: 1665323197100,\n                    type: \"SOME_CATEGORY\"\n                }\n            ],\n            ANOTHER_CATEGORY: [{\n                    name: \"An activity\",\n                    start: 1665323197000,\n                    end: 1665323197100,\n                    type: \"ANOTHER_CATEGORY\"\n                }\n            ]\n        }\n    }\n}\n```\n\nIf your data has non-standard keys for `start, end, type and activities` properties, use the `sourceMap` property mapping.\n```javascript\n{\n    identifier: {\n        namespace: \"\"\n        key: \"another-test-plan\"\n    }\n    name:\"Another plan object\",\n    type:\"plan\",\n    location:\"ROOT\",\n    sourceMap: {\n        start: 'start_time',\n        end: 'end_time',\n        activities: 'items',\n        groupId: 'category'\n    },\n    selectFile: {\n        body: {\n            items: [\n                {\n                    name: \"An activity\",\n                    start_time: 1665323197000,\n                    end_time: 1665323197100,\n                    category: \"SOME_CATEGORY\"\n                },\n                {\n                    name: \"Another activity\",\n                    start_time: 1665323198000,\n                    end_time: 1665323198100,\n                    category: \"ANOTHER_CATEGORY\"\n                }\n            ]\n        }\n    }\n}\n```\n\n## Rendering categories and activities:\nThe algorithm to render categories and activities on a canvas is as follows:\n* Each category gets a swimlane.\n* Activities within a category are rendered within it's swimlane.\n* Render each activity on a given row if it's duration+label do not overlap (start/end times) with an existing activity on that row.\n* Move to the next available row within a swimlane if there is overlap\n* Labels for a given activity will be rendered within it's duration slot if it fits in that rectangular space.\n* Labels that do not fit within an activity's duration slot are rendered outside, to the right of the duration slot.\n\n","isInternal":false,"tokens":800,"sizeBytes":3543},{"name":"README.md","path":"src/plugins/plot/README.md","rawUrl":"https://raw.githubusercontent.com/nasa/openmct/HEAD/src/plugins/plot/README.md","title":"plot Documentation","category":"plugin-manifest","format":"markdown","content":"# Plot Plugin\n\nEnables plot visualization of telemetry data. This plugin adds a plot view that is available from the view switcher for \nall telemetry objects. Two user createable objects are also added by this plugin, for Overlay and Stacked Plots. \nTelemetry objects can be added to Overlay and Stacked Plots via drag and drop.\n\n## Installation\n``` js\nopenmct.install(openmct.plugins.Plot());\n```","isInternal":false,"tokens":89,"sizeBytes":397},{"name":"README.md","path":"src/plugins/staticRootPlugin/README.md","rawUrl":"https://raw.githubusercontent.com/nasa/openmct/HEAD/src/plugins/staticRootPlugin/README.md","title":"staticRootPlugin Documentation","category":"plugin-manifest","format":"markdown","content":"# Static Root Plugin\n\nThis plugin takes an object tree as JSON and exposes it as a non-editable root level tree. This can be useful if you \nhave static non-editable content that you wish to expose, such as a standard set of displays that should not be edited \n(but which can be copied and then modified if desired).\n\nAny object tree in Open MCT can be exported as JSON after installing the \n[Import/Export plugin](../../../platform/import-export/README.md).\n\n## Installation\n``` js\nopenmct.install(openmct.plugins.StaticRootPlugin({ namespace: 'mission', exportUrl: 'data/static-objects.json' }));\n```\n\n## Parameters\nThe StaticRootPlugin takes two parameters:\n1. __namespace__: This should be a name that uniquely identifies this collection of objects.\n2. __exportUrl__: The file that the static tree should be exposed from. This will need to be a path that is reachable by a web \nbrowser, ie not a path on the local file system.","isInternal":false,"tokens":207,"sizeBytes":929},{"name":"README.md","path":"src/plugins/summaryWidget/README.md","rawUrl":"https://raw.githubusercontent.com/nasa/openmct/HEAD/src/plugins/summaryWidget/README.md","title":"summaryWidget Documentation","category":"plugin-manifest","format":"markdown","content":"# Summary Widget Plugin\nSummary widgets can be used to provide visual indication of state based on telemetry data. They allow rules to be \ndefined that can then be used to change the appearance of the summary widget element based on data. For example, a \nsummary widget could be defined that is green when a temperature reading is between `0` and `100` centigrade, red when \nit's above `100`, and orange when it's below `0`.\n\n## Installation\n```js\nopenmct.install(openmct.plugins.SummaryWidget());\n```","isInternal":false,"tokens":112,"sizeBytes":501},{"name":"README.md","path":"src/plugins/URLIndicatorPlugin/README.md","rawUrl":"https://raw.githubusercontent.com/nasa/openmct/HEAD/src/plugins/URLIndicatorPlugin/README.md","title":"URLIndicatorPlugin Documentation","category":"plugin-manifest","format":"markdown","content":"# URL Indicator\nAdds an indicator which shows the availability of a URL, with success based on receipt of a 200 HTTP code. Can be used \nfor monitoring the availability of web services.\n\n## Installation\n```js\nopenmct.install(openmct.plugins.URLIndicator({\n  url: 'http://localhost:8080',\n    iconClass: 'check',\n    interval: 10000,\n    label: 'Localhost'\n })\n);\n```\n\n## Options\n* __url__: URL to indicate the status of\n* __iconClass__: Icon to show in the status bar, defaults to icon-database. See the [Style Guide](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home/glyphs?view=styleguide.glyphs) for more icon options.\n* __interval__: Interval between checking the connection, defaults to 10000\n* __label__: Name showing up as text in the status bar, defaults to url\n\n","isInternal":false,"tokens":200,"sizeBytes":788},{"name":"README.md","path":"src/plugins/userIndicator/README.md","rawUrl":"https://raw.githubusercontent.com/nasa/openmct/HEAD/src/plugins/userIndicator/README.md","title":"userIndicator Documentation","category":"plugin-manifest","format":"markdown","content":"# User Indicator\n\nThis plugin provides a user indicator for the top status bar that displays user information as\ndefined by a User Provider. A User Provider must be registered as a prerequisite for this plugin.\n\nIf the User Provider supports role-based access control, the user indicator will display the user's\ncurrent role and, if the user has multiple roles, allow the user to switch between them.\n\n## Usage\n\nTo use this plugin, first register a custom User Provider with the `openmct` API, or install the example\nUser Provider plugin:\n\n```javascript\nopenmct.install(openmct.plugins.example.ExampleUser());\n```\n\nThen, install the User Indicator plugin:\n\n```javascript\nopenmct.install(openmct.plugins.UserIndicator());\n```\n\n## Configuration\n\nThe User Indicator plugin does not require any configuration itself.\n\n## Mission Status\n\n\"Mission Status\" is a feature that is used to indicate the current state of a mission with regards to\none or more \"Mission Actions\". A mission action defines a verb that may be, for example, a task \nfor a spacecraft (such as \"Drive\" or \"Imagery\"), a change in the state of a ground system, or any \nother event that is relevant to the mission. Example states for a mission action might include\n\"Go\" or \"No Go\", indicating whether a particular action is currently cleared for execution.\n\nA user with the appropriate permissions may set the mission status by clicking on either the\nUser Indicator itself, or the \"Mission Status\" button next to the User Indicator. This will\nopen a dialog that allows the user to set the status of each mission action.\n\n### Provider Configuration\n\nIn order to use the Mission Status feature, a registered User Provider must define the following\nmethods:\n\n* `canSetMissionStatus`: A method that returns a boolean indicating whether the current user has\n  permission to set the mission status.\n* `getPossibleMissionActions`: A method that returns an array of mission actions that the user\n  may set the status of. Each mission action should have a `key` and a `name` property.\n* `getPossibleMissionActionStatuses`: A method that returns an array of `MissionStatusOption` objects,\n  which define the possible statuses for each mission action.\n* `getStatusForMissionAction`: A method that returns the current status for a given mission action.\n* `setStatusForMissionAction`: A method that sets the status for a given mission action.\n\nThe [Example User Provider](../../../example/exampleUser/ExampleUserProvider.js) provides an example\nimplementation of these methods.\n","isInternal":false,"tokens":526,"sizeBytes":2526}],"systemPromptSnippet":"<yakaai_skills repo=\"nasa/openmct\">\n<!-- File: AGENTS.md (Tokens: ~1713 | Category: root-instruction) -->\n# AGENTS.md\n\nGuidance for AI coding assistants (Claude Code, Gemini CLI, and other agentic tools)\nworking in this repository.\n\n**Human contributors:** start with [CONTRIBUTING.md](CONTRIBUTING.md) instead. This file\nadds no policy of its own — it orients an agent and routes it to the canonical docs below.\n\n`CLAUDE.md` and `GEMINI.md` exist only so that tools which look for a vendor-specific\nfilename find this file. They contain a single import line and no content. Support for\nanother tool is one more one-line file; no assistant gets privileged instructions.\n\n## Where the canonical docs live\n\nRead the relevant document before working in that area rather than inferring conventions\nfrom surrounding code. Do not restate their contents here — these files are the source of\ntruth and this one goes stale if it duplicates them.\n\n| Topic | Document |\n| --- | --- |\n| Contribution process, branching, merging, code standards, commit format | [CONTRIBUTING.md](CONTRIBUTING.md) |\n| Public plugin-authoring API reference | [API.md](API.md) |\n| Test strategy, coverage, CI troubleshooting | [TESTING.md](TESTING.md) |\n| Writing and running Playwright tests, fixtures, CI architecture | [e2e/README.md](e2e/README.md) |\n| Security policy and vulnerability reporting | [SECURITY.md](SECURITY.md) |\n| Release process and notable-change policy | [docs/src/process/release.md](docs/src/process/release.md) |\n| Common coding pitfalls (clean code, function design, Vue and API usage) | [docs/src/process/common-coding-pitfalls.md](docs/src/process/common-coding-pitfalls.md) |\n\n## Attribution\n\nAgents should disclose their involvement in contributions. Use an `Assisted-by:` commit\ntrailer naming the tool, for example:\n\n```text\nAssisted-by: Claude Code\n```\n\n## Review scope\n\nDo not flag issues that `npm run lint` already catches — ESLint, Prettier, and cspell run\nin CI. Spend review effort on what automated checks cannot verify: API compatibility for\nthird-party plugin authors, test coverage of the changed code path, and adherence to the\nconventions in CONTRIBUTING.md that no linter enforces.\n\n## Commands\n\nNode version is pinned via `.nvmrc` (`nvm use`). Install with `npm install`.\n\n### Build and run\n\n- `npm start` — dev server at http://localhost:8080 (webpack dev config)\n- `npm run start:prod` — prod webpack config\n- `npm run build` — production build plus TS declarations (`dist/types`)\n- `npm run clean` — removes `dist`, `node_modules`, `coverage`, `html-test-results`, and\n  e2e test-results/nyc output. This is a full reset; `npm install` is required afterward.\n\n### Lint and format\n\n- `npm run lint` — runs `lint:js` + `lint:vue` + `lint:spelling`\n- `npm run lint:fix` — auto-fix JS/Vue lint issues\n\n### Unit tests (Jasmine + Karma)\n\n- `npm test` — full suite, headless Chrome\n- `npm run test:debug` — `KARMA_DEBUG=true`, runs in a real Chrome window for interactive\n  debugging\n- Specs are colocated with source and named `*Spec.js` (`src/foo/Bar.js` →\n  `src/foo/BarSpec.js`). Karma auto-discovers anything matching that pattern under `src/`.\n- To run a single spec or suite, temporarily prefix the relevant `describe`/`it` with `f`\n  (Jasmine's \"focused\" variant), then `npm test`. Remove it before committing.\n\n### e2e, visual, and performance tests (Playwright, in the `e2e/` workspace)\n\n- Run `npx playwright install` first to fetch the browser builds pinned by this Playwright\n  version. A stale or partial `~/Library/Caches/ms-playwright` from another project fails\n  with `Executable doesn't exist` even though *some* Chromium is cached.\n- `npm run test:e2e:ci` — the standard functional suite (excludes `@couchdb` and\n  `@generatedata` tagged tests)\n- `npm run test:e2e:local` — config meant for local iteration\n- `npm run test:e2e:watch` — Playwright UI mode\n- Single test by name:\n  `npx playwright test --config=e2e/playwright-ci.config.js --project=chrome --grep \"<test name>\"`\n- `npm run test:e2e:couchdb` — tests tagged `@couchdb`, needs a CouchDB persistence\n  backend, run with `--workers=1`\n- `npm run test:e2e:visual:ci` / `:full` — Percy.io visual regression, a no-op without a\n  `PERCY_TOKEN`\n- `npm run test:e2e:a11y` — accessibility checks (axe + Playwright)\n- `npm run test:e2e:checksnapshots` / `test:e2e:updatesnapshots` — pixel snapshot tests.\n  These are discouraged (see [e2e/README.md](e2e/README.md)) and must run inside the\n  official Playwright Docker image to match CI.\n\n## Architecture\n\nOpen MCT is a browser-based mission control framework built by NASA Ames for visualizing\nand interacting with telemetry data. It is a plugin-based single-page application: nearly\nthe entire built-in feature set (plots, imagery, display layouts, tables, notifications)\nis implemented as plugins registered through the same public API available to third-party\nintegrators.\n\n### Bootstrapping (`src/MCT.js`, `openmct.js`)\n\n`openmct.js` instantiates a singleton `MCT` (extends `EventEmitter`) and exports it as the\ndefault and as `window.openmct`. The `MCT` constructor wires up the core APIs as properties\non itself (`this.telemetry`, `this.objects`, `this.composition`, `this.time`, `this.types`,\n`this.actions`, `this.user`, `this.editor`, `this.router`, and more — see `src/MCT.js` for\nthe full list) and installs a set of always-on plugins. An application then calls\n`openmct.install(plugin)` for anything else it wants, and finally\n`openmct.start(domElement)` to mount the Vue app (`src/ui/layout/AppLayout.vue`) and start\nrouting.\n\n### Plugin pattern\n\nAlmost everything is a plugin: a factory function returning an `install(openmct)` function.\nFor example `src/plugins/clock/plugin.js` exports `ClockPlugin(options)` →\n`function install(openmct) { ... }`. Plugins register against the registries and APIs on\nthe `openmct` instance (`openmct.types.addType(...)`,\n`openmct.objectViews.addProvider(...)`, `openmct.composition.addPolicy(...)`) rather than\nbeing wired in centrally. `src/plugins/plugins.js` is the master export of built-in plugins\n(as `openmct.plugins.X`), most of which are opt-in. A handful are installed unconditionally\nin the `MCT` constructor; those are core, not optional.\n\n## Rules\n\n- [API.md](API.md) is the canonical reference for the public plugin-authoring API. Consult\n  it before changing any signature under `src/api/`. Those are contracts for external\n  plugin authors, not just internal callers, and changes require senior developer\n  approval. TypeScript declarations are generated (`emitDeclarationOnly`) from\n  `src/api/**/*.js` only, per `tsconfig.json`.\n- Generated code must follow\n  [docs/src/process/common-coding-pitfalls.md](docs/src/process/common-coding-pitfalls.md)\n  in addition to the standards in [CONTRIBUTING.md](CONTRIBUTING.md).\n- Deviating from any documented convention requires two-party agreement between author\n  and reviewer.\n\n<!-- File: CLAUDE.md (Tokens: ~6 | Category: claude-rule) -->\n- @AGENTS.md\n\n<!-- File: src/plugins/autoflow/README.md (Tokens: ~123 | Category: plugin-manifest) -->\n# Autoflow View\n\nThis plugin provides the Autoflow View for domain objects in Open MCT. This view allows users to visualize the latest \nvalues of a collection of telemetry points in a condensed list.\n\n## Installation\n``` js\n    openmct.install(openmct.plugins.AutoflowView({\n        type: \"telemetry.fixed\"\n    }));\n```\n\n## Options\n* `type`: The object type to add the Autoflow View to. Currently supports a single value. If not provided, will make the \nAutoflow view available for all objects (which is probably not what you want).\n\n<!-- File: src/plugins/filters/README.md (Tokens: ~1034 | Category: plugin-manifest) -->\n# Server side filtering in Open MCT\n\n## Introduction\n\nIn Open MCT, filters can be constructed to filter out telemetry data on the server side. This is useful for reducing the amount of data that needs to be sent to the client. For example, in [Open MCT for MCWS](https://github.com/NASA-AMMOS/openmct-mcws/blob/e8846d325cc3f659d8ad58d1d24efaafbe2b6bb7/src/constants.js#L115), they can be used to filter realtime data from recorded data. In the [Open MCT YAMCS plugin](https://github.com/akhenry/openmct-yamcs/blob/9c4ed03e23848db3215fdb6a988ba34b445a3989/src/providers/events.js#L44), we can use them to filter incoming event data by severity.\n\n## Installing the filter plugin\n\nYou'll need to install the filter plugin first. For example:\n\n```js\nopenmct.install(openmct.plugins.Filters(['telemetry.plot.overlay', 'table']));\n```\n\nwill install the filters plugin and have it apply to overlay plots and tables. You can see an example of this in the [Open MCT YAMCS plugin](https://github.com/akhenry/openmct-yamcs/blob/9c4ed03e23848db3215fdb6a988ba34b445a3989/example/index.js#L58).\n\n## Defining a filter\n\nTo define a filter, you'll need to add a new `filter` property to the domain object's `telemetry` metadata underneath the `values` array. For example, if you have a domain object with a `telemetry` metadata that looks like this:\n\n```js\n{\n    key: 'fruit',\n    name: 'Types of fruit',\n    filters: [{\n        singleSelectionThreshold: true,\n        comparator: 'equals',\n        possibleValues: [\n            { label: 'Apple', value: 'apple' },\n            { label: 'Banana', value: 'banana' },\n            { label: 'Orange', value: 'orange' }\n        ]\n    }]\n}\n```\n\nThis will define a filter that allows an operator to choose one (due to `singleSelectionThreshold` being `true`) of the three possible values. The `comparator` property defines how the filter will be applied to the telemetry data.\nSetting `singleSelectionThreshold` to `false` will render the `possibleValues` as a series of checkboxes. Removing the `possibleValues` property will render the filter as a text box, allowing the operator to enter a value to filter on.\n\nNote that how the filter is interpreted is ultimately decided by the individual telemetry providers.\n\n## Implementing a filter in a telemetry provider\n\nImplementing a filter requires two parts:\n\n- First, one needs to add the filter implementation to the [subscribe](https://github.com/nasa/openmct/blob/5df7971438acb9e8b933edda2aed432b1b8bb27d/src/api/telemetry/TelemetryAPI.js#L366) method in your telemetry provider. The filter will be passed to you in the `options` argument. You can either add the filter to your telemetry subscription request, or filter manually as new messages appears. An example of the latter is [shown in the YAMCS plugin for Open MCT](https://github.com/akhenry/openmct-yamcs/blob/9c4ed03e23848db3215fdb6a988ba34b445a3989/src/providers/events.js#L95).\n\n- Second, one needs to add the filter implementation to the [request](https://github.com/nasa/openmct/blob/5df7971438acb9e8b933edda2aed432b1b8bb27d/src/api/telemetry/TelemetryAPI.js#L318) method in your telemetry provider. The filter again will be passed to you in the `options` argument. You can either add the filter to your telemetry request, or filter manually after the request is made. An example of the former is [shown in the YAMCS plugin for Open MCT](https://github.com/akhenry/openmct-yamcs/blob/9c4ed03e23848db3215fdb6a988ba34b445a3989/src/providers/historical-telemetry-provider.js#L171).\n\n## Using filters\n\nIf you installed the plugin to have it apply to `table`, create a Telemetry Table in Open MCT and drag your telemetry object that contains the filter to it. Then click \"Edit\", and notice the \"Filter\" tab in the inspector. It allows operator to either select a \"Global Filter\", or a regular filter. The \"Global Filter\" will apply for all telemetry objects in the table, while the regular filter will only apply to the telemetry object that it is defined on.\n\n<!-- File: src/plugins/myItems/README.md (Tokens: ~203 | Category: plugin-manifest) -->\n# My Items plugin\nDefines top-level folder named \"My Items\" to store user-created items. Enabled by default, this can be disabled in a read-only deployment with no user-editable objects.\n\n## Installation\n```js\nopenmct.install(openmct.plugins.MyItems());\n```\n\n## Options\nWhen installing, the plugin can take several options:\n\n- `name`: The label of the root object. Defaults to \"My Items\"\n  - Example: `'Apple Items'`\n\n- `namespace`: The namespace to create the root object in. Defaults to the empty string `''`\n  - Example: `'apple-namespace'`\n\n- `priority`: The optional priority to install this plugin. Defaults to `openmct.priority.LOW`\n  - Example: `'openmct.priority.LOW'`\n\nE.g., to install with a custom name and namespace, you could use:\n\n\n```js\nopenmct.install(openmct.plugins.MyItems('Apple Items', 'apple-namespace'));\n```\n\n<!-- File: src/plugins/performanceIndicator/README.md (Tokens: ~98 | Category: plugin-manifest) -->\n# URL Indicator\nAdds an indicator which shows the number of frames that the browser is able to render per second. This is a useful proxy for the maximum number of updates that any telemetry display can perform per second. This may be useful during performance testing, but probably should not be enabled by default. \n\nThis indicator adds adds about 3% points to CPU usage in the Chrome task manager.\n\n## Installation\n```js\nopenmct.install(openmct.plugins.PerformanceIndicator());\n```\n\n<!-- File: src/plugins/persistence/couch/README.md (Tokens: ~2601 | Category: plugin-manifest) -->\n# Installing CouchDB\n\n## Introduction\n\nThese instructions are for setting up CouchDB for a **development** environment. For a production environment, we recommend running Open MCT behind a proxy server (e.g., Nginx or Apache), and securing the CouchDB server properly:\n<https://docs.couchdb.org/en/main/intro/security.html>\n\n## Docker Quickstart\n\nThe following process is the preferred way of using CouchDB as it is automatic and closely resembles a production environment.\n\nRequirement:\nGet docker compose (or recent version of docker) installed on your machine. We recommend [Docker Desktop](https://www.docker.com/products/docker-desktop/)\n\n1. Open a terminal to this current working directory (`cd openmct/src/plugins/persistence/couch`)\n2. Create and start the `couchdb` container:\n\n```sh\ndocker compose -f ./couchdb-compose.yaml up --detach\n```\n\n3. Copy `.env.ci` file to file named `.env.local`\n4. (Optional) Change the values of `.env.local` if desired\n5. Set the environment variables in bash by sourcing the env file\n\n```sh\nexport $(cat .env.local | xargs)\n```\n\n6. Execute the configuration script:\n\n```sh\nsh ./setup-couchdb.sh\n```\n\n7. `cd` to the workspace root directory (the same directory as `index.html`)\n8. Update `index.html` to use the CouchDB plugin as persistence store:\n\n```sh\nsh ./src/plugins/persistence/couch/replace-localstorage-with-couchdb-indexhtml.sh\n```\n\n9. ✅ Done!\n\nOpen MCT will now use your local CouchDB container as its persistence store. Access the CouchDB instance manager by visiting <http://localhost:5984/_utils>.\n\n### Removing CouchDB Container completely\n\nTo completely remove the CouchDB container and volumes:\n\n```sh\ndocker stop couch-couchdb-1;docker rm couch-couchdb-1;docker volume rm couch_couchdb\n```\n\n## macOS\n\nWe highly recommend using the CouchDB `docker compose` method of installation, though it is still possible to install CouchDB through other means.\n\n### Installing CouchDB\n\n1. Install CouchDB using: `brew install couchdb`.\n2. Edit `/usr/local/etc/local.ini` and add the following settings:\n\n  ```ini\n  [admins]\n  admin = youradminpassword\n  ```\n\n  And set the server up for single node:\n\n  ```ini\n  [couchdb]\n  single_node=true\n  ```\n\n  Enable CORS\n\n  ```ini\n  [chttpd]\n  enable_cors = true\n  [cors]\n  origins = http://localhost:8080\n  ```\n\n### Installing CouchDB without admin privileges to your computer\n\nIf `brew` is not available on your mac machine, you'll need to get the CouchDB installed using the official sourcefiles.\n\n1. Install CouchDB following these instructions: <https://docs.brew.sh/Installation#untar-anywhere>.\n1. Edit `local.ini` in Homebrew's `/etc/` directory as directed above in the 'Installing with admin privileges to your computer' section.\n\n## Other Operating Systems\n\nFollow the installation instructions from the CouchDB installation guide: <https://docs.couchdb.org/en/stable/install/index.html>\n\n# Configuring CouchDB\n\n## Configuration script\n\nThe simplest way to config a CouchDB instance is to use our provided tooling:\n\n1. Copy `.env.ci` file to file named `.env.local`\n2. Set the environment variables in bash by sourcing the env file\n\n```sh\nexport $(cat .env.local | xargs)\n```\n\n3. Execute the configuration script:\n\n```sh\nsh ./setup-couchdb.sh\n```\n\n## Manual Configuration\n\n1. Start CouchDB by running: `couchdb`.\n2. Add the `_global_changes` database using `curl` (note the `youradminpassword` should be changed to what you set above 👆): `curl -X PUT http://admin:youradminpassword@127.0.0.1:5984/_global_changes`\n3. Navigate to <http://localhost:5984/_utils>\n4. Create a database called `openmct`\n5. Navigate to <http://127.0.0.1:5984/_utils/#/database/openmct/permissions>\n6. Remove permission restrictions in CouchDB from Open MCT by deleting `_admin` roles for both `Admin` and `Member`.\n\n## Document Sizes\n\nCouchDB has size limits on both its internal documents, and its httpd interface. If dealing with larger documents in Open MCT (e.g., users adding images to notebook entries), you may to increase this limit. To do this, add the following to the two sections:\n\n```ini\n  [couchdb]\n  max_document_size = 4294967296 ; approx 4 GB\n  \n  [chttpd]\n  max_http_request_size = 4294967296 ; approx 4 GB\n```\n  \nIf not present, add them under proper sections. The values are in bytes, and can be adjusted to whatever is appropriate for your use case.\n\n# Configuring Open MCT to use CouchDB\n\n## Configuration script\n\nThe simplest way to config a CouchDB instance is to use our provided tooling:\n\n1. `cd` to the workspace root directory (the same directory as `index.html`)\n2. Update `index.html` to use the CouchDB plugin as persistence store:\n\n```sh\nsh ./src/plugins/persistence/couch/replace-localstorage-with-couchdb-indexhtml.sh\n```\n\n## Manual Configuration\n\n1. Edit `openmct/index.html` comment out the following line:\n\n  ```js\n  openmct.install(openmct.plugins.LocalStorage());\n  ```\n\n  Add a line to install the CouchDB plugin for Open MCT:\n\n  ```js\n  openmct.install(\n        openmct.plugins.CouchDB({\n          databases: [\n            {\n              url: 'http://localhost:5984/openmct',\n              namespace: '',\n              additionalNamespaces: [],\n              readOnly: false,\n              useDesignDocuments: false,\n              indicator: true\n            }\n          ]\n        })\n      );\n  ```\n\n### Configuration Options for OpenMCT\n\nWhen installing the CouchDB plugin for OpenMCT, you can specify a list of databases with configuration options for each. Here's a breakdown of the available options for each database:\n\n- `url`: The URL to the CouchDB instance, specifying the protocol, hostname, and port as needed.\n  - Example: `'http://localhost:5984/openmct'`\n\n- `namespace`: The namespace associated with this database.\n  - Example: `'openmct-sandbox'`\n\n- `additionalNamespaces`: Other namespaces that this plugin should respond to requests for.\n  - Example: `['apple-namespace', 'pear-namespace']`\n\n- `readOnly`: A boolean indicating whether the database should be treated as read-only. If set to `true`, OpenMCT will not attempt to write to this database.\n  - Example: `false`\n\n- `useDesignDocuments`: Indicates whether design documents should be used to speed up annotation search.\n  - Example: `false`\n\n- `indicator`: A boolean to specify whether an indicator should show the status of this CouchDB connection in the OpenMCT interface.\n  - Example: `true`\n\nNote: If using the `exampleTags` plugin with non-blank namespaces, you'll need to configure it point to a writable database. For example:\n\n```js\nopenmct.install(\n        openmct.plugins.example.ExampleTags({ namespaceToSaveAnnotations: 'openmct-sandbox' })\n      );\n```\n\nNote: If using the `MyItems` plugin, be sure to configure a root for each writable namespace. E.g., if you have two namespaces called `apple-namespace` and `pear-namespace`:\n\n```js\n      openmct.install(openmct.plugins.MyItems('Apple Items', 'apple-namespace'));\n      openmct.install(openmct.plugins.MyItems('Pear Items', 'pear-namespace'));\n```\n\nThis will create a root object with the id of `mine` in both namespaces upon load if not already created.\n\n# Validating a successful Installation\n\n1. Start Open MCT by running `npm start` in the `openmct` path.\n2. Navigate to <http://localhost:8080/> and create a random object in Open MCT (e.g., a 'Clock') and save.\n3. Navigate to: <http://127.0.0.1:5984/_utils/#database/openmct/_all_docs>\n4. Look at the 'JSON' tab and ensure you can see the specific object you created above.\n5. All done! 🏆\n\n# Maintenance\n\nOne can delete annotations by running inside this directory (i.e., `src/plugins/persistence/couch`):\n\n```sh\nnpm run deleteAnnotations:openmct:PIXEL_SPATIAL\n```\n\nwill delete all image tags.\n\n```sh\nnpm run deleteAnnotations:openmct \n```\n\nwill delete all tags.\n\n```sh\nnpm run deleteAnnotations:openmct -- --help\n```\n\nwill print help options.\n\n# Search Performance\n\nFor large Open MCT installations, it may be helpful to add additional CouchDB capabilities to bear to improve performance.\n\n## Indexing\n\nIndexing the `model.type` field in CouchDB can benefit the performance of queries significantly, particularly if there are a large number of documents in the database. An index can accelerate annotation searches by reducing the number of documents that the database needs to examine.\n\nTo create an index for `model.type`, you can use the following payload [using the API](https://docs.couchdb.org/en/stable/api/database/find.html#post--db-_index):\n\n```json\n{\n  \"index\": {\n    \"fields\": [\"model.type\", \"model.tags\"]\n  },\n  \"name\": \"type_tags_index\",\n  \"type\": \"json\"\n}\n```\n\nThis instructs CouchDB to create an index on the `model.type` field and the `model.tags` field. Once this index is created, queries that include a selector on `model.type` and `model.tags` (like when searching for tags) can use this index to retrieve results faster.\n\nYou can find more detailed information about indexing in CouchDB in the [official documentation](https://docs.couchdb.org/en/stable/api/database/find.html#db-index).\n\n## Design Documents\n\nWe can also add a design document [through the API](https://docs.couchdb.org/en/stable/api/ddoc/common.html#put--db-_design-ddoc) for retrieving domain objects for specific tags:\n\n```json\n{\n  \"_id\": \"_design/annotation_tags_index\",\n  \"views\": {\n    \"by_tags\": {\n      \"map\": \"function (doc) { if (doc.model && doc.model.type === 'annotation' && doc.model.tags) { doc.model.tags.forEach(function (tag) { emit(tag, doc._id); }); } }\"\n    }\n  }\n}\n```\n\nand can be retrieved by issuing a `GET` to <http://localhost:5984/openmct/_design/annotation_tags_index/_view/by_tags?keys=[\"TAG_ID_TO_SEARCH_FOR\"]&include_docs=true>\nwhere `TAG_ID_TO_SEARCH_FOR` is the tag UUID we're looking for.\n\nand for targets:\n\n```javascript\n{\n  \"_id\": \"_design/annotation_keystring_index\",\n  \"views\": {\n    \"by_keystring\": {\n      \"map\": \"function (doc) { if (doc.model && doc.model.type === 'annotation' && doc.model.targets) { doc.model.targets.forEach(function(target) { if(target.keyString) { emit(target.keyString, doc._id); } }); } }\"\n    }\n  }\n}\n```\n\nand can be retrieved by issuing a `GET` to <http://localhost:5984/openmct/_design/annotation_keystring_index/_view/by_keystring?keys=[\"KEY_STRING_TO_SEARCH_FOR\"]&include_docs=true>\nwhere `KEY_STRING_TO_SEARCH_FOR` is the UUID we're looking for.\n\nTo enable them in Open MCT, we need to configure the plugin `useDesignDocuments` like so:\n\n  ```js\n  openmct.install(openmct.plugins.CouchDB({url: \"http://localhost:5984/openmct\", useDesignDocuments: true}));\n  ```\n\n<!-- File: src/plugins/plan/README.md (Tokens: ~800 | Category: plugin-manifest) -->\n# Plan view and domain objects\nPlans provide a view for a list of activities grouped by categories.\n\n## Plan category and activity JSON format\nThe JSON format for a plan consists of categories/groups and a list of activities for each category.\nActivity properties include:\n* name: Name of the activity\n* start: Timestamps in milliseconds\n* end: Timestamps in milliseconds\n* type: Matches the name of the category it is in\n* color: Background color for the activity\n* textColor: Color of the name text for the activity\n* The format of the json file is as follows:\n\n```json\n{\n    \"TEST_GROUP\": [{\n    \"name\": \"Event 1 with a really long name\",\n    \"start\": 1665323197000,\n    \"end\": 1665344921000,\n    \"type\": \"TEST_GROUP\",\n    \"color\": \"orange\",\n    \"textColor\": \"white\"\n    }],\n    \"GROUP_2\": [{\n    \"name\": \"Event 2\",\n    \"start\": 1665409597000,\n    \"end\": 1665456252000,\n    \"type\": \"GROUP_2\",\n    \"color\": \"red\",\n    \"textColor\": \"white\"\n    }]\n}\n```\n\n## Plans using JSON file uploads\nPlan domain objects can be created by uploading a JSON file with the format above to render categories and activities.\n\n## Using Domain Objects directly\nIf uploading a JSON is not desired, it is possible to visualize domain objects of type 'plan'.\nThe standard model is as follows: \n```javascript\n{\n    identifier: {\n        namespace: \"\"\n        key: \"test-plan\"\n    }\n    name:\"A plan object\",\n    type:\"plan\",\n    location:\"ROOT\",\n    selectFile: {\n        body: {\n            SOME_CATEGORY: [{\n                    name: \"An activity\",\n                    start: 1665323197000,\n                    end: 1665323197100,\n                    type: \"SOME_CATEGORY\"\n                }\n            ],\n            ANOTHER_CATEGORY: [{\n                    name: \"An activity\",\n                    start: 1665323197000,\n                    end: 1665323197100,\n                    type: \"ANOTHER_CATEGORY\"\n                }\n            ]\n        }\n    }\n}\n```\n\nIf your data has non-standard keys for `start, end, type and activities` properties, use the `sourceMap` property mapping.\n```javascript\n{\n    identifier: {\n        namespace: \"\"\n        key: \"another-test-plan\"\n    }\n    name:\"Another plan object\",\n    type:\"plan\",\n    location:\"ROOT\",\n    sourceMap: {\n        start: 'start_time',\n        end: 'end_time',\n        activities: 'items',\n        groupId: 'category'\n    },\n    selectFile: {\n        body: {\n            items: [\n                {\n                    name: \"An activity\",\n                    start_time: 1665323197000,\n                    end_time: 1665323197100,\n                    category: \"SOME_CATEGORY\"\n                },\n                {\n                    name: \"Another activity\",\n                    start_time: 1665323198000,\n                    end_time: 1665323198100,\n                    category: \"ANOTHER_CATEGORY\"\n                }\n            ]\n        }\n    }\n}\n```\n\n## Rendering categories and activities:\nThe algorithm to render categories and activities on a canvas is as follows:\n* Each category gets a swimlane.\n* Activities within a category are rendered within it's swimlane.\n* Render each activity on a given row if it's duration+label do not overlap (start/end times) with an existing activity on that row.\n* Move to the next available row within a swimlane if there is overlap\n* Labels for a given activity will be rendered within it's duration slot if it fits in that rectangular space.\n* Labels that do not fit within an activity's duration slot are rendered outside, to the right of the duration slot.\n\n<!-- File: src/plugins/plot/README.md (Tokens: ~89 | Category: plugin-manifest) -->\n# Plot Plugin\n\nEnables plot visualization of telemetry data. This plugin adds a plot view that is available from the view switcher for \nall telemetry objects. Two user createable objects are also added by this plugin, for Overlay and Stacked Plots. \nTelemetry objects can be added to Overlay and Stacked Plots via drag and drop.\n\n## Installation\n``` js\nopenmct.install(openmct.plugins.Plot());\n```\n\n<!-- File: src/plugins/staticRootPlugin/README.md (Tokens: ~207 | Category: plugin-manifest) -->\n# Static Root Plugin\n\nThis plugin takes an object tree as JSON and exposes it as a non-editable root level tree. This can be useful if you \nhave static non-editable content that you wish to expose, such as a standard set of displays that should not be edited \n(but which can be copied and then modified if desired).\n\nAny object tree in Open MCT can be exported as JSON after installing the \n[Import/Export plugin](../../../platform/import-export/README.md).\n\n## Installation\n``` js\nopenmct.install(openmct.plugins.StaticRootPlugin({ namespace: 'mission', exportUrl: 'data/static-objects.json' }));\n```\n\n## Parameters\nThe StaticRootPlugin takes two parameters:\n1. __namespace__: This should be a name that uniquely identifies this collection of objects.\n2. __exportUrl__: The file that the static tree should be exposed from. This will need to be a path that is reachable by a web \nbrowser, ie not a path on the local file system.\n\n<!-- File: src/plugins/summaryWidget/README.md (Tokens: ~112 | Category: plugin-manifest) -->\n# Summary Widget Plugin\nSummary widgets can be used to provide visual indication of state based on telemetry data. They allow rules to be \ndefined that can then be used to change the appearance of the summary widget element based on data. For example, a \nsummary widget could be defined that is green when a temperature reading is between `0` and `100` centigrade, red when \nit's above `100`, and orange when it's below `0`.\n\n## Installation\n```js\nopenmct.install(openmct.plugins.SummaryWidget());\n```\n\n<!-- File: src/plugins/URLIndicatorPlugin/README.md (Tokens: ~200 | Category: plugin-manifest) -->\n# URL Indicator\nAdds an indicator which shows the availability of a URL, with success based on receipt of a 200 HTTP code. Can be used \nfor monitoring the availability of web services.\n\n## Installation\n```js\nopenmct.install(openmct.plugins.URLIndicator({\n  url: 'http://localhost:8080',\n    iconClass: 'check',\n    interval: 10000,\n    label: 'Localhost'\n })\n);\n```\n\n## Options\n* __url__: URL to indicate the status of\n* __iconClass__: Icon to show in the status bar, defaults to icon-database. See the [Style Guide](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home/glyphs?view=styleguide.glyphs) for more icon options.\n* __interval__: Interval between checking the connection, defaults to 10000\n* __label__: Name showing up as text in the status bar, defaults to url\n\n<!-- File: src/plugins/userIndicator/README.md (Tokens: ~526 | Category: plugin-manifest) -->\n# User Indicator\n\nThis plugin provides a user indicator for the top status bar that displays user information as\ndefined by a User Provider. A User Provider must be registered as a prerequisite for this plugin.\n\nIf the User Provider supports role-based access control, the user indicator will display the user's\ncurrent role and, if the user has multiple roles, allow the user to switch between them.\n\n## Usage\n\nTo use this plugin, first register a custom User Provider with the `openmct` API, or install the example\nUser Provider plugin:\n\n```javascript\nopenmct.install(openmct.plugins.example.ExampleUser());\n```\n\nThen, install the User Indicator plugin:\n\n```javascript\nopenmct.install(openmct.plugins.UserIndicator());\n```\n\n## Configuration\n\nThe User Indicator plugin does not require any configuration itself.\n\n## Mission Status\n\n\"Mission Status\" is a feature that is used to indicate the current state of a mission with regards to\none or more \"Mission Actions\". A mission action defines a verb that may be, for example, a task \nfor a spacecraft (such as \"Drive\" or \"Imagery\"), a change in the state of a ground system, or any \nother event that is relevant to the mission. Example states for a mission action might include\n\"Go\" or \"No Go\", indicating whether a particular action is currently cleared for execution.\n\nA user with the appropriate permissions may set the mission status by clicking on either the\nUser Indicator itself, or the \"Mission Status\" button next to the User Indicator. This will\nopen a dialog that allows the user to set the status of each mission action.\n\n### Provider Configuration\n\nIn order to use the Mission Status feature, a registered User Provider must define the following\nmethods:\n\n* `canSetMissionStatus`: A method that returns a boolean indicating whether the current user has\n  permission to set the mission status.\n* `getPossibleMissionActions`: A method that returns an array of mission actions that the user\n  may set the status of. Each mission action should have a `key` and a `name` property.\n* `getPossibleMissionActionStatuses`: A method that returns an array of `MissionStatusOption` objects,\n  which define the possible statuses for each mission action.\n* `getStatusForMissionAction`: A method that returns the current status for a given mission action.\n* `setStatusForMissionAction`: A method that sets the status for a given mission action.\n\nThe [Example User Provider](../../../example/exampleUser/ExampleUserProvider.js) provides an example\nimplementation of these methods.\n</yakaai_skills>"}