Skip to content

chore(deps): Astro 6 → 7 major upgrade (+ Starlight 0.41) - #1067

Draft
Iamfle4ka wants to merge 5 commits into
mainfrom
chore/astro-7-upgrade
Draft

chore(deps): Astro 6 → 7 major upgrade (+ Starlight 0.41)#1067
Iamfle4ka wants to merge 5 commits into
mainfrom
chore/astro-7-upgrade

Conversation

@Iamfle4ka

Copy link
Copy Markdown
Collaborator

PR B of the Dependabot split — the coupled major upgrade, deliberately separate from #1066 (the safe patch/minor security batch) because this is the half that can break the custom setup. Supersedes the bot's #1062, and #1041 before it.

Package From To Why
astro ^6 ^7.1.6 closes advisories #41, #45, #46
@astrojs/starlight ^0.38 ^0.41.6 0.41.0 adds Astro 7, drops Astro 6
@astrojs/mdx ^5.0.2 ^7.0.5 peers astro ^7
sharp ^0.33 ^0.35.3 closes #54 (high)
starlight-image-zoom ^0.14 ^0.15 peers starlight >=0.41
@astrojs/markdown-remark ^7.2.2 (new) we now import it directly — see below

package.json bumped by hand, lockfile regenerated from scratch — none of Dependabot's lock diffs pulled in. No --force, no --legacy-peer-deps; every peer resolves on astro@7.1.6, all deduped.

The one thing that made this risky

Astro 7 renders Markdown with Sätteri by default, and Sätteri does not run remark plugins. src/integrations/beacon-transforms.mjs is a remark plugin, and it produces the entire Beacon design on every page — check grids, step cards, pseudo-H4s (which feed the right-rail TOC), bold-prefix asides, table scrollers, glossaries. Left alone it would have gone completely silent with a green build.

So the config opts back into the remark/rehype pipeline explicitly, which is exactly the replacement the Astro 6.4 deprecation warning asks for:

markdown: { processor: unified({ remarkPlugins: [beaconTransforms] }) }

Side benefit: this removes a deprecation warning main currently prints on every build.

@astrojs/markdown-satteri is intentionally not declared — it's an optional peer of @astrojs/mdx and we stay on remark. It still installs transitively, so adopting Sätteri later remains open.

Verification — A/B'd against a build of the same commit

A green build proves nothing here, so main was built from an identical checkout and the two dist/ trees compared mechanically.

Structure: 306 pages, 193 redirect pages, 304 raw-markdown pages, 500 HTML files — identical on both sides.

Beacon + chrome markers, counted across all 500 files (marker names taken from the plugin's own class strings, not guessed) — all 26 identical, including beacon-steps 25, beacon-step 40, beacon-pseudo-h4 51, beacon-check-grid 5, beacon-glossary 262, beacon-table-scroll 168, starlight-aside 1110, h4 314, expressive-code 656, image-zoom 6754, anchor-links 2292. The remark pipeline is provably still running.

Visible text, all 500 pages (scripts/styles stripped, whitespace collapsed): 4 pages differ, all typographic quote direction from a newer SmartyPants — and 3 of the 4 are fixes, where an opening quote was previously rendered as a closing one:

  • /kai/best-practices/, /kai/use-cases/”Calculate…"“Calculate…”
  • /cli/getting-started/don'tdon’t
  • /storage/tables/csv-files/ — a literal " in the CSV-enclosure table flips . Pre-existing issue, not caused by this PR: SmartyPants mangles that literal quote in both builds. Worth a separate content fix (that table documents literal " characters); out of scope here.

Gates: audit-phase2.mjs 147 issues / 0 missing images / 45 broken links / 3 multi-h1 — byte-identical to the main baseline. check-cli-reference.mjs 0 findings. npm run gen:sidebar produces no diff (Starlight 0.39's autogenerateitems breaking change doesn't apply — our sidebar is fully explicit).

Build warnings: the markdown.remarkPlugins … deprecated warning is gone; the two remaining (/404 route priority, missing R highlighter language) are pre-existing and identical on main.

Preview probes: Pagefind runtime + UI 200, MDX page 200, unknown path → 404, Ask Kai markup present and identical, and custom.css still ships in the linked common.*.css (not inlined) — so the known view-transition fragility is unchanged. The extra inline <style> Astro 7 adds is only Starlight's own scoped component CSS.

Notes for review

  • Browser support drops with Starlight 0.41: Chromium < 111 and Safari < 16.4 are no longer supported.
  • Interaction with PRDCT-360: rework the 404 page and add the Ink-dash octopus game #1056 (404 + InkDash): that branch adds src/pages/404.astro + disable404Route: true, and its comment notes the route collision "is currently a warning, a hard error in later Astro versions." I checked — disable404Route still exists in Starlight 0.41.6 with identical semantics, and the collision is still a warning on Astro 7. Whichever of the two lands second should be rebuilt once to confirm.
  • Lockfile will conflict trivially with PRDCT-585: Dependabot security bumps — safe set (no framework majors) #1066; whichever merges second gets a regen.
  • No documentation content changed.

Still needs a human

Everything above is static/mechanical. The click-through checklist is in the comment below — please don't merge before it's walked, per the original ask.

🤖 Generated with Claude Code

Coordinated major upgrade, kept separate from the safe security batch (#1066)
because it can break the custom setup:

  astro                    ^6      -> ^7.1.6
  @astrojs/starlight       ^0.38   -> ^0.41.6   (0.41.0 drops Astro 6)
  @astrojs/mdx             ^5.0.2  -> ^7.0.5    (peers astro ^7)
  sharp                    ^0.33   -> ^0.35.3   (astro 7 allows ^0.34 || ^0.35)
  starlight-image-zoom     ^0.14   -> ^0.15     (peers starlight >=0.41)
  @astrojs/markdown-remark  new       ^7.2.2    (see below)

Bumped in package.json by hand and the lockfile regenerated from scratch, so
none of Dependabot's lock diffs are pulled in. The stale lockfile had to go:
npm otherwise tries to reconcile the old pinned tree (mdx 5.0.2,
starlight 0.38.1, image-zoom 0.14.1) against the new ranges and reports a
phantom peer conflict. Resolved cleanly with no --force and no
--legacy-peer-deps; every peer lands on astro 7.1.6, all deduped.

Astro 7 renders Markdown with Sätteri by default, and Sätteri does not run
remark plugins. src/integrations/beacon-transforms.mjs IS a remark plugin and
produces the entire Beacon design on every page, so under Sätteri it would go
silent with a green build. astro.config.mjs therefore opts back into the
remark/rehype pipeline explicitly:

  markdown: { processor: unified({ remarkPlugins: [beaconTransforms] }) }

That is the replacement the Astro 6.4 deprecation warning asks for, so this
also removes a warning main currently prints on every build.

@astrojs/markdown-satteri is not declared: it is an optional peer of
@astrojs/mdx and we stay on the remark pipeline. It still installs
transitively, so the Sätteri path remains available later.

Closes the sharp high-severity alert (#54, needs 0.35.0 — unreachable on
astro 6, which pins sharp ^0.34) plus the three astro 7.x advisories
(#41, #45, #46).

No documentation content changed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
connection-docs Ready Ready Preview Aug 6, 2026 11:37pm

Request Review

@Iamfle4ka

Copy link
Copy Markdown
Collaborator Author

Manual click-through checklist

A green build is not proof — everything automated has been run and reported in the PR body; this is the part that needs eyes. Open the Vercel preview for this PR (not npm run dev — Pagefind has no index there, and dev injects <style> tags that hide the view-transition bug).

For each row: does it behave the same as production? "Different" is the finding, not "broken".

# Check What to do Watch for
1 Sidebar Expand + collapse a nested group (e.g. Getting Started Tutorial → Part 1), click into a page Group stays open, current page is highlighted, scroll position holds
2 Pagefind search Ctrl/⌘ K, search snowflake Results appear with titles + excerpts; clicking one lands on the right page
3 Image zoom Open /storage/tables/ and click a screenshot Opens in the lightbox; Esc and click-outside both close it
4 View transitions ⚠️ Navigate 4–5 pages in a row without reloading — sidebar link → in-page link → back button Known fragile spot. Styles must not degrade after the first swap: fonts, sidebar chrome, code-block theming
5 404 Go to /does-not-exist/ Renders the styled 404, not a bare Vercel error
6 Ask Kai Click the Ask Kai entry point Drawer opens, input focuses. (The #ak-header-kai desktop header button already doesn't inject on main — pre-existing, not from these PRs. Answers also won't stream on a preview unless AI_SERVICE_URL + KBC_STORAGE_API_TOKEN are set.)
7 Beacon design /transformations/snowflake-plain/ Green check grid, numbered step cards, 3 callout asides — all styled, not plain lists
8 MDX + code blocks /cli/getting-started/ Tabs switch; code blocks have syntax colours + working copy button. (Only .mdx page in the repo, so it's the whole MDX smoke test.)
9 Wide table /storage/tables/csv-files/ Table scrolls horizontally inside its own container; the page body does not scroll sideways

Rows 4 and 8 are where I'd expect trouble first if anything is wrong.

On this PR specifically (Astro 7): row 4 matters most — Astro 7 changes CSS delivery (Starlight now inlines some component CSS). I verified statically that our custom.css still ships as a linked stylesheet, which is what survives a transition swap, but only real navigation confirms it. Row 8 is second: @astrojs/mdx went 5 → 7.

Also worth an extra beat on row 7 — if the Beacon design were going to break, this is the PR that would do it (see the Sätteri note in the description). The marker counts say it's intact; your eyes confirm it looks intact.

@Iamfle4ka

Copy link
Copy Markdown
Collaborator Author

Refreshed onto main (#1061 landed) and re-verified from scratch. Plus one finding I owe you that the first pass missed.

Refresh: merged main in — one content file (ai/mcp-server/index.md), no conflict, and it touches nothing in the dependency or Markdown-pipeline surface. A fresh baseline was built at the new main and everything re-run against it, not carried over: 306 pages / 500 HTML files identical, all 678 beacon markers identical across 26 marker types, the same 4 typographic-quote diffs, audit-phase2 147 / 0 missing images / 45 broken links, check-cli-reference 0.

New finding — a cosmetic peer warning this upgrade introduces. npm ls now reports 3 invalid markers that main does not:

@types/node@20.11.0 deduped invalid: "^20.19.0 || >=22.12.0" from node_modules/astro/node_modules/vite

Cause: @vercel/node@5.9.3 pins @types/node@20.11.0 exactly and it hoists to the root, while the vite@8.2.0 bundled inside astro 7 wants ^20.19.0 || >=22.12.0. Types-only and dev-scope — there is no tsc or astro check in scripts, nothing typechecks during the build, the build is green and the output is byte-comparable. It has zero effect on the shipped static site.

I did not add an @types/node override to silence it: that would mean pinning types on behalf of @vercel/node, which is a real change to the dev surface to quiet a cosmetic warning. Reporting it instead of forcing it, per the original ask. Worth revisiting whenever @vercel/node moves off the 20.11.0 pin.

One process note: a plain npm install on this branch drifts the lockfile (it prunes a nested @types/node@26.1.2 under astro, −17 lines). I reverted that and verified with npm ci, which is what Vercel and CI run — deterministic, lockfile unchanged. If you pull this branch, prefer npm ci.

The click-through checklist above is unchanged and still needs walking before merge.

@Iamfle4ka

Copy link
Copy Markdown
Collaborator Author

Walked the 9-row checklist myself in a real browser, so you're re-checking rather than discovering.

Caveat on where: the network was down here, so this ran against the local astro preview of this branch's build (astro v7.1.6), not the Vercel preview. Same commit and the same dist/ I fingerprinted, but it is not literally the preview URL — worth one confirming pass on the Vercel deploy for anything that depends on Vercel's own serving (redirects, headers).

# Check Result Evidence
1 Sidebar Expanded COMPONENTS, children appeared, TRANSFORMATIONS stayed open, active item highlighted, scroll position held
2 Pagefind search snowflake workspace36 results, titles + sub-results + highlighted terms
3 Image zoom Clicked the Transformations schema — opened enlarged with dimmed backdrop and caption, body.starlight-image-zoom-opened; Esc closed it
4 View transitions See below — the one I pushed hardest on
5 404 /this-page-does-not-exist/ → styled "Page Not Found", octopus, support link, sidebar intact. (Octopus page, not the InkDash game — that's unmerged #1056, correct for this branch.)
6 Ask Kai Drawer opens 480×760: header, greeting, 3 suggestion chips, textarea, send button, AI-disclosure footnote. No visible trigger — and that is correct here, see below
7 Beacon design Check grid renders as a real two-column grid (grid-template-columns: 405px 405px), asides styled, step blocks present
8 MDX + code 3 tabs (macOS/Linux/Windows); clicked Windows → panel switched, exactly one panel visible, code changed. 12 expressive-code blocks, 12 copy buttons, terminal chrome, syntax colours
9 Wide table .beacon-table-scroll has overflow-x: auto; document itself does not scroll sideways (scrollWidth == clientWidth == 1440)

Row 4 in detail — the fragile spot

Round trip snowflake-plain → transformations → snowflake-plain, all by real sidebar clicks. I set window.__m before navigating and it survived every hop, which proves these were client-side view-transition swaps and not full reloads. On return to the code-heavy page:

  • 15 expressive-code blocks, pre background rgb(34, 37, 41), JetBrains MonoCSS re-attached, code blocks did not lose theming
  • .beacon-check-grid still display: grid, 405px 405px
  • body font still Inter, active sidebar link still tinted rgba(31, 143, 255, 0.16)
  • no horizontal overflow

One thing worth knowing so it doesn't scare you: a screenshot taken mid-transition shows the content shifted left and clipped. That is the transition animation in flight — 3 seconds later the layout is pixel-identical to the pre-navigation state. Not a defect.

Row 6 — the Ask Kai trigger is supposed to be missing here

I first read the absent #ak-header-kai button as a pre-existing defect. It isn't — I went and read the source, and it's a deliberate gate. src/components/AskKaiDrawer.astro:356-397:

// Kai only works when the backend env (AI_SERVICE_URL + KBC_STORAGE_API_TOKEN)
// is configured. A static page can't see server env, so probe GET /api/chat
// once per session and hide the entry points unless the backend confirms it.

It probes GET /api/chat and fails closed — on a non-ok response or a network error it calls removeKaiEntrypoints(), which deletes #ak-header-kai and .ak-search-cta, explicitly so the UI never advertises "a Kai that 404s".

A local astro preview serves only the static build; /api/chat is a Vercel function and isn't there. So the probe fails, the gate hides the button, and that is the designed behaviour, correctly exercised. The drawer markup is present and renders fine when opened directly, which is what this row actually needed to prove.

Two consequences worth being explicit about:

  • This is not a bug and does not need a ticket. It also retro-corrects the note in PRDCT-585: Dependabot security bumps — safe set (no framework majors) #1066's description ("#ak-header-kai isn't injected on desktop") — that observation was almost certainly made the same way, against a build with no reachable /api/chat. On production, where the env vars are set, the probe succeeds and the button is injected.
  • It means row 6 cannot be fully judged on a preview deploy unless that deploy has AI_SERVICE_URL + KBC_STORAGE_API_TOKEN. If the Vercel preview doesn't carry them, expect no trigger there either — again correctly. The real check is production after merge.

What still needs you

All 9 rows pass, so this isn't "unverified" any more — but it's my read, on a local serve. Before merging I'd still want your eyes on row 4 on the actual Vercel preview (the one thing where Vercel's serving could differ) and a subjective look at row 7, since "renders" and "looks right" aren't the same claim.

@Iamfle4ka

Copy link
Copy Markdown
Collaborator Author

Closing the gap I left open above: row 4 now verified on the actual Vercel preview, not just a local serve. The network came back, so I redid it there.

Preview confirms it's serving this build — <meta name="generator" content="Astro v7.1.6">.

Row 4 on the preview — same round trip, snowflake-plain → transformations → snowflake-plain, by real sidebar clicks, with a window marker set beforehand. Marker survived both hops, so these were client-side view-transition swaps, not reloads. On return:

  • 15 expressive-code blocks, pre background rgb(251, 251, 250) (light theme here), JetBrains Monotheming re-attached
  • .beacon-check-grid still display: grid, 389px 389px (narrower than the 405px I saw locally — just a different container width, not a defect)
  • body font Inter, no horizontal overflow, and after the animation settles the layout is pixel-identical to first load

Row 2 on the previewsnowflake workspace36 results, the same count as locally. Pagefind is fine on the real deploy.

The Kai gate, now confirmed empirically rather than by reading code

I predicted above that the Ask Kai trigger would also be absent on this preview, and why. That's now measured, and the mechanism is visible end to end:

  • GET /api/chat on the preview returns 200 — so the function is deployed
  • its body is {"enabled": false} — the env vars aren't set on preview
  • the gate does kaiEnabled = Boolean(enabled); if (!kaiEnabled) removeKaiEntrypoints()
  • and #ak-header-kai is indeed absent in the DOM

So the trigger's absence is the gate working correctly at both ends — a 404'd endpoint locally, an explicit enabled: false here. Nothing to fix, and nothing about it is caused by this PR. It does mean row 6 can only be truly judged on production, where the env vars exist.

That leaves the checklist fully walked, on the artifact you'd actually click. What's genuinely left is a subjective look — "renders" and "looks right" aren't the same claim, and that call is yours.

Nikita added 2 commits August 7, 2026 01:36
Astro 6's compiler auto-closed the element at EOF; Astro 7's rejects it with
`Unexpected token` at 141:0 and the entire build fails. Closing the tag at the
end of the file reproduces the tree Astro 6 emitted — verified in dist/404.html:
sidebar, NotFoundSuggestions and the InkDash canvas all still render.
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.

1 participant