Skip to content

fix(zed-theme): stop the installer from reloading the window manager - #137

Merged
neur0map merged 1 commit into
Ryoku-dev:mainfrom
Satirito:fix/zed-theme-installer-materialize-and-theme-regex
Oct 25, 2026
Merged

neur0map merged 1 commit into
Ryoku-dev:mainfrom
Satirito:fix/zed-theme-installer-materialize-and-theme-regex

Conversation

@Satirito

@Satirito Satirito commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Why

Installing Ryoku for Zed ended with ryoku materialize. That reloads the compositor, which on a hybrid NVIDIA multi-monitor setup re-initialises DRM/KMS: the screens go black and the resolution can change. That is a heavy price for picking a theme.

The same run also aborted on current Zed settings. The installer used a line regex that only matched "theme": "Name", but Zed now writes an object:

"theme": {
  "mode": "system",
  "light": "Ayu Light",
  "dark": "Ayu Dark"
}

What changed

  • No more ryoku materialize. The initial theme.ts --sync already writes ryoku-dynamic.json, and the post_hook registered moments earlier rebuilds it on the next palette change. Nothing is lost; the screens are left alone.

  • A JSONC-aware settings editor replaces the regex. It masks comments and string bodies (UTF-16 offsets, so emoji cannot shift positions), reads the top-level theme value only, and writes:

    • plain string form ("theme": "..."),
    • object form, updating dark/light and filling in whichever key is missing.

    Comments, indentation and trailing commas are preserved. If the file is not valid JSONC, or its shape is unexpected, the installer prints a warning and continues instead of aborting the install.

  • Ordering fix: the sync command is now created before install-sync.ts registers the Matugen hook, so the hook can never point at a missing executable. install-sync.ts also refuses a relative path or a command that is not executable.

  • Regression test tests/ryoku-zed-theme-installer.test.sh covers object form, string form, comments (including an emoji), trailing comments, empty/nested theme objects, root insertion, root arrays, missing settings.json, and the missing-command abort. It also asserts the installer never calls ryoku and that both installer copies stay byte-identical. Wired into .github/workflows/validate.yml.

  • Bundle bumped to 1.2.0; bundle.json hashes and bundles/registry.json refreshed.

Testing

  • bash tests/ryoku-zed-theme-installer.test.sh — PASS (Node 26 locally; bundle requires ≥ 22.18)
  • bash tests/validate-catalogue.sh — PASS
  • python3 tests/validate-store.py — PASS
  • Manual installer run in a throwaway HOME against a copy of a real Zed settings.json: only the light/dark values changed, comments survived, no ryoku call was made.

shellcheck is not installed locally; the workflow runs it on merge.

Submission checks

This is a fix to an existing bundle, not a new item, so the item checklist applies only where it can.

  • One folder under bundles/ryoku-zed-theme/, manifest and preview images unchanged.
  • Registry entry updated in place: version 1.2.0 and the regenerated manifestSha256.
  • Tested against a real Zed settings.json in a throwaway HOME (object theme, comments, trailing commas); the real desktop was not touched.
  • tests/validate-catalogue.sh prints catalogue OK.
  • python3 tests/validate-store.py passes.
  • python3 tools/security-screen.py --root . --revision HEAD reports 0 blocking findings (147 advisory warnings, none in the changed files).
  • No compositor in the code: the removed call was the only compositor-facing line, and the remaining mention of Hyprland is a comment explaining why it must not come back.
  • No privileged commands, no new downloads, no network access; the installer only writes the theme, its own command, and the Matugen post_hook it already owned.

The installer finished by running `ryoku materialize`, which reloads the
compositor. On hybrid NVIDIA multi-monitor setups that re-initialises DRM/KMS,
blanks the monitors and can change the resolution just because someone
installed a Zed theme.

The initial `theme.ts --sync` already writes ryoku-dynamic.json, and the
Matugen post_hook registered right before it applies the theme on the next
palette change, so materialize was never needed. Drop it.

The settings editor was a line regex that only understood
`"theme": "..."`. Zed's current settings use
`"theme": { "mode": ..., "light": ..., "dark": ... }`, so the installer
aborted instead of selecting the theme. Replace the regex with a small
JSONC-aware editor: it masks comments and string bodies (UTF-16 safe, so
emojis do not shift offsets), reads the top-level theme value, and writes
either form while preserving comments, indentation and trailing commas.
Unparseable input is reported and left untouched rather than failing the
install.

Also create the sync command before install-sync.ts registers the hook, so
the hook can never point at a missing executable, and add a regression test
covering every shape, wired into the catalogue workflow.

Bump the bundle to 1.2.0.
@Satirito
Satirito requested a review from neur0map as a code owner October 25, 2026 11:37
@neur0map
neur0map merged commit bc9b9a8 into Ryoku-dev:main Oct 25, 2026
1 check passed
@neur0map

Copy link
Copy Markdown
Member

Thanks for the fix, it's live in the store now.

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.

2 participants