Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions assets/icon-sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -2552,5 +2552,13 @@
"homepage": "https://www.liblib.tv",
"mimeType": "image/png",
"sha256": "ada9717d540928baec64105056b93e8e8bc6cfbff145f9f3a9eadb6dd9b90689"
},
{
"name": "prism",
"icon": "prism/icon.png",
"source": "https://raw.githubusercontent.com/saralaaga/prism/main/prism/assets/icon.svg",
"matchedBy": "official-repository-asset",
"mimeType": "image/png",
"sha256": "a8d57df3856a7e0088f9f7a42d7daa588c3c729b94841ec9c96000bb75233cfa"
}
]
Binary file added assets/prism/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 48 additions & 0 deletions external_plugins/prism/.zcode-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "prism",
"description": "EXPERIMENTAL, OPT-IN: give every project in the ZCode desktop sidebar its own color, icon and display name, recolor individual conversations and automation cards, and keep the sidebar ordered by the most recently active conversation. Nothing is modified until you create the opt-in marker (~/.zcode/prism-opt-in); a SessionStart hook then installs a small renderer shim into the ZCode.app bundle (macOS), re-applies it after app updates, and automatically restores the original bundle once the marker is removed.",
"description_i18n": {
"en": "EXPERIMENTAL, OPT-IN: give every project in the ZCode desktop sidebar its own color, icon and display name, recolor individual conversations and automation cards, and keep the sidebar ordered by the most recently active conversation. Nothing is modified until you create the opt-in marker (~/.zcode/prism-opt-in); a SessionStart hook then installs a small renderer shim into the ZCode.app bundle (macOS), re-applies it after app updates, and automatically restores the original bundle once the marker is removed.",
"zh-CN": "实验性、需显式开启:为 ZCode 桌面端侧边栏的每个项目提供专属颜色、图标与显示名,支持单条对话与自动化卡片换色,并可让侧边栏按最近活跃自动排序。创建开启标记(~/.zcode/prism-opt-in)前不做任何修改;开启后 SessionStart 钩子向 ZCode.app 包内安装轻量渲染层 shim(仅限 macOS,应用更新后自动恢复),移除标记即自动还原原始应用包。"
},
"version": "0.6.0",
"author": {
"name": "Carlos",
"url": "https://github.com/saralaaga"
},
"license": "MIT",
"keywords": [
"sidebar",
"colors",
"icons",
"rename",
"appearance",
"customization"
],
"userConfig": {
"dimTitles": {
"title": "压暗对话标题",
"description": "会话标题以 60% 不透明度显示;取色盘里的开关可临时覆盖此设置",
"type": "boolean",
"default": true
},
"brightenThinking": {
"title": "调亮思考扫光",
"description": "提升思考/流式动画在深色主题下的可见度;取色盘开关可临时覆盖",
"type": "boolean",
"default": true
},
"autoColor": {
"title": "自动配色(未指定的项目)",
"description": "未手动指定颜色的项目按路径哈希自动分配色相;默认关闭,只有手动指定的项目染色",
"type": "boolean",
"default": false
},
"groupRecency": {
"title": "侧边栏按最近活跃排序",
"description": "对话按最后活跃时间排序、项目/分组按最新对话排序;纯显示层重排,不影响手动拖拽顺序",
"type": "boolean",
"default": true
}
}
}
25 changes: 25 additions & 0 deletions external_plugins/prism/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
MIT License

Copyright (c) 2026 Carlos

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

---

Embedded icon path data is from Lucide (https://lucide.dev), licensed ISC.
79 changes: 79 additions & 0 deletions external_plugins/prism/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Prism

> A beam of white light enters the prism and comes out as every color of the rainbow.

**Prism** is a desktop-side customization plugin for [ZCode](https://zcode.z.ai): it gives every project in the left sidebar its own color, icon and display name, lets you recolor individual conversations and automation cards, and can keep the sidebar ordered by the most recently active conversation.

> ⚠️ **Experimental, opt-in (0.6.0+)**: Prism restyles the desktop UI by injecting a renderer script into the ZCode.app bundle, which goes beyond the official plugin API. It therefore modifies **nothing by default** — create `~/.zcode/prism-opt-in` to enable it; remove the marker and the original bundle is restored automatically on the next session start. See [Opt-in](#opt-in) and the safety notes below.

## Features

- **Project colors** — all conversation rows of a project are tinted (background overlay + left accent bar), consistently across the sidebar's project / grouped / timeline views. Colors are only applied where you picked them.
- **Conversation colors** — right-click any conversation row and choose **Adjust color (this conversation)** to recolor a single conversation on top of its project color, **Cancel color (this conversation)** for an explicit transparent state, and transparent swatches in the picker for "no color" that take precedence over project colors.
- **Automation colors** — every card on the Automations page follows its project's color by default (the page is rendered per project); right-click a card, or use its `…` menu → **Adjust color (this automation)**, to override a single automation, with the same explicit transparent / follow-project states.
- **Project icons** — 30 curated Lucide icons (extracted from ZCode's own renderer assets) replace the generic folder icon on project headers, and the picked icon also appears at the far left of each conversation row in the grouped view (before the title, tinted with the project color); home/remote projects keep their house/cloud semantic icons.
- **Project aliases** — rename a project inside ZCode without touching the folder on disk or the workspace association.
- **Recency ordering** — optionally keep every sidebar view ordered by last activity: conversations by their most recent message, projects/groups by the newest conversation inside them. Implemented as a display-only reorder (CSS `order`) that never writes the app's persisted manual order — toggle it off and the native order is restored verbatim.
- **Global toggles** — dim conversation titles, brighten the thinking shimmer, automatic hash-based colors for unpicked projects (off by default), and recency ordering.

## Requirements

- macOS with the ZCode desktop app installed at `/Applications/ZCode.app` (this is the only layout Prism patches; other locations are left untouched).

## Opt-in

Installing the plugin changes nothing on disk. To enable the renderer shim, create the marker file and start a new session (or restart ZCode):

```sh
mkdir -p ~/.zcode && touch ~/.zcode/prism-opt-in
```

From then on a SessionStart hook installs and maintains the shim (and re-applies it after app updates). Without the marker the hook stays inert, and any previously applied patch is automatically stripped, restoring the original `app.asar` and refreshing the pristine backup. `$ZCODE_PLUGIN_DATA/opt-in` is honored as an alternative marker location.

## Usage

| Action | Entry point |
| --- | --- |
| Project color / icon | Right-click a project header, or the header `…` menu → **Adjust color** |
| Conversation color | Right-click a conversation row → **Adjust color (this conversation)** |
| Automation color | Right-click an automation card on the Automations page → **Adjust color (this automation)** (defaults to its project's color) |
| Cancel color | Right-click a conversation row / project `…` menu → **Cancel color** |
| Alias | Header `…` menu → **Rename** (display name only) |
| Global toggles | Bottom of the color picker → **Prism** |

All settings apply immediately and are stored in the renderer's `localStorage` (`zcProjectTint.*` / `zcPrism.settings.v1`). Run `/status` inside a session to check the shim's installation state.

## Settings

Prism declares four global toggles through the manifest's `userConfig`, so they appear in ZCode's plugin settings page (Plugin management → Prism → Configure):

| Setting | Default | Meaning |
| --- | --- | --- |
| Dim conversation titles | on | Titles render at 60% opacity |
| Brighten thinking shimmer | on | Improve shimmer visibility on dark themes |
| Auto colors for unpicked projects | off | Hash-based hue for projects without a manual pick |
| Order sidebar by recent activity | on | Display-only recency ordering, never touches manual drag order |

The plugin settings page provides the defaults and is applied when a session starts; the toggles inside the color picker are immediate overrides stored per client and win over the settings page.


## Side effects, permissions and safety

Read this before installing — Prism modifies the application bundle, which is the only way a plugin can restyle the desktop UI today.

- **What gets written**: the SessionStart hook (`hooks/ensure-shim.js`) extracts `/Applications/ZCode.app/Contents/Resources/app.asar`, injects a single `<script>` block (this plugin's `renderer/prism.js`) into `out/renderer/index.html`, repacks the archive, and swaps it in place. Before the first patch it keeps an untouched copy at `app.asar.pristine-backup`; run state is recorded in `~/.zcode/prism-state.json`.
- **When it runs**: only in quick mode (a hash check against the installed shim) on every session start, and only while the opt-in marker exists. The full repack happens only when the shim is missing or stale (e.g. after a ZCode update); without the marker no write to the bundle ever happens, and a legacy patch found without the marker is stripped instead. Nothing else is modified — no other files, no preferences, no launch agents.
- **Network**: none. Prism never opens a connection; everything is local file and DOM work.
- **Telemetry**: none.
- **Rollback**: remove the marker (`rm ~/.zcode/prism-opt-in`) and start a new session — the hook strips the shim, restores the unpatched `app.asar` and refreshes `app.asar.pristine-backup`. Manual alternatives: `node hooks/ensure-shim.js --rollback`, or `mv /Applications/ZCode.app/Contents/Resources/app.asar{.pristine-backup,}` (or reinstall ZCode). Disabling/uninstalling the plugin stops the hook; already-applied tinting disappears with the rollback.
- **Fail-safety**: the injected script is fully defensive — every entry point is wrapped, and any error it hits is logged to the console without affecting the app. If the app updates and breaks the shim contract, the next session re-applies the current version automatically.

## Third-party material and licensing

- This plugin's code: MIT (see `LICENSE`).
- [Lucide](https://lucide.dev) icon path data (ISC), pre-extracted from ZCode's own renderer chunks.
- The hook reads and repacks the app archive using [`@electron/asar`](https://www.npmjs.com/package/@electron/asar) (MIT) when available. Marketplace installs ship no `node_modules`, so the hook falls back to `hooks/asar-lite.js` — a bundled, dependency-free implementation of exactly the archive subset the hook needs (pickle framing, integrity hashes, unpacked sidecars), byte-verified against the library on the real application archive. No `npm install` is required.

## Development

Source of truth: <https://github.com/saralaaga/prism>. Rebuild the icon set with the tools there, or converge the shim manually: `node hooks/ensure-shim.js --apply` (follows the opt-in marker; strips only when it is absent) and `node hooks/ensure-shim.js --rollback` (strips unconditionally).
79 changes: 79 additions & 0 deletions external_plugins/prism/README_CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Prism

> 一束白光进棱镜,折射出每个项目自己的颜色。

**Prism** 是面向 [ZCode](https://zcode.z.ai) 桌面端的个性化插件:给左侧边栏里的每个项目一套独立的视觉身份——颜色、图标、显示名,支持给单条对话与自动化卡片换色,并可让侧边栏按最近活跃自动排序。

> ⚠️ **实验性、需显式开启(0.6.0 起)**:Prism 通过向 ZCode.app 应用包注入渲染层脚本来重整桌面端 UI,这超出了官方插件 API 的边界。因此**默认不做任何修改**——创建 `~/.zcode/prism-opt-in` 标记后才启用;删除标记后下次会话自动恢复原始应用包。见下文「开启(opt-in)」与安全说明。

## 功能

- **项目颜色**:项目的所有会话行染上专属色(背景叠加 + 左侧色条),跨「项目 / 分组 / 时间线」视图一致;只染你手动指定的项目。
- **对话颜色**:右键任意对话行 →「调整颜色(此对话)」只给这一条换色、覆盖项目色;「取消颜色(此对话)」和取色盘里的「透明」是显式无色状态,优先于项目颜色。
- **自动化颜色**:「自动化」页的每张自动化卡片默认跟随其所在项目的颜色(该页面按项目作用域渲染);右键卡片,或卡片「…」菜单 →「调整颜色(此自动化)」单独指定,同样有显式「透明」/恢复跟随项目的状态。
- **项目图标**:30 个精选 Lucide 图标(从 ZCode 自带渲染资源抽取)替换项目头的 folder 图标,所选图标还会显示在「分组」视图每条对话行的最左侧(标题前,颜色随项目色);home/远程项目保留 house/cloud 语义图标。
- **项目重命名**:只改 ZCode 内的显示名(别名),不碰磁盘文件夹与工作区关联。
- **按最近活跃排序**:项目、分组、时间线三个视图都生效——对话按各自最后活跃时间排,项目/分组按其最新对话排。纯显示层重排(CSS `order`),不写入手动拖拽顺序,关掉开关立即恢复原样。
- **全局开关**:压暗对话标题、调亮思考扫光、未指定项目的自动配色(默认关)、按最近活跃排序。

## 环境要求

- macOS,且 ZCode 桌面端安装在 `/Applications/ZCode.app`(Prism 只处理这一默认布局,其他位置不会被改动)。

## 开启(opt-in)

安装插件不会改动磁盘上的任何东西。要启用渲染层 shim,请创建标记文件并开一个新会话(或重启 ZCode):

```sh
mkdir -p ~/.zcode && touch ~/.zcode/prism-opt-in
```

此后 SessionStart 钩子会安装并维护 shim(应用更新后自动重打)。没有标记时钩子保持静默;发现无标记的历史补丁会自动剥离,恢复原始 `app.asar` 并刷新 pristine 备份。也接受 `$ZCODE_PLUGIN_DATA/opt-in` 作为替代标记位置。

## 使用

| 操作 | 入口 |
| --- | --- |
| 项目颜色 / 图标 | 右键项目标题行,或项目头 `…` 菜单 →「调整颜色」 |
| 对话颜色 | 右键对话行 →「调整颜色(此对话)」 |
| 自动化颜色 | 右键「自动化」页的卡片 →「调整颜色(此自动化)」(默认跟随所在项目色) |
| 取消颜色 | 右键对话行 / 项目头 `…` 菜单 →「取消颜色」 |
| 重命名 | 项目头 `…` 菜单 →「重命名」(仅显示名) |
| 全局开关 | 取色盘底部「Prism」 |

所有选择即时生效,数据存于渲染进程 `localStorage`(`zcProjectTint.*` / `zcPrism.settings.v1`)。会话内运行 `/status` 可查看 shim 安装状态。

## 设置

Prism 通过 manifest 的 `userConfig` 声明了四个全局开关,会出现在 ZCode 的插件设置页(插件管理 → Prism → 配置):

| 设置项 | 默认 | 含义 |
| --- | --- | --- |
| 压暗对话标题 | 开 | 会话标题以 60% 不透明度显示 |
| 调亮思考扫光 | 开 | 提升深色主题下扫光动画的可见度 |
| 自动配色(未指定的项目) | 关 | 未手动指定的项目按路径哈希自动分配色相 |
| 侧边栏按最近活跃排序 | 开 | 纯显示层重排,不影响手动拖拽顺序 |

插件设置页提供默认值,在会话启动时生效;取色盘里的开关是即时覆盖层,优先级高于设置页。


## 副作用、权限与安全

安装前请先读这一节——修改应用包是插件重整桌面端 UI 的唯一途径。

- **写入了什么**:SessionStart 钩子(`hooks/ensure-shim.js`)解包 `/Applications/ZCode.app/Contents/Resources/app.asar`,向 `out/renderer/index.html` 注入唯一一个 `<script>` 块(即本插件的 `renderer/prism.js`),重新打包后原位替换。首次打补丁前会把原始包备份为 `app.asar.pristine-backup`;运行状态记录在 `~/.zcode/prism-state.json`。
- **何时运行**:每次会话开始只做快速模式(按内容哈希比对已装 shim),且仅在 opt-in 标记存在时才会写入;仅当 shim 缺失或过期(例如 ZCode 刚自动更新)才完整重打包。没有标记时绝不修改应用包,发现历史遗留补丁会改为自动剥离。除此之外不修改任何文件——没有偏好设置、没有启动项。
- **网络**:无。Prism 不会建立任何网络连接,全部是本地文件与 DOM 操作。
- **遥测**:无。
- **回滚**:删除标记(`rm ~/.zcode/prism-opt-in`)后开一个新会话——钩子会剥离 shim、恢复未打补丁的 `app.asar` 并刷新 `app.asar.pristine-backup`。手动方式:`node hooks/ensure-shim.js --rollback`,或 `mv /Applications/ZCode.app/Contents/Resources/app.asar{.pristine-backup,}`(或重装 ZCode)。禁用/卸载插件后钩子停止;已打入的效果随回滚消失。
- **失败安全**:注入脚本全防御式编写——每个入口都有兜底,异常只打日志、不影响 App。若应用更新破坏 shim 契约,下次会话自动重装当前版本。

## 第三方素材与许可

- 本插件代码:MIT(见 `LICENSE`)。
- [Lucide](https://lucide.dev) 图标 path 数据(ISC),抽自 ZCode 自带渲染资源。
- 钩子读写应用档案时优先使用 [`@electron/asar`](https://www.npmjs.com/package/@electron/asar)(MIT)。市场安装不携带 `node_modules`,此时回退到内置的 `hooks/asar-lite.js`——一个零依赖、只实现钩子所需档案能力子集(pickle 帧、完整性哈希、unpacked 旁路目录)的实现,已在真实应用档案上与官方库做过字节级比对验证。无需任何 `npm install`。

## 开发

源码仓库:<https://github.com/saralaaga/prism>。手动收敛 shim:`node hooks/ensure-shim.js --apply`(跟随 opt-in 标记,无标记时只剥离不安装)、`node hooks/ensure-shim.js --rollback`(无条件剥离)。
Loading