From e5627facd571293ebba8f05f970121716af39603 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Fri, 05 Jun 2026 01:30:07 +0800
Subject: [PATCH] Include CoreServices apps in quick search index
---
Apptag/DataLayer.swift | 2 +
Apptag/Info.plist | 4 +-
CHANGELOG.md | 6 +++
Scripts/quick_search_system_app_qa.sh | 97 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 107 insertions(+), 2 deletions(-)
diff --git a/Apptag/DataLayer.swift b/Apptag/DataLayer.swift
index 36fd8c8..b77bf4c 100644
--- a/Apptag/DataLayer.swift
+++ b/Apptag/DataLayer.swift
@@ -109,6 +109,7 @@
static let searchPaths: [URL] = [
URL(fileURLWithPath: "/Applications"),
URL(fileURLWithPath: "/System/Applications"),
+ URL(fileURLWithPath: "/System/Library/CoreServices/Applications"),
URL(fileURLWithPath: "/System/Cryptexes/App/System/Applications"),
URL(fileURLWithPath: "/System/Volumes/Preboot/Cryptexes/App/System/Applications"),
FileManager.default.homeDirectoryForCurrentUser
@@ -117,6 +118,7 @@
private static let systemAppPathPrefixes = [
"/System/Applications/",
+ "/System/Library/CoreServices/Applications/",
"/System/Cryptexes/App/System/Applications/",
"/System/Volumes/Preboot/Cryptexes/App/System/Applications/"
]
diff --git a/Apptag/Info.plist b/Apptag/Info.plist
index 11f278e..8cdb717 100644
--- a/Apptag/Info.plist
+++ b/Apptag/Info.plist
@@ -19,9 +19,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>7.8.13</string>
+ <string>7.8.14</string>
<key>CFBundleVersion</key>
- <string>20260604.1121</string>
+ <string>20260605.0122</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e21d2ae..90a7920 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# TagLauncher Changelog
+## [7.8.14] — 2026-06-05
+
+- 修复 Quick Search 和 App Grid 没有扫描 `/System/Library/CoreServices/Applications`,导致“钥匙串访问 / Keychain Access”等系统应用无法被检索和启动的问题
+- 该目录纳入轻量应用目录签名检查;目录未变化时仍不会触发额外索引刷新,避免拖慢打开 App Grid / Quick Search 的体验
+- 版本号更新为 `7.8.14`,Build 更新为 `20260605.0122`
+
## [7.8.13] — 2026-06-04
- 修复 App 运行期间新安装应用后,App Grid 和 Quick Search 仍复用旧应用索引、无法立即检索到新应用的问题
diff --git a/Scripts/quick_search_system_app_qa.sh b/Scripts/quick_search_system_app_qa.sh
new file mode 100755
index 0000000..08e75a1
--- /dev/null
+++ b/Scripts/quick_search_system_app_qa.sh
@@ -0,0 +1,97 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+DATA_LAYER="$ROOT_DIR/Apptag/DataLayer.swift"
+KEYCHAIN_APP="/System/Library/CoreServices/Applications/Keychain Access.app"
+
+rg -Fq 'URL(fileURLWithPath: "/System/Library/CoreServices/Applications")' "$DATA_LAYER"
+rg -Fq '"/System/Library/CoreServices/Applications/"' "$DATA_LAYER"
+
+swift - "$KEYCHAIN_APP" <<'SWIFT'
+import Foundation
+import CoreServices
+
+let appPath = CommandLine.arguments[1]
+let appURL = URL(fileURLWithPath: appPath)
+
+func fail(_ message: String) -> Never {
+ FileHandle.standardError.write(Data("FAIL: \(message)\n".utf8))
+ exit(1)
+}
+
+guard FileManager.default.fileExists(atPath: appPath) else {
+ fail("Keychain Access app is missing at \(appPath)")
+}
+
+let indexedSearchPaths = [
+ "/Applications",
+ "/System/Applications",
+ "/System/Library/CoreServices/Applications",
+ "/System/Cryptexes/App/System/Applications",
+ "/System/Volumes/Preboot/Cryptexes/App/System/Applications",
+ FileManager.default.homeDirectoryForCurrentUser
+ .appendingPathComponent("Applications")
+ .path
+]
+
+guard indexedSearchPaths.contains(where: { appPath.hasPrefix($0 + "/") }) else {
+ fail("Keychain Access is not under a configured app search path")
+}
+
+var names: [String] = [
+ appURL.deletingPathExtension().lastPathComponent
+]
+
+if let item = MDItemCreate(nil, appPath as CFString),
+ let displayName = MDItemCopyAttribute(item, kMDItemDisplayName) as? String {
+ names.append(displayName)
+}
+
+if let bundle = Bundle(url: appURL),
+ let loctableURL = bundle.url(forResource: "InfoPlist", withExtension: "loctable"),
+ let loctable = NSDictionary(contentsOf: loctableURL) as? [String: Any],
+ let zhTable = loctable["zh_CN"] as? [String: Any] {
+ if let value = zhTable["CFBundleDisplayName"] as? String { names.append(value) }
+ if let value = zhTable["CFBundleName"] as? String { names.append(value) }
+}
+
+func normalize(_ value: String) -> String {
+ value
+ .trimmingCharacters(in: .whitespacesAndNewlines)
+ .folding(options: [.caseInsensitive, .diacriticInsensitive], locale: .current)
+ .lowercased()
+}
+
+func pinyinCandidates(for value: String) -> [String] {
+ let mutable = NSMutableString(string: value)
+ CFStringTransform(mutable, nil, kCFStringTransformToLatin, false)
+ CFStringTransform(mutable, nil, kCFStringTransformStripCombiningMarks, false)
+ let spaced = normalize(mutable as String)
+ .components(separatedBy: CharacterSet.alphanumerics.inverted)
+ .filter { !$0.isEmpty }
+ .joined(separator: " ")
+ let compact = spaced.replacingOccurrences(of: " ", with: "")
+ let initials = spaced
+ .split(separator: " ")
+ .compactMap(\.first)
+ .map(String.init)
+ .joined()
+ var seen = Set<String>()
+ return [spaced, compact, initials].filter { !$0.isEmpty && seen.insert($0).inserted }
+}
+
+let searchable = names.flatMap { name in
+ [normalize(name)] + pinyinCandidates(for: name)
+}
+
+let queries = ["keychain", "钥匙串", "yaoshichuan", "ysc"]
+for query in queries {
+ let token = normalize(query)
+ guard searchable.contains(where: { $0 == token || $0.hasPrefix(token) || $0.contains(token) }) else {
+ fail("query \(query) did not match Keychain Access candidates: \(searchable)")
+ }
+}
+
+print("PASS Keychain Access indexed search candidates: \(names.joined(separator: " | "))")
+SWIFT
--
Gitblit v1.9.3