Skip to content

fix: improve project favicon detection for monorepos#1024

Open
ponbac wants to merge 2 commits intopingdotgg:mainfrom
ponbac:favicon-recursive
Open

fix: improve project favicon detection for monorepos#1024
ponbac wants to merge 2 commits intopingdotgg:mainfrom
ponbac:favicon-recursive

Conversation

@ponbac
Copy link

@ponbac ponbac commented Mar 13, 2026

What Changed

Improve project favicon detection without introducing a broad recursive search.
Closes #1020.

Rules, in order:

  • Check well-known favicon paths in the requested project root.
    Example: /repo/favicon.svg or /repo/public/favicon.ico.
  • If none exist, look for <link rel="icon" ... href="..."> tags or object-style { href, rel: "icon" } declarations in a small set of common source files, then resolve that target.
    Example: /repo/index.html points to /brand/logo.svg, so the route first tries /repo/public/brand/logo.svg and then /repo/brand/logo.svg.
  • If still nothing is found, repeat the same checks for first-level children of apps/ and packages/, plus other top-level directories in the requested root, using the same non-git directory ignore rules as workspaceEntries.
    Example: /repo/apps/web/public/favicon.png or /repo/frontend/public/favicon.png is found when the cwd is /repo.
  • Prefer a root match over nested workspace matches.
    Example: /repo/favicon.svg wins over /repo/apps/web/public/favicon.ico.
  • Fall back to the existing generated SVG when nothing is found.

I also extracted the shared gitignore probing into apps/server/src/gitIgnore.ts so both workspaceEntries and projectFaviconRoute use the same chunked git check-ignore --no-index -z --stdin filtering. I also extracted the shared workspace directory ignore policy into apps/server/src/workspaceIgnore.ts, so projectFaviconRoute now uses the same non-git skip rules as workspaceEntries when scanning nested roots instead of keeping a separate ignore list.

Why

The current behavior misses common monorepo layouts where the favicon lives under an app directory instead of the repo root.

There was already an earlier PR for this in the upstream repo: #690. That version was larger and messier. This keeps the rules simple on purpose, leaving more extensive changes to project icons for trusted maintainers.

UI Changes

Not applicable.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Note

Improve project favicon detection to support monorepos and respect .gitignore

  • Rewrites tryHandleProjectFaviconRequest in projectFaviconRoute.ts as an Effect-based handler using FileSystem; now prefers a root favicon, then searches nested apps/ and packages/ directories, and falls back to a built-in SVG.
  • Extracts favicon hrefs from HTML and TSX source files when no well-known favicon file is found, supporting both /public/<href> and app-relative paths.
  • Adds gitIgnore.ts with filterGitIgnoredPaths (using git check-ignore) and isInsideGitWorkTree; ignored directories and files are skipped during favicon search and workspace indexing.
  • Extracts shared ignore logic into workspaceIgnore.ts and updates workspaceEntries.ts to use it.
  • Risk: the favicon route now requires an Effect runtime with FileSystem; wsServer.ts is updated to provide this, but any other callers would need the same.

Macroscope summarized d07c91b.

@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 6d8821c9-b99b-455d-80c2-80ba94c6bd2f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

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.

@github-actions github-actions bot added size:XL 500-999 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Mar 13, 2026
@ponbac ponbac force-pushed the favicon-recursive branch 2 times, most recently from 30cac2c to b936f17 Compare March 13, 2026 13:47
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a4a8d330eb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ponbac ponbac force-pushed the favicon-recursive branch 2 times, most recently from c396c88 to 551d9f2 Compare March 14, 2026 08:09
@eddieajau
Copy link

My 2c

getIgnore.ts should be separated into individual commands for isInsideGitWorkTree, filterGitIgnoredPaths. You've done the right think pulling it out, but it could go further.

I would add unit tests for this file rather than relying on integration tests.

Since this is a new file, I would also add some solid docblocks to provide good human and AI context for the decisions being made. Hopefully the reviewers will pick that up and think it's a good idea for their code standards.

@github-actions github-actions bot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Mar 14, 2026
@ponbac
Copy link
Author

ponbac commented Mar 14, 2026

My 2c

getIgnore.ts should be separated into individual commands for isInsideGitWorkTree, filterGitIgnoredPaths. You've done the right think pulling it out, but it could go further.

I would add unit tests for this file rather than relying on integration tests.

Since this is a new file, I would also add some solid docblocks to provide good human and AI context for the decisions being made. Hopefully the reviewers will pick that up and think it's a good idea for their code standards.

Not sure about separating them right now, but I also feel like isInsideGitWorkTree() should live somewhere else. It does not really have anything to do with .gitignore.

I agree with the unit tests, added now.

Also added an explanatory comment to the filterGitIgnoredPaths(). I should maybe add additional ones, but I am not sure what is preferred here.

@ponbac ponbac force-pushed the favicon-recursive branch from 80c01a3 to d07c91b Compare March 14, 2026 16:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

monorepo projects do not resolve nested app favicons

2 participants