Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>Workspace & Session ManagerNew to Visual Studio Code? Get it now.
Workspace & Session Manager

Workspace & Session Manager

gy903

|
1 install
| (0) | Free
See every VS Code workspace storage and Copilot chat session at a glance: disk usage, session inventory, sessions missing from the panel, and stale index entries — all repairable in place. Deletions always go to the Recycle Bin and need your confirmation; the extension only recommends, it never dele
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Workspace & Session Manager — 工作区与会话管家

English: README.en.md

一览 VS Code 的全部工作区存储与 Copilot 会话:体积占用、会话清单、被隐藏的会话、失效的索引条目,并可就地修复。

只推荐,不自动删。 所有删除都由你右键显式触发 + 二次确认 + 进回收站。

(扩展的界面文案——命令名、设置说明、视图名——跟随 VS Code 的显示语言。)


⚠️ 必读

1. 修复后要重载窗口(扩展会直接给你按钮)

VS Code 把会话索引缓存在内存里。若那个工作区正开着,它下次会话变更(发消息 / 新建 / 改标题)会把内存版本整体写回盘上,覆盖刚做的修复。

不需要关 VS Code,也不需要换窗口 —— 扩展直接写盘,完成后弹一个「立即重载窗口」按钮:

目标工作区 做法
就是当前窗口 点提示里的「立即重载窗口」
开在别的窗口 到那个窗口执行 Developer: Reload Window
没开在任何窗口 什么都不用做

原理:flushIndex() 只在会话变更时触发,重载本身不会回写 —— 所以「写盘 → 立刻重载」这个窗口期是安全的,只要别在这几秒里发消息。 想彻底免掉重载,可以用 scripts\ 里的独立脚本(完全退出 VS Code 后运行)。

2. 「清理空会话」只看内容,不看标题

判据是会话文件里 requests 数组为空 —— 从未发出过任何一条消息。 标题为空、或叫「新建聊天」,只是信号而非判据;有内容的会话永远不会被动到。

3. 当前工作区没有「删除存储」入口

不是点了报错,是菜单里就不出现(它用的是独立的 contextValue,when 子句直接排除)。 因为它正被 VS Code 占用 —— state.vscdb 是活的 SQLite 连接,强删可能留下残缺目录,比全删更难收拾。

4. 误删可以还原,但要先完全退出 VS Code

工作区存储的目录名是由工作区路径算出的稳定 hash(同一个目录永远同一个),把它从回收站还原回原位即可复用,会话与状态都会回来。

⚠️ 但 VS Code 若还在运行,它很可能已经重建了同名空目录 → 还原时撞名失败(变成 xxx (1))。 正确顺序:退出 VS Code → 还原 → 再启动。


名词表(先看这个,后面都靠它)

会话的可见性由两个互相独立的维度决定,混起来就会看不懂。

维度一:索引 / 文件是否对得上

名称 含义 面板里
正常 索引有登记 + 磁盘有文件 显示
孤儿 磁盘有文件、索引没登记 看不见 —— 文件没丢,只是没有入口
幽灵 索引有登记、磁盘没文件 看不见 —— 见下方说明

维度二:有没有内容

名称 含义 面板里
有内容 发过消息 显示
空会话 一条消息都没发过(刚建时文件约 1.5 KB,只含界面状态) 看不见;新建后可能闪现一下再消失——那是刷新节流,不是被删

面板实际显示 = 索引有 ∩ isExternal:false ∩ initialLocation:"chat" ∩ isEmpty:false —— 这是 ChatService.getHistorySessionItems() 的原始过滤条件。它不检查文件是否存在。

幽灵和空会话为什么都不显示

两者在面板里都不会出现,原因不同、结论一致:

  • 空会话:索引条目里 isEmpty: true → 被上面那条过滤条件直接刷掉。条目仍在索引里占位(只有 clearSession 才会真删)。
  • 幽灵:文件不存在这件事本身就必然意味着它没发过消息 —— VS Code 写 JSONL 与写索引走的是同一条路径(storeSessions),发过消息就一定有文件。所以幽灵的 isEmpty 也是 true → 同样被刷掉。
  • 例外(要清的就是这种):文件被外部工具删掉或搬走、而索引没跟着改 —— 索引里存的是陈旧的 isEmpty: false。这种幽灵会进列表,点开才加载失败,看起来就是个「空白项」。

所以判定空会话不能依赖索引里的 isEmpty(它可能陈旧或标错),必须去读文件内容 —— 这正是本扩展的做法。

外部会话:Copilot CLI / Claude 等以 agent-host- 为前缀的会话,实体存放在 %APPDATA%\Code\agentSessionData\。 它们的 id 含 : 和 /,不可能在 chatSessions\ 里对上文件 —— 所以永远不要把它们当作幽灵清理。


用法

资源管理器侧边栏 → 工作区管家。在工作区节点上右键:

命令 作用
一键修复 清掉空会话与失效条目、把被隐藏的会话召回面板(怎么做的不重要,详情见文末原理)
还原索引备份 把索引回退到上一次修改之前。交换式:再点一次就换回来
清理可重建的缓存 清掉各扩展的工作区缓存与本扩展旧格式的索引备份(走回收站)。不碰会话数据与索引本体
打开此工作区 / 在资源管理器中打开目录 / 复制路径 —
删除此工作区存储 仅非当前工作区可见,进回收站

每次改动索引前,都会把 state.vscdb 备份成同目录下的 state.vscdb.wsmgr-bak —— 只保留这一份,每次覆盖,不会越攒越多。

标题栏另有 刷新、生成总览报告 与 查找重复会话。悬停工作区节点可看到完整信息:目标路径、是否存在、体积构成、最后使用时间。

查找重复会话:跨所有工作区比对指纹(文件大小 + 前 64 KB 的 SHA-1,实测 105 个文件耗时 ~46 ms)。 同工作区内不会重复(文件名就是 sessionId);重复几乎都来自会话同步/搬运工具把同一份 JSONL 复制到多个工作区。 它只生成报告,不删任何东西。

展开某个工作区,存储明细里每一项都带了类别标记——省得你对着 redhat.java 这种东西猜能不能删:

图标 类别 含义
🔒 数据 chatSessions / chatEditingSessions / state.vscdb / workspace.json —— 不要动
📦 可清理 扩展的工作区缓存(删后自动重建,可能慢一次)、旧格式的索引备份
❓ 未识别 用途不明 —— 不建议清理

分类原则是宁少勿多:白名单只标数据,扩展目录按缓存处理,认不出的一律不给清理建议。 state.vscdb.backup(VS Code 自己的)与当前那份额外的索引备份也不在可清范围 —— 它们是回退用的保底。

命令面板里另有细粒度的 修复会话索引 与 清理空会话,用于单独执行其中一步。

会话节点右键(支持 Ctrl / Shift 多选):

命令 作用
复制会话到… 复制到另一个工作区,源会话不受影响
移动会话到… 复制到目标 + 源文件移入回收站 + 源索引注销
删除会话 进回收站,支持多选

⚠️ 搬运后若涉及当前工作区,同样需要按提示重载窗口。

推荐用法

右键工作区 → 一键修复 → 按提示点「立即重载窗口」。

就这一步。(想分步来,也可以用命令面板里的「修复会话索引」/「清理空会话」。)

避免超大会话

会话文件是只增不减的:工具输出、附件都会被原样写进去(附件还会 base64 内联,体积 ×1.33), 而且同一份数据会同时存进 result 和 response 两个字段。在几十万文件的仓库里裸跑一次 git ls-files, 就可能造出几百 MB 的会话。

做法 说明
给命令加限制 git ls-files \| Select-Object -First 200;列文件用 Everything CLI(es.exe)而不是 Get-ChildItem -Recurse
别把大文件 / 图片丢进聊天框 附件会被 base64 内联 —— 一张 5 MB 的图 ≈ 6.7 MB 文本。改成"我把路径给你,按需读"
一个任务一个会话 会话越长、快照越大;顺带也避免老的被 trimEntries 挤成孤儿
盯住体积列 「会话」列表里每项都有体积;超过 wsManager.bigSessionMB(默认 50 MB)会带 ⚠️ 标记
发现巨物后别在里面继续聊 只会更大。记下要点 → 用「删除会话(回收站)」清掉

⚠️ 这类会话是单个巨型 kind0 快照(整个文件一行),走的是 VS Code 的 "flat" 写入路径。 用 readline 之类逐行读取会卡死(单行可达数百 MB)。

独立脚本(脱离 VS Code 运行)

想彻底免掉「重载」这一步时用 —— 完全退出 VS Code 后执行。

node scripts\repair-index.js --list                     # 列出所有工作区
node scripts\repair-index.js --hash <hash>              # 体检,不写任何东西
node scripts\repair-index.js --hash <hash> --apply      # 写入(请先完全退出 VS Code)
node scripts\repair-index.js --path "d:\your-project" --apply

检测到 Code.exe 正在运行时会拒绝写入(--force 可跳过,后果自负)。


原理

存储位置

%APPDATA%\Code\User\workspaceStorage\{hash}\
  ├── workspace.json            {"folder":"file:///…"} —— 该存储对应哪个工作区
  ├── chatSessions\{id}.jsonl   会话数据(kind0 全量快照 + kind1 增量 delta)
  ├── chatEditingSessions\
  ├── GitHub.copilot-chat\      debug-logs / transcripts / 会话资源
  └── state.vscdb               内含 chat.ChatSessionStore.index(会话索引)

面板显示只看 {hash}\state.vscdb 里的索引 —— chatSessions\ 里有文件但索引里没登记,就等于没有入口:

{ version: 1, entries: { "<sessionId>": { sessionId, title, lastMessageDate, timing,
    initialLocation: "panel", isEmpty, isExternal, lastResponseState, … } } }

⚠️ initialLocation 必须正好是 "panel"(ChatAgentLocation.Chat 的值)—— 写成别的值,条目会被面板过滤掉。 重建索引条目时这一点极易弄错。

孤儿和幽灵是怎么产生的

  • ChatSessionStore.trimEntries() 的裁剪上限是 400 条,而且它只删索引条目、从不删文件 → 超上限的旧会话就变成孤儿(文件还在,没有入口)
  • 跨工作区搬运会话文件时若没同步索引,整批都会变孤儿
  • 会话是空着创建的:创建即写索引,但 JSONL 只在发出第一条消息后才落盘 → 中途放弃就留下幽灵
  • 因此判定空会话不能只看 kind0 快照(那里永远是 "requests":[]),必须同时寻找 "k":["requests",…] 形式的 delta;文件很大时用流式扫描,找到证据就返回,扫不到则保守判为有内容

写入为什么会被覆盖,以及重载为什么能解决

ChatSessionStore.internalGetIndex() 是同步方法,直接返回内存里的 indexCache;flushIndex() 再把它整体写回盘上。 所以对「正开在窗口里」的工作区写盘,等于和内存里那份旧索引赛跑 —— 输的总是盘上那份。

但 flushIndex() 只在会话变更时触发(storeSessions()),而重载窗口不会触发它(onWillShutdown 只 join 已存在的写任务)。 所以「写盘 → 立刻重载」是安全的:重载会重建 ChatSessionStore,内存缓存作废并重新从盘上读取。


开发

# F5 → 启动扩展开发主机
node test\smoke.js      # 冒烟测试(不需要 VS Code)
.\build.ps1             # 打包 vsix

test\ 里的探查脚本需要知道「当前窗口对应哪个存储目录」,用环境变量给它:

$env:WSM_HASH = '<某项工作区的 hash>'   # 用 node scripts\repair-index.js --list 查看

界面文案的本地化在 package.nls.json(英,默认)与 package.nls.zh-cn.json(中)里; _tmp\l10n.js 能把 package.json 的新文案批量换成 %key% 占位符并校验两个文件覆盖完整。

路线图

  • 空间拆解与清理建议
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft