@alleninstitute/cortex-ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +390 -0
  2. package/dist/cjs/cortex-ui.cjs.js +24 -0
  3. package/dist/cjs/cui-tag.cjs.entry.js +24 -0
  4. package/dist/cjs/index-Rxdz0vyq.js +1337 -0
  5. package/dist/cjs/index.cjs.js +2 -0
  6. package/dist/cjs/loader.cjs.js +12 -0
  7. package/dist/collection/collection-manifest.json +13 -0
  8. package/dist/collection/components/cui-tag/cui-tag.css +49 -0
  9. package/dist/collection/components/cui-tag/cui-tag.js +97 -0
  10. package/dist/collection/index.js +8 -0
  11. package/dist/collection/stories/assets/accessibility.svg +1 -0
  12. package/dist/collection/stories/assets/discord.svg +1 -0
  13. package/dist/collection/stories/assets/github.svg +1 -0
  14. package/dist/collection/stories/assets/tutorials.svg +1 -0
  15. package/dist/collection/stories/assets/youtube.svg +1 -0
  16. package/dist/components/cui-tag.d.ts +11 -0
  17. package/dist/components/cui-tag.js +1 -0
  18. package/dist/components/index.d.ts +35 -0
  19. package/dist/components/index.js +1 -0
  20. package/dist/cortex-ui/cortex-ui.css +1 -0
  21. package/dist/cortex-ui/cortex-ui.esm.js +1 -0
  22. package/dist/cortex-ui/index.esm.js +0 -0
  23. package/dist/cortex-ui/p-054ebfa8.entry.js +1 -0
  24. package/dist/cortex-ui/p-C70YK15K.js +2 -0
  25. package/dist/esm/cortex-ui.js +20 -0
  26. package/dist/esm/cui-tag.entry.js +22 -0
  27. package/dist/esm/index-C70YK15K.js +1330 -0
  28. package/dist/esm/index.js +1 -0
  29. package/dist/esm/loader.js +10 -0
  30. package/dist/index.cjs.js +1 -0
  31. package/dist/index.js +1 -0
  32. package/dist/types/components/cui-tag/cui-tag.d.ts +12 -0
  33. package/dist/types/components.d.ts +84 -0
  34. package/dist/types/global.d.ts +2 -0
  35. package/dist/types/index.d.ts +1 -0
  36. package/dist/types/stencil-public-runtime.d.ts +1861 -0
  37. package/loader/cdn.js +1 -0
  38. package/loader/index.cjs.js +1 -0
  39. package/loader/index.d.ts +24 -0
  40. package/loader/index.es2017.js +1 -0
  41. package/loader/index.js +2 -0
  42. package/package.json +128 -0
package/README.md ADDED
@@ -0,0 +1,390 @@
1
+ # Cortex UI – Web Components Library
2
+
3
+ A reusable web components library built with [Stencil.js](https://stenciljs.com/), documented with [Storybook](https://storybook.js.org/).
4
+
5
+ ## Getting Started
6
+
7
+ ### Prerequisites
8
+
9
+ - Node.js >= 24
10
+ - pnpm >= 11
11
+
12
+ ### Install dependencies
13
+
14
+ ```bash
15
+ pnpm install
16
+ ```
17
+
18
+ ### Development
19
+
20
+ Start the Stencil dev server and Storybook as preview playground (live-reload):
21
+
22
+ ```bash
23
+ pnpm dev
24
+ ```
25
+
26
+ #### Stencil only:
27
+
28
+ ```bash
29
+ pnpm dev:stencil
30
+ ```
31
+
32
+ #### Storybook only:
33
+
34
+ ```bash
35
+ pnpm dev:storybook
36
+ ```
37
+
38
+ ### Build
39
+
40
+ Build the component library for production:
41
+
42
+ ```bash
43
+ pnpm build
44
+ ```
45
+
46
+ Build the React wrapper library (`@alleninstitute/cortex-ui-react`):
47
+
48
+ ```bash
49
+ pnpm build:react
50
+ ```
51
+
52
+ Build everything (web components first, then the React wrappers and MCP server that depend on them):
53
+
54
+ ```bash
55
+ pnpm build:all
56
+ ```
57
+
58
+ ### Test
59
+
60
+ Run unit tests:
61
+
62
+ ```bash
63
+ pnpm test
64
+ ```
65
+
66
+ Watch mode:
67
+
68
+ ```bash
69
+ pnpm test:watch
70
+ ```
71
+
72
+ ### Lint & Format
73
+
74
+ ```bash
75
+ pnpm lint
76
+ pnpm fmt
77
+ ```
78
+
79
+ ### Generate a new component
80
+
81
+ ```bash
82
+ pnpm generate
83
+ ```
84
+
85
+ ## Component Maturity
86
+
87
+ Every component publishes a maturity label — the stability promise its public API makes — shown as a badge at the top
88
+ of its Storybook docs page:
89
+
90
+ | Label | What it promises |
91
+ | -------------- | ----------------------------------------------------------------- |
92
+ | `experimental` | New and unproven; may change or be removed without notice. |
93
+ | `beta` | In real use and settling, but may still shift in a minor release. |
94
+ | `stable` | Committed API; breaking changes require a major version. |
95
+ | `deprecated` | Scheduled for removal, with the replacement named in its docs. |
96
+
97
+ Check the label before you build against a component. The full explanation lives on the
98
+ [Component Maturity](https://alleninstitute.github.io/cortex-ui/?path=/docs/component-maturity--docs) page, and each
99
+ component's maturity is also included in the machine-readable docs below so agents can read it too.
100
+
101
+ ## Using the Library
102
+
103
+ ### Script tag
104
+
105
+ Add the following to your HTML:
106
+
107
+ TBD process
108
+
109
+ Then use the components anywhere in your HTML:
110
+
111
+ ```html
112
+ <cui-tag
113
+ variant="positive"
114
+ label="Active"
115
+ ></cui-tag>
116
+ ```
117
+
118
+ ### NPM package
119
+
120
+ ```bash
121
+ npm install @alleninstitute/cortex-ui
122
+ ```
123
+
124
+ #### Vanilla JS / framework-agnostic
125
+
126
+ ```js
127
+ import { defineCustomElements } from '@alleninstitute/cortex-ui/loader';
128
+ defineCustomElements();
129
+ ```
130
+
131
+ #### TypeScript support
132
+
133
+ The package ships with full type definitions. Import the generated types:
134
+
135
+ ```ts
136
+ import { Components } from '@alleninstitute/cortex-ui';
137
+ ```
138
+
139
+ #### React
140
+
141
+ React consumers should use the dedicated wrapper package `@alleninstitute/cortex-ui-react`, which provides typed React components (with JSX prop/event bindings) generated from the web components.
142
+
143
+ ```bash
144
+ npm install @alleninstitute/cortex-ui-react
145
+ # peer deps: react, react-dom (>= 18)
146
+ ```
147
+
148
+ ```tsx
149
+ import { CuiTag } from '@alleninstitute/cortex-ui-react';
150
+
151
+ function Example() {
152
+ return (
153
+ <CuiTag
154
+ variant="positive"
155
+ label="Active"
156
+ />
157
+ );
158
+ }
159
+ ```
160
+
161
+ ## AI Tooling
162
+
163
+ Cortex UI is built to be agent-friendly. If you (or your coding agent) are building UIs with this library:
164
+
165
+ ### MCP server
166
+
167
+ `@alleninstitute/cortex-ui-mcp` is a [Model Context Protocol](https://modelcontextprotocol.io) server that lets AI
168
+ agents list and search components, read full component APIs and design tokens, fetch framework setup guides, and
169
+ validate generated `cui-*` markup before shipping it.
170
+
171
+ ```sh
172
+ # Claude Code
173
+ claude mcp add cortex-ui -- npx @alleninstitute/cortex-ui-mcp
174
+ ```
175
+
176
+ Agents working **inside this repo** get the server from the checked-in [.mcp.json](.mcp.json) instead — no client
177
+ config needed, but it runs from a local build, so build it once first:
178
+
179
+ ```bash
180
+ pnpm build # writes docs/ (component manifest + tokens + llms*.txt)
181
+ pnpm build:mcp # compiles packages/mcp/dist and snapshots docs/ into it
182
+ ```
183
+
184
+ That config sets `CORTEX_UI_DOCS_DIR=docs`, so the server reads the generated docs live: a plain `pnpm build` picks up
185
+ your component changes, with no `pnpm build:mcp` and no client restart needed.
186
+
187
+ See [packages/mcp](packages/mcp/README.md) for the full tool list, config for other MCP clients, and how to drive the
188
+ server by hand with the MCP inspector.
189
+
190
+ ### Machine-readable docs
191
+
192
+ Every build regenerates agent-consumable docs, which are also served from the deployed Storybook site root:
193
+
194
+ - `docs/llms.txt` / `docs/llms-full.txt` — [llms.txt](https://llmstxt.org) index and full plain-text API reference
195
+ - `docs/components.json` — Stencil docs-json component manifest
196
+ - `docs/tokens.json` — structured `--cui-*` design tokens with light/dark values
197
+
198
+ ### Storybook MCP addon
199
+
200
+ `pnpm dev` runs Storybook with [`@storybook/addon-mcp`](https://storybook.js.org/addons/@storybook/addon-mcp), which
201
+ exposes a live MCP endpoint at `http://localhost:6001/mcp` for story-aware tooling during development.
202
+
203
+ ## Developing Locally Against a Consuming App
204
+
205
+ This repo is a **pnpm workspace** with three published packages:
206
+
207
+ | Package | Location | What it is |
208
+ | --------------------------------- | ------------------------ | ---------------------------- |
209
+ | `@alleninstitute/cortex-ui` | repo root | the Stencil web components |
210
+ | `@alleninstitute/cortex-ui-react` | `packages/react-library` | the generated React wrappers |
211
+ | `@alleninstitute/cortex-ui-mcp` | `packages/mcp` | the MCP server for AI agents |
212
+
213
+ When you want to develop against these packages from another local app (before publishing), link them with pnpm's [`link:` protocol](https://pnpm.io/cli/link). The key gotcha: **`link:` takes a directory path, not the package name** — and the React package's folder is `packages/react-library`, _not_ `cortex-ui-react`.
214
+
215
+ ### 1. Build the packages first
216
+
217
+ The `link:` targets point at the built `dist/` output, so build before (and after) consuming:
218
+
219
+ ```bash
220
+ # in the cortex-ui repo
221
+ pnpm install
222
+ pnpm build:all
223
+ ```
224
+
225
+ While actively iterating, keep the wrappers rebuilding on change:
226
+
227
+ ```bash
228
+ pnpm dev:react # tsc --watch for the React wrappers
229
+ # and, in another terminal, rebuild the web components on change:
230
+ pnpm dev:stencil
231
+ ```
232
+
233
+ ### 2. Add the `link:` dependencies in the consuming app
234
+
235
+ In the **consuming app's** `package.json`, add relative paths from that app to each package's directory:
236
+
237
+ ```jsonc
238
+ {
239
+ "dependencies": {
240
+ // path to the repo root (the web components package)
241
+ "@alleninstitute/cortex-ui": "link:<relative-path>/cortex-ui",
242
+ // path to the React wrapper package directory
243
+ "@alleninstitute/cortex-ui-react": "link:<relative-path>/cortex-ui/packages/react-library",
244
+ },
245
+ }
246
+ ```
247
+
248
+ To compute the correct relative path, run this from the consuming app's directory:
249
+
250
+ ```bash
251
+ # web components (repo root)
252
+ node -p "require('path').relative(process.cwd(), '/absolute/path/to/cortex-ui')"
253
+ # React wrappers (note the packages/react-library suffix)
254
+ node -p "require('path').relative(process.cwd(), '/absolute/path/to/cortex-ui/packages/react-library')"
255
+ ```
256
+
257
+ Then install in the consuming app:
258
+
259
+ ```bash
260
+ pnpm install
261
+ ```
262
+
263
+ ### Troubleshooting
264
+
265
+ - **`Failed to resolve ... @alleninstitute/cortex-ui-react`** — the `link:` path is wrong. It must end in `.../cortex-ui/packages/react-library` (the folder), not `.../cortex-ui-react` (the package name). The folder name and package name differ.
266
+ - **Types or components look stale / missing exports** — the `dist/` output is out of date. Re-run `pnpm build:all` in this repo (or use `pnpm dev:react` + `pnpm dev:stencil` to watch). Nothing works until `dist/` exists.
267
+ - **Do not commit the `link:` lines** in the consuming app — they only make sense on your machine. Swap back to a normal version range before committing.
268
+
269
+ ## Releasing
270
+
271
+ All three packages are versioned and published **in lockstep** under a single `v<semver>` git tag. They are not
272
+ independently versioned: the React wrappers are generated from the Stencil build and the MCP server bundles a snapshot
273
+ of the generated docs, so a component change ripples through all three. `@alleninstitute/cortex-ui-react` depends on
274
+ `@alleninstitute/cortex-ui` via `workspace:*`, which pnpm rewrites to the exact matching version as it packs.
275
+
276
+ Versions and release notes come from [git-cliff](https://git-cliff.org), driven by
277
+ [conventional commit](https://www.conventionalcommits.org) messages, configured in [cliff.toml](cliff.toml).
278
+
279
+ ### Cutting a release
280
+
281
+ Releasing is a deliberate, manual step — merging to `main` does not publish.
282
+
283
+ 1. Run the **Release** workflow (`Actions` → `Release` → `Run workflow`) from `main`. Tick **dry-run** first if you want
284
+ to preview the version and changelog without touching anything.
285
+ 2. It derives the next version from the commits since the last tag, verifies the build and tests, bumps every
286
+ publishable `package.json`, regenerates `CHANGELOG.md`, then commits and pushes `chore(release): v<semver>` plus the
287
+ `v<semver>` tag.
288
+ 3. Pushing that tag triggers the **Publish to npm** workflow, which builds all three packages, publishes them to npm
289
+ (root first, since the others depend on it) with [provenance](https://docs.npmjs.com/generating-provenance-statements),
290
+ and opens a GitHub Release with the generated notes.
291
+
292
+ To preview locally what the next release would be:
293
+
294
+ ```bash
295
+ pnpm release:version # the version git-cliff would pick
296
+ pnpm changelog:unreleased # the notes for the unreleased commits
297
+ pnpm changelog # rewrite CHANGELOG.md in full
298
+ ```
299
+
300
+ ### Version numbers
301
+
302
+ The library is pre-1.0 while components are still tagged `experimental` / `beta`, so `cliff.toml` sets
303
+ `breaking_always_bump_major = false`: while the major is `0`, a breaking change bumps the **minor** (`0.1.0` → `0.2.0`)
304
+ rather than jumping to `1.0.0`. Cutting `1.0.0` is intentional — pass it via the workflow's `version` input.
305
+
306
+ ### One-time setup
307
+
308
+ Publishing uses [npm trusted publishing](https://docs.npmjs.com/trusted-publishers): GitHub mints a short-lived OIDC
309
+ token that npm exchanges for publish credentials, so **there is no `NPM_TOKEN` secret**. Requires npm >= 11.5.1 and
310
+ Node >= 22.14.0, which the publish job asserts up front.
311
+
312
+ The catch is bootstrapping. npm's trusted-publisher config lives in a package's settings page, so the package has to
313
+ exist before it can be configured — unlike PyPI, npm cannot pre-authorize a name that has never been published
314
+ ([npm/cli#8544](https://github.com/npm/cli/issues/8544)). Each of the three packages therefore needs one manual publish
315
+ first:
316
+
317
+ ```bash
318
+ npm login # an account with publish rights on @alleninstitute
319
+ pnpm build:all
320
+ pnpm publish --access public --no-git-checks # @alleninstitute/cortex-ui
321
+ pnpm --filter @alleninstitute/cortex-ui-react publish --access public --no-git-checks
322
+ pnpm --filter @alleninstitute/cortex-ui-mcp publish --access public --no-git-checks
323
+ ```
324
+
325
+ Then, for **each** of the three packages, on npmjs.com → package `Settings` → `Trusted Publisher`, select GitHub Actions
326
+ and set:
327
+
328
+ | Field | Value |
329
+ | ----------------- | ---------------- |
330
+ | Organization | `AllenInstitute` |
331
+ | Repository | `cortex-ui` |
332
+ | Workflow filename | `publish.yml` |
333
+ | Environment | _(leave blank)_ |
334
+
335
+ After that the Release → Publish pipeline runs unattended, and the manual step never has to happen again.
336
+
337
+ The one secret that _is_ required:
338
+
339
+ - **`SERVICE_ACCOUNT_SSH_KEY`** — an SSH deploy key with write access, so the release commit and tag can land on the
340
+ protected `main` branch. Same secret name and service account as the other Allen Institute repos.
341
+
342
+ ### Provenance and repository visibility
343
+
344
+ Trusted publishing works regardless of repository visibility, but
345
+ [provenance attestations require a **public source repository**](https://github.blog/changelog/2023-07-26-publishing-with-npm-provenance-from-private-source-repositories-is-no-longer-supported/) —
346
+ npm dropped support for private ones in 2023. `cortex-ui` is currently private, so the publish job sets
347
+ `NPM_CONFIG_PROVENANCE=false` and ships without attestations.
348
+
349
+ This is derived from `github.event.repository.private` at run time, not hardcoded: **make the repo public and the next
350
+ release gets provenance automatically**, with no change to the workflow. It is set explicitly in both directions on
351
+ purpose — OIDC otherwise auto-enables provenance based on _package_ visibility, and since these packages are public
352
+ while the repo is not, it would enable provenance and then fail the publish.
353
+
354
+ ### If a publish fails partway
355
+
356
+ npm versions are immutable, so a failure between packages leaves the release half-published — say `cortex-ui` at the new
357
+ version but `cortex-ui-react` still at the old one. The tag and changelog are already correct at that point, so **do not
358
+ re-run Release**; that would only try to cut a second version. Fix the cause, then re-run the failed **Publish to npm**
359
+ run. The publish step skips any package whose version is already on npm, so a re-run picks up exactly the packages that
360
+ did not make it.
361
+
362
+ ### Prepublish safety
363
+
364
+ Every package runs its own build in `prepack`, so `dist/`, the generated React source, and the MCP docs snapshot can
365
+ never be published stale — including from a hand-run `pnpm publish`. The publish workflow additionally runs
366
+ `pnpm build:all` up front so a build failure stops the release before any package reaches npm.
367
+
368
+ ## Project Structure
369
+
370
+ ```
371
+ src/
372
+ components/ # Stencil web components
373
+ cui-tag/ # Example tag component
374
+ utils/ # Internal dev helpers
375
+ index.ts # Library entry point
376
+ index.html # Dev server preview page
377
+ packages/
378
+ react-library/ # @alleninstitute/cortex-ui-react — generated React wrappers
379
+ src/
380
+ components/
381
+ stencil-generated/ # auto-generated by the Stencil React output target
382
+ index.ts
383
+ mcp/ # @alleninstitute/cortex-ui-mcp — MCP server for AI agents
384
+ docs/ # generated component manifest + AI docs (llms.txt, tokens.json)
385
+ scripts/ # build helpers (generate-ai-docs.mjs)
386
+ .storybook/ # Storybook configuration
387
+ .mcp.json # registers the MCP server for agents working in this repo
388
+ stencil.config.ts # Stencil build configuration (incl. React output target)
389
+ pnpm-workspace.yaml # pnpm workspace definition
390
+ ```
@@ -0,0 +1,24 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-Rxdz0vyq.js');
4
+
5
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
6
+ /*
7
+ Stencil Client Patch Browser v4.43.5 | MIT Licensed | https://stenciljs.com
8
+ */
9
+
10
+ var patchBrowser = () => {
11
+ const importMeta = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cortex-ui.cjs.js', document.baseURI).href));
12
+ const opts = {};
13
+ if (importMeta !== "") {
14
+ opts.resourcesUrl = new URL(".", importMeta).href;
15
+ }
16
+ return index.promiseResolve(opts);
17
+ };
18
+
19
+ patchBrowser().then(async (options) => {
20
+ await index.globalScripts();
21
+ return index.bootstrapLazy([["cui-tag.cjs",[[1,"cui-tag",{"label":[1],"variant":[1],"size":[1]}]]]], options);
22
+ });
23
+
24
+ exports.setNonce = index.setNonce;
@@ -0,0 +1,24 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-Rxdz0vyq.js');
4
+
5
+ const cuiTagCss = () => `:host{display:inline-block}.cui-tag{font-family:var(--cui-font-family-base);display:inline-flex;align-items:center;justify-content:center;border-radius:var(--cui-radius-sm);font-weight:var(--cui-font-weight-semibold);white-space:nowrap}.cui-tag--small{padding:var(--cui-spacing-xxs) var(--cui-spacing-sm);font-size:var(--cui-font-size-xs)}.cui-tag--medium{padding:var(--cui-spacing-xs) var(--cui-spacing-md);font-size:var(--cui-font-size-sm)}.cui-tag--default{background-color:var(--cui-accent-bg);color:var(--cui-accent-text)}.cui-tag--highlight{background-color:var(--cui-highlight-bg);color:var(--cui-highlight-text)}.cui-tag--info{background-color:var(--cui-info-bg);color:var(--cui-info-text)}.cui-tag--negative{background-color:var(--cui-negative-bg);color:var(--cui-negative-text)}.cui-tag--neutral{background-color:var(--cui-neutral-bg);color:var(--cui-neutral-text)}.cui-tag--positive{background-color:var(--cui-positive-bg);color:var(--cui-positive-text)}.cui-tag--warning{background-color:var(--cui-warning-bg);color:var(--cui-warning-text)}`;
6
+
7
+ const CuiTag = class {
8
+ constructor(hostRef) {
9
+ index.registerInstance(this, hostRef);
10
+ this.label = '';
11
+ this.variant = 'default';
12
+ this.size = 'medium';
13
+ }
14
+ render() {
15
+ return (index.h("span", { key: 'd2bab55fc1472bb8f004ef648103478070bb4723', class: {
16
+ 'cui-tag': true,
17
+ [`cui-tag--${this.variant}`]: true,
18
+ [`cui-tag--${this.size}`]: true,
19
+ } }, this.label));
20
+ }
21
+ };
22
+ CuiTag.style = cuiTagCss();
23
+
24
+ exports.cui_tag = CuiTag;