Skip to content

build(deps): make website a pnpm workspace member so one lockfile covers every manifest - #1266

Merged
xiaolai merged 1 commit into
mainfrom
chore/website-into-pnpm-workspace
Aug 13, 2026
Merged

xiaolai merged 1 commit into
mainfrom
chore/website-into-pnpm-workspace

Conversation

@xiaolai

@xiaolai xiaolai commented Aug 13, 2026

Copy link
Copy Markdown
Owner

Closes the gap left open in #1262 by taking the first of the two options offered there: move website/ into the pnpm workspace so the root pnpm-lock.yaml is the only npm lockfile in the repo, and .github/dependabot.yml has exactly one npm entry.

Why this rather than a drift gate

A per-directory Dependabot entry cannot keep a manifest and its lockfile in step unless both live in that directory. This repo had both ways of getting that wrong at the same time:

Manifest Layout Symptom
server/mcp, server/content workspace members, no private lockfile entry rewrote the member package.json, never the root lockfile → every PR born failing --frozen-lockfile, unmergeable (6 opened, 5 closed unmerged)
website standalone, private lockfile entry rewrote website/package.json, and not that lockfile either → PRs merged green and silently drifted (#1238, #1129, #1038; repaired by hand in bfc7d2456, c5486c5e3)

Same cause, opposite symptoms — one fails loudly and cannot land, the other lands and rots. #1262 deleted the first two entries once the root entry was shown to cover them. This removes the third by removing the condition that made website special, so the remaining / entry updates every manifest together with the lockfile in one consistent PR.

A drift gate was the alternative. It would have detected the same defect while leaving it in place, and made every future website bump red until someone regenerated a lockfile by hand. This makes the bump correct on arrival instead.

deploy-website.yml now runs one frozen install rather than a frozen root install followed by an unfrozen --ignore-workspace install of the site. The missing --frozen-lockfile is precisely what made the drift silent, so the lockfile is load-bearing now instead of decorative.

Verification

The app is untouched, and that is checked rather than asserted:

  • Root importer in pnpm-lock.yaml is byte-identical before and after — the app's resolution does not move. pnpm typecheck passes.
  • pnpm check:static green: 38 gate files, 836 tests, knip baseline and debt register unchanged.

The website's resolution does move, so the built site was diffed rather than assumed. vitepress and vue now take peers from the root tree (typescript 7.0.2 instead of a private 5.9.3; React 19 now visible to @docsearch/react) and cytoscape dedupes to 3.34.1:

  • Both builds emit 1549 files with an identical route and asset set — nothing added, nothing dropped.
  • All 474 HTML pages render byte-identical text.
  • Asset content hashes differ, which is the cytoscape patch bump re-bundling — expected, and the reason a raw byte-diff is the wrong test here.
  • The @docsearch/react React-19 peer warning is inert: search is provider: "local", no Algolia component is instantiated, and the theme chunk has zero React references and identical size across both builds.

Cost

Installing website everywhere adds 89 net-new packages on 1886 — the trees overlap heavily, since VMark already ships Mermaid. Cold local install measured 7s with and 7s without; CI timing on this PR is the real measurement.

Follow-on

Dependabot will now open website bumps through the / group alongside the rest of the npm tree, touching website/package.json and pnpm-lock.yaml together. Both paths are already in deploy-website.yml's paths: trigger, so the deploy still fires on a website dependency change.

…ers all

Every npm manifest in this repo now resolves through the root
pnpm-lock.yaml, and .github/dependabot.yml has exactly one npm entry as a
result. This deletes a failure class rather than detecting it.

A per-directory Dependabot entry cannot keep a manifest and its lockfile in
step unless both live in that directory, and this repo had both ways of
getting that wrong at once. server/mcp and server/content are workspace
members with no lockfile of their own, so their entries rewrote a member
package.json and never the root lockfile: every PR was born failing
--frozen-lockfile and could not merge (six opened, five closed unmerged).
website was the mirror image — standalone with its own lockfile that
Dependabot also did not update, so its PRs merged green and left manifest
and lockfile silently drifted, twice needing a repair commit (bfc7d24,
c5486c5). The first two entries were deleted when the root entry was shown
to cover them; this removes the third by removing the condition that made it
special.

deploy-website.yml now does ONE frozen install instead of a frozen root
install followed by an unfrozen --ignore-workspace install of the site. The
missing --frozen-lockfile is what made the website drift silent, so the
lockfile is now load-bearing rather than decorative.

Verified that this changes nothing user-visible:

- The root importer in pnpm-lock.yaml is byte-identical before and after, so
  the app's dependency resolution does not move. pnpm typecheck passes.
- website's own resolution DOES move: vitepress and vue now take their peers
  from the root tree (typescript 7.0.2 rather than a private 5.9.3, react 19
  visible to @docsearch/react) and cytoscape dedupes to 3.34.1. So the built
  site was diffed rather than assumed. Both builds emit the same 1549 files
  with an identical route and asset set, and all 474 HTML pages render
  byte-identical text. Asset content hashes differ, which is the cytoscape
  patch bump re-bundling.
- The @docsearch/react peer warning is inert: search is provider "local", no
  Algolia component is instantiated, the theme chunk contains zero react
  references and is byte-identical in size across both builds.
- Cost of installing website everywhere is 89 net-new packages on 1886
  (website overlaps root heavily — VMark already ships mermaid). Cold local
  install measured 7s with and 7s without.

pnpm check:static passes: 38 gate files, 836 tests, knip baseline and debt
register unchanged.
@xiaolai
xiaolai merged commit 039b702 into main Aug 13, 2026
15 checks passed
@xiaolai
xiaolai deleted the chore/website-into-pnpm-workspace branch August 13, 2026 14:12
bet4it pushed a commit to bet4it/vmark that referenced this pull request Aug 19, 2026
Ships the DMG notarization fix (xiaolai#1271): tauri-action signed the disk image
but never notarized it, so Gatekeeper refused the download with
"Unnotarized Developer ID" before the stapled app inside was ever assessed.

Also carries this cycle's dependency updates (xiaolai#1262, xiaolai#1268, xiaolai#1269) and the
pnpm workspace consolidation (xiaolai#1266).

All five version sources plus the derived src-tauri/Cargo.lock move together
per .claude/rules/40-version-bump.md.
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