
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),僅供參考