Repository navigation
Tweaks: per-site looks and code, an editor over the page, the Library's list and the switch for all of them (BO) - #30
Conversation
…o the site controls panel Modules named *.site-controls.tsx that export a SiteControlsSection are collected at build time and rendered between the panel's built-in sections by their order (Permissions 20, Devices 30, Picture in Picture 40, Zoom 50). Tweaks (BO-14) and the extensions lane use it (D37). Documented at its definition. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…main The shared model, page sheets before first paint, the editor panel's view and its first controls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… Tweaks apply before first paint (BO-01, BO-02, BO-18) - Entry points: command bar (New Tweak…, also "customize"), the sidebar's + menu, the site controls panel, a paintbrush in the address field and the tab's menu (Tweak this Site…). Internal pages and error pages take none; the actions say why. - The editor is a small view of its own over the page's top-right corner, sized to the panel, draggable by its title and kept inside the page; Esc, ✕ and Done close it and give the page the keyboard back. A Tweak the panel made and left empty goes with it. - The page preload asks main for the site's sheets before first paint (D40); main swaps in its own insertCSS copies at document ready and keeps them in line with every edit. - e2e: tests/e2e/tweaks.spec.ts, with a frame-capture test that no frame shows the page without its Tweak. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…us; tab menu key hint from the tweaks lane - ARCHITECTURE §10: orbit-page:tweak-sheets (BO-18), its own block beside the pages lane's channels; the JavaScript Tweak line says where Tweak scripts run (main, document ready). - feature-status: BO-01 built, BO-02 and BO-18 partial, with notes; FEATURES.md regenerated. - The tab menu's "Tweak this Site…" key hint (KS-18) comes from src/main/tweaks/menu.ts and is joined at the tab menu's call site, so keys' TAB_MENU_KEYS stays as main has it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es (BO-11, BO-14, BO-17, BO-21) - BO-11: a code area in the Tweak editor with CSS and JavaScript tabs, a home-grown code editor (text field over a coloured copy, line numbers, Tab/Shift+Tab, Enter keeps indentation, the platform's own undo). Typed CSS reaches the page in about 0.1 s. JavaScript runs from main at document ready, once per load, in the page's main world; "Run now" and "Reload page" buttons. Editing JavaScript never allows it; JavaScript from elsewhere waits for "Allow". Errors go to the page's console. - BO-14: each Tweak has its own switch in site controls; the paintbrush turns the site's Tweaks off and on. - BO-17: "Also apply to subdomains" (not for IP hosts; fixed when edited from a subdomain page), every profile, private windows get CSS and, only when the Tweak allows it, JavaScript. - BO-21: the command bar finds Tweak actions by "customize", "customization" and "site style". Tests without the fix (D18): - no flush before closing: a fresh Tweak's typed CSS is lost (received undefined) - auto-allow on a JavaScript edit: jsAllowed became true - private-window check skipped: the script ran in a private window - subdomain box not fixed: toBeDisabled failed Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nts, case, Hide-element mode, name menu and Shuffle (BO-03 to BO-10, BO-12, BO-13) - Colour area (BO-03 to BO-06): a hue wheel with a big handle and an accent handle on its rim, intensity, invert (media keep their colours), contrast, brightness and saturation sliders; wheel edits go to main once a frame. - Fonts (BO-07): presets as system font stacks (nothing bundled), never on icons or code; text size (BO-08), separate from page zoom; text case (BO-09). - Hide-element mode (BO-10): the picker runs in isolated world 1040, outlines what is under the pointer and picks on a click the page never sees; "Hide this" and "Hide all similar" (narrow to broad, counted and outlined) save plain CSS; Esc steps back (pick, mode, editor); restore markers in the panel. - Title menu (BO-12, BO-13): Rename…, Shuffle, Reset all edits… (asks first). - The name drags the panel too past 4 px; Hide elements and Code share one row. Tests: tweaks-look.spec.ts (6), tweaks-hide.spec.ts (3), unit tests for the hidden list, reset and Shuffle. BO-03 is measured against the page changing the same colours itself: under xvfb 60/s at 1024x768; at 1440x900 the page manages ~35/s itself and the drag matches it. Without each fix the test fails (D18): - big handle wins near the rim handle: hue stayed 140 degrees off - Esc steps back (pick, mode, editor): the hint was gone, the editor closed - fonts skip icons and code: the icon and the code took the preset - media keep their colours: the photo was off by 135 - the name drags past a slop: dx 0, dy 0 - Esc in rename keeps the panel: the panel closed Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-15, BO-16, BO-21 View Tweaks) - BO-15: a Tweaks section in the Library lists every Tweak on this device by site, a site's oldest first: name, site (and "and its subdomains"), a JS badge (struck through where it may not run here) and a switch that turns it off or on at once. Right-click or the row's ⋯ opens the Library's own menu: Edit, Open Site, Rename… (in place) and Delete… (asks; its styles leave open pages at once). Edit and Open Site show a tab of the site in the Space, else open a new one where the Tweak was made; Edit opens the editor once that page can take it. Keys: up/down/Home/End, Enter edits, Space switches, F2 renames, Delete asks, Shift+F10 opens the menu. With no Tweaks, a short explanation and Tweak This Site. - A Tweak now keeps the origin it was made on (scheme, host and port) for Open Site; older ones get https://host (http for localhost and IP hosts). - BO-16: Settings → Advanced, "Apply Tweaks on websites I visit" (on by default). Off, pages lose their Tweaks at once, the editor closes and the entry points go or say so; the Library says so with Turn On. Each Tweak keeps its own on or off. - BO-21: View Tweaks in the command bar (also "view customizations"). Hook in another lane's file: settings/sections/advanced.settings.tsx renders <TweaksSetting /> and adds its search keywords. Tests: tweaks-library.spec.ts (4); unit tests for the list order and the kept origin. The fixtures' home page can answer late, as a slow server does. Without each fix the test fails (D18): - Edit waits until the page can take the editor: on a tab still waiting for its server, no editor opened (placed stayed false) - the site's tab is reused: the editor opened on a new tab, not the news tab - Esc in the row menu stays in it: Esc closed the Library (data-open false) - the origin is kept: it was https://shop.lib.test, not http://shop.lib.test:3370 Rerun for BO-18 (item 1): without the preload's sheets, the page's first frame was white (#ffffff at 132 ms) before the Tweak's dark. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 33551c62-d75d-409f-b4c1-4f4607da3e11) |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… retired by a message (D85); Hide mode holds; scripts check their host Must-fixes 1 and 2 (D85): - The page preload inserts the first-paint sheets with webFrame.insertCSS (author origin) and keeps their keys in its own world (src/preload/tweak-sheets.ts); nothing goes into document.adoptedStyleSheets. - Main's answer carries a number for the document's read; once main's own copies are in, it sends orbit-page:tweak-retire with that number to the main frame and never waits. The preload removes its sheets only for its own document's number. - No change to a page's Tweaks waits on a script any more, so changes show while it loads. TWEAK_SHEET_MEDIA and the world-1040 retire are gone. - ARCHITECTURE lists the new message and drops the "until document ready" limit. Follow-ups: - F1: Hide mode blocks presses and clicks at the window (capture), puts its layer back when the page takes it out, and ends (telling main) when the page keeps doing so. - F2: a JavaScript Tweak checks location.hostname against its host (or a subdomain, when ticked) as it starts. - F9: "Hide all similar" shows "n (m shown)" when fewer of the matches show on the page. Tests: R1-R3 shapes (head read, own adopted sheets, layered !important), R9 shape (off, on, edit, switch for all while an image holds the load), the retire's document number (unit), the script's host check (unit), the removed and covered layer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: cc366263-0c43-4f92-a95b-d7bfd8e614a1) |
…say why in the browser window; Edit never takes a floating page (review F7) - target() refuses a Mini Window's window or tab, as it does a Peek's, with a note in a browser window (a Mini Window shows none); tweaks.create with a Mini Window's tab makes nothing. - The Mini Window lets the Tweak actions reach their handlers: View Tweaks opens the Library in the browser window behind, the others say why. - The Library's Edit and Open Site skip floating (Peek and Mini Window) tabs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s, and says why (review F8) whenTweakable ends as soon as the tab's page fails to load (the tab runtime's error) or the tab goes, not after its 20 s wait; Edit then notes that the site didn't load. Tested with a home page that drops the connection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…not numbers of their own (review F6) Reduced motion keeps its rules. A unit test reads the Tweak stylesheets: every animation and transition is timed by a token. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ve (review F5) At 1440x900 under xvfb the page itself recolours only ~35 times a second, so the rate alone can't tell an editor that applies every move from one that applies every other. Main took 60 edits for 60 moves; a half-rate stand-in in useStyleEdits gives 30 and fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…round 1 (review F3, F4) BO-02, BO-14 and BO-16: changes show at once while the page loads too; what a Tweak's JavaScript already did stays until the next load (also in Settings). BO-18: injected sheets the page can't read, remove or outrank, retired by a document-numbered message; scripts check their host. BO-10: the picker holds while the page fights its layer; "n (m shown)". BO-01, BO-15, BO-21: a Mini Window's page takes no Tweak; Edit on a site that doesn't load says so. BO-03: main takes an edit per move. FEATURES.md regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 3f95c9a0-5ba4-4ded-b5a9-18f1e2514a58) |
… late key goes back only to its own renderer (fix check must-fix 1) A Tweak change waited on insertCSS, which never settles where the page's renderer crashed, or where another site's page took its place while it was busy: the tab then took no change again. Each document now has an end that answer() (a new document), render-process-gone and destroyed settle, and its passes stop waiting then. A key that comes back late is removed only where the renderer that gave it (main frame processId and routingId when the insert was sent) still holds the page: keys count 1, 2, ... in each renderer. Tests: tweaks-page-sheets unit test; tweaks.spec.ts N5 (crash and reload) and N6 (another site) shapes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…that it is starting (D89) A click on the lightning button while the page is still loading now shows the mode starting at once: the button pressed, and the panel's line saying it starts when the page has loaded. Main waits for the load itself and sends the picker to world 1040 only then; Done, Esc or another document cancels the start, and the picker never goes in. The picker's header also says that the page's own capture listeners on its window, added before the mode started, still hear presses and clicks first (fix check follow-up 2). Test: tweaks-hide.spec.ts, with an image the fixture holds until released. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… (D89) and what the page's own window listeners still hear; BO-21, BO-01 and KS-20 say what Tweak keys do from a Mini Window (fix check follow-ups 1-3) Regenerated FEATURES.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…here, and late keys go back only to their renderer; the Hide picker on a page still loading (D89) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… begun before the click brings (D89) A click while a navigation is pending showed the mode starting, and the picker then went into the new document once it loaded. Another document ends a start, as it ends the mode, and main checks the page still takes Tweaks before it sends the picker. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…animation is done The panel opens with a scale from 0.97 on the snappy token; measured during it, the panel looked up to 2.1 px shorter than the view sized to it, and the check failed 2 of 4 runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: f5407e28-6acf-4bb7-a76a-12f1e6742d59) |
Conflicts, each keeping both sides: - src/main/tabs/commands.ts imports: the Tweak menu items and keys, and registerBlankWindows / registerLinkDrop. - src/shared/rpc.ts imports: TweakCommands, TweakEvents and WindowMaterial. - docs/ARCHITECTURE.md: main's paragraph on scripts in pages (shortcuts that count as gestures, DevTools) with this lane's sentence on the Hide picker's world 1040 (D89). - FEATURES.md: regenerated (472 features). docs/feature-status.json merged without conflict: no row changed on both sides; 385 keys, no duplicates, 115 feel marks. The tab's menu is now finish-tabs' row menu in the overlay (TB-14), so the Tweak tests read and choose it through rowMenu / chooseRowMenu, and check the key hint the overlay draws beside "Tweak this Site…". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…brary opens; Esc in the page cancels Hide's start (D89 (5)) - say(), from a Mini Window, picks the window View Tweaks' Library would (mainWindowOf): the focused browser window that isn't private, else the last one; never a private window opened after it (fix check 2, follow-up 1). - While Hide-element mode starts on a page still loading, an Esc pressed in the page cancels the start, as the panel's does; main sees it in before-input-event, and the page still gets it (D89 (5); fix check 2, follow-up 2). BO-10's note says so. - Tests: "Tweak this Site…" chosen in a row's overlay menu, by a click or Enter, leaves the keyboard in the editor (F9); the note from a Mini Window in front of a private window; Esc in the page while the mode starts; a late key from a busy page's renderer never takes a sheet of the page that replaced it (N9, follow-up 3). Fixtures: /busy pages and a frame log on /page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…weak, not every one Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t for its address The address could still read the other site's page before the busy one came in, so the test could take the busy page for the one that came back and lose its context as it went back. It now waits for a new document of that page that has noted its first frame. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 66363c35-dec7-4a2e-be94-ef1e11350a21) |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FEATURES.md conflicted (generated); regenerated with scripts/features.mjs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FEATURES.md regenerated; docs/feature-status.json merged without conflict. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tweaks lane builds Tweaks (D36): per-site changes to how a site looks and behaves. They're made in a small editor over the live page and applied before the page's first paint.
It's built from
lanes/tweaks.mdonmainat62f6fd6. Since then it has merged pages (PR #27, at1ccdbad), the sign-off marks (PR #28, at73eb3f9), PR #29 (atd2e22b1) and finish-tabs (PR #31, at8d3201a);mainis21487aa. Againstmainit changes 62 files (+11765/−43). The builder stopped after item 4, near D30's 9k lines, so item 5's BO-19 and BO-20 are left.The reports are in the project's context folder:
reviews/lane-tweaks-report.mdfor the lane, andlane-tweaks-fix1-report.md,-fix2-report.mdand-fix3-report.mdfor the three fix rounds.What it builds
e1bd19d), so other features can add rows to the panel. The extensions lane uses it next.The page preload (D40, D85)
Two channels, each with its D40 (4) entry in
docs/ARCHITECTURE.md:orbit-page:tweak-sheets: a synchronous read before the page's first paint. The message carries nothing. Main answers from the sending frame's own URL, with the CSS of the Tweaks that are on for that host, and a number for this document's read. It answers only:http:orhttps:.webFrame.insertCSS,src/preload/tweak-sheets.ts), and keeps their keys in its own world. So the page can't read or remove them, and the Tweak's layer comes first, so the page's!importantrules don't outrank it. There's no global.orbit-page:tweak-retire(main → page): once main's own copies are in, it tells the preload to take its sheets out. It carries only the document's number, and main never waits for it, so a late one can't touch a newer document's sheets.Decisions where the spec was unclear
https://host, orhttpfor localhost and IP hosts.tweaks.setGlobalcommand. While Tweaks are off, the row switches stay usable, dimmed.Edits in other lanes' files
Each one is small and additive:
page.ts: the D40 block, with the newtweak-sheets.tsmodule;state.ts: the Tweak fields;defaults.ts,persist.ts,actions.ts,rpc.tsandsite.ts.tabs/menus.tsandtabs/commands.ts: Tweak this Site… and its key hint, now in finish-tabs' overlay row menu;Address.tsx: the paintbrush;SpacePanels.tsx: the + menu;miniwindow/index.ts: the Tweak actions reach their handlers from a Mini Window (KS-20);main.tsx.advanced.settings.tsx:<TweaksSetting />and its keywords.1ccdbad, and the Tweak channel is a block of its own.8d3201a): the tab menu's imports and keys,rpc.ts, and ARCHITECTURE.md's page-scripts paragraph. The Tweak specs now use finish-tabs' overlay row menu, and F9's test checks that "Tweak this Site…" from a row menu leaves the keyboard in the editor.Merge gate (D42, local)
Gate r2 ran on this exact head,
86dcc5e, on the VPS (Linux, under Xvfb), from 23:51 to 00:39 (10-12) UTC. The lead ran it with the gate script:e2e exit 0. Load average 14.2 at the start, 3.1 at the end.3f6bad0(the head the review read): 786 passed, 1 failed, 2 skipped (44.0 min). The failure,import-file.spec.ts:151[IM-13], passed when rerun alone: the import window closed while Playwright was still finishing its Cancel click.Review
reviews/lane-tweaks.md), both reproduced, with the fix prototyped:document.adoptedStyleSheets, so the page's own scripts could read the user's CSS, drop the sheets (2 of 3 first frames then lacked the Tweak), and outrank them with layered!importantrules.webFrame.insertCSS, and main retires them with one message that carries only a document number and is never awaited. D86 keeps BO-10's restore markers in the panel.46a87d9): both must-fixes by D85. A Tweak turned off on a loading page now shows in 6–17 ms, where3f6bad0took 7.9 s. Follow-ups F1–F9: Hide mode holds against the page, scripts check their host, the notes say only what's true, BO-03's drag test counts main's edits, FL-01's motion tokens, a Mini Window's Tweak keys, the Library's Edit on a failed load, and Hide all similar's count. Each code fix's test failed on3f6bad0.reviews/lane-tweaks-fixcheck.md). Both D85 fixes behaved as the reviewer's prototype did, and each cut failed its test.3f6bad0: aninsertCSSthat never answers (after a crash, or when another site's page replaces a busy one) left the tab's sync busy, so no later Tweak change showed in that tab. A late answer also sent a removal to the new page's renderer.db7354c): each document's wait also ends on a new document, a gone renderer or closed contents, and a late key goes back only to its own renderer. D89's start shows at once. Each fix's test fails without it.reviews/lane-tweaks-fixcheck2.md). After a crash or a navigation the next change shows, a late key never reaches the new renderer, and no wait is left. Its follow-ups:80748acto86dcc5e, aftermainwas merged in at8d3201a): all three follow-ups and F9's test, each failing without its fix (reviews/lane-tweaks-fix3-report.md).reviews/lane-tweaks-fix3-check.md). The lead built none of this lane.🤖 Generated with Claude Code
Note
Medium Risk
Introduces early CSS injection and optional user JavaScript in web pages; safeguards exist (global toggle, JS allow/import gates, main-frame-only, private-window option) but the attack surface and persistence path are materially larger.
Overview
Adds Tweaks: per-site visual and behavioral customizations edited in a draggable panel over the live page, persisted in app state and reflected in the feature checklist/docs.
Application model: Before first paint, the page preload synchronously fetches Tweak CSS via
orbit-page:tweak-sheetsand injects author sheets; main later replaces them withinsertCSSand retires preload copies viaorbit-page:tweak-retire. Live edits sync sheets while loading; allowed JavaScript runs once per load from main in the page’s main world (not via preload). Hide-element mode uses an isolated-world picker (src/main/tweaks/hide.ts).Product surfaces: Command bar, tab menu (“Tweak this Site…”), address paintbrush, sidebar + menu, site-controls registry sections, Settings → Advanced global toggle, and Library Tweaks list. Mini Windows forward Tweak actions to the browser window behind them (KS-20). State load uses
normalizeTweaks/normalizeTweakSettings.UI: New
tweakrenderer view (TweakEditorApp) with colour wheel, fonts, size/case, code editor, hide UI, etc. BO-19 (Space theme colours in CSS) and BO-20 (export/gallery) remain unbuilt; BO-07 fonts are partial (system stacks only).Reviewed by Cursor Bugbot for commit 86dcc5e. Bugbot is set up for automated code reviews on this repo. Configure here.