0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-05-11 13:35:24 +02:00

20760 Commits

Author SHA1 Message Date
Myers Carpenter
9e031eb3df
Serve OpenAPI 3.0 spec at /openapi.v1.json (#37038)
Add a build-time conversion step that transforms the existing Swagger
2.0 spec into an OpenAPI 3.0 spec. The OAS3 spec is served alongside the
existing Swagger 2.0 spec, enabling API clients that require OAS3 to
generate code directly from Gitea's API.

This is not to be an answer to how gitea handles OAS3 long term,
but a way to use what we have to move a step forward.

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-29 20:47:52 +08:00
Myers Carpenter
18762c7748
Batch-load related data in actions run, job, and task API endpoints (#37032)
Avoid per-item DB queries in ListRuns, ListJobs, and ListActionTasks by
batch-loading trigger users, repositories, and task attributes before
the conversion loop. Remove ReferencesGitRepo from the /actions route
group since no task/run endpoints use it.

Added tests for these endpoints as well.

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-29 08:39:43 +00:00
0xGREG
0ba862cb97
Add DEFAULT_TITLE_SOURCE setting for pull request title default behavior (#37465)
Adds a new `DEFAULT_TITLE_SOURCE` option under
`[repository.pull-request]` with three values:

- `first-commit` (default): uses the oldest commit summary, current
behavior since v1.26
- `auto`: normalizes branch name as title for multi-commit PRs (just
like GitHub), use commit summary for single-commit PRs

Closes: #37463
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-04-28 21:33:20 +00:00
Nicolas
deec2b0929
Fix compare dropdown for branches without common history (#37470) 2026-04-28 23:03:50 +02:00
Nicolas
fedc9dc993
FIX: URL sanitization to handle schemeless credentials (#37440)
Fixes #37435

---------

Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-04-28 23:26:08 +08:00
wxiaoguang
8bf51da65f
Refactor pull request view (4) (#37451)
Use JSON attribute instead of inline script

---------

Co-authored-by: Nicolas <bircni@icloud.com>
2026-04-28 04:36:39 +00:00
silverwind
4e1c658db5
Merge branch 'main' into search 2026-04-28 06:02:16 +02:00
Rayan Salhab
c8e67799b2
Fix scheduled action panic with null event payload (#37459)
This fixes the scheduled action panic when an event payload is JSON
`null` by initializing the payload map before adding `schedule`. It also
adds regression coverage for the null-payload case.

Fixes #37447.

Testing:
- `go test -tags 'sqlite sqlite_unlock_notify' ./services/actions -run
'^TestWithScheduleInEventPayload$' -count=1`
- Local note: this agent ran the command as root with a temporary
`GITEA_TEST_CONF=custom/conf/app-test-root.ini` file that only set
`I_AM_BEING_UNSAFE_RUNNING_AS_ROOT = true`.

Authorship: cyphercodes; AI assistance disclosed: Hermes Agent
(GPT-5.5).

---------

Co-authored-by: cyphercodes <cyphercodes@users.noreply.github.com>
Co-authored-by: Hermes Agent (GPT-5.5) <hermes-agent@users.noreply.github.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-04-28 01:58:04 +00:00
wxiaoguang
15b23f037d
Fix attachment Content-Security-Policy (#37455)
See the comments. Others are not changed, only added a new rule for
medias: `serveHeaderCspMedia`

---------

Co-authored-by: Giteabot <teabot@gitea.io>
2026-04-28 01:29:09 +00:00
GiteaBot
596a8868d7 [skip ci] Updated translations via Crowdin 2026-04-28 01:04:43 +00:00
wxiaoguang
c6ffbfe0d2
Rename CurrentRefPath to CurrentRefSubURL (#37453)
Fix a TODO

Co-authored-by: Nicolas <bircni@icloud.com>
2026-04-28 00:34:17 +00:00
wxiaoguang
4952a48b4e
Clean up org pages layout (#37445)
1. Fix overview sidebar regression
2. Remove unnecessary classes and styles
3. Fix "org invite" page
2026-04-27 23:30:27 +00:00
wxiaoguang
89d358d8a7
Fix script error alert (#37458)
After using CSP nonce, the "onerror" doesn't work anymore. Change it to
use a global variable to detect

Also help users like #37379 to catch errors more easily.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-04-28 01:08:50 +02:00
silverwind
6da8027446
Fix inconsistent disabled styling on logged-out repo header buttons (#37406)
Make the watch, star, and fork buttons in the repo header consistent for
logged-out users:

- Apply the same look to all three buttons (number labels
included), instead of only the action button being grayed.
- Clicking any of them while logged out now leads to the login page
(with a redirect back) instead of being inert.
- Split the per-button markup out of `header.tmpl` into a dedicated
`templates/repo/header/` folder (`fork.tmpl`, `star.tmpl`,
`watch.tmpl`).

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-27 17:33:10 +00:00
silverwind
331450b17a
Add API endpoint to reply to pull request review comments (#36683)
Adds a dedicated endpoint for replying to pull request review comments,

```
POST /repos/{owner}/{repo}/pulls/{index}/comments/{id}/replies
{ "body": "..." }
```

The reply is threaded under the same review as the parent comment.

Ref: https://gitea.com/gitea/gitea-mcp/issues/129
Fixes: https://github.com/go-gitea/gitea/issues/37419
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-27 08:45:59 +00:00
wxiaoguang
b45be5b20d
Add CurrentURL template variable back (#37444)
Because some custom template users need it, also add a new test and
comments
2026-04-27 14:19:46 +08:00
silverwind
73d7f6867a
Address Copilot review on attachSearchBox
- hide() also cancels the pending debounced search so a fetch scheduled
  before blur/Escape/outside-click does not fire afterwards and re-show
  the dropdown on a field the user has already left
- use urlQueryEscape for the {query} substitution to keep escaping
  symmetric with the Go backend (matches Go's url.QueryEscape: space → +,
  strict RFC 3986 for !'()*); both decoders still accept %20

Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-27 02:08:02 +02:00
silverwind
6b7c386452
Simplify attachSearchBox and restore the CSS comment
- collapse the render/keydown/select helpers (replaceChildren with mapped
  array, inline ArrowUp/Down branch, drop the move() helper)
- abort the in-flight fetch from hide() so Escape/blur/outside-click
  cancel the request, and gate the post-await render on
  ctrl.signal.aborted to suppress responses that settle after hide()
- rename idx → index
- restore the leading comment in web_src/css/modules/search.css that an
  earlier commit on this branch dropped

Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-27 01:37:51 +02:00
silverwind
a9a2e6085f
Apply suggestion from @silverwind
Signed-off-by: silverwind <me@silverwind.io>
2026-04-27 01:06:02 +02:00
silverwind
dbe3328e6a
Extend e2e test to verify selected user lands in collaborator list
After clicking the search result, the test now also clicks Add
Collaborator and asserts the username appears in the page body
(i.e., in the collaborator list after the redirect), proving the
chosen result drives the form submission end-to-end.

Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-27 00:51:58 +02:00
silverwind
5859380a12
Convert search box to imperative attach API
- attachSearchBox(el, url, parse) replaces the await-style chooseFromApi
- The component handles input update + change-event dispatch on
  selection, so callers don't loop or write back the value themselves
- Each caller is now a single statement; response shape is conveyed via
  the parse callback's parameter annotation (T inferred)

Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-27 00:44:53 +02:00
Copilot
45b4fffae4
refactor: use named Permission field in Repository struct instead of anonymous embedding (#37441)
The `Repository` struct in `services/context/repo.go` embedded
`access_model.Permission` anonymously, causing all permission methods to
be promoted directly onto `Repository`. This made it unclear at call
sites whether a method belonged to `Repository` itself or to its
embedded `Permission`.

### Changes

- **`services/context/repo.go`**: Replace anonymous
`access_model.Permission` with named field `Permission
access_model.Permission`
- **49 files** updated to route permission method calls through the
named field:

```go
// Before
ctx.Repo.IsAdmin()
ctx.Repo.CanWrite(unit.TypeCode)
ctx.Repo.CanReadIssuesOrPulls(isPull)
slices.ContainsFunc(unitTypes, ctx.Repo.CanWrite)

// After
ctx.Repo.Permission.IsAdmin()
ctx.Repo.Permission.CanWrite(unit.TypeCode)
ctx.Repo.Permission.CanReadIssuesOrPulls(isPull)
slices.ContainsFunc(unitTypes, ctx.Repo.Permission.CanWrite)
```

Methods defined directly on `*Repository` (`CanWriteToBranch`,
`CanCreateBranch`, etc.) are unchanged.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <2114189+wxiaoguang@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-04-26 20:18:28 +00:00
silverwind
26cdb902c9
Tighten search-box types, expand test prefix, drop stale CSS comment
- chooseFromApi is now generic over the response shape; each caller
  declares a typed *SearchResponse, removing four `any` annotations
- e2e test prefix: rc- → repo-collab- for legibility in the test DB
- web_src/css/modules/search.css: drop the stale leading comment

Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-26 21:16:32 +02:00
silverwind
4fd1adee5f
Expand rc- prefix to repo-collab- for clarity
Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-26 21:08:07 +02:00
silverwind
fae5d792f4
Rename test var target to userName for clarity
Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-26 21:07:19 +02:00
silverwind
2ecee0bb0a
Refactor search-box module to await-style chooseFromApi
Move web_src/js/modules/fomantic/search.ts to web_src/js/modules/search.ts
(no Fomantic dependency anymore). Replace the imperative
initSearchBox(el, opts) with chooseFromApi(el, url, parse) that returns
a Promise<SearchResult> resolving with the user's chosen item; callers
loop with `while (box.isConnected) { const pick = await ...; ... }` and
own writing back to whatever input/state they manage.

Cleanup is via a single AbortController whose signal is passed to all
listeners; the in-flight fetch has its own controller so a new keystroke
can cancel just the request without tearing down listeners.

Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-26 21:05:36 +02:00
wxiaoguang
55c9b936cb
Refactor pull request view (3) (#37439)
Move some complex logic to backend

Rename `pr.CanAutoMerge` to `pr.IsStatusMergeable`
2026-04-26 19:03:41 +00:00
silverwind
cfe9e70e3e
Trim e2e to a single minimal collaborator-search test
Three boxes (repo/user/team) all share the same first-party module, so
one happy-path test on the user box is sufficient as a regression
gate. Drops the org/team helpers in tests/e2e/utils.ts that only those
extra tests motivated.

Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-26 20:51:47 +02:00
silverwind
77f78076fe
Replace Fomantic search module with first-party autocomplete
Drops the 1565-line vendored Fomantic UI search jQuery plugin in favor
of a small first-party TypeScript module covering the three call sites
(repo, user, and team autocomplete). Adds an e2e regression suite that
exercises each search box.

Also fixes input/button vertical alignment in the four forms that wrap
a search box: the fomantic-era `tw-align-middle` workaround is replaced
by `flex-text-block` on the form, which is the codebase's standard
flex helper for this layout.

Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-26 20:43:58 +02:00
Nicolas
29c510ef94
Update 1.26.1 changelog in main (#37442)
Signed-off-by: Nicolas <bircni@icloud.com>
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-26 20:05:35 +02:00
wxiaoguang
068b59aa97
Make GetPossibleUserByID can handle deleted user (#37430)
Make sure deleted user won't cause 500 error, simplify the caller's code
2026-04-26 16:57:53 +00:00
wxiaoguang
2f42c8cf72
Fix fetch action redirect (#37437)
And add tests for its behavior
2026-04-26 16:37:03 +00:00
Copilot
2671b997f2
Refactor integration test DecodeJSON calls to use generic return value (#37432)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <2114189+wxiaoguang@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-26 14:57:07 +00:00
silverwind
99cd4f6b22
Integrate renovate bot for all dependency updates (#37050)
Replaces Dependabot with Renovate. The new setup:

- One PR per ecosystem (GitHub Actions, Go modules + Makefile go-tool
pins, npm, Python via uv, Nix flake), opened weekly on Mondays with a
5-day release-age cooldown. Vulnerability PRs ship next-day via daily
cron + Renovate's `vulnerabilityAlerts` schedule bypass.
- All `uses:` action refs SHA-pinned with patch-level version comments
(same format as #36971, which this supersedes);
`helpers:pinGitHubActionDigests` keeps future bumps in that format.
- `renovatebot/github-action` runtime image pinned via the
upstream-recommended `RENOVATE_VERSION` env + magic comment +
`customManagers:githubActionsVersions` preset, so Renovate keeps the pin
updated.
- Custom regex manager tracks the `*_PACKAGE ?= <import-path>@<version>`
lines in `Makefile` (golangci-lint, swagger, actionlint, etc.) and
groups them into the same Go PR via `matchDatasources: ["go"]`.
- Post-upgrade tasks regenerate `assets/go-licenses.json` (`make tidy`)
and the SVG sprite (`make svg`), gated by an env-level command
allowlist.
- Replaces the standalone `cron-flake-updater` workflow — Renovate's nix
manager tracks `flake.nix` inputs and produces the same `flake.lock`
bump PRs on the regular weekly schedule.
- npm and gomod-replace pins live in `renovate.json5` only;
`updates@17.16.3` reads them from there too, so the standalone
`updates.config.ts` is gone and one source of truth covers both tools.

Fixes: https://github.com/go-gitea/gitea/issues/33386
Signed-off-by: silverwind <me@silverwind.io>
Signed-off-by: TheFox0x7 <thefox0x7@gmail.com>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: TheFox0x7 <thefox0x7@gmail.com>
Co-authored-by: Nicolas <bircni@icloud.com>
Co-authored-by: Giteabot <teabot@gitea.io>
2026-04-26 14:25:22 +00:00
wxiaoguang
b3ed4cde9a
Refactor pull request view (2) (#37428)
Follow up #37380

Some code is moved to the place whether it should be.
2026-04-26 13:58:48 +00:00
wxiaoguang
712b3a54b5
Use MarkLongPolling instead of hard-coded route path (#37427) 2026-04-26 11:42:29 +00:00
silverwind
ebf30ac4db
Optimize CI caches (#37387)
Cache includes go, lint and unittests. Integration tests with their
standalone binaries are uncacheable with their current architecture.

Every Go job uses a new composite action (`.github/actions/go-cache`)
that restores and saves the Go module cache, a shared build cache, and
the golangci-lint cache. A `cache-seeder` workflow runs on `push: main`
to pre-populate those slots; PRs read them via GitHub's default-branch
fallback, so the common case is warm from the first commit.

Also dropped `-coverprofile` from `test-unit` (it silently disabled Go's
test result cache), and `-race` from `test-pgsql` and `test-mysql` (kept
on `test-unit` and `test-sqlite`).

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-04-26 10:25:35 +00:00
silverwind
f2a7f6c999
Update AGENTS.md (#37420)
`make test-sqlite#TestName` was much too slow, suggest `go test`. Also
added a similar instruction for js tests.

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: Nicolas <bircni@icloud.com>
2026-04-26 12:00:48 +02:00
github-actions[bot]
9e0f692f28
Update Nix flake (#37425)
Automated changes by the
[update-flake-lock](https://github.com/DeterminateSystems/update-flake-lock)
GitHub Action.

```
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/4bd9165' (2026-04-14)
  → 'github:nixos/nixpkgs/0726a0e' (2026-04-22)
```

### Running GitHub Actions on this PR

GitHub Actions will not run workflows on pull requests which are opened
by a GitHub Action.

**To run GitHub Actions workflows on this PR, close and re-open this
pull request.**

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-04-26 11:46:48 +02:00
GiteaBot
d19f653479 [skip ci] Updated translations via Crowdin 2026-04-26 01:04:13 +00:00
TheFox0x7
3e0b99da3b
remove excessive quote from terraform instructions (#37424)
fixes: https://github.com/go-gitea/gitea/issues/37423
2026-04-26 00:59:58 +02:00
Copilot
9b9fb95559
Improve testing init, clean up webhook tests (#37412)
Avoid webhook test fixtures affect other tests (be triggered)

Also fixed more testing problems including path init, global config
pollution & conflict

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <2114189+wxiaoguang@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
2026-04-25 18:55:18 +00:00
silverwind
24b60f8ff9
Fix color regressions, add priority color (#37417)
- fix markup attention block regressions on 2 colors
- added new color "priority" color for important severity in markup
- all message-box style, and error form elements use monochrome text
- tweaked and improved action logs colors

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-25 19:08:10 +02:00
GiteaBot
683f8c0014 [skip ci] Updated translations via Crowdin 2026-04-25 00:56:33 +00:00
silverwind
0277e3ebaa
Stabilize e2e logout propagation test (#37403)
The `events › logout propagation` e2e test ([example
flake](https://github.com/go-gitea/gitea/actions/runs/24878089698/job/72839454932))
was racing the SSE connection setup: if page2's SharedWorker had not
finished registering its messenger by the time page1 triggered logout,
the event was silently dropped and page2 stayed on the authenticated
page.

Wait 500ms after verifying page2 is signed in, before triggering the
logout from page1, so the SharedWorker has time to register. Comment
points at a cleaner future fix (expose a ready attribute on the page)
that will also work for the planned WebSocket SharedWorker.

---
This PR was written with the help of Claude Opus 4.7

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-24 15:37:01 +00:00
Copilot
c5c9713ed4
refactor: serve site manifest via /assets/site-manifest.json endpoint (#37405)
Slightly reduce the page size for every request, and don't need to use `href="data:`

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: wxiaoguang <2114189+wxiaoguang@users.noreply.github.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-24 13:00:59 +00:00
Sai Asish Y
6826321570
feat(security): set X-Content-Type-Options: nosniff by default (#37354)
Fixes #37316.

---------

Signed-off-by: SAY-5 <SAY-5@users.noreply.github.com>
Co-authored-by: SAY-5 <SAY-5@users.noreply.github.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-04-24 11:21:34 +00:00
wxiaoguang
1483291a87
Refactor pull request view (1) (#37380)
Refactor preparePullViewPullInfo and related functions, split them into
small ones:

* preparePullViewPullInfo creates PullRequestViewInfo struct
* if the PR is merged: prepareView**Merged**PullInfo
* if the PR is open: prepareView**Open**PullInfo

In prepareViewMergedPullInfo and preparePullViewFillInfo: call
preparePullView**FillInfo** consistnently

preparePullViewFillInfo calls preparePullViewFill**CompareInfo** and
preparePullViewFill**CommitStatusInfo**
2026-04-24 10:24:41 +00:00
silverwind
de99b1fbbf
Improve AGENTS.md (#37382)
Adds points to `AGENTS.md` how to run single tests because AIs get these
wrong too often (either they trigger the whole suite or run into other
errors).

---
This PR was written with the help of Claude Opus 4.7

---------

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-24 09:49:20 +00:00
silverwind
58a1330078
Remove dead CSS (#37376)
Removes CSS rules that have zero usages across templates, Go source,
JS/TS/Vue, and `options/`. Each selector was cross-checked for runtime
additions (Fomantic JS, library classes) before removal.

A few rules with no current usages are kept as symmetric pairs of
heavily-used classes likely to be needed:
- `.ui.bottom.attached.header` / `.ui.bottom.attached.message` — pair
with the widely-used `top.attached` variants
- `.ui.warning.header` / `.ui.warning.segment` — warning-themed variants
of error-themed classes that are kept
- `.btn.small` — size variant alongside the kept `.btn.tiny`

---
This PR was written with the help of Claude Opus 4.7

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
2026-04-24 09:45:16 +00:00