Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
07a2b4b
ci: sync the release workflow on v2/main with main's verbatim (#1902)…
cliffhall Aug 2, 2026
943f37a
docs: make assigning a milestone the act that moves a card to Todo
cliffhall Aug 5, 2026
04f1a56
docs: make triage runnable — state-based test, both-board sweep, boar…
cliffhall Aug 5, 2026
a923842
docs: Done means shipped — remove, don't park, issues closed any othe…
cliffhall Aug 5, 2026
d0b683d
docs: require a type label (bug/enhancement/documentation/chore/quest…
cliffhall Aug 5, 2026
22da48c
fix: ship clients/web/static so the MCP Apps sandbox proxy loads
cliffhall Aug 5, 2026
28a21c5
test: add an MCP App showcase config to reproduce and verify #1859
cliffhall Aug 5, 2026
cf0ed4a
test: add smoke:web:app — drive a real MCP App end to end in headless…
cliffhall Aug 5, 2026
3f4f686
fix: give smoke:web:app its own port; note the App config's era in th…
cliffhall Aug 6, 2026
556aaca
fix: fail smoke:web:app on async crashes, not just sync page errors
cliffhall Aug 6, 2026
5401e52
fix: handle spawn failure of the MCP test server in smoke:web:app
cliffhall Aug 6, 2026
097bfaf
Merge pull request #1934 from modelcontextprotocol/v2/fix/package-san…
cliffhall Aug 6, 2026
9644ac7
fix: prime SSE streams so Firefox resolves the events fetch
cliffhall Aug 6, 2026
f201032
fix: surface list-fetch failures instead of swallowing them
cliffhall Aug 8, 2026
1e427c0
fix: mark a rejected standalone response entry as an error too
cliffhall Aug 8, 2026
fad8480
fix: only attribute a decode rejection to a Protocol entry
cliffhall Aug 8, 2026
a6f233e
fix: read the list error via useSyncExternalStore; clear correlation …
cliffhall Aug 8, 2026
8b3d2bc
Merge pull request #1954 from modelcontextprotocol/v2/fix/surface-lis…
cliffhall Aug 8, 2026
bb219dc
fix: construct AsyncEntry inside the try so keychain degradation enga…
olaservo Aug 9, 2026
a09f2dc
fix: load @napi-rs/keyring lazily so an unsupported platform degrades…
olaservo Aug 9, 2026
1881e5c
fix: settle the deliberately in-flight tool calls in the progress tests
cliffhall Aug 10, 2026
0b9aee1
fix: only absorb the teardown's own rejection in settleInFlight
cliffhall Aug 10, 2026
c60563b
fix: observe the derived promise so an unexpected rejection can't go …
cliffhall Aug 10, 2026
347173f
fix: absorb only the teardown's own close, not any ConnectionClosed
cliffhall Aug 10, 2026
2e89443
docs: add the v1 → v2 migration guide
cliffhall Aug 10, 2026
6f53535
fix: key tool rows by source position so duplicate names filter corre…
cliffhall Aug 10, 2026
4340283
test: add a duplicate-tool-names test server for the #1957 repro
cliffhall Aug 11, 2026
6c33da3
chore(deps): align zod across installs and guard against version skew
cliffhall Aug 11, 2026
e328da4
test: cover the duplicateToolNames server option over a live connection
cliffhall Aug 11, 2026
e480fdc
chore(deps): cover .mts/.cts in the shared-source scan, fix the READM…
cliffhall Aug 11, 2026
20527dc
docs: address Copilot review on the v1 → v2 migration guide
cliffhall Aug 11, 2026
7a74b5e
fix: forward the negotiated protocol version to the remote backend tr…
cliffhall Aug 11, 2026
47e0ee0
chore(deps): match CommonJS and template-literal imports in the share…
cliffhall Aug 11, 2026
908284d
docs: address Copilot's suppressed comments on the migration guide
cliffhall Aug 11, 2026
8c9cf40
docs: qualify the ad-hoc rule and fix the contradicting `--` guidance
cliffhall Aug 11, 2026
ddfce0f
fix: reject a non-string protocolVersion, and drop the test double casts
cliffhall Aug 11, 2026
4fe02bc
docs: keep the Docker recipes loopback-only; note the legacy token fa…
cliffhall Aug 11, 2026
35317fd
chore(deps): scope the allowlist to a major, cover vitest.shared.mts,…
cliffhall Aug 11, 2026
2dcf145
chore(deps): see imports through comment trivia; name vitest.shared.m…
cliffhall Aug 11, 2026
2f1d97e
chore(deps): treat line comments as trivia too in the import scan
cliffhall Aug 11, 2026
fcd4503
chore(deps): extract specifiers with ts.preProcessFile; document the …
cliffhall Aug 11, 2026
3638185
chore(deps): fail with a cause when typescript can't be resolved
cliffhall Aug 11, 2026
48d74ba
chore(deps): check each shared source contributed, not the aggregate …
cliffhall Aug 11, 2026
2f2d545
docs: narrow the dep-lockstep summaries to the invariant it actually …
cliffhall Aug 11, 2026
32c827f
test(scripts): exercise the dep-lockstep guard's executable path
cliffhall Aug 11, 2026
af63a07
chore(deps): reject an unreadable lockfile instead of failing open
cliffhall Aug 11, 2026
87c1e05
chore(deps): count triple-slash type references as candidates
cliffhall Aug 11, 2026
8a2035c
test(scripts): cover verify-format-coverage's sibling-guard vouch
cliffhall Aug 11, 2026
e1768e4
chore(deps): check the declared lockfileVersion, not just the package…
cliffhall Aug 11, 2026
288adbc
chore(deps): enrol installs by package.json, and fail on a missing lo…
cliffhall Aug 11, 2026
719da6f
ci: gate claude.yml on same-repo PRs and pin actions to commit SHAs (…
cliffhall Aug 11, 2026
0325d81
fix: open the modern listen stream whenever the filter is non-empty (…
cliffhall Aug 11, 2026
eda8ec0
fix: guard the connect-time listen failure on the refresh generation
cliffhall Aug 11, 2026
ca70a7c
chore(storybook): drop the redundant setProjectAnnotations setup file
cliffhall Aug 11, 2026
d08a530
fix: dispatch the connect event after the listen stream is up
cliffhall Aug 11, 2026
d1135df
chore(storybook): derive the primary shade from the theme in the guard
cliffhall Aug 11, 2026
b2dfd40
docs: correct three comments the connect-ordering change invalidated
cliffhall Aug 11, 2026
2a4e93c
fix: only announce the connection if it is still live after the strea…
cliffhall Aug 11, 2026
31c41d3
chore: declare the MCP SDK packages only at the repo root (#1970)
cliffhall Aug 11, 2026
51bbe99
fix(web): keep the text being typed in a schema number field (#1888)
cliffhall Aug 11, 2026
6f47eaa
fix: render a tool result's structuredContent in the Tools screen (#1…
cliffhall Aug 11, 2026
e132d55
docs: record where a dependency is declared, and why
cliffhall Aug 11, 2026
3173b26
fix(docker): publish on loopback by default; make a mounted state dir…
cliffhall Aug 11, 2026
5a3a343
docs: correct the dependency-classification claims
cliffhall Aug 11, 2026
24a9786
fix(web): reset a number field's draft text when the form changes entity
cliffhall Aug 11, 2026
5be2b3e
docs: address Copilot review — volume upgrade path, and drop the toke…
cliffhall Aug 11, 2026
6fd03d6
fix(web): don't round unrepresentable numbers, and reset app-switch d…
cliffhall Aug 11, 2026
8049b4f
test: cover the structured-output cap and the list_items showcase end…
cliffhall Aug 11, 2026
539067f
Merge pull request #1975 from modelcontextprotocol/v2/fix/1908-struct…
cliffhall Aug 11, 2026
e7f0dc8
Merge pull request #1974 from modelcontextprotocol/v2/docs/1964-docke…
cliffhall Aug 11, 2026
a4a8d4e
Merge pull request #1972 from modelcontextprotocol/v2/fix/1888-float-…
cliffhall Aug 11, 2026
2ccda80
Merge pull request #1932 from modelcontextprotocol/v2/docs/incoming-t…
cliffhall Aug 11, 2026
0f44288
Merge branch 'v2/main' into v2/fix/tool-row-keys
cliffhall Aug 11, 2026
d5b948b
Merge pull request #1961 from modelcontextprotocol/v2/fix/tool-row-keys
cliffhall Aug 11, 2026
eee482e
Merge pull request #1966 from modelcontextprotocol/v2/ci/harden-claud…
cliffhall Aug 11, 2026
16b9eff
Merge pull request #1962 from modelcontextprotocol/v2/chore/zod-versi…
cliffhall Aug 11, 2026
59f5b6d
Merge pull request #1971 from modelcontextprotocol/v2/chore/root-only…
cliffhall Aug 11, 2026
f404d50
Merge pull request #1963 from modelcontextprotocol/v2/fix/proxy-proto…
cliffhall Aug 11, 2026
e5b32ef
Merge branch 'v2/main' into v2/docs/1822-migration-guide
cliffhall Aug 11, 2026
53b619d
Merge pull request #1958 from modelcontextprotocol/v2/fix/unhandled-r…
cliffhall Aug 11, 2026
0a2b7f7
Merge branch 'v2/main' into v2/docs/1822-migration-guide
cliffhall Aug 11, 2026
4b9d84d
Merge pull request #1968 from modelcontextprotocol/v2/chore/1898-drop…
cliffhall Aug 11, 2026
75f4597
Merge pull request #1967 from modelcontextprotocol/v2/fix/modern-list…
cliffhall Aug 11, 2026
9e074aa
Merge pull request #1946 from modelcontextprotocol/v2/fix/firefox-sse…
cliffhall Aug 11, 2026
925b699
Merge pull request #1960 from modelcontextprotocol/v2/docs/1822-migra…
cliffhall Aug 11, 2026
29e3ce9
chore(smoke): run the web smokes against a throwaway catalog
cliffhall Aug 11, 2026
16c96d4
fix(smoke): await the server's exit before removing its catalog, and …
cliffhall Aug 11, 2026
4a993fc
docs(smoke): document the throwaway-catalog invariant and fix the lab…
cliffhall Aug 11, 2026
3d54138
test(smoke): exercise the real teardown path, not just removeSafe
cliffhall Aug 11, 2026
678184e
fix(smoke): pin the teardown ordering, and correct a docblock the tes…
cliffhall Aug 11, 2026
bb599e5
docs: add the six-month Inspector roadmap (Aug 2026 → Feb 2027)
cliffhall Aug 11, 2026
f060c97
docs: mirror the smoke-isolation invariant into copilot-instructions
cliffhall Aug 11, 2026
b737360
Merge pull request #1978 from modelcontextprotocol/v2/chore/1977-isol…
cliffhall Aug 11, 2026
f4529df
docs: document the DCO signoff requirement
cliffhall Aug 12, 2026
b3242bc
fix(docs): format.signOff does not sign commits, and remediation is u…
cliffhall Aug 12, 2026
6899e0a
fix(docs): make the signoff hook identity-aware
cliffhall Aug 12, 2026
3c93c05
fix(docs): the DCO app does have a write-access override
cliffhall Aug 12, 2026
eb5bba6
fix(tui): bundle React-rendering deps so a consumer install can't spl…
cliffhall Aug 12, 2026
bd6c107
fix(docs): drop the signoff hook — it cannot know the commit author
cliffhall Aug 12, 2026
3c1bbbc
fix(tui): correct ink-form's misspelled incomplete-form hint
cliffhall Aug 12, 2026
c158ad8
fix(docs): correct the DCO rules against the validator source
cliffhall Aug 12, 2026
39575ff
test(tui): drive the ink-form patch through the plugin, and drop the …
cliffhall Aug 12, 2026
9fd5bc1
chore: drop the orphaned root override, and correct the TUI coverage …
cliffhall Aug 12, 2026
1e0f94b
fix(test): clear leaked timers so one cannot fail an unrelated CI run
cliffhall Aug 12, 2026
94a227b
fix(tui): widen the root react range so an external ink can't split R…
cliffhall Aug 12, 2026
24d89d7
fix(test): wait for the dead transport instead of sleeping 300ms
cliffhall Aug 12, 2026
10793d7
Merge pull request #1983 from modelcontextprotocol/v2/fix/1952-tui-fo…
cliffhall Aug 12, 2026
c4e8ed9
fix(test): cancel queued frames before sweeping timers
cliffhall Aug 12, 2026
b70aed6
test(fix): probe a single-source route when waiting for the dead tran…
cliffhall Aug 12, 2026
b451949
docs: the renderWithMantine rule no longer rests on timer safety
cliffhall Aug 12, 2026
c0e4b89
fix(test): treat timer handles as opaque; the numeric guard never mat…
cliffhall Aug 12, 2026
95d4799
Merge pull request #1987 from modelcontextprotocol/v2/fix/1985-dead-s…
cliffhall Aug 12, 2026
f9d893f
Merge pull request #1986 from modelcontextprotocol/v2/fix/1984-mantin…
cliffhall Aug 12, 2026
532ad82
Merge pull request #1982 from modelcontextprotocol/v2/docs/1979-dco-s…
cliffhall Aug 12, 2026
3e76498
chore: upgrade the MCP TypeScript SDK from 2.0.0-beta.5 to 2.0.0
cliffhall Aug 12, 2026
5587829
docs: correct the EMA spec's stale SDK-dependency claim
cliffhall Aug 12, 2026
57d6e0d
Merge pull request #1989 from modelcontextprotocol/v2/chore/1988-sdk-…
cliffhall Aug 12, 2026
c8aa54d
chore: merge v2/main for the v2.2.0 milestone release
cliffhall Aug 12, 2026
27cd42b
chore: 2.2.0
cliffhall Aug 12, 2026
5ec2ecf
Merge pull request #1981 from modelcontextprotocol/v2/docs/1980-inspe…
cliffhall Aug 12, 2026
ec28099
chore: merge v2/main — the roadmap (#1981)
cliffhall Aug 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ Both exist and do different jobs. Theme files (`src/theme/<Component>.ts`) custo
- `src/types/` is only for ambient `.d.ts` module stubs — not a home for new domain types.
- ⚠️ The coverage `include` is a **whitelist** naming `components` / `hooks` / `theme` / `lib` / `utils` / `server` (plus the `core/*` runtime). A module placed outside those directories silently falls out of the ≥90% gate. Flag new top-level files or new grab-bag directories.

## Dependency placement

- **The MCP SDK packages (`@modelcontextprotocol/client`, `core`, `server`, `server-legacy`, `ext-apps`) belong in the root `package.json` only.** Adding one to a `clients/*/package.json` is a review finding: Node resolution walks up, so the root install already serves every client, and a per-client entry installs a second copy that drifts (it produced two versions of `ext-apps`, and of the transitive v1 SDK, at once — #1970) and reintroduces the duplicate-copy failure `vitest.shared.mts` has a `dedupe` workaround for.
- **The v1 `@modelcontextprotocol/sdk` is not a dependency of this repo** and must not become one. It is a peer of `ext-apps`, present in lock files only.
- Dependencies reached only through **root-owned code with no manifest** (`test-servers/src`, `core/`) are declared at the root and aliased to the **repo root** in `vitest.shared.mts` — as `express` and `yaml` are — not to `<client>/node_modules` like the other pins there.
- **A dependency that renders React components must be bundled into the client that uses it, and is then not a root dependency.** An externalized package resolves its own `react` from wherever npm placed it in the *consumer's* tree, beside a React satisfying *its* peer range — looser than ours, which is all it takes to split React. `ink-form`/`ink-scroll-view` declare `">=18"`, so a consumer's React 18 satisfies them, the TUI ends up with two React instances, and it crashes on the first hook (#1952). Both are inlined via `noExternal` in `clients/tui/tsup.config.ts`. **`ink` is the one exemption, justified by cost (~1.4MB) — never by a peer range**: flag any claim that `">=19"` keeps npm from misplacing it, which is false and was in this repo once. What keeps it safe is the **root `react` range staying open to the whole major (`^19.0.0`)** so npm can dedupe with a consumer's pinned React 19; treat narrowing that range as reopening the bug. `clients/tui/__tests__/tsupConfig.test.ts` enforces the split, the root-declaration of exempt packages, and that range.
- **Which section is a separate question from which manifest.** A package `core/` imports at runtime must be in root **`dependencies`**: client builds externalize npm packages, so a published install resolves them from the root manifest and devDependencies are absent there. Only test/build-only packages (`express`) belong in `devDependencies`. Flag a runtime `core/` import added to `devDependencies` — it passes every local check and breaks the published package.

## Tests and the coverage gate

- **All new or modified code needs tests.** The per-file gate is **≥ 90% on all four dimensions** — lines, statements, functions, **and branches** — enforced in CI for `clients/{web,cli,tui,launcher}` and the gated `core/` runtime.
Expand All @@ -85,15 +93,18 @@ Both exist and do different jobs. Theme files (`src/theme/<Component>.ts`) custo

### Rendering components in tests

- **Always render through `renderWithMantine`** from `src/test/renderWithMantine.tsx`. Never hand-roll a bare `MantineProvider` — that reintroduces a real failure class where a `Transition`/`Modal` timer fires after happy-dom tears down `window` and fails the entire run.
- **Always render through `renderWithMantine`** from `src/test/renderWithMantine.tsx`. A hand-rolled bare `MantineProvider` skips the project theme and the helper's options, and drifts from every other test. (It does *not* reintroduce the timer-leak class — an older version of this rule said so; the leaked-timer net in `setup.ts` is global and covers every unit test regardless of how it renders.)
- For a forced color scheme, pass the option — `renderWithMantine(ui, { colorScheme: "dark" })` — rather than a hand-rolled `defaultColorScheme` provider.
- Only when asserting _mid-flight_ transition state, use `renderWithMantineTransitions`, passing `settleMs` derived from the component's real animation duration. Do **not** combine it with `vi.useFakeTimers()`, and use the `unmount()` it returns if the test unmounts the tree itself.

## Gates and PR hygiene

- `npm run format` before committing; **`npm run ci` before pushing** (`validate` → `coverage` → `verify:build-gate` → `smoke` → Storybook). `npm run validate` is the fast inner-loop check and is **not** a substitute — it runs `test`, not `test:coverage`, so it does zero coverage gating.
- **A dependency bump must land in every install that declares it.** v2 is not a workspace — the root and each `clients/*` have their own `node_modules`, and a client's test project compiles `core/` and `test-servers/src` (which resolve from the **root**) alongside the client's own sources. Bumping a shared dependency in one manifest only puts two versions of it in one `tsc` program; for a recursive-generic surface like zod that exhausts the tsc heap (#1896). `verify:dep-lockstep` fails the build on this, so a PR bumping a package that the shared sources import should update the root **and every client that already lists it** — not every client unconditionally, since a package absent from an install can't skew and adding it there would be a spurious dependency.
- **A test or smoke must not touch real user state.** The web smokes run against a throwaway catalog via the shared `scripts/lib/prod-web-server.mjs` helper, never the developer's `~/.mcp-inspector/mcp.json` (#1977); the cli/tui smokes drive a temp `--catalog`. A new smoke spawning its own server, or teardown that removes a work dir without first awaiting `stopChild` (the #1801 race — `child-cleanup.mjs` exports both halves and both are required), should be flagged.
- **Every PR references an issue**, first body line `Closes #<ISSUE_NUMBER>`.
- **Every PR carries exactly one version label**, `v1` or `v2`, matching its base branch.
- **Commits carry a `Signed-off-by:` trailer.** The DCO check is a hard merge gate and fails on a single unsigned commit; it matches the trailer against the author *or* committer, and skips only merge and bot commits. Use `git commit -s` — note `format.signOff` does *not* sign `git commit` (only `format-patch`). Repairing pushed commits means `git rebase HEAD~<n> --signoff` + `git push --force-with-lease`; remediation commits are not enabled on this repo.
- Update the relevant `README.md` / `AGENTS.md` when a change adds, removes, renames, or repurposes a file or folder, changes the structure or tech stack, or introduces a command, dependency, or architectural pattern.

## What to prioritize in review
Expand Down
53 changes: 45 additions & 8 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,18 @@ jobs:
id-token: write
actions: read
steps:
# Actions are pinned to full commit SHAs rather than mutable major tags:
# this job holds ANTHROPIC_API_KEY and grants the agent Bash, so a
# force-moved tag would be an unreviewed code change inside a
# secret-holding job. The trailing `# vX.Y.Z` comment is the form
# Dependabot reads, so pinning costs us no upgrade automation. (#1882)
- name: Get PR details
if: |
(github.event_name == 'issue_comment' && github.event.issue.pull_request) ||
github.event_name == 'pull_request_review_comment' ||
github.event_name == 'pull_request_review'
id: pr
uses: actions/github-script@v8
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
let prNumber;
Expand All @@ -57,26 +62,58 @@ jobs:
pull_number: prNumber
});

// A fork PR's head lives in a different repository — or in none at
// all, if the fork was deleted after the PR was opened (`head.repo`
// is then null). Neither is ours to check out, so both count as a
// fork here and the steps below decline rather than guess.
const headRepo = pr.data.head.repo?.full_name ?? null;
const isFork = headRepo !== `${context.repo.owner}/${context.repo.repo}`;

core.setOutput('sha', pr.data.head.sha);
core.setOutput('repo', pr.data.head.repo.full_name);
core.setOutput('is_fork', String(isFork));

# A fork PR's head is untrusted code, and checking it out would put it in
# reach of a tool-enabled agent run holding ANTHROPIC_API_KEY. Reviewing
# the base tree instead would only trade that for a confident review of
# the wrong tree, so decline visibly and leave the reason in the run.
- name: Decline fork PR
if: steps.pr.outcome == 'success' && steps.pr.outputs.is_fork == 'true'
run: |
{
echo "### Claude Code declined this pull request"
echo
echo "The head branch lives in a fork, so its code is not checked out and Claude is not run."
echo "Push the branch to this repository and re-trigger if a review is needed."
} >> "$GITHUB_STEP_SUMMARY"

# No `repository:` — a same-repo head is all that reaches this step, and
# checkout defaults to `github.repository`, which no PR can influence.
- name: Checkout PR branch
if: steps.pr.outcome == 'success'
uses: actions/checkout@v6
if: steps.pr.outcome == 'success' && steps.pr.outputs.is_fork == 'false'
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ steps.pr.outputs.sha }}
repository: ${{ steps.pr.outputs.repo }}
fetch-depth: 0

# `skipped` means the trigger was an issue or a non-PR comment, so there
# is no head to check out and the base tree is the right one. The lookup
# having *failed* is deliberately not included: this condition carries no
# status-check function, so GitHub applies an implicit `success()` and
# skips the step after a failed prior step anyway. Spelling out `skipped`
# keeps that from having to be re-derived by the next reader.
- name: Checkout repository
if: steps.pr.outcome != 'success'
uses: actions/checkout@v6
if: steps.pr.outcome == 'skipped'
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0

- name: Run Claude Code
# Runs only against a tree this workflow actually checked out: the base
# repo (non-PR trigger) or a same-repo PR head. A fork PR reaches here
# with `is_fork == 'true'` and both disjuncts false, so it is skipped.
if: steps.pr.outcome == 'skipped' || steps.pr.outputs.is_fork == 'false'
id: claude
uses: anthropics/claude-code-action@v1
uses: anthropics/claude-code-action@5ef2e550a465a721f4f45e4a7d3c340c873e1dcc # v1.0.190
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}

Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,11 @@ jobs:
# CLI/web). Not part of any client's `validate`: it needs the
# cli/tui/launcher bundles, which `validate` above already built
# (smoke:web builds clients/web/dist on demand — #1486). smoke:web:browser
# boots the prod web bundle in headless chromium (#1615). smoke:tui
# self-skips here — the Ink TUI needs a real TTY (raw mode) that headless
# CI lacks, so its boot/render check is local-only.
# boots the prod web bundle in headless chromium (#1615); smoke:web:app
# goes further and drives connect → open app → widget ready against a
# composable MCP App server (#1859). Both reuse the chromium installed
# above. smoke:tui self-skips here — the Ink TUI needs a real TTY (raw
# mode) that headless CI lacks, so its boot/render check is local-only.
run: npm run smoke

- name: Run Storybook play-function tests
Expand Down
Loading
Loading