Skip to content

Release 2.0.0-beta.7 - #449

Open
saeedjamshaid wants to merge 5 commits into
betafrom
dev
Open

saeedjamshaid wants to merge 5 commits into
betafrom
dev

Conversation

@saeedjamshaid

Copy link
Copy Markdown
Collaborator

Promotes dev to beta, expected to publish 2.0.0-beta.7 to the npm beta dist-tag as a GitHub prerelease. The run commits nothing back to beta; the tag goes on this merge commit.

Merge with Create a merge commit.

What releases

🤖 Generated with Claude Code

mehnoorsiddiqui and others added 5 commits October 16, 2026 17:41
… and other components (#439)

## The problem

The portal registered only Fumadocs' default MDX components (Callout,
Card, the code block tabs). Writing any other component from the
Fumadocs docs in a content page, such as `<Tabs>` or `<Steps>`, failed
the build unless the author imported it from Fumadocs' internal package
paths. Those paths are Fumadocs' layout, not something we can promise to
keep working across upgrades.

## What changes

- **`portal-template/src/components/mdx.tsx` registers these Fumadocs
components**, so `.mdx` pages can use them without an import:
  - `Tabs`, `Tab`
  - `Steps`, `Step`
  - `Accordions`, `Accordion`
  - `Files`, `Folder`, `File`
  - `TypeTable`
- `InlineTOC`, which takes the page's own `toc`: `<InlineTOC items={toc}
/>`
  - `Banner`
- **Left out:**
- `ImageZoom` imports its own stylesheet, which Node cannot load in the
server build, so the build fails. Making it work needs a client-only
wrapper of our own.
  - Mermaid: Fumadocs has no component for it.
- **Tests:** a page in the default fixture, `guides/components.mdx`,
uses every author-facing component and most of its props, and
`<include>`s `intro.md`. The new end-to-end test checks that the
server-rendered page carries each of them.

## How it was tested

- `APIMATIC_E2E=1` `test/e2e/portal-build.test.ts`: 66 passing.
- The portal generate and serve tests that use the default fixture: 75
passing.
- Driven by hand in headless Chrome, at the root and under `/api/`.
These checks are not in the repo, which has no browser test setup:
- tab switching, including `defaultIndex`, `tab="…"` fences, `npm`
fences and composed `CodeBlockTabs`
  - copy button
  - single and multiple accordions
  - opening a folder
  - expanding a TypeTable row
  - InlineTOC links
  - closing a dismissible Banner, which stays closed after a reload
- an internal Card navigating without a reload, under the base path too
  - no horizontal overflow at 390px
  - no console errors or hydration warnings
  - screenshots in light and dark mode

## Already true, and unchanged here

These apply to the existing components too:

- **Search:** text inside a component is not in the search index;
headings and top-level paragraphs are.
- **Markdown twin and `llms-full.txt`:** they keep components as tags,
with `{…}` props written out as strings, for example `items="toc"`.
- **Included files:** a file under `content/` that a page `<include>`s
is also published as a page of its own.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Removes code that nothing in the CLI calls, mostly left behind when `sdk
save-changes` was retired (#359) and when the portal stopped reading
`APIMATIC-BUILD.json`. Nothing behaves differently.

Review it commit by commit.

**1. `BuildConfig` and the plugin generate tests**
- `BuildConfig.toJSON()`, the `[key: string]: unknown` index signature
and `BuildConfig.from()` existed so the build file could be written back
to disk. The code that wrote it was removed in #343.
- The plugin generate tests no longer create an empty
`APIMATIC-BUILD.json`, which plugin generation has not needed since
#333. The upload test no longer checks that the file was uploaded.

**2. Unused code and `isomorphic-git`**
- `src/infrastructure/git-service.ts`: the whole file. Nothing has
imported it since `sdk save-changes` was retired.
`Directory.createFromRelativePaths` goes with it, because only this file
called it.
- `isomorphic-git`: only `git-service.ts` used it. The lockfile loses it
and the 22 packages only it depended on.
- Methods with no callers in `src/` or `test/`:
  - `FileService`: `fileExistsSync`, `pollDeleteDirectory`, `copyToDir`
- `LauncherService`: `isIdeAvailable`, `openFolderInIdeWithWait`,
`openInEditor`, `openFile`
  - `ActionResult`: `match`
  - `ServiceError`: `invalidResponse()`, `values`
- `SdkPublishInteractivePrompts`:
`sdkDirectoryCannotBeSameAsSourceDirectory`
  - `FileName.isMarkDown`, `UrlPath.isLocalhost`

Knip found the candidates, and each one was checked with grep, because
knip also flagged methods that are called.

**3. What review found**
- More methods with no callers, or only a call to themselves:
  - `ActionResult.getValueOr` (it came back with the merge from `dev`)
  - `FileService.copyDirectoryExcluding`
- `Directory.mapFilesInDirectory`, and `Directory.isEmpty`, which only
it called
  - `CodegenOption.codeGenerationVersion`
- The plugin upload test seeds a spec under `src/` and checks it goes up
beside `apimatic.json`, so a test still shows the whole of `src/` is
sent.
- The "generates without an APIMATIC-BUILD.json" test is dropped: every
test now runs without the build file, so it repeated the success path.
- `.ai/skills/value-object.md` names `hasExtension` instead of
`isMarkDown` as `FileName`'s predicate.

Left for later PRs:
- Unused packages in `package.json`: `async-mutex`, `@oclif/test`,
`simple-git`, `nyc`, `eslint-plugin-import`, `eslint-config-prettier`,
and the `@types` packages for `base-64`, `treeify`, `unzipper` and
`prettier`. `prettier` also belongs in devDependencies.
- Code only tests call: `PluginConfig.hasNoSourceRepository`,
`ServiceError.getError`, `PortalArtifacts.none()`.
- `sdk generate` still reads `generateVersionedPortal` from
`APIMATIC-BUILD.json` to tell whether the SDK is versioned. 2.0 dropped
versioned projects, so that check can go, in its own PR.

Tests: 1780 passing, 63 pending (after the merge from `dev`). `tsc
--noUnusedLocals` finds no unused imports left behind.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…images included (#437)

## Summary

Upgrades `fumadocs-core`, `fumadocs-ui` and `fumadocs-mdx` for the fix
to
[fuma-nama/fumadocs#3662](fuma-nama/fumadocs#3662),
which we reported upstream. It changes no portal code.

| Issue | Fixed in | What changes in a portal |
|---|---|---|
|
[fuma-nama/fumadocs#3662](fuma-nama/fumadocs#3662)
| fumadocs-core 16.17.0, fumadocs-mdx 15.4.7 | "View as Markdown", Copy
Markdown, the AI page actions and `llms-full.txt` keep each page as its
author wrote it. Images keep their address instead of `<img src="__img0"
/>` |

The `fumadocs-openapi` upgrade, with the fixes for #3661 and #3663 and
the API page redesign, moved to #441. This PR keeps `fumadocs-openapi`
at 12.1.1, which accepts core and ui `^16.15.0`.

## What else changes in a portal

- **The Markdown copies are the authored source.** Fumadocs 16.17 slices
each page's copy from its MDX instead of re-serializing the parsed tree.
So a copy keeps the author's text exactly as written:
  - bare autolinks stay bare instead of becoming `[url](url)`;
  - `- [X]` keeps its capital X;
  - entities such as `&copy;` stay as written;
  - code inside `<Tab>` keeps its indentation;
- JSX props such as `items={[…]}` keep their braces, where the old copy
printed `items="[…]"`.

Comparing the old and new `llms-full.txt` of the test petstore portal
found no lost content. Every difference was formatting or the image fix.
- **No drop shadow on callouts and code blocks.** fumadocs-ui 16.17
removed `shadow-md` from callouts and `shadow-sm` from code blocks. That
is visible in light mode only. Pixel diffs against `dev` found no other
visual change, in light, dark or at phone width.

## Before merge

`portal_tests.yml` [run on this
branch](https://github.com/apimatic/apimatic-cli/actions/runs/39219964368):
- **Visual:** passes.
- **Functional:** passes.
- **Artifacts:** fails only `llms-full.txt matches the baseline`,
because of the copy change above. 11 of its 12 tests pass.

The `portal-snapshots/artifacts/petstore/llms-full.txt` baseline in
`apimatic/v4-test-automation` needs updating alongside this PR, so dev's
run stays green.

## Changes

- `fumadocs-core` and `fumadocs-ui` 16.15.17 → 16.17.1, and
`fumadocs-mdx` 15.4.0 → 15.4.7.
- `shiki` 4.4.3 → 4.5.0 and `lucide-react` 1.47.0 → 1.54.0: the versions
core and ui 16.17 require (`^4.5.0`, `^1.50.0`), so each has a single
copy. #441 makes the same change.
- `pnpm dedupe` also merged a few other duplicate copies:
- `@semantic-release/github`'s `undici` goes from 7.27.0 to 7.29.1. The
next release run will use it.
  - `micromark-util-types` goes from 2.0.2 to 2.0.3.
  - `zod` goes from 4.5.4 to 4.6.5.
- New subpath e2e test: the Markdown copies and `llms-full.txt` keep
`![…](/images/diagram.png)` and the reference-style `![…][flow]`, and
contain no `__img`.
- `.ai/plans/portal-subpath-hosting.md` records #3662 as fixed and drops
the follow-up ticket it needed. Section 9 now records the limitation
that remains: root-relative images in the copies don't carry the base
path, the same as links.

**Release age:** these versions were published on 2026-10-09, 11 days
ago. That clears the 7-day `minimumReleaseAge`.

## Test results

**Unit and integration suite** (`pnpm test`, merged with `dev` at
0e9052c, after #427): 1852 passing, 69 pending, 0 failing. Build and
lint pass.

**Full suite with e2e builds** (`APIMATIC_E2E=1 pnpm test`, before #427
was merged in): 1922 passing, 0 failing.

**In the browser.** fumadocs-openapi 12.1.1 with core and ui 16.17.1 is
a new combination. I built the `default` fixture at the root and the
`subpath` fixture under `/api/`, both with an OAuth2 scheme added, on
this branch and on `dev`. I drove each with headless Chrome. Every check
below gave the same result on both branches, except for the image fix.

| Check | Root | `/api/` | `portal serve` |
|---|---|---|---|
| Content components from #439: Tabs, code tabs, composed tabs,
Accordions (single and multiple), Files, TypeTable, InlineTOC, the code
copy button | All open, switch and copy as expected | – | Same |
| Playground OAuth: Authorize sends `redirect_uri`, then the callback
page | `/oauth/callback`, then the token request |
`/api/oauth/callback`, then the token request | Same |
| Playground Send (`GET /SUM`) | `200`, body `0.2` | `200`, body `0.2` |
Same |
| Copy Markdown and View as Markdown | Copy as written | Keeps
`![…][flow]`; `dev` copies `<img … src="__img…">` | Same |
| The Open menu's AI links | Page URL | Page URL under `/api/` | – |
| Search, opened with Enter | Right page | Right page under `/api/` | –
|
| Hot reload of an edited page | – | – | Reloads |
| Console errors | None | None | None |

## Follow-ups

- The search dialog still uses `useDocsSearch`, which 16.17 deprecates
in favour of `useStaticSearch`.
- Root-relative image paths in the Markdown copies don't carry the base
path (plan, section 9).
- #441 and this PR both change `package.json`, the lockfile and the
plan. Whichever merges second needs a rebase.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants