ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Qwen Code 会话分组自定义 Hex 颜色:从核心校验到 WebShell 的端到端实现指南

Qwen Code 会话分组自定义 Hex 颜色:从核心校验到 WebShell 的端到端实现指南 Qwen Code 会话分组自定义 Hex 颜色从核心校验到 WebShell 的端到端实现指南【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code本文围绕 qwen-code 仓库中命名会话组自定义 Hex 颜色issue #6744这一功能展开完整梳理其从核心服务校验、REST/ACP 传输、TypeScript SDK 类型到 WebShell 侧边栏编辑器的全链路实现与验证方案。读完本文你将掌握六位#RRGGBB颜色值的接受规则与归一化策略、预设色与自定义色的边界划分、以及如何用一套 e2e 测试计划对核心契约 守护进程传输 前端 UI三层做回归验证。背景为什么需要自定义分组颜色qwen-code 中命名会话组named session groups此前与快速会话颜色标签quick session color tags共享同一个六值颜色枚举red、orange、yellow、green、blue、purple。这套枚举带来的限制是明确的守护进程daemon对任何枚举之外的取值一律以invalid_group_color拒绝TypeScript SDK 暴露的是同样的封闭联合类型closed unionWebShell 的分组编辑器只提供一个预设色下拉框。结果就是用户无法让命名分组与既有项目配色对齐也无法在分组目录变大时靠颜色做视觉区分。该问题由 docs/design/session-group-custom-hex-colors.md 记录设计决策并在 .qwen/e2e-tests/session-group-custom-hex-colors.md 中给出完整验证方案。设计上遵循一个核心原则将预设会话标签色与命名分组展示色拆成两条互不干扰的路径——命名分组接受预设色或六位 Hex快速标签保持预设色不变。各层改动一览层变更内容Core把预设会话标签色与命名分组展示色拆分。命名分组接受预设色或六位#RRGGBB快速标签仅限预设色。有效 Hex 在持久化前统一归一化为小写。REST / ACP快速标签校验保持预设色唯一命名分组颜色透传给 Core 校验。TypeScript SDK导出预设色与 Hex 色两种类型。分组输入/输出使用二者的联合类型会话组织session organization继续使用预设色。WebShell保留预设选项新增 Custom 选项原生取色器 Hex 文本框。自定义分组圆点以内联background-color渲染。对应源码文件清单见设计文档 docs/design/session-group-custom-hex-colors.md核心实现集中在 packages/core/src/services/session-organization-service.ts。核心契约Core 层的颜色校验与归一化类型边界预设色 vs Hex 色packages/core/src/services/session-organization-service.ts 中定义了清晰的类型体系export const GROUP_COLOR_OPTIONS [ red, orange, yellow, green, blue, purple, ] as const; export type SessionGroupPresetColor (typeof GROUP_COLOR_OPTIONS)[number]; /** Shape hint only; runtime validation below enforces exactly six Hex digits. */ export type SessionGroupHexColor #${string}; export type SessionGroupColor SessionGroupPresetColor | SessionGroupHexColor;注意SessionGroupHexColor在类型层面只是#${string}的形状提示真正的必须恰好六位十六进制约束由运行时校验强制见normalizeGroupColor。与此同时会话组织SessionOrganization的color字段仍限定为SessionGroupPresetColor | nullassertSessionColor也严格拒绝非预设值——这就是会话快速标签仍拒绝 Hex的实现根基。归一化规则trim 小写normalizeGroupColor是这一功能的核心函数function normalizeGroupColor(color: unknown): SessionGroupColor { const normalized typeof color string ? color.trim() : color; if (typeof normalized string isPresetGroupColor(normalized)) { return normalized; } if (typeof normalized string /^#[0-9a-f]{6}$/i.test(normalized)) { return normalized.toLowerCase() as SessionGroupHexColor; } throw new SessionOrganizationError( color must be a supported preset or a #RRGGBB hex value, invalid_group_color, color, ); }关键行为接受偶然的周边空白先trim()因此 #12ABEF 也能通过小写规范化#12ABEF会被持久化为#12abef保证所有已存值形态可预测严格六位正则^#[0-9a-f]{6}$i标志拒绝三、四、八位形式如#abc、#abcd、#aabbccdd也拒绝命名 CSS 颜色与 alpha 通道失败即抛错invalid_group_color结构化错误附带field: color字段便于 REST 层直接映射 HTTP 400。createGroup与updateGroup都会在写库前调用normalizeGroupColor随后通过withStoreLock串行化写操作并调用atomicWriteJSON做原子写入。分组名称同样有独立校验1–64 字符、禁止控制字符、大小写不敏感去重颜色只是其中的一个字段。持久化与容错分组数据存储在侧边车文件session-organization.v1.json中STORE_FILE常量schema 版本保持为 1——因为存储字段仍是字符串旧预设值天然有效无需迁移。读取侧normalizeSessionGroup对不支持的颜色值做降级处理回退到FALLBACK_GROUP_COLOR blue并只告警一次确保未来出现未知颜色类时旧客户端也能安全失败。测试印证packages/core/src/services/session-organization-service.test.ts 中有一条与本文主题直接对应的用例it(accepts and normalizes custom hex colors for named groups, async () { const group await service.createGroup({ name: Custom, color: #12ABef as never, }); expect(group.color).toBe(#12abef); const updated await service.updateGroup(group.id, { color: #FEDCBA as never, }); expect(updated.color).toBe(#fedcba); const catalog await service.listGroups(); expect(catalog.groups[0]?.color).toBe(#fedcba); expect(catalog.colorOptions).toEqual(GROUP_COLOR_OPTIONS); const restarted new SessionOrganizationService(cwd); expect((await restarted.listGroups()).groups[0]?.color).toBe(#fedcba); });这条用例同时验证了带空白输入被接受、小写归一化、列表读取返回规范值、重启后restarted实例持久化值不丢失、且colorOptions预设目录保持原样。同文件还覆盖了#abc被拒、pink等非预设/非 Hex 值返回invalid_group_color、未知存储色回退为blue并告警等容错路径。传输层REST 与 ACP 的 Hex 透传REST 层位于 packages/cli/src/serve/routes/session.ts命名分组路由在 POST/workspace/:id/session-groups与 PATCH/workspace/:id/session-groups/:groupId中把请求体color字段原样传入 Coreconst group await runWithWorkspaceRuntimeStorage(runtime, () service.createGroup({ name: body[name] as string, color: body[color] as SessionGroupColor, }), ); res.status(201).json({ group });也就是说REST 层对命名分组颜色不做二次校验全部交由 Core 的normalizeGroupColor决定成败——非法值自然映射为invalid_group_color错误HTTP 400合法 Hex 则回传小写规范化后的值。快速标签路径session organization 的color字段则保持预设色唯一校验例如 packages/cli/src/serve/routes/session.ts 中对rawColor的检查仍限定为SessionGroupPresetColor | null。ACPAgent Client ProtocolHTTP 侧由packages/cli/src/serve/acp-http/dispatch.ts走同样的校验与转发逻辑桥接层类型定义在 packages/acp-bridge/src/bridgeTypes.ts。SDK 类型导出预设色与 Hex 的联合类型TypeScript SDK 的类型定义位于 packages/sdk-typescript/src/daemon/types.tsexport type DaemonSessionGroupPresetColor /* 六值预设色 */; export type DaemonSessionGroupHexColor #${string}; export type DaemonSessionGroupColor | DaemonSessionGroupPresetColor | DaemonSessionGroupHexColor;分组创建/更新输入color?: DaemonSessionGroupColor与分组返回类型color: DaemonSessionGroupColor使用联合类型因此#12abef可以完整地经 SDK 往返会话组织相关接口color?: DaemonSessionGroupPresetColor | null仍限定预设色与 Core 的SessionOrganization边界保持一致分组目录响应中的colorOptions继续返回预设色数组。SDK 的导出面packages/sdk-typescript/src/daemon/index.ts与packages/sdk-typescript/src/index.ts需要把新类型暴露给使用方。WebShellCustom 选项与取色器实现渲染逻辑Hex 判定与内联背景色packages/web-shell/client/components/sidebar/WebShellSidebar.tsx 中分组圆点的渲染按是否为 Hex分流function getGroupColorClass(color: DaemonSessionGroupColor) { if (color.startsWith(#)) return styles.groupColorCustom; // ... 预设色走既有 class } function getGroupColorStyle(color: DaemonSessionGroupColor) { return color.startsWith(#) ? { backgroundColor: color } : undefined; }预设色继续使用预定义 CSS 类packages/web-shell/client/components/sidebar/WebShellSidebar.module.css自定义 Hex 分组则通过内联background-color渲染圆点——这样不认识 Hex 类的旧客户端也能安全失败设计文档明确要求Existing clients that do not recognize a Hex class should fail safely。编辑器取色器与 Hex 文本框双向同步编辑器在 Create/Rename 分组对话框中新增了 Custom 选项下拉框保留全部预设选项并追加自定义Custom选项选中 Custom 后展开一行groupCustomColorRow左侧是原生input typecolor取色器右侧是 Hex 文本输入框组件用lastValidCustomGroupColor状态保存最后一次合法自定义颜色原生取色器变化onChange直接更新该状态Hex 文本框输入先经normalizeHexColorInput校验合法才同步回状态无效文本不会破坏取色器即使 Hex 框内容非法取色器仍停留在上一个合法自定义色上非法 Hex 禁用保存提交前用normalizeGroupColorInput重新校验非法时 Save 按钮不可用并暴露可访问的错误提示带FieldLabel与htmlFor关联的输入框既有自定义值回显编辑已有分组时若group.color以#开头则自动进入 Custom 模式并回填 Hex 框保存成功后分组圆点即使用持久化的 Hex 颜色。相关状态初始化可见 packages/web-shell/client/components/sidebar/WebShellSidebar.tsx 中的setLastValidCustomGroupColor(DEFAULT_CUSTOM_GROUP_COLOR)等逻辑i18n 文案如sidebar.groupColor.hex在 packages/web-shell/client/i18n.tsx 中维护。下面的截图展示了新建分组对话框分组名称为Design system颜色下拉选中自定义...下方出现颜色预览方块与 Hex 文本框当前值#12abefE2E 验证三层回归的完整测试计划功能落地后.qwen/e2e-tests/session-group-custom-hex-colors.md 给出了从基线到构建验证的完整回归路径。基线 dry-run在本地构建之前用全局安装的 CLI 验证旧行为qwen --version对既有 session-groups 端点写入#12ABEF的预期基线是 HTTP 400 且codeinvalid_group_colorWebShell 编辑器只暴露六个预设选项。Group ACore 契约cd packages/core npx vitest run src/services/session-organization-service.test.ts预期结果create/update 接受#12ABEF含偶然的周边空白并返回#12abeflist/restart 保持规范值畸形 Hex 返回invalid_group_color会话快速标签仍拒绝 Hex预设目录保持不变。Group B守护进程传输与 SDKcd packages/cli npx vitest run src/serve/server.test.ts src/serve/acp-http/transport.test.ts cd ../sdk-typescript npx vitest run test/unit/DaemonClient.test.ts预期REST 与 ACP 的命名分组变更往返 Hex 值会话组织仍仅限预设色SDK 分组类型与响应暴露自定义值。Group CWebShell UIcd packages/web-shell npx vitest run client/components/sidebar/WebShellSidebar.test.tsx预期Create/Rename 分组提供 Custom 选项原生取色器与 Hex 文本框保持同步非法文本时取色器停留在最后一个合法自定义色非法 Hex 禁用 Save 并暴露可访问错误既有自定义值以 Custom 模式重新打开自定义分组圆点使用持久化 Hex 色预设选择行为不变。构建验证与手动检查npm run format npm run build npm run typecheck npm run bundle手动 WebShell 检查使用隔离运行目录export QWEN_RUNTIME_DIR$(mktemp -d /tmp/qwen-hex-groups.XXXXXX) node dist/cli.js serve --web在 WebShell 中创建名为Hex demo、颜色为#12ABEF的分组刷新页面后重命名切换到预设色再切回 Custom确认圆点颜色与小写 Hex 均持久化同时确认快速会话标签仍只提供六个预设。结果摘录文档记录的验证结果macOS 环境Core 契约 24 项通过REST 命名分组 Hex 路径 1 项通过ACP HTTP 命名分组 Hex 路径 1 项通过TypeScript SDK 229 项通过WebShell 侧边栏 61 项通过仅存在既有的 Reactact()警告完整server.test.ts674 项通过唯一无关失败位于 extension-update 状态处理期望 202 实际 200。根构建在同步上游 main 并应用 #6748 的ScheduledTasksDialog导入修复后通过。Windows 与 Linux 行为交由 CI 覆盖。边界与设计取舍最后再总结几条关键决策方便后续维护者理解为什么这样做只接受六位#RRGGBB三、四、八位形式一律拒绝保证每个持久化值只有一种可预测形态Core 是权威客户端可以提前归一化以获得即时反馈但最终以 Core 的 trim 小写归一化结果为准不扩展现有快速标签六值预设目录作为紧凑的排序/过滤维度保持向后兼容sidecar schema 保持 v1字段仍是字符串旧预设值继续有效无需迁移旧客户端安全失败WebShell 用内联background-color渲染 Hex 圆点不认识的客户端直接跳过该样式即可快速标签与命名分组互斥在 UI 语义上二者是单选命名分组赋值会清除颜色标签反之亦然这一行为在 packages/web-shell/client/components/sidebar/WebShellSidebar.tsx 的注释与updateSessionOrganization调用中均有体现。至此从 Core 校验、REST/ACP 透传、SDK 类型到 WebShell 交互的完整闭环已经打通。若你想亲手验证直接按上文 Group A/B/C 的命令在对应包目录下运行测试即可复现全部结果。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表