下载地址
https://www.zhengdianxue.com/wp-content/uploads/skills/nestmold--notrat-ui-control-skill.zip将提示词发送给你的 AI 安装该 skills
请根据 https://skillhub.cn/install/skillhub.md,安装 @nestmold/notrat-ui-control-skill。通过 MCP 工具操控 Notrat 应用 UI 外观(主题色彩、字体、侧边栏、编辑器样式等)。当用户要求修改 Notrat 界面样式、改字体颜色、改背景色、调整侧边栏、自定义 UI 组件时使用此技能。不需要 Notrat 源代码,纯靠 MCP slot_set_style / config_set 等工具完成。
阅读全文 (展开查看完整说明)
概述
Notrat UI Control(无源码操控指南)
核心能力:不碰 Notrat 源代码,纯靠 MCP 工具实时操控 UI 外观。
一、可用工具一览
| 工具 | 作用 | 典型场景 |
|---|---|---|
slot_set_style | 给任意 CSS 选择器注入样式 | 改颜色、字体大小、背景、边框 |
slot_set_props | 修改 React 组件 props | 改 placeholder、disabled 等 |
slot_set_behavior | 绑定事件处理 | onClick、onChange |
slot_set_content | 替换元素内容 | 改标题文字、插入 HTML |
slot_clear_all | 清除所有覆盖 | 恢复默认样式 |
config_get / config_get_all | 读取配置 | 查看当前主题、字体大小 |
config_set | 写入配置 | 切换主题、改字号 |
config_toggle_theme | 明暗主题切换 | 一键切 dark/light |
component_modify | 热替换组件源码 | 改组件结构/逻辑(需源码) |
ui_get_state | 获取当前 UI 状态 | 查看活动 tab、打开的文件 |
ui_click / ui_type | 模拟用户操作 | 点击按钮、输入文字 |
二、Notrat 主题系统架构(源码逆向)
2.1 CSS 变量体系
Notrat 使用 shadcn/ui 风格 的 CSS 变量 + Tailwind 主题系统。所有颜色都是 HSL 无前缀格式(如 0 0% 10%,不带 hsl())。
2.2 核心变量速查表
全局基础变量
| 变量名 | 作用 | 默认值(light) | 默认值(dark) |
|---|---|---|---|
--background | 编辑器/主背景 | 0 0% 100% | 0 0% 10% |
--foreground | 主文字色 | 0 0% 10% | 0 0% 95% |
--card | 卡片背景 | 0 0% 100% | 0 0% 12% |
--popover | 弹窗背景 | 0 0% 100% | 0 0% 12% |
--muted | 静音区域背景 | 0 0% 94% | 0 0% 16% |
--muted-foreground | 次要文字色 | 0 0% 45% | 0 0% 65% |
--accent | 强调区域背景 | 0 0% 96% | 0 0% 16% |
--border | 边框色 | 0 0% 90% | 0 0% 16% |
--input | 输入框背景 | 0 0% 92% | 0 0% 16% |
--ring | 聚焦环色 | 215 95% 55% | 215 95% 60% |
--radius | 圆角 | 0.625rem | 同 |
--secondary | 次级背景 | 0 0% 96% | 0 0% 16% |
--destructive | 危险/删除色 | 0 72% 51% | 0 62% 50% |
侧边栏专用变量
| 变量名 | 作用 | 默认值(light) | 默认值(dark) |
|---|---|---|---|
--sidebar-background | 侧边栏背景 | 0 0% 97% | 0 0% 8% |
--sidebar-foreground | 侧边栏文字 | 0 0% 15% | 0 0% 90% |
--sidebar-border | 侧边栏边框 | 0 0% 90% | 0 0% 16% |
主色调变量
| 变量名 | 作用 | 默认值 |
|---|---|---|
--primary | 主色调 | 215 95% 55%(蓝) |
--primary-foreground | 主色调上的文字 | 白 |
--accent-color | 强调色(CSS 值,非 HSL) | #3b82f6 |
--accent-hover | 强调色悬停 | #2563eb |
--hue-accent | 色相值 | 215 |
排版变量
| 变量名 | 默认值 | 作用 |
|---|---|---|
--font-size-xs | 12px | 超小字 |
--font-size-sm | 12px | 小字 |
--font-size-base | 14px | 正文字号 |
--font-size-md | 16px | 中号 |
--font-size-lg | 18px | 大号 |
--font-size-xl | 20px | 超大 |
--font-size-2xl | 24px | 二级标题 |
--font-size-3xl | 30px | 三级标题 |
--font-size-4xl | 38px | 四级标题 |
布局变量
| 变量名 | 默认值 | 作用 |
|---|---|---|
--left-panel-width | 260px | 左侧面板宽度 |
2.3 主题选择器优先级
Notrat 的主题通过 :root 上挂 class 实现,选择器优先级从低到高:
:root ← 最基础(fallback 值)
:root.theme-minimalist:not(.dark) ← 极简白(默认 light 主题)
:root.theme-minimalist.dark ← 极简白 dark
:root.theme-oceanic:not(.dark) ← 海洋蓝
:root.theme-oceanic.dark ← 海洋蓝 dark
:root.theme-forest:not(.dark) ← 森林绿
:root.theme-forest.dark ← 森林绿 dark
...(更多主题)⚠️ 关键陷阱:直接改 :root 不一定生效!主题 class 选择器(如 .theme-minimalist:not(.dark))优先级更高,会覆盖 :root 的值。
正确写法:同时写两个选择器,双保险:
selector: ":root, :root.theme-minimalist:not(.dark)"2.4 已知主题列表
| 主题名 | CSS class | 风格 |
|---|---|---|
| 极简白 | .theme-minimalist | 默认,纯灰白 |
| 海洋蓝 | .theme-oceanic | 蓝色调 |
| 森林绿 | .theme-forest | 绿色调 |
| 暖阳橙 | .theme-warm | 橙暖色调 |
| 紫罗兰 | .theme-violet | 紫色调 |
| 兰花紫 | .theme-orchid | 深紫调 |
| 深海蓝 | .theme-deepblue | 深蓝色 |
| 玫红 | .theme-rose | 粉红调 |
| 青绿 | .theme-teal | 青色 |
| 日落 | .theme-sunset | 橙红调 |
| 薰衣草 | .theme-lavender | 浅紫调 |
| 品红 | .theme-magenta | 洋红调 |
| 板岩 | .theme-slate | 灰蓝调 |
| 午夜 | .theme-midnight | 深蓝调(dark-only) |
三、完整 CSS Selector 速查表(源码逆向)
以下选择器全部从 Notrat 源码
src/styles/index.css、src/styles/tiptap.css及各组件 TSX 中提取。
3.1 Activity Bar(活动栏 / 最左侧图标栏)
| 选择器 | 用途 |
|---|---|
.activity-bar | 活动栏容器 |
.activity-bar-item | 每个图标按钮 |
.activity-bar-item.active | 当前激活的图标 |
.activity-bar-item:hover | 鼠标悬停状态 |
.activity-bar-item::before | 悬停背景 |
.activity-bar-item.active::before | 激活背景 |
.activity-bar-item.active::after | 激活指示条(左侧竖线) |
.activity-bar-item-badge | 角标/红点 |
.activity-bar-divider | 分割线 |
.activity-bar-spacer | 弹性间距 |
.activity-bar-macos | macOS 样式变体 |
3.2 Sidebar Panel(侧边栏面板)
| 选择器 | 用途 |
|---|---|
.sidebar-panel | 侧边栏面板容器(文件树、会话列表等的父容器) |
.file-tree-panel | 文件树面板 |
.file-tree | 文件树容器 |
.file-tree-header | 文件树头部 |
.file-tree-toolbar | 文件树工具栏 |
.file-tree-node | 文件树节点 |
.file-tree-node.selected | 选中的文件/文件夹 |
.file-tree-node.focused | 聚焦的节点 |
.file-tree-node:hover | 悬停的节点 |
.file-tree-node.dragging | 正在拖拽的节点 |
.file-tree-node.drag-over | 拖拽悬停目标 |
.file-tree .tree-node | 树节点(react-arborist) |
.file-tree .tree-node-content | 树节点内容 |
3.3 Editor(编辑器区域)
| 选择器 | 用途 |
|---|---|
.editor-container | 编辑器外层容器 |
.editor-content | 编辑器内容区 |
.editor-tabs | 标签栏容器 |
.editor-tabs-container | 标签栏内部容器 |
.editor-tab | 单个标签 |
.editor-tab.active | 当前激活标签 |
.editor-tab.hover | 悬停标签 |
.editor-tab.closing | 正在关闭的标签 |
.editor-tab.drag-over | 拖拽悬停标签 |
.editor-tab.enter | 进入动画标签 |
.editor-tabs-count | 标签计数 |
.editor-tabs-scroll-button | 标签滚动按钮 |
.editor-tabs-scroll-button.left | 左滚动 |
.editor-tabs-scroll-button.right | 右滚动 |
.rich-text-editor | 富文本编辑器 |
.word-editor-content | Word 编辑器内容 |
.wysiwyg-editor | 所见即所得编辑器 |
3.4 ProseMirror / TipTap(Markdown 编辑器核心)
| 选择器 | 用途 |
|---|---|
.ProseMirror | ProseMirror 编辑器根元素 |
.ProseMirror-focused | 聚焦状态 |
.ProseMirror p | 段落 |
.ProseMirror h1 ~ .ProseMirror h6 | 标题(h1=2em, h2=1.5em, h3=1.25em, h4=1.125em, h5=1em, h6=0.875em) |
.ProseMirror a | 链接 |
.ProseMirror blockquote | 引用 |
.ProseMirror code | 行内代码 |
.ProseMirror pre | 代码块 |
.ProseMirror pre code | 代码块内代码 |
.ProseMirror ul / .ProseMirror ol | 列表 |
.ProseMirror ul.contains-task-list | 任务列表 |
.ProseMirror img | 图片 |
.ProseMirror table | 表格 |
.ProseMirror table td / .th | 表格单元格 |
.ProseMirror hr | 分割线 |
.ProseMirror mark | 高亮标记 |
.ProseMirror strong | 加粗 |
.ProseMirror em | 斜体 |
.ProseMirror s / .ProseMirror strike | 删除线 |
.ProseMirror ::selection | 文本选区 |
.ProseMirror .drag-handle | 拖拽手柄 |
.ProseMirror .heading-hash-prefix | 标题井号前缀 |
.ProseMirror .md-heading-draft-marker | 标题草稿标记 |
.ProseMirror .md-syntax-hint | 语法提示 |
.ProseMirror .inline-image | 行内图片 |
.ProseMirror .inline-math-edit | 行内数学编辑 |
.ProseMirror .inline-math-edit--selected | 选中的数学编辑 |
.ProseMirror .column-resize-handle | 列调整手柄 |
.ProseMirror .selectedCell:after | 选中的单元格 |
.notrat-editor-root | 编辑器根容器(语义 hook) |
3.5 TipTap 数学 / 公式
| 选择器 | 用途 |
|---|---|
.tiptap-editor | TipTap 编辑器容器 |
.tiptap-editor .math-delim | 数学分隔符 |
.tiptap-editor .math-katex-render | KaTeX 渲染 |
.tiptap-editor .math-live-preview | 实时预览 |
.tiptap-editor div[data-type="block-math"] | 块级公式 |
.tiptap-editor span[data-type="inline-math"] | 行内公式 |
.tiptap-mathematics-render | 数学渲染组件 |
.highlight-mark | 高亮标记 |
.inline-math-edit__input | 数学输入框 |
.inline-math-edit__delim | 数学分隔符 |
.katex | KaTeX 渲染根 |
.markdown-table | Markdown 表格 |
3.6 代码高亮(highlight.js)
| 选择器 | 用途 |
|---|---|
.hljs | 代码块根 |
.code-block-wrapper | 代码块外包装 |
.code-block-wrapper pre | 代码块 pre 元素 |
.hljs-keyword | 关键字 |
.hljs-string | 字符串 |
.hljs-comment | 注释 |
.hljs-number | 数字 |
.hljs-function | 函数名 |
.hljs-title | 标题 |
.hljs-attr | 属性 |
.hljs-built_in | 内置 |
.hljs-meta | 元信息 |
.hljs-tag | 标签 |
.hljs-name | 名称 |
.hljs-variable | 变量 |
.hljs-type | 类型 |
.hljs-params | 参数 |
3.7 Slash Menu(斜杠菜单)
| 选择器 | 用途 |
|---|---|
.slash-menu-popup | 弹窗容器 |
.slash-menu-popup-inner | 弹窗内部 |
.slash-menu-list | 菜单列表 |
.slash-menu-search | 搜索区域 |
.slash-menu-search-input | 搜索输入框 |
.slash-menu-search-icon | 搜索图标 |
.slash-menu-item | 菜单项 |
.slash-menu-item.selected | 选中的菜单项 |
.slash-menu-item:hover | 悬停菜单项 |
.slash-menu-item-icon | 菜单项图标 |
.slash-menu-item-label | 菜单项标签 |
.slash-menu-item-desc | 菜单项描述 |
.slash-menu-item-text | 菜单项文本 |
.slash-menu-group-label | 分组标签 |
.slash-menu-footer | 底部 |
.slash-menu-empty | 空状态 |
.slash-menu-chevron | 箭头 |
.slash-submenu | 子菜单 |
.slash-table-picker | 表格选择器 |
.slash-table-picker-grid | 表格网格 |
.slash-table-cell | 表格单元格 |
.slash-table-cell.active | 活动单元格 |
3.8 Status Bar(底部状态栏)
| 选择器 | 用途 |
|---|---|
.status-bar | 状态栏容器 |
注意:StatusBar 组件主要使用 Tailwind 内联类,常用模式:
text-[10px] text-muted-foreground/70— 状态栏小字text-[10px] text-muted-foreground/80— 状态栏文字text-[10px] font-mono text-muted-foreground/70— 等宽状态文字text-[10px] text-foreground/70— 强调状态文字text-[11px] font-semibold— Notrat 标题bg-muted/30— 状态栏背景
3.9 Title Bar(顶部标题栏)
| 选择器 | 用途 |
|---|---|
.app-region-drag | 可拖拽区域(标题栏) |
.app-region-no-drag | 不可拖拽区域(按钮) |
.app-region-drag:hover | 拖拽区悬停 |
常用 Tailwind 类:
h-8 bg-background border-b border-border/50— 标题栏容器text-sm font-medium text-foreground— 标题文字w-11 h-8 text-muted-foreground hover:bg-muted hover:text-foreground— 窗口控制按钮
3.10 Chat / Session List(聊天侧边栏)
| 选择器 | 用途 |
|---|---|
.sidebar-panel | 聊天侧边栏容器(同文件树) |
SessionList 常用 Tailwind 类:
text-foreground— 会话标题text-muted-foreground— 预览文本、图标text-muted-foreground/70— 时间戳text-muted-foreground/60— 搜索图标text-accent-color— 当前选中会话bg-muted/50— 搜索框背景
3.11 Chat Input(聊天输入框)
常用 Tailwind 类:
bg-muted/30 rounded-2xl border border-border— 输入区容器bg-background border-0 rounded-xl focus:ring-2 focus:ring-primary/20— textareaplaceholder:text-muted-foreground/50— placeholder 颜色bg-accent-color/10 border border-accent-color/30— 上下文提示条bg-muted rounded-full text-xs— 标签 chiptext-muted-foreground hover:text-foreground hover:bg-muted— 发送按钮
3.12 Immersive AI(沉浸式 AI 界面)
| 选择器 | 用途 |
|---|---|
.immersive-ai-view | 沉浸式 AI 主视图 |
.immersive-ai-main | 主内容区 |
.immersive-ai-canvas | 画布区 |
.immersive-ai-topbar | 顶部栏 |
.immersive-ai-topbar-title-wrap | 标题容器 |
.immersive-ai-topbar-context | 上下文信息 |
.immersive-ai-overlay-scrim | 遮罩层 |
.immersive-ai-composer-surface | 输入区域 |
.immersive-ai-composer-surface:focus-within | 输入区聚焦 |
.immersive-ai-composer-width | 输入区宽度 |
.immersive-ai-user-bubble | 用户消息气泡 |
.immersive-ai-section-card | 分区卡片 |
.immersive-ai-section-item | 分区项 |
.immersive-ai-chip | 芯片/标签 |
.immersive-ai-chip-row | 芯片行 |
.immersive-ai-attachment-chip | 附件芯片 |
.immersive-ai-pill | 药丸按钮 |
.immersive-ai-mode-pill | 模式选择 |
.immersive-ai-state-pill | 状态药丸 |
.immersive-ai-state-pill-active | 活动状态 |
.immersive-ai-state-pill-error | 错误状态 |
.immersive-ai-status-chip | 状态芯片 |
.immersive-ai-status-chip-accent | 强调状态 |
.immersive-ai-status-chip-muted | 静音状态 |
.immersive-ai-count-pill | 计数药丸 |
.immersive-ai-tone-dot | 语气圆点 |
.immersive-ai-tone-dot-active | 活动语气 |
.immersive-ai-tone-dot-error | 错误语气 |
.immersive-ai-toggle | 开关 |
.immersive-ai-toggle-group | 开关组 |
.immersive-ai-title | 标题 |
.immersive-ai-kicker | 标题前缀 |
.immersive-ai-danger-button | 危险按钮 |
.immersive-ai-danger-button:hover | 危险按钮悬停 |
.immersive-ai-inline-notice | 内联通知 |
.immersive-ai-inline-notice-permission | 权限通知 |
.immersive-ai-inline-notice-thinking | 思考通知 |
.immersive-ai-process-timeline | 流程时间线 |
.immersive-ai-process-item | 流程项 |
.immersive-ai-process-node | 流程节点 |
.immersive-ai-process-summary-row | 流程摘要行 |
.immersive-ai-process-summary-dot | 摘要圆点 |
.immersive-ai-process-summary-badge | 摘要徽章 |
.immersive-ai-process-detail | 流程详情 |
.immersive-ai-process-count | 流程计数 |
.immersive-ai-process-error-reason | 错误原因 |
.immersive-ai-execution-drawer | 执行抽屉 |
.immersive-ai-execution-drawer-error | 执行错误 |
.immersive-ai-details-entry | 详情条目 |
.immersive-ai-details-entry-active | 活动条目 |
.immersive-ai-details-entry-attention | 注意条目 |
.immersive-ai-details-entry-error | 错误条目 |
.immersive-ai-details-entry-badge | 条目徽章 |
.immersive-ai-runtime-status-bar | 运行时状态栏 |
.immersive-ai-trace-item | 追踪项 |
.immersive-ai-trace-shell | 追踪外壳 |
.immersive-ai-surface-active | 活动表面 |
.immersive-ai-page-column | 页面列 |
.immersive-ai-document-segment | 文档片段 |
.immersive-document-segment | 文档段落 |
3.13 Mention Dashboard(@提及面板)
| 选择器 | 用途 |
|---|---|
.mention-dashboard-shell | 面板外壳 |
.mention-dashboard-header | 头部 |
.mention-dashboard-subtitle | 副标题 |
.mention-dashboard-search-icon | 搜索图标 |
.mention-dashboard-footer | 底部 |
.mention-dashboard-empty | 空状态 |
.mention-dashboard-section-label | 分区标签 |
.mention-dashboard-item | 条目 |
.mention-dashboard-item-active | 活动条目 |
.mention-dashboard-item:hover | 悬停条目 |
.mention-dashboard-meta | 元信息 |
.mention-dashboard-category-card | 分类卡片 |
.mention-dashboard-category-card-active | 活动分类 |
3.14 Scrollbar(滚动条)
| 选择器 | 用途 |
|---|---|
.custom-scrollbar | 自定义滚动条 |
.custom-scrollbar::-webkit-scrollbar | 滚动条轨道 |
.custom-scrollbar::-webkit-scrollbar-thumb | 滚动条滑块 |
.custom-scrollbar::-webkit-scrollbar-thumb:hover | 滑块悬停 |
.custom-scrollbar::-webkit-scrollbar-track | 滚动条轨道背景 |
.scrollbar-thin | 细滚动条 |
.scrollbar-thin-hover | 悬停显示滚动条 |
.scrollbar-visible | 可见滚动条 |
3.15 Tree / react-arborist(文件树底层)
| 选择器 | 用途 |
|---|---|
.tree-container | 树容器 |
.react-arborist-tree | arborist 树 |
.react-arborist-row | 树行 |
.react-arborist-row:hover | 树行悬停 |
.react-arborist-row-focused | 聚焦行 |
.react-arborist-row-selected | 选中行 |
.react-arborist-drag-preview | 拖拽预览 |
.react-arborist-line | 拖拽线 |
.react-arborist-row-selected .row-content | 选中行内容 |
3.16 Excel Editor(Excel 编辑器)
| 选择器 | 用途 |
|---|---|
.excel-editor-container | Excel 编辑器容器 |
.excel-cell | 单元格 |
.excel-cell:focus | 聚焦单元格 |
.excel-header | 表头 |
3.17 Source Code Editor(源码编辑器)
| 选择器 | 用途 |
|---|---|
.CodeMirror | CodeMirror 根 |
.CodeMirror-scroll | CodeMirror 滚动区 |
.source-editor-textarea | 源码编辑 textarea |
.source-editor-textarea::placeholder | placeholder |
3.18 Diagram Preview(图表预览)
| 选择器 | 用途 |
|---|---|
.diagram-preview | 图表预览容器 |
.diagram-preview img | 预览图片 |
.diagram-preview svg | 预览 SVG |
.drag-ghost | 拖拽幽灵 |
.drag-handle | 拖拽手柄 |
.drag-handle:hover | 手柄悬停 |
.drag-handle.dragging | 正在拖拽 |
.drag-insert-line | 拖拽插入线 |
3.19 Icon Colors(图标颜色类)
| 选择器 | 用途 |
|---|---|
.icon-blue | 蓝色图标 |
.icon-cyan | 青色图标 |
.icon-gray | 灰色图标 |
.icon-green | 绿色图标 |
.icon-orange | 橙色图标 |
.icon-pink | 粉色图标 |
.icon-purple | 紫色图标 |
.icon-red | 红色图标 |
.icon-yellow | 黄色图标 |
3.20 Misc / 动画
| 选择器 | 用途 |
|---|---|
.tour-highlight-pulse | 引导高亮脉冲 |
.wc-shell | 写作画布外壳 |
.wc-shell-paint | 写作画布绘制层 |
.wc-fade-left | 向左淡入 |
.wc-fade-up | 向上淡入 |
.wc-fade-rule | 分割线淡入 |
.wc-fade-wash | 冲刷动画 |
.wc-delay-1 ~ .wc-delay-5 | 动画延迟(0.04s ~ 0.28s) |
.changelog-md | 更新日志 Markdown |
.drag-ghost | 拖拽幽灵元素 |
3.21 Tailwind Utility 选择器(高频使用)
以下 Tailwind class 在源码中频繁出现,可通过 CSS 变量统一控制:
| Tailwind class | 对应 CSS 变量 | 出现频率 |
|---|---|---|
.text-foreground | --foreground | 极高 |
.text-muted-foreground | --muted-foreground | 极高 |
.text-muted-foreground/70 | --muted-foreground × 0.7 | 高 |
.text-muted-foreground/60 | --muted-foreground × 0.6 | 中 |
.text-muted-foreground/80 | --muted-foreground × 0.8 | 高 |
.text-muted-foreground/50 | --muted-foreground × 0.5 | 中 |
.text-accent-color | --accent-color | 高 |
.text-accent-foreground | --accent-foreground | 中 |
.text-primary | --primary | 中 |
.bg-background | --background | 极高 |
.bg-muted | --muted | 高 |
.bg-muted/30 | --muted × 0.3 | 中 |
.bg-muted/50 | --muted × 0.5 | 中 |
.bg-card | --card | 中 |
.bg-popover | --popover | 中 |
.bg-accent | --accent | 中 |
.bg-accent-color/10 | --accent-color × 0.1 | 中 |
.border-border | --border | 高 |
.border-border/50 | --border × 0.5 | 高 |
.border-border/30 | --border × 0.3 | 中 |
.ring-primary/20 | --primary × 0.2 | 中 |
.text-[10px] | 直接像素值 | 高(状态栏、小字) |
.text-[11px] | 直接像素值 | 中 |
.text-[9px] | 直接像素值 | 低(极小字) |
四、实战配方(直接抄)
4.1 改全局文字颜色更深
{
"selector": ":root, :root.theme-minimalist:not(.dark)",
"styles": {
"--muted-foreground": "0 0% 25%",
"--foreground": "0 0% 8%"
}
}4.2 暖白主题(全局暖色)
{
"selector": ":root, :root.theme-minimalist:not(.dark)",
"styles": {
"--background": "40 30% 99%",
"--foreground": "0 0% 8%",
"--card": "40 20% 99%",
"--popover": "40 20% 99%",
"--secondary": "40 20% 96%",
"--muted": "40 20% 95%",
"--accent": "40 20% 95%",
"--muted-foreground": "0 0% 25%",
"--border": "38 15% 88%",
"--input": "40 20% 96%",
"--sidebar-background": "40 30% 96%",
"--sidebar-foreground": "0 0% 10%",
"--sidebar-border": "38 15% 88%",
"--ring": "38 60% 50%"
}
}4.3 改活动栏图标颜色
{
"selector": ".activity-bar-item",
"styles": {
"color": "hsl(0 0% 30%) !important"
}
}
// 激活状态
{
"selector": ".activity-bar-item.active",
"styles": {
"color": "hsl(215 95% 55%) !important"
}
}4.4 改标签页样式
{
"selector": ".editor-tab",
"styles": {
"font-size": "13px",
"color": "hsl(0 0% 30%)"
}
}
// 激活标签
{
"selector": ".editor-tab.active",
"styles": {
"color": "hsl(0 0% 8%)",
"font-weight": "600"
}
}4.5 改滚动条样式
{
"selector": ".custom-scrollbar::-webkit-scrollbar-thumb",
"styles": {
"background": "hsl(0 0% 70%)",
"border-radius": "4px"
}
}
{
"selector": ".custom-scrollbar::-webkit-scrollbar-thumb:hover",
"styles": {
"background": "hsl(0 0% 50%)"
}
}4.6 改代码块字体大小
{
"selector": ".ProseMirror pre, .code-block-wrapper pre",
"styles": {
"font-size": "13px"
}
}4.7 改沉浸式 AI 界面
{
"selector": ".immersive-ai-canvas",
"styles": {
"background": "hsl(220 20% 97%)"
}
}
// 用户消息气泡
{
"selector": ".immersive-ai-user-bubble",
"styles": {
"background": "hsl(var(--primary) / 0.08)",
"border-radius": "12px"
}
}4.8 改状态栏
{
"selector": ".status-bar",
"styles": {
"background": "hsl(0 0% 95%)",
"color": "hsl(0 0% 30%)",
"font-size": "11px"
}
}4.9 改标题栏
{
"selector": ".app-region-drag",
"styles": {
"background": "hsl(0 0% 98%)",
"border-bottom": "1px solid hsl(0 0% 90%)"
}
}4.10 改侧边栏会话记录字体加深加大
// 1. 改 CSS 变量(从根源改)
{
"selector": ":root, :root.theme-minimalist:not(.dark)",
"styles": {
"--muted-foreground": "0 0% 25%",
"--sidebar-foreground": "0 0% 10%"
}
}
// 2. 强制覆盖(变量改不动时的暴力方案)
{
"selector": ".text-muted-foreground, [class*="text-muted-foreground"]",
"styles": {
"color": "hsl(0 0% 25%) !important",
"opacity": "1 !important"
}
}4.11 改字号
{
"selector": ":root, :root.theme-minimalist:not(.dark)",
"styles": {
"--font-size-base": "15px",
"--font-size-sm": "13px"
}
}4.12 自定义主色调
{
"selector": ":root, :root.theme-minimalist:not(.dark)",
"styles": {
"--primary": "270 80% 55%",
"--accent-color": "#8b5cf6",
"--accent-hover": "#7c3aed",
"--ring": "270 80% 55%"
}
}常用色相参考:
| 风格 | --primary (HSL) | --accent-color |
|---|---|---|
| 蓝(默认) | 215 95% 55% | #3b82f6 |
| 紫 | 270 80% 55% | #8b5cf6 |
| 绿 | 150 60% 45% | #10b981 |
| 橙 | 30 90% 50% | #f59e0b |
| 红 | 0 80% 55% | #ef4444 |
| 青 | 180 70% 45% | #06b6d4 |
| 粉 | 330 75% 55% | #ec4899 |
4.13 切换主题(config 层面)
// 通过 config_set
{ "key": "theme", "value": "dark" }
// 或通过 toggle
config_toggle_theme()
// 或直接读当前配置
config_get_all()4.14 恢复默认
slot_clear_all() // 清除所有 style/props/behavior/content 覆盖五、Tailwind class 与 CSS 变量对应关系
⚠️ Tailwind 的 /70 透明度后缀会在编译后变成 opacity: 0.7 或 color-mix(),用 !important 强制覆盖时需要同时设 color 和 opacity。
透明度叠加问题示例:
text-muted-foreground/70 → hsl(0 0% 45% / 0.7) → 实际亮度 ≈ 58% ❌ 看不清
text-muted-foreground/60 → hsl(0 0% 45% / 0.6) → 实际亮度 ≈ 63% ❌ 更看不清
修改 --muted-foreground 为 25% 后:
text-muted-foreground/70 → hsl(0 0% 25% / 0.7) → 实际亮度 ≈ 33% ✅ 清楚
text-muted-foreground/60 → hsl(0 0% 25% / 0.6) → 实际亮度 ≈ 40% ✅ 可接受六、调试技巧
6.1 查看当前状态
config_get_all() // 看当前主题、字号等配置
ui_get_state() // 看当前活动 tab、打开文件6.2 CSS 变量改了没效果?
排查顺序:
- 选择器优先级:主题 class(如
.theme-minimalist)比:root高,需要同时写两个 - Tailwind 编译:Tailwind 在构建时把
text-muted-foreground编译成color: hsl(var(--muted-foreground)),改变量会影响所有用了这个 class 的元素 - 透明度后缀:
text-muted-foreground/70=hsl(var(--muted-foreground) / 0.7),需要额外加opacity: 1 !important - !important 叠加:如果之前注入了
!important的样式,后注入的也需要!important - slot_clear_all 后重设:如果改动叠加太多产生冲突,先 clear 再重新设
6.3 批量覆盖策略
如果 CSS 变量方案不够,可以按 Tailwind class 名批量覆盖:
// 所有次要文字
{ "selector": ".text-muted-foreground", "styles": { "color": "hsl(0 0% 25%) !important" } }
// 所有主要文字
{ "selector": ".text-foreground", "styles": { "color": "hsl(0 0% 8%) !important" } }
// 所有小字
{ "selector": ".text-\[10px\]", "styles": { "font-size": "12px !important" } }
// 侧边栏整体
{ "selector": ".sidebar-panel *", "styles": { "font-size": "14px !important" } }6.4 查看实际 DOM 结构
用 ui_get_state() 获取当前 UI 状态,或用 ui_click 配合 ui_type 模拟交互验证样式是否生效。
七、注意事项
- slot 覆盖是临时的:
slot_clear_all()或刷新页面后恢复默认。如需永久生效,需要改 Notrat 源代码。 - 全局变量影响范围大:改
--muted-foreground会影响整个 app 所有用了这个变量的组件,不只侧边栏。 - HSL 格式:Notrat 的 CSS 变量值不含
hsl()前缀(写0 0% 10%而非hsl(0 0% 10%))。但在slot_set_style的 styles 里写最终 CSS 值时(如直接给某个元素设 color),需要带hsl()(因为 slot 注入的是最终 CSS 值,不是变量赋值)。**改变量本身时不需要hsl()**。 **!important要慎用**:一旦加了!important,后续所有覆盖都需要!important。能用变量解决的优先用变量。- 暗色主题适配:如果用户用暗色主题,选择器要改成
:root.theme-minimalist.dark或对应的主题 class。 - reload 会清除覆盖:
app_reload_window()会清除所有 slot 注入的样式。需要时重新注入。 - 自定义 class vs Tailwind class:自定义 class(如
.activity-bar、.editor-tab)可直接用 selector 覆盖。Tailwind class(如.text-muted-foreground)背后是 CSS 变量,改变量更优雅。 - 伪元素:
.activity-bar-item::before、.editor-tab.active::after等伪元素可以直接作为 selector 传给slot_set_style。
八、弹窗与对话框(2026-07-30 新增)
8.1 语义钩子类速查
所有弹窗都已挂语义钩子类(与 .notrat-editor-root 同一约定),DIY / slot_set_style 直接定位:
| 弹窗 | 根类 | 关键子类 |
|---|---|---|
| 角落活动提醒(右下角) | .notrat-corner-notify | -host(容器)/ -accent(顶部渐变条)/ -title / -body / -item / -item-title / -item-desc / -item-action / -actions / -action(-primary) / -close |
| 官方推荐技能(模态) | .notrat-recommend-dialog | -accent / -title / -subtitle / -items / -item / -item-action / -actions / -action-primary |
| AI 服务商导入(模态) | .notrat-import-dialog | -title / -subtitle / -actions / -action-primary |
| 全局确认框(globalDialog) | .notrat-global-dialog | -accent / -title / -body / -actions / -action-primary |
8.2 弹窗 z-index 层级表
| 层级 | z-index | 用途 |
|---|---|---|
| 导入服务商 | 90 | 模态 |
| 角落提醒 | 9990 | 右下角非模态 |
| 推荐技能 | 9995 | 模态(带 backdrop) |
| 全局确认框 | 9999 | 最高优先 |
改弹窗层级前先想交互:角落提醒必须低于模态框,否则会把模态框顶穿。
8.3 一条规则统一改全部弹窗
{
"selector": ".notrat-corner-notify, .notrat-recommend-dialog, .notrat-import-dialog, .notrat-global-dialog",
"styles": { "border-color": "#e07856", "border-radius": "16px" }
}8.4 单独改角落提醒(示例)
{ "selector": ".notrat-corner-notify", "styles": { "border": "2px solid hsl(16 68% 50%)", "box-shadow": "0 8px 30px hsl(16 68% 50% / 0.25)" } }
{ "selector": ".notrat-corner-notify-item-action", "styles": { "background": "hsl(16 68% 50%)", "color": "#fff" } }九、踩过的坑(2026-07 实录)
- CDN Referer 热链保护:
public.cdn.nestmold.cn的图片带 Referer 请求返回 403,不带 200。Electron 里<img>默认带 Referer,技能图标/头像会裂图。源码里写<img>必须加referrerPolicy="no-referrer"。slot 改不了这个属性,只能改源码。 - backdrop-filter 创建 stacking context:给
.activity-bar这类容器加backdrop-filter: blur(...)后,整个子树(含内部 z-50 的下拉菜单)会被主内容区压在下面——菜单 z-index 多大都没用。弹层被遮挡时先查祖先有没有backdrop-filter/filter/transform/perspective。 - Electron 不支持
window.prompt():调用直接抛Error: prompt() is not supported。需要输入时改用应用内对话框(如 ImageDialog)或内联编辑,keymap 里用window.dispatchEvent(new CustomEvent(...))把事件桥到 React 组件里开对话框。 - slot 注入 CSS 变量 vs 最终值的区别:改
:root变量写 HSL 通道(40 30% 96%),改具体元素的color/background写完整值(hsl(40 30% 96%)或#hex),别混。 - 功能提交夹带实验代码:UI 突然和原版不一样时,先
git log -p -- <文件>查最近提交——已发生两次(Icons.tsx 被 debug 提交夹带全量改写、index.css 被 Slot 系统提交夹带背景实验 CSS)。 - 新增主进程/ preload IPC 必须完全重启 dev 应用:Ctrl+R 只刷渲染进程,新 handler 不存在会抛「No handler registered」并被静默 catch,表现为"功能完全没反应"。
十、相关公开接口(NotratPayment / notrat.cn)
| 接口 | 鉴权 | 用途 |
|---|---|---|
GET /api/skills | 公开 | 官方推荐技能列表(name/description/icon_url/skillhub_url/clawhub_url/sort_order) |
GET /api/campaigns/public-active | OptionalAuth(可匿名) | 公开活动列表;带 token 时附 user_redeemed |
GET /api/campaigns/active | Bearer | 已登录活动(含领取状态) |
POST /api/campaigns/free-trial | Bearer | 领取免费体验(body: {campaign_id}) |
POST /api/campaigns/cashback/claim | Bearer | 领取返现(body: {campaign_id}) |
mente 侧渲染层不直接调,走 preload:window.electronAPI.notratAuth.getPublicCampaigns() / getRecommendedSkills()。