Skip to content

fix(wallpaper): bot-fix v2 — Kilo 1S + CodeRabbit 6 findings (supersedes #1902)#1982

Merged
jaylfc merged 5 commits into
jaylfc:devfrom
hognek:fix/wallhaven-bot-fixes
Jul 18, 2026
Merged

fix(wallpaper): bot-fix v2 — Kilo 1S + CodeRabbit 6 findings (supersedes #1902)#1982
jaylfc merged 5 commits into
jaylfc:devfrom
hognek:fix/wallhaven-bot-fixes

Conversation

@hognek

@hognek hognek commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Task: t_cc32e61b. Supersedes #1902.

Changes

All 7 bot findings in one commit (7a5cb34):

Kilo SUGGESTION

  • wallhaven.py:19 — Add max_length=200 on q and sorting params, validate sorting against known Wallhaven values

CodeRabbit MAJOR/MINOR

  1. WallhavenBrowser.tsx:43useRef<ReturnType<typeof setTimeout>>(undefined) fixes React 19 typings
  2. WallhavenBrowser.tsx:85 — Recheck cancelled after resp.json() to prevent stale error overwriting active state
  3. WallhavenBrowser.tsx:113 — Pass img.path (direct image) not img.url (details page) to onSelect. Fixtures swapped in both backend test and desktop test
  4. WallpaperPicker.tsx:229 — Move WallhavenBrowser into Online section's overflow-y-auto panel instead of shrink-0 footer
  5. config.py:182 — Read WALLHAVEN_API_KEY before missing-file branch so fresh installs pick it up. Both config paths now receive the key
  6. wallhaven.py:61 — Replace client.get() + resp.content with client.stream() + aiter_bytes() to enforce 1MB limit incrementally

Test additions

  • test_config.py: 2 new tests for WALLHAVEN_API_KEY on fresh install + existing config
  • test_wallhaven.py: 4 new tests (invalid sorting, valid sorting forwarded, query max_length, empty query allowed)
  • WallhavenBrowser.test.tsx: url/path fixture swap

Test results

  • Config tests: 2/2 new tests pass
  • Wallhaven test: test_search_returns_results passes (async fixture teardown hang is pre-existing in conftest, observed on unmodified code too)

hognek added 3 commits July 18, 2026 11:21
…tion

- Add wallhaven_api_key config field (env-only, never in repo)
- Create GET /api/wallhaven/search proxy route to wallhaven.cc API
- Keyless by default; optional X-API-Key header when WALLHAVEN_API_KEY set
- Handle rate limiting (429), timeouts (504), and Wallhaven errors (502)
- New WallhavenBrowser component: debounced search, thumbnail grid, pagination
- Integrate WallhavenBrowser into WallpaperPicker as collapsible section
- WallpaperPicker: "Browse online" toggle expands search UI, selecting a
  Wallhaven image applies it as a remote wallpaper
- Backend tests (test_wallhaven.py, 12 tests) with respx mocking
- Frontend tests (WallhavenBrowser.test.tsx, 8 tests; WallpaperPicker 14 tests)

Fixes jaylfc#864
…NResponse, validate categories/purity, move os import

- Escape single-quotes and backslashes in remote wallpaper URLs to prevent
  CSS injection and render breakage (WallpaperPicker.tsx onSelect).
- Route through a state updater that sets wallpaperIdByTheme, and include
  light/mobile/fallback variants so theme switch preserves remote wallpapers.
- Use the received label as wallpaperOverlayText instead of discarding it.
- Guard resp.json() with try/except ValueError and cap response at 1 MB
  (wallhaven.py:71).
- Validate categories/purity with ^[01]{3}$ before forwarding to Wallhaven.
- Move import os as _os from inside load_config to module top (config.py).
…aven

- wallhaven.py: add max_length=200 on q/sorting params, validate sorting
  against known Wallhaven values, use client.stream() + aiter_bytes()
  to enforce 1MB limit incrementally (CR6)
- WallhavenBrowser.tsx: init useRef with undefined (React 19, CR1),
  recheck cancellation after resp.json() (CR2), pass img.path not
  img.url to onSelect (CR3)
- WallpaperPicker.tsx: move WallhavenBrowser into Online section's
  scrollable panel instead of shrink-0 footer (CR4)
- config.py: read WALLHAVEN_API_KEY before missing-file branch so
  fresh installs pick it up (CR5)
- tests: swap url/path fixtures to match real Wallhaven API, add
  sorting validation + max_length + api_key fresh-install tests
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@hognek, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 14 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 6eda8eaf-d873-4371-8d11-7a66b8221d2c

📥 Commits

Reviewing files that changed from the base of the PR and between 0e6e6fa and 77e8f4c.

📒 Files selected for processing (9)
  • desktop/src/components/WallhavenBrowser.test.tsx
  • desktop/src/components/WallhavenBrowser.tsx
  • desktop/src/components/WallpaperPicker.test.tsx
  • desktop/src/components/WallpaperPicker.tsx
  • tests/test_config.py
  • tests/test_wallhaven.py
  • tinyagentos/config.py
  • tinyagentos/routes/__init__.py
  • tinyagentos/routes/wallhaven.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hognek
hognek marked this pull request as ready for review July 18, 2026 09:49
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@gitar-bot

gitar-bot Bot commented Jul 18, 2026

Copy link
Copy Markdown

Gitar is working

Gitar

},
}));
}}
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CRITICAL: JSX tags are unbalanced — this file will not compile.

<WallhavenBrowser /> is self-closed here, but its wrapper <div className="pt-2"> (line 198), the {browseOnlineOpen && ( group (line 197), and the {section.id === "online" && ( group (line 181) are never closed. Lines 227–231 emit more closing tags (</div>, )}, </div>, </div>, ))}) than were opened inside this section, so the pt-2 div and both && groups are left unterminated. This is a fatal TSX parse error (Expected corresponding JSX closing tag) that breaks the entire WallpaperPicker module and the desktop build.

Before the section's closing </div>/))}, the inner block must close in order: </div> (for pt-2), ) (for browseOnlineOpen &&), ) (for section.id === "online" &&).

Comment thread tinyagentos/routes/__init__.py Outdated
app.include_router(receipts_router, dependencies=_csrf)

from tinyagentos.routes import wallhaven as wallhaven_routes
app.include_router(wallhaven_routes.router)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: Wallhaven router is registered without the _csrf dependency that every other router in this function uses (e.g. lines 389, 392, 395, 401).

This endpoint is GET-only and acts as a read proxy, so CSRF risk is low, but the inconsistency means the route is unprotected while sibling routes require CSRF. If CSRF protection is meant to be global, include dependencies=_csrf here too for consistency (or document why this route is exempt).

@kilo-code-bot

kilo-code-bot Bot commented Jul 18, 2026

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (9 files)
  • desktop/src/components/WallhavenBrowser.test.tsx
  • desktop/src/components/WallhavenBrowser.tsx
  • desktop/src/components/WallpaperPicker.test.tsx
  • desktop/src/components/WallpaperPicker.tsx
  • tests/test_config.py
  • tests/test_wallhaven.py
  • tinyagentos/config.py
  • tinyagentos/routes/__init__.py
  • tinyagentos/routes/wallhaven.py

Incremental Review (since 09d80ff)

The only change since the previous review is a test-only edit in desktop/src/components/WallpaperPicker.test.tsx (replacing a fragile getByText("Browse online") with getByRole("heading", { name: "Browse online" }) to disambiguate from a same-text toggle button). No new issues found.

Previous findings (WallpaperPicker.tsx:226 JSX balance, init.py Wallhaven router registration) remain resolved at HEAD (77e8f4c).

Previous Review Summaries (3 snapshots, latest commit 09d80ff)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 09d80ff)

Status: No Issues Found | Recommendation: Merge

Both prior findings are resolved by the incremental diff (squash at 09d80ff):

  • CRITICAL desktop/src/components/WallpaperPicker.tsx:226 — JSX imbalance resolved. The <WallhavenBrowser /> block now closes in correct order: </div> (pt-2, L227), )} (browseOnlineOpen &&, L228), </div> (mt-2, L229), )} (section.id online &&, L230), </div> (section container, L231), ))} (map, L232). Module compiles.
  • SUGGESTION tinyagentos/routes/__init__.py — Wallhaven router now registers with dependencies=_csrf (lines 397–398), matching every other router in register_all_routers.

The current HEAD (09d80ff) was reviewed against merge-base e895f71a (8 files, +904 lines). No new issues found in changed lines. Backend (wallhaven.py) validates categories/purity regex, whitelists sorting, enforces q/sorting max_length=200, streams with a 1MB cap, and returns appropriate 4xx/5xx status codes. config.py reads WALLHAVEN_API_KEY before branching and to_dict() correctly omits it so the key is never persisted. Frontend debounces, cancels stale requests, and escapes the CSS url. Tests cover backend validation, key handling, and frontend behavior.

Files Reviewed (8 files)
  • desktop/src/components/WallhavenBrowser.test.tsx - new, no issues
  • desktop/src/components/WallhavenBrowser.tsx - new, no issues
  • desktop/src/components/WallpaperPicker.tsx - prior CRITICAL resolved
  • tests/test_config.py - new tests, no issues
  • tests/test_wallhaven.py - new tests, no issues
  • tinyagentos/config.py - prior-adjacent change, no issues
  • tinyagentos/routes/__init__.py - prior SUGGESTION resolved
  • tinyagentos/routes/wallhaven.py - new, no issues

Previous review (commit 74edc84)

Status: No Issues Found | Recommendation: Merge

Both prior findings from the previous review are resolved by the incremental commits in this run:

  • CRITICAL desktop/src/components/WallpaperPicker.tsx:226 — JSX imbalance is fixed. Current HEAD closes the online block in correct order: </div> (pt-2), )} (browseOnlineOpen &&), </div> (mt-2), )} (section.id online &&), </div> (section container), ))}. The module now compiles.
  • SUGGESTION tinyagentos/routes/__init__.py:398 — Wallhaven router now registers with dependencies=_csrf, matching every other router in register_all_routers.

The incremental diff (7a5cb34..74edc848) only touched these two files, both being fixes to the previous findings. No new issues were introduced in the changed lines.

Files Reviewed (2 files, incremental)
  • desktop/src/components/WallpaperPicker.tsx - prior CRITICAL resolved
  • tinyagentos/routes/__init__.py - prior SUGGESTION resolved

Previous review (commit 7a5cb34)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 1
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

CRITICAL

File Line Issue
desktop/src/components/WallpaperPicker.tsx 226 Unbalanced JSX — the browse-online block leaves <div className="pt-2"> (198) and the two && groups (181, 197) unclosed; lines 227–231 over-close. Fatal TSX parse error, breaks the module and desktop build.

SUGGESTION

File Line Issue
tinyagentos/routes/__init__.py 398 Wallhaven router registered without the _csrf dependency used by every other router here; inconsistent CSRF posture for the new route.
Files Reviewed (8 files)
  • desktop/src/components/WallhavenBrowser.test.tsx
  • desktop/src/components/WallhavenBrowser.tsx
  • desktop/src/components/WallpaperPicker.tsx
  • tests/test_config.py
  • tests/test_wallhaven.py
  • tinyagentos/config.py
  • tinyagentos/routes/__init__.py
  • tinyagentos/routes/wallhaven.py

Fix these issues in Kilo Cloud


Reviewed by hy3:free · Input: 32.5K · Output: 1.4K · Cached: 104.1K

@jaylfc

jaylfc commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Held on a build-breaker. The two correctness bugs from #1902 are genuinely fixed (CSS url() escape at WallpaperPicker.tsx:205, and the wallhaven route now streams with a 1MB cap and wraps json.loads in try/except returning 502), and CR1/CR2/CR3/CR5/CR6 are folded, thanks. But before this can merge:

  • BLOCKER (Kilo CRITICAL, confirmed with esbuild): WallpaperPicker.tsx ~199-230 has unbalanced JSX. The {section.id === "online" && ( block opened around line 199 is never closed with )} - the closing run is missing one )}, so the module fails to compile ("Unterminated regular expression"). This is the CR4 'move browser into the Online section' restructure. Desktop build is broken as-is. Please balance the closer and confirm npm run build (or npx tsc --noEmit + vitest run) passes locally.
  • Minor (Kilo suggestion): the wallhaven router is registered in routes/init.py:398 without dependencies=_csrf unlike its siblings. It is a GET read-proxy so low risk, but add it for consistency.

Heads up on why CI did not catch the build break: this PR's checks are only Gitar/Kilo/cla/CodeRabbit - no desktop typecheck/build/vitest job ran, so green here is not evidence the desktop compiles. Fix the JSX + run the build locally and I will re-review.

…endency on wallhaven router

Remove unbalanced </div> that broke the desktop build after CR4 restructure
(WallhavenBrowser moved into Online section). The .map() callback and p-4
wrapper were missing closing tags; add ))} and </div> to properly close both.

Also add missing dependencies=_csrf on the wallhaven router registration in
routes/__init__.py for consistency with every sibling router.

Docs-Reviewed: wallpaper proxy is a protected internal route, no external API docs needed
@hognek
hognek force-pushed the fix/wallhaven-bot-fixes branch from 74edc84 to 09d80ff Compare July 18, 2026 10:20
…est query

The 'renders section headings for all four sections' test used getByText('Browse online')
which now matches both the section heading (h4) and the browser-toggle button inside the
Online section. Scope the query to getByRole('heading', ...) so it only matches the h4.
@jaylfc
jaylfc merged commit 4adb976 into jaylfc:dev Jul 18, 2026
9 checks passed
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.

2 participants