Skip to content

feat(zcode-beautify): wallpaper and Monet theming plugin (v6.3.0, opt-in experimental CDP + Bubble Studio UI) - #87

Open
Mc-GrowlR wants to merge 1 commit into
zai-org:mainfrom
Mc-GrowlR:feat/zcode-beautify
Open

Mc-GrowlR wants to merge 1 commit into
zai-org:mainfrom
Mc-GrowlR:feat/zcode-beautify

Conversation

@Mc-GrowlR

@Mc-GrowlR Mc-GrowlR commented Oct 13, 2026 •

Copy link
Copy Markdown

Updated 2026-11-15 (rebased onto latest main): the conflict with marketplace.json is resolved — every existing entry kept, mine re-added at the end. Per the intake guidance the plugin now lives under external_plugins/zcode-beautify/ (community publisherType, source ./external_plugins/zcode-beautify), and its prebuilt bundles ship as bundle/ since the marketplace packaging contract reserves dist/ for in-repo builds.

Updated 2026-11-14 (v6.3.0): addresses the review feedback — the CDP launch/injection layer is now an explicit opt-in experimental capability (disabled by default) with recovery guidance for disable / uninstall / upgrades (see "Experimental opt-in" below). Since 6.2.0 the plugin is also a UI plugin: it ships Bubble Studio, an MCP Apps interactive page. Marketplace entry + manifest bumped to 6.3.0.

Plugin type (required) / 插件类型(必填)

Select exactly one before requesting review. / 发起评审前必须且只能勾选一项。

  • Standard plugin / 普通插件(非 UI) — does not provide MCP Apps interactive pages / 不提供 MCP Apps 交互页面
  • UI Plugin / 是 UI 插件 — provides MCP Apps interactive pages / 提供 MCP Apps 交互页面
  • Not applicable / 不适用 — repository-only changes; no plugin content changed / 仅仓库级改动,不涉及插件内容

Affected plugin name(s) / 涉及的插件名称:zcode-beautify

What / 改动内容

New plugin zcode-beautify (v6.3.0): wallpaper + Material Design 3 (Monet) theming for the ZCode desktop client.

  • Sets an image (or a Wallpaper Engine scene / video) as the ZCode background by injecting a wallpaper layer into the renderer; scenes are rendered in Wallpaper Engine, recorded, processed into seamless loops, cached (content-addressed, 10 GB cap) and streamed over local HTTP.
  • Extracts a Monet source color from the wallpaper and maps light/dark MD3 palettes onto ZCode's semantic CSS variables.
  • Ships a live in-app settings panel (blur / dim / framing, chat-area masks, wallpaper library with batch scene import, rotation playlists, config export/import), the /beautify and /bubble commands, the beautify skill, and a stdio MCP server with 12 tools: set_background, import_scene_wallpaper, apply_options, refresh_theme, reset_appearance, beautify_status, bubble_studio_state, save_bubble_recipe, delete_bubble_recipe, enable_experimental, disable_experimental, repair_launchers.
  • UI plugin: since 6.2.0 the plugin ships Bubble Studio (ui://zcode-beautify/bubble-studio.html, text/html;profile=mcp-app), an interactive in-chat gallery for editing chat bubble styles (presets + saved recipes, per-card scoped preview, sliders for tint / radius / width), applied to the real conversation via apply_options (which returns _meta.ui.resourceUri). Declared in the manifest under ui.surfaces (id bubble-studio, availability session).
  • Chat-area personalization: message column width (+ edge drag handles), long-session smooth mode, sidebar list paging, custom settings FAB, session hover preview cards, custom loading icon, sidebar dim, elapsed-time trim.
  • Experimental opt-in (CDP injection) — disabled by default (since 0.6.0): the wallpaper/theme injection mechanism bypasses the plugin UI API over CDP, so it stays behind an explicit gate. Until the user opts in (enable_experimental, or zcode-beautify enable), the plugin starts no background service, writes nothing to any launch entry, and the agent-side tools answer with guidance instead of acting. Opting in records consent (timestamp + plugin version), adds --remote-debugging-port=9222 to the launch entries, and starts the local service. The opt-in section documents the exposure plainly: the CDP port binds to 127.0.0.1 (loopback only) but is unauthenticated Chromium behavior — any process running as your user can attach while it is open — so it should not be enabled on machines with untrusted local users or software.
  • Recovery / uninstall / upgrades (both READMEs): disable_experimental / zcode-beautify disable is a full rollback — stops the service, clears the injected theme including the renderer's cached copy, and strips the flag from the launch entries again; zcode-beautify repair-launchers --remove strips just the flag; uninstalling = run node <plugin>/bundle/cli.js disable first, then remove the plugin; upgrades — while disabled nothing is ever re-added, while enabled the self-heal re-adds the flag after ZCode's updater rebuilds shortcuts.
  • Registered in the root marketplace.json (category utilities, icon added at assets/zcode-beautify/icon.png); name / version / description_i18n (en + zh-CN) match between the marketplace entry and .zcode-plugin/plugin.json.

What user problem it solves: ZCode's UI appearance is fixed; this plugin personalizes the desktop client end-to-end (background + full theme + chat layout) without modifying ZCode's installation files, and lets the agent manage it through MCP tools and an interactive page.

Visible behavior and how it was tested

Tested on Windows with the ZCode desktop client; this code line has been in daily use on the maintainer's machine — image wallpaper + Monet apply; live panel tuning (sliders preview instantly and persist); Wallpaper Engine scene import (render → record → seamless loop → cache; re-imports instant); batch import; rotation playlists (sequence / random / daily schedule); Bubble Studio apply-to-conversation; sidebar list paging; custom FAB; reset restoring the stock look. The opt-in gate was exercised end-to-end: tools refuse with guidance before opt-in; enable → service starts + launch entries carry the flag; disable → full rollback verified against every launch-entry type (shortcuts, zcode:// handler, context-menu verbs).

npm test passes (jsdom lifecycle tests per feature + normalize / payload-gating / wiring assertions); python3 scripts/validate.py (OK: 34 plugin(s) validated) and python3 scripts/build_dist.py (deterministic plugins/zcode-beautify/6.3.0/plugin.zip) pass on this tree.

Dependencies, network, permissions, side effects

  • Runs node from PATH (like the other Node-based plugins). prebuilt esbuild bundles ship in the package (bundle/), so installation needs no build step: @modelcontextprotocol/sdk (MIT), @material/material-color-utilities (Apache-2.0), jimp (MIT).
  • Only after explicit opt-in: starts one background local Node service (serve) — HTTP on 127.0.0.1:9223 with a random per-start token — and adds --remote-debugging-port=9222 to ZCode's launch entries (fully reversible, see above). Scene/video import (Windows-only) additionally launches Wallpaper Engine and ffmpeg; the panel file picker uses a PowerShell dialog on Windows.
  • Writes runtime data (config, wallpaper copies, poster/thumbnail/scene-loop caches) only into the plugin data directory (wired via ZCODE_BEAUTIFY_DATA_DIR); never writes into its install directory; never modifies ZCode's installation files.
  • No external network access at runtime.
  • Licensing / provenance: MIT-licensed fork of Logocceai/zcode-beautify; the LICENSE retains the original copyright.

Self-check / 自查清单

  • Plugin name is unique kebab-case; directory is external_plugins/<name>/ (community publisherType)
  • Plugin type and affected names are declared above
  • version bumped in BOTH plugin.json and marketplace.json (artifacts are immutable) — 0.4.0 → 6.3.0
  • README.md (EN) and README_CN.md (中文) both updated and equivalent
  • description_i18n has both en and zh-CN, identical in the manifest and the marketplace entry
  • No secrets, machine-specific paths, or private dependencies
  • Model/API/network dependencies documented
  • python3 scripts/validate.py and python3 scripts/build_dist.py pass locally

@panda920

Copy link
Copy Markdown
Collaborator

✅ Internal validation passed. A ZCode maintainer will review the change next; after acceptance, release checks run separately and this PR is closed automatically.

@jacksonliuyn

Copy link
Copy Markdown
Collaborator

Thanks for the implementation and the detailed notes. I’d like to clarify one boundary: the plugin launches ZCode with --remote-debugging-port=9222, persists that flag into the launch shortcuts, and injects DOM/CSS into the renderer over CDP. Although it does not modify app.asar, this still bypasses the plugin UI API, and the debugging port gives other local processes a fairly broad level of control over the renderer. Could this be marked as an explicit opt-in/experimental capability, with clear recovery guidance for uninstall and upgrades, until the desktop client provides a supported extension point? Happy to discuss a safer integration approach as well. Thanks!

@Mc-GrowlR Mc-GrowlR changed the title feat(zcode-beautify): add wallpaper and Monet theming plugin feat(zcode-beautify): wallpaper and Monet theming plugin (v6.3.0, opt-in experimental CDP + Bubble Studio UI) Nov 14, 2026
@Mc-GrowlR

Copy link
Copy Markdown
Author

Thanks for the clear boundary framing — agreed on all points. The branch is now updated to v6.3.0 (commit 60c0552) implementing exactly this:

Explicit opt-in / experimental gate (off by default, since 0.6.0):

  • Before opt-in the plugin does nothing invasive: no background service, no launch-entry writes, and the agent-side tools (set_background, apply_options, …) only return guidance instead of acting. Nothing happens automatically on install or update.
  • Opting in is a deliberate user action: enable_experimental (MCP), zcode-beautify enable (CLI), or the panel's gate switch. It records consent (timestamp + plugin version) in the plugin config before touching anything.
  • The manifest/marketplace descriptions and both READMEs now state it up front: "The CDP injection layer is an explicit opt-in experimental capability (disabled by default)."
  • The opt-in section also documents the exposure honestly: the CDP port binds to 127.0.0.1 (loopback only) but is unauthenticated Chromium behavior — any process running as your user can attach to the renderer while it's open — so it shouldn't be enabled on machines with untrusted local users or software. The plugin's own control API is separately token-gated.

Recovery guidance (README "Experimental opt-in (CDP injection)" section, EN + CN):

  • disable_experimental / zcode-beautify disable — full rollback: stops the service, clears the injected theme including the renderer's cached copy, and strips --remote-debugging-port=9222 from every launch entry it had touched. Stored wallpaper settings are kept, so re-enabling later restores the look.
  • zcode-beautify repair-launchers --remove — strips just the flag, without touching anything else.
  • Uninstall: run node <plugin>/dist/cli.js disable first, then remove the plugin.
  • Upgrades: while disabled, nothing is ever re-added; while enabled, ZCode's updater rebuilding shortcuts is healed on the next start — and the commands above always strip it back.

One additional change to flag: since 6.2.0 the plugin is no longer standard-only — it ships Bubble Studio, an MCP Apps interactive page (ui.surfaces, session-level, plus _meta.ui.resourceUri on apply_options), so I've updated the PR type above to UI plugin. The manifest now declares mcpServers inline (repo convention) with the plugin data dir passed via ZCODE_BEAUTIFY_DATA_DIR, and CHANGES.md ships with the package for the in-panel changelog window.

Happy to discuss a safer integration approach as well — if the desktop client grows a supported extension point for background/theming, the injection layer would be retired in its favor; until then it stays behind this gate.

Verification on this tree: python3 scripts/validate.py → OK: 34 plugin(s) validated; python3 scripts/build_dist.py → deterministic plugins/zcode-beautify/6.3.0/plugin.zip; npm test → all suites green (exit 0).

@panda920

Copy link
Copy Markdown
Collaborator

Thanks for the contribution! This PR no longer applies cleanly on top of the latest main (conflicts in: marketplace.json). Please rebase onto main and push again; it will be picked up automatically.

🤖 Copy this prompt into Claude Code / Codex to fix it
You are updating my pull request #87 to github.com/zai-org/zcode-plugins (the ZCode plugin marketplace).
The maintainers' automated intake reported: the PR conflicts with the latest main

Conflicting files: marketplace.json

Fix it in this repository:
- New external plugins belong under external_plugins/<my-plugin>/; keep existing plugins in their current directory;
  never modify .github/, scripts/, tests/, .gitignore, .gitattributes or AGENTS.md.
- Follow CONTRIBUTING.md and AGENTS.md: the manifest lives at <plugin-directory>/.zcode-plugin/plugin.json,
  its name/version must match marketplace.json, names are kebab-case, keep the required i18n fields.
- Fetch the latest main of zai-org/zcode-plugins and rebase onto it; if marketplace.json conflicts,
  keep every existing entry and re-add mine.
- Run `python scripts/validate.py` until it passes, then force-push my PR branch.

Rebased on upstream/main (6e3951d); resolves the marketplace.json
conflict by keeping every existing entry and re-adding mine at the end
of the plugins array.

Per the intake guidance this moves the plugin to
external_plugins/zcode-beautify/ (community publisherType), source
./external_plugins/zcode-beautify in the root marketplace.json. The
icon stays under assets/zcode-beautify/icon.png per the assets
convention.

Layout note: the plugin ships its own prebuilt esbuild bundles (built
and released from its upstream repo, linked as homepage). The
marketplace packaging contract refuses a dist/ directory for plugins
without an in-repo build source, so the bundles are shipped as
bundle/cli.js and bundle/mcp/server.js instead, and every reference was
updated to match: both manifests (/bundle/mcp/
server.js), the CLI/service paths in both READMEs, the beautify skill,
the /beautify and /bubble commands, and the two user-visible offline
hints inside bundle/cli.js ('node dist/cli.js serve --detach' ->
'node bundle/cli.js serve --detach'; the only content difference from
the upstream release bundles). Both READMEs also note the dist-vs-
bundle difference between the source repo and the marketplace package.

CHANGES.md ships with the package (the panel's changelog window reads
it via /api/changelog).

CDP injection remains an explicit opt-in experimental capability
(disabled by default) with recovery guidance for disable, uninstall,
and upgrades, per the earlier review feedback.

python scripts/validate.py -> OK: 55 plugin(s) validated. The
plugin's artifact builds through scripts/build_dist.py's build_zip
(deterministic zip, sha256 1b18612912e2fea0...).
@panda920

Copy link
Copy Markdown
Collaborator

✅ Internal validation passed. A ZCode maintainer will review the change next; after acceptance, release checks run separately and this PR is closed automatically.

This branch has not been deployed

No deployments
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.

3 participants