fix(vscode): pin theme extensions for 10 marketplace palettes

Before this fix, only the 6 palettes whose theme extensions ship in
pkgs.vscode-extensions had working VSCode theming. Every other palette
had `workbench.colorTheme` set to a name VSCode couldn't find, so it
silently fell back to its built-in default. Including the DEFAULT
summer-night palette (sainnhe.everforest) — the default install had
broken VSCode theming.

Probed the 13 unique extensions against the VSCode marketplace
extensionquery API:

  - 10 exist and are pinnable: sainnhe.everforest,
    shadesOfBuntu.flexoki-light, qufiwefefwoyn.kanagawa,
    oldjobobo.{lumon,miasma,retro-82}-theme, TahaYVR.matteblack,
    jovejonovski.ocean-green, monokai.theme-monokai-pro-vscode,
    Bjarne.white-theme.
  - 3 don't exist on the marketplace and are unpublished custom
    Nomarchy themes: Bjarne.{ethereal,hackerman,vantablack}-nomarchy.
    Logged as a new Later row.

For the 10, fetched version + sha256 via:

  URL='https://${publisher}.gallery.vsassets.io/_apis/public/gallery/publisher/${publisher}/extension/${name}/${version}/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage'
  nix store prefetch-file --hash-type sha256 "$URL"

Added a marketplaceExtensions list to features/apps/vscode.nix that
wraps each in pkgs.vscode-utils.extensionFromVscodeMarketplace and
concatenates with the existing nixpkgs-packaged list — so 10 more
palettes (including the default) now get correct VSCode theming on
first launch. Smoke-built sainnhe.everforest end-to-end. Module
comment documents the version-bump procedure.

docs/OPTIONS.md updated: the nomarchy.vscode.devExtensions entry
drops the "still break" caveat for everything except the three
unpublished Bjarne palettes.

`nix flake check --no-build` clean.
This commit is contained in:
Bernardo Magri
2026-05-22 20:21:43 +01:00
parent a901b1db0b
commit 9b26eda388
3 changed files with 68 additions and 15 deletions

View File

@@ -263,7 +263,7 @@ Without prime config, supergfxd still switches modes but render-offload via `nvi
### `nomarchy.vscode.devExtensions` ### `nomarchy.vscode.devExtensions`
`bool`, default `false`. Install Nomarchy's curated VSCode extension pack (Nix, language servers, theme variants). `bool`, default `false`. Install Nomarchy's curated VSCode extension pack (language servers + git + editor enhancements). The palette theme extensions are *always* installed regardless of this flag — every palette except `ethereal`, `hackerman`, and `vantablack` resolves its `workbench.colorTheme` via either `pkgs.vscode-extensions` (catppuccin/nord/tokyo-night/rose-pine/gruvbox) or `pkgs.vscode-utils.extensionFromVscodeMarketplace` with version + sha256 pinned (sainnhe.everforest, qufiwefefwoyn.kanagawa, monokai.theme-monokai-pro-vscode, oldjobobo.{lumon,miasma,retro-82}, shadesOfBuntu.flexoki-light, jovejonovski.ocean-green, TahaYVR.matteblack, Bjarne.white-theme). The three palettes whose theme extension isn't on the marketplace fall back to VSCode's default theme; see the ROADMAP Later row.
### `nomarchy.themeLoader.enable` ### `nomarchy.themeLoader.enable`

View File

@@ -36,7 +36,7 @@ _(empty — all entries shipped or moved to Later)_
- **Optional `nomarchy-installer-vm`** rebuilt as a real flake app (not a one-off shell script) so users can install Nomarchy into a libvirt VM declaratively. - **Optional `nomarchy-installer-vm`** rebuilt as a real flake app (not a one-off shell script) so users can install Nomarchy into a libvirt VM declaratively.
- **Surface support module** via the relevant `nixos-hardware` profile + Surface kernel patches behind a `nomarchy.hardware.isSurface` toggle. - **Surface support module** via the relevant `nixos-hardware` profile + Surface kernel patches behind a `nomarchy.hardware.isSurface` toggle.
- **High-contrast accessibility palette.** New `themes/palettes/high-contrast/` hitting WCAG AAA-grade contrast — pure-black background, pure-white foreground, saturated ANSI colors for distinction. Ships its own `colors.toml`, `icons.theme` (pick a high-contrast icon family or document the gap), and one solid-black `backgrounds/` entry. Pairs with `nomarchy.accessibility.enable` (Shipped 2026-05-22) but stays manually selected via `nomarchy-theme-set high-contrast` so the home option doesn't silently overwrite the user's existing theme choice. Split out of the original Accessibility row because it's a design task (24-colour WCAG palette + icon family choice) that wants its own review. - **High-contrast accessibility palette.** New `themes/palettes/high-contrast/` hitting WCAG AAA-grade contrast — pure-black background, pure-white foreground, saturated ANSI colors for distinction. Ships its own `colors.toml`, `icons.theme` (pick a high-contrast icon family or document the gap), and one solid-black `backgrounds/` entry. Pairs with `nomarchy.accessibility.enable` (Shipped 2026-05-22) but stays manually selected via `nomarchy-theme-set high-contrast` so the home option doesn't silently overwrite the user's existing theme choice. Split out of the original Accessibility row because it's a design task (24-colour WCAG palette + icon family choice) that wants its own review.
- **Package missing VSCode theme extensions via `extensionFromVscodeMarketplace`.** 15 of the 21 palettes that ship a `themes/palettes/<theme>/apps/vscode.json` declare a theme extension that isn't in `pkgs.vscode-extensions` — including `sainnhe.everforest` which is the default `summer-night` palette's theme. With the `577b3ae` fix in place, the 6 nixpkgs-packaged extensions install by default (catppuccin, catppuccin-latte, nord, tokyo-night, rose-pine, gruvbox), but the other 15 (`sainnhe.everforest`, `qufiwefefwoyn.kanagawa`, `monokai.theme-monokai-pro-vscode`, `oldjobobo.{lumon,miasma,retro-82}-theme`, `Bjarne.{ethereal,hackerman,vantablack,white}-nomarchy`, `shadesOfBuntu.flexoki-light`, `jovejonovski.ocean-green`, `TahaYVR.matteblack`) still leave `workbench.colorTheme` referencing an unloaded theme, so VSCode silently falls back. Fix: extend `features/apps/vscode.nix` to look up the active palette's extension via `pkgs.vscode-utils.extensionFromVscodeMarketplace { publisher; name; version; sha256; }` — each entry pinned by hash. Could be table-driven in `lib/` so a new palette only needs to add a row. - **Publish or replace `Bjarne.{ethereal,hackerman,vantablack}-nomarchy` VSCode theme extensions.** The `ethereal`, `hackerman`, and `vantablack` palettes' `apps/vscode.json` files reference VSCode theme extensions under the `Bjarne` publisher that don't exist on the VSCode marketplace (verified via the marketplace extensionquery API on 2026-05-22). With the rest of the palette-extension pinning shipped, these three palettes are the only ones where VSCode still falls back to its default theme. Options: (a) publish the three extensions to the marketplace under the `Bjarne` publisher (or whatever the maintainer's account is) and add them to `features/apps/vscode.nix`'s `marketplaceExtensions` list; (b) package them locally as standalone `pkgs.vscode-utils.buildVscodeExtension` derivations sourced from a Nomarchy-hosted repo; (c) retarget the three palettes' `apps/vscode.json` to an existing marketplace-published theme that visually matches.
## 3. Pillar: Script & menu audit ## 3. Pillar: Script & menu audit
@@ -147,6 +147,7 @@ Pillar is **done** when every component has a closed `wave/qa-<component>` PR an
(Move items here when they land — keep them brief, link the commit/PR.) (Move items here when they land — keep them brief, link the commit/PR.)
- _2026-05-22_ — **VSCode theme extensions pinned for 10 marketplace palettes.** Before this fix, only the 6 palettes whose theme extensions ship in `pkgs.vscode-extensions` (catppuccin, catppuccin-latte, nord, tokyo-night, rose-pine, gruvbox) had working VSCode theming — every other palette had `workbench.colorTheme` set to a theme VSCode couldn't find, so it silently fell back to the built-in default. Including the default `summer-night` palette (sainnhe.everforest), which meant the default install had broken VSCode theming. Probed all 13 unique extensions against the VSCode marketplace extensionquery API; 10 exist (`sainnhe.everforest`, `shadesOfBuntu.flexoki-light`, `qufiwefefwoyn.kanagawa`, `oldjobobo.{lumon,miasma,retro-82}-theme`, `TahaYVR.matteblack`, `jovejonovski.ocean-green`, `monokai.theme-monokai-pro-vscode`, `Bjarne.white-theme`) and 3 don't (`Bjarne.{ethereal,hackerman,vantablack}-nomarchy` — unpublished custom Nomarchy themes; logged as a new Later row). Fetched the latest version + sha256 for each of the 10 via `nix store prefetch-file` against `https://${publisher}.gallery.vsassets.io/_apis/public/gallery/publisher/${publisher}/extension/${name}/${version}/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage`. Added a `marketplaceExtensions` list to `features/apps/vscode.nix` that wraps each entry in `pkgs.vscode-utils.extensionFromVscodeMarketplace { publisher; name; version; sha256; }` and concatenates with the existing nixpkgs-packaged list. Smoke-built `sainnhe.everforest` end-to-end to confirm the URL pattern + sha256 resolve. Documented the version-bump procedure in the module comment. `docs/OPTIONS.md` updated to drop the "still break" caveat for everything except the three Bjarne palettes.
- _2026-05-22_ — **Chromium static `Default/Preferences` deleted.** `features/apps/chromium/default.nix` was deploying a 204-byte static `Default/Preferences` via Home Manager symlink into Chromium's mutable profile directory. Chromium expects to write that file at runtime, so the symlink-into-store deployment was structurally broken (Chromium either fails to save, or replaces the symlink on first write — losing whatever the static file claimed to set). The contents (`extensions.theme.{use_system,use_custom} = false`, `browser.theme.{color_scheme,user_color} = 2`) are duplicates of the managed-policy intent in `core/system/browser.nix` (`BrowserThemeColor` from palette `base00`, `BrowserColorScheme` from `isLightTheme`) — and worse, the static `color_scheme = 2` hardcoded "dark" while the policy is dynamic, so a light-palette user would have hit a conflict. Removed the whole `features/apps/chromium/` directory (8 lines + the 204-byte file) and dropped the import from `features/default.nix`. Chromium theming continues to flow through the system-level managed policy, which is the canonical chromium-on-NixOS path. - _2026-05-22_ — **Chromium static `Default/Preferences` deleted.** `features/apps/chromium/default.nix` was deploying a 204-byte static `Default/Preferences` via Home Manager symlink into Chromium's mutable profile directory. Chromium expects to write that file at runtime, so the symlink-into-store deployment was structurally broken (Chromium either fails to save, or replaces the symlink on first write — losing whatever the static file claimed to set). The contents (`extensions.theme.{use_system,use_custom} = false`, `browser.theme.{color_scheme,user_color} = 2`) are duplicates of the managed-policy intent in `core/system/browser.nix` (`BrowserThemeColor` from palette `base00`, `BrowserColorScheme` from `isLightTheme`) — and worse, the static `color_scheme = 2` hardcoded "dark" while the policy is dynamic, so a light-palette user would have hit a conflict. Removed the whole `features/apps/chromium/` directory (8 lines + the 204-byte file) and dropped the import from `features/default.nix`. Chromium theming continues to flow through the system-level managed policy, which is the canonical chromium-on-NixOS path.
- _2026-05-22_ — **Plymouth boot splash follows the active palette.** `themes/engine/plymouth/nomarchy.script` had `Window.SetBackgroundTopColor(0.101, 0.105, 0.149)` hardcoded — a Tokyo-Night-ish `#1a1b26` — and `nomarchy.plymouth` had a matching `ConsoleLogBackgroundColor=0x1a1b26`. Both were frozen regardless of `nomarchy.system.theme`. Replaced the literals with `@BG_R@`/`@BG_G@`/`@BG_B@`/`@BG_HEX@` placeholders; `themes/engine/plymouth.nix` now reads the active palette via `nomarchyLib.getPalette config.nomarchy.system.theme`, converts `palette.base00` into three 0.01.0 floats (Nix has no FP math, so `(byte * 1000) / 255` integer division formatted as `0.XXX`), and `sed`-substitutes during `installPhase`. Smoke-built the derivation against the default `summer-night` palette: emits `0.176, 0.207, 0.231` (matches `0x2d353b`) and `ConsoleLogBackgroundColor=0x2d353b`. Closes the "Plymouth theme variants per palette" Next-column item. - _2026-05-22_ — **Plymouth boot splash follows the active palette.** `themes/engine/plymouth/nomarchy.script` had `Window.SetBackgroundTopColor(0.101, 0.105, 0.149)` hardcoded — a Tokyo-Night-ish `#1a1b26` — and `nomarchy.plymouth` had a matching `ConsoleLogBackgroundColor=0x1a1b26`. Both were frozen regardless of `nomarchy.system.theme`. Replaced the literals with `@BG_R@`/`@BG_G@`/`@BG_B@`/`@BG_HEX@` placeholders; `themes/engine/plymouth.nix` now reads the active palette via `nomarchyLib.getPalette config.nomarchy.system.theme`, converts `palette.base00` into three 0.01.0 floats (Nix has no FP math, so `(byte * 1000) / 255` integer division formatted as `0.XXX`), and `sed`-substitutes during `installPhase`. Smoke-built the derivation against the default `summer-night` palette: emits `0.176, 0.207, 0.231` (matches `0x2d353b`) and `ConsoleLogBackgroundColor=0x2d353b`. Closes the "Plymouth theme variants per palette" Next-column item.
- _2026-05-22_ — **`nomarchy.overrides.*` loader implemented.** The option surface (`enable`, `paths`) had existed in `core/home/overrides.nix` since 2026-05-18 but did nothing — `paths` was a reserved attrset that never reached `xdg.configFile`. Now wired: every entry in `nomarchy.overrides.paths` substitutes the matching `xdg.configFile.<key>.source` at `lib.mkForce` priority, beating Nomarchy's own `lib.mkDefault` writes. Other fields on the original entry (`recursive` etc.) survive via the standard module-system merge. Picked the attrset model from the row's two options rather than runtime `~/.config/nomarchy/overrides/` directory discovery — Nix needs every managed file declared at evaluation time, and the attrset matches the explicit-config shape used everywhere else in the Nomarchy surface. `docs/OPTIONS.md` updated: both `overrides.{enable,paths}` entries gain real content + an example, the `configOverrides` row now contrasts bulk-vs-per-file accurately, and the "Where these are defined" footer drops the (reserved) tag. Closes the Next-column row. Unlocks the future replacement for the removed Setup→Config menu. - _2026-05-22_ — **`nomarchy.overrides.*` loader implemented.** The option surface (`enable`, `paths`) had existed in `core/home/overrides.nix` since 2026-05-18 but did nothing — `paths` was a reserved attrset that never reached `xdg.configFile`. Now wired: every entry in `nomarchy.overrides.paths` substitutes the matching `xdg.configFile.<key>.source` at `lib.mkForce` priority, beating Nomarchy's own `lib.mkDefault` writes. Other fields on the original entry (`recursive` etc.) survive via the standard module-system merge. Picked the attrset model from the row's two options rather than runtime `~/.config/nomarchy/overrides/` directory discovery — Nix needs every managed file declared at evaluation time, and the attrset matches the explicit-config shape used everywhere else in the Nomarchy surface. `docs/OPTIONS.md` updated: both `overrides.{enable,paths}` entries gain real content + an example, the `configOverrides` row now contrasts bulk-vs-per-file accurately, and the "Where these are defined" footer drops the (reserved) tag. Closes the Next-column row. Unlocks the future replacement for the removed Setup→Config menu.

View File

@@ -7,24 +7,76 @@ let
else else
{ name = "Default Dark Modern"; }; { name = "Default Dark Modern"; };
# Theme extensions matching palette vscode.json `extension` fields. Always # Theme extensions matching palette vscode.json `extension` fields.
# installed because workbench.colorTheme is set unconditionally from the # Always installed because workbench.colorTheme is set unconditionally
# active palette — without the matching extension VSCode silently falls # from the active palette — without the matching extension VSCode
# back to its default theme. Only the extensions available in # silently falls back to its default theme.
# pkgs.vscode-extensions are listed. Palettes whose theme extension is on #
# the VSCode marketplace but not packaged in nixpkgs (sainnhe.everforest — # The list is split because nixpkgs doesn't package every theme our
# affects the DEFAULT summer-night palette — plus qufiwefefwoyn.kanagawa, # palettes use. Six are in pkgs.vscode-extensions; the rest are pulled
# monokai.theme-monokai-pro-vscode, oldjobobo.*, Bjarne.*, # from the VSCode marketplace via extensionFromVscodeMarketplace with
# shadesOfBuntu.flexoki-light, jovejonovski.ocean-green, TahaYVR.matteblack) # publisher / name / version / sha256 pinned. To refresh a version,
# still break and need pkgs.vscode-utils.extensionFromVscodeMarketplace — # bump the `version` and `nix-prefetch-url` the new .vsix:
# tracked in ROADMAP Later. #
themeExtensions = with pkgs.vscode-extensions; [ # URL='https://${publisher}.gallery.vsassets.io/_apis/public/gallery/publisher/${publisher}/extension/${name}/${version}/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage'
# nix store prefetch-file --hash-type sha256 "$URL"
#
# Three palette extensions remain unfixed because the corresponding
# marketplace entries don't exist — Bjarne.ethereal-nomarchy,
# Bjarne.hackerman-nomarchy, Bjarne.vantablack-nomarchy. The matching
# palettes (ethereal, hackerman, vantablack) still fall back to
# VSCode's default theme; see the ROADMAP Later row for next steps.
marketplaceExtensions = with pkgs.vscode-utils; [
(extensionFromVscodeMarketplace { # everforest, summer-day, summer-night
publisher = "sainnhe"; name = "everforest"; version = "0.3.0";
sha256 = "sha256-nZirzVvM160ZTpBLTimL2X35sIGy5j2LQOok7a2Yc7U=";
})
(extensionFromVscodeMarketplace { # flexoki-light
publisher = "shadesOfBuntu"; name = "flexoki-light"; version = "1.0.0";
sha256 = "sha256-//y9uvIUGGDEhd8inDHvNy2e1IKNx6hSfO9sxNOTcUE=";
})
(extensionFromVscodeMarketplace { # kanagawa
publisher = "qufiwefefwoyn"; name = "kanagawa"; version = "1.5.1";
sha256 = "sha256-AGGioXcK/fjPaFaWk2jqLxovUNR59gwpotcSpGNbj1c=";
})
(extensionFromVscodeMarketplace { # lumon
publisher = "oldjobobo"; name = "lumon-theme"; version = "0.0.7";
sha256 = "sha256-YlO1r1JjaumiicvMk5fBr+PZCYFaII03PaLiyqE35Go=";
})
(extensionFromVscodeMarketplace { # matte-black
publisher = "TahaYVR"; name = "matteblack"; version = "1.0.3";
sha256 = "sha256-wn/llGidzyPd91XT3xVqAvaU4NcTTggTSz8WmUcV8HM=";
})
(extensionFromVscodeMarketplace { # miasma
publisher = "oldjobobo"; name = "miasma-theme"; version = "0.1.1";
sha256 = "sha256-STFTGFhQqxocr+YNFQp36IQWJRKTDBgBg4MOCOq1IPQ=";
})
(extensionFromVscodeMarketplace { # osaka-jade
publisher = "jovejonovski"; name = "ocean-green"; version = "1.1.2";
sha256 = "sha256-sUNjnzqXya23Uieg8RLcEfnxiX0ImZ6CIjFtSJ66vM4=";
})
(extensionFromVscodeMarketplace { # retro-82
publisher = "oldjobobo"; name = "retro-82-theme"; version = "0.1.4";
sha256 = "sha256-GqFeFFG5scO7CEXlKjj6uoilCoUfpRaQa5jBSnNJyJA=";
})
(extensionFromVscodeMarketplace { # ristretto
publisher = "monokai"; name = "theme-monokai-pro-vscode"; version = "2.0.13";
sha256 = "sha256-5bKwVzDfZoSipR04tPDx9jbKhYsSsa3z6Ei9E2jhudo=";
})
(extensionFromVscodeMarketplace { # white
publisher = "Bjarne"; name = "white-theme"; version = "0.0.1";
sha256 = "sha256-3ZyWNVlQO3Tof49FFF3OImuo7hgtJXLNuwQ+iHjzzGk=";
})
];
themeExtensions = (with pkgs.vscode-extensions; [
catppuccin.catppuccin-vsc # catppuccin, catppuccin-latte catppuccin.catppuccin-vsc # catppuccin, catppuccin-latte
enkia.tokyo-night # tokyo-night enkia.tokyo-night # tokyo-night
arcticicestudio.nord-visual-studio-code # nord arcticicestudio.nord-visual-studio-code # nord
mvllow.rose-pine # rose-pine mvllow.rose-pine # rose-pine
jdinhlife.gruvbox # gruvbox jdinhlife.gruvbox # gruvbox
]; ]) ++ marketplaceExtensions;
# Development extensions — opt-in via nomarchy.vscode.devExtensions. # Development extensions — opt-in via nomarchy.vscode.devExtensions.
devExtensions = with pkgs.vscode-extensions; [ devExtensions = with pkgs.vscode-extensions; [