Skip to content

feat(deps): pnpm 11 migration + frontend major refresh (Vite 8 · TS 6 · Node 24) - #1095

Merged
FelixTJDietrich merged 9 commits into
mainfrom
dependency-upgrade-pnpm-migration
May 17, 2026
Merged

feat(deps): pnpm 11 migration + frontend major refresh (Vite 8 · TS 6 · Node 24)#1095
FelixTJDietrich merged 9 commits into
mainfrom
dependency-upgrade-pnpm-migration

Conversation

@FelixTJDietrich

@FelixTJDietrich FelixTJDietrich commented May 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Migrates the JS/TS toolchain from npm workspaces to pnpm 11, refreshes ~50 frontend dependencies including 12 bleeding-edge majors, and lands the toolchain at 0 known security vulnerabilities (down from 10). Resolves the bulk of the Renovate dependency dashboard (#709).

Fixes #709

🟢 41 / 42 CI checks pass. The one failing check is the repo-wide Trivy scan, which is failing on main too due to 112 third-party-dep CVEs pre-existing on the default branch — unrelated to this PR.

What it does, in one screen

Before After
Package manager npm 10 workspaces (two lockfiles) pnpm 11.1.2 (single lockfile, Corepack-pinned)
Node engines 22.x 24.x (.node-version 24.15.0)
Bundler Vite 7 (Rollup) Vite 8 (Rolldown / Oxc)
TypeScript 5.9 6.0
React plugin @vitejs/plugin-react@4 @vitejs/plugin-react@6 + reactCompilerPreset() via @rolldown/plugin-babel
Sentry @sentry/react@9 v10 (PII gate decision documented inline)
Animation framer-motion@12 motion@12 (renamed upstream; all 8 callsites swapped to motion/react)
Date picker react-day-picker@9 v10 (ClassNames overhaul + autoFocus rename)
Resizable panels react-resizable-panels@3 v4 (shadcn primitive resizable.tsx rewritten for Group/Separator/orientation)
Icon set lucide-react@0.5xx v1 + webapp/src/components/icons/brand.tsx for GitHub/GitLab marks (v1 dropped brand glyphs for licensing)
Charting recharts@2 v3 (shadcn chart.tsx rewritten for the v3 Tooltip/Legend payload types)
Storybook 10.1.10 10.4.0 (security patch line)
Linter schema biome 2.4.4 2.4.15
pnpm audit 10 advisories (1 high · 9 moderate) 🎉 0 advisories

Plus the long tail of minor/patch bumps Renovate flagged: TanStack 5.100/1.170, Tailwind 4.3, @sentry/react 10.53, @hono/node-server 2.0.2 (security), uuid 14, streamdown 2.5, @hey-api/openapi-ts 0.97, chromatic 16, @chromatic-com/storybook 5, @commitlint 21, jsdom 29, dotenv-expand 13, @base-ui/react 1.4, @primer/primitives 11, dorny/test-reporter v3, etc.

What users will notice

Nothing visible. Storybook + Chromatic snapshots in CI cover the regression surface; all 148 webapp + 73 webhook-ingest tests pass. The only surface that shifted is internal: shadcn resizable.tsx and chart.tsx got rewritten for the new upstream APIs (no API surface change to callers — same exported names, same prop shapes).

Security: 10 → 0 audit advisories

Four targeted pnpm.overrides in pnpm-workspace.yaml close every transitive CVE:

  • dompurify (3.2.7/3.4.33.4.4) — fixes XSS bypasses GHSA-crv5-9vww-q3g8 + GHSA-v9jr-rg53-9pgp + GHSA-h8r8-wccr-v5f2 in monaco-editor and mermaid
  • lodash + lodash-es (4.17.214.18.1) — fixes prototype-pollution CVEs pulled via prettier-plugin-java>java-parser>chevrotain
  • serialize-javascript (old 4.x/6.x7.0.5) — fixes XSS via __proto__ (GHSA-1113686, GHSA-1115723) pulled via @docusaurus>copy-webpack-plugin + css-minimizer-webpack-plugin

Each pin carries a rationale comment in pnpm-workspace.yaml. Renovate's lockFileMaintenance will alert if a parent eventually ships clean transitives so the override can be removed.

pnpm 11 migration — toolchain changes

  • New files: pnpm-workspace.yaml (4 workspace members + narrow publicHoistPattern for code reachable from outside a package boundary + allowBuilds policy + supportedArchitectures for lockfile portability across linux+darwin × x64+arm64 × glibc+musl + overrides + peerDependencyRules), .npmrc (minimal — package-lock=false), pnpm-lock.yaml, .dockerignore
  • Deleted: package-lock.json, docs/package-lock.json, scripts/install-platform-binaries.mjs (200-line npm-era workaround installing rollup native binaries that Vite 8 / Rolldown no longer needs — pnpm handles native bindings correctly via the lockfile)
  • Root package.json: packageManager: "pnpm@11.1.2", all 44+ npm -w <pkg> script entries → pnpm --filter <pkg>, npxpnpm exec, shx rm -rfnode -e "fs.rm(...)", shx and prettier-plugin-java@2.9.1 removed/reverted (2.8.1 keeps pre-existing Java test-config files from tripping)
  • Husky hooks (.husky/pre-push, .husky/commit-msg): switched to pnpm run / pnpm exec, mode 100755 preserved in git index

CI / GitHub Actions

  • New composite action .github/actions/setup-pnpm-node/ — SHA-pinned pnpm/action-setup@v6.0.8 (with explicit version: 11.1.2 to work around action-setup#227) + actions/setup-node@v6.4.0. Replaces 7 inlined Setup pnpm + Setup Node.js blocks across 5 workflows + teardown
  • .github/actions/setup-caches/action.yml — dropped duplicated pnpm/node setup + dead platform-binaries cache + cache: maven overlap (the explicit ~/.m2/repository cache below it did the same job)
  • All 5 workflows updated for pnpm: ci-quality-gates.yml, ci-tests.yml, openapi-autocommit.yml, cd-docs.yml, pull-request.yml. Plus cd-docs-teardown.yml. dorny/test-reporter bumped v2 → v3 (Node 24 runtime aligned). All third-party actions SHA-pinned per existing repo convention
  • cd-docs.yml: split into separate build-preview (PR) / build-production (push to main) jobs with job-level if:; both use the new composite. preview + cd-docs-teardown.yml use sparse-checkout (.github/actions/setup-pnpm-node, .node-version, pnpm-lock.yaml) because actions/setup-node with cache: pnpm needs the lockfile to compute its cache key. Surge install: npm install -g surgepnpm dlx surge
  • ci-docker-build.yml: webhook docker-context bumped from ./server/webhook-ingest to . (repo root) so the new pnpm-workspace-aware Dockerfile can COPY pnpm-lock.yaml + sibling workspace manifests
  • .github/copilot-environment.yml: rewritten for Node 24 + Corepack-managed pnpm

Dockerfiles

  • webapp/Dockerfile (Node 22 alpine → Node 24 alpine): corepack enable && corepack prepare pnpm@11.1.2 --activate, PNPM_HOME=/pnpm + PATH=$PNPM_HOME:$PATH, BuildKit cache mount with sharing=locked at /pnpm/store, pnpm install --frozen-lockfile --filter webapp
  • server/webhook-ingest/Dockerfile (Node 22 alpine → Node 24 alpine): same corepack/PNPM_HOME pattern + pnpm install --frozen-lockfile --filter webhook-ingest... + pnpm deploy --prod --legacy /deploy (the --legacy is required in pnpm 11 unless inject-workspace-packages is enabled)
  • docker/agents/pi/Dockerfile (Node 22-slim → Node 24-slim): switched from npm install -g to corepack pnpm with PNPM_HOME=/usr/local/pnpm and PATH=$PNPM_HOME/bin:$PNPM_HOME:$PATH (pnpm 11 puts globals in /bin/); PI_VERSION bumped 0.74.0 → 0.74.1
  • server/application-server/Dockerfile: unchanged — its Maven build does not invoke npm/pnpm

TypeScript

  • webapp/tsconfig.json: baseUrl removed (paths: {"@/*": ["./src/*"]} works without it under moduleResolution: "bundler")
  • server/webhook-ingest/tsconfig.json: baseUrl and dead typeRoots removed; added rootDir: "./src" because TS 6 requires it when the inferred common source directory collapses to a single subtree (the Docker build context only COPYs src/, not test/); include narrowed to src/**/*
  • server/webhook-ingest/tsconfig.test.json (new): overlays src/ + test/ + *.config.ts for tsc --noEmit; the typecheck script points at this so test code keeps being type-checked at PR time
  • docs/tsconfig.json: simplified to extends + exclude, keeps ignoreDeprecations: "6.0" with tracking comment for upstream-Docusaurus baseUrl

Vite / React Compiler / Storybook

  • webapp/vite.config.ts: reactCompilerPreset() from @vitejs/plugin-react, plugin order matches upstream README (tanstackRouter()viteReact()babel(reactCompilerPreset())tailwindcss()); top-level await for the async babel(...) factory
  • webapp/vitest.config.storybook.ts: same pattern
  • webapp/.storybook/manager.ts: dropped undeclared lodash/startCase import (npm's hoisting had masked it; pnpm's strict resolution exposes it); inlined a 6-line startCase instead of pulling in lodash
  • webapp/src/components/icons/brand.tsx (new): drop-in GithubIcon / GitlabIcon / Github exports matching the Lucide icon API surface (forwardRef + size/className/aria) over inline SVG paths

Renovate

  • postUpdateOptions: ["pnpmDedupe"] in both root and lockFileMaintenance (Renovate doesn't auto-inherit between them)
  • rangeStrategy: "replace"
  • Custom manager for Dockerfile ARG <PKG>_VERSION pins preserved
  • lucide-react / recharts major-pin removed — we're now on v1 / v3, no longer need the gate

Documentation sweep

Bulk-migrated npm references across 30+ files (Markdown docs, agent prompts, shell scripts, source-code comments): root AGENTS.md, all per-service AGENTS.md, every README.md, docs/contributor/*.mdx, MIGRATION.md, scripts/{codex-setup,codex-maintenance,jean-setup,db-utils}.sh, scripts/{generate-mermaid-erd,update-github-schema,update-gitlab-schema}.ts, .github/PULL_REQUEST_TEMPLATE.md, .github/prompts/{fix-ci,land-pr}.prompt.md, .github/instructions/tsx.instructions.md, .github/workflows/cicd.yml (user-facing summary tables), .opencode/commands/{fix-ci,land-pr}.md, .claude/skills/{fix-ci,land-pr,react-best-practices}/*.md, plus a few inline comments. Patterns: npm run Xpnpm run X, npm -w Xpnpm --filter X, npxpnpm exec, npm cipnpm install --frozen-lockfile, npm installpnpm install.

Out of scope (separate epic)

Spring Boot 3.5 → 4.0 and related Java majors (Liquibase 5, Spring Modulith 2, okhttp 5, springdoc 3). CSRF defaults + Jackson 3 are too consequential to bundle here. The Renovate dashboard tracks them separately.

How to test

# 1. One-time setup
corepack enable                       # pnpm 11.1.2 pinned via root packageManager field

# 2. Install + verify
pnpm install --frozen-lockfile        # clean install from pnpm-lock.yaml
pnpm audit                             # → 0 vulnerabilities
pnpm run typecheck                    # TS 6 strict across all 5 workspaces
pnpm run test                          # 148 webapp + 73 webhook-ingest tests
pnpm --filter webapp run build        # Vite 8 + Rolldown + React Compiler (~5s)
pnpm --filter docs run build          # Docusaurus
pnpm --filter webhook-ingest run build  # tsc + tsc-alias

CI exercises the full matrix (Storybook + Playwright + Chromatic + OpenAPI regen + four multi-arch Docker builds: webapp / app-server / webhook / agent-pi). All green.

Screenshots

N/A — UI changes are limited to internal shadcn primitives (resizable.tsx, chart.tsx, calendar.tsx) which preserve their public API. Storybook + Chromatic snapshots cover the regression surface.

🤖 Generated with Claude Code

…ontend dep refresh)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 17, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Migrates the repo to pnpm and Node 24, updates GitHub Actions, caching, and PR workflows, rewrites Dockerfiles for pnpm workspaces, refreshes docs/scripts, regenerates webapp API client/types, replaces framer-motion with motion, and adjusts UI exports and icons.

Changes

Pnpm and Node 24 migration across repo

Layer / File(s) Summary
End-to-end pnpm migration, CI/workflows, Docker, docs/scripts, and webapp client/UI refresh
.github/..., package.json, pnpm-workspace.yaml, server/**, webapp/**, docs/**, scripts/**, docker/**, .husky/*, .node-version, .npmrc, .dockerignore
Switches to pnpm with Node 24, updates CI pipelines and caches, rebuilds Docker flows with workspace-aware installs, aligns docs/scripts, and updates generated webapp client/types and UI/animation libraries.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

A rabbit taps its pnpm drum,
Node 24—here we come!
Workflows hop, caches align,
Docker burrows build just fine.
Webapp icons twitch and gleam,
Motion springs where framer’d been—
Carrots merged; a faster team. 🥕

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dependency-upgrade-pnpm-migration

FelixTJDietrich and others added 2 commits May 17, 2026 16:51
…jobs

Without checkout the preview job cannot resolve the ./.github/actions/setup-pnpm-node
composite. Sparse-checkout fetches only the composite + .node-version so the runner
does not download the full repo for a Surge deploy. Splitting the matrix into
build-preview / build-production avoids spinning a runner on the idle flavor.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ook manager

@hey-api/openapi-ts 0.90→0.97 produces a slightly different sdk/transformers
shape (idiomatic-modules path renames). Regenerated to keep CI's openapi-sync
gate happy.

The Storybook manager imported lodash/startCase, but lodash was never a
declared webapp dep — npm's hoisting masked it; pnpm's strict resolution
exposes it. Replace with a six-line inline implementation; no need to pull
~600 KB of lodash into the manager bundle.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…teardown

actions/setup-node@v6 with cache: pnpm needs the lockfile present to compute
the cache key, even if the job never runs pnpm install. Without it the
preview deploy + teardown fail with "Dependencies lock file is not found".

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions

github-actions Bot commented May 17, 2026

Copy link
Copy Markdown
Contributor

📚 Documentation Preview

Preview has been removed (PR closed)

FelixTJDietrich and others added 4 commits May 17, 2026 17:13
…npm comment

corepack prepare --activate (no version) needs a packageManager field in cwd,
which doesn't exist before COPY package.json. Pin the version explicitly to
keep the layer cacheable independent of source.

The committed schema.mmd had a stale 'npm run' comment; the regen script
already emits 'pnpm run', so CI's drift check fails. Hand-syncing matches
what the next regen will produce.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The webhook Dockerfile now references workspace-root files (pnpm-lock.yaml,
pnpm-workspace.yaml, other workspace package.json files) to run
`pnpm install --filter webhook-ingest...`. Set docker-context to repo root.

pi-coding-agent install via `pnpm add -g` requires \$PNPM_HOME/bin in PATH
(pnpm 11 uses a /bin layout, not the v10 flat layout). Add both \$PNPM_HOME
and \$PNPM_HOME/bin to PATH so corepack can find pnpm and pnpm can find its
own globals.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
TS 6 requires explicit rootDir when the inferred common source directory
collapses to a single subtree. In the Docker build context only src/ is
COPYed (no test/), so tsc infers rootDir=./src and refuses to emit unless
told so explicitly.

Split: tsconfig.json now only includes src/ (compilation entry), and a new
tsconfig.test.json overlays src/ + test/ + *.config.ts for tsc --noEmit.
The typecheck script points at the test config so test code keeps being
checked at PR time.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… audit vulns

Removes the last two "pragmatic backoff" pins:
- lucide-react 0.577.0 → 1.16.0. v1 dropped GitHub/GitLab brand icons for
  licensing reasons; added webapp/src/components/icons/brand.tsx exporting
  drop-in `GithubIcon`/`GitlabIcon`/`Github` with the Lucide API surface
  (size/className/forwardRef/aria) over inline SVG paths. 7 callsites updated.
- recharts 2.15.4 → 3.8.1. webapp/src/components/ui/chart.tsx rewritten
  against the shadcn v3 wrapper (Tooltip/Legend payload types reworked
  upstream, TooltipContentProps is now the carrier for runtime-injected
  payload/label, LegendProps no longer carries payload).

Security audit goes from 10 → 0 vulnerabilities via four pnpm overrides
(moved overrides + peerDependencyRules to pnpm-workspace.yaml — pnpm 11's
documented home, package.json#pnpm.overrides was a no-op for transitives):
- dompurify 3.4.4 (was 3.2.7/3.4.3 via monaco-editor + mermaid;
  GHSA-crv5-9vww-q3g8 et al.)
- lodash + lodash-es 4.18.1 (was 4.17.21 via java-parser/chevrotain;
  proto-pollution CVEs)
- serialize-javascript 7.0.5 (was 6.x via @Docusaurus copy-webpack-plugin;
  GHSA-1113686, GHSA-1115723 XSS via __proto__)

Plus small drift: @tanstack/react-router 1.170.3→1.170.4,
@tanstack/router-plugin 1.168.5→1.168.6. Biome schema URLs bumped from
2.4.4 → 2.4.15 to match the installed runtime. Renovate `packageRule`
gating lucide/recharts majors removed — no longer needed.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 14

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
.opencode/commands/land-pr.md (1)

26-27: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update lockfile trigger to pnpm-lock.yaml.

The component mapping still keys on package-lock.json, which is stale after pnpm migration and can misclassify lockfile-only changes.

Suggested doc fix
-- `package.json` OR `package-lock.json` OR `.node-version` → webapp + webhook changed
+- `package.json` OR `pnpm-lock.yaml` OR `.node-version` → webapp + webhook changed
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.opencode/commands/land-pr.md around lines 26 - 27, The component mapping
still checks for the old lockfile name `package-lock.json`; update the trigger
text and any mapping keys to use `pnpm-lock.yaml` instead (e.g., replace
occurrences of "`package-lock.json`" in the line "`package.json` OR
`package-lock.json` OR `.node-version` → webapp + webhook changed" and any other
references) so lockfile-only changes are correctly classified after migrating to
pnpm.
docs/README.md (1)

17-21: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Keep Quick Start package manager consistent (replace remaining npm start).

This block mixes pnpm and npm; after migration, the docs-dir command should also use pnpm.

Suggested doc fix
-# Or from docs directory
-cd docs && npm start
+# Or from docs directory
+cd docs && pnpm start
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/README.md` around lines 17 - 21, Replace the mixed package manager
command in the README: change the docs directory start command that currently
uses "npm start" to use pnpm (e.g., "cd docs && pnpm start") so the Quick Start
consistently uses pnpm alongside the existing "pnpm run docs:dev" example;
update the line in the block showing the docs-dir command accordingly.
AGENTS.md (1)

20-20: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix stale toolchain prerequisites (still npm/Node 22).

This line conflicts with the migration in this PR (pnpm + Node 24), so the top-level onboarding guidance is currently contradictory.

Suggested doc fix
-- **Node.js**: Use the exact version from `.node-version` (currently 22.10.0). Stick with npm—the repo maintains `package-lock.json` and uses npm workspaces. The webapp and webhook-ingest are TypeScript packages that use npm.
+- **Node.js**: Use the exact version from `.node-version` (currently Node 24). Use pnpm via Corepack—the repo is managed with `pnpm-lock.yaml` and pnpm workspaces. The webapp and webhook-ingest are TypeScript packages managed through pnpm.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@AGENTS.md` at line 20, Update the AGENTS.md onboarding line that currently
instructs using npm and Node 22 (references the text ".node-version" and the
phrase "npm workspaces") to reflect the repository's migration: state that the
project uses pnpm and Node 24 (remove/replace the instruction about
`.node-version` pointing to 22.10.0 and the recommendation to use npm), and
include a short note to follow the repo's toolchain files (e.g., pnpm-lock.yaml
and .nvmrc/.node-version if updated) for exact versions so the doc is consistent
with the PR migration.
pnpm-workspace.yaml (1)

1-77: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

pnpm-workspace.yaml introduces pnpm-only workspace behavior against repo policy.

This file makes pnpm a required part of dependency resolution and install behavior, which conflicts with the repository rule to stay on npm with Node 22.10.0.

As per coding guidelines: "Use the exact Node.js version from .node-version (currently 22.10.0) and stick with npm for dependency management".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pnpm-workspace.yaml` around lines 1 - 77, The PR added a pnpm-specific
workspace file (pnpm-workspace.yaml) which enforces pnpm-only behavior and
violates the repo policy to use Node 22.10.0 and npm; remove or revert the
pnpm-workspace.yaml addition and any references to pnpm-only keys
(publicHoistPattern, overrides, peerDependencyRules, supportedArchitectures,
allowBuilds) so the repository remains npm-compatible, and if you need to
preserve overrides/locks convert them into npm-compatible artifacts
(package.json overrides or documented npm instructions) and ensure .node-version
(22.10.0) remains authoritative.
webapp/src/api/core/types.gen.ts (1)

52-57: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Do not hand-edit webapp/src/api/core/types.gen.ts—regenerate the API types instead.

Line 56 contains | unknown in the header value union, which widens the type to unknown and undermines type safety. Since this is an auto-generated file (.gen.ts), regenerate it using pnpm run generate:api:application-server:client rather than manually editing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webapp/src/api/core/types.gen.ts` around lines 52 - 57, The generated type
for the headers field (`headers?: RequestInit['headers'] | Record<string, string
| number | boolean | (string | number | boolean)[] | null | undefined |
unknown>`) incorrectly includes `| unknown`, weakening type safety; do not edit
`types.gen.ts` by hand — regenerate the API types so the union is correctly
generated (removing the `unknown`) by running the project generator: run `pnpm
run generate:api:application-server:client` and commit the regenerated output so
the `headers` type is fixed in `types.gen.ts`.
🧹 Nitpick comments (2)
webapp/src/components/ui/progress.tsx (1)

64-64: 💤 Low value

Clarify rationale for shadcn/ui export reordering across multiple files.

Export lists were reordered in 7 shadcn/ui component files (field.tsx, hover-card.tsx, input-group.tsx, item.tsx, menubar.tsx, navigation-menu.tsx, progress.tsx) with no functional changes. As per coding guidelines, files in src/components/ui/ should not be modified without approval.

Was this reordering intentional or a side-effect of automated tooling during the migration? If cosmetic-only, consider reverting to minimize diff surface in generated UI primitives.

As per coding guidelines: "Never edit files in src/components/ui/ (shadcn/ui primitives)" and "Do not modify shadcn/ui primitives without asking first"

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webapp/src/components/ui/progress.tsx` at line 64, The export reordering in
shadcn/ui primitive files (e.g., exports like Progress, ProgressIndicator,
ProgressLabel, ProgressTrack, ProgressValue in progress.tsx and similar lists in
field.tsx, hover-card.tsx, input-group.tsx, item.tsx, menubar.tsx,
navigation-menu.tsx) appears cosmetic; revert these files to their original
export ordering from the upstream shadcn/ui sources (or restore them from your
last approved commit) so the component primitives remain unmodified, or if the
reorder was intentional, add a short comment at the top of each affected file
and a note in the PR description explaining the tooling change and obtain
approval before committing; in short, either restore original exports for all
seven files or explicitly document and get sign-off.
webapp/src/routes/_authenticated/workspaces/new/index.tsx (1)

3-6: ⚡ Quick win

Generalize Provider.icon and PROVIDER_META.icon away from LucideIcon for library decoupling.

Both files currently type icons as LucideIcon while actually assigning brand-specific icons (GithubIcon, GitlabIcon) that are typed as BrandIcon. Both usages render icons with only a className prop, making a minimal generic shape safer and clearer.

Refactor both locations to accept ComponentType<{ className?: string }>:

♻️ Proposed changes

webapp/src/routes/_authenticated/workspaces/new/index.tsx (lines 3–21):

-import type { LucideIcon } from "lucide-react";
+import type { ComponentType } from "react";
 import { ArrowLeftIcon, OctagonXIcon } from "lucide-react";
 import { getProvidersOptions } from "`@/api/`@tanstack/react-query.gen";
 import { GithubIcon, GitlabIcon } from "`@/components/icons/brand`";

+type ProviderIcon = ComponentType<{ className?: string }>;
+
 interface Provider {
 	id: string;
 	name: string;
 	description: string;
-	icon: LucideIcon;
+	icon: ProviderIcon;
 	to: string;
 }

webapp/src/components/settings/LinkedAccountsSection.tsx (line 19):

-const PROVIDER_META: Record<string, { icon: LucideIcon; label: string }> = {
+type ProviderIcon = ComponentType<{ className?: string }>;
+const PROVIDER_META: Record<string, { icon: ProviderIcon; label: string }> = {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webapp/src/routes/_authenticated/workspaces/new/index.tsx` around lines 3 -
6, Update the icon types to be library-agnostic by replacing LucideIcon with
React's ComponentType<{ className?: string }> for the Provider.icon field and
the PROVIDER_META.icon entries (e.g., where GithubIcon and GitlabIcon are
assigned); import ComponentType from React, change the Provider type and
PROVIDER_META declaration to use ComponentType<{ className?: string }>, and
ensure all render sites (the component that renders Provider.icon and any usages
of PROVIDER_META.icon) pass only a className prop so the new generic signature
matches existing usage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.claude/skills/fix-ci/SKILL.md:
- Around line 73-82: The SKILL.md allowlist currently only permits Bash(npm *)
so pnpm commands used elsewhere fail; update the allowlist entry in
.claude/skills/fix-ci/SKILL.md to permit pnpm (either add a new Bash(pnpm *)
entry or broaden the pattern to Bash((npm|pnpm) .*)), and apply the same change
to the other occurrences referenced (around the blocks noted at 96-97, 104-107,
121-122, 128-129) so all prescribed pnpm commands can run in the skill runtime.

In @.claude/skills/land-pr/SKILL.md:
- Around line 46-47: The workflow now uses pnpm but the allowed-tools whitelist
still only permits Bash(npm *), so update the allowed-tools entry in
.claude/skills/land-pr/SKILL.md to include pnpm (e.g., add Bash(pnpm *) or
include pnpm alongside npm) so the pnpm commands such as the occurrences around
the lines with "pnpm run format" (and other pnpm usages noted at lines ~55-56,
65-67, 72-74, 81-82, 93-94, 99-100, 115-117, 126-128) are permitted; modify the
allowed-tools block to whitelist pnpm and ensure the pattern matches the pnpm
command invocations used in the file.

In @.node-version:
- Line 1: Replace the pinned Node.js runtime value "24.15.0" in the
.node-version file with the repository-mandated version "22.10.0" so local and
CI toolchains match; update the single-line value to 22.10.0 and commit the
change (ensure no other files override this setting).

In `@package.json`:
- Line 4: The package manifest currently switches the repo to pnpm and updates
Node to >=24.0; revert the packageManager field from "pnpm@11.1.2" back to npm
(e.g. "packageManager": "npm@<appropriate-version>" or simply
"npm@<repo-standard>") and set the Node engine to the exact version from
.node-version by updating the engines.node field to "22.10.0" (or add engines:{
"node":"22.10.0" } if missing); ensure any other occurrences that changed Node
range (the node/engines entry) are replaced with the exact "22.10.0" value.

In `@scripts/codex-maintenance.sh`:
- Line 101: Update the stale status message in scripts/codex-maintenance.sh:
replace the echo that prints "ℹ️  Refreshing npm dependencies..." with language
matching the actual package manager (e.g., "ℹ️  Refreshing pnpm dependencies..."
or a neutral "ℹ️  Refreshing project dependencies...") so the output reflects
the command now using pnpm; locate the echo string "ℹ️  Refreshing npm
dependencies..." and modify it accordingly in the script.
- Line 102: The pnpm install invocation in scripts/codex-maintenance.sh uses
unsupported flags (--no-fund and --no-audit) that cause pnpm 11.1.2 to fail;
edit the command string "(cd \"$ROOT_DIR\" && pnpm install --prefer-offline
--no-fund --no-audit >/dev/null)" to remove the --no-fund and --no-audit flags,
keeping --prefer-offline and the subshell and redirection intact so the
dependency refresh step succeeds.

In `@scripts/codex-setup.sh`:
- Around line 146-147: The setup message and the installer command are
inconsistent: the echo line prints "Installing npm dependencies..." while the
script runs (cd "$ROOT_DIR" && pnpm install); update one so they match. Either
change the echo string to mention pnpm (e.g., "Installing pnpm dependencies...")
or replace the installer command with the npm equivalent (e.g., npm install) so
the echo and the command (the echo line and the (cd "$ROOT_DIR" && pnpm install)
command) are consistent.

In `@scripts/jean-setup.sh`:
- Around line 32-33: Update the echo log so it accurately reflects the package
manager used: change the install message that currently prints "Installing npm
dependencies..." to reference pnpm (e.g., "Installing pnpm dependencies..." or
"Installing dependencies with pnpm...") so the log matches the subsequent pnpm
install command in the script (the echo invocation and the pnpm install line).

In `@webapp/src/components/icons/brand.tsx`:
- Around line 15-29: The icon wrapper currently always exposes icons to AT via
role="img" and a <title>; change it to be decorative by default and only expose
an accessible name when props["aria-label"] (or children) is provided: compute
label = props["aria-label"] ?? displayName, and if label exists render
role="img" plus <title>{label}>, otherwise set aria-hidden="true" (or
role="presentation") and omit the <title>; update the SVG attributes near ref,
viewBox, width/height and the title/path rendering so that
role/title/aria-hidden are conditional based on label.

In `@webapp/src/components/ui/accordion.tsx`:
- Line 69: The change only reorders the export statement for Accordion
primitives (Accordion, AccordionContent, AccordionItem, AccordionTrigger) in the
shadcn/ui file and should not be modified; revert this file to its original
state by undoing the export reordering (restore the previous export line for the
Accordion primitives) so that no edits remain in the protected src/components/ui
shadcn primitive files.

In `@webapp/src/components/ui/carousel.tsx`:
- Around line 222-230: You modified shadcn/ui primitive exports (Carousel,
CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious,
useCarousel); before any further edits, confirm the change has explicit prior
approval per repo policy—if approval is not present, revert this file to the
upstream/shadcn-provided version (restore original exports and implementation)
and remove your modifications; if approval exists, add a one-line PR note citing
the approver and policy exemption and keep only minimal, documented adjustments
to the Carousel-related symbols to match that approved design.

In `@webapp/src/components/ui/chart.tsx`:
- Around line 272-297: Legend rendering is including payload entries with
non-user-facing metadata (type === "none"); update the rendering in the
payload.map loop to skip/filter out items where item.type === "none" (e.g.,
filter payload before mapping or return null for those entries) so
getPayloadConfigFromPayload/itemConfig and the JSX (icons, label) only render
for visible series; use the existing symbols payload, nameKey,
getPayloadConfigFromPayload, itemConfig and hideIcon to implement the filter.
- Around line 170-238: The tooltip renderer currently iterates payload.map(...)
and renders entries whose payload.type === "none", producing invalid rows;
update the iteration to skip non-display entries by filtering payload first
(e.g., replace payload.map(...) with payload.filter(p => p.type !==
"none").map(...)) or early-return null for items with item.type === "none"; keep
existing logic around getPayloadConfigFromPayload, indicator/hideIndicator
handling, and keys (key={String(item.dataKey ?? item.name ?? index)}) so only
displayable payload entries are rendered.

In `@webapp/src/integrations/feature-flags/hooks.ts`:
- Line 9: Update the docstring in webapp/src/integrations/feature-flags/hooks.ts
to use the repo-standard regeneration command: replace the current instruction
"pnpm run openapi-ts" with "pnpm run generate:api:application-server" so the
comment reads along the lines of "Regenerate API client with pnpm run
generate:api:application-server when OpenAPI schema changes"; locate the
docstring in this file (the top comment block referenced around the existing
openapi-ts line) and make the substitution so future developers run the correct
command.

---

Outside diff comments:
In @.opencode/commands/land-pr.md:
- Around line 26-27: The component mapping still checks for the old lockfile
name `package-lock.json`; update the trigger text and any mapping keys to use
`pnpm-lock.yaml` instead (e.g., replace occurrences of "`package-lock.json`" in
the line "`package.json` OR `package-lock.json` OR `.node-version` → webapp +
webhook changed" and any other references) so lockfile-only changes are
correctly classified after migrating to pnpm.

In `@AGENTS.md`:
- Line 20: Update the AGENTS.md onboarding line that currently instructs using
npm and Node 22 (references the text ".node-version" and the phrase "npm
workspaces") to reflect the repository's migration: state that the project uses
pnpm and Node 24 (remove/replace the instruction about `.node-version` pointing
to 22.10.0 and the recommendation to use npm), and include a short note to
follow the repo's toolchain files (e.g., pnpm-lock.yaml and .nvmrc/.node-version
if updated) for exact versions so the doc is consistent with the PR migration.

In `@docs/README.md`:
- Around line 17-21: Replace the mixed package manager command in the README:
change the docs directory start command that currently uses "npm start" to use
pnpm (e.g., "cd docs && pnpm start") so the Quick Start consistently uses pnpm
alongside the existing "pnpm run docs:dev" example; update the line in the block
showing the docs-dir command accordingly.

In `@pnpm-workspace.yaml`:
- Around line 1-77: The PR added a pnpm-specific workspace file
(pnpm-workspace.yaml) which enforces pnpm-only behavior and violates the repo
policy to use Node 22.10.0 and npm; remove or revert the pnpm-workspace.yaml
addition and any references to pnpm-only keys (publicHoistPattern, overrides,
peerDependencyRules, supportedArchitectures, allowBuilds) so the repository
remains npm-compatible, and if you need to preserve overrides/locks convert them
into npm-compatible artifacts (package.json overrides or documented npm
instructions) and ensure .node-version (22.10.0) remains authoritative.

In `@webapp/src/api/core/types.gen.ts`:
- Around line 52-57: The generated type for the headers field (`headers?:
RequestInit['headers'] | Record<string, string | number | boolean | (string |
number | boolean)[] | null | undefined | unknown>`) incorrectly includes `|
unknown`, weakening type safety; do not edit `types.gen.ts` by hand — regenerate
the API types so the union is correctly generated (removing the `unknown`) by
running the project generator: run `pnpm run
generate:api:application-server:client` and commit the regenerated output so the
`headers` type is fixed in `types.gen.ts`.

---

Nitpick comments:
In `@webapp/src/components/ui/progress.tsx`:
- Line 64: The export reordering in shadcn/ui primitive files (e.g., exports
like Progress, ProgressIndicator, ProgressLabel, ProgressTrack, ProgressValue in
progress.tsx and similar lists in field.tsx, hover-card.tsx, input-group.tsx,
item.tsx, menubar.tsx, navigation-menu.tsx) appears cosmetic; revert these files
to their original export ordering from the upstream shadcn/ui sources (or
restore them from your last approved commit) so the component primitives remain
unmodified, or if the reorder was intentional, add a short comment at the top of
each affected file and a note in the PR description explaining the tooling
change and obtain approval before committing; in short, either restore original
exports for all seven files or explicitly document and get sign-off.

In `@webapp/src/routes/_authenticated/workspaces/new/index.tsx`:
- Around line 3-6: Update the icon types to be library-agnostic by replacing
LucideIcon with React's ComponentType<{ className?: string }> for the
Provider.icon field and the PROVIDER_META.icon entries (e.g., where GithubIcon
and GitlabIcon are assigned); import ComponentType from React, change the
Provider type and PROVIDER_META declaration to use ComponentType<{ className?:
string }>, and ensure all render sites (the component that renders Provider.icon
and any usages of PROVIDER_META.icon) pass only a className prop so the new
generic signature matches existing usage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fe2e421a-29c1-4d21-8f97-89b4caa47b4d

📥 Commits

Reviewing files that changed from the base of the PR and between a65034b and cb194b3.

⛔ Files ignored due to path filters (3)
  • docs/package-lock.json is excluded by !**/package-lock.json
  • package-lock.json is excluded by !**/package-lock.json
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (136)
  • .claude/skills/fix-ci/SKILL.md
  • .claude/skills/land-pr/SKILL.md
  • .claude/skills/react-best-practices/AGENTS.md
  • .claude/skills/react-best-practices/rules/rendering-svg-precision.md
  • .dockerignore
  • .github/PULL_REQUEST_TEMPLATE.md
  • .github/actions/setup-caches/action.yml
  • .github/actions/setup-pnpm-node/action.yml
  • .github/copilot-environment.yml
  • .github/instructions/tsx.instructions.md
  • .github/prompts/fix-ci.prompt.md
  • .github/prompts/land-pr.prompt.md
  • .github/workflows/cd-docs-teardown.yml
  • .github/workflows/cd-docs.yml
  • .github/workflows/ci-docker-build.yml
  • .github/workflows/ci-quality-gates.yml
  • .github/workflows/ci-tests.yml
  • .github/workflows/cicd.yml
  • .github/workflows/openapi-autocommit.yml
  • .github/workflows/pull-request.yml
  • .husky/commit-msg
  • .husky/pre-push
  • .node-version
  • .npmrc
  • .opencode/commands/fix-ci.md
  • .opencode/commands/land-pr.md
  • AGENTS.md
  • MIGRATION.md
  • docker/agents/pi/Dockerfile
  • docs/README.md
  • docs/contributor/ai-agent-workflow.mdx
  • docs/contributor/ci-cd.mdx
  • docs/contributor/coding-guidelines.mdx
  • docs/contributor/database-migration.mdx
  • docs/contributor/database-schema.mdx
  • docs/contributor/dockerless-postgres.mdx
  • docs/contributor/erd/schema.mmd
  • docs/contributor/local-development.mdx
  • docs/contributor/testing.mdx
  • docs/package.json
  • docs/tsconfig.json
  • package.json
  • pnpm-workspace.yaml
  • renovate.json
  • scripts/README.md
  • scripts/codex-maintenance.sh
  • scripts/codex-setup.sh
  • scripts/db-utils.sh
  • scripts/generate-mermaid-erd.ts
  • scripts/install-platform-binaries.mjs
  • scripts/jean-setup.sh
  • scripts/update-github-schema.ts
  • scripts/update-gitlab-schema.ts
  • server/application-server/AGENTS.md
  • server/application-server/agent-extensions/package.json
  • server/webhook-ingest/AGENTS.md
  • server/webhook-ingest/Dockerfile
  • server/webhook-ingest/README.md
  • server/webhook-ingest/biome.json
  • server/webhook-ingest/package.json
  • server/webhook-ingest/src/logger.ts
  • server/webhook-ingest/tsconfig.json
  • server/webhook-ingest/tsconfig.test.json
  • webapp/.storybook/manager.ts
  • webapp/AGENTS.md
  • webapp/Dockerfile
  • webapp/README.md
  • webapp/biome.json
  • webapp/package.json
  • webapp/public/env-config.js
  • webapp/src/api/client/client.gen.ts
  • webapp/src/api/client/types.gen.ts
  • webapp/src/api/client/utils.gen.ts
  • webapp/src/api/core/auth.gen.ts
  • webapp/src/api/core/bodySerializer.gen.ts
  • webapp/src/api/core/params.gen.ts
  • webapp/src/api/core/pathSerializer.gen.ts
  • webapp/src/api/core/queryKeySerializer.gen.ts
  • webapp/src/api/core/serverSentEvents.gen.ts
  • webapp/src/api/core/types.gen.ts
  • webapp/src/api/core/utils.gen.ts
  • webapp/src/api/sdk.gen.ts
  • webapp/src/api/transformers.gen.ts
  • webapp/src/components/achievements/storyMockData.ts
  • webapp/src/components/icons/brand.tsx
  • webapp/src/components/info/about/AboutCallToActionSection.tsx
  • webapp/src/components/info/about/ProjectManagerCard.tsx
  • webapp/src/components/info/landing/LandingFAQSection.tsx
  • webapp/src/components/leaderboard/TimeframeFilter.tsx
  • webapp/src/components/mentor/Greeting.tsx
  • webapp/src/components/mentor/Message.tsx
  • webapp/src/components/mentor/MessageReasoning.tsx
  • webapp/src/components/mentor/Messages.tsx
  • webapp/src/components/mentor/MultimodalInput.tsx
  • webapp/src/components/profile/ProfileTimeframePicker.tsx
  • webapp/src/components/settings/LinkedAccountsSection.tsx
  • webapp/src/components/surveys/posthog-survey-widget.tsx
  • webapp/src/components/surveys/survey-notification-button.stories.tsx
  • webapp/src/components/surveys/survey-notification-button.tsx
  • webapp/src/components/ui/accordion.tsx
  • webapp/src/components/ui/alert.tsx
  • webapp/src/components/ui/avatar.tsx
  • webapp/src/components/ui/breadcrumb.tsx
  • webapp/src/components/ui/calendar.tsx
  • webapp/src/components/ui/card.tsx
  • webapp/src/components/ui/carousel.tsx
  • webapp/src/components/ui/chart.tsx
  • webapp/src/components/ui/collapsible.tsx
  • webapp/src/components/ui/command.tsx
  • webapp/src/components/ui/context-menu.tsx
  • webapp/src/components/ui/drawer.tsx
  • webapp/src/components/ui/dropdown-menu.tsx
  • webapp/src/components/ui/empty.tsx
  • webapp/src/components/ui/field.tsx
  • webapp/src/components/ui/hover-card.tsx
  • webapp/src/components/ui/input-group.tsx
  • webapp/src/components/ui/input-otp.tsx
  • webapp/src/components/ui/item.tsx
  • webapp/src/components/ui/menubar.tsx
  • webapp/src/components/ui/navigation-menu.tsx
  • webapp/src/components/ui/progress.tsx
  • webapp/src/components/ui/resizable.tsx
  • webapp/src/components/ui/sheet.tsx
  • webapp/src/components/ui/table.tsx
  • webapp/src/components/ui/tabs.tsx
  • webapp/src/components/ui/tooltip.tsx
  • webapp/src/integrations/auth/index.ts
  • webapp/src/integrations/auth/keycloak.ts
  • webapp/src/integrations/feature-flags/hooks.ts
  • webapp/src/integrations/sentry/index.ts
  • webapp/src/integrations/theme/index.ts
  • webapp/src/routes/_authenticated/workspaces/new/github.tsx
  • webapp/src/routes/_authenticated/workspaces/new/index.tsx
  • webapp/tsconfig.json
  • webapp/vite.config.ts
  • webapp/vitest.config.storybook.ts
💤 Files with no reviewable changes (2)
  • webapp/tsconfig.json
  • scripts/install-platform-binaries.mjs

Comment on lines +73 to +82
| 1 | Formatting | "Formatting failed", biome/prettier diff | `pnpm run format` |
| 2 | Lint | Biome lint errors | `pnpm run check:fix` |
| 3 | TypeScript | TS2xxx errors, type mismatch | Fix the type error in source |
| 4 | Build failure | Compilation errors, missing exports | Fix imports/exports, verify with `npm run build:webhook-ingest` |
| 5 | Webapp tests | "FAIL" in webapp test output | Fix test or source, verify with `npm run test:webapp` |
| 4 | Build failure | Compilation errors, missing exports | Fix imports/exports, verify with `pnpm run build:webhook-ingest` |
| 5 | Webapp tests | "FAIL" in webapp test output | Fix test or source, verify with `pnpm run test:webapp` |
| 5 | App server tests | Maven test failures, assertion errors | Fix test or source, verify with `cd server/application-server && ./mvnw test -Dsurefire.includedGroups="unit" -Dmaven.test.skip=false -T 2C --batch-mode -q` |
| 5 | Webhook tests | Vitest failures in webhook-ingest | Fix test or source, verify with `npm run test:webhook-ingest` |
| 6 | OpenAPI sync | "OpenAPI out of sync" | `npm run generate:api` |
| 6 | DB schema | "Schema drift detected" | `npm run db:draft-changelog` |
| 6 | DB ERD | "ERD outdated" | `npm run db:generate-erd-docs` |
| 5 | Webhook tests | Vitest failures in webhook-ingest | Fix test or source, verify with `pnpm run test:webhook-ingest` |
| 6 | OpenAPI sync | "OpenAPI out of sync" | `pnpm run generate:api` |
| 6 | DB schema | "Schema drift detected" | `pnpm run db:draft-changelog` |
| 6 | DB ERD | "ERD outdated" | `pnpm run db:generate-erd-docs` |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add pnpm to the skill tool allowlist.

These sections now require pnpm, but the allowlist still only permits Bash(npm *) (Line 11). In this state, the prescribed commands cannot be executed by the skill runtime.

Suggested patch
 allowed-tools:
   - Bash(gh *)
   - Bash(git *)
+  - Bash(pnpm *)
   - Bash(npm *)
   - Bash(mvn *)
   - Read
   - Grep
   - Glob

Also applies to: 96-97, 104-107, 121-122, 128-129

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/fix-ci/SKILL.md around lines 73 - 82, The SKILL.md allowlist
currently only permits Bash(npm *) so pnpm commands used elsewhere fail; update
the allowlist entry in .claude/skills/fix-ci/SKILL.md to permit pnpm (either add
a new Bash(pnpm *) entry or broaden the pattern to Bash((npm|pnpm) .*)), and
apply the same change to the other occurrences referenced (around the blocks
noted at 96-97, 104-107, 121-122, 128-129) so all prescribed pnpm commands can
run in the skill runtime.

Comment on lines +46 to 47
pnpm run format
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Whitelist pnpm in allowed-tools to match the migrated commands.

This workflow now relies on pnpm, but allowed-tools still only grants Bash(npm *) (Line 10). That blocks execution of the updated steps.

Suggested patch
 allowed-tools:
   - Bash(gh *)
   - Bash(git *)
+  - Bash(pnpm *)
   - Bash(npm *)
   - Bash(mvn *)
   - Read
   - Grep
   - Glob

Also applies to: 55-56, 65-67, 72-74, 81-82, 93-94, 99-100, 115-117, 126-128

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/land-pr/SKILL.md around lines 46 - 47, The workflow now uses
pnpm but the allowed-tools whitelist still only permits Bash(npm *), so update
the allowed-tools entry in .claude/skills/land-pr/SKILL.md to include pnpm
(e.g., add Bash(pnpm *) or include pnpm alongside npm) so the pnpm commands such
as the occurrences around the lines with "pnpm run format" (and other pnpm
usages noted at lines ~55-56, 65-67, 72-74, 81-82, 93-94, 99-100, 115-117,
126-128) are permitted; modify the allowed-tools block to whitelist pnpm and
ensure the pattern matches the pnpm command invocations used in the file.

Comment thread .node-version
@@ -1 +1 @@
22.22.0
24.15.0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

cat .node-version

Repository: ls1intum/Hephaestus

Length of output: 71


Revert the Node.js runtime pin to the repository-mandated version.

Line 1 sets 24.15.0, which conflicts with the coding guidelines requiring version 22.10.0. This version mismatch can desynchronize local and CI toolchains.

🔧 Proposed fix
-24.15.0
+22.10.0
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
24.15.0
22.10.0
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.node-version at line 1, Replace the pinned Node.js runtime value "24.15.0"
in the .node-version file with the repository-mandated version "22.10.0" so
local and CI toolchains match; update the single-line value to 22.10.0 and
commit the change (ensure no other files override this setting).

Comment thread package.json
"server/webhook-ingest",
"server/application-server/agent-extensions"
],
"packageManager": "pnpm@11.1.2",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Root manifest now violates the package-manager and Node version policy.

Line 4 and Lines 8-57 switch the repo to pnpm, and Line 80 moves Node to >=24.0. This conflicts with the repository rule for this file to use npm and the exact Node version from .node-version (22.10.0).

As per coding guidelines: "Use the exact Node.js version from .node-version (currently 22.10.0) and stick with npm for dependency management".

Also applies to: 8-57, 80-80

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` at line 4, The package manifest currently switches the repo to
pnpm and updates Node to >=24.0; revert the packageManager field from
"pnpm@11.1.2" back to npm (e.g. "packageManager": "npm@<appropriate-version>" or
simply "npm@<repo-standard>") and set the Node engine to the exact version from
.node-version by updating the engines.node field to "22.10.0" (or add engines:{
"node":"22.10.0" } if missing); ensure any other occurrences that changed Node
range (the node/engines entry) are replaced with the exact "22.10.0" value.

@@ -99,7 +99,7 @@ fi

if [[ -d "$ROOT_DIR" ]]; then
echo "ℹ️ Refreshing npm dependencies..."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Status message is stale after the package-manager switch.

Line 101 still says “npm dependencies” while the command now runs pnpm.

✏️ Proposed fix
-    echo "ℹ️  Refreshing npm dependencies..."
+    echo "ℹ️  Refreshing pnpm dependencies..."
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
echo "ℹ️ Refreshing npm dependencies..."
echo "ℹ️ Refreshing pnpm dependencies..."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/codex-maintenance.sh` at line 101, Update the stale status message in
scripts/codex-maintenance.sh: replace the echo that prints "ℹ️  Refreshing npm
dependencies..." with language matching the actual package manager (e.g., "ℹ️ 
Refreshing pnpm dependencies..." or a neutral "ℹ️  Refreshing project
dependencies...") so the output reflects the command now using pnpm; locate the
echo string "ℹ️  Refreshing npm dependencies..." and modify it accordingly in
the script.

}

export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid modifying shadcn primitive files in src/components/ui.

This export reorder is a no-op but still changes a protected primitive file. Please revert and keep these files untouched unless explicit approval was granted.

As per coding guidelines webapp/src/components/ui/**/*.{ts,tsx}: “Never edit files in src/components/ui/ (shadcn/ui primitives)”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webapp/src/components/ui/accordion.tsx` at line 69, The change only reorders
the export statement for Accordion primitives (Accordion, AccordionContent,
AccordionItem, AccordionTrigger) in the shadcn/ui file and should not be
modified; revert this file to its original state by undoing the export
reordering (restore the previous export line for the Accordion primitives) so
that no edits remain in the protected src/components/ui shadcn primitive files.

Comment on lines 222 to 230
export {
type CarouselApi,
Carousel,
type CarouselApi,
CarouselContent,
CarouselItem,
CarouselPrevious,
CarouselNext,
CarouselPrevious,
useCarousel,
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Confirm approval before modifying shadcn/ui primitive files.

This file is under src/components/ui/, and the PR edits it. Please confirm this change had prior approval per repo policy.

As per coding guidelines: webapp/src/components/ui/**/*.{ts,tsx}: Never edit files in src/components/ui/ (shadcn/ui primitives).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webapp/src/components/ui/carousel.tsx` around lines 222 - 230, You modified
shadcn/ui primitive exports (Carousel, CarouselApi, CarouselContent,
CarouselItem, CarouselNext, CarouselPrevious, useCarousel); before any further
edits, confirm the change has explicit prior approval per repo policy—if
approval is not present, revert this file to the upstream/shadcn-provided
version (restore original exports and implementation) and remove your
modifications; if approval exists, add a one-line PR note citing the approver
and policy exemption and keep only minimal, documented adjustments to the
Carousel-related symbols to match that approved design.

Comment on lines +170 to +238
{payload.map((item, index) => {
const key = `${nameKey || item.name || item.dataKey || "value"}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key);
const indicatorColor =
color || (item.payload as { fill?: string } | undefined)?.fill || item.color;

return (
<div
key={String(item.dataKey ?? item.name ?? index)}
className={cn(
"[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5",
indicator === "dot" && "items-center",
)}
>
{formatter && item.value !== undefined && item.name ? (
formatter(item.value, item.name, item, index, item.payload)
) : (
<>
{itemConfig?.icon ? (
<itemConfig.icon />
) : (
!hideIndicator && (
<div
className={cn(
"shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)",
{
"h-2.5 w-2.5": indicator === "dot",
"w-1": indicator === "line",
"w-0 border-[1.5px] border-dashed bg-transparent":
indicator === "dashed",
"my-0.5": nestLabel && indicator === "dashed",
},
)}
style={
{
"--color-bg": indicatorColor,
"--color-border": indicatorColor,
} as React.CSSProperties
}
/>
)
)}
<div
className={cn(
"flex flex-1 justify-between leading-none",
nestLabel ? "items-end" : "items-center",
)}
<div
className={cn(
"flex flex-1 justify-between leading-none",
nestLabel ? "items-end" : "items-center",
)}
>
<div className="grid gap-1.5">
{nestLabel ? tooltipLabel : null}
<span className="text-muted-foreground">
{itemConfig?.label || item.name}
</span>
</div>
{item.value && (
<span className="text-foreground font-mono font-medium tabular-nums">
{item.value.toLocaleString()}
</span>
)}
>
<div className="grid gap-1.5">
{nestLabel ? tooltipLabel : null}
<span className="text-muted-foreground">
{itemConfig?.label || item.name}
</span>
</div>
</>
)}
</div>
);
})}
{item.value !== undefined && item.value !== null && (
<span className="text-foreground font-mono font-medium tabular-nums">
{Array.isArray(item.value)
? item.value.join(", ")
: typeof item.value === "number"
? item.value.toLocaleString()
: item.value}
</span>
)}
</div>
</>
)}
</div>
);
})}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Restore filtering for non-display tooltip payload entries.

payload.map(...) now renders all entries, including type === "none", which can introduce extra/invalid tooltip rows.

Proposed fix
-				{payload.map((item, index) => {
+				{payload
+					.filter((item) => item.type !== "none")
+					.map((item, index) => {
 					const key = `${nameKey || item.name || item.dataKey || "value"}`;
 					const itemConfig = getPayloadConfigFromPayload(config, item, key);
 					const indicatorColor =
 						color || (item.payload as { fill?: string } | undefined)?.fill || item.color;
@@
-				})}
+					})}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webapp/src/components/ui/chart.tsx` around lines 170 - 238, The tooltip
renderer currently iterates payload.map(...) and renders entries whose
payload.type === "none", producing invalid rows; update the iteration to skip
non-display entries by filtering payload first (e.g., replace payload.map(...)
with payload.filter(p => p.type !== "none").map(...)) or early-return null for
items with item.type === "none"; keep existing logic around
getPayloadConfigFromPayload, indicator/hideIndicator handling, and keys
(key={String(item.dataKey ?? item.name ?? index)}) so only displayable payload
entries are rendered.

Comment on lines +272 to 297
{payload.map((item, index) => {
const key = `${nameKey || item.dataKey || "value"}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key);

return (
<div
key={item.value ?? index}
className={cn(
"[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3",
)}
>
{itemConfig?.icon && !hideIcon ? (
<itemConfig.icon />
) : (
<div
className="h-2 w-2 shrink-0 rounded-[2px]"
style={{
backgroundColor: item.color,
}}
/>
)}
{itemConfig?.label}
</div>
);
})}
</div>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Filter legend payload entries with type === "none".

Legend rendering now includes all payload entries, which can surface non-user-facing series metadata.

Proposed fix
-			{payload.map((item, index) => {
+			{payload.filter((item) => item.type !== "none").map((item, index) => {
 				const key = `${nameKey || item.dataKey || "value"}`;
 				const itemConfig = getPayloadConfigFromPayload(config, item, key);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{payload.map((item, index) => {
const key = `${nameKey || item.dataKey || "value"}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key);
return (
<div
key={item.value ?? index}
className={cn(
"[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3",
)}
>
{itemConfig?.icon && !hideIcon ? (
<itemConfig.icon />
) : (
<div
className="h-2 w-2 shrink-0 rounded-[2px]"
style={{
backgroundColor: item.color,
}}
/>
)}
{itemConfig?.label}
</div>
);
})}
</div>
{payload.filter((item) => item.type !== "none").map((item, index) => {
const key = `${nameKey || item.dataKey || "value"}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key);
return (
<div
key={item.value ?? index}
className={cn(
"[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3",
)}
>
{itemConfig?.icon && !hideIcon ? (
<itemConfig.icon />
) : (
<div
className="h-2 w-2 shrink-0 rounded-[2px]"
style={{
backgroundColor: item.color,
}}
/>
)}
{itemConfig?.label}
</div>
);
})}
</div>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webapp/src/components/ui/chart.tsx` around lines 272 - 297, Legend rendering
is including payload entries with non-user-facing metadata (type === "none");
update the rendering in the payload.map loop to skip/filter out items where
item.type === "none" (e.g., filter payload before mapping or return null for
those entries) so getPayloadConfigFromPayload/itemConfig and the JSX (icons,
label) only render for visible series; use the existing symbols payload,
nameKey, getPayloadConfigFromPayload, itemConfig and hideIcon to implement the
filter.

* Feature flag name type derived from the generated OpenAPI types.
* Adding a new flag to the backend FeatureFlag enum + FeatureFlagsDTO
* and running `npm run openapi-ts` automatically updates this type.
* and running `pnpm run openapi-ts` automatically updates this type.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use the repo-standard API client regeneration command in this docstring.

Line 9 points to pnpm run openapi-ts, but the documented team workflow uses pnpm run generate:api:application-server. Please align this comment to avoid drift.

Based on learnings: Regenerate API client with pnpm run generate:api:application-server when OpenAPI schema changes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webapp/src/integrations/feature-flags/hooks.ts` at line 9, Update the
docstring in webapp/src/integrations/feature-flags/hooks.ts to use the
repo-standard regeneration command: replace the current instruction "pnpm run
openapi-ts" with "pnpm run generate:api:application-server" so the comment reads
along the lines of "Regenerate API client with pnpm run
generate:api:application-server when OpenAPI schema changes"; locate the
docstring in this file (the top comment block referenced around the existing
openapi-ts line) and make the substitution so future developers run the correct
command.

@FelixTJDietrich FelixTJDietrich changed the title chore(deps): migrate to pnpm 11 + Vite 8 + TypeScript 6 + Node 24 (frontend dep refresh) feat(deps): pnpm 11 migration + frontend major refresh (Vite 8 · TS 6 · Node 24) May 17, 2026
@FelixTJDietrich
FelixTJDietrich merged commit f079cea into main May 17, 2026
51 checks passed
@FelixTJDietrich
FelixTJDietrich deleted the dependency-upgrade-pnpm-migration branch May 17, 2026 17:58
@FelixTJDietrich

Copy link
Copy Markdown
Collaborator Author

🎉 This PR is included in version 0.67.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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.

Dependency Dashboard

1 participant