Skip to content

Comments

feat: Improved Custom Protocol Routing#165

Merged
iamEvanYT merged 15 commits intomainfrom
evan/better-router
Oct 30, 2025
Merged

feat: Improved Custom Protocol Routing#165
iamEvanYT merged 15 commits intomainfrom
evan/better-router

Conversation

@iamEvanYT
Copy link
Member

@iamEvanYT iamEvanYT commented Oct 30, 2025

  • Use hono/tiny for Routing
  • New Standard Domain Resolver
  • Unresolved Domains is now redirected to Error Page
  • Generate individual HTML, JS and CSS for each page to improve performance
  • Replace use-query-params with nuqs
  • Fix settings window flickering on start
  • Fix theme flickering on start

Summary by CodeRabbit

  • New Features

    • Added query parameter state management system for improved URL state handling.
    • Enabled dynamic route generation for multi-view architecture support.
  • Bug Fixes

    • Fixed theme flicker by synchronizing theme application before render.
    • Settings and onboarding windows now properly wait for content load before displaying.
  • Refactor

    • Restructured protocol and routing architecture for improved modularity and maintainability.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 30, 2025

Build artifacts for all platforms are ready! 🚀

Download the artifacts from:

(execution 18951159478 / attempt 1)

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 30, 2025

Warning

Rate limit exceeded

@iamEvanYT has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 3 minutes and 46 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 88ae57c and 98f2c54.

📒 Files selected for processing (8)
  • scripts/frontend-routes-generator/common.ts (1 hunks)
  • scripts/frontend-routes-generator/generator.ts (1 hunks)
  • scripts/frontend-routes-generator/pruner.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/active-favicon.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/extension-icon.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/utils.ts (1 hunks)
  • src/main/controllers/windows-controller/types/base.ts (3 hunks)
  • src/renderer/src/components/providers/nuqs-provider.tsx (1 hunks)

Walkthrough

This PR refactors the application's protocol handling and frontend routing system. It introduces a new frontend route generation infrastructure using Hono, replaces monolithic protocol handlers with modular Hono-based applications, migrates from use-query-params to nuqs for query parameter management, removes route wrapper components, and adds deferred window loading capability.

Changes

Cohort / File(s) Summary
Frontend Route Generation Infrastructure
scripts/frontend-routes-generator/common.ts, generator.ts, pruner.ts
New scripts for generating dynamic route HTML files and main.tsx entrypoints, plus pruning logic to clean up generated assets.
Protocol Handler Refactoring - Flow
src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts, flow/favicon.ts, flow/assets.ts, flow/extension-icon.ts, flow/pdf-cache.ts
Replaces monolithic flow protocol handler with modular Hono-based routes for favicon, asset, extension-icon, and pdf-cache serving; previous monolithic flow.ts removed.
Protocol Handler Refactoring - Flow Internal
src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/index.ts, flow-internal/active-favicon.ts
Replaces monolithic flow-internal protocol handler with modular Hono app; separates active favicon caching and routing logic; previous monolithic flow-internal.ts removed.
Protocol Handler Refactoring - Flow External
src/main/controllers/sessions-controller/protocols/_protocols/flow-external/index.ts
Replaces monolithic flow-external protocol handler with Hono-based app; previous flow-external.ts removed.
Static Domain Routing
src/main/controllers/sessions-controller/protocols/static-domains/index.ts, config.ts, types.ts, serve-static.ts
New infrastructure for serving static files across multiple domains with route-based and subdirectory-based mappings; includes path normalization, traversal protection, and hot-reload development support.
Protocol Type System & Utilities
src/main/controllers/sessions-controller/protocols/index.ts, types.ts, utils.ts
Updated protocol registration to use new CustomProtocol type; added transformPathForRequest utility and ServeStaticFileOptions interface for flexible route handling.
Dependency & Build Configuration
package.json, electron.vite.config.ts, tsconfig.node.json
Added hono and nuqs dependencies, removed use-query-params; new build scripts for route generation/pruning; updated vite config to import and spread commonOptions and configure renderer input with generated routes; removed electron.vite.config.ts from tsconfig includes.
Window Controller Deferred Loading
src/main/controllers/windows-controller/types/base.ts, types/settings.ts, interfaces/onboarding.ts, interfaces/settings.ts
Added deferShowUntilAfterLoad option to BaseWindow; new loaded event and showImmediately() method; made show() async to wait for load completion when deferred; settings and onboarding windows now await show operations.
Renderer Entry Points & Router Removal
src/renderer/index.html, src/renderer/src/main.tsx, src/renderer/src/App.tsx, src/renderer/src/router/*
Deleted root HTML bootstrapping, main React entry, App component, and entire router subsystem (provider, route, README); routes now generated and mounted dynamically.
Query Parameter Migration
src/renderer/src/routes/extensions/page.tsx, pdf-viewer/page.tsx
Replaced useQueryParam from use-query-params with useQueryState from nuqs; extensions page now manages selected ID via query state instead of URL manipulation.
Route Configuration & Component Updates
src/renderer/src/routes/*/config.tsx (about, error, games, main-ui, new-tab, omnibox-debug, omnibox, onboarding, popup-ui, settings), src/renderer/src/types/routes.ts
Removed Fallback: null property from all route configs; removed Fallback field from RouteConfigType interface.
Route Wrapper Component Removal
src/renderer/src/routes/*/route.tsx (about, error, extensions, games, main-ui, new-tab, omnibox-debug, omnibox, onboarding, pdf-viewer, popup-ui, settings)
Deleted all route-level wrapper components that provided RouteConfig.Providers and Suspense boundaries.
Provider & Component Updates
src/renderer/src/components/providers/nuqs-provider.tsx, routes/extensions/config.tsx, routes/pdf-viewer/config.tsx, components/main/theme.tsx
New NuqsProvider component; extended Providers in extensions and pdf-viewer configs to wrap with NuqsProvider; replaced useEffect with useLayoutEffect in theme component for synchronized rendering.
Renderer Gitignore & Utilities
src/renderer/.gitignore, src/main/modules/utils.ts, typed-event-emitter.ts
Added ignore patterns for generated route files; new bufferToArrayBuffer() utility; new waitUntil() method on TypedEventEmitter for promise-based event waiting.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas requiring extra attention:

  • Hono protocol handler architecture & correctness: Verify that request routing, static file serving, path normalization, and security checks (traversal protection) are correctly implemented across flow/, flow-internal/, and flow-external/ handlers.
  • Frontend route generation integration: Review the route generator and pruner scripts for correctness; ensure routes are properly generated before build and cleanly pruned after; verify electron.vite.config.ts correctly awaits and spreads generated routes into renderer input.
  • Query parameter state management migration: Confirm useQueryState from nuqs correctly replaces useQueryParam from use-query-params in extensions and pdf-viewer pages, especially around state persistence and URL synchronization.
  • Window deferred loading logic: Validate that deferShowUntilAfterLoad timing works correctly for settings and onboarding windows; ensure loaded event is emitted at the right point and show() properly waits before revealing windows.
  • Static domain serving & security: Review path validation, traversal checks, and content-type resolution in serve-static.ts to ensure files are served safely across multiple domains.
  • Removal of router & Suspense boundaries: Verify that route composition still works correctly after deleting route.tsx wrappers and Suspense fallbacks; ensure no rendering issues arise from removal.

Possibly related PRs

  • #161 — Updates protocol types (CustomProtocol/Protocols union) and refactors protocol handler registration alongside similar static-domains and session-controller protocol logic.
  • #26 — Refactors custom protocol handlers (flow, flow-internal, flow-external) with domain/static-file routing logic.
  • #29 — Updates electron.vite.config.ts with changes to imports, config structure, and commonOptions handling.

Suggested labels

enhancement

Poem

🐰 Routes now dance in Hono's graceful streams,
Where protocols once monolithic, now modular dreams.
Query params flow through nuqs, so pristine and bright,
Windows defer their curtain calls till load's done right.
Fallbacks fade away, and routers bid adieu—
A refactored flow-browser, reborn anew! 🌟

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.77% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title "feat: Improved Custom Protocol Routing" is partially related to the changeset. The PR does indeed improve custom protocol routing by introducing Hono for the flow://, flow-internal://, and flow-external:// protocols, implementing domain resolution, and redirecting unresolved domains to an error page. However, the title significantly understates the PR's scope by omitting a major objective: the introduction of a frontend route generation system that creates individual HTML, JS, and CSS files for each page. The raw summary shows extensive changes to the renderer including new route generation scripts, removal of the old router system, and migration from use-query-params to nuqs, which are not protocol-routing-related but represent substantial architectural changes that would be important for developers reviewing the PR.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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 and usage tips.

@iamEvanYT iamEvanYT marked this pull request as ready for review October 30, 2025 17:01
@iamEvanYT
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 30, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/renderer/src/routes/extensions/page.tsx (1)

22-22: Race condition: shared isProcessing state can cause inconsistent UI behavior.

The single isProcessing boolean is shared across all extension operations (enable/disable, pin/unpin). If a user triggers multiple operations concurrently—for example, toggling one extension while pinning another—the first operation to complete will reset isProcessing to false, prematurely re-enabling UI controls while other operations are still in flight.

Consider using per-extension processing state instead:

-  const [isProcessing, setIsProcessing] = useState(false);
+  const [processingExtensions, setProcessingExtensions] = useState<Set<string>>(new Set());

Then update the handlers:

  const setExtensionEnabled = async (id: string, enabled: boolean) => {
-    setIsProcessing(true);
+    setProcessingExtensions(prev => new Set(prev).add(id));

    const success = await flow.extensions.setExtensionEnabled(id, enabled);
    if (success) {
      toast.success(`This extension has been successfully ${enabled ? "enabled" : "disabled"}!`);
    } else {
      toast.error(`Failed to ${enabled ? "enable" : "disable"} this extension!`);
    }

-    setIsProcessing(false);
+    setProcessingExtensions(prev => {
+      const next = new Set(prev);
+      next.delete(id);
+      return next;
+    });
    return success;
  };

And pass processingExtensions.has(extension.id) instead of isProcessing to child components.

src/renderer/src/routes/pdf-viewer/page.tsx (1)

6-19: Consider optional UX improvements.

The core logic correctly uses the cacheURL fallback and passes the appropriate path to the PDF viewer. Consider these optional enhancements:

  1. Title element (line 15): The raw URL may be too long or not user-friendly. Consider extracting a filename or using a formatted title.
  2. URL validation: No validation that the URL is well-formed or accessible before passing to PDFViewerApp.
  3. Loading state: No loading indicator while the PDF is being fetched.

These are nice-to-have improvements rather than critical issues.

♻️ Duplicate comments (5)
src/renderer/src/routes/games/config.tsx (1)

5-9: Same Fallback removal pattern.

This change is identical to the pattern in src/renderer/src/routes/omnibox-debug/config.tsx. Refer to the consolidated verification comment in that file.

src/renderer/src/routes/settings/config.tsx (1)

5-9: Same Fallback removal pattern.

This change is identical to the pattern in src/renderer/src/routes/omnibox-debug/config.tsx. Refer to the consolidated verification comment in that file.

src/renderer/src/routes/popup-ui/config.tsx (1)

5-9: Same Fallback removal pattern.

This change is identical to the pattern in src/renderer/src/routes/omnibox-debug/config.tsx. Refer to the consolidated verification comment in that file.

src/renderer/src/routes/new-tab/config.tsx (1)

5-9: Same Fallback removal pattern.

This change is identical to the pattern in src/renderer/src/routes/omnibox-debug/config.tsx. Refer to the consolidated verification comment in that file.

src/renderer/src/routes/about/config.tsx (1)

5-9: Same Fallback removal pattern.

This change is identical to the pattern in src/renderer/src/routes/omnibox-debug/config.tsx. Refer to the consolidated verification comment in that file.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2b8ddcb and 88ae57c.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (67)
  • docs/contributing/dependencies.md (1 hunks)
  • electron.vite.config.ts (2 hunks)
  • package.json (2 hunks)
  • scripts/frontend-routes-generator/common.ts (1 hunks)
  • scripts/frontend-routes-generator/generator.ts (1 hunks)
  • scripts/frontend-routes-generator/pruner.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-external.ts (0 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-external/index.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal.ts (0 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/active-favicon.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/index.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow.ts (0 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/assets.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/extension-icon.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/favicon.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/pdf-cache.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/index.ts (2 hunks)
  • src/main/controllers/sessions-controller/protocols/static-domains/config.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/static-domains/index.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/static-domains/serve-static.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/static-domains/types.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/types.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/utils.ts (3 hunks)
  • src/main/controllers/windows-controller/interfaces/onboarding.ts (1 hunks)
  • src/main/controllers/windows-controller/interfaces/settings.ts (1 hunks)
  • src/main/controllers/windows-controller/types/base.ts (3 hunks)
  • src/main/controllers/windows-controller/types/settings.ts (1 hunks)
  • src/main/modules/typed-event-emitter.ts (1 hunks)
  • src/main/modules/utils.ts (1 hunks)
  • src/renderer/.gitignore (1 hunks)
  • src/renderer/index.html (0 hunks)
  • src/renderer/src/App.tsx (0 hunks)
  • src/renderer/src/components/main/theme.tsx (3 hunks)
  • src/renderer/src/components/providers/nuqs-provider.tsx (1 hunks)
  • src/renderer/src/main.tsx (0 hunks)
  • src/renderer/src/router/README.md (0 hunks)
  • src/renderer/src/router/provider.tsx (0 hunks)
  • src/renderer/src/router/route.tsx (0 hunks)
  • src/renderer/src/routes/about/config.tsx (1 hunks)
  • src/renderer/src/routes/about/route.tsx (0 hunks)
  • src/renderer/src/routes/error/config.tsx (1 hunks)
  • src/renderer/src/routes/error/route.tsx (0 hunks)
  • src/renderer/src/routes/extensions/config.tsx (1 hunks)
  • src/renderer/src/routes/extensions/page.tsx (2 hunks)
  • src/renderer/src/routes/extensions/route.tsx (0 hunks)
  • src/renderer/src/routes/games/config.tsx (1 hunks)
  • src/renderer/src/routes/games/route.tsx (0 hunks)
  • src/renderer/src/routes/main-ui/config.tsx (1 hunks)
  • src/renderer/src/routes/main-ui/route.tsx (0 hunks)
  • src/renderer/src/routes/new-tab/config.tsx (1 hunks)
  • src/renderer/src/routes/new-tab/route.tsx (0 hunks)
  • src/renderer/src/routes/omnibox-debug/config.tsx (1 hunks)
  • src/renderer/src/routes/omnibox-debug/route.tsx (0 hunks)
  • src/renderer/src/routes/omnibox/config.tsx (1 hunks)
  • src/renderer/src/routes/omnibox/route.tsx (0 hunks)
  • src/renderer/src/routes/onboarding/config.tsx (1 hunks)
  • src/renderer/src/routes/onboarding/route.tsx (0 hunks)
  • src/renderer/src/routes/pdf-viewer/config.tsx (2 hunks)
  • src/renderer/src/routes/pdf-viewer/page.tsx (1 hunks)
  • src/renderer/src/routes/pdf-viewer/route.tsx (0 hunks)
  • src/renderer/src/routes/popup-ui/config.tsx (1 hunks)
  • src/renderer/src/routes/popup-ui/route.tsx (0 hunks)
  • src/renderer/src/routes/settings/config.tsx (1 hunks)
  • src/renderer/src/routes/settings/route.tsx (0 hunks)
  • src/renderer/src/types/routes.ts (0 hunks)
  • tsconfig.node.json (1 hunks)
💤 Files with no reviewable changes (22)
  • src/renderer/src/routes/about/route.tsx
  • src/renderer/src/types/routes.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-external.ts
  • src/renderer/src/main.tsx
  • src/renderer/src/router/README.md
  • src/renderer/src/App.tsx
  • src/renderer/src/routes/new-tab/route.tsx
  • src/renderer/src/routes/omnibox-debug/route.tsx
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal.ts
  • src/renderer/src/routes/games/route.tsx
  • src/renderer/src/routes/settings/route.tsx
  • src/main/controllers/sessions-controller/protocols/_protocols/flow.ts
  • src/renderer/src/routes/main-ui/route.tsx
  • src/renderer/src/routes/omnibox/route.tsx
  • src/renderer/src/routes/onboarding/route.tsx
  • src/renderer/src/routes/error/route.tsx
  • src/renderer/src/routes/extensions/route.tsx
  • src/renderer/src/router/route.tsx
  • src/renderer/index.html
  • src/renderer/src/routes/pdf-viewer/route.tsx
  • src/renderer/src/routes/popup-ui/route.tsx
  • src/renderer/src/router/provider.tsx
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

**/*.{js,jsx,ts,tsx}: Use bun <file> instead of node <file> or ts-node <file>
Bun automatically loads .env, so don't use dotenv.
Use Bun.serve() for HTTP servers and WebSockets instead of express.
Use bun:sqlite for SQLite instead of better-sqlite3.
Use Bun.redis for Redis instead of ioredis.
Use Bun.sql for Postgres instead of pg or postgres.js.
Use built-in WebSocket instead of ws.
Prefer Bun.file over node:fs's readFile/writeFile.
Use Bun.$ for shell commands instead of execa.

Files:

  • src/renderer/src/routes/main-ui/config.tsx
  • src/renderer/src/routes/omnibox/config.tsx
  • src/renderer/src/routes/extensions/page.tsx
  • src/renderer/src/routes/extensions/config.tsx
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/pdf-cache.ts
  • src/main/modules/typed-event-emitter.ts
  • src/main/controllers/sessions-controller/protocols/static-domains/types.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/active-favicon.ts
  • scripts/frontend-routes-generator/generator.ts
  • src/main/controllers/sessions-controller/protocols/utils.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/favicon.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/index.ts
  • src/renderer/src/components/providers/nuqs-provider.tsx
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/extension-icon.ts
  • src/main/controllers/sessions-controller/protocols/types.ts
  • src/main/controllers/sessions-controller/protocols/static-domains/config.ts
  • src/renderer/src/routes/pdf-viewer/config.tsx
  • src/renderer/src/routes/pdf-viewer/page.tsx
  • src/renderer/src/routes/popup-ui/config.tsx
  • src/renderer/src/routes/new-tab/config.tsx
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/assets.ts
  • src/main/controllers/sessions-controller/protocols/index.ts
  • src/main/controllers/windows-controller/interfaces/settings.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts
  • scripts/frontend-routes-generator/common.ts
  • src/main/modules/utils.ts
  • src/renderer/src/routes/onboarding/config.tsx
  • electron.vite.config.ts
  • src/renderer/src/routes/omnibox-debug/config.tsx
  • scripts/frontend-routes-generator/pruner.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-external/index.ts
  • src/main/controllers/sessions-controller/protocols/static-domains/serve-static.ts
  • src/renderer/src/components/main/theme.tsx
  • src/renderer/src/routes/settings/config.tsx
  • src/main/controllers/windows-controller/types/settings.ts
  • src/main/controllers/windows-controller/types/base.ts
  • src/renderer/src/routes/about/config.tsx
  • src/renderer/src/routes/error/config.tsx
  • src/renderer/src/routes/games/config.tsx
  • src/main/controllers/sessions-controller/protocols/static-domains/index.ts
  • src/main/controllers/windows-controller/interfaces/onboarding.ts
**/*.{js,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Import .css files directly in .tsx, .jsx, or .js files and it works with Bun.

Files:

  • src/renderer/src/routes/main-ui/config.tsx
  • src/renderer/src/routes/omnibox/config.tsx
  • src/renderer/src/routes/extensions/page.tsx
  • src/renderer/src/routes/extensions/config.tsx
  • src/renderer/src/components/providers/nuqs-provider.tsx
  • src/renderer/src/routes/pdf-viewer/config.tsx
  • src/renderer/src/routes/pdf-viewer/page.tsx
  • src/renderer/src/routes/popup-ui/config.tsx
  • src/renderer/src/routes/new-tab/config.tsx
  • src/renderer/src/routes/onboarding/config.tsx
  • src/renderer/src/routes/omnibox-debug/config.tsx
  • src/renderer/src/components/main/theme.tsx
  • src/renderer/src/routes/settings/config.tsx
  • src/renderer/src/routes/about/config.tsx
  • src/renderer/src/routes/error/config.tsx
  • src/renderer/src/routes/games/config.tsx
**/*.{html,ts,css}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Use bun build <file.html|file.ts|file.css> instead of webpack or esbuild

Files:

  • src/main/controllers/sessions-controller/protocols/_protocols/flow/pdf-cache.ts
  • src/main/modules/typed-event-emitter.ts
  • src/main/controllers/sessions-controller/protocols/static-domains/types.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/active-favicon.ts
  • scripts/frontend-routes-generator/generator.ts
  • src/main/controllers/sessions-controller/protocols/utils.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/favicon.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/index.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/extension-icon.ts
  • src/main/controllers/sessions-controller/protocols/types.ts
  • src/main/controllers/sessions-controller/protocols/static-domains/config.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/assets.ts
  • src/main/controllers/sessions-controller/protocols/index.ts
  • src/main/controllers/windows-controller/interfaces/settings.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts
  • scripts/frontend-routes-generator/common.ts
  • src/main/modules/utils.ts
  • electron.vite.config.ts
  • scripts/frontend-routes-generator/pruner.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-external/index.ts
  • src/main/controllers/sessions-controller/protocols/static-domains/serve-static.ts
  • src/main/controllers/windows-controller/types/settings.ts
  • src/main/controllers/windows-controller/types/base.ts
  • src/main/controllers/sessions-controller/protocols/static-domains/index.ts
  • src/main/controllers/windows-controller/interfaces/onboarding.ts
package.json

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

package.json: Use bun install instead of npm install or yarn install or pnpm install
Use bun run <script> instead of npm run <script> or yarn run <script> or pnpm run <script>

Files:

  • package.json
🧠 Learnings (10)
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use `Bun.serve()` for HTTP servers and WebSockets instead of `express`.

Applied to files:

  • src/main/controllers/sessions-controller/protocols/utils.ts
  • src/main/controllers/sessions-controller/protocols/static-domains/serve-static.ts
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to **/*.html : Use HTML imports with `Bun.serve()` instead of `vite`.

Applied to files:

  • src/main/controllers/sessions-controller/protocols/utils.ts
  • src/renderer/.gitignore
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to **/*.{html,ts,css} : Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild`

Applied to files:

  • src/main/controllers/sessions-controller/protocols/utils.ts
  • package.json
  • src/renderer/.gitignore
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use `bun <file>` instead of `node <file>` or `ts-node <file>`

Applied to files:

  • tsconfig.node.json
  • package.json
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to **/*.{test,spec}.{js,jsx,ts,tsx} : Use `bun test` instead of `jest` or `vitest`

Applied to files:

  • tsconfig.node.json
  • package.json
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to package.json : Use `bun run <script>` instead of `npm run <script>` or `yarn run <script>` or `pnpm run <script>`

Applied to files:

  • package.json
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use `Bun.$` for shell commands instead of execa.

Applied to files:

  • package.json
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to package.json : Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`

Applied to files:

  • package.json
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to **/*.html : HTML files can import .tsx, .jsx, or .js files directly and Bun's bundler will transpile & bundle automatically.

Applied to files:

  • src/renderer/.gitignore
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to **/*.{js,jsx,tsx} : Import .css files directly in .tsx, .jsx, or .js files and it works with Bun.

Applied to files:

  • src/renderer/.gitignore
🧬 Code graph analysis (20)
src/renderer/src/routes/extensions/config.tsx (3)
src/renderer/src/routes/pdf-viewer/config.tsx (1)
  • RouteConfig (11-19)
src/renderer/src/types/routes.ts (1)
  • RouteConfigType (3-5)
src/renderer/src/components/providers/nuqs-provider.tsx (1)
  • NuqsProvider (3-5)
src/main/controllers/sessions-controller/protocols/_protocols/flow/pdf-cache.ts (2)
src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts (1)
  • HonoApp (14-14)
src/main/modules/pdf-cache.ts (2)
  • getPdfResponseFromCache (12-14)
  • removePdfResponseFromCache (16-18)
src/main/controllers/sessions-controller/protocols/static-domains/types.ts (1)
src/main/controllers/sessions-controller/protocols/types.ts (1)
  • CustomProtocol (1-1)
src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/active-favicon.ts (2)
src/main/controllers/tabs-controller/index.ts (1)
  • tabsController (758-758)
src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/index.ts (1)
  • HonoApp (11-11)
scripts/frontend-routes-generator/generator.ts (1)
scripts/frontend-routes-generator/common.ts (3)
  • getDirectories (9-12)
  • ROUTES_PATH (6-6)
  • FRONTEND_PATH (5-5)
src/main/controllers/sessions-controller/protocols/utils.ts (1)
src/main/modules/paths.ts (1)
  • PATHS (18-23)
src/main/controllers/sessions-controller/protocols/_protocols/flow/favicon.ts (2)
src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts (1)
  • HonoApp (14-14)
src/main/modules/utils.ts (1)
  • bufferToArrayBuffer (115-117)
src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/index.ts (3)
src/main/controllers/sessions-controller/protocols/utils.ts (1)
  • transformPathForRequest (86-96)
src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/active-favicon.ts (1)
  • registerActiveFaviconRoutes (16-57)
src/main/controllers/sessions-controller/protocols/static-domains/index.ts (1)
  • registerStaticDomainsRoutes (13-51)
src/main/controllers/sessions-controller/protocols/_protocols/flow/extension-icon.ts (4)
src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts (1)
  • HonoApp (14-14)
src/main/controllers/loaded-profiles-controller/index.ts (1)
  • loadedProfilesController (325-325)
src/main/modules/extensions/management.ts (1)
  • getExtensionIcon (99-151)
src/main/modules/utils.ts (1)
  • bufferToArrayBuffer (115-117)
src/main/controllers/sessions-controller/protocols/static-domains/config.ts (1)
src/main/controllers/sessions-controller/protocols/static-domains/types.ts (1)
  • StaticDomainInfo (14-18)
src/renderer/src/routes/pdf-viewer/config.tsx (1)
src/renderer/src/components/providers/nuqs-provider.tsx (1)
  • NuqsProvider (3-5)
src/main/controllers/sessions-controller/protocols/_protocols/flow/assets.ts (3)
src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts (1)
  • HonoApp (14-14)
src/main/modules/paths.ts (1)
  • PATHS (18-23)
src/main/modules/utils.ts (2)
  • getContentType (23-25)
  • bufferToArrayBuffer (115-117)
src/main/controllers/sessions-controller/protocols/index.ts (1)
src/main/controllers/sessions-controller/protocols/types.ts (1)
  • CustomProtocol (1-1)
src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts (6)
src/main/controllers/sessions-controller/protocols/utils.ts (1)
  • transformPathForRequest (86-96)
src/main/controllers/sessions-controller/protocols/_protocols/flow/favicon.ts (1)
  • registerFaviconRoutes (5-20)
src/main/controllers/sessions-controller/protocols/_protocols/flow/assets.ts (1)
  • registerAssetsRoutes (7-43)
src/main/controllers/sessions-controller/protocols/_protocols/flow/extension-icon.ts (1)
  • registerExtensionIconRoutes (6-39)
src/main/controllers/sessions-controller/protocols/_protocols/flow/pdf-cache.ts (1)
  • registerPdfCacheRoutes (4-21)
src/main/controllers/sessions-controller/protocols/static-domains/index.ts (1)
  • registerStaticDomainsRoutes (13-51)
electron.vite.config.ts (1)
scripts/frontend-routes-generator/generator.ts (1)
  • generateRoutes (8-73)
scripts/frontend-routes-generator/pruner.ts (1)
scripts/frontend-routes-generator/common.ts (3)
  • getDirectories (9-12)
  • ROUTES_PATH (6-6)
  • FRONTEND_PATH (5-5)
src/main/controllers/sessions-controller/protocols/_protocols/flow-external/index.ts (2)
src/main/controllers/sessions-controller/protocols/utils.ts (1)
  • transformPathForRequest (86-96)
src/main/controllers/sessions-controller/protocols/static-domains/index.ts (1)
  • registerStaticDomainsRoutes (13-51)
src/main/controllers/sessions-controller/protocols/static-domains/serve-static.ts (4)
src/main/modules/paths.ts (1)
  • PATHS (18-23)
src/main/modules/flags.ts (1)
  • FLAGS (16-40)
src/main/controllers/sessions-controller/protocols/static-domains/hot-reload.ts (3)
  • setupHotReloadFileDescriptors (9-15)
  • isDevelopmentServerRunning (21-27)
  • fetchFromDevServer (45-81)
src/main/modules/utils.ts (2)
  • getContentType (23-25)
  • bufferToArrayBuffer (115-117)
src/main/controllers/windows-controller/types/base.ts (1)
src/main/modules/typed-event-emitter.ts (1)
  • TypedEventEmitter (11-114)
src/main/controllers/sessions-controller/protocols/static-domains/index.ts (3)
src/main/controllers/sessions-controller/protocols/types.ts (1)
  • CustomProtocol (1-1)
src/main/controllers/sessions-controller/protocols/static-domains/config.ts (1)
  • STATIC_DOMAINS (3-132)
src/main/controllers/sessions-controller/protocols/static-domains/serve-static.ts (1)
  • serveStaticDomainFile (35-132)
🔇 Additional comments (47)
src/renderer/src/routes/extensions/page.tsx (3)

7-7: LGTM! Clean migration to new dependencies.

The imports for toast from sonner and useQueryState from nuqs align with the PR's migration from URL-based routing to query-state management.

Also applies to: 12-12


24-50: LGTM! Clean async handlers with user feedback.

Both setExtensionEnabled and setExtensionPinned follow a consistent pattern: they call the corresponding API, provide clear toast feedback to users, and return the success status. The implementation is straightforward and maintainable, though it assumes the flow.extensions APIs return false on failure rather than throwing exceptions.

Note: This assumes the processing state race condition (flagged separately) will be addressed.


52-58: LGTM! Query-state navigation is correctly implemented.

The navigation handlers properly use setSelectedExtensionId to manage the query parameter, and the selectedExtension lookup at line 60 safely handles the case where the ID might not match any extension by falling back to the list view.

Minor edge case: If a user navigates directly to a URL with an invalid extension ID (e.g., ?id=nonexistent), they'll see the extensions list without any feedback about the invalid ID. This is acceptable self-recovering behavior, though you could optionally add a toast notification if desired.

Also applies to: 60-60

src/renderer/src/routes/pdf-viewer/page.tsx (3)

1-1: LGTM! Migration to nuqs.

The import statement correctly migrates from the previous query parameter library to nuqs, aligning with the PR objectives.


7-8: LGTM! Correct nuqs hook usage.

The useQueryState hooks are used correctly with appropriate destructuring to extract only the query parameter values.


9-11: No changes needed—the current null return is the correct behavior.

The component correctly returns null when the url query parameter is missing. The codebase has no centralized error page mechanism for this scenario, and the null pattern is consistent with how the application handles other routing edge cases (e.g., the Route component also returns null for unmatched conditions). The PR description's reference to "unresolved domains" likely pertains to PDF fetch failures within PDFViewerApp, not missing query parameters.

Likely an incorrect or invalid review comment.

src/renderer/.gitignore (1)

1-2: LGTM!

Properly excludes generated files from version control. The patterns correctly ignore:

  • route-*.html: Generated HTML route files
  • src/routes/*/main.tsx: Generated entry point files

This aligns with the frontend routes generation workflow mentioned in the PR objectives.

src/renderer/src/routes/omnibox-debug/config.tsx (1)

5-9: Verification Confirmed: RouteConfigType Update and Fallback Removal Complete

The review comment's concerns have been fully verified:

  1. RouteConfigType interface updated: The type definition in src/renderer/src/types/routes.ts now contains only the Providers property. The Fallback property has been completely removed from the interface.

  2. All route configurations updated: All 12 route config files in src/renderer/src/routes/ have been consistently updated to include only the Providers property. No config file retains the Fallback property.

  3. No breaking references: A complete codebase search found zero instances of RouteConfig.Fallback access, confirming that no code attempts to use the removed property.

The refactoring is complete, consistent, and introduces no breaking changes.

src/renderer/src/routes/omnibox/config.tsx (1)

5-9: LGTM! Configuration simplified.

The removal of the Fallback property aligns with the broader pattern across route configs in this PR. The Providers implementation remains intact and correct.

src/renderer/src/routes/main-ui/config.tsx (1)

5-9: LGTM! Consistent configuration pattern.

The removal of the Fallback property is consistent with the route config refactoring across the codebase.

src/main/modules/utils.ts (1)

110-117: LGTM! Clean utility function.

The bufferToArrayBuffer implementation is correct and follows the standard pattern for converting Node.js Buffer to ArrayBuffer. The JSDoc is clear and the function is properly utilized across multiple Flow protocol handlers.

src/renderer/src/components/main/theme.tsx (2)

22-31: Good refactor for clarity.

Extracting theme class manipulation into a dedicated helper function improves readability and maintainability.


71-81: Excellent change to prevent theme flicker.

Switching from useEffect to useLayoutEffect ensures the theme class is applied synchronously before the browser paints, eliminating visual flicker during theme changes or initialization. This is the correct approach for DOM mutations that affect visual appearance.

src/main/controllers/sessions-controller/protocols/_protocols/flow/extension-icon.ts (1)

6-38: LGTM! Well-structured route handler.

The extension icon handler properly validates query parameters, checks for loaded profile and extension data, and returns appropriate status codes. The use of bufferToArrayBuffer for converting the PNG buffer is consistent with other Flow protocol handlers.

src/main/controllers/sessions-controller/protocols/_protocols/flow/pdf-cache.ts (1)

4-20: LGTM! Clean cache-and-serve implementation.

The PDF cache handler correctly implements a one-time cache pattern: it checks the cache, redirects to the actual URL on miss (graceful fallback), and removes the cached response after serving it on hit. This prevents stale cache accumulation and is appropriate for single-use cached responses.

docs/contributing/dependencies.md (1)

100-101: Documentation updated correctly.

The dependency documentation accurately reflects the replacement of use-query-params with nuqs for query parameter management and the addition of hono for custom protocol routing.

src/main/controllers/sessions-controller/protocols/_protocols/flow/favicon.ts (1)

5-20: LGTM! Clean favicon handler.

The favicon route properly validates the URL parameter, normalizes the URL (good practice for consistent lookup), and returns appropriate status codes. The implementation is consistent with the other Flow protocol handlers and correctly converts the buffer to ArrayBuffer for the response.

src/renderer/src/routes/onboarding/config.tsx (1)

5-9: LGTM!

The removal of the Fallback property simplifies the route configuration and aligns with the broader refactoring of RouteConfigType across the codebase.

src/renderer/src/routes/error/config.tsx (1)

5-9: LGTM!

Consistent with the route configuration simplification across the codebase.

src/main/controllers/sessions-controller/protocols/types.ts (1)

1-1: LGTM!

Clean type definition that provides type safety for the custom protocol system.

src/renderer/src/routes/extensions/config.tsx (1)

2-13: LGTM!

The addition of NuqsProvider follows the established pattern seen in other route configurations (e.g., pdf-viewer) and properly nests providers for the query parameter management.

src/main/controllers/sessions-controller/protocols/static-domains/config.ts (3)

3-44: LGTM!

The flow-internal protocol mappings are well-structured and follow a consistent pattern for internal UI routes.


104-132: LGTM!

Excellent practice including source attribution comments for the external game resources. The subdirectory-based mapping is appropriate for these static assets.


79-86: No changes required; the duplicate hostname is intentional and correct.

The "omnibox" hostname appears under two different protocols: flow-internal (line 31) maps to route "omnibox", and flow (line 81) maps to route "omnibox-debug". This is valid routing design—same hostname under different protocols creates distinct routing entries with no conflict. The code is correct as-is.

src/main/controllers/sessions-controller/protocols/static-domains/index.ts (4)

13-17: LGTM!

Efficient filtering and early return pattern when no domains match the protocol.


19-38: LGTM!

The handler properly implements case-insensitive domain matching and correctly delegates to serveStaticDomainFile with appropriate options for both route and subdirectory types.


40-46: Good error handling with Chrome-compatible error codes.

The redirect to the error page with context preservation is well-implemented. The error code -300 (ERR_INVALID_URL) appropriately matches the Chrome network error convention.


49-50: LGTM!

The route registration correctly handles both root domain requests and paths with the wildcard pattern {.+}.

src/renderer/src/components/providers/nuqs-provider.tsx (1)

3-5: LGTM!

Clean abstraction layer that provides a project-specific provider name while delegating to the nuqs library's adapter.

src/renderer/src/routes/pdf-viewer/config.tsx (1)

12-18: Nuqs provider placement looks solid.

Keeping NuqsProvider inside the theme wrapper gives the page access to query-state utilities without losing theme context, matching how the other upgraded routes are structured.

src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts (1)

11-29: Consolidated flow protocol handler reads clean.

Registering every route on a single Hono app with transformPathForRequest keeps the hostname routing logic consistent and lets the static-domain catch-all sit safely after the specific endpoints—nicely done.

scripts/frontend-routes-generator/common.ts (1)

5-12: Directory helper is tidy.

Centralizing the renderer paths and using withFileTypes for directory detection keeps the generator/pruner logic DRY and efficient.

electron.vite.config.ts (1)

53-68: Route generation pipeline fits neatly into Vite config.

Pulling the generated inputs straight into rollupOptions.input while reusing the shared build settings keeps the multipage renderer build cohesive.

src/main/controllers/sessions-controller/protocols/index.ts (1)

23-34: Type alignment is spot on.

Switching to the shared CustomProtocol[] keeps the registration callsites in sync with the new protocol definitions and avoids drift.

src/main/controllers/sessions-controller/protocols/_protocols/flow/assets.ts (1)

20-29: LGTM: Solid path traversal protection.

The combination of path normalization (line 21) and directory boundary enforcement (lines 26-29) effectively prevents directory traversal attacks.

src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/index.ts (1)

7-24: LGTM: Clean protocol handler implementation.

The Hono app configuration with custom path transformation and the protocol delegation pattern via app.fetch is well-structured and follows a consistent approach across protocol handlers.

src/main/controllers/sessions-controller/protocols/_protocols/flow-external/index.ts (1)

6-23: LGTM: Consistent with flow-internal implementation.

The structure mirrors the flow-internal protocol handler, maintaining consistency across the codebase.

src/main/controllers/sessions-controller/protocols/utils.ts (2)

18-44: LGTM: Clean extension of serveStaticFile with options.

The addition of ServeStaticFileOptions and the recursive call pattern to handle overrideRouteName is well-designed and maintains backward compatibility with the default empty options object.


86-96: LGTM: Path transformation logic is correct.

The transformPathForRequest function correctly combines hostname and path to create a routable path for the Hono app.

src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/active-favicon.ts (1)

16-57: LGTM: Robust favicon caching with proper validation.

The handler validates all required inputs (tabId parsing, tab existence, favicon and profile availability) and correctly uses Response.clone() to prevent cache corruption. The cache invalidation logic in the cleanup interval appropriately checks both tab destruction and favicon URL changes.

src/main/controllers/sessions-controller/protocols/static-domains/serve-static.ts (3)

38-55: LGTM: Strong security and UX measures.

The path traversal prevention (line 39) and trailing slash redirect (lines 52-54) demonstrate good security practices and user experience considerations.


70-74: LGTM: Important security boundary.

Preventing direct access to route entrypoints (lines 70-73) ensures routes can only be served through their intended domain mappings, maintaining proper isolation between different protocol domains.


83-101: LGTM: Well-integrated hot reload support.

The development server integration properly handles path transformation with extraBaseDir and falls back gracefully when the dev server isn't available.

scripts/frontend-routes-generator/generator.ts (1)

8-31: Document the auto-generated workflow or add a safety check in the generator.

The route HTML files are handled by a separate pruner.ts that removes old files before generation runs. However, the generator itself has no safeguards—it directly overwrites files with fs.writeFile(). While the typical workflow (pruner runs first) prevents conflicts, the generator can silently overwrite files if:

  • It runs independently without the pruner
  • Files are manually edited between runs

Either add a warning check in the generator before writing, or document that these files are auto-generated and should not be manually edited.

src/main/controllers/sessions-controller/protocols/static-domains/types.ts (3)

1-1: LGTM! Proper type-only import.

The import type syntax is best practice for type-only imports, eliminating runtime overhead.


3-12: LGTM! Well-structured discriminated union.

The discriminated union pattern with the type literal field is properly implemented, enabling type-safe exhaustive checking and narrowing in consuming code.


14-18: LGTM! Clean type composition.

The exported type properly composes the imported CustomProtocol and internal ActualDomainInfo types. The structure is clear and follows good TypeScript practices.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/main/controllers/windows-controller/interfaces/onboarding.ts (1)

20-26: Consider making toggle() async to await show().

The toggle() method calls onboarding.show() without awaiting (line 24). Since show() is now async, this fire-and-forget call could lead to race conditions if toggle() is called multiple times before the window finishes showing. The window might not be visible yet when isVisible() is checked in subsequent calls.

Consider making toggle() async:

- toggle: () => {
+ toggle: async () => {
    if (onboarding.isVisible()) {
      onboarding.hide();
    } else {
-     onboarding.show();
+     await onboarding.show();
    }
  },
src/main/controllers/windows-controller/interfaces/settings.ts (1)

20-26: Consider making toggle() async to await show().

The toggle() method calls settings.show() without awaiting (line 24). Since show() is now async, this fire-and-forget call could lead to race conditions if toggle() is called multiple times before the window finishes showing. The window might not be visible yet when isVisible() is checked in subsequent calls.

Consider making toggle() async:

- toggle: () => {
+ toggle: async () => {
    if (settings.isVisible()) {
      settings.hide();
    } else {
-     settings.show();
+     await settings.show();
    }
  },
src/renderer/src/routes/extensions/page.tsx (1)

24-50: Reset isProcessing even when flow calls reject.

If flow.extensions.setExtensionEnabled or .setExtensionPinned throws, the setIsProcessing(false) lines never run, leaving the UI locked in a permanently disabled state and causing unhandled rejections. Wrap these calls in try/catch/finally so isProcessing always resets and unexpected errors surface via a toast. Example fix for setExtensionEnabled:

  const setExtensionEnabled = async (id: string, enabled: boolean) => {
    setIsProcessing(true);

-    const success = await flow.extensions.setExtensionEnabled(id, enabled);
-    if (success) {
-      toast.success(`This extension has been successfully ${enabled ? "enabled" : "disabled"}!`);
-    } else {
-      toast.error(`Failed to ${enabled ? "enable" : "disable"} this extension!`);
-    }
-
-    setIsProcessing(false);
-    return success;
+    try {
+      const success = await flow.extensions.setExtensionEnabled(id, enabled);
+      if (success) {
+        toast.success(`This extension has been successfully ${enabled ? "enabled" : "disabled"}!`);
+      } else {
+        toast.error(`Failed to ${enabled ? "enable" : "disable"} this extension!`);
+      }
+      return success;
+    } catch (error) {
+      toast.error(`Unexpected error while trying to ${enabled ? "enable" : "disable"} this extension.`);
+      return false;
+    } finally {
+      setIsProcessing(false);
+    }
  };

Please apply the same pattern to setExtensionPinned.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2b8ddcb and 88ae57c.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (67)
  • docs/contributing/dependencies.md (1 hunks)
  • electron.vite.config.ts (2 hunks)
  • package.json (2 hunks)
  • scripts/frontend-routes-generator/common.ts (1 hunks)
  • scripts/frontend-routes-generator/generator.ts (1 hunks)
  • scripts/frontend-routes-generator/pruner.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-external.ts (0 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-external/index.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal.ts (0 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/active-favicon.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/index.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow.ts (0 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/assets.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/extension-icon.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/favicon.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/pdf-cache.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/index.ts (2 hunks)
  • src/main/controllers/sessions-controller/protocols/static-domains/config.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/static-domains/index.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/static-domains/serve-static.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/static-domains/types.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/types.ts (1 hunks)
  • src/main/controllers/sessions-controller/protocols/utils.ts (3 hunks)
  • src/main/controllers/windows-controller/interfaces/onboarding.ts (1 hunks)
  • src/main/controllers/windows-controller/interfaces/settings.ts (1 hunks)
  • src/main/controllers/windows-controller/types/base.ts (3 hunks)
  • src/main/controllers/windows-controller/types/settings.ts (1 hunks)
  • src/main/modules/typed-event-emitter.ts (1 hunks)
  • src/main/modules/utils.ts (1 hunks)
  • src/renderer/.gitignore (1 hunks)
  • src/renderer/index.html (0 hunks)
  • src/renderer/src/App.tsx (0 hunks)
  • src/renderer/src/components/main/theme.tsx (3 hunks)
  • src/renderer/src/components/providers/nuqs-provider.tsx (1 hunks)
  • src/renderer/src/main.tsx (0 hunks)
  • src/renderer/src/router/README.md (0 hunks)
  • src/renderer/src/router/provider.tsx (0 hunks)
  • src/renderer/src/router/route.tsx (0 hunks)
  • src/renderer/src/routes/about/config.tsx (1 hunks)
  • src/renderer/src/routes/about/route.tsx (0 hunks)
  • src/renderer/src/routes/error/config.tsx (1 hunks)
  • src/renderer/src/routes/error/route.tsx (0 hunks)
  • src/renderer/src/routes/extensions/config.tsx (1 hunks)
  • src/renderer/src/routes/extensions/page.tsx (2 hunks)
  • src/renderer/src/routes/extensions/route.tsx (0 hunks)
  • src/renderer/src/routes/games/config.tsx (1 hunks)
  • src/renderer/src/routes/games/route.tsx (0 hunks)
  • src/renderer/src/routes/main-ui/config.tsx (1 hunks)
  • src/renderer/src/routes/main-ui/route.tsx (0 hunks)
  • src/renderer/src/routes/new-tab/config.tsx (1 hunks)
  • src/renderer/src/routes/new-tab/route.tsx (0 hunks)
  • src/renderer/src/routes/omnibox-debug/config.tsx (1 hunks)
  • src/renderer/src/routes/omnibox-debug/route.tsx (0 hunks)
  • src/renderer/src/routes/omnibox/config.tsx (1 hunks)
  • src/renderer/src/routes/omnibox/route.tsx (0 hunks)
  • src/renderer/src/routes/onboarding/config.tsx (1 hunks)
  • src/renderer/src/routes/onboarding/route.tsx (0 hunks)
  • src/renderer/src/routes/pdf-viewer/config.tsx (2 hunks)
  • src/renderer/src/routes/pdf-viewer/page.tsx (1 hunks)
  • src/renderer/src/routes/pdf-viewer/route.tsx (0 hunks)
  • src/renderer/src/routes/popup-ui/config.tsx (1 hunks)
  • src/renderer/src/routes/popup-ui/route.tsx (0 hunks)
  • src/renderer/src/routes/settings/config.tsx (1 hunks)
  • src/renderer/src/routes/settings/route.tsx (0 hunks)
  • src/renderer/src/types/routes.ts (0 hunks)
  • tsconfig.node.json (1 hunks)
💤 Files with no reviewable changes (22)
  • src/renderer/src/router/README.md
  • src/renderer/src/routes/onboarding/route.tsx
  • src/renderer/src/routes/omnibox/route.tsx
  • src/renderer/src/routes/popup-ui/route.tsx
  • src/renderer/src/routes/pdf-viewer/route.tsx
  • src/renderer/src/routes/settings/route.tsx
  • src/renderer/src/routes/about/route.tsx
  • src/renderer/src/router/provider.tsx
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal.ts
  • src/renderer/src/App.tsx
  • src/renderer/src/types/routes.ts
  • src/renderer/src/main.tsx
  • src/renderer/src/router/route.tsx
  • src/renderer/src/routes/new-tab/route.tsx
  • src/main/controllers/sessions-controller/protocols/_protocols/flow.ts
  • src/renderer/src/routes/games/route.tsx
  • src/renderer/index.html
  • src/renderer/src/routes/extensions/route.tsx
  • src/renderer/src/routes/error/route.tsx
  • src/renderer/src/routes/omnibox-debug/route.tsx
  • src/renderer/src/routes/main-ui/route.tsx
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-external.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

**/*.{js,jsx,ts,tsx}: Use bun <file> instead of node <file> or ts-node <file>
Bun automatically loads .env, so don't use dotenv.
Use Bun.serve() for HTTP servers and WebSockets instead of express.
Use bun:sqlite for SQLite instead of better-sqlite3.
Use Bun.redis for Redis instead of ioredis.
Use Bun.sql for Postgres instead of pg or postgres.js.
Use built-in WebSocket instead of ws.
Prefer Bun.file over node:fs's readFile/writeFile.
Use Bun.$ for shell commands instead of execa.

Files:

  • src/main/modules/utils.ts
  • src/renderer/src/routes/settings/config.tsx
  • src/main/controllers/sessions-controller/protocols/types.ts
  • scripts/frontend-routes-generator/generator.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/assets.ts
  • src/renderer/src/components/providers/nuqs-provider.tsx
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/active-favicon.ts
  • src/renderer/src/routes/error/config.tsx
  • src/renderer/src/routes/onboarding/config.tsx
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-external/index.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/pdf-cache.ts
  • src/renderer/src/routes/pdf-viewer/config.tsx
  • src/renderer/src/routes/main-ui/config.tsx
  • src/main/controllers/sessions-controller/protocols/index.ts
  • src/renderer/src/routes/new-tab/config.tsx
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/extension-icon.ts
  • src/renderer/src/routes/pdf-viewer/page.tsx
  • src/main/controllers/sessions-controller/protocols/static-domains/index.ts
  • src/renderer/src/routes/omnibox/config.tsx
  • src/renderer/src/routes/about/config.tsx
  • src/main/controllers/sessions-controller/protocols/static-domains/types.ts
  • src/renderer/src/routes/popup-ui/config.tsx
  • src/renderer/src/routes/extensions/page.tsx
  • src/renderer/src/routes/extensions/config.tsx
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/favicon.ts
  • src/main/modules/typed-event-emitter.ts
  • src/renderer/src/routes/games/config.tsx
  • src/main/controllers/windows-controller/interfaces/onboarding.ts
  • src/main/controllers/windows-controller/types/settings.ts
  • src/renderer/src/routes/omnibox-debug/config.tsx
  • scripts/frontend-routes-generator/common.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/index.ts
  • src/renderer/src/components/main/theme.tsx
  • src/main/controllers/sessions-controller/protocols/static-domains/config.ts
  • scripts/frontend-routes-generator/pruner.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts
  • src/main/controllers/windows-controller/interfaces/settings.ts
  • src/main/controllers/sessions-controller/protocols/utils.ts
  • electron.vite.config.ts
  • src/main/controllers/sessions-controller/protocols/static-domains/serve-static.ts
  • src/main/controllers/windows-controller/types/base.ts
**/*.{html,ts,css}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Use bun build <file.html|file.ts|file.css> instead of webpack or esbuild

Files:

  • src/main/modules/utils.ts
  • src/main/controllers/sessions-controller/protocols/types.ts
  • scripts/frontend-routes-generator/generator.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/assets.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/active-favicon.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-external/index.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/pdf-cache.ts
  • src/main/controllers/sessions-controller/protocols/index.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/extension-icon.ts
  • src/main/controllers/sessions-controller/protocols/static-domains/index.ts
  • src/main/controllers/sessions-controller/protocols/static-domains/types.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/favicon.ts
  • src/main/modules/typed-event-emitter.ts
  • src/main/controllers/windows-controller/interfaces/onboarding.ts
  • src/main/controllers/windows-controller/types/settings.ts
  • scripts/frontend-routes-generator/common.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/index.ts
  • src/main/controllers/sessions-controller/protocols/static-domains/config.ts
  • scripts/frontend-routes-generator/pruner.ts
  • src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts
  • src/main/controllers/windows-controller/interfaces/settings.ts
  • src/main/controllers/sessions-controller/protocols/utils.ts
  • electron.vite.config.ts
  • src/main/controllers/sessions-controller/protocols/static-domains/serve-static.ts
  • src/main/controllers/windows-controller/types/base.ts
**/*.{js,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

Import .css files directly in .tsx, .jsx, or .js files and it works with Bun.

Files:

  • src/renderer/src/routes/settings/config.tsx
  • src/renderer/src/components/providers/nuqs-provider.tsx
  • src/renderer/src/routes/error/config.tsx
  • src/renderer/src/routes/onboarding/config.tsx
  • src/renderer/src/routes/pdf-viewer/config.tsx
  • src/renderer/src/routes/main-ui/config.tsx
  • src/renderer/src/routes/new-tab/config.tsx
  • src/renderer/src/routes/pdf-viewer/page.tsx
  • src/renderer/src/routes/omnibox/config.tsx
  • src/renderer/src/routes/about/config.tsx
  • src/renderer/src/routes/popup-ui/config.tsx
  • src/renderer/src/routes/extensions/page.tsx
  • src/renderer/src/routes/extensions/config.tsx
  • src/renderer/src/routes/games/config.tsx
  • src/renderer/src/routes/omnibox-debug/config.tsx
  • src/renderer/src/components/main/theme.tsx
package.json

📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)

package.json: Use bun install instead of npm install or yarn install or pnpm install
Use bun run <script> instead of npm run <script> or yarn run <script> or pnpm run <script>

Files:

  • package.json
🧠 Learnings (10)
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use `bun <file>` instead of `node <file>` or `ts-node <file>`

Applied to files:

  • tsconfig.node.json
  • package.json
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to **/*.{test,spec}.{js,jsx,ts,tsx} : Use `bun test` instead of `jest` or `vitest`

Applied to files:

  • tsconfig.node.json
  • package.json
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to **/*.{html,ts,css} : Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild`

Applied to files:

  • src/renderer/.gitignore
  • package.json
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to **/*.html : HTML files can import .tsx, .jsx, or .js files directly and Bun's bundler will transpile & bundle automatically.

Applied to files:

  • src/renderer/.gitignore
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to **/*.html : Use HTML imports with `Bun.serve()` instead of `vite`.

Applied to files:

  • src/renderer/.gitignore
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to **/*.{js,jsx,tsx} : Import .css files directly in .tsx, .jsx, or .js files and it works with Bun.

Applied to files:

  • src/renderer/.gitignore
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to package.json : Use `bun run <script>` instead of `npm run <script>` or `yarn run <script>` or `pnpm run <script>`

Applied to files:

  • package.json
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use `Bun.$` for shell commands instead of execa.

Applied to files:

  • package.json
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to package.json : Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`

Applied to files:

  • package.json
📚 Learning: 2025-07-24T08:49:07.217Z
Learnt from: CR
PR: MultiboxLabs/flow-browser#0
File: .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc:0-0
Timestamp: 2025-07-24T08:49:07.217Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Use `Bun.serve()` for HTTP servers and WebSockets instead of `express`.

Applied to files:

  • src/main/controllers/sessions-controller/protocols/utils.ts
  • src/main/controllers/sessions-controller/protocols/static-domains/serve-static.ts
🧬 Code graph analysis (20)
scripts/frontend-routes-generator/generator.ts (1)
scripts/frontend-routes-generator/common.ts (3)
  • getDirectories (9-12)
  • ROUTES_PATH (6-6)
  • FRONTEND_PATH (5-5)
src/main/controllers/sessions-controller/protocols/_protocols/flow/assets.ts (3)
src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts (1)
  • HonoApp (14-14)
src/main/modules/paths.ts (1)
  • PATHS (18-23)
src/main/modules/utils.ts (2)
  • getContentType (23-25)
  • bufferToArrayBuffer (115-117)
src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/active-favicon.ts (2)
src/main/controllers/tabs-controller/index.ts (1)
  • tabsController (758-758)
src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/index.ts (1)
  • HonoApp (11-11)
src/main/controllers/sessions-controller/protocols/_protocols/flow-external/index.ts (2)
src/main/controllers/sessions-controller/protocols/utils.ts (1)
  • transformPathForRequest (86-96)
src/main/controllers/sessions-controller/protocols/static-domains/index.ts (1)
  • registerStaticDomainsRoutes (13-51)
src/main/controllers/sessions-controller/protocols/_protocols/flow/pdf-cache.ts (2)
src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts (1)
  • HonoApp (14-14)
src/main/modules/pdf-cache.ts (2)
  • getPdfResponseFromCache (12-14)
  • removePdfResponseFromCache (16-18)
src/renderer/src/routes/pdf-viewer/config.tsx (2)
src/renderer/src/components/main/theme.tsx (1)
  • ThemeProvider (33-106)
src/renderer/src/components/providers/nuqs-provider.tsx (1)
  • NuqsProvider (3-5)
src/main/controllers/sessions-controller/protocols/index.ts (1)
src/main/controllers/sessions-controller/protocols/types.ts (1)
  • CustomProtocol (1-1)
src/main/controllers/sessions-controller/protocols/_protocols/flow/extension-icon.ts (4)
src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts (1)
  • HonoApp (14-14)
src/main/controllers/loaded-profiles-controller/index.ts (1)
  • loadedProfilesController (325-325)
src/main/modules/extensions/management.ts (1)
  • getExtensionIcon (99-151)
src/main/modules/utils.ts (1)
  • bufferToArrayBuffer (115-117)
src/main/controllers/sessions-controller/protocols/static-domains/index.ts (3)
src/main/controllers/sessions-controller/protocols/types.ts (1)
  • CustomProtocol (1-1)
src/main/controllers/sessions-controller/protocols/static-domains/config.ts (1)
  • STATIC_DOMAINS (3-132)
src/main/controllers/sessions-controller/protocols/static-domains/serve-static.ts (1)
  • serveStaticDomainFile (35-132)
src/main/controllers/sessions-controller/protocols/static-domains/types.ts (1)
src/main/controllers/sessions-controller/protocols/types.ts (1)
  • CustomProtocol (1-1)
src/renderer/src/routes/extensions/config.tsx (3)
src/renderer/src/types/routes.ts (1)
  • RouteConfigType (3-5)
src/renderer/src/components/main/theme.tsx (1)
  • ThemeProvider (33-106)
src/renderer/src/components/providers/nuqs-provider.tsx (1)
  • NuqsProvider (3-5)
src/main/controllers/sessions-controller/protocols/_protocols/flow/favicon.ts (2)
src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts (1)
  • HonoApp (14-14)
src/main/modules/utils.ts (1)
  • bufferToArrayBuffer (115-117)
src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/index.ts (3)
src/main/controllers/sessions-controller/protocols/utils.ts (1)
  • transformPathForRequest (86-96)
src/main/controllers/sessions-controller/protocols/_protocols/flow-internal/active-favicon.ts (1)
  • registerActiveFaviconRoutes (16-57)
src/main/controllers/sessions-controller/protocols/static-domains/index.ts (1)
  • registerStaticDomainsRoutes (13-51)
src/main/controllers/sessions-controller/protocols/static-domains/config.ts (1)
src/main/controllers/sessions-controller/protocols/static-domains/types.ts (1)
  • StaticDomainInfo (14-18)
scripts/frontend-routes-generator/pruner.ts (1)
scripts/frontend-routes-generator/common.ts (3)
  • getDirectories (9-12)
  • ROUTES_PATH (6-6)
  • FRONTEND_PATH (5-5)
src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts (6)
src/main/controllers/sessions-controller/protocols/utils.ts (1)
  • transformPathForRequest (86-96)
src/main/controllers/sessions-controller/protocols/_protocols/flow/favicon.ts (1)
  • registerFaviconRoutes (5-20)
src/main/controllers/sessions-controller/protocols/_protocols/flow/assets.ts (1)
  • registerAssetsRoutes (7-43)
src/main/controllers/sessions-controller/protocols/_protocols/flow/extension-icon.ts (1)
  • registerExtensionIconRoutes (6-39)
src/main/controllers/sessions-controller/protocols/_protocols/flow/pdf-cache.ts (1)
  • registerPdfCacheRoutes (4-21)
src/main/controllers/sessions-controller/protocols/static-domains/index.ts (1)
  • registerStaticDomainsRoutes (13-51)
src/main/controllers/sessions-controller/protocols/utils.ts (1)
src/main/modules/paths.ts (1)
  • PATHS (18-23)
electron.vite.config.ts (1)
scripts/frontend-routes-generator/generator.ts (1)
  • generateRoutes (8-73)
src/main/controllers/sessions-controller/protocols/static-domains/serve-static.ts (4)
src/main/modules/paths.ts (1)
  • PATHS (18-23)
src/main/modules/flags.ts (1)
  • FLAGS (16-40)
src/main/controllers/sessions-controller/protocols/static-domains/hot-reload.ts (3)
  • setupHotReloadFileDescriptors (9-15)
  • isDevelopmentServerRunning (21-27)
  • fetchFromDevServer (45-81)
src/main/modules/utils.ts (2)
  • getContentType (23-25)
  • bufferToArrayBuffer (115-117)
src/main/controllers/windows-controller/types/base.ts (1)
src/main/modules/typed-event-emitter.ts (1)
  • TypedEventEmitter (11-130)
🔇 Additional comments (35)
tsconfig.node.json (1)

3-3: tsconfig.node.json narrowing is correct and properly architected.

The change to restrict include to only application source directories (src/main, src/preload, src/shared) is intentional and well-supported. Build-time artifacts—including electron.vite.config.ts and all scripts in scripts/—are now explicitly covered by the dedicated tsconfig.scripts.json, which includes "electron.vite.config.*" and "scripts/**/*". This represents a clean separation: Node application code vs. build tooling. Type-checking coverage is maintained across all code paths.

src/main/controllers/windows-controller/interfaces/onboarding.ts (1)

7-10: LGTM! Properly awaiting the async show() method.

The change correctly awaits the async show() method from BaseWindow, ensuring the show operation completes before the function returns.

src/main/controllers/windows-controller/types/base.ts (3)

6-14: LGTM! Well-designed additions for deferred window loading.

The new loaded event and deferShowUntilAfterLoad option provide clean control over window show timing, allowing callers to wait for load completion before displaying the window.


71-76: LGTM! Clean extraction of immediate show logic.

The new showImmediately() method provides a synchronous way to show the window without waiting for load completion, which is useful when the window is already loaded.


78-83: LGTM! Correctly implements deferred show logic.

The async show() method properly waits for the loaded event when deferShowUntilAfterLoad is enabled and the window hasn't finished loading yet. The use of waitUntil() from TypedEventEmitter ensures the show operation is deferred until load completion.

src/main/controllers/windows-controller/types/settings.ts (1)

31-31: LGTM! Correctly enables deferred showing for SettingsWindow.

The addition of { deferShowUntilAfterLoad: true } ensures that the settings window won't be displayed until after it finishes loading, providing a better user experience by avoiding flickering or incomplete content.

src/main/controllers/windows-controller/interfaces/settings.ts (1)

7-10: LGTM! Properly awaiting the async show() method.

The change correctly awaits the async show() method from BaseWindow, ensuring the show operation completes before the function returns.

src/renderer/.gitignore (1)

1-2: LGTM!

The ignore patterns correctly target generated artifacts from the new frontend route generation system, preventing them from being committed to version control.

docs/contributing/dependencies.md (1)

100-101: LGTM!

Documentation correctly reflects the dependency changes, replacing use-query-params with nuqs for query parameter management and adding hono for custom protocol routing.

src/renderer/src/components/main/theme.tsx (2)

22-31: LGTM!

The applyThemeClass helper cleanly encapsulates theme application logic, ensuring mutual exclusivity of theme classes.


71-81: Excellent refactor to prevent theme flicker.

Switching to useLayoutEffect ensures the theme is applied synchronously before the browser paints, eliminating the flash of incorrect theme on initial load or theme changes.

scripts/frontend-routes-generator/common.ts (1)

9-12: LGTM!

The getDirectories helper is cleanly implemented using modern fs APIs with proper filtering and mapping.

package.json (2)

22-22: LGTM!

The build script correctly integrates the pruning step after the build completes, ensuring generated artifacts don't ship with the production bundle.


30-31: LGTM!

The new script entries correctly use bun run and follow the project's naming conventions. Based on coding guidelines.

src/renderer/src/routes/games/config.tsx (1)

5-9: LGTM!

The removal of the Fallback property simplifies the route configuration and aligns with the broader RouteConfig type refactoring across the PR.

scripts/frontend-routes-generator/generator.ts (1)

34-63: No issues found — all route directories contain required files.

Verification confirms that all routes have both config.tsx and page.tsx files. The generator's assumptions are valid, and the relative imports will resolve correctly.

src/renderer/src/routes/omnibox/config.tsx (1)

5-8: LGTM: RouteConfig simplified.

The removal of Fallback: null simplifies the RouteConfig object and aligns with the broader refactoring pattern across multiple route configurations in this PR.

src/renderer/src/routes/error/config.tsx (1)

5-8: LGTM: Consistent with RouteConfig refactoring.

The Fallback removal matches the pattern applied consistently across route configurations.

src/renderer/src/routes/new-tab/config.tsx (1)

5-8: LGTM: RouteConfig simplified.

The Fallback removal is consistent with the broader refactoring. The persist prop on ThemeProvider is correctly preserved.

src/renderer/src/routes/settings/config.tsx (1)

5-8: LGTM: Consistent RouteConfig simplification.

The removal of Fallback matches the refactoring pattern applied across all route configurations.

src/main/modules/utils.ts (1)

110-117: LGTM: Standard Buffer to ArrayBuffer conversion.

The implementation correctly converts a Node.js Buffer to an ArrayBuffer using the standard pattern. Note that the returned ArrayBuffer shares the underlying memory with the original Buffer, so mutations to the Buffer would be reflected in the ArrayBuffer. This is typically fine for one-time conversions (e.g., serving HTTP responses), but be mindful if the source Buffer is reused or mutated elsewhere.

src/renderer/src/routes/main-ui/config.tsx (1)

5-8: LGTM: RouteConfig simplified.

The Fallback removal is consistent with the broader refactoring. The PortalsProvider wrapper is correctly preserved.

src/renderer/src/routes/pdf-viewer/page.tsx (1)

1-1: Migration verification complete—no issues found.

The nuqs migration is properly executed:

  • nuqs is installed in devDependencies (v2.7.2)
  • use-query-params is completely removed from package.json and codebase
  • The useQueryState destructuring pattern on lines 7-8 is identical to the previous implementation
  • The null/undefined check on line 9 (if (!url)) correctly handles both cases, consistent with previous behavior
  • Nullish coalescing on line 15 (cacheURL ?? url) is appropriate for handling potential undefined values
src/main/controllers/sessions-controller/protocols/types.ts (1)

1-1: Type definition is clean and properly used across the codebase.

The verification confirms that CustomProtocol is correctly typed in the registerProtocolsWithSession function signature as CustomProtocol[], and all calls pass valid protocol values. Hardcoded strings elsewhere (Electron API calls like protocol.registerSchemesAsPrivileged and protocol.handle) are necessary and appropriate for those APIs.

src/renderer/src/routes/omnibox-debug/config.tsx (1)

5-9: LGTM! Clean removal of Fallback property.

The RouteConfig now correctly contains only the Providers property, aligning with the updated RouteConfigType interface.

src/renderer/src/routes/about/config.tsx (1)

5-9: LGTM! Consistent with the RouteConfig refactor.

The change correctly removes the Fallback property while maintaining the ThemeProvider wrapper.

src/renderer/src/routes/popup-ui/config.tsx (1)

5-9: LGTM! Consistent refactor with appropriate provider.

The Fallback removal is consistent with other route configs, and the PortalsProvider is suitable for the popup UI route.

src/renderer/src/components/providers/nuqs-provider.tsx (1)

1-5: LGTM! Clean abstraction over NuqsAdapter.

The NuqsProvider component is a simple, well-typed wrapper that provides a consistent API for integrating nuqs query parameter management across routes.

src/renderer/src/routes/pdf-viewer/config.tsx (1)

11-19: LGTM! Consistent NuqsProvider integration.

The provider nesting is correct and consistent with the extensions route. The PDF viewer route appropriately uses NuqsProvider for query parameter management, likely for passing the PDF URL.

src/main/controllers/sessions-controller/protocols/_protocols/flow/index.ts (3)

11-14: LGTM! Proper Hono app initialization.

The Hono app is correctly initialized with a custom getPath transformer, which enables hostname-based routing for the Flow protocol.


16-23: LGTM! Well-organized route registration.

All route handlers are registered in a logical order, with static domains correctly registered last as the catch-all handler.


26-30: LGTM! Clean protocol handler implementation.

The Flow protocol handler correctly delegates requests to the Hono app, aligning with the PR's objective to use Hono for routing.

src/renderer/src/routes/onboarding/config.tsx (1)

5-9: LGTM! Consistent with the RouteConfig refactor.

The removal of the Fallback property aligns with the updated RouteConfigType interface across all route configurations.

src/renderer/src/routes/extensions/config.tsx (1)

6-14: Selective NuqsProvider usage is intentional and correct.

The codebase shows different query parameter patterns that justify selective NuqsProvider usage:

  • error route: Uses native URLSearchParams for one-time query param reads (errorCode, url) with URL history manipulation. No reactive state management needed.
  • extensions & pdf-viewer routes: Use NuqsProvider for reactive query state management, likely for features requiring reactive URL param tracking.

The nesting and selective application are appropriate given the distinct use cases.

src/main/controllers/sessions-controller/protocols/utils.ts (1)

92-95: Fix the URL parsing implementation.

Line 92 calls URL.parse(request.url), but the WHATWG URL class exposed in Electron/Node does not ship a static parse method. In practice this throws TypeError: URL.parse is not a function, so the protocol handler crashes on every request. Swap to new URL(request.url) (and fall back gracefully if parsing fails) or import parse from "node:url".

-  const url = URL.parse(request.url);
-  const hostname = url?.hostname;
-
-  return `/${hostname}${realPath}`;
+  try {
+    const hostname = new URL(request.url).hostname;
+    return hostname ? `/${hostname}${realPath}` : realPath;
+  } catch {
+    return realPath;
+  }
⛔ Skipped due to learnings
Learnt from: iamEvanYT
PR: MultiboxLabs/flow-browser#24
File: electron/browser/tabs/tab.ts:309-310
Timestamp: 2025-04-18T23:20:02.623Z
Learning: In the Flow Browser codebase, `URL.parse` is preferred over `new URL()` for URL parsing because it works without errors in the Electron runtime environment, even though TypeScript's type definitions require `ts-ignore` comments.

@iamEvanYT iamEvanYT merged commit 1ee519e into main Oct 30, 2025
9 of 10 checks passed
@iamEvanYT iamEvanYT deleted the evan/better-router branch October 30, 2025 18:38
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.

1 participant