From ec338c687e2e04bd37ab5c76a0a9c19769190502 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Sun, 30 Aug 2026 02:09:13 +0800
Subject: [PATCH] docs: record 8.4.0 testflight upload

---
 CODEGRAPH.md |   27 ++++++++++++++++-----------
 1 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/CODEGRAPH.md b/CODEGRAPH.md
index fc7f098..fa29b4f 100644
--- a/CODEGRAPH.md
+++ b/CODEGRAPH.md
@@ -1,13 +1,13 @@
 # TagLauncher CODEGRAPH
 
-最后更新:2026-07-02
+最后更新:2026-07-07
 
 用途:本文件是 TagLauncher 的长期工程地图。修改用户可见行为、状态模型、构建/发布入口、核心源码或 QA 入口前,应先读本文件,再读指向的真实源码。若本文件与源码不一致,以源码为准,并在同一任务内更新本文件。
 
 ## 项目边界
 
-- 仓库根目录:`/Users/ar/Projects/Taglauncher2/03-O`
-- 唯一源码根目录:`/Users/ar/Projects/Taglauncher2/03-O/C1.source`
+- 仓库根目录:`/Users/ar/Projects/Taglauncher/03-O`
+- 唯一源码根目录:`/Users/ar/Projects/Taglauncher/03-O/C1.source`
 - macOS App 源码:`C1.source/Apptag/`
 - 构建入口:`C1.source/build.sh`
 - DMG 打包入口:`C1.source/make_dmg.sh`
@@ -33,11 +33,12 @@
   - 编辑模式使用 runtime theme override:任何主题下进入编辑都临时显示默认浅色毛玻璃。
   - 使用最近一次完整 `AppLibrarySnapshot` 先渲染 AppGrid,再后台刷新,避免启动/重开时立刻显示转圈。
   - 使用技巧关闭提醒由 `ContentView` 统一弹 modal 并写入 `hideUsageTips` / `skipUsageTipsCloseReminder`。
+  - Quick Search 标签筛选状态只存在于当前面板生命周期;`ContentView` 从当前索引和 `tagDefinitions` 生成可选真实标签,并通过 `AppContainerID.isReservedGroupName` 排除未分类 / Mac 自带 / 不常用等保护容器名,打开、关闭、初始 Quick Search、标签删除/重命名或刷新后失效时都清空筛选。
   - Quick Search 点击 TagLauncher 自身结果时只关闭当前浮层,不走外部自启动,避免 AppGrid 被重新拉起。
 - `C1.source/Apptag/PreferencesView.swift`
   - `PreferencesView`:设置窗口、语言、通用、主题、快捷键、标签、数据、Pro、关于等设置页。
   - 顶部设置页签必须保持 8 个标签总宽不超过旧 7 标签宽度;图标统一使用线型 SF Symbols,`Pro` 页签位于数据之后、关于之前,使用线型皇冠。
-  - 设置页签下方按页签渲染统一固定位置的 `settingsFixedProHeader`:语言 / 通用 / 主题 / 快捷键 / 标签 / 数据 / Pro / 关于 8 个页签都显示该行且位置不漂移。免费态左侧状态用“当前免费版用户”完整句而不是“免费版”胶囊;通用 / 主题 / 快捷键 / 标签 / 数据页显示当前 tab 对应购买引导和解锁/恢复按钮,语言和关于页只显示状态与操作按钮,不显示购买说明文字;已解锁 Pro 时,语言 / Pro / 关于页统一居中显示 `Pro 已解锁` 胶囊加 `settings.proStatus.proUser` 文案,不显示恢复购买按钮,且 `settings.proStatus.proUser` 本地化文字不再内置皇冠图标。
+  - 设置页签下方按页签渲染统一固定位置的 `settingsFixedProHeader`:语言 / 通用 / 主题 / 快捷键 / 标签 / 数据 / Pro / 关于 8 个页签都显示该行且位置不漂移。免费态左侧状态用“当前免费版用户”完整句而不是“免费版”胶囊;通用 / 主题 / 快捷键 / 标签 / 数据页显示当前 tab 对应购买引导和解锁/恢复按钮,语言和关于页只显示状态与操作按钮,不显示购买说明文字;已解锁 Pro 时,语言 / Pro / 关于页统一居中显示 `Pro 已解锁` 胶囊加 `settings.proStatus.proUser` 文案,不显示恢复购买按钮,且 `settings.proStatus.proUser` 本地化文字不再内置皇冠图标。8.3.6 起该固定行不渲染包住整行的外层圆角矩形背景或描边。
   - Pro 专属主题、彩色容器 / 彩色网格、自定义快捷键、自定义标签颜色和数据导入导出入口即使已解锁,也应保留皇冠 Pro 标识。
   - Language tab 去掉重复标题说明,语言矩阵在主内容区域上下左右居中;About tab 应用信息块也在主内容区域居中。
   - Theme tab 只写视觉偏好 `appGridThemeID` 和炫彩主题调色值,炫彩滑轨只能影响 AppGrid 背景,不得改变标签、排序、备注或分类数据。
@@ -71,7 +72,7 @@
   - `ProStatusPill`:高级功能入口的小型 Pro 胶囊;Pro / 已锁定高级功能使用金色皇冠体系,免费状态使用中性胶囊。
   - `ProUpgradePromptView`:功能被锁时的统一解锁提示,购买 / 恢复动作由调用方闭包绑定。
 - `C1.source/Apptag/AppGridSupport.swift`
-  - 图标气泡、基础 metrics、气泡 placement 支撑。
+  - 图标气泡、基础 metrics、气泡 placement 支撑;备注编辑气泡使用原生 `NSTextField` 桥接,placeholder 需显式使用次级但可读的浅色 attributed string,避免系统默认 placeholder 在深色浮层上近似消失。
 - `C1.source/Apptag/TagNavigationView.swift`
   - AppKit 标签导航栏,支持标签 hover 滚动、选中、拖放、双击进入标签设置页;标签按钮颜色优先使用 `TagDef.customColor`。
 - `C1.source/Apptag/AppDragCoordinator.swift`
@@ -83,7 +84,7 @@
 - `C1.source/Apptag/DataLayer.swift`
   - `AppInfo`:应用模型。
   - `AppDisplayNameResolver`:多语言应用显示名解析。
-  - `AppIndexer`:扫描 `/Applications` 等应用来源,处理 bundle / wrapper / localized display name。
+  - `AppIndexer`:扫描 `/Applications` 等应用来源,处理 bundle / wrapper / localized display name;主分组生成时通过 `AppContainerID.isReservedGroupName` 跳过被错误写成普通标签的未分类 / Mac 自带 / 不常用等保护容器名,避免本地化显示名重复导致标签导航 fatal。
   - `TagGroup` / `TagColor` / `TagCustomColor`:标签分组、基础色和可选 sRGB 自定义色;`TagDef.customColor` 为可选字段,旧 JSON 缺字段时保持兼容。
   - `TagDatabase`:标签、备注、隐藏状态、分类方案、导入导出、备份和持久化。
   - `TagEditor`:把数据库中的标签/备注/隐藏状态标注回扫描到的 App 列表;`setCustomColor` 是写入自定义标签颜色的唯一数据层入口,必须先过 Pro gate,基础色切换会清除自定义色。
@@ -104,9 +105,10 @@
 - `C1.source/Apptag/QuickSearch.swift`
   - `LauncherHotkey` / `LauncherHotkeyKind`:主面板和 Quick Search 快捷键定义。
   - `LauncherHotkeyRegistrationStore`:快捷键注册状态持久化。
-  - `QuickSearchDocument` / `QuickSearchEngine`:搜索索引与排序。
+  - `QuickSearchDocument` / `QuickSearchEngine`:搜索索引与排序;`selectedTagName` 是运行时单选筛选条件,先按真实标签精确收窄文档,再与文本 token 做交集。无文本但已选标签时列出该标签下 App;无标签筛选的空搜索继续保持最近/常用候选。
+  - `QuickSearchTagFilterOption` / `QuickSearchTagFilterBar` / `QuickSearchTagFilterChip`:搜索框下方、结果列表上方的单行横向标签筛选条;只在存在真实可用标签时显示,包含本地化 `全部` 和真实标签胶囊,不改结果长条列表形态。
   - `QuickSearchPanelPresentationView` / `QuickSearchOverlayView` / `QuickSearchResultListHostView`:Quick Search 浮层 UI 与结果列表;Quick Search 面板必须是可成为 key 的激活面板,不能使用 `.nonactivatingPanel`,否则 Return 可能落到前一个前台 App。
-  - `QuickSearchPanel.sendEvent` 对左键点击做 AppKit 层兜底:先通过 `hitTest` 解析 `QuickSearchResultRowView`,失败时按窗口坐标递归扫描结果行几何命中,并走同一启动路径,避免 SwiftUI / NSHostingView / NSScrollView 层级吞掉候选行点击。
+  - `QuickSearchPanel.sendEvent` 对左键点击做 AppKit 层兜底:先解析 `QuickSearchTagFilterClickTargetView` 并触发标签筛选 / 清除;再通过 `hitTest` 和窗口坐标递归几何命中解析 `QuickSearchResultRowView` 并走同一启动路径,避免 SwiftUI / NSHostingView / NSScrollView 层级吞掉标签 chip 或候选行点击。
   - `QuickSearchResultRowView`:结果行内部文字、图标、标签区域统一命中到整行,保证点击任意可见区域都能启动并关闭浮层。
   - `QuickSearchTextField` 同时保留 field editor command delegate 和 `NSControl.target/action` submit fallback,保证 Return / Enter 都能进入 `.submit`。
 - `C1.source/Apptag/LauncherHotkeySettings.swift`
@@ -184,12 +186,14 @@
   - Quick Search 应用显示名回归。
 - `C1.source/Scripts/quick_search_system_app_qa.sh`
   - Quick Search 系统应用回归。
+- `C1.source/Scripts/quick_search_tag_filter_qa.sh`
+  - Quick Search 标签筛选静态门禁;检查运行时单选标签筛选、`全部` 清除、tag chip 原生鼠标命中兜底、空搜索 + 标签列出该标签 App、标签 + 关键词交集、保护容器名从 Quick Search / 主分组排除且导航复用不因重复显示名 fatal、标签条横向胶囊、结果仍走长条候选项和 29 语种本地化 key 完整。
 - `C1.source/Scripts/quick_search_launch_contract_qa.sh`
   - Quick Search 启动路径静态门禁;检查 in-app mouse monitor 不吞结果行点击、面板是激活 key panel、panel-level `sendEvent` 点击兜底存在、Return submit fallback 存在、点击 / submit 都接到 `NSWorkspace.openApplication` 启动路径。
 - `C1.source/Scripts/windowserver_event_safety_qa.sh`
   - WindowServer / TextInput 事件安全静态门禁;检查 Quick Search marked-text 输入保护、composition 期间不响应鼠标 / 背景关闭、面板置前去重,以及 TagNavigation 阻塞式事件循环兜底退出。
 - `C1.source/Scripts/app_note_bubble_input_qa.sh`
-  - App note 泡泡输入框 IME 安全门禁;检查备注泡泡使用原生 `NSTextField` 桥接、marked text 期间不覆盖/截断/提交,最终提交仍受备注长度上限约束。
+  - App note 泡泡输入框 IME / placeholder 可读性门禁;检查备注泡泡使用原生 `NSTextField` 桥接、placeholder 使用显式次级浅色 attributed string、marked text 期间不覆盖/截断/提交,最终提交仍受备注长度上限约束。
 - `C1.source/Scripts/pro_custom_hotkeys_qa.sh`
   - Pro 自定义快捷键静态与 Carbon 运行时门禁;检查 Pro gate、录制期间暂停/恢复全局快捷键、事务式注册保存、重复校验、禁用重权限键盘 API、设置页 Pro 按钮组合和 29 语种文案。
 - `C1.source/Scripts/pro_tag_custom_color_qa.sh`
@@ -205,7 +209,7 @@
 - `C1.source/Scripts/pro_localization_qa.sh`
   - Pro 文案 29 语种静态门禁;检查 `pro.*`、设置页 Pro 状态/对比表、自定义标签颜色、Quick Search 快捷键页和气泡提示设置键完整、占位符完整、无生成污染和非英文语言无英文兜底复制。
 - `C1.source/Scripts/pro_feature_gate_qa.sh`
-  - Pro 功能源码门禁;检查 StoreKit 权益、老用户自动 Pro、主题门禁、导入导出硬拦截、3 条备注额度、自定义标签颜色、自定义快捷键、容器内 App 排序预览、Pro UI 提示、设置页线型图标、轻量 Pro 权益行、Pro 页签、免费列“不支持”状态和 About 页不回归 Pro 汇总卡。
+  - Pro 功能源码门禁;检查 StoreKit 权益、老用户自动 Pro、主题门禁、导入导出硬拦截、3 条备注额度、自定义标签颜色、自定义快捷键、容器内 App 排序预览、Pro UI 提示、设置页线型图标、轻量 Pro 权益行、固定 Pro 行不回归外层圆角矩形框、Pro 页签、免费列“不支持”状态和 About 页不回归 Pro 汇总卡。
 - `C1.source/Scripts/pro_theme_preview_countdown_qa.sh`
   - Pro 主题 / 彩色显示模式预览倒计时门禁;检查状态行倒计时、当前预览卡片 `MM:SS`、到期清理、29 语种 `%time%` 占位符和禁止写死体验时长。
 - `C1.source/Scripts/pro_display_mode_preview_qa.sh`
@@ -242,9 +246,10 @@
 - 旧用户 `useDarkAppGrid=true` 必须迁移到 `deepBlue` 主题。
 - AppGrid 启动或重开不应因为新 `ContentView` 初始 `allApps.isEmpty` 立刻显示转圈;应先复用最近一次完整快照,并延迟显示 loading。
 - Quick Search 显示标题应优先使用解析后的 `AppInfo.displayName`,内部 bundle 名只作为搜索字段。
+- Quick Search 标签筛选条只做 V1 单选运行时过滤:显示 `全部` + 当前索引中真实存在的标签;不得显示未分类 / Mac 自带 / 不常用等保护容器;点击已选标签或 `全部` 清除,并由原生鼠标命中兜底保持面板稳定打开;选中标签后输入关键词必须取交集;不得改成方块矩阵、不得持久化筛选状态。
 - Quick Search 结果行内部文字 / 图标区域不得吞掉点击;点中行内任意可见区域都应按结果启动路径处理。
 - Quick Search 打开后必须可靠接收键盘;面板不得是 non-activating panel,展示时必须激活 App 并成为 key window,Return / Enter 必须通过 command delegate 或 target/action fallback 进入 submit。
-- Quick Search 打开期间,本地 mouse monitor 不得吞掉 TagLauncher overlayWindow 内部事件;外部点击可关闭 Quick Search,结果行点击必须通过 `QuickSearchResultRowView.mouseDown` 或 `QuickSearchPanel.sendEvent` 兜底进入同一启动路径;panel 级兜底不得只依赖 `hitTest`,必须保留窗口坐标递归几何命中结果行的路径。
+- Quick Search 打开期间,本地 mouse monitor 不得吞掉 TagLauncher overlayWindow 内部事件;外部点击可关闭 Quick Search,标签 chip 和结果行点击必须通过对应 native view mouseDown 或 `QuickSearchPanel.sendEvent` 兜底进入同一筛选 / 启动路径;panel 级兜底不得只依赖 `hitTest`,必须保留窗口坐标递归几何命中路径。
 - Quick Search-only 点击 TagLauncher 自身结果必须关闭浮层,不得重新打开 AppGrid。
 - Apple 默认应用备注必须按当前语言显示,不允许 A 语言出现 B 语言备注。
 - SmartStart/default system tag 初始化标签必须按当前语言显示;升级用户启动后应重刷带 `systemCategoryID` 的系统标签,不能长期保留旧英文初始化标签。

--
Gitblit v1.9.3