Skip to content

spec: File Tree icon themes (#9731)#10013

Open
lonexreb wants to merge 1 commit intowarpdotdev:masterfrom
lonexreb:spec/9731-file-tree-icon-themes
Open

spec: File Tree icon themes (#9731)#10013
lonexreb wants to merge 1 commit intowarpdotdev:masterfrom
lonexreb:spec/9731-file-tree-icon-themes

Conversation

@lonexreb
Copy link
Copy Markdown
Contributor

@lonexreb lonexreb commented May 4, 2026

Adds a product+tech spec for #9731: icon-theme support for the Project Explorer / File Tree, replacing today's hardcoded mapping in app/src/code/icon.rs with a small, data-driven theme registry that the community can extend via PRs.

Files

  • specs/GH9731/product.md (140 lines) — V1 scope, user experience, configuration shape, 10 testable behavior invariants
  • specs/GH9731/tech.md (270 lines) — module layout, theme model + registry types, integration with the existing icon_from_file_path call site, settings entry, bundled-theme catalog, end-to-end flow

Total: 538 insertions, 0 deletions. No code changes — this is a spec PR.

V1 scope (per reporter's pre-bounding in #9731)

  • Settings → Appearance dropdown picks the active theme.
  • Two bundled themes: default (byte-equivalent to today's mapping; zero visual regression) and material (alternative).
  • JSON theme format, modeled on the VS Code File Icon Theme spec: iconDefinitions + fileExtensions + fileNames + folderNames + folderNamesExpanded + file/folder/folderExpanded defaults.
  • Lookup order: exact filename → extension → folder name → file/folder fallback. Folder lookups have separate open/closed states.
  • Read-only catalog in V1: themes loaded from bundled assets only.

Out of V1 (tracked as follow-ups)

  • User-supplied theme files from disk (the reporter's primary community-contributable angle — explicitly suggested for V2).
  • In-app theme editor, per-file overrides, theme marketplace.
  • Language-ID-based resolution (current spec uses filename + extension only).
  • Per-icon tint: true flag in the theme JSON (V1 hard-codes the existing tint set used for md and sh).
  • Nerd Font codepoint format alternative.

Why this spec

  • The reporter pre-bounded V1 in their issue body — this spec adopts those bounds verbatim, plus the lookup order they describe.
  • Issue is ready-to-spec, no existing PR claims it.
  • Aligns with Warp's community-contributable trajectory: terminal themes scale via PRs precisely because they're data-driven; the file-tree icon set is on the opposite trajectory today, and this fixes that.
  • Implementation surface is small and well-isolated: one new module under app/src/code/, one new settings entry, the existing icon_from_file_path signature is preserved, only one render-site change to handle folder rendering.

Open questions for maintainers

  1. TOML key location. This spec uses appearance.file_tree_icon_theme. Confirm the right Rust setting group (AppearanceSettings vs a new FileTreeSettings) at implementation time.
  2. Material theme licensing. Material Icon Theme is MIT-licensed. If bundling is blocked, the V1 alternative ships as Warp-original Seti-inspired art instead — same theme system, different SVGs.
  3. docs/file-tree-icon-themes.md packaging. Recommend it ships in the same release as the implementation PR but does not block this spec.

Happy to iterate on the design or tighten the V1 scope further.

Adds product.md and tech.md for issue warpdotdev#9731: support icon themes for the
Project Explorer.

V1 scope (per reporter's pre-bounding):
- Settings → Appearance dropdown picks between bundled themes
- Two bundled themes: `default` (byte-equivalent to today's hardcoded
  mapping in app/src/code/icon.rs) and `material` (alternative)
- Documented JSON theme format (VS Code File Icon Theme-style):
  iconDefinitions + fileExtensions + fileNames + folderNames +
  folderNamesExpanded + file/folder/folderExpanded defaults
- Resolution order: filename → extension → folder name → fallback
- Read-only theme catalog (themes loaded from bundled assets only)

Out of V1 (tracked as follow-ups):
- User-supplied theme files from disk
- In-app theme editor, per-file overrides, theme marketplace
- Language-ID-based resolution
- Per-icon tint flag (V1 hard-codes the existing tint set for md/sh)
- Nerd Font codepoint format alternative

10 testable behavior invariants, each mapped to a test layer in tech.md.
Invariant 1 enforces byte-equivalence between the new default theme and
today's hardcoded mapping — zero visual regression for existing users.

Tech spec maps to existing call sites: app/src/code/icon.rs preserves
its function signature; app/src/code/file_tree/view/render.rs gets a
new folder_icon helper; settings entry plugs into the existing
define_settings_group! macro.
@cla-bot cla-bot Bot added the cla-signed label May 4, 2026
@github-actions github-actions Bot added the external-contributor Indicates that a PR has been opened by someone outside the Warp team. label May 4, 2026
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 4, 2026

@lonexreb

I'm starting a first review of this spec-only pull request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

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

Overview

This spec PR defines product and technical requirements for configurable File Tree icon themes, including bundled theme JSON, settings UI, registry lookup, and tests. The scope generally matches the linked issue, but several spec contradictions would lead to an implementation that fails the stated behavior invariants.

Concerns

  • The tech spec simultaneously says render.rs needs no changes and later requires folder-render changes for themed folder icons.
  • The folder lookup pseudocode does not implement the documented per-folder expanded-to-collapsed fallback and would fail invariant 6 when folderNamesExpanded is partially populated.
  • Missing asset handling is specified as fallthrough, but the registry pseudocode returns icon paths without any existence validation.
  • The default catalog example maps JavaScript extensions to the TypeScript key even though the current implementation uses javascript.svg, undermining the zero-regression requirement.

Security

  • The spec introduces community-contributed bundled SVG assets but leaves SVG safety constraints to a follow-up; add V1 acceptance criteria for safe bundled SVGs so the new asset format has a clear trust boundary.

Verdict

Found: 0 critical, 4 important, 1 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Comment thread specs/GH9731/tech.md
| Path | Role |
|---|---|
| `app/src/code/icon.rs` | The closed `match` to be replaced by the theme registry. The function signature `icon_from_file_path(path: &str, appearance: &Appearance) -> Option<Box<dyn Element>>` is preserved to keep the call site untouched. |
| `app/src/code/file_tree/view/render.rs` | Sole call site. Calls `icon_from_file_path` per row; falls back to `Icon::File`/`Icon::Folder` on `None`. No changes required to this file. |
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.

⚠️ [IMPORTANT] This says render.rs needs no changes, but Section 4 requires changing folder rendering to support themed folders; update this table so implementers do not skip the render-site change.

Comment thread specs/GH9731/tech.md
Comment on lines +87 to +93
let folder_map = if is_expanded
&& !self.file.folder_names_expanded.is_empty()
{
&self.file.folder_names_expanded
} else {
&self.file.folder_names
};
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.

⚠️ [IMPORTANT] This only falls back to folderNames when folderNamesExpanded is empty globally; if the expanded map has entries for other folders, a folder declared only in folderNames falls through to the generic default, contradicting invariant 6. Specify per-name fallback from folderNamesExpanded.get(name) to folderNames.get(name).

Comment thread specs/GH9731/tech.md
&self.file.folder_names
};
if let Some(key) = folder_map.get(name) {
if let Some(def) = self.file.icon_definitions.get(key) {
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.

⚠️ [IMPORTANT] resolve returns the referenced iconPath as soon as the key exists, so nonexistent assets cannot fall through to the next lookup step as product.md requires. Specify load-time validation that removes invalid definitions, or a runtime asset-existence check before returning.

Comment thread specs/GH9731/tech.md
"rs": "rs",
"json": "json",
"ts": "ts", "tsx": "ts",
"js": "ts", "jsx": "ts",
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.

⚠️ [IMPORTANT] Mapping js/jsx to the ts key contradicts the zero-regression default theme requirement and the current icon.rs JavaScript mapping; make the concrete catalog example byte-equivalent instead of leaving a contradictory note later.

Comment thread specs/GH9731/product.md
## Goals

- A user can switch the File Tree icon theme in **Settings → Appearance** without restarting Warp.
- The theme format is documented so a community PR adding a third theme is mechanical: drop a JSON file plus its referenced SVGs under the bundled assets directory and add an entry to the theme registry.
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.

💡 [SUGGESTION] [SECURITY] Since V1 allows community PRs to add bundled SVGs, include V1 asset constraints here: SVGs must be local bundled assets with no scripts, remote references, or unsafe external dependencies, rather than deferring SVG constraints entirely to follow-up docs.

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

Labels

cla-signed external-contributor Indicates that a PR has been opened by someone outside the Warp team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant