# TagLauncher 当前产品功能树 生成日期:2026-05-20 ## 0. 产品定位 TagLauncher 是一个 macOS 本地 App 启动器。它用“标签 + 默认智能分类 + 快速搜索 + 用途备注”的方式替代纯系统启动器,让用户能够浏览、整理、记忆并快速启动本机 App。 当前产品有两个核心启动入口: - 主界面:用于浏览、整理和维护 App 分类。 - Quick Search:用于键盘肌肉记忆式快速启动。 ## 1. App 外壳与入口 ### 1.1 菜单栏入口 - 在 macOS 菜单栏创建固定状态栏图标。 - 点击菜单栏图标打开或隐藏 TagLauncher 主浮层。 - 菜单包含:显示 App 列表、版本信息、偏好设置、语言切换、退出。 - 菜单栏图标使用稳定 `autosaveName`、identifier 和 accessibility 标识,便于系统和第三方菜单栏管理工具识别。 业务规则: - 菜单栏图标始终可见,除非未来显式增加关闭规则。 - 主菜单中的“显示 App 列表”会根据主快捷键注册状态展示正常标题或“快捷键不可用”类状态。 - 切换语言后,菜单栏和应用菜单需要立即刷新。 ### 1.2 Dock 与应用菜单 - 设置允许显示或隐藏 Dock 图标。 - Dock 图标点击重新打开时,显示主浮层。 - 应用菜单保留偏好设置入口和显示 App 列表入口,移除不需要的系统服务、隐藏、取消隐藏等默认菜单项。 业务规则: - `showDockIcon = true` 时,App 使用 regular activation policy。 - `showDockIcon = false` 时,App 使用 accessory activation policy。 - 设置窗口打开时不隐藏主浮层,而是浮在主浮层上方。 ### 1.3 全局快捷键入口 - 主界面快捷键:`Shift + Option + Space`。 - Quick Search 直接快捷键:`Fn + Space`。 - 两个快捷键均使用 Carbon `RegisterEventHotKey` 注册。 业务规则: - 主快捷键用于打开或隐藏主界面。 - Quick Search 全局快捷键只在主界面不可见时生效;若主界面已经可见,则不额外打开 Quick Search。 - 快捷键注册成功时状态为 `active`。 - 快捷键注册失败时状态为 `failed`,记录失败 OSStatus,并在设置页和菜单中提示。 - 当前版本不提供用户自定义快捷键;旧的快捷键自定义相关 `UserDefaults` 会被清理。 ### 1.4 开机登录 - 设置中可控制是否开机登录。 - 非沙盒环境通过 LaunchAgent 实现。 业务规则: - 新用户默认开启开机登录。 - 沙盒环境不支持当前 LaunchAgent 方式时,默认关闭并不创建 LaunchAgent。 - LaunchAgent 路径为 `~/Library/LaunchAgents/com.apptag.launcher.plist`。 ## 2. 主界面 App 浏览 ### 2.1 App 扫描 扫描范围: - `/Applications` - `/System/Applications` - `/System/Cryptexes/App/System/Applications` - `/System/Volumes/Preboot/Cryptexes/App/System/Applications` - `~/Applications` 业务规则: - 只识别 `.app` 包。 - 跳过隐藏文件。 - 跳过嵌套在其他 `.app` 包内部的 App。 - 对符号链接解析真实路径,避免重复。 - 以 bundle identifier 优先去重;没有 bundle identifier 时以规范化名称去重。 - 去重时优先保留 `/Applications`、用户 `~/Applications`、系统路径等更高分路径。 - 图标在扫描阶段预加载,降低渲染阶段成本。 - 扫描结果有 30 分钟会话缓存。 ### 2.2 App 数据标注 扫描得到的 App 会叠加本地数据库中的用户数据: - 标签 - 是否不常用 - 用户备注 - 启动次数 - 最近启动时间 业务规则: - 扫描结果本身不直接代表用户分类;必须经过 `TagEditor.annotate` 才成为可展示数据。 - Apple App 通过 bundle identifier `com.apple.*` 或系统路径识别。 - Apple App 无论是否有用户标签,都会客观出现在“Mac 自带”分组中。 ### 2.3 分组展示 主界面按标签分组显示 App。 分组类型: - 普通用户标签分组 - 系统 Smart Start 标签分组 - “未分类”分组 - “Mac 自带”分组 业务规则: - 一个 App 可属于多个标签,因此可出现在多个分组。 - 同一 App 在同一分组内只出现一次。 - 非 Apple App 没有任何标签时进入“未分类”。 - Apple App 没有标签时不进入“未分类”,但仍进入“Mac 自带”。 - “Mac 自带”固定排在最后。 - “未分类”固定排在倒数第二。 - 其他分组优先按用户自定义 `tagOrder` 排序,剩余按本地化字符串排序。 - 显示时“未分类”和“Mac 自带”会使用当前语言文案。 ### 2.4 视图样式 当前支持 5 种 App 列表样式: - 平铺 - 无色容器 - 彩色容器 - 无色网格容器 - 彩色网格容器 业务规则: - 新用户默认使用彩色网格容器。 - 平铺模式按分组纵向展开。 - 容器模式采用瀑布流列布局。 - 网格容器模式按可用宽度选择 1、2、3 列轨道,并缓存行布局。 - 彩色容器使用标签色作为背景提示。 - 无色容器 hover 或标签导航触发后会保留填充;再次点击同一容器清除填充。 - 滚动期间冻结 App hover 放大、用途气泡和容器 hover,高频滚动停止约 0.18 秒后恢复。 ### 2.5 标签导航 标签可显示在顶部、左侧或右侧。 业务规则: - 新用户默认标签在右侧。 - 点击标签滚动到对应分组。 - hover 标签时也会滚动到对应分组,并触发无色容器填充。 - 标签导航中的用户标签可长按拖拽排序。 - “Mac 自带”和“未分类”不可排序。 - 排序完成后写入数据库,拖动过程中不持续写盘。 ### 2.6 App 启动 - 点击 App 图标启动对应 App。 - Quick Search 启动和主界面点击启动最终走同一套启动逻辑。 业务规则: - 启动成功后记录该 App 的打开次数和最近打开时间。 - 启动成功后默认隐藏主浮层。 - 启动失败不记录打开历史。 - Quick Search 启动失败时不关闭搜索浮层,而是显示失败提示并保持输入焦点。 - 自动标记为“不常用”的 App,累计从 TagLauncher 成功打开达到 100 次后,会自动取消自动“不常用”标记。 ## 3. App 用途气泡与备注 ### 3.1 用途气泡 - App hover 时可显示黑色气泡,展示 App 名称和备注。 - 气泡支持在 App 上方或下方自动摆位。 业务规则: - 新用户默认“全部应用”都可显示用途气泡。 - 设置中可切换为“仅不常用应用”显示气泡。 - 开始拖拽、滚动、出现模态确认或 Quick Search 时会关闭或禁用气泡。 - 如果隐藏 App 名称且某 App 不会显示用途气泡,hover 时可以临时显示小名称,避免完全不可识别。 ### 3.2 备注编辑 - 右键 App 可编辑备注。 - 备注在气泡内以输入框编辑。 业务规则: - 备注最大长度为 80 个 Unicode 字符。 - 保存时去除首尾空白。 - 空备注会从数据库删除。 - 保存非空备注会自动把该 App 标记为手动“不常用”。 - 编辑备注时降低覆盖层窗口层级,避免输入法候选窗被挡住。 ## 4. App 拖拽整理 ### 4.1 App 拖拽 - 长按 App 图标约 0.5 秒进入拖拽准备。 - 鼠标移动超过阈值后开始拖拽。 - 拖拽时显示放大的 App 图标。 - 按住 Option 拖拽表示复制标签关系。 业务规则: - 拖拽时禁用 hover 气泡。 - 拖拽状态最多自动保持约 8 秒,避免残留。 - 拖拽目标按屏幕坐标命中,优先选择面积更小的目标。 ### 4.2 拖到普通标签 业务规则: - 目标必须是存在于数据库中的标签。 - 拖到同一标签且不是复制模式时无动作。 - 非复制模式会从源标签移除,再加入目标标签。 - 复制模式保留源标签,只追加目标标签。 - 若目标标签不存在,会按传入颜色创建。 - 拖拽完成后触发刷新,并显示最短约 0.85 秒的刷新反馈。 ### 4.3 拖到未分类 业务规则: - 拖到“未分类”不是直接执行,而是先弹出确认浮层。 - 确认后移除该 App 当前全部普通标签。 - 拖到“未分类”不会移除“不常用”状态。 - 用户可以取消误拖。 ### 4.4 拖到 Mac 自带 业务规则: - “Mac 自带”是客观系统属性,不接受用户拖入。 - 拖到“Mac 自带”会显示短提示,不改变数据。 ## 5. 标签管理 ### 5.1 标签增删改 入口: - 主界面编辑模式中的标签编辑 - 设置页标签页 能力: - 新建标签 - 重命名标签 - 删除标签 - 修改标签颜色 - 调整标签顺序 业务规则: - 新建标签名称去除首尾空白,不能为空。 - 如果标签已存在,新建无动作。 - 重命名时新名称不能为空,且不能与已有标签重名。 - 删除标签会从标签定义和所有 App 的标签关系中删除。 - 删除系统标签时,会记录对应系统分类 ID 为已禁用。 - 已禁用的系统分类不会在普通 Smart Start 刷新中偷偷恢复。 - 显式应用系统初始方案时,会清空禁用记录并重建系统分类。 - 标签颜色取值来自固定色板。 ### 5.2 批量编辑 App 标签 - 主界面右上角编辑按钮进入批量编辑 App。 - 支持“添加标签”和“移除标签”两种模式。 业务规则: - 必须同时选择至少一个 App 和至少一个有效标签,确认按钮才可用。 - 添加标签只追加缺失标签,不重复添加。 - 移除标签只移除选中 App 已存在的标签,不影响其他标签。 - “不常用”在编辑模式中作为特殊项显示,不是普通标签。 - 批量操作完成后清空选择状态,刷新 App 列表,并显示反馈浮层。 ## 6. Quick Search 快速搜索 ### 6.1 打开入口 入口: - 主界面可见时按 `Space`。 - 主界面不可见时按 `Fn + Space`。 业务规则: - 主界面内 `Space` 只在非编辑、非备注编辑、非模态、非控件焦点、非文本输入状态下打开 Quick Search。 - Quick Search 打开时不推动、不缩放、不重排 App 列表。 - 通过全局 Quick Search 打开时,关闭搜索会同时隐藏主浮层。 - 从主界面打开时,关闭搜索后保留主界面。 - Quick Search 打开时清空查询并立即聚焦输入框。 ### 6.2 默认快速建议 当查询为空时显示 Quick Suggestions。 业务规则: - 最多显示 6 个 App。 - 先按最近打开时间倒序展示。 - 最近打开不足时,用常用 App 按打开次数补齐。 - 最近和常用只统计 TagLauncher 成功启动过的 App。 - 如果没有任何历史数据,显示空提示,不展示全量 App 列表。 ### 6.3 搜索字段 每个 App 会建立搜索文档,包含: - App 主名称 - App 本地化显示名 - 内部 Bundle 名称 - 标签名 - App 备注 - Bundle identifier - 最近打开时间 - 打开次数 业务规则: - 搜索范围是全部已知可启动 App,不限于当前可见分组。 - 备注优先读取数据库 `appNotes[path]`,其次使用扫描标注中的 note。 - 本地化名称来自 Bundle 本地化信息、Info.plist 和 Finder display name。 - 搜索索引在 App 刷新阶段预计算,避免输入时重复计算。 ### 6.4 匹配规则 支持: - 精确匹配 - 前缀匹配 - 子串匹配 - 首字母缩写匹配 - 非连续字符匹配 - 非拉丁文字拉丁化/拼音候选匹配 业务规则: - 查询会去首尾空白、合并空白、大小写不敏感、变音符不敏感。 - 多词查询是 AND 语义,每个词都必须命中同一 App 的某个字段。 - App 名、标签、备注允许子串和非连续字符匹配。 - Bundle identifier 和内部 Bundle 名只允许精确或前缀匹配。 - 原文字段非连续字符匹配要求查询词至少 4 个字符。 - 拼音或转写候选非连续匹配要求查询词至少 3 个字符。 - 备注允许拼音/转写子串匹配,但不允许拼音/转写非连续匹配。 - 标签原文允许非连续字符匹配,但标签的拼音/转写候选不扩展子串和非连续匹配。 ### 6.5 排序规则 评分模型: ```text finalScore = textScore + behaviorBoost textScore = 每个查询词最佳命中分之和 behaviorBoost = min(recentBoost + frequencyBoost, 20) ``` 字段权重: | 字段 | 权重 | | ----------------- | --: | | App 名称/本地化名称 | 100 | | 标签 | 70 | | 备注 | 45 | | 内部 Bundle 名 | 30 | | Bundle identifier | 20 | 匹配权重: | 匹配类型 | 权重 | | ----- | --: | | 精确 | 100 | | 前缀 | 80 | | 子串 | 60 | | 首字母缩写 | 55 | | 非连续字符 | 35 | 排序兜底: 1. finalScore 高者优先。 2. textScore 高者优先。 3. 最佳字段 rank 更靠前者优先。 4. 最近打开时间更新者优先。 5. 打开次数更多者优先。 6. App 名称更短者优先。 7. App 名称本地化排序。 ### 6.6 搜索交互 业务规则: - 有结果时默认选中第一项。 - 用户用键盘或鼠标手动选中过结果后,如果该结果仍在新结果中,则保留选中。 - 上下方向键在列表边界处停住,不循环。 - Enter 启动选中结果。 - Esc 关闭 Quick Search。 - 鼠标 hover 结果会同步选中。 - 点击结果会启动。 - 点击浮层外部背景关闭 Quick Search。 - App 失去焦点或外部鼠标点击时关闭 Quick Search。 ## 7. Smart Start 智能初始分类 ### 7.1 本地目录 - 使用内置 `SmartStartUltimateDefaultCatalog.json`。 - 当前目录版本为 `2`。 - 目录包含稳定分类 ID、bundle identifier、normalizedName、多语言默认备注和来源证据。 业务规则: - 运行时优先读取 JSON 目录。 - JSON 不可用时才回退旧 CSV 目录。 - 目录中的 `other` 不作为有效赋值标签。 - 匹配优先 bundle identifier,其次 normalizedName。 ### 7.2 自动运行 业务规则: - 当本地 store 的 Smart Start catalogVersion 小于当前版本时运行。 - 或从未运行、从未应用、从未生成建议时运行。 - 如果当前用户没有任何手动 App 标签分配,则自动应用。 - 如果已有用户标签分配,则只生成建议,不静默覆盖。 - 没有匹配结果时,只记录运行状态,不改变分类。 ### 7.3 应用规则 业务规则: - 应用前先备份旧 store。 - 对匹配 App 应用全部目录分类。 - 创建缺失的系统分类标签。 - 不创建用户已删除且记录为 disabled 的系统分类,除非是显式应用系统初始方案。 - 默认备注只在当前备注为空,或当前备注仍是已知默认备注时写入。 - 写入默认备注的 App 会自动标记为自动“不常用”。 - 不覆盖用户手写备注。 - 应用后记录匹配 App 数、赋值标签数、创建标签数、备份路径和模式。 ### 7.4 显式应用系统初始方案 入口:设置页数据页。 业务规则: - 需要确认弹窗。 - 使用当前扫描 App 生成 draft。 - 清空现有 tags、appTags、tagOrder 和 disabled system category 记录。 - 创建完整系统分类方案。 - 备份旧方案,可在设置页恢复上一个方案。 ### 7.5 语言切换后的备注重本地化 业务规则: - 切换语言后,系统标签名称会重本地化。 - 默认备注只有在当前备注仍然属于任一语言的默认备注候选时才会替换为当前语言版本。 - 用户改写过的备注不会被语言切换覆盖。 ## 8. 设置系统 设置页包含: - 语言 - 通用 - 快捷键 - 标签 - 数据 - 关于 ### 8.1 语言 业务规则: - 新用户默认跟随系统语言。 - 不支持的系统语言回退英文。 - 用户手动选择语言后,保存为 `appLanguage`。 - 支持 29 种语言。 - 语言切换触发菜单、设置页、标签、默认备注刷新。 ### 8.2 通用 可配置项: - 开机登录 - Dock 显示 - 隐藏 App 名称 - App 列表样式 - 标签位置 - 标签字号 - 图标大小 新用户默认值: - 开机登录:开 - Dock 显示:开 - 隐藏 App 名称:开 - App 列表样式:彩色网格容器 - 标签位置:右侧 - 标签字号:22 - 图标大小:80 ### 8.3 快捷键 业务规则: - 当前设置页只展示固定快捷键信息和注册状态。 - 主快捷键:`Shift + Option + Space`。 - 主界面内 Quick Search:`Space`。 - 全局 Quick Search:`Fn + Space`。 - 注册失败时显示不可用状态和失败提示。 ### 8.4 标签 业务规则: - 标签页复用主界面的标签编辑组件。 - “Mac 自带”和“未分类”不作为普通用户可编辑标签。 - 编辑完成后刷新当前 App 数据。 ### 8.5 数据 能力: - 查看系统初始方案、上一个方案、当前方案。 - 应用系统初始方案。 - 恢复上一个方案。 - 导出当前分类数据。 - 导入分类数据。 - 设置用途气泡显示范围。 业务规则: - 导出前刷新分类方案状态,并用当前方案名称生成文件名。 - 导入 JSON 后会把导入前方案保存为“上一个方案”。 - 文件选择面板以设置窗口 sheet 方式显示。 - 自动分类方案备份保留 30 天。 ### 8.6 关于 - 显示 App 名称、描述、版本号、构建号和署名文案。 ## 9. 本地化 业务规则: - UI 文案通过 `tr(key)` 获取。 - 当前语言资源从 `Apptag/Localization/.json` 加载。 - 如果指定语言资源缺失,回退英文。 - 系统分类名称按当前语言动态读取。 - 分类方案名称中的时间戳使用语言无关格式 `yyyy.MMdd.HHmm`。