Skip to content

Add user-local project icons#4401

Open
colonelpanic8 wants to merge 9 commits into
pingdotgg:mainfrom
colonelpanic8:feat/project-icons
Open

Add user-local project icons#4401
colonelpanic8 wants to merge 9 commits into
pingdotgg:mainfrom
colonelpanic8:feat/project-icons

Conversation

@colonelpanic8

@colonelpanic8 colonelpanic8 commented Jul 23, 2026

Copy link
Copy Markdown

What Changed

  • Added user-local projectIcons and projectIconsByGitRemote maps to the server settings.json, keyed by workspace root or normalized repository identity.
  • Workspace-specific icons override git-remote icons; missing overrides fall through to repository metadata and automatic discovery.
  • Custom icon paths may be absolute, home-relative (~/…), or project-relative. They override t3.json and automatic favicon discovery without changing the repository.
  • Added exact signed-asset capabilities for configured icons outside the workspace, while retaining compatibility with existing favicon URLs.
  • Added project-icon controls to the classic project context menu and Sidebar v2 project settings.
  • Added a direct Sidebar v2 interaction: right-click the project icon on a thread and choose Set/Change project icon….

Why

Project icons are currently discovered from files committed to each repository. Personal project organization should not require adding app-specific assets or metadata to the project itself. Git-remote keys also make a dotfile-backed setting portable across devices and clone paths while retaining exact-path overrides for worktrees or exceptional clones.

UI Changes

Before — automatic folder icon:

Automatic project icon

After — right-clicking the Sidebar v2 thread icon exposes the action:

Project icon context menu

After — the dialog shows the configured external icon and the persistent settings file:

Project icon dialog

After — a second clone at a different path inherits the normalized git-remote icon:

Portable git-remote project icon

Checklist

  • vp check
  • vp run typecheck
  • vp test run packages/contracts/src/settings.test.ts packages/shared/src/serverSettings.test.ts apps/server/src/project/ProjectFaviconResolver.test.ts apps/server/src/assets/AssetAccess.test.ts apps/server/src/serverSettings.test.ts apps/web/src/components/ProjectIconSettings.test.ts
  • Verified classic-sidebar project context menu in an isolated development environment.
  • Verified Sidebar v2 thread-icon right-click, persistence to settings.json, and a signed SVG asset outside the repository.
  • Verified one github.com/pingdotgg/t3code icon setting renders for two clones at different local paths.

Note

Add user-local project icon configuration to the sidebar

  • Adds support for configuring custom project icons per workspace path or git remote, stored in server settings under projectIcons and projectIconsByGitRemote.
  • Right-clicking a project favicon in the sidebar or SidebarV2 opens a context menu with 'Set/Change project icon...' that opens a dialog to enter a custom icon path (absolute, home-relative, or workspace-relative).
  • ProjectFaviconResolver now accepts customIconPaths and a new resolve method returns both the icon path and its source (custom-setting vs workspace); home-relative paths (~) are expanded automatically.
  • AssetAccess.issueAssetUrl for project favicons now reads server settings and repository identity to issue v2 project-icon claims carrying an absolute path; resolveAsset validates the canonical path matches before serving the file.
  • ProjectFavicon computes a revision token from settings and repository identity so cached URLs invalidate when icon settings change.
  • Risk: existing v1 project-favicon asset tokens continue to resolve via the old path, but new requests emit v2 tokens; mixed token versions may coexist during a transition period.

Macroscope summarized 9759616.


Note

Medium Risk
Signed asset serving now allows explicit paths outside the workspace and uses a new claim version; implementation adds symlink/canonical-path guards but this is still security-sensitive file access tied to user settings.

Overview
Adds user-local project icons stored in server settings.json (projectIcons by workspace root, projectIconsByGitRemote by normalized git remote), with workspace overrides winning over remote keys and automatic repo discovery unchanged when no override applies.

Server: ProjectFaviconResolver gains customIconPaths and a resolve result that tags icons as custom-setting vs workspace; AssetAccess loads settings and repository identity, signs v2 project-icon tokens with a canonical absolute path for configured icons outside the repo, and keeps v1 project-favicon resolution for existing tokens. Resolve-time checks reject symlink escapes and post-sign path swaps.

Contracts / shared: Settings schema, projectIconUpdate atomic patches, and applyProjectIconUpdate / applyServerSettingsPatch handle scope switches and resets. Optional revision on project-favicon asset requests and settingsConfigPath on server config support cache busting and UI copy.

Web: ProjectFavicon hashes settings + repository key into a revision for asset URLs. New Project icon flows in classic sidebar context menu, Sidebar V2 project settings / favicon right-click, and a dialog or inline path field with “use for all clones” when a git remote is known.

Reviewed by Cursor Bugbot for commit 9759616. Bugbot is set up for automated code reviews on this repo. Configure here.

Current combined-stack UI evidence (2026-07-24)

Captured from PR head 804efc44c5a8321667f51400b3c513af593cde82 on upstream main ece05087a70e94efcd57441337fa1249559362ba, using combined integration 4dd4cef40 and package /nix/store/pf7fjqw8ykkdgayf3ywsbgxxp6wi1m42-t3code-0.0.29-patched-main-20260724.

The settings capture shows an external SVG stored by normalized remote identity for every clone; the second capture shows the resulting custom tree icon in Sidebar V2 and the draft header. All names, remotes, paths, and assets are disposable seed data.

Portable custom project icon setting

Custom project icon rendered in Sidebar V2

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

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 Plus

Run ID: fe3e71aa-c89a-4afe-895e-70fa3aa2dc11

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

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.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 23, 2026
Comment thread apps/web/src/components/ProjectIconSettings.tsx
Comment thread apps/server/src/assets/AssetAccess.ts
Comment thread apps/web/src/components/ProjectIconSettings.tsx
Comment thread apps/web/src/components/ProjectFavicon.tsx Outdated
@macroscopeapp

macroscopeapp Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a substantial new feature (user-local project icons) with new UI components, settings schema, and server-side resolution logic. New features introducing new user-facing behavior and workflows warrant human review.

You can customize Macroscope's approvability policy. Learn more.

@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Jul 23, 2026
Comment thread apps/web/src/components/ProjectFavicon.tsx Outdated
Comment thread apps/web/src/components/ProjectIconSettings.tsx Outdated
Comment thread apps/web/src/components/ProjectIconSettings.tsx Outdated
Comment thread apps/web/src/components/ProjectFavicon.tsx Outdated
Comment thread apps/server/src/assets/AssetAccess.ts
Comment thread apps/server/src/assets/AssetAccess.ts
Comment thread apps/web/src/components/ProjectFavicon.tsx
Comment thread apps/web/src/components/ProjectIconSettings.tsx
Comment thread apps/web/src/components/ProjectFavicon.tsx Outdated
Comment thread apps/web/src/components/ProjectIconSettings.tsx
Comment thread apps/server/src/assets/AssetAccess.ts Outdated
Comment thread apps/web/src/components/ProjectIconSettings.tsx
Comment thread apps/web/src/components/ProjectIconSettings.tsx Outdated
Comment thread apps/web/src/components/ProjectIconSettings.tsx Outdated
Comment thread apps/web/src/components/ProjectIconSettings.tsx
Comment thread apps/web/src/components/ProjectIconSettings.tsx
Comment thread apps/web/src/components/SidebarV2.tsx

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5c2c09c. Configure here.

"remotes",
remoteEntries.sort(([left], [right]) => left.localeCompare(right)),
]);
return `icons:${revisionSource.length}:${hashProjectFaviconRevision(revisionSource)}`;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Revision misses normalized workspace keys

Medium Severity

projectFaviconSettingsRevision only reads projectIcons[cwd], while asset issuance also checks the normalized workspace root and the raw request cwd. When the stored key differs from the UI cwd string, the server can serve a custom icon but the client omits revision, so cached favicon URLs may stay stale for minutes.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5c2c09c. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 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.

1 participant