@max-null/dsh-node-appearance 0.2.3 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -79,3 +79,9 @@ npm run build # tsc 类型 + tsdown(lib/index.js + lib/client.js)
79
79
 
80
80
  - [决策记录](docs/决策/2026-08-17-节点外观插件-独立插件决策.md)
81
81
  - [设计方案](docs/设计/DSH节点外观插件-设计方案.md)
82
+
83
+ ## SSID 系列
84
+
85
+ 本插件属于 **`@max-null/*` 插件系列**——这一系列共同构成 **[SSID(思灵 · Seek Soul in Darkness)](https://github.com/Max-Null/seek-soul-in-darkness)** 桌面体验。SSID 是整合它们的盒:`dsh-chat-rail` · `dsh-chinese-thinking` · `dsh-draft-polish` · `dsh-guardian` · `dsh-habit` · `dsh-header-unify` · `dsh-memory` · `dsh-node-appearance` · `dsh-plugin-center` · `dsh-skill-mcp-center` · `dsh-ssid-panels` · `dsh-ssid-zh-ui`。
86
+
87
+ This plugin belongs to the **`@max-null/*` family** — a set of plugins that together form the **[SSID (思灵 · Seek Soul in Darkness)](https://github.com/Max-Null/seek-soul-in-darkness)** desktop experience.
package/lib/client.js CHANGED
@@ -184,12 +184,15 @@ window.__ModuleLoader__.load({
184
184
  -webkit-mask: url("${STEERING_ICON}") center / contain no-repeat;
185
185
  mask: url("${STEERING_ICON}") center / contain no-repeat;
186
186
  }`);
187
- if (settings?.showThinking === false) lines.push(`${THINK_ROW} { display: none !important; }`);
187
+ if (settings?.showThinking === false) {
188
+ lines.push(`${THINK_ROW} { display: none !important; }`);
189
+ lines.push(`[data-chat-flow-kind="assistant"]:has(${THINK_ROW}:only-child),`, `[data-chat-flow-kind="assistant-step"]:has(${THINK_ROW}:only-child) { display: none !important; }`);
190
+ }
188
191
  return lines.join("\n");
189
192
  }
190
193
  //#endregion
191
194
  //#region \0dsh-css:H:\MaxNull\WorkStation\dsh-node-appearance\src\client\card.module.css.mjs
192
- const css = ".AWuyDW_group{border-bottom:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:10px;padding:16px 0;display:flex}.AWuyDW_header{appearance:none;width:100%;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:6px;align-items:center;gap:8px;padding:0;display:flex}.AWuyDW_title{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:14px;font-weight:400;line-height:22px}.AWuyDW_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.AWuyDW_chevronOpen{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s;transform:rotate(180deg)}.AWuyDW_body{flex-direction:column;display:flex}.AWuyDW_row{align-items:center;gap:10px;padding:6px 0;font-size:13px;display:flex}.AWuyDW_rowLabel{color:var(--dsw-alias-label-primary);flex:0 0 132px;font-size:13px;font-weight:500;line-height:1.5}.AWuyDW_rowHint{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:12px;line-height:1.5;overflow:hidden}.AWuyDW_checkbox{accent-color:var(--dsw-alias-brand-primary);cursor:pointer;width:15px;height:15px}.AWuyDW_colorInput{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);cursor:pointer;border-radius:6px;width:44px;height:26px;padding:2px}.AWuyDW_colorInput:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.AWuyDW_colorValue{color:var(--dsw-alias-label-secondary);font-family:ui-monospace,monospace;font-size:12px}.AWuyDW_sectionTitle{color:var(--dsw-alias-label-primary);border-top:1px solid var(--dsw-alias-border-l1);margin-top:10px;padding:10px 0 4px;font-size:13px;font-weight:600;line-height:1.5}.AWuyDW_toolRow{align-items:center;gap:10px;padding:6px 0;font-size:13px;display:flex}.AWuyDW_toolName{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-secondary);flex:1;font-family:ui-monospace,monospace;font-size:12px;line-height:1.5;overflow:hidden}.AWuyDW_removeButton,.AWuyDW_addButton{appearance:none;font:inherit;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.AWuyDW_removeButton:hover:not(:disabled),.AWuyDW_addButton:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.AWuyDW_removeButton:disabled,.AWuyDW_addButton:disabled{opacity:.4;cursor:default}.AWuyDW_removeButton:focus-visible,.AWuyDW_addButton:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.AWuyDW_addRow{align-items:center;gap:10px;padding:10px 0 4px;display:flex}.AWuyDW_toolInput{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);min-width:0;height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;flex:1;padding:0 12px;font-size:13px;line-height:1.5}.AWuyDW_toolInput:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}.AWuyDW_statusLine{color:var(--dsw-alias-label-tertiary);margin:0 0 8px;font-size:12px;line-height:1.5}.AWuyDW_disabled{opacity:.5;pointer-events:none}";
195
+ const css = ".AWuyDW_group{border-bottom:1px solid var(--dsw-alias-border-l2);flex-direction:column;gap:10px;padding:12px 0;display:flex}.AWuyDW_header{appearance:none;width:100%;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:6px;align-items:center;gap:8px;padding:0;display:flex}.AWuyDW_title{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.AWuyDW_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.AWuyDW_chevronOpen{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s;transform:rotate(180deg)}.AWuyDW_body{flex-direction:column;display:flex}.AWuyDW_row{align-items:center;gap:10px;padding:6px 0;font-size:13px;display:flex}.AWuyDW_rowLabel{color:var(--dsw-alias-label-primary);flex:none;font-size:13px;font-weight:500;line-height:1.5}.AWuyDW_rowHint{color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none;font-size:12px;line-height:1.5}.AWuyDW_checkbox{accent-color:var(--dsw-alias-brand-primary);cursor:pointer;width:15px;height:15px}.AWuyDW_switch{cursor:pointer;background:var(--dsw-alias-border-l4,#00000029);border:none;border-radius:11px;flex:none;width:40px;height:22px;margin-left:auto;padding:0;transition:background .15s}.AWuyDW_switch.AWuyDW_on{background:var(--dsw-alias-state-business-primary,#4fc3f7)}.AWuyDW_switch .AWuyDW_knob{background:#fff;border-radius:8px;width:16px;height:16px;margin-left:2px;transition:margin-left .15s;display:block}.AWuyDW_switch.AWuyDW_on .AWuyDW_knob{margin-left:22px}.AWuyDW_colorInput{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);cursor:pointer;border-radius:6px;width:44px;height:26px;margin-left:auto;padding:2px}.AWuyDW_colorInput:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.AWuyDW_colorValue{color:var(--dsw-alias-label-secondary);font-family:ui-monospace,monospace;font-size:12px}.AWuyDW_sectionTitle{letter-spacing:.06em;text-transform:uppercase;color:var(--dsw-alias-label-tertiary);border-top:1px solid var(--dsw-alias-border-l2);margin-top:10px;padding:10px 0 4px;font-size:12px;font-weight:600;line-height:1.5}.AWuyDW_toolRow{align-items:center;gap:10px;padding:6px 0;font-size:13px;display:flex}.AWuyDW_toolName{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-secondary);flex:1;font-family:ui-monospace,monospace;font-size:12px;line-height:1.5;overflow:hidden}.AWuyDW_removeButton,.AWuyDW_addButton{appearance:none;font:inherit;cursor:pointer;color:var(--dsw-alias-label-secondary);background:0 0;border:none;border-radius:7px;padding:5px 8px;font-size:12.5px;line-height:1.5}.AWuyDW_removeButton:hover:not(:disabled),.AWuyDW_addButton:hover:not(:disabled){color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.AWuyDW_removeButton:disabled,.AWuyDW_addButton:disabled{opacity:.4;cursor:default}.AWuyDW_removeButton:focus-visible,.AWuyDW_addButton:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.AWuyDW_addRow{align-items:center;gap:10px;padding:10px 0 4px;display:flex}.AWuyDW_toolInput{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);min-width:0;height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;flex:1;padding:0 12px;font-size:13px;line-height:1.5}.AWuyDW_toolInput:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}.AWuyDW_statusLine{color:var(--dsw-alias-label-tertiary);margin:0 0 8px;font-size:12px;line-height:1.5}.AWuyDW_disabled{opacity:.5;pointer-events:none}";
193
196
  const tagId = "@max-null/dsh-node-appearance/card.module.css";
194
197
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
195
198
  const tag = document.createElement("style");
@@ -199,27 +202,30 @@ window.__ModuleLoader__.load({
199
202
  document.head.appendChild(tag);
200
203
  }
201
204
  var card_module_css_default = {
202
- "header": "AWuyDW_header",
205
+ "addButton": "AWuyDW_addButton",
203
206
  "addRow": "AWuyDW_addRow",
204
- "chevron": "AWuyDW_chevron",
205
- "sectionTitle": "AWuyDW_sectionTitle",
206
- "toolRow": "AWuyDW_toolRow",
207
- "chevronOpen": "AWuyDW_chevronOpen",
208
- "colorValue": "AWuyDW_colorValue",
209
- "rowLabel": "AWuyDW_rowLabel",
210
207
  "toolInput": "AWuyDW_toolInput",
211
- "rowHint": "AWuyDW_rowHint",
212
- "checkbox": "AWuyDW_checkbox",
208
+ "switch": "AWuyDW_switch",
213
209
  "colorInput": "AWuyDW_colorInput",
214
- "row": "AWuyDW_row",
215
- "toolName": "AWuyDW_toolName",
216
- "group": "AWuyDW_group",
217
- "removeButton": "AWuyDW_removeButton",
218
- "addButton": "AWuyDW_addButton",
210
+ "title": "AWuyDW_title",
211
+ "checkbox": "AWuyDW_checkbox",
219
212
  "statusLine": "AWuyDW_statusLine",
213
+ "on": "AWuyDW_on",
214
+ "header": "AWuyDW_header",
215
+ "row": "AWuyDW_row",
220
216
  "disabled": "AWuyDW_disabled",
221
217
  "body": "AWuyDW_body",
222
- "title": "AWuyDW_title"
218
+ "colorValue": "AWuyDW_colorValue",
219
+ "toolRow": "AWuyDW_toolRow",
220
+ "removeButton": "AWuyDW_removeButton",
221
+ "knob": "AWuyDW_knob",
222
+ "chevron": "AWuyDW_chevron",
223
+ "group": "AWuyDW_group",
224
+ "chevronOpen": "AWuyDW_chevronOpen",
225
+ "rowLabel": "AWuyDW_rowLabel",
226
+ "rowHint": "AWuyDW_rowHint",
227
+ "sectionTitle": "AWuyDW_sectionTitle",
228
+ "toolName": "AWuyDW_toolName"
223
229
  };
224
230
  //#endregion
225
231
  //#region src/client/settings-card.tsx
@@ -297,18 +303,19 @@ window.__ModuleLoader__.load({
297
303
  htmlFor: "node-appearance-show-thinking",
298
304
  children: "显示思考过程"
299
305
  }),
300
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
301
- id: "node-appearance-show-thinking",
302
- className: card_module_css_default.checkbox,
303
- type: "checkbox",
304
- checked: showThinking,
305
- onChange: (event) => {
306
- setShowThinking(event.target.checked);
307
- }
308
- }),
309
306
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
310
307
  className: card_module_css_default.rowHint,
311
308
  children: "关闭后会话中的 Think 思考行隐藏"
309
+ }),
310
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
311
+ id: "node-appearance-show-thinking",
312
+ className: `${card_module_css_default.switch}${showThinking ? ` ${card_module_css_default.on}` : ""}`,
313
+ type: "button",
314
+ "aria-pressed": showThinking,
315
+ onClick: () => {
316
+ setShowThinking(!showThinking);
317
+ },
318
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: card_module_css_default.knob })
312
319
  })
313
320
  ]
314
321
  }),
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["useState","css","IconChevronDownOutline14"],"sources":["../src/client/palette.ts","../src/client/settings-card.tsx","../src/client/index.ts"],"sourcesContent":["/**\n * Node appearance palette: category/tool mapping, default colors, and the pure\n * CSS-rule generator that paints the chat flow. Browser-half owned; the Host\n * half mirrors the same defaults through its schemastery schema (the two\n * cannot share a value import — the browser bundle purity gate forbids\n * cross-package value imports).\n */\n\n/** The settings namespace this plugin owns (spelled identically in both halves). */\nexport const NODE_APPEARANCE_NS = 'node-appearance'\n\n/** The plugin's style tag identity (removed/replaced on every re-paint). */\nexport const STYLE_TAG_ID = `${NODE_APPEARANCE_NS}/rules`\n\n/** One paintable node category. `command`, `thinking`, `context` are non-tool rows. */\nexport type NodeCategory =\n | 'search' | 'agent' | 'execute' | 'file' | 'task' | 'command' | 'thinking' | 'context' | 'steering' | 'other'\n\n/** Accent color per category (CSS colors). */\nexport type NodeAppearanceColors = Record<NodeCategory, string>\n\n/** The settings value this plugin reads from its namespace scope. */\nexport interface NodeAppearanceSettings {\n /** Show assistant reasoning blocks as Think rows; false hides them. */\n showThinking?: boolean | undefined\n /** Per-category accent colors; missing keys fall back to defaults. */\n colors?: Partial<NodeAppearanceColors> | undefined\n /** Per-tool accent overrides keyed by wire tool name. */\n toolColors?: Record<string, string> | undefined\n}\n\n/** Initial palette: mid-luminance hues readable on both light and dark themes. */\nexport const DEFAULT_COLORS: NodeAppearanceColors = {\n search: '#3b82f6', // blue — web_search / web_fetch\n agent: '#a855f7', // purple — subagent / workflow / send_message …\n execute: '#f59e0b', // amber — bash / pwsh / run_code / terminal_*\n file: '#22c55e', // green — read / write / edit / glob / grep\n task: '#ec4899', // pink — todo_write / goal / job_* / schedule_*\n command: '#f97316', // orange — /command nodes\n thinking: '#c4b5fd', // light purple — Think rows\n context: '#8a9bb5', // slate blue — injected context rows (informational)\n steering: '#14b8a6', // teal — steering rows (rc.8)\n other: '#64748b', // slate — every unlisted tool\n}\n\n/** Wire tool name → category for the shipped mapping. */\nexport const TOOL_CATEGORIES: Record<Exclude<NodeCategory, 'command' | 'thinking' | 'context' | 'steering'>, readonly string[]> = {\n search: ['web_search', 'web_fetch'],\n agent: ['subagent', 'subagent_acp', 'subagent_fork', 'send_message', 'interrupt_agent', 'list_agents', 'report', 'workflow'],\n execute: ['bash', 'pwsh', 'run_code', 'terminal_open', 'terminal_close', 'terminal_list', 'terminal_read', 'terminal_send', 'terminal_signal', 'str_replace_editor'],\n file: ['read', 'write', 'edit', 'read_image', 'glob', 'grep'],\n task: ['todo_write', 'create_goal', 'get_goal', 'update_goal', 'job_kill', 'job_list', 'job_output', 'schedule_create', 'schedule_delete', 'schedule_list', 'exit_plan_mode'],\n other: [],\n}\n\n/** Selector matching every tool row inside a tool-call node. */\nconst TOOL_ROW = '[data-chat-flow-kind=\"tool-call\"] [data-tool]'\n/** The ToolRow root itself (carries data-variant; the wrapper callRow does not). */\nconst TOOL_ROW_ROOT = '[data-chat-flow-kind=\"tool-call\"] [data-tool][data-variant]'\n/** Selector of the command node wrapper. */\nconst COMMAND_ROW = '[data-chat-flow-kind=\"command\"]'\n/** Selector of the Think reasoning row. */\nconst THINK_ROW = '[data-variant=\"think\"]'\n/** Selector of the injected-context row (the flow-item wrapper). */\nconst CONTEXT_ROW = '[data-chat-flow-kind=\"context\"]'\n/** Selector of a settled tool-result row (rc.8: tool results render as their own row). */\nconst TOOL_RESULT_ROW = '[data-chat-flow-kind=\"tool-result\"]'\n\n/**\n * The rows that carry the accent paint: the ToolRow root (not its wrapper\n * callRow — both carry data-tool, only the inner row carries data-variant),\n * command nodes, Think rows, injected-context rows, and tool-result rows.\n * User input rows are excluded — right-alignment already\n * distinguishes them (2026-08-20 用户反馈);steering rows 也走独立规则\n * (见 buildCss:在 userStack 层做 wash,不涂整行 rail)。\n * The 3px inset rail is compensated\n * with a matching padding-left so the rail never covers the row's leading icon.\n */\nconst ACCENTED_ROWS = [\n TOOL_ROW_ROOT, COMMAND_ROW, THINK_ROW, CONTEXT_ROW, TOOL_RESULT_ROW,\n].join(',\\n')\n\n/**\n * Accept a configured CSS color (hex, color functions) or reject it so an\n * invalid value falls back to the category default instead of poisoning CSS.\n * @param value - configured color string.\n * @returns whether the value is a plausible CSS color literal.\n */\nexport function isCssColor(value: string): boolean {\n const trimmed = value.trim()\n if (trimmed === '') return false\n if (/^#[0-9a-f]{3,8}$/i.test(trimmed)) return true\n return /^(rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color|device-cmyk)\\(/i.test(trimmed)\n}\n\n/** Resolve the effective palette from user settings merged over defaults. */\nexport function resolveColors(settings: NodeAppearanceSettings): NodeAppearanceColors {\n const colors: NodeAppearanceColors = { ...DEFAULT_COLORS }\n const configured = settings.colors\n if (configured !== undefined && typeof configured === 'object' && configured !== null) {\n for (const key of Object.keys(DEFAULT_COLORS) as NodeCategory[]) {\n const value = configured[key]\n if (typeof value === 'string' && isCssColor(value)) colors[key] = value\n }\n }\n return colors\n}\n\n/** Escape a tool name into a CSS attribute selector string literal. */\nfunction attributeLiteral(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')\n}\n\n/**\n * Steering marker icon: a corner-up-left arrow (mid-turn guidance inserted\n * into the running answer), drawn as a mask so the icon inherits the\n * configured steering color. Encoded data URI, no external asset.\n */\nconst STEERING_ICON = \"data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='9 14 4 9 9 4'/%3E%3Cpath d='M20 20v-7a4 4 0 0 0-4-4H4'/%3E%3C/svg%3E\"\n\n/**\n * Build the complete stylesheet text for one settings snapshot.\n * @param settings - the namespace scope value (may be partial or undefined).\n * @returns CSS text painting accent rows and (optionally) hiding Think rows.\n */\nexport function buildCss(settings: NodeAppearanceSettings | undefined): string {\n const colors = resolveColors(settings ?? {})\n const toolOverrides = settings?.toolColors\n const lines: string[] = []\n\n // Unlisted tools keep the neutral fallback. Declared BEFORE the per-tool\n // rules: both selectors carry equal specificity (two attribute selectors),\n // so of two conflicting declarations the later one wins — a fallback\n // declared after the category rules would override every category color.\n lines.push(`${TOOL_ROW} { --ncolor-accent: ${colors.other}; }`)\n\n // Per-tool accent assignments (explicit overrides win over category color).\n for (const [category, tools] of Object.entries(TOOL_CATEGORIES)) {\n const key = category as keyof typeof TOOL_CATEGORIES\n for (const tool of tools) {\n const override = toolOverrides?.[tool]\n const color = typeof override === 'string' && isCssColor(override)\n ? override\n : colors[key]\n lines.push(`[data-chat-flow-kind=\"tool-call\"] [data-tool=\"${attributeLiteral(tool)}\"] { --ncolor-accent: ${color}; }`)\n }\n }\n\n // Non-tool accent rows.\n lines.push(`${COMMAND_ROW} { --ncolor-accent: ${colors.command}; }`)\n lines.push(`${THINK_ROW} { --ncolor-accent: ${colors.thinking}; }`)\n lines.push(`${CONTEXT_ROW} { --ncolor-accent: ${colors.context}; }`)\n lines.push(`${TOOL_RESULT_ROW} { --ncolor-accent: ${colors.file}; }`)\n\n // One shared paint rule: 3px inset left rail (layout-free) + 8% wash. The\n // matching padding-left moves the row content off the rail so the leading\n // icon is never covered.\n lines.push(`${ACCENTED_ROWS} {\n box-shadow: inset 3px 0 0 var(--ncolor-accent);\n background-color: color-mix(in srgb, var(--ncolor-accent) 8%, transparent);\n padding-left: 3px;\n}`)\n\n // Steering rows (mid-turn user steering) stay visually distinct from plain\n // user rows with a compass marker beside the right-aligned bubble. The\n // marker is a mask over the user-stack — the container that hugs the bubble\n // — positioned to the left of it, so the tint reads as a glyph next to the\n // message rather than a detached full-width rail (2026-08-21 用户反馈:\n // 整行 rail 突兀,改在 userStack 层做图标区分;slot 方案不可行:\n // conversation.message.images 是 single 槽且已被官方 ui-attachment 占用).\n lines.push(`[data-chat-flow-kind=\"steering\"] [data-time-hover-root] > :first-child {\n position: relative;\n}`)\n lines.push(`[data-chat-flow-kind=\"steering\"] [data-time-hover-root] > :first-child::before {\n content: '';\n position: absolute;\n right: 100%;\n margin-right: 6px;\n top: 50%;\n width: 14px;\n height: 14px;\n transform: translateY(-50%);\n background-color: ${colors.steering};\n -webkit-mask: url(\"${STEERING_ICON}\") center / contain no-repeat;\n mask: url(\"${STEERING_ICON}\") center / contain no-repeat;\n}`)\n\n // Visibility switch: hide Think rows entirely on the frontend. `!important`\n // outranks the module stylesheet's `.root { display: flex }` (same\n // specificity, but the plugin style tag is injected before the module's).\n if (settings?.showThinking === false) {\n lines.push(`${THINK_ROW} { display: none !important; }`)\n }\n\n return lines.join('\\n')\n}\n","/**\n * The plugin's General-settings row: a \"节点外观\" title with the standard\n * chevron, expanding to palette rows, tool overrides, and the Think\n * visibility switch. Reads the namespace scope through the injected hooks\n * face and writes through the injected actions; every change applies\n * immediately. Drawn by hand (no value import from ui-settings-plugins — the\n * client bundle purity gate forbids cross-plugin value imports), styled with\n * the DSH design tokens like the shipped Appearance row.\n */\n\nimport { useState, type ChangeEvent, type FormEvent } from 'react'\nimport type { SettingsScopeSnapshot } from '@deepseek-ai/dsh-client-runtime/client'\nimport { IconChevronDownOutline14 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport {\n DEFAULT_COLORS, isCssColor, resolveColors, TOOL_CATEGORIES,\n type NodeAppearanceSettings, type NodeCategory,\n} from './palette.ts'\nimport css from './card.module.css'\n\n/** The row's inject face: the read-only scope snapshot plus write actions. */\nexport interface NodeAppearanceRowFace {\n hooks: {\n /** The bound settings-scope snapshot, rendered as useNodeAppearance. */\n nodeAppearance: {\n getSnapshot(): SettingsScopeSnapshot<NodeAppearanceSettings>\n subscribe(listener: () => void): () => void\n }\n }\n /** Write the Think visibility switch. */\n setShowThinking(show: boolean): void\n /** Merge one category color into the palette section. */\n setCategoryColor(category: NodeCategory, color: string): void\n /** Merge one tool override into the toolColors section. */\n setToolColor(tool: string, color: string): void\n /** Remove one tool override. */\n removeToolColor(tool: string): void\n}\n\n/** Props the renderer binds for this General row. */\nexport type NodeAppearanceRowProps =\n PropsRuntime<'settings.general.item'>\n & InjectFace<NodeAppearanceRowFace>\n\n/** Chinese labels per category (product copy is Chinese). */\nconst CATEGORY_LABELS: Record<NodeCategory, string> = {\n search: '联网搜索',\n agent: '智能体调用',\n execute: '代码 / 指令执行',\n file: '文件操作',\n task: '任务 / 目标',\n command: '指令节点',\n thinking: '思考过程',\n context: '上下文注入',\n steering: '模型引导',\n other: '其他工具',\n}\n\n/** Tools shown in the add-override autocomplete-free text input placeholder. */\nconst TOOL_SUGGESTIONS = Object.values(TOOL_CATEGORIES).flat().join('、')\n\n/**\n * Render the node-appearance General row.\n * @param props - the injected scope snapshot hook and write actions.\n * @returns the row, always visible once its namespace is served.\n */\nexport function NodeAppearanceRow({ useNodeAppearance, setShowThinking, setCategoryColor, setToolColor, removeToolColor }: NodeAppearanceRowProps) {\n const [open, setOpen] = useState(false)\n const [toolName, setToolName] = useState('')\n const [toolColor, setToolColorDraft] = useState('#64748b')\n const snapshot = useNodeAppearance(snapshot => snapshot)\n const colors = resolveColors(snapshot.value ?? {})\n const toolColors = snapshot.value?.toolColors ?? {}\n const showThinking = snapshot.value?.showThinking ?? true\n const disabled = snapshot.writable === false\n\n const addTool = (event: FormEvent) => {\n event.preventDefault()\n const name = toolName.trim()\n if (name === '' || !isCssColor(toolColor)) return\n setToolColor(name, toolColor)\n setToolName('')\n }\n\n return (\n <div className={css.group}>\n <button\n type=\"button\"\n className={css.header}\n aria-expanded={open}\n onClick={() => { setOpen(!open) }}\n >\n <span className={css.title}>节点外观</span>\n <IconChevronDownOutline14 className={open ? css.chevronOpen : css.chevron} />\n </button>\n {open && (\n <div className={css.body}>\n {snapshot.status !== 'ready' && (\n <p className={css.statusLine}>\n {snapshot.status === 'unavailable'\n ? '配置暂不可用:插件主机侧未挂载或连接非本机。'\n : '配置加载中…'}\n </p>\n )}\n <div className={`${disabled ? css.disabled : ''}`}>\n <div className={css.row}>\n <label className={css.rowLabel} htmlFor=\"node-appearance-show-thinking\">显示思考过程</label>\n <input\n id=\"node-appearance-show-thinking\"\n className={css.checkbox}\n type=\"checkbox\"\n checked={showThinking}\n onChange={(event: ChangeEvent<HTMLInputElement>) => { setShowThinking(event.target.checked) }}\n />\n <span className={css.rowHint}>关闭后会话中的 Think 思考行隐藏</span>\n </div>\n {(Object.keys(CATEGORY_LABELS) as NodeCategory[]).map(category => (\n <div className={css.row} key={category}>\n <label className={css.rowLabel} htmlFor={`node-appearance-color-${category}`}>\n {CATEGORY_LABELS[category]}\n </label>\n <input\n id={`node-appearance-color-${category}`}\n className={css.colorInput}\n type=\"color\"\n value={colors[category]}\n onChange={(event: ChangeEvent<HTMLInputElement>) => { setCategoryColor(category, event.target.value) }}\n />\n <span className={css.colorValue}>{colors[category]}</span>\n </div>\n ))}\n <div className={css.sectionTitle}>工具颜色覆盖(可选)</div>\n {Object.entries(toolColors).map(([tool, color]) => (\n <div className={css.toolRow} key={tool}>\n <span className={css.toolName} title={tool}>{tool}</span>\n <input\n className={css.colorInput}\n type=\"color\"\n value={isCssColor(color) ? color : DEFAULT_COLORS.other}\n onChange={(event: ChangeEvent<HTMLInputElement>) => { setToolColor(tool, event.target.value) }}\n />\n <button type=\"button\" className={css.removeButton} onClick={() => { removeToolColor(tool) }}>删除</button>\n </div>\n ))}\n <form className={css.addRow} onSubmit={addTool}>\n <input\n className={css.toolInput}\n type=\"text\"\n placeholder={`工具名,如 ${TOOL_SUGGESTIONS}`}\n value={toolName}\n onChange={(event: ChangeEvent<HTMLInputElement>) => { setToolName(event.target.value) }}\n />\n <input\n className={css.colorInput}\n type=\"color\"\n value={toolColor}\n onChange={(event: ChangeEvent<HTMLInputElement>) => { setToolColorDraft(event.target.value) }}\n />\n <button type=\"submit\" className={css.addButton} disabled={toolName.trim() === ''}>添加</button>\n </form>\n </div>\n </div>\n )}\n </div>\n )\n}\n","/**\n * Browser half: binds the `node-appearance` settings scope, paints the chat\n * flow from it (a single <style data-plugin-css> tag rebuilt on every\n * snapshot change), and registers the settings card.\n */\n\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { SettingsScope } from '@deepseek-ai/dsh-client-runtime/client'\n// Type-only: the ctx.settingsScope Context merge and the slot's declaration.\n// Cross-plugin collaboration goes through cordis services; a value import\n// would fail the client bundle-purity gate.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\nimport { buildCss, NODE_APPEARANCE_NS, STYLE_TAG_ID, type NodeAppearanceSettings } from './palette.ts'\nimport { NodeAppearanceRow, type NodeAppearanceRowFace } from './settings-card.tsx'\n\nexport const inject = ['slots', 'connection', 'remote', 'settingsScope']\n\n/** Upsert the plugin's paint stylesheet with the current snapshot's CSS. */\nfunction paint(scope: SettingsScope<NodeAppearanceSettings>): void {\n let tag = document.querySelector<HTMLStyleElement>(`style[data-plugin-css=\"${STYLE_TAG_ID}\"]`)\n if (tag === null) {\n tag = document.createElement('style')\n tag.dataset.plugin = NODE_APPEARANCE_NS\n tag.dataset.pluginCss = STYLE_TAG_ID\n document.head.appendChild(tag)\n }\n tag.textContent = buildCss(scope.getSnapshot().value)\n}\n\n/**\n * Mount the node-appearance plugin on the page.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n const scope = ctx.settingsScope.bind<NodeAppearanceSettings>({ namespace: NODE_APPEARANCE_NS })\n // Paint once from the current snapshot (defaults before the first Host read).\n paint(scope)\n ctx.effect(\n () => scope.subscribe(() => { paint(scope) }),\n 'dsh-node-appearance: repaint on settings change',\n )\n\n const face: NodeAppearanceRowFace = {\n hooks: { nodeAppearance: scope },\n setShowThinking: (show) => { void scope.set('showThinking', show) },\n setCategoryColor: (category, color) => {\n const value = scope.getSnapshot().value\n void scope.set('colors', { ...value?.colors, [category]: color })\n },\n setToolColor: (tool, color) => {\n const value = scope.getSnapshot().value\n void scope.set('toolColors', { ...value?.toolColors, [tool]: color })\n },\n removeToolColor: (tool) => {\n const value = scope.getSnapshot().value\n const toolColors = { ...value?.toolColors }\n delete toolColors[tool]\n void scope.set('toolColors', toolColors)\n },\n }\n\n // The General settings section stacks preference rows (locale → Language,\n // ui-theme → Appearance, dsh-skin → Skins). Node appearance is the same\n // kind of visual preference, so it registers here beside them.\n ctx.slots.inject('settings.general.item', () => ctx.slots.register({\n name: 'settings.general.item',\n id: NODE_APPEARANCE_NS,\n order: 30,\n inject: () => face,\n }, NodeAppearanceRow))\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["useState","css","IconChevronDownOutline14"],"sources":["../src/client/palette.ts","../src/client/settings-card.tsx","../src/client/index.ts"],"sourcesContent":["/**\n * Node appearance palette: category/tool mapping, default colors, and the pure\n * CSS-rule generator that paints the chat flow. Browser-half owned; the Host\n * half mirrors the same defaults through its schemastery schema (the two\n * cannot share a value import — the browser bundle purity gate forbids\n * cross-package value imports).\n */\n\n/** The settings namespace this plugin owns (spelled identically in both halves). */\nexport const NODE_APPEARANCE_NS = 'node-appearance'\n\n/** The plugin's style tag identity (removed/replaced on every re-paint). */\nexport const STYLE_TAG_ID = `${NODE_APPEARANCE_NS}/rules`\n\n/** One paintable node category. `command`, `thinking`, `context` are non-tool rows. */\nexport type NodeCategory =\n | 'search' | 'agent' | 'execute' | 'file' | 'task' | 'command' | 'thinking' | 'context' | 'steering' | 'other'\n\n/** Accent color per category (CSS colors). */\nexport type NodeAppearanceColors = Record<NodeCategory, string>\n\n/** The settings value this plugin reads from its namespace scope. */\nexport interface NodeAppearanceSettings {\n /** Show assistant reasoning blocks as Think rows; false hides them. */\n showThinking?: boolean | undefined\n /** Per-category accent colors; missing keys fall back to defaults. */\n colors?: Partial<NodeAppearanceColors> | undefined\n /** Per-tool accent overrides keyed by wire tool name. */\n toolColors?: Record<string, string> | undefined\n}\n\n/** Initial palette: mid-luminance hues readable on both light and dark themes. */\nexport const DEFAULT_COLORS: NodeAppearanceColors = {\n search: '#3b82f6', // blue — web_search / web_fetch\n agent: '#a855f7', // purple — subagent / workflow / send_message …\n execute: '#f59e0b', // amber — bash / pwsh / run_code / terminal_*\n file: '#22c55e', // green — read / write / edit / glob / grep\n task: '#ec4899', // pink — todo_write / goal / job_* / schedule_*\n command: '#f97316', // orange — /command nodes\n thinking: '#c4b5fd', // light purple — Think rows\n context: '#8a9bb5', // slate blue — injected context rows (informational)\n steering: '#14b8a6', // teal — steering rows (rc.8)\n other: '#64748b', // slate — every unlisted tool\n}\n\n/** Wire tool name → category for the shipped mapping. */\nexport const TOOL_CATEGORIES: Record<Exclude<NodeCategory, 'command' | 'thinking' | 'context' | 'steering'>, readonly string[]> = {\n search: ['web_search', 'web_fetch'],\n agent: ['subagent', 'subagent_acp', 'subagent_fork', 'send_message', 'interrupt_agent', 'list_agents', 'report', 'workflow'],\n execute: ['bash', 'pwsh', 'run_code', 'terminal_open', 'terminal_close', 'terminal_list', 'terminal_read', 'terminal_send', 'terminal_signal', 'str_replace_editor'],\n file: ['read', 'write', 'edit', 'read_image', 'glob', 'grep'],\n task: ['todo_write', 'create_goal', 'get_goal', 'update_goal', 'job_kill', 'job_list', 'job_output', 'schedule_create', 'schedule_delete', 'schedule_list', 'exit_plan_mode'],\n other: [],\n}\n\n/** Selector matching every tool row inside a tool-call node. */\nconst TOOL_ROW = '[data-chat-flow-kind=\"tool-call\"] [data-tool]'\n/** The ToolRow root itself (carries data-variant; the wrapper callRow does not). */\nconst TOOL_ROW_ROOT = '[data-chat-flow-kind=\"tool-call\"] [data-tool][data-variant]'\n/** Selector of the command node wrapper. */\nconst COMMAND_ROW = '[data-chat-flow-kind=\"command\"]'\n/** Selector of the Think reasoning row. */\nconst THINK_ROW = '[data-variant=\"think\"]'\n/** Selector of the injected-context row (the flow-item wrapper). */\nconst CONTEXT_ROW = '[data-chat-flow-kind=\"context\"]'\n/** Selector of a settled tool-result row (rc.8: tool results render as their own row). */\nconst TOOL_RESULT_ROW = '[data-chat-flow-kind=\"tool-result\"]'\n\n/**\n * The rows that carry the accent paint: the ToolRow root (not its wrapper\n * callRow — both carry data-tool, only the inner row carries data-variant),\n * command nodes, Think rows, injected-context rows, and tool-result rows.\n * User input rows are excluded — right-alignment already\n * distinguishes them (2026-08-20 用户反馈);steering rows 也走独立规则\n * (见 buildCss:在 userStack 层做 wash,不涂整行 rail)。\n * The 3px inset rail is compensated\n * with a matching padding-left so the rail never covers the row's leading icon.\n */\nconst ACCENTED_ROWS = [\n TOOL_ROW_ROOT, COMMAND_ROW, THINK_ROW, CONTEXT_ROW, TOOL_RESULT_ROW,\n].join(',\\n')\n\n/**\n * Accept a configured CSS color (hex, color functions) or reject it so an\n * invalid value falls back to the category default instead of poisoning CSS.\n * @param value - configured color string.\n * @returns whether the value is a plausible CSS color literal.\n */\nexport function isCssColor(value: string): boolean {\n const trimmed = value.trim()\n if (trimmed === '') return false\n if (/^#[0-9a-f]{3,8}$/i.test(trimmed)) return true\n return /^(rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color|device-cmyk)\\(/i.test(trimmed)\n}\n\n/** Resolve the effective palette from user settings merged over defaults. */\nexport function resolveColors(settings: NodeAppearanceSettings): NodeAppearanceColors {\n const colors: NodeAppearanceColors = { ...DEFAULT_COLORS }\n const configured = settings.colors\n if (configured !== undefined && typeof configured === 'object' && configured !== null) {\n for (const key of Object.keys(DEFAULT_COLORS) as NodeCategory[]) {\n const value = configured[key]\n if (typeof value === 'string' && isCssColor(value)) colors[key] = value\n }\n }\n return colors\n}\n\n/** Escape a tool name into a CSS attribute selector string literal. */\nfunction attributeLiteral(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')\n}\n\n/**\n * Steering marker icon: a corner-up-left arrow (mid-turn guidance inserted\n * into the running answer), drawn as a mask so the icon inherits the\n * configured steering color. Encoded data URI, no external asset.\n */\nconst STEERING_ICON = \"data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='9 14 4 9 9 4'/%3E%3Cpath d='M20 20v-7a4 4 0 0 0-4-4H4'/%3E%3C/svg%3E\"\n\n/**\n * Build the complete stylesheet text for one settings snapshot.\n * @param settings - the namespace scope value (may be partial or undefined).\n * @returns CSS text painting accent rows and (optionally) hiding Think rows.\n */\nexport function buildCss(settings: NodeAppearanceSettings | undefined): string {\n const colors = resolveColors(settings ?? {})\n const toolOverrides = settings?.toolColors\n const lines: string[] = []\n\n // Unlisted tools keep the neutral fallback. Declared BEFORE the per-tool\n // rules: both selectors carry equal specificity (two attribute selectors),\n // so of two conflicting declarations the later one wins — a fallback\n // declared after the category rules would override every category color.\n lines.push(`${TOOL_ROW} { --ncolor-accent: ${colors.other}; }`)\n\n // Per-tool accent assignments (explicit overrides win over category color).\n for (const [category, tools] of Object.entries(TOOL_CATEGORIES)) {\n const key = category as keyof typeof TOOL_CATEGORIES\n for (const tool of tools) {\n const override = toolOverrides?.[tool]\n const color = typeof override === 'string' && isCssColor(override)\n ? override\n : colors[key]\n lines.push(`[data-chat-flow-kind=\"tool-call\"] [data-tool=\"${attributeLiteral(tool)}\"] { --ncolor-accent: ${color}; }`)\n }\n }\n\n // Non-tool accent rows.\n lines.push(`${COMMAND_ROW} { --ncolor-accent: ${colors.command}; }`)\n lines.push(`${THINK_ROW} { --ncolor-accent: ${colors.thinking}; }`)\n lines.push(`${CONTEXT_ROW} { --ncolor-accent: ${colors.context}; }`)\n lines.push(`${TOOL_RESULT_ROW} { --ncolor-accent: ${colors.file}; }`)\n\n // One shared paint rule: 3px inset left rail (layout-free) + 8% wash. The\n // matching padding-left moves the row content off the rail so the leading\n // icon is never covered.\n lines.push(`${ACCENTED_ROWS} {\n box-shadow: inset 3px 0 0 var(--ncolor-accent);\n background-color: color-mix(in srgb, var(--ncolor-accent) 8%, transparent);\n padding-left: 3px;\n}`)\n\n // Steering rows (mid-turn user steering) stay visually distinct from plain\n // user rows with a compass marker beside the right-aligned bubble. The\n // marker is a mask over the user-stack — the container that hugs the bubble\n // — positioned to the left of it, so the tint reads as a glyph next to the\n // message rather than a detached full-width rail (2026-08-21 用户反馈:\n // 整行 rail 突兀,改在 userStack 层做图标区分;slot 方案不可行:\n // conversation.message.images 是 single 槽且已被官方 ui-attachment 占用).\n lines.push(`[data-chat-flow-kind=\"steering\"] [data-time-hover-root] > :first-child {\n position: relative;\n}`)\n lines.push(`[data-chat-flow-kind=\"steering\"] [data-time-hover-root] > :first-child::before {\n content: '';\n position: absolute;\n right: 100%;\n margin-right: 6px;\n top: 50%;\n width: 14px;\n height: 14px;\n transform: translateY(-50%);\n background-color: ${colors.steering};\n -webkit-mask: url(\"${STEERING_ICON}\") center / contain no-repeat;\n mask: url(\"${STEERING_ICON}\") center / contain no-repeat;\n}`)\n\n // Visibility switch: hide Think rows entirely on the frontend. `!important`\n // outranks the module stylesheet's `.root { display: flex }` (same\n // specificity, but the plugin style tag is injected before the module's).\n if (settings?.showThinking === false) {\n lines.push(`${THINK_ROW} { display: none !important; }`)\n // A think-only node leaves its flowItem seat with zero height: the seat\n // still consumes the column's 16px flex gap on both sides, doubling the\n // spacing between the neighbors. Hide the whole seat when the think row\n // is the only child of its block container — block-internal thinks\n // (text + reasoning in one node) stay gap-neutral after hiding the row.\n lines.push(\n `[data-chat-flow-kind=\"assistant\"]:has(${THINK_ROW}:only-child),`,\n `[data-chat-flow-kind=\"assistant-step\"]:has(${THINK_ROW}:only-child) { display: none !important; }`,\n )\n }\n\n return lines.join('\\n')\n}\n","/**\n * The plugin's General-settings row: a \"节点外观\" title with the standard\n * chevron, expanding to palette rows, tool overrides, and the Think\n * visibility switch. Reads the namespace scope through the injected hooks\n * face and writes through the injected actions; every change applies\n * immediately. Drawn by hand (no value import from ui-settings-plugins — the\n * client bundle purity gate forbids cross-plugin value imports), styled with\n * the DSH design tokens like the shipped Appearance row.\n */\n\nimport { useState, type ChangeEvent, type FormEvent } from 'react'\nimport type { SettingsScopeSnapshot } from '@deepseek-ai/dsh-client-runtime/client'\nimport { IconChevronDownOutline14 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport {\n DEFAULT_COLORS, isCssColor, resolveColors, TOOL_CATEGORIES,\n type NodeAppearanceSettings, type NodeCategory,\n} from './palette.ts'\nimport css from './card.module.css'\n\n/** The row's inject face: the read-only scope snapshot plus write actions. */\nexport interface NodeAppearanceRowFace {\n hooks: {\n /** The bound settings-scope snapshot, rendered as useNodeAppearance. */\n nodeAppearance: {\n getSnapshot(): SettingsScopeSnapshot<NodeAppearanceSettings>\n subscribe(listener: () => void): () => void\n }\n }\n /** Write the Think visibility switch. */\n setShowThinking(show: boolean): void\n /** Merge one category color into the palette section. */\n setCategoryColor(category: NodeCategory, color: string): void\n /** Merge one tool override into the toolColors section. */\n setToolColor(tool: string, color: string): void\n /** Remove one tool override. */\n removeToolColor(tool: string): void\n}\n\n/** Props the renderer binds for this General row. */\nexport type NodeAppearanceRowProps =\n PropsRuntime<'settings.general.item'>\n & InjectFace<NodeAppearanceRowFace>\n\n/** Chinese labels per category (product copy is Chinese). */\nconst CATEGORY_LABELS: Record<NodeCategory, string> = {\n search: '联网搜索',\n agent: '智能体调用',\n execute: '代码 / 指令执行',\n file: '文件操作',\n task: '任务 / 目标',\n command: '指令节点',\n thinking: '思考过程',\n context: '上下文注入',\n steering: '模型引导',\n other: '其他工具',\n}\n\n/** Tools shown in the add-override autocomplete-free text input placeholder. */\nconst TOOL_SUGGESTIONS = Object.values(TOOL_CATEGORIES).flat().join('、')\n\n/**\n * Render the node-appearance General row.\n * @param props - the injected scope snapshot hook and write actions.\n * @returns the row, always visible once its namespace is served.\n */\nexport function NodeAppearanceRow({ useNodeAppearance, setShowThinking, setCategoryColor, setToolColor, removeToolColor }: NodeAppearanceRowProps) {\n const [open, setOpen] = useState(false)\n const [toolName, setToolName] = useState('')\n const [toolColor, setToolColorDraft] = useState('#64748b')\n const snapshot = useNodeAppearance(snapshot => snapshot)\n const colors = resolveColors(snapshot.value ?? {})\n const toolColors = snapshot.value?.toolColors ?? {}\n const showThinking = snapshot.value?.showThinking ?? true\n const disabled = snapshot.writable === false\n\n const addTool = (event: FormEvent) => {\n event.preventDefault()\n const name = toolName.trim()\n if (name === '' || !isCssColor(toolColor)) return\n setToolColor(name, toolColor)\n setToolName('')\n }\n\n return (\n <div className={css.group}>\n <button\n type=\"button\"\n className={css.header}\n aria-expanded={open}\n onClick={() => { setOpen(!open) }}\n >\n <span className={css.title}>节点外观</span>\n <IconChevronDownOutline14 className={open ? css.chevronOpen : css.chevron} />\n </button>\n {open && (\n <div className={css.body}>\n {snapshot.status !== 'ready' && (\n <p className={css.statusLine}>\n {snapshot.status === 'unavailable'\n ? '配置暂不可用:插件主机侧未挂载或连接非本机。'\n : '配置加载中…'}\n </p>\n )}\n <div className={`${disabled ? css.disabled : ''}`}>\n <div className={css.row}>\n <label className={css.rowLabel} htmlFor=\"node-appearance-show-thinking\">显示思考过程</label>\n <span className={css.rowHint}>关闭后会话中的 Think 思考行隐藏</span>\n <button\n id=\"node-appearance-show-thinking\"\n className={`${css.switch}${showThinking ? ` ${css.on}` : ''}`}\n type=\"button\"\n aria-pressed={showThinking}\n onClick={() => { setShowThinking(!showThinking) }}\n >\n <span className={css.knob} />\n </button>\n </div>\n {(Object.keys(CATEGORY_LABELS) as NodeCategory[]).map(category => (\n <div className={css.row} key={category}>\n <label className={css.rowLabel} htmlFor={`node-appearance-color-${category}`}>\n {CATEGORY_LABELS[category]}\n </label>\n <input\n id={`node-appearance-color-${category}`}\n className={css.colorInput}\n type=\"color\"\n value={colors[category]}\n onChange={(event: ChangeEvent<HTMLInputElement>) => { setCategoryColor(category, event.target.value) }}\n />\n <span className={css.colorValue}>{colors[category]}</span>\n </div>\n ))}\n <div className={css.sectionTitle}>工具颜色覆盖(可选)</div>\n {Object.entries(toolColors).map(([tool, color]) => (\n <div className={css.toolRow} key={tool}>\n <span className={css.toolName} title={tool}>{tool}</span>\n <input\n className={css.colorInput}\n type=\"color\"\n value={isCssColor(color) ? color : DEFAULT_COLORS.other}\n onChange={(event: ChangeEvent<HTMLInputElement>) => { setToolColor(tool, event.target.value) }}\n />\n <button type=\"button\" className={css.removeButton} onClick={() => { removeToolColor(tool) }}>删除</button>\n </div>\n ))}\n <form className={css.addRow} onSubmit={addTool}>\n <input\n className={css.toolInput}\n type=\"text\"\n placeholder={`工具名,如 ${TOOL_SUGGESTIONS}`}\n value={toolName}\n onChange={(event: ChangeEvent<HTMLInputElement>) => { setToolName(event.target.value) }}\n />\n <input\n className={css.colorInput}\n type=\"color\"\n value={toolColor}\n onChange={(event: ChangeEvent<HTMLInputElement>) => { setToolColorDraft(event.target.value) }}\n />\n <button type=\"submit\" className={css.addButton} disabled={toolName.trim() === ''}>添加</button>\n </form>\n </div>\n </div>\n )}\n </div>\n )\n}\n","/**\n * Browser half: binds the `node-appearance` settings scope, paints the chat\n * flow from it (a single <style data-plugin-css> tag rebuilt on every\n * snapshot change), and registers the settings card.\n */\n\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { SettingsScope } from '@deepseek-ai/dsh-client-runtime/client'\n// Type-only: the ctx.settingsScope Context merge and the slot's declaration.\n// Cross-plugin collaboration goes through cordis services; a value import\n// would fail the client bundle-purity gate.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\nimport { buildCss, NODE_APPEARANCE_NS, STYLE_TAG_ID, type NodeAppearanceSettings } from './palette.ts'\nimport { NodeAppearanceRow, type NodeAppearanceRowFace } from './settings-card.tsx'\n\nexport const inject = ['slots', 'connection', 'remote', 'settingsScope']\n\n/** Upsert the plugin's paint stylesheet with the current snapshot's CSS. */\nfunction paint(scope: SettingsScope<NodeAppearanceSettings>): void {\n let tag = document.querySelector<HTMLStyleElement>(`style[data-plugin-css=\"${STYLE_TAG_ID}\"]`)\n if (tag === null) {\n tag = document.createElement('style')\n tag.dataset.plugin = NODE_APPEARANCE_NS\n tag.dataset.pluginCss = STYLE_TAG_ID\n document.head.appendChild(tag)\n }\n tag.textContent = buildCss(scope.getSnapshot().value)\n}\n\n/**\n * Mount the node-appearance plugin on the page.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n const scope = ctx.settingsScope.bind<NodeAppearanceSettings>({ namespace: NODE_APPEARANCE_NS })\n // Paint once from the current snapshot (defaults before the first Host read).\n paint(scope)\n ctx.effect(\n () => scope.subscribe(() => { paint(scope) }),\n 'dsh-node-appearance: repaint on settings change',\n )\n\n const face: NodeAppearanceRowFace = {\n hooks: { nodeAppearance: scope },\n setShowThinking: (show) => { void scope.set('showThinking', show) },\n setCategoryColor: (category, color) => {\n const value = scope.getSnapshot().value\n void scope.set('colors', { ...value?.colors, [category]: color })\n },\n setToolColor: (tool, color) => {\n const value = scope.getSnapshot().value\n void scope.set('toolColors', { ...value?.toolColors, [tool]: color })\n },\n removeToolColor: (tool) => {\n const value = scope.getSnapshot().value\n const toolColors = { ...value?.toolColors }\n delete toolColors[tool]\n void scope.set('toolColors', toolColors)\n },\n }\n\n // The General settings section stacks preference rows (locale → Language,\n // ui-theme → Appearance, dsh-skin → Skins). Node appearance is the same\n // kind of visual preference, so it registers here beside them.\n ctx.slots.inject('settings.general.item', () => ctx.slots.register({\n name: 'settings.general.item',\n id: NODE_APPEARANCE_NS,\n order: 30,\n inject: () => face,\n }, NodeAppearanceRow))\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"palette.d.ts","sourceRoot":"","sources":["../../../src/client/palette.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,oFAAoF;AACpF,eAAO,MAAM,kBAAkB,oBAAoB,CAAA;AAEnD,4EAA4E;AAC5E,eAAO,MAAM,YAAY,0BAAgC,CAAA;AAEzD,uFAAuF;AACvF,MAAM,MAAM,YAAY,GACpB,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAA;AAEhH,8CAA8C;AAC9C,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAA;AAE/D,qEAAqE;AACrE,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAClC,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG,SAAS,CAAA;IAClD,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;CAChD;AAED,kFAAkF;AAClF,eAAO,MAAM,cAAc,EAAE,oBAW5B,CAAA;AAED,yDAAyD;AACzD,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAO7H,CAAA;AA6BD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAKjD;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,QAAQ,EAAE,sBAAsB,GAAG,oBAAoB,CAUpF;AAcD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,GAAG,SAAS,GAAG,MAAM,CAsE7E"}
1
+ {"version":3,"file":"palette.d.ts","sourceRoot":"","sources":["../../../src/client/palette.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,oFAAoF;AACpF,eAAO,MAAM,kBAAkB,oBAAoB,CAAA;AAEnD,4EAA4E;AAC5E,eAAO,MAAM,YAAY,0BAAgC,CAAA;AAEzD,uFAAuF;AACvF,MAAM,MAAM,YAAY,GACpB,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAA;AAEhH,8CAA8C;AAC9C,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAA;AAE/D,qEAAqE;AACrE,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAClC,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG,SAAS,CAAA;IAClD,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;CAChD;AAED,kFAAkF;AAClF,eAAO,MAAM,cAAc,EAAE,oBAW5B,CAAA;AAED,yDAAyD;AACzD,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAO7H,CAAA;AA6BD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAKjD;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,QAAQ,EAAE,sBAAsB,GAAG,oBAAoB,CAUpF;AAcD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,GAAG,SAAS,GAAG,MAAM,CA+E7E"}
@@ -1 +1 @@
1
- {"version":3,"file":"settings-card.d.ts","sourceRoot":"","sources":["../../../src/client/settings-card.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAA;AAEnF,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAEhF,OAAO,EAEL,KAAK,sBAAsB,EAAE,KAAK,YAAY,EAC/C,MAAM,cAAc,CAAA;AAGrB,8EAA8E;AAC9E,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE;QACL,wEAAwE;QACxE,cAAc,EAAE;YACd,WAAW,IAAI,qBAAqB,CAAC,sBAAsB,CAAC,CAAA;YAC5D,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;SAC5C,CAAA;KACF,CAAA;IACD,yCAAyC;IACzC,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;IACpC,yDAAyD;IACzD,gBAAgB,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7D,2DAA2D;IAC3D,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/C,gCAAgC;IAChC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CACpC;AAED,qDAAqD;AACrD,MAAM,MAAM,sBAAsB,GAChC,YAAY,CAAC,uBAAuB,CAAC,GACnC,UAAU,CAAC,qBAAqB,CAAC,CAAA;AAmBrC;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,iBAAiB,EAAE,eAAe,EAAE,gBAAgB,EAAE,YAAY,EAAE,eAAe,EAAE,EAAE,sBAAsB,+BAmGhJ"}
1
+ {"version":3,"file":"settings-card.d.ts","sourceRoot":"","sources":["../../../src/client/settings-card.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAA;AAEnF,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAEhF,OAAO,EAEL,KAAK,sBAAsB,EAAE,KAAK,YAAY,EAC/C,MAAM,cAAc,CAAA;AAGrB,8EAA8E;AAC9E,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE;QACL,wEAAwE;QACxE,cAAc,EAAE;YACd,WAAW,IAAI,qBAAqB,CAAC,sBAAsB,CAAC,CAAA;YAC5D,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;SAC5C,CAAA;KACF,CAAA;IACD,yCAAyC;IACzC,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;IACpC,yDAAyD;IACzD,gBAAgB,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7D,2DAA2D;IAC3D,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/C,gCAAgC;IAChC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CACpC;AAED,qDAAqD;AACrD,MAAM,MAAM,sBAAsB,GAChC,YAAY,CAAC,uBAAuB,CAAC,GACnC,UAAU,CAAC,qBAAqB,CAAC,CAAA;AAmBrC;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,iBAAiB,EAAE,eAAe,EAAE,gBAAgB,EAAE,YAAY,EAAE,eAAe,EAAE,EAAE,sBAAsB,+BAqGhJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@max-null/dsh-node-appearance",
3
- "version": "0.2.3",
3
+ "version": "0.3.3",
4
4
  "description": "会话节点外观插件:按节点类型/工具名着色的可配置配色,思考过程显示开关(DeepSeek Harness Web GUI)",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -33,6 +33,7 @@
33
33
  "client": {
34
34
  "inject": [
35
35
  "@deepseek-ai/dsh-client-runtime",
36
+ "@deepseek-ai/dsh-client-ui-primitives",
36
37
  "@deepseek-ai/dsh-client-ui-settings",
37
38
  "@deepseek-ai/dsh-client-ui-settings-plugins"
38
39
  ],
@@ -69,18 +70,21 @@
69
70
  },
70
71
  "peerDependencies": {
71
72
  "@deepseek-ai/cordis": "^4.0.1",
72
- "@deepseek-ai/dsh-client-runtime": ">=0.1.0-rc.7",
73
- "@deepseek-ai/dsh-client-ui-settings": ">=0.1.0-rc.7",
74
- "@deepseek-ai/dsh-client-ui-settings-plugins": ">=0.1.0-rc.7",
75
- "@deepseek-ai/dsh-settings": ">=0.1.0-rc.7",
73
+ "@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.1",
74
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.1-rc.1",
75
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.1-rc.1",
76
+ "@deepseek-ai/dsh-client-ui-settings-plugins": "^0.1.1-rc.1",
77
+ "@deepseek-ai/dsh-settings": "^0.1.1-rc.1",
76
78
  "react": "^18.2.0"
77
79
  },
78
80
  "devDependencies": {
79
81
  "@deepseek-ai/cordis": "^4.0.1",
80
- "@deepseek-ai/dsh-client-runtime": ">=0.1.0-rc.7",
81
- "@deepseek-ai/dsh-client-ui-settings": ">=0.1.0-rc.7",
82
- "@deepseek-ai/dsh-client-ui-settings-plugins": ">=0.1.0-rc.7",
83
- "@deepseek-ai/dsh-settings": ">=0.1.0-rc.7",
82
+ "@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.1",
83
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.1-rc.1",
84
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.1-rc.1",
85
+ "@deepseek-ai/dsh-client-ui-settings-plugins": "^0.1.1-rc.1",
86
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.1-rc.1",
87
+ "@deepseek-ai/dsh-settings": "^0.1.1-rc.1",
84
88
  "@types/node": "^26.0.0",
85
89
  "@types/react": "~18.3.1",
86
90
  "lightningcss": "^1.32.0",