Skip to content

Commit 72ee317

Browse files
authored
Merge branch 'main' into fix-german-locale-inconsistency
2 parents a2a2849 + fa2eb67 commit 72ee317

4,096 files changed

Lines changed: 560423 additions & 127492 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
---
2+
name: feature-walkthrough
3+
description: >-
4+
Explain the full logic and process of the current branch end-to-end so someone
5+
with no prior knowledge of the task can understand, review, and reproduce it.
6+
Scopes the change from the branch diff, traces the flow across every layer it
7+
touches (frontend tool/hook/component, Java controller/service/endpoint, Python
8+
engine, config, i18n, tests), and produces a self-contained walkthrough document
9+
with Mermaid diagrams (sequence/flow/architecture), annotated file map with
10+
clickable references, before/after behavior, screenshots where a UI is involved,
11+
a "try it locally" section, and edge cases/risks. Use when asked for a feature or
12+
branch walkthrough, "explain what this branch does", a design/logic writeup, PR
13+
reviewer onboarding, or a hand-off doc. Pass --html to also emit a rendered HTML
14+
version; --no-screens to skip screenshots.
15+
argument-hint: "[branch-or-area] [--html] [--no-screens]"
16+
allowed-tools: Read, Write, Edit, Glob, Grep, Bash
17+
---
18+
19+
# Feature / Branch Walkthrough
20+
21+
Turn the current branch into a walkthrough a newcomer can follow. Audience:
22+
**someone who has never seen this task**. Explain the *why*, the *flow*, and *how to
23+
try it* - not just a diff summary.
24+
25+
`$ARGUMENTS` may name a branch or area to focus on; default is the current branch
26+
vs `main`. Flags: `--html` (also emit a rendered HTML twin), `--no-screens`.
27+
28+
## Process
29+
30+
### 1. Scope the change
31+
- `git log --oneline main..HEAD` and `git diff --stat main...HEAD` for the shape.
32+
- Read the PR description / commit messages for stated intent. Do **not** invent
33+
history or motivation that isn't evidenced (state current behavior in present tense).
34+
- Classify touched files by layer:
35+
- **Frontend**: tools (`frontend/editor/src/core/components/tools/*` or `.../core/tools/*`),
36+
hooks (`core/hooks/tools/*`, `useToolOperation`), contexts, routes, i18n
37+
(`public/locales/en-US`).
38+
- **Java backend**: controllers (`.../controller/api/...`), services, models, config.
39+
- **Engine**: `engine/src/stirling/{agents,contracts,api,services}`.
40+
- **Config / build / docker / tests.**
41+
42+
### 2. Trace the flow end-to-end
43+
Follow one real path from user action to result. For a typical PDF tool that's:
44+
UI control → `useToolOperation` hook → `POST /api/v1/...` → Spring controller →
45+
service (PDFBox / LibreOffice / engine call) → response → review panel → download.
46+
Read the actual files so the narrative is true to the code, and collect the exact
47+
file:line anchors you'll cite.
48+
49+
### 3. Draw the diagrams (Mermaid)
50+
Pick what fits; usually 2-3 of:
51+
- **Sequence diagram** - request/response across frontend → backend → engine.
52+
- **Flowchart** - the core decision/branching logic of the feature.
53+
- **Architecture/component** - new pieces and how they wire to existing ones.
54+
- **State** - if the feature has modes/steps.
55+
Keep nodes labeled in plain language. Validate the Mermaid parses before shipping.
56+
57+
### 4. Screenshots (unless --no-screens)
58+
If a UI is involved, capture key states with the stubbed Playwright harness
59+
(see the **ui-walkthrough** skill and `files-page-screenshots.spec.ts` for the
60+
pattern) or, for before/after, capture `main` then the branch. Drop PNGs in
61+
`walkthrough/<feature>/` and reference them from the doc. For backend-only
62+
changes, show request/response examples (curl + JSON) instead.
63+
64+
### 5. Write the walkthrough
65+
Create `walkthrough/<feature>/FEATURE-WALKTHROUGH.md` with:
66+
1. **TL;DR** - what the branch does and who it's for, in 3-4 sentences.
67+
2. **Problem & approach** - what wasn't possible before; the chosen solution.
68+
3. **Architecture diagram** + 1-paragraph orientation.
69+
4. **End-to-end flow** - the sequence diagram + a numbered walk of each step,
70+
each citing the real file (clickable `path:line`).
71+
5. **Key files** - annotated map (path → one line on its role).
72+
6. **Logic deep-dive** - the flowchart + prose for the non-obvious decisions.
73+
7. **Behavior** - before vs after; screenshots or request/response examples.
74+
8. **Try it locally** - exact steps (`task dev` / `task dev:all`, the route to
75+
open or the curl to run, any env like `DOCKER_ENABLE_SECURITY` or a test
76+
license key). Make it copy-pasteable.
77+
9. **Edge cases, risks, follow-ups** - what's untested, known limits, gotchas.
78+
79+
Markdown is the primary deliverable - it renders with diagrams in GitHub PRs and
80+
IDEs, no build step, ideal for review.
81+
82+
### 6. If `--html`
83+
Also emit `walkthrough/<feature>/walkthrough.html`: the same content with Mermaid
84+
rendered via `mermaid.initialize({startOnLoad:true})` (script from CDN; note in
85+
the file that rendering diagrams needs network, the `.md` is the offline copy) and
86+
screenshots inline. Keep it self-contained otherwise.
87+
88+
### 7. Deliver
89+
Give the doc path and a short chat summary. Offer to `SendUserFile` it.
90+
91+
## Principles
92+
- **True to the code.** Every claim traces to a file you read; cite `path:line`.
93+
No fabricated migration/version history.
94+
- **Newcomer-first.** Define repo-specific terms (FileContext, `useToolOperation`,
95+
the `@app/*` layer cascade, stubbed vs live tests) on first use.
96+
- **Show, don't assert.** Prefer a diagram + a real example over adjectives.
97+
- Don't commit the `walkthrough/` output unless asked.

.claude/skills/pr-quiz/SKILL.md

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
---
2+
name: pr-quiz
3+
description: >-
4+
Quiz the PR author on their own branch before they request review, to prove they
5+
actually understand the change - especially code an AI wrote for them. Scopes the
6+
branch diff vs its base, reads the changed code, then asks graded questions about
7+
what changed, why, how it works, what it could break, and which edge cases it must
8+
handle. Presents all questions first, waits for the author's answers, then grades
9+
each honestly against the real code (Correct / Partial / Incorrect with the true
10+
answer and file:line), scores it, and gives a readiness verdict that names the
11+
areas to re-study before asking humans to review. Use when asked to quiz me on my
12+
PR/branch, "test my understanding before review", a self-check gate before opening
13+
a PR, or before requesting reviewers. Administered as an interactive
14+
multiple-choice quiz (clickable options) by default; pass --free-text for
15+
written answers, --questions N to set count, --save to write a scorecard.
16+
argument-hint: "[branch-or-base-ref] [--questions N] [--free-text] [--save]"
17+
allowed-tools: Bash, Read, Grep, Glob, Write, AskUserQuestion
18+
---
19+
20+
# PR Quiz
21+
22+
Test whether the **author** genuinely understands their own branch before they ask
23+
other people to spend time reviewing it. This is a self-check gate: the point is to
24+
catch changes - often AI-written - that the author would not be able to explain or
25+
defend in review. Be a fair but honest examiner, not a pushover.
26+
27+
`$ARGUMENTS` may name a base ref or branch to diff against; default is this branch
28+
vs where it forked from the main line. Flags:
29+
- `--questions N` - target N questions (else scale to diff size, see below).
30+
- `--free-text` - administer as a written numbered list instead of the default
31+
interactive multiple-choice.
32+
- `--save` - also write a scorecard file after grading.
33+
34+
## Integrity rules (read first - the whole skill depends on these)
35+
36+
1. **Present every question before revealing any answer.** Ask, then wait. Never
37+
show the answer key alongside the questions.
38+
2. **Do not give hints or the answer while the quiz is open.** If the author asks
39+
"what's the answer?" or "is it X?" before committing, decline warmly and tell
40+
them to give their best answer first - guessing is part of the signal.
41+
3. **Grade truthfully.** Vague, hand-wavy, or "the AI did it" non-answers are
42+
Partial or Incorrect, not Correct. Do not inflate the score to be nice; a false
43+
pass defeats the entire purpose.
44+
4. **Ground everything in code you actually read.** Every question and every model
45+
answer must trace to a real line in the diff. Cite `path:line`. No trivia
46+
("how many lines?"), no invented behavior.
47+
5. **Credit real understanding.** If the author explains it correctly in their own
48+
words, mark it Correct even if worded differently than your key.
49+
50+
## Process
51+
52+
### 1. Scope the change (silently)
53+
- Find the base. Prefer the fork point off the main line so the quiz covers only
54+
this branch's work:
55+
```bash
56+
git fetch -q origin 2>/dev/null; \
57+
BASE=$(git merge-base HEAD origin/main 2>/dev/null || git merge-base HEAD main); \
58+
git diff --stat "$BASE"...HEAD
59+
```
60+
If `$ARGUMENTS` names a ref, diff against that instead.
61+
- If the diff is empty, stop and say there's nothing to quiz on.
62+
- Read commit messages / PR description for the *stated* intent, but verify it
63+
against the actual diff - a mismatch is itself a good question.
64+
65+
### 2. Understand the code well enough to examine on it
66+
Read the full diff plus enough surrounding context and related files to answer
67+
every question you plan to ask. You cannot grade understanding you don't have.
68+
Note the non-obvious parts: the design decisions, the risky lines, the edge cases,
69+
the cross-file ripples, and anything that violates or upholds repo conventions
70+
(for this repo e.g. `@app/*` import layering, all file ops via FileContext,
71+
Jackson 3 / Spring Boot 4 APIs, engine typed-contract boundaries).
72+
73+
### 3. Build the question set
74+
Scale count to the change unless `--questions N` is given:
75+
small (< ~50 changed lines) 3-4, medium 5-8, large 9-12. Cap at 12.
76+
Draw from these categories - weight toward the ones the diff actually exercises:
77+
- **Intent** - what problem this solves; why it was needed now.
78+
- **Mechanism** - how a specific non-trivial piece actually works ("walk me
79+
through what `foo()` does when called with X").
80+
- **Decisions & alternatives** - why this approach over an obvious alternative;
81+
what a reviewer would reasonably push back on.
82+
- **Blast radius** - what else this touches or could break; what you'd retest.
83+
- **Edge cases** - inputs/states the change must handle (null, empty, large,
84+
concurrent, error paths).
85+
- **Conventions & correctness** - does it follow the repo's rules; is there a
86+
latent bug the author should be able to spot.
87+
Prefer questions the author can only answer if they read and understood the code.
88+
Keep a private answer key with `path:line` for each - do **not** show it yet.
89+
90+
### 4. Administer the quiz
91+
- **Default (multiple choice):** use the `AskUserQuestion` tool. Per question write
92+
3-4 options where **every** option is independently plausible - each distractor a
93+
real-but-wrong reading of the code, not filler. Two hard rules so the answer
94+
can't be spotted by shape rather than knowledge:
95+
- **Randomise the correct option's position** across questions - never default
96+
it to first. Spread it roughly evenly over the slots.
97+
- **Keep all options the same depth and length.** Do not describe the correct
98+
one more fully than the distractors - a longer or more-detailed option is a
99+
dead giveaway. Trim the right answer or flesh out the wrong ones until a
100+
reader can't tell them apart by size.
101+
The tool caps a call at 4 questions, so ask in batches of 4 - but run them as
102+
one continuous flow: fire the next batch immediately after the previous
103+
returns, with no narration ("Round 2 of 3") and no grading between batches.
104+
The author always has an "Other" free-text escape, which is fine.
105+
- **`--free-text`:** present all questions in one numbered list, then say
106+
"Answer in one reply; number your answers. I won't grade until you're done."
107+
Wait for the author's answers.
108+
- Do not proceed to grading until every answer is in.
109+
110+
### 5. Grade
111+
For each question, in order:
112+
- Verdict: **Correct** / **Partial** / **Incorrect**.
113+
- The model answer in one or two sentences, citing the real `path:line`.
114+
- One line on the gap when Partial/Incorrect - what they missed and where to look.
115+
Then a **Score** (e.g. 6/8, counting Partial as half) and a one-line summary of
116+
the pattern (e.g. "solid on intent, shaky on the error paths").
117+
118+
### 6. Readiness verdict
119+
End with a clear call:
120+
- **Ready for review** - understanding is sound; note anything to mention to
121+
reviewers proactively.
122+
- **Study first** - list the specific files/concepts to re-read before requesting
123+
review, each as a clickable `path:line`. Be concrete: "re-read the null handling
124+
in X before you send this out."
125+
Keep it honest - if they'd get grilled in review on something, say so now.
126+
127+
### 7. If `--save`
128+
Write `pr-quiz/<branch>-scorecard.md`: the questions, their answers, your grades
129+
and model answers, the score, and the verdict. Don't commit it unless asked.
130+
131+
## Principles
132+
- **The author is the examinee, not the collaborator.** During the quiz you withhold
133+
answers; you're measuring them, not helping them pass.
134+
- **A failed quiz is a successful outcome** - it caught a gap before a human's time
135+
was spent. Frame it that way, not as a scolding.
136+
- **True to the code.** Every question, answer, and grade traces to a line you read.
137+
- **Terse and direct** in chat - the questions and the verdict, minimal preamble.
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
---
2+
name: ui-before-after
3+
description: >-
4+
Analyse a branch or PR and automatically capture before/after screenshots of
5+
every UI surface its changes touch, then pixel-diff the pairs to surface what
6+
actually changed and assemble PR-ready before/after montage images. Generic and
7+
diff-driven: it derives the capture targets from the diff (changed tools/routes →
8+
URLs) instead of hand-listing screens, captures "before" from the base branch and
9+
"after" from the head, then keeps only the views that visually differ. Each
10+
comparison is auto-cropped to the region that actually changed (the bounding box of
11+
differing pixels), falling back to the full page only when the change spans most of
12+
it. Use for before/after shots, a visual diff of a branch/PR, "screenshots for the
13+
PR description", "show what changed in the UI", or a side-by-side of UI changes.
14+
Takes a PR number/URL (resolved via gh) or a branch; defaults to the current branch
15+
vs its base. Flags: --scope <selector>, --base <ref|merge-base>, --theme
16+
light|dark|both, --all (capture every route, not just changed), --no-autocrop,
17+
--pagewide <n>, --threshold <n>.
18+
argument-hint: "[PR# | PR-url | branch] [--scope <sel>] [--base <ref>] [--theme both] [--all] [--no-autocrop]"
19+
allowed-tools: Read, Write, Edit, Glob, Grep, Bash
20+
---
21+
22+
# UI Before / After (generic visual diff)
23+
24+
Point it at a branch or PR; it figures out which UI changed, screenshots every
25+
affected surface **before** (base) and **after** (head), pixel-diffs the pairs, and
26+
montages the ones that actually changed into images for the PR description.
27+
28+
`$ARGUMENTS`: a PR number/URL, a branch, or nothing (current branch vs base).
29+
By default it captures the full viewport and auto-crops each comparison to the region
30+
that changed. Flags: `--scope <css>` (narrow the *capture* to a container, e.g.
31+
`[data-sidebar="tool-panel"]`, when you already know where the change is),
32+
`--no-autocrop` (keep full frames), `--pagewide <fraction>` (above this share of the
33+
page, skip cropping; default 0.6), `--base <ref|merge-base>`,
34+
`--theme light|dark|both`, `--all` (walk every route, not just changed),
35+
`--threshold <fraction>` (diff sensitivity, default 0.001).
36+
37+
Shares the capture harness with **ui-walkthrough** - read its SKILL.md for the
38+
stubbed-Playwright setup, worktree node_modules + `generate-icons`, the
39+
stale-`:5173` gotcha, and the dark-mode init-script. Bundled helpers:
40+
[capture-spec.template.ts](capture-spec.template.ts), [diff-shots.mjs](diff-shots.mjs),
41+
[montage-template.html](montage-template.html), [shoot-sections.mjs](shoot-sections.mjs).
42+
43+
## Process
44+
45+
### 1. Resolve target + base
46+
```
47+
gh pr view <pr> --json number,title,headRefName,baseRefName,url,files # PR
48+
# or branch: base = merge-base(main, HEAD); head = HEAD
49+
gh pr diff <pr> --name-only # or: git diff --name-only <base>...HEAD
50+
```
51+
52+
### 2. Derive capture targets from the diff (the "analyse" step - no hand-listing)
53+
Map changed frontend files to URLs generically:
54+
- **Tools**: a changed `components/tools/<toolDir>/…` or `hooks/tools/<tool>/…`
55+
toolId → URL via the repo's own rule `getToolUrlPath` in
56+
[toolsTaxonomy.ts:200](frontend/editor/src/core/data/toolsTaxonomy.ts): `/` + the
57+
id kebab-cased (`addPageNumbers``/add-page-numbers`).
58+
- **Pages/routes**: changed `filesPage/*``/files`, etc.
59+
- `--all`: enumerate every tool in the registry instead of just changed ones.
60+
Write `frontend/editor/screenshots/ui-diff/targets.json` =
61+
`[{ "id":"compress", "url":"/compress", "name":"Compress" }]`. This is what makes
62+
it generic - the spec never names a tool.
63+
64+
### 3. Capture AFTER (head) then BEFORE (base)
65+
Copy [capture-spec.template.ts](capture-spec.template.ts)
66+
`src/core/tests/stubbed/ui-before-after.spec.ts` (it loops `targets.json`, seeds a
67+
sample PDF so file-dependent panels render, navigates to each URL, and screenshots
68+
the full viewport - or the `--scope` container if given). Ensure the harness is ready
69+
(node_modules + icons).
70+
```
71+
# after = current head
72+
cd frontend/editor && PR_SHOT_SIDE=after PR_SHOT_THEME=light \
73+
npx playwright test --project=stubbed ui-before-after.spec.ts
74+
# before = base, in an isolated worktree (copy the spec + targets.json in)
75+
git worktree add ../ba-base origin/<baseRefName> # or the merge-base
76+
# set up its frontend, copy spec + screenshots/ui-diff/targets.json across, then:
77+
cd ../ba-base/frontend/editor && PR_SHOT_SIDE=before PR_SHOT_THEME=light \
78+
npx playwright test --project=stubbed ui-before-after.spec.ts
79+
# copy its screenshots/ui-diff/before/ back next to after/. Repeat with
80+
# PR_SHOT_THEME=dark if --theme includes dark. Remove worktree when done.
81+
```
82+
83+
### 4. Auto-diff (surface what changed)
84+
```
85+
cd frontend/editor && node <skill>/diff-shots.mjs \
86+
screenshots/ui-diff/before screenshots/ui-diff/after screenshots/ui-diff
87+
```
88+
Produces `diff-report.json` classifying each view `unchanged | changed | added |
89+
removed`. For each changed view it computes the bounding box of differing pixels and
90+
writes cropped `__before_crop.png` / `__after_crop.png` / `__diff.png` to that region
91+
(+ padding) - **unless** the change covers more than `--pagewide` of the frame, where
92+
it keeps the full frame (`pageWide:true`). Drop `unchanged` - that's the noise the
93+
user doesn't want.
94+
95+
### 5. Montage the changes
96+
Build the manifest from the non-unchanged entries (group by tab/tool; each becomes a
97+
state row with before/after). For changed views use the cropped `cropBefore` /
98+
`cropAfter` from `diff-report.json` (tight on the affected region; full frame when
99+
`pageWide`); `added`/`removed` render the "not present" placeholder. Fill
100+
[montage-template.html](montage-template.html) (replace the `window.__BA__` data
101+
block; base64-inline the PNGs for portability), then render one PNG per section with
102+
[shoot-sections.mjs](shoot-sections.mjs). Optionally include the `__diff.png` overlay
103+
as a third column.
104+
105+
### 6. Deliver
106+
Output the `montage_<tab>.png` files + a short summary (N changed / added / removed,
107+
M unchanged skipped) and a paste-ready Markdown block. GitHub has no PR-body image
108+
API, so tell the user to drag the PNGs into the description. Do **not** post to the
109+
PR.
110+
111+
## Gotchas
112+
- Two installs (base worktree + head); junction main's node_modules only if its deps
113+
match that ref, else `npm ci` (see ui-walkthrough's stale-dep note).
114+
- A view that errors on one side (refactored/removed) → that side is missing; the
115+
diff marks it added/removed rather than failing the run.
116+
- Pixel diff needs equal dimensions, so capture at a fixed viewport (the template
117+
does); a view whose size changed is reported as "changed (dimensions differ)",
118+
uncropped.
119+
- Auto-crop uses a single bounding box, so two far-apart changes give one large crop
120+
(or trip `--pagewide`); narrow with `--scope` if that happens.
121+
- `getToolUrlPath` is the source of truth for tool URLs - use it, don't guess slugs.
122+
- Don't commit `screenshots/`, the throwaway spec, or the base worktree.

0 commit comments

Comments
 (0)