Skip to content

fix: 修复全新安装后顶部残留大量 project tab + sync 清理 - #115

Merged
ACCSCI merged 6 commits into
masterfrom
fix/sync-cleanup
Jul 15, 2026
Merged

fix: 修复全新安装后顶部残留大量 project tab + sync 清理#115
ACCSCI merged 6 commits into
masterfrom
fix/sync-cleanup

Conversation

@ACCSCI

@ACCSCI ACCSCI commented Jul 15, 2026

Copy link
Copy Markdown
Owner

问题

全新安装 AgentDock 后(无论安装/卸载多少次),顶部残留大量 project tab —— 包括安装目录、历史项目、worktree 目录、build 产物、e2e temp 目录。用户全新安装后未执行任何操作,tab 就已存在。

两个独立根因

根因 1: 打包后 process.cwd() 被 auto-register 成项目

main.ts 启动执行 activeProjectPath = process.cwd()。打包后 cwd = 安装目录(不是用户项目),syncProject 把它 auto-register 成 'AgentDock' 项目。
修复: 仅 dev 模式 auto-init;打包模式显示'打开项目'欢迎页。

根因 2: legacy ~/.agentdock/projects.db 未清理

v0.1-v0.2 的 global DB 在 $HOME/.agentdock/projects.db,积累 41 行历史残留,卸载不清、重装照读。
修复: app 启动时 JS 层清理(100% 可靠,不依赖 NSIS 宏)。

NSIS 踩坑(写进经验文档)

  • $USERPROFILE 不是 NSIS 内置变量 → RMDir 静默失败(warning 6000)→ 改用 $DESKTOP 倒推 home 目录
  • customUnInstall/customUnInstallSection 宏在 NSIS 3.0.4 不展开 → 关键清理放 JS 层,NSIS 只兜底

附带修复(sync-cleanup)

  • syncProject 清理不完整 worktree(无 .git 指针)+ git worktree prune
  • SyncReport 返回结构化统计(inserted/removed/cleanedOrphans/prunedRefs/total)
  • db:projects:create fuzzy 匹配 + path healing(同 path 不同大小写/斜杠不再重复创建)
  • Ctrl+W 通过 IPC 关闭 tab(main 拦截 + 通知 renderer)

测试

  • 单测 12/12 通过(sync-cleanup + db-projects-dedup)
  • silent install/uninstall 验证:全新安装启动后 projects.db = 0 行 ✅
  • 卸载后 4 个数据目录全清 ✅

文档

  • docs/fix-stale-project-tabs.md — 完整修复经验
  • docs/troubleshooting.md — 用户清理指南
  • docs/tech-debt/nsis-macro-expansion.md — NSIS 宏技术债

Marco Taylor added 3 commits July 7, 2026 10:11
Three syncProject improvements for Copilot-Switch orphan worktree
cleanup:

1. Incomplete worktrees deleted automatically:
   Directories without .git pointer (empty dirs from failed session
   creation) are removed during sync. Previously they accumulated in
   .agentdock/worktrees/ and confused users.

2. git worktree prune cleans dead registry entries:
   syncProject now runs 'git worktree prune --verbose' to remove stale
   refs in .git/worktrees/. After manual cleanup that removed the
   worktree directory but left the registry entry, prune removes it.

3. SyncReport replaces synced count:
   syncProject now returns { inserted, removed, cleanedOrphans, prunedRefs, total }
   instead of a single count. The toast in SessionSidebar uses the new
   structure to show accurate per-operation stats.

- electron/main/ipc/db.ts: added git worktree prune, delete incomplete
  worktrees, SyncReport return type.
- electron/preload.ts: sync.project() return type updated to SyncReport.
- src/components/SessionSidebar.tsx: toast uses new SyncReport fields.
- plugins/__tests__/sync-cleanup.test.ts: 5/5 tests pass.
- docs/tech-debt/nsis-macro-expansion.md: documented NSIS macro issue.

Resolves: orphan .agentdock/worktrees/ directories accumulating in
Copilot-Switch after repeated install/uninstall cycles.
$USERPROFILE is not an NSIS built-in variable and is silently ignored
in the uninstaller context (warning 6000: unknown variable/constant
"USERPROFILE" detected, ignoring). This caused RMDir /r to not delete
~/.agentdock (the legacy global DB path written by v0.1-v0.2), so
stale project tabs survived uninstall.

Fix: derive the user's home directory from $DESKTOP (which IS a valid
NSIS built-in variable) by stripping the trailing 8 characters
("Desktop"). $DESKTOP = C:\Users\<u>\Desktop → stripping gives
C:\Users\<u> → append "\.agentdock" to get the target path.

Also clean both customUnInstall (macro-level) and customUnInstallSection
(Section-level fallback) to handle both cases.
…cy DB

全新安装后顶部残留大量 project tab 的完整修复。

根因 1: 打包后 process.cwd() 是安装目录(不是用户项目),被
main.ts 的 auto-init 逻辑当成 active project,syncProject 再把它
auto-register 进 global DB,产生 'AgentDock' 这一行 tab。
修复: 仅在 dev 模式 auto-init 到 cwd;打包模式不设 active project,
显示'打开项目'欢迎页。

根因 2: legacy $HOME/.agentdock/projects.db (v0.1-v0.2 的 global DB)
积累了 41 行历史残留(e2e temp 目录、worktree 目录、build 产物),
卸载不清、重装照读。
修复: app 启动时在 JS 层清理 legacy projects.db(100% 可靠,
不依赖 NSIS 宏)。

NSIS 踩坑:
- $USERPROFILE 不是 NSIS 内置变量,RMDir 静默失败(warning 6000)。
  改用 $DESKTOP 倒推 home 目录。
- customUnInstall/customUnInstallSection 宏在 NSIS 3.0.4 下不展开,
  不能依赖它做关键清理。userData 清理放 JS 层,NSIS 只兜底。

验证: silent install/uninstall + 启动后断言 projects.db 为 0 行。

改动:
- electron/main.ts: 打包不 auto-init + 启动清 legacy DB
- build/installer/installer.nsh: $DESKTOP 倒推 + 双保险清理
- electron-builder.yml: deleteAppDataOnUninstall true
- docs/fix-stale-project-tabs.md: 完整修复经验
- docs/troubleshooting.md: 用户清理指南
Copilot AI review requested due to automatic review settings July 15, 2026 06:04

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces robust cleanup mechanisms and path normalization to resolve issues with stale project tabs, redundant directories, and improper uninstallation behavior. Key changes include updating the electron main process to avoid auto-registering the installation directory as a project in packaged builds, cleaning up legacy databases on startup, pruning stale git worktree refs, and implementing fuzzy path matching with path healing. Additionally, Ctrl+W/Cmd+W shortcut handling was refactored to use IPC for closing tabs reliably across platforms. Review feedback highlights a critical security concern regarding the validation of worktree paths before deletion to prevent accidental data loss, suggests using the native $PROFILE variable in NSIS instead of fragile string manipulation on $DESKTOP, and points out a duplicate definition of onCloseTab in the preload script.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread electron/main/ipc/db.ts
Comment thread build/installer/installer.nsh Outdated
Comment thread build/installer/installer.nsh Outdated
Comment thread electron/preload.ts Outdated
Marco Taylor added 3 commits July 15, 2026 22:24
1. (security-critical) syncProject 删除不完整 worktree 前校验路径确实
   在 <projectPath>/.agentdock/worktrees/ 内,防止畸形 sessionId
   (如 ../..) 逃逸目录导致 rmSync 误删。

2/3. (high) NSIS installer.nsh 改用 $PROFILE 内置变量替代 $DESKTOP -8
   倒推。$DESKTOP 在 OneDrive 环境下是
   C:\Users\<u>\OneDrive\Desktop,倒推会得到错误的 home 目录。
   $PROFILE 直接是 C:\Users\<u>,可靠。customUnInstall 和
   customUnInstallSection 两处都改。

4. (medium) preload.ts 删除 onCloseTab 的重复定义(windowControls 内
   多余一份),保留顶层 api 对象上的定义(TabBar 用的是这个)。

单测 12/12 通过。
# Conflicts:
#	electron-builder.yml
#	electron/main.ts
installer.nsh 的 preInit/customInstall 宏用了
  !ifdef BUILD_UNINSTALLER
    !macroend
  !endif
试图在 uninstaller build 时提前结束宏,但 NSIS 不允许 !macroend
出现在 !ifdef 条件块内(宏定义结构必须完整),导致
'!include: error in script ... on line 6' 编译失败。

改为整个宏体用 !ifndef UNINSTALLER_OUT_FILE 包裹(合法),
uninstaller build 时宏体为空,不碰 $INSTDIR。

本地 pack 验证通过。
@ACCSCI
ACCSCI merged commit 17ff2b2 into master Jul 15, 2026
1 check passed
@ACCSCI
ACCSCI deleted the fix/sync-cleanup branch July 15, 2026 15:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants