feat: 完成 TraceMemo v2.2.0 品牌身份与数据迁移升级

- 将 WechatExplorer 产品身份升级为 TraceMemo
- 更新 appId、Runtime Identity、Reader Skill 和 API 环境变量
- 增加旧用户数据、Knowledge、Token 与 AI Provider 安全迁移
- 保留 Windows WeFlow 和旧版配置兼容
- 完善首次启动迁移测试及 v2.2.0 发布文档
- 移除 macOS Intel x64 构建与发布支持
This commit is contained in:
Wxw-Gu
2026-08-11 17:52:57 +08:00
parent 0c1d859e1b
commit cf3f115124
39 changed files with 1837 additions and 545 deletions
+28 -11
View File
@@ -272,21 +272,38 @@ export function resolveWindowsNativeAccountRoot(
.find((candidate) => candidate && isAsciiPath(candidate))
if (!publicRoot || !isAsciiPath(publicRoot)) return accountRoot
// Preserve the legacy ASCII bridge path so existing junctions remain reusable.
const bridgeRoot = path.join(publicRoot, 'WechatExplorer', 'path-bridges')
const bridgePath = path.join(
bridgeRoot,
crypto
.createHash('sha256')
.update(path.resolve(accountRoot).toLowerCase())
.digest('hex')
.slice(0, 24)
)
const bridgeId = crypto
.createHash('sha256')
.update(path.resolve(accountRoot).toLowerCase())
.digest('hex')
.slice(0, 24)
const legacyBridgePath = path.join(publicRoot, 'WechatExplorer', 'path-bridges', bridgeId)
try {
if (fs.existsSync(legacyBridgePath)) {
const legacyTarget = fs.realpathSync.native(legacyBridgePath)
const canonicalAccountRoot = fs.realpathSync.native(accountRoot)
if (
path.resolve(legacyTarget).toLowerCase() ===
path.resolve(canonicalAccountRoot).toLowerCase()
) {
return legacyBridgePath
}
}
} catch {
// An unreadable legacy junction is left untouched; TraceMemo creates its own bridge below.
}
const bridgeRoot = path.join(publicRoot, 'TraceMemo', 'path-bridges')
const bridgePath = path.join(bridgeRoot, bridgeId)
try {
fs.ensureDirSync(bridgeRoot)
if (fs.existsSync(bridgePath)) {
const existingTarget = fs.realpathSync.native(bridgePath)
if (path.resolve(existingTarget).toLowerCase() === path.resolve(accountRoot).toLowerCase()) {
const canonicalAccountRoot = fs.realpathSync.native(accountRoot)
if (
path.resolve(existingTarget).toLowerCase() ===
path.resolve(canonicalAccountRoot).toLowerCase()
) {
return bridgePath
}
fs.removeSync(bridgePath)