Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .agents/skills/fix-ci/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ disable-model-invocation: true
allowed-tools:
- Bash(gh *)
- Bash(git *)
- Bash(pnpm *)
- Bash(bun *)
- Bash(./mvnw *)
- Read
- Grep
Expand Down Expand Up @@ -62,17 +62,17 @@ Each leg's annotation names its own command; this table is only what the annotat

| Failure | What it actually means |
|---|---|
| `routeTree.gen.ts is stale` | Only a Vite build writes it. `cd webapp && pnpm run build`, then commit the file. |
| `README images are stale` | The storybook job runs `export:readme-assets` *after* `test:storybook`, so the job goes red having printed a clean pass line. Run `pnpm --filter webapp run export:readme-assets` and commit `docs/images/readme`. |
| `routeTree.gen.ts is stale` | Only a Vite build writes it. `cd webapp && bun run build`, then commit the file. |
| `README images are stale` | The storybook job runs `export:readme-assets` *after* `test:storybook`, so the job goes red having printed a clean pass line. Run `bun run --filter webapp export:readme-assets` and commit `docs/images/readme`. |
| Migrations gate | A changelog that reached `main` was edited, renamed or deleted, or a `master.xml` `<include>` was not appended at the end. Fix forward with a new changeset; never edit the released file. |
| `verify-changesets` | The PR touches shipped code with no `.changeset/*.md`. `/land-pr` step 9 has the rules. |
| App Server leg red on a docs-only PR | Expected, not a misconfiguration: `docs/**` is inside the `application-server` paths filter, because `docs:lint` and `check:diagrams` run on that leg. |

## 4. Reproduce locally before pushing

```bash
pnpm run format
pnpm run check
bun run format
bun run check
```

`check` runs every leg CI runs except those needing Docker or a live credential — `docs:lint`
Expand Down
20 changes: 10 additions & 10 deletions .agents/skills/land-pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ disable-model-invocation: true
allowed-tools:
- Bash(gh *)
- Bash(git *)
- Bash(pnpm *)
- Bash(bun *)
- Bash(./mvnw *)
- Read
- Grep
Expand Down Expand Up @@ -42,8 +42,8 @@ than guessing, and note the two shapes that surprise people:
## 3. Format, then check

```bash
pnpm run format
pnpm run check
bun run format
bun run check
```

`check` is the complete local quality gate — every leg is listed under `check` in the root
Expand All @@ -57,9 +57,9 @@ Generated artefacts are never hand-edited, and regeneration is destructive — i
directory first, so stash local edits.

```bash
pnpm run generate:api # controllers or DTOs changed: rewrites openapi.yaml AND webapp/src/api
pnpm run db:draft-changelog # entities changed (needs Docker); then prune the diff to real deltas
pnpm run db:generate-erd-docs # after any changelog change
bun run generate:api # controllers or DTOs changed: rewrites openapi.yaml AND webapp/src/api
bun run db:draft-changelog # entities changed (needs Docker); then prune the diff to real deltas
bun run db:generate-erd-docs # after any changelog change
```

`generate:api:application-server:specs` **exits 0 having written nothing** when a port it needs is
Expand All @@ -69,7 +69,7 @@ busy — HTTP, management, or the JMX port it defaults to. Pass free ports; the
## 5. Run the tests your diff can break

```bash
pnpm run test:webapp
bun run test:webapp
cd server && ./mvnw -pl application -am test -Dsurefire.includedGroups=unit -T 2C --batch-mode -q
```

Expand All @@ -85,11 +85,11 @@ A PR touching `server/`, `webapp/` or `docker/` needs a `.changeset/*.md` or `ve
fails it.

```bash
pnpm changeset # user-facing: pick the bump, write the summary in the operator's voice
pnpm changeset --empty # no user-facing effect; say why in the body
bun changeset # user-facing: pick the bump, write the summary in the operator's voice
bun changeset --empty # no user-facing effect; say why in the body
```

`pnpm changeset` is interactive — with no TTY, hand-write `.changeset/<slug>.md` (`.changeset/README.md`
`bun changeset` is interactive — with no TTY, hand-write `.changeset/<slug>.md` (`.changeset/README.md`
has the shape). The summary lands in `CHANGELOG.md` verbatim, so it names what an operator or user can
now do, not a class or a file. **Pre-1.0, never pick `major`** — it would cut 1.0.0 and the gate
rejects it; a breaking change rides in `minor` with `**Operators:** …` in the summary and a
Expand Down
6 changes: 3 additions & 3 deletions .changeset/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ the version bump. (Not a Liquibase `<changeSet>` — a schema change needs both.
Every PR that changes shipped code (anything under `server/`, `webapp/`, or `docker/` except tests and in-tree docs) ships one; CI (`verify-changesets`) enforces it.

```bash
pnpm changeset # write one (pick the bump, describe the change)
pnpm changeset --empty # no user-facing effect — then write why in the file body (non-interactive)
bun changeset # write one (pick the bump, describe the change)
bun changeset --empty # no user-facing effect — then write why in the file body (non-interactive)
```

The summary lands in the changelog **verbatim**, in the operator/user's voice — lead with what they can now
do, or the symptom a fix removes. No class/hook/file names. No agent-attribution trailers. One changeset per
user-visible change; unsure whether it's visible? Add one — a reviewer can delete it, a missing note can't.

No TTY (agents, CI)? `pnpm changeset` is interactive — instead write `.changeset/<slug>.md` by hand in the
No TTY (agents, CI)? `bun changeset` is interactive — instead write `.changeset/<slug>.md` by hand in the
format shown below. That is the one sanctioned hand-write; never touch `CHANGELOG.md` directly.

**Bump = the operator's upgrade cost:**
Expand Down
5 changes: 5 additions & 0 deletions .changeset/modern-bun-package-manager.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
---

This package-management migration changes contributor and build infrastructure only; released
application behavior and operator configuration are unchanged.
10 changes: 5 additions & 5 deletions .claude/skills/fix-ci/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ disable-model-invocation: true
allowed-tools:
- Bash(gh *)
- Bash(git *)
- Bash(pnpm *)
- Bash(bun *)
- Bash(./mvnw *)
- Read
- Grep
Expand Down Expand Up @@ -62,17 +62,17 @@ Each leg's annotation names its own command; this table is only what the annotat

| Failure | What it actually means |
|---|---|
| `routeTree.gen.ts is stale` | Only a Vite build writes it. `cd webapp && pnpm run build`, then commit the file. |
| `README images are stale` | The storybook job runs `export:readme-assets` *after* `test:storybook`, so the job goes red having printed a clean pass line. Run `pnpm --filter webapp run export:readme-assets` and commit `docs/images/readme`. |
| `routeTree.gen.ts is stale` | Only a Vite build writes it. `cd webapp && bun run build`, then commit the file. |
| `README images are stale` | The storybook job runs `export:readme-assets` *after* `test:storybook`, so the job goes red having printed a clean pass line. Run `bun run --filter webapp export:readme-assets` and commit `docs/images/readme`. |
| Migrations gate | A changelog that reached `main` was edited, renamed or deleted, or a `master.xml` `<include>` was not appended at the end. Fix forward with a new changeset; never edit the released file. |
| `verify-changesets` | The PR touches shipped code with no `.changeset/*.md`. `/land-pr` step 9 has the rules. |
| App Server leg red on a docs-only PR | Expected, not a misconfiguration: `docs/**` is inside the `application-server` paths filter, because `docs:lint` and `check:diagrams` run on that leg. |

## 4. Reproduce locally before pushing

```bash
pnpm run format
pnpm run check
bun run format
bun run check
```

`check` runs every leg CI runs except those needing Docker or a live credential — `docs:lint`
Expand Down
20 changes: 10 additions & 10 deletions .claude/skills/land-pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ disable-model-invocation: true
allowed-tools:
- Bash(gh *)
- Bash(git *)
- Bash(pnpm *)
- Bash(bun *)
- Bash(./mvnw *)
- Read
- Grep
Expand Down Expand Up @@ -42,8 +42,8 @@ than guessing, and note the two shapes that surprise people:
## 3. Format, then check

```bash
pnpm run format
pnpm run check
bun run format
bun run check
```

`check` is the complete local quality gate — every leg is listed under `check` in the root
Expand All @@ -57,9 +57,9 @@ Generated artefacts are never hand-edited, and regeneration is destructive — i
directory first, so stash local edits.

```bash
pnpm run generate:api # controllers or DTOs changed: rewrites openapi.yaml AND webapp/src/api
pnpm run db:draft-changelog # entities changed (needs Docker); then prune the diff to real deltas
pnpm run db:generate-erd-docs # after any changelog change
bun run generate:api # controllers or DTOs changed: rewrites openapi.yaml AND webapp/src/api
bun run db:draft-changelog # entities changed (needs Docker); then prune the diff to real deltas
bun run db:generate-erd-docs # after any changelog change
```

`generate:api:application-server:specs` **exits 0 having written nothing** when a port it needs is
Expand All @@ -69,7 +69,7 @@ busy — HTTP, management, or the JMX port it defaults to. Pass free ports; the
## 5. Run the tests your diff can break

```bash
pnpm run test:webapp
bun run test:webapp
cd server && ./mvnw -pl application -am test -Dsurefire.includedGroups=unit -T 2C --batch-mode -q
```

Expand All @@ -85,11 +85,11 @@ A PR touching `server/`, `webapp/` or `docker/` needs a `.changeset/*.md` or `ve
fails it.

```bash
pnpm changeset # user-facing: pick the bump, write the summary in the operator's voice
pnpm changeset --empty # no user-facing effect; say why in the body
bun changeset # user-facing: pick the bump, write the summary in the operator's voice
bun changeset --empty # no user-facing effect; say why in the body
```

`pnpm changeset` is interactive — with no TTY, hand-write `.changeset/<slug>.md` (`.changeset/README.md`
`bun changeset` is interactive — with no TTY, hand-write `.changeset/<slug>.md` (`.changeset/README.md`
has the shape). The summary lands in `CHANGELOG.md` verbatim, so it names what an operator or user can
now do, not a class or a file. **Pre-1.0, never pick `major`** — it would cut 1.0.0 and the gate
rejects it; a breaking change rides in `minor` with `**Operators:** …` in the summary and a
Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/react-best-practices/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1403,7 +1403,7 @@ Reduce SVG coordinate precision to decrease file size. The optimal precision dep
**Automate with SVGO:**

```bash
pnpm exec svgo --precision=1 --multipass icon.svg
bun x svgo --precision=1 --multipass icon.svg
```

### 6.5 Prevent Hydration Mismatch Without Flickering
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ Reduce SVG coordinate precision to decrease file size. The optimal precision dep
**Automate with SVGO:**

```bash
pnpm exec svgo --precision=1 --multipass icon.svg
bun x svgo --precision=1 --multipass icon.svg
```
6 changes: 3 additions & 3 deletions .claude/skills/storybook-components/RUBRIC.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Scope: `webapp/src/components/**` and their colocated `*.stories.tsx`. **Grade a diff, not the repo.**

**Calibration contract.** A file that renders correctly, is formatted, passes `pnpm run check`, has a
**Calibration contract.** A file that renders correctly, is formatted, passes `bun run check`, has a
story per variant and a green a11y panel scores **C**. C is the floor for competent work, not a
criticism. B costs deliberate design. A costs a rejected alternative written down. A+ is rare by
construction — at most one dimension per PR should reach it.
Expand Down Expand Up @@ -192,7 +192,7 @@ Nearly every file carries `tags: ["autodocs"]`, so a JSDoc block above `meta` or
(`webapp/src/components/admin/practice-catalog/SortableCatalogTree.stories.tsx` — the stories render
a harness).

`node scripts/check-story-prose.ts` gates `<p>` only. For the D band there is no gate — it is a review
`bun scripts/check-story-prose.ts` gates `<p>` only. For the D band there is no gate — it is a review
question: *delete this block; is anything lost?* Rather less than half the files carry a meta JSDoc and
rather less than half the stories carry one, so the absence of a block is not by itself a finding.

Expand All @@ -201,7 +201,7 @@ rather less than half the stories carry one, so the absence of a block is not by
- **D** — A new rule added to prose that contradicts existing code, with no migration and no gate.
- **C** — Rule in prose, no gate.
- **B** — Rule in prose plus a mechanical check — an oxlint rule in `webapp/tools/oxlint/rules/`, or a
node gate in `scripts/` wired into `pnpm run check`.
repository gate in `scripts/` wired into `bun run check`.
- **A** — B, and the gate's own comment explains the neighbouring shapes it deliberately does *not*
match, so nobody widens it into a nuisance — the house rules in `webapp/tools/oxlint/rules/` are the
worked examples.
Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/storybook-components/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Load the one file that answers your question.

## Already enforced — do not re-litigate, and do not restate in prose

These fail `pnpm run check`. Treat a violation as a build error, not a style opinion, and do not
These fail `bun run check`. Treat a violation as a build error, not a style opinion, and do not
write a guideline that repeats one.

The house rules are registered in `webapp/tools/oxlint/index.ts` — read it rather than trusting a
Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/storybook-components/traps.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ story file installs no handlers at all, and `scripts/check-presentational-compon
`.github/workflows/ci-tests.yml` runs the webapp package's `export:readme-assets` immediately after
`test:storybook`, and fails the job if `docs/images/readme` is dirty afterwards. So the storybook job can go red
having printed a clean pass line. If a change moves or renames a story that exports a README asset,
run `pnpm --filter webapp run export:readme-assets` and commit the result.
run `bun run --filter webapp export:readme-assets` and commit the result.

## 6. A hand-rolled stateful wrapper swallows the spy in `meta.args`

Expand Down
8 changes: 4 additions & 4 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ TITLE FORMAT (required):
✗ Bad: Added weekly ranking filter to leaderboard

BEFORE PUSHING:
pnpm run format && pnpm run check # Format + lint + typecheck all services
bun run format && bun run check # Format + lint + typecheck all services

AFTER API CHANGES:
pnpm run generate:api # Regenerate all OpenAPI clients
bun run generate:api # Regenerate all OpenAPI clients

AFTER DATABASE/ENTITY CHANGES:
pnpm run db:draft-changelog # Generate Liquibase migration
pnpm run db:generate-erd-docs # Update ERD documentation
bun run db:draft-changelog # Generate Liquibase migration
bun run db:generate-erd-docs # Update ERD documentation
-->

## Description
Expand Down
13 changes: 13 additions & 0 deletions .github/actions/setup-bun/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: "Setup Bun"
description: "Installs the Bun version pinned by package.json."
runs:
using: "composite"
steps:
- name: Configure Bun environment
shell: bash
run: |
echo "HUSKY=0" >> "$GITHUB_ENV"
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version-file: package.json
4 changes: 2 additions & 2 deletions .github/actions/setup-caches/action.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: "Setup CI caches"
description: "Caches Maven dependencies, generated-client build outputs, and Playwright browsers. Node/pnpm setup happens in the calling workflow."
description: "Caches Maven dependencies, generated-client build outputs, and Playwright browsers."
inputs:
cache-type:
description: "Type of cache to setup"
Expand Down Expand Up @@ -57,6 +57,6 @@ runs:
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ~/.cache/ms-playwright
key: ${{ inputs.os }}-playwright-${{ hashFiles('pnpm-lock.yaml') }}
key: ${{ inputs.os }}-playwright-${{ hashFiles('bun.lock') }}
restore-keys: |
${{ inputs.os }}-playwright-
25 changes: 0 additions & 25 deletions .github/actions/setup-pnpm-node/action.yml

This file was deleted.

5 changes: 2 additions & 3 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ dependencies:
- changed-files:
- any-glob-to-any-file:
- "**/package.json"
- "**/pnpm-lock.yaml"
- "pnpm-workspace.yaml"
- ".npmrc"
- "**/bun.lock"
- "bunfig.toml"
- "**/pom.xml"
- "renovate.json"

Expand Down
3 changes: 1 addition & 2 deletions .github/scripts/label-pr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ const GENERATED_PATTERNS = [
// Docs generated
/^docs\/contributor\/erd\/.*\.mmd$/, // Generated Mermaid ERD diagrams

// Lock files (not code, just dependency resolution)
/pnpm-lock\.yaml$/,
/bun\.lock$/,
/\.lock$/,
];

Expand Down
22 changes: 5 additions & 17 deletions .github/workflows/cd-docs-teardown.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
# Documentation Preview Teardown
#
# Separate workflow for tearing down Surge.sh previews when PRs close.
# This is in a separate file because:
# 1. Path filters are unreliable for 'closed' events
# 2. Keeping deployment and teardown separate is cleaner
# 3. Teardown is a no-op if no preview exists (safe to run always)

name: CD / Docs Teardown

on:
Expand All @@ -24,18 +16,14 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
sparse-checkout: |
.github/actions/setup-pnpm-node
.node-version
pnpm-lock.yaml
sparse-checkout-cone-mode: false

- name: Setup pnpm + Node.js
uses: ./.github/actions/setup-pnpm-node
- name: Setup Bun
uses: ./.github/actions/setup-bun

- run: bun install --frozen-lockfile --ignore-scripts

- name: Teardown Surge.sh preview
run: pnpm dlx surge teardown ${{ env.PREVIEW_URL }} --token ${{ secrets.SURGE_TOKEN }}
run: bun --bun surge teardown ${{ env.PREVIEW_URL }} --token ${{ secrets.SURGE_TOKEN }}
continue-on-error: true

- name: Update PR comment
Expand Down
Loading
Loading