Releases: deep-copilot/DeepCopilot
Deep Copilot v0.43.1
Deep Copilot v0.43.1
中文版在下方 / English notes below.
🇨🇳 中文
主题:工具调用前穿插逐步文字解说 + 后台唤醒调度 + DeepSeek 前缀缓存调优
本版本主要打包 PR #180(v0.43.0)的全部能力,并以 0.43.1 重新构建 VSIX。
✨ 新特性 1:每个工具调用前都有「人话解说」
此前多步工具回合常常表现为「一堆工具先跑,最后才蹦出文字」。日志里每个 ITER_END 的 assistant_chars:0 说明模型把「我现在要做 X」的解说全塞进了 DeepSeek 的隐藏 reasoning_content 通道,可见正文 content 全程为空。
修复(src/prompts/system.js):
- Tone 段:把原来禁止前导解说的
No preamble, no "I'll now…"改成「禁空话(Great question/Sure),但要求动作解说」——每次工具调用前用一句可见正文说明「要做什么 + 为什么」。 - System 段:新增强约束,要求把面向用户的解说写进
content而非 reasoning/thinking 通道;多步工具回合里每个工具调用前先写一句,而不是沉默到最后。 - 流式管道(
src/api/openai-client.js)本身已支持content先于tool_calls穿插渲染,无需改动。
体验上更接近 GitHub Copilot「先说一句话 → 再调工具」的节奏,用户能跟着模型一步一步看。
✨ 新特性 2:watch + yield_turn 后台唤醒调度
长跑任务(模型训练、大型构建、长下载、dev server)的痛点是:要么阻塞 turn 等到超时,要么手动轮询。
新增工具:
watch({ condition, description? }):注册一个声明式触发器,支持time_elapsed/job_end/output_match/output_silent/progress_at,可用first_of组合(成功 OR 失败 OR 卡死 OR 兜底超时)。yield_turn({ reason? }):干净地结束当前 turn,会话进入挂起状态。- 任一 watcher 触发 → 由
wake-scheduler构建结构化 digest(异常 / 进度 / 输出尾巴)→ 通过Provider.autoResume自动恢复对话。
安全约束:
watch的条件必须包含time_elapsed兜底(直接或在first_of中),否则被工具拒绝——避免会话永久挂起。yield_turn必须在watch之后调用;空 watcher 列表会被拒绝。- 每会话最多 8 个 active watcher,每小时最多 12 次 auto-resume(可通过
deepseekAgent.autoResumeMaxPerHour配置)。 - 挂起前必须有一句用户可见的总结(「我做了 X / 现在在等 Y」),否则系统会主动 nudge 一次。
新增模块:
src/chat/wake-scheduler.js(407 行):watcher 生命周期、轮询、限流、路由src/chat/digest.js(144 行):本地、确定性、无网络的输出 digest 构造器,自动抽取 anomaly / progresssrc/tools/sleep.js(139 行):watch/yield_turn的模型侧入口
⚡ 优化:DeepSeek 前缀缓存命中率
DeepSeek 服务端 KV 前缀缓存按字节比对。任何在历史中段重写消息的操作都会让从该字节起的整条 prefix cache miss,明显推高 token 成本。本版本系统性地审计并修复了若干「无意中破坏前缀」的代码路径:
- 系统提示重排(
src/prompts/system.js):按 stability 由低到高排序(env → paradigm → skills → memory → workspace),让最长可能的前缀在跨 turn 时保持字节一致;移除原本的__DYNAMIC_BOUNDARY__噪音 marker。 - 持久化时不再 eager 压缩(
src/chat/session-store.js):之前每次 turn save 都强制压缩到 40% context window,反复改写历史头部 → 每次「重开同一会话」都吃满 prefix cache miss。改为完全 lazy,只在 agent loop 里真正撑爆时压缩。 - 去掉定期重压缩(
src/chat/agent-loop.js):原本每 12 iter 把 budget 收紧到 80% 触发预防性压缩——节奏性地清空 prefix cache。改为只在真正超出(更宽松的 70%)才触发。 - dedup 阈值提到 95%(
src/chat/compact.js):重复文件读取去重会改写中段消息,cost cache。改成「快要溢出才做」。 - 附件排序稳定化(
src/chat/agent-loop.js):同一组文件按不同顺序点选 → byte-identical 的 user content,命中前缀缓存。 - 截断结果冻结(
src/chat/compact.js):已被截断的工具结果加_cacheFrozen标记,避免反复重算导致对象身份变化。 - 可观测性:每轮 USAGE 事件新增
cache_hit_rate字段;日志同步打出CACHE_HIT_RATE行。
🐞 修复 1:空响应自愈
模型偶发输出 0 token + 0 工具调用(mimic reasoning placeholder 后停止),旧代码当作「正常结束」直接退出 turn,表现为「鬼魂中断」。新增最多 2 次的 EMPTY_REPLY_RETRY:注入 forward nudge 让模型继续,超过上限才放弃,避免无限循环。
🐞 修复 2:reasoning_content 占位符不再诱导模型「跟着说停」
DeepSeek thinking 模式要求一旦出现过 reasoning_content,后续每条 assistant 消息都必须带非空 reasoning,否则 HTTP 400。我们之前用的占位符 "(no thoughts surfaced for this step)" 重复出现后变成强 in-context 模板,模型开始照着发然后停下——又一种「鬼魂中断」。
通过 scripts/probe-reasoning-placeholder.js 实测验证:thinking 模式只要求非空字符串。改成 forward-nudging 的 "Continue with the next concrete step."——即便被模型 mimic,也是「继续干活」而不是「停下来」。
🐞 修复 3:Windows cmd.exe 多行 inline 脚本陷阱提示
python -c "..." / node -e "..." 这类多行内联脚本在 Windows 上会被 cmd.exe 按换行切碎,常表现为「exit 0 + 无输出」。src/tools/shell.js 现在会检测这种 pattern,在结果里追加 actionable hint:建议写到临时文件再执行,或改用单行命令。
🐞 修复 4:Provider sanitize 防止 _ 前缀字段泄露到 HTTP
_cacheFrozen 这类 compactor / agent-loop 用的内部标志一旦混进 OpenAI 兼容 API 的 payload,会被 HTTP 400 拒绝。src/providers/index.js 的 sanitizeMessages 现在统一剥离所有 _ 前缀字段,并用 spread(非 Object.assign)规避 __proto__ 原型污染风险。
🐞 修复 5:terminal capture 饱和不再被误判为「沉默」
run_shell_bg 的输出捕获有 64KB×20 上限。原来当 capture 触顶停止增长时,output_silent watcher 会误以为任务沉默而提前触发。现在 terminal-monitor.js 在 record 上设置 truncated 标记,watcher 看到饱和后保持「仍活跃」语义。
🐞 修复 6:rate limit 不再永久销毁 watcher
_fire 命中限流时旧代码会先 _cleanupWatcher 再检查 rate——直接把 watcher 拆了,挂起的会话再也唤不醒。改为先检查、限流命中时保留 watcher 并 arm 单个 retry timer 到限流窗口释放为止。
🧹 其他
- 侧边栏抽屉打开时主区域 push(不再 cover),右侧空出 280px,体验更接近原生侧栏(
media/chat.css+media/chat.js)。 - 新增配置项
deepseekAgent.autoResumeMaxPerHour(默认 12,范围 1–120)。 - 默认
compactBudgetTokens从 50% context window 提到 70%,配合前缀缓存调优。
🔒 安全 / 兼容性
- Webview CSP 不变。
- 不引入新运行时依赖。
- 旧会话兼容,无需迁移。
- 新工具
watch/yield_turn不暴露 destructive 能力,被 schema 验证 + 安全兜底约束。
关联
- PR #180(本版本合并 PR)
🇺🇸 English
Theme: Per-step narration before each tool call · auto-resume scheduler · DeepSeek prefix-cache tuning
This release packages everything from PR #180 (v0.43.0) and rebuilds the VSIX as 0.43.1.
✨ Feature 1 — Plain-text narration before every tool call
Previously, multi-step tool turns showed up as "a bunch of tools fire silently, then text appears at the very end". Logs consistently reported ITER_END with assistant_chars:0 — the model was stuffing its "I'm about to do X because Y" narration into DeepSeek's hidden reasoning_content channel, leaving the visible content channel empty.
Fix (src/prompts/system.js):
- Tone section: replaced the old anti-preamble line (
No preamble, no "I'll now…") with "no empty filler (Great question/Sure), but DO narrate actions" — one short visible sentence before each tool call saying what and why. - System section: hard rule that user-facing narration must land in
content, not inreasoning_content/thinking; in multi-step turns, narrate before every tool call rather than at the end. - The streaming pipeline (
src/api/openai-client.js) already supports interleavingcontentbeforetool_calls, so no plumbing change was needed.
The result reads like GitHub Copilot's "say one sentence → call tool" cadence; users can follow the agent step by step.
✨ Feature 2 — watch + yield_turn auto-resume scheduler
Long-running shell work (training, large builds, downloads, dev servers) used to either block the turn until timeout or require manual polling. This release introduces declarative auto-resume:
New tools:
watch({ condition, description? })— register a declarative trigger. Supported kinds:time_elapsed/job_end/output_match/output_silent/progress_at. Compose withfirst_of(success OR failure OR hang OR fallback timeout).yield_turn({ reason? })— cleanly end the current turn; the session enters a suspended state.- When any watcher fires,
wake-schedulerbuilds a structured digest (anomalies / progress snapshot / output tail) andProvider.autoResumere-enters the agent loop with it injected as a<system-reminder channel="auto-wake">.
Safety constraints:
watchconditions must include atime_elapsedsafety bound (directly or insidefirst_of) — otherwise the tool rejects the call. A session can never be suspended forever.yield_turnrequires at least one armed watcher, otherwise it is rejected.- Per-session caps: 8 active watchers; 12 auto-resumes per hour (configurable via
deepseekAgent.autoResumeMaxPerHour). - The model is required to write a brief user-facing summary ("did X / now waiting for Y") before suspending — a nudge is injected once if it tries to suspend silently.
New modules:
src/chat/wake-scheduler.js(407 lines) — watcher lifecycle, polling, rate-limiting, routing.src/chat/digest.js(144 lines) — local, deterministic, network-free digest builder; extracts anomaly lines and progress snapshots.src/tools/sleep.js(139 lines) —watch/yield_turnentry points exposed to the model.
⚡ Optimisation — DeepSeek prefix-cache hit-rate
DeepSeek's server-side KV prefix cache hashes the request byte-by-byte. Any rewrite of mid-history bytes invalidates the cache from that point onward — silently driving up token cost. This release systematically audits and fixes paths that were unintentionally breaking the prefix:
- System prompt re-ordering (
src/prompts/system.js): sections re-ordered most-stable-first (env → paradigm → skills → memory → workspace). The literal__DYNAMIC_BOUNDARY__marker is removed (cache-irrelevant noise). - No more eager compaction on persist (
src/chat/session-store.js): the old "compact to 40% of context window on every save" pass rewrote the head of history on every turn-save and every reload, so "reopen the same session" always paid a full prefix-cache miss. Compaction is now fully lazy. - No more periodic re-compaction (
src/chat/agent-loop.js): the old "every 12 iterations, tighten budget to 80%" trigger was a periodic cache-buster. Compaction now fires only when the real token estimate actually exceeds the (already-generous) 70% budget. - Dedup raised to 95% (
src/chat/compact.js): deduplicating repeated file reads rewrites mid-history messages and costs the cache. Defer to a near-overflow trigger. - Stable attachment ordering (
src/chat/agent-loop.js): sorting text attachments by (path, line-range) means the same files added in different click orders yield byte-identical user content — and therefore the same prefix-cache hit. - Frozen truncated tool results (
src/chat/compact.js): once a tool result has been truncated, it's marked_cacheFrozenso the truncator never runs over it again (guaranteed object identity → byte identity). - Observability: every USAGE event now carries a
cache_hit_ratefield;CACHE_HIT_RATElog lines surface the hit/miss split per turn.
🐞 Fix 1 — Empty-response self-heal
The model occasionally emits a degenerate turn: no text AND no tool call (it just mimics the reasoning placeholder and stops). The old code treated that as a normal end-of-turn and silently broke out — a "ghost interruption". A capped EMPTY_REPLY_RETRY (max 2) now injects a forward-nudge and continues; only after that gives up.
🐞 Fix 2 — reasoning_content placeholder no longer trains the model to stop
DeepSeek thinking-mode enforces that once any assistant message carries a non-empty reasoning_content,...
v0.41.6 — Archive pure-export + watchdog stays on duty
Deep Copilot v0.41.6
中文版在下方 / English notes below.
🇨🇳 中文
主题:Archive 改为纯导出 · 值守任务不再提前结束会话 · 打包卫生
🐞 修复 1:Archive 语义改为「纯导出」(Issue #169)
旧版「存档」实际上是「软隐藏 + 导出」——点一下生成 Markdown,同时把会话从侧边栏抽走,连点两次第二次还会把它「unarchive」回来,体验和菜单文案完全不符。
新行为(PR #170):
archive(id)只做一件事:调用exportSessionToMarkdown把整个会话渲染为 Markdown,写到.deep-copilot/archives/yyyyMMdd-HHmmss-<title>.md。- 不再 把
archived置为true,不再 把当前激活的 session 切走,不再 广播sessionLoaded空消息。 - 出错或用户在保存对话框里取消,session 状态都保持原样——只 toast 一下。
- 同一会话连点两次「存档」 → 生成两个 md 文件,会话本体不动。
一次性迁移 _migrateArchivedFlagIfNeeded:
- 由
globalState['deepseekAgent.archiveSemanticsV2Migrated']守护,幂等; - 升级到本版本后首次启动会把所有旧
archived: true的会话翻回false,让侧边栏重新看到它们; - 失败走
Logger.info('ARCHIVE_V2_MIGRATION_FAILED', { message, stack }),下次启动自动重试,不阻塞激活; - 仅当真有 session 被翻转时才调
postList(),避免无谓刷新。
⚠️ 兼容性:升级后曾经被「藏起来」的所有会话会一次性回到侧边栏。.filter(s => !s.archived)/find(s => !s.archived)这两处过滤器保留,作为 schema 向后兼容;后续 minor 版本会移除archived字段。
🐞 修复 2:值守任务不再被提前掐断
模型执行「值守」类任务(盯训练、盯长跑构建、盯日志)时,如果那个 bg job 是在上一个 turn 启动的,当前 turn 的 run._sessionStartedBgJobs 是空集,BG_WAIT_SKIPPED_MODEL_DONE 守卫就会在模型说完「我会持续监控」之后立刻结束 turn,把值守静默掐断——用户看着模型像断片一样不再有任何后续。
修复:
src/chat/tool-executor.js新增对read_terminal(terminal: "deepseek-job-*")的拦截:当模型读取某个后台任务的终端输出时,把该 jobId 记入run._monitoredBgJobs,作为「当前 run 正在主动监控该任务」的信号。src/chat/agent-loop.js:- 初始化
run._monitoredBgJobs = new Set(); - bg job 结束事件同步清理该集合;
BG_WAIT_SKIPPED_MODEL_DONE守卫新增_hasMonitoredRunningJob条件——任何被监控且仍活着的 bg job 都会阻止 turn 提前退出,循环继续走 4 分钟快照 / 等结束事件,直到任务完成或命中 4h 本轮预算。
- 初始化
🛠 修复 3:迁移失败走 Logger(替换 console.warn)
_migrateArchivedFlagIfNeeded 的失败分支改用 Logger.info('ARCHIVE_V2_MIGRATION_FAILED', { message, stack }),统一走 Deep Copilot Debug 输出面板,符合仓库已有的 src/logger.js 路径。
🧹 打包卫生
.vscodeignore 增加 .tmp-*.json / .tmp-*.txt / .tmp-*.md 过滤规则,防止本地拉取 PR 评论 / Review API 时产生的临时缓存文件被打进 VSIX。
🔒 安全 / 兼容性
- Webview CSP 不变。
- 不引入新运行时依赖。
- Archive 旧 md 文件(
.deep-copilot/archives/*.md)原封不动。 - Watchdog 改动只放宽提前退出条件,不改变正常 turn 结束语义;模型从未
read_terminal过的 bg job(例如旁路 dev server)依然走老的 short-circuit。
关联
🇺🇸 English
Theme: Archive becomes a pure export · watchdog turns stay on duty · packaging hygiene
🐞 Fix 1 — Archive semantics: pure export (Issue #169)
Pre-#169 the "Archive" action was actually "soft-hide + export": it produced a Markdown snapshot but also swept the session out of the sidebar; clicking the same row a second time silently un-hid it. The menu label promised one thing, the behaviour did another.
New behaviour (PR #170):
archive(id)does exactly one thing: callexportSessionToMarkdownto render the whole session to.deep-copilot/archives/yyyyMMdd-HHmmss-<title>.md.- It no longer sets
archived = true, no longer swapssessionIdto null, no longer broadcasts asessionLoadedempty message. - On error or user-cancelled save dialog, session state is untouched — only a toast.
- Clicking "Archive" twice on the same session produces two snapshots; the session itself stays put.
One-shot migration _migrateArchivedFlagIfNeeded:
- Idempotent, guarded by
globalState['deepseekAgent.archiveSemanticsV2Migrated']. - On first launch after upgrade, flips every legacy
archived: trueback tofalseso old hidden sessions reappear in the sidebar. - Failure routes through
Logger.info('ARCHIVE_V2_MIGRATION_FAILED', { message, stack }); the next launch retries because the flag was never written. Activation is never blocked. postList()only fires when something actually changed.
⚠️ Compatibility: every session that used to be hidden by the old archive flow will reappear in the sidebar exactly once after this upgrade. The.filter(s => !s.archived)andfind(s => !s.archived)call-sites are kept as a no-op safety net so the data schema stays backward-compatible; a future minor release will drop the field.
🐞 Fix 2 — Watchdog turns no longer cut themselves off
When the model is asked to watch a long-running background job (training, build, dev server), and that job was spawned in an earlier turn, the current turn's run._sessionStartedBgJobs is empty. The BG_WAIT_SKIPPED_MODEL_DONE guard would then end the turn the instant the model said "I'll keep monitoring", silently dropping the watchdog. Users would see the model go quiet right after promising to stay on duty.
Fix:
src/chat/tool-executor.jsnow hooksread_terminal(terminal: "deepseek-job-*"): inspecting adeepseek-job-*terminal in this run adds that jobId torun._monitoredBgJobs— a signal that the model is actively watching the job.src/chat/agent-loop.js:- Initialises
run._monitoredBgJobs = new Set(). - Clears entries when the corresponding bg-job-end event fires.
- Adds
_hasMonitoredRunningJobto the early-exit guard; as long as any monitored job is still alive, the turn refuses to end and keeps polling / emitting 4-minute snapshots until the job finishes or the 4-hour per-turn budget elapses.
- Initialises
🛠 Fix 3 — Migration failures use Logger (not console.warn)
_migrateArchivedFlagIfNeeded now routes its failure path through Logger.info('ARCHIVE_V2_MIGRATION_FAILED', { message, stack }), matching the repo's existing src/logger.js pipeline so diagnostics respect deepseekAgent.enableDebugLog and land in the "Deep Copilot Debug" output channel.
🧹 Packaging hygiene
.vscodeignore now filters .tmp-*.json / .tmp-*.txt / .tmp-*.md, so scratch files created locally while pulling PR comments or review payloads via the GitHub API never end up shipped inside the VSIX.
🔒 Security / compatibility
- Webview CSP unchanged.
- No new runtime dependencies.
- Existing archive Markdown files (
.deep-copilot/archives/*.md) are untouched. - The watchdog change only loosens the early-exit guard; it does not change normal turn-end semantics. Bg jobs the model never inspected via
read_terminal(e.g. a side-channel dev server) still go through the original short-circuit.
Related
v0.41.0 - Context Window Overhaul
Deep Copilot v0.41.0
中文版在下方 / English notes below.
🇨🇳 中文
主题:Context Window 优化套件 · 三个新斜杠命令 · 底部 Context Ring · 会话切换闪屏修复
✨ 新功能 1:上下文窗口管理重构(Issue #142)
长对话越来越容易吃满 token 窗口,0.41.0 把"上下文管理"做成了一套完整的机制:
- 结构感知截断(structure-aware truncation)
- 保留最新工具调用的完整内容
- 较旧的轮次自动折叠为"摘要骨架"(保留语义,丢弃大段冗余)
- 同文件读取去重
- 多次读取同一路径时,只保留最后一次完整内容
- 较早的读取被折叠为占位符:
<file path=... read-collapsed='true'/>
- 滚动摘要(rolling summary)
- 超阈值时按需调用模型,把更早的对话压缩为结构化摘要节点
- 会话历史持久化层(
session-store.js)已适配,重新加载会话能正确回放摘要节点
- MCP per-server opt-out:可以为某个 MCP server 显式关闭上下文压缩参与
- 大文件读取提示:
file-read.js在读取大文件时附带read-large-filehint,引导模型先用 grep 而非整文件读入
✨ 新功能 2:三个新斜杠命令
| 命令 | 说明 |
|---|---|
/compact [focus] |
立即压缩当前会话历史;[focus] 可选,作为摘要方向偏置;会自动合并工作区根目录下的 .deepcopilot/compact.md 或 CLAUDE.md 中的项目级 compact 指令 |
/context |
弹出当前会话的 token 占用细分(system / messages / tools / files / hints) |
/fork [name] |
把当前会话从某一条消息派生为一个新会话,保留该消息之前的全部上下文作为起点 |
✨ 新功能 3:底部 Context Ring 指示器
- 替换原本底栏右下角的状态点(
#foot .dot) - 新的环形进度(
#ft-ctx)实时显示上下文窗口占用百分比 - 颜色按阈值渐变:
<60%绿 →<85%黄 →<100%橙 → 满 红 - 点击环形展开 popover,显示与
/context一致的占用细分 - 数据源:agent-loop 每轮回写的
ctxUsage事件
🐞 修复:会话切换闪屏 / 滚动条抖动(Issue #143)
切走再切回正在运行的会话时,缓冲事件被同步全部重放,每个事件触发一次 requestAnimationFrame 滚动,导致:
- 聊天面板明显闪烁
- 滚动条来回抖动
- 重放期间用户无法稳定阅读
修复手法:
_loadSession用setTimeout(..., 0)把事件重放推到下一个宏任务- 重放序列由
replayStart/replayEnd信封包裹 - Webview 端新增
_replaying标志,在重放期间ascroll()静默 - 重放结束时一次性滚到底部,体验与单条事件流入一致
🛠 内部改动
src/chat/agent-loop.js/src/chat/provider.js:上下文窗口管理主逻辑、ctxUsage事件源src/chat/compact.js:滚动摘要 +/compact实现src/chat/context-refs.js:/contexttoken 细分src/chat/session-store.js:摘要节点的持久化与回放src/tools/file-read.js:大文件 hint 输出src/api/anthropic-client.js/src/api/openai-client.js:客户端小幅清理src/errors.js:错误文案微调media/chat.{css,js}/src/webview/html.js:#ft-ctx环形指示器 + popover;_replaying抑制src/utils/i18n.js:新增上下文管理相关中英双语文案
🔒 安全 / 兼容性
- 不放宽 Webview CSP
- 不引入新运行时依赖(运行时仍仅
@anthropic-ai/sdk/openai/js-tiktoken) - 滚动摘要使用既有 API 通道,无新网络入口
- 所有 token 统计在本地完成,不上送任何额外信息
🇺🇸 English
Theme: Context-window overhaul · three new slash commands · footer context ring · session-switch flash fix
✨ Feature 1 — Context-window overhaul (Issue #142)
Long conversations chew through the token window quickly. 0.41.0 turns "context management" into a real mechanism:
- Structure-aware truncation
- Latest tool results kept verbatim
- Older turns collapse to summary skeletons (semantics preserved, bulk dropped)
- Per-file read dedup
- Multiple reads of the same path keep only the latest payload
- Earlier reads become placeholders:
<file path=... read-collapsed='true'/>
- Rolling summary fallback
- When thresholds are crossed, the model is invoked on-demand to compress older history into structured summary nodes
session-store.jspersists & replays these nodes correctly when sessions are reloaded
- MCP per-server opt-out: any MCP server can explicitly opt out of compaction
- Large-file read hint:
file-read.jsnow ships aread-large-filehint nudging the model to grep first instead of slurping the whole file
✨ Feature 2 — Three new slash commands
| Command | Behaviour |
|---|---|
/compact [focus] |
Force-compacts the active session; optional focus biases the summarisation; merges project-level instructions from .deepcopilot/compact.md or CLAUDE.md in the workspace root |
/context |
Opens a breakdown popover (system / messages / tools / files / hints) of the current token spend |
/fork [name] |
Forks the current session from a chosen message into a brand-new session, with that message as the new origin |
✨ Feature 3 — Footer context ring
- Replaces the legacy footer status dot (
#foot .dot) - The new ring indicator (
#ft-ctx) shows live context-window usage - Colour ramps green → yellow → orange → red across the 60% / 85% / 100% thresholds
- Click to open the same breakdown popover used by
/context - Data source: the
ctxUsageevent written by the agent loop after every round
🐞 Fix — Session-switch flash / scrollbar jitter (Issue #143)
Switching away from and back to a running session previously replayed every buffered event in a tight loop, each one scheduling its own RAF scroll-to-bottom. Symptoms:
- Visible flash in the chat panel
- Scrollbar oscillating up/down
- Unreadable during the replay burst
Fix:
_loadSessiondefers the replay viasetTimeout(..., 0)into the next macrotask- The replay burst is wrapped with
replayStart/replayEndenvelopes - The webview adds a
_replayingflag that silencesascroll()for the duration - A single final scroll-to-bottom is performed on
replayEnd
🛠 Internals
src/chat/agent-loop.js/src/chat/provider.js— context-window management core +ctxUsageevent sourcesrc/chat/compact.js— rolling summary +/compactimplementationsrc/chat/context-refs.js—/contexttoken breakdownsrc/chat/session-store.js— persist & replay summary nodessrc/tools/file-read.js— large-file hint outputsrc/api/anthropic-client.js/src/api/openai-client.js— minor cleanupssrc/errors.js— copy tweaksmedia/chat.{css,js}/src/webview/html.js—#ft-ctxring + popover;_replayingsuppressionsrc/utils/i18n.js— new bilingual strings for context management
🔒 Security / compatibility
- Webview CSP unchanged
- No new runtime dependencies (still just
@anthropic-ai/sdk/openai/js-tiktoken) - Rolling summary uses the existing API channel — no new network entrypoints
- All token accounting happens locally; nothing extra is transmitted
Deep Copilot v0.40.4
Deep Copilot v0.40.4
中文版在下方 / English notes below.
🇨🇳 中文
✨ 新功能:待审编辑面板(Pending Edits Panel)
参考 GitHub Copilot 在 VS Code 中的体验,新增「待审编辑」弹窗,让你在 Agent 改动文件后,
能在合并到工作树之前先看到全部变更并决定保留或丢弃。
- 输入框正上方新增一个浮窗,列出本会话中 Agent 写入 / 修补 / 替换的所有文件
- 文件名 +
+xxx -xxx行级统计 - 新建文件标
new,删除标deleted,二进制文件标binary
- 文件名 +
- 行内操作:鼠标悬停时显示 ✓(保留)和 ✕(丢弃)按钮
- 批量操作:右上角「全部保留」/「全部丢弃」
- 点击文件名 → 原生 Diff 编辑器
- 左侧:Agent 写入前的快照(由新的
deepcopilot-before:TextDocumentContentProvider提供) - 右侧:当前磁盘内容
- URI 带时间戳防缓存,并通过
onDidChange主动刷新,保证可以反复点击
- 左侧:Agent 写入前的快照(由新的
- 跨轮次持久:
pendingEdits以 session 为维度维护,即使本轮对话结束、run实例被回收,
面板项仍可继续点击查看 / 保留 / 丢弃,与 GH Copilot 行为一致 - 「丢弃」会用原始快照恢复磁盘内容;「保留」仅清除面板项
- 与现有「回滚本轮」状态栏按钮 /
revert_last_turn工具完全联动,回滚后面板会自动清空
🔧 模型参数刷新(同版本携带)
- DeepSeek
v4-pro/v4-flash:最大输出提升至 384 000 tokens - OpenAI
gpt-5.5/gpt-5.4:上下文提升至 1 050 000 tokens - Anthropic Opus 4-7 / 4-6:上下文提升至 1 000 000 tokens、最大输出提升至 128 000 tokens
- Anthropic Sonnet 4-6:上下文提升至 1 000 000 tokens
- 按官方公告将 DeepSeek v4-pro 2.5 折折扣有效期延长至 2099 年(实质永久 2.5 折)
🛠 内部改动
- 新增
src/chat/diff-utils.js:基于 LCS 的轻量行级 diff,大文件(>10k 行 / >100k 字符)自动降级,二进制文件安全检测 src/chat/tool-executor.js:snapshotForEdit同步填充 session 级pendingEdits,
写工具成功后调用recordEditResult+ 推送pendingEdits事件src/chat/provider.js:pendingEdits改为_pendingEditsBySession维护,新增
keepEdit / keepAllEdits / discardEdit / discardAllEdits / openEditDiff五个消息处理src/extension.js:注册deepcopilot-before:TextDocumentContentProvider与onDidChange事件源media/chat.{css,js}/src/webview/html.js/src/utils/i18n.js:新增#pending-edits-panelUI + 中英双语文案- 把
toolMap/_readTermCardMap从普通对象改为原生Map,彻底消除 CodeQL 标记的
remote-property-injection / prototype-pollution sink
🔒 安全 / 兼容性
- 不改变任何工具的对外行为,纯增量功能
- 复用既有的
turnSnapshots快照机制,零额外磁盘 I/O - Webview CSP 未放宽
- content provider 仅返回内存中的快照,不读取任何新路径
- 不引入新依赖
🇺🇸 English
✨ New feature: Pending Edits Panel
Inspired by GitHub Copilot's review-edits experience in VS Code. A new popover sits right
above the composer and lets you inspect every file the agent just wrote / patched, and
decide whether to keep or discard each one before they become part of your "real" edits.
- Popover lists every file the agent wrote / patched / replaced in the current session
- File name + per-file
+xxx -xxxline stats new/deleted/binarytags where relevant
- File name + per-file
- Per-file actions: hover a row to reveal ✓ (Keep) and ✕ (Discard)
- Bulk actions: "Keep all" / "Discard all" in the header
- Click a row → native VS Code Diff editor
- Left: pre-edit snapshot served by a new
deepcopilot-before:TextDocumentContentProvider - Right: current on-disk content
- URI carries a cache-busting timestamp and the provider fires
onDidChange, so repeat clicks always re-open
- Left: pre-edit snapshot served by a new
- Survives turn end:
pendingEditsis now keyed by session rather than by run, so panel rows remain
clickable even after the agent finishes the turn and AgentLoop reaps the run — matching GH Copilot UX - Discard restores the file from the snapshot; Keep just removes the entry (disk stays as the agent wrote it)
- Fully integrated with the existing "Revert this turn" status-bar button and the
revert_last_turntool —
the panel clears automatically on revert
🔧 Model spec refresh (bundled)
- DeepSeek
v4-pro/v4-flash: max output → 384 000 tokens - OpenAI
gpt-5.5/gpt-5.4: context → 1 050 000 tokens - Anthropic Opus 4-7 / 4-6: context → 1 000 000 tokens, max output → 128 000 tokens
- Anthropic Sonnet 4-6: context → 1 000 000 tokens
- DeepSeek v4-pro 2.5× discount extended to 2099 per the official announcement (effectively permanent)
🛠 Internals
- New
src/chat/diff-utils.js: LCS-based line diff with graceful fallback for files >10k lines / >100k chars and a binary-safety guard src/chat/tool-executor.js:snapshotForEditnow also populates session-levelpendingEdits; newrecordEditResult/serializePendingEditshelpers fire after every successfulwrite_file/str_replace_in_file/apply_patchsrc/chat/provider.js: pending state moved to a session-keyed_pendingEditsBySessionmap; newkeepEdit/keepAllEdits/discardEdit/discardAllEdits/openEditDiffwebview handlerssrc/extension.js: registersdeepcopilot-before:TextDocumentContentProvider+onDidChangeemittermedia/chat.{css,js}/src/webview/html.js/src/utils/i18n.js: new#pending-edits-panelUI markup, styling, dispatcher entry, bilingual EN/ZH strings- Switched
toolMap/_readTermCardMapfrom plain objects to nativeMap, eliminating the CodeQL remote-property-injection and prototype-pollution sinks
🔒 Security / compatibility
- No tool surface changes; the feature is purely additive
- Reuses the existing
turnSnapshotsmechanism, zero extra disk I/O - Webview CSP unchanged
- The content provider only returns in-memory snapshots and never touches new paths on disk
- No new dependencies
v0.40.0 - UI refresh, terminal early-exit, vscodeignore cleanup
Deep Copilot v0.40.0 — UI 视觉统一 · Terminal Early-Exit · 打包清理
本版本聚焦三件事:聊天界面的设计语言统一、
run_shell_bg的早退捕获窗口、.vscodeignore与发布产物清理。同时修复了 PR #130 的 CodeQL 安全告警。
🇨🇳 中文说明
1. 聊天 UI 视觉重构 🎨
- 引入设计令牌:
--dc-indent/--dc-fg-*/--dc-accent/--dc-rule - 8 大容器统一为「2px 左侧色条 + 16px 缩进」节奏:
.tool卡片头部、.tl工具行、.tl-detail详情区、.tool .b主体全部对齐 - 工具类型色条:
k-read/k-write/k-search/k-shell/k-agent/k-plan/k-other,一眼可分 .tl-group .tl-summary折叠摘要同步采用 2px 色条- 工具名 chip 由
<span>改为<code>,与正文 monospace 一致
2. Thinking 块体验 🧠
模型开始正文输出后,思考块头部自动汇总为 Thought for Ns 并折叠,保留头部入口可随时展开复盘。
3. Output Style Contract 📝
系统提示词新增"输出风格契约"段,约束等宽规则、列表语义、段落控制、禁用装饰性 emoji,对话排版更稳定。
4. Terminal Early-Exit Window ⚡
run_shell_bg提交后增加 2.5 秒早退捕获窗口:若命令在窗口内崩溃/退出(缺依赖、错 cwd、语法错误),同步返回真实的exit_code+ 输出,模型立刻看见错误- 窗口超时则按原
running流程异步推进 terminal-monitor新增markSyncReturnedJob/wasSyncReturned,避免延迟到达的bg-job-end事件被重复注入
5. .vscodeignore 清理 🧹
- 移除 14 条失效规则(已删除的
test/data/models/runs/及一批.pt权重) - 新增
.github/**/.eslintrc.json/.gitleaksignore - 按用途分组并加注释,vsix 体积更精简
6. 安全修复 🔒
media/chat.js:新增isUnsafeKey守卫,过滤__proto__/prototype/constructor,消除 7 处 Remote Property Injection(High)与 2 处 Prototype-Polluting Assignment(Medium)src/chat/agent-loop.js:移除lastSnapshotAt死赋值
🇬🇧 English
1. Chat UI Visual Refresh 🎨
- New design tokens:
--dc-indent/--dc-fg-*/--dc-accent/--dc-rule - Eight container types now share one "2px left rule + 16px indent" rhythm —
.toolcard headers,.tltool rows,.tl-detailpanels, and.tool .bbody all align - Tool-type color rails:
k-read/k-write/k-search/k-shell/k-agent/k-plan/k-other .tl-group .tl-summaryadopts the same 2px rail- Tool-name chip changed from
<span>to<code>for monospace alignment
2. Thinking-Block UX 🧠
As soon as the model starts streaming, the thought block auto-collapses with a Thought for Ns summary while keeping the header clickable for on-demand review.
3. Output Style Contract 📝
System prompt gains an "Output style contract" section governing monospace usage, list semantics, paragraph control, and banning decorative emoji — markdown output is far more consistent.
4. Terminal Early-Exit Window ⚡
run_shell_bgnow races the spawn against a 2.5 s capture window: if the command crashes/exits inside the window (missing deps, bad cwd, syntax errors), the realexit_code+ output are returned synchronously, so the model sees failures immediately instead of giving up after a fire-and-forget submission- On timeout, the original async
runningpath takes over terminal-monitorexposesmarkSyncReturnedJob/wasSyncReturnedto deduplicate the latebg-job-endevent so the agent loop never re-injects what was already returned
5. .vscodeignore Cleanup 🧹
- Removed 14 stale rules (deleted
test/data/models/runs/and a batch of.ptweights) - Added
.github/**/.eslintrc.json/.gitleaksignore - Grouped and commented by purpose — leaner vsix payload
6. Security Hardening 🔒
media/chat.js: newisUnsafeKeyguard filters__proto__/prototype/constructorbefore any dynamic key write — closes 7× Remote Property Injection (High) and 2× Prototype-Polluting Assignment (Medium) CodeQL findingssrc/chat/agent-loop.js: removed deadlastSnapshotAtassignment
🙏 致谢 / Acknowledgements
特别感谢仓库管理员 @YSMsimon SY 在本版本中的代码审查、安全告警跟进与发布把关工作。Deep Copilot 的稳定迭代离不开你的支持 💙
Special thanks to repository admin @YSMsimon SY for code review, security-alert triage, and release gatekeeping on this version. Deep Copilot would not iterate this smoothly without your support 💙
📦 安装 / Install
下载附件 deep-copilot-0.40.0.vsix,在 VS Code 中:
- 命令面板 →
Extensions: Install from VSIX...→ 选择文件 - 或终端:
code --install-extension deep-copilot-0.40.0.vsix
Download the attached deep-copilot-0.40.0.vsix and install via:
- Command Palette →
Extensions: Install from VSIX... - Or CLI:
code --install-extension deep-copilot-0.40.0.vsix
v0.35.3 — Explorer 附加 · read_terminal · Agent 验证闭环 · save_plan
🇨🇳 中文
一、Explorer 右键附加文件/文件夹 📁
在 VS Code 资源管理器右键点击任意文件或文件夹,选择「附加到 Deep Copilot」,一键将文件内容或目录结构注入聊天上下文。文件超 64 KB 自动截断;文件夹递归遍历(最深 3 层 / 最多 200 条目,自动跳过
ode_modules\ / .git\ / \dist\ 等)。
二、\
ead_terminal\ 工具 🖥
模型可主动读取 VS Code 集成终端的最新输出,无需用户手动粘贴;支持按终端名称过滤;输出自动截断并脱敏。
三、Agent 主动验证闭环 🔁
执行关键写操作或命令后,Agent 自动生成验证 tool call(读回文件确认、执行测试)。
un_shell\ 结果结构化为 {exit_code, stdout, stderr}\,模型可直接按成功/失败分支处理。
四、\save_plan\ 工具 📋
Plan 模式调查结束时将结构化计划(标题、目标、步骤、涉及文件、风险)持久化到 .deep-copilot/plans/\,以时间戳命名为标准 Markdown 文件。
五、上下文 chip 自动附加当前文件 📎
打开编辑器文件后,该文件路径自动以 chip 形式出现在输入框;切换文件时实时更新;聚焦聊天面板时 chip 不再被误清除。
六、Bug 修复与 UI 调整
- 技能路径跨 home / 工作区目录解析修复
- 工具卡片边框改为主题感知色 \�ar(--vscode-panel-border)\
- 工具头部状态栏恢复显示
- Composer 区域移除多余顶部分隔线
🇬🇧 English
1. Explorer Context Menu — Attach File / Folder 📁
Right-click any file or folder in VS Code Explorer → Attach to Deep Copilot injects its content or directory tree as a chip. Files truncated at 64 KB; folders walked recursively (max depth 3, max 200 entries;
ode_modules\ / .git\ / \dist\ etc. skipped automatically).
2. \
ead_terminal\ Tool 🖥
The model can proactively read the latest output of the VS Code integrated terminal — no more manual copy-pasting. Supports filtering by terminal name; output auto-truncated with sensitive paths sanitised.
3. Agent Proactive Verification Loop 🔁
After critical writes or shell commands, the agent automatically emits a follow-up verification tool call (re-read file, run tests).
un_shell\ result is structured as {exit_code, stdout, stderr}\ so the model branches on success/failure.
4. \save_plan\ Tool 📋
At the end of a Plan-mode investigation, the structured plan (title, goal, steps, files, risks) is persisted to .deep-copilot/plans/\ as a timestamped Markdown file.
5. Context-Chip Auto-Attach Current File 📎
When an editor file is focused its path appears as a chip in the input bar; updates live as you switch files; chip is preserved when focus moves to the chat panel.
6. Bug Fixes & UI
- Skill SKILL.md path resolution across home / workspace directories
- Tool-card borders replaced with theme-aware \�ar(--vscode-panel-border)\
- Tool header status bar restored (was accidentally hidden)
- Composer top separator removed
v0.35.2 — Explorer 附加 · read_terminal · Agent 验证闭环 · save_plan
🇨🇳 中文
一、Explorer 右键附加文件/文件夹 📁
在 VS Code 资源管理器右键点击任意文件或文件夹,选择「附加到 Deep Copilot」,一键将文件内容或目录结构注入聊天上下文。文件超 64 KB 自动截断;文件夹递归遍历(最深 3 层 / 最多 200 条目,自动跳过
ode_modules\ / .git\ / \dist\ 等)。
二、\
ead_terminal\ 工具 🖥
模型可主动读取 VS Code 集成终端的最新输出,无需用户手动粘贴;支持按终端名称过滤;输出自动截断并脱敏。
三、Agent 主动验证闭环 🔁
执行关键写操作或命令后,Agent 自动生成验证 tool call(读回文件确认、执行测试)。
un_shell\ 结果结构化为 {exit_code, stdout, stderr}\,模型可直接按成功/失败分支处理。
四、\save_plan\ 工具 📋
Plan 模式调查结束时将结构化计划(标题、目标、步骤、涉及文件、风险)持久化到 .deep-copilot/plans/\,以时间戳命名为标准 Markdown 文件。
五、上下文 chip 自动附加当前文件 📎
打开编辑器文件后,该文件路径自动以 chip 形式出现在输入框;切换文件时实时更新;聚焦聊天面板时 chip 不再被误清除。
六、Bug 修复与 UI 调整
- 技能路径跨 home / 工作区目录解析修复
- 工具卡片边框改为主题感知色 \�ar(--vscode-panel-border)\
- 工具头部状态栏恢复显示
- Composer 区域移除多余顶部分隔线
🇬🇧 English
1. Explorer Context Menu — Attach File / Folder 📁
Right-click any file or folder in VS Code Explorer → Attach to Deep Copilot injects its content or directory tree as a chip. Files truncated at 64 KB; folders walked recursively (max depth 3, max 200 entries;
ode_modules\ / .git\ / \dist\ etc. skipped automatically).
2. \
ead_terminal\ Tool 🖥
The model can proactively read the latest output of the VS Code integrated terminal — no more manual copy-pasting. Supports filtering by terminal name; output auto-truncated with sensitive paths sanitised.
3. Agent Proactive Verification Loop 🔁
After critical writes or shell commands, the agent automatically emits a follow-up verification tool call (re-read file, run tests).
un_shell\ result is structured as {exit_code, stdout, stderr}\ so the model branches on success/failure.
4. \save_plan\ Tool 📋
At the end of a Plan-mode investigation, the structured plan (title, goal, steps, files, risks) is persisted to .deep-copilot/plans/\ as a timestamped Markdown file.
5. Context-Chip Auto-Attach Current File 📎
When an editor file is focused its path appears as a chip in the input bar; updates live as you switch files; chip is preserved when focus moves to the chat panel.
6. Bug Fixes & UI
- Skill SKILL.md path resolution across home / workspace directories
- Tool-card borders replaced with theme-aware \�ar(--vscode-panel-border)\
- Tool header status bar restored (was accidentally hidden)
- Composer top separator removed
v0.33.0 — 史诗级 UI 重构 · Epic UI Overhaul
Deep Copilot v0.33.0 — 史诗级 UI 重构 · Epic UI Overhaul
这是 DeepCopilot 有史以来最大规模的界面体验升级,全面对标顶级 AI 编程助手的交互标准。
🇨🇳 中文说明
总览
v0.33.0 以"少即是多"为核心理念,对聊天界面进行了三大方向的深度重构:
- 工具调用展示 — 从繁琐的卡片式布局,蜕变为 Sema / GitHub Copilot 同款的极简单行文本
- 进度动画 — 彻底重设计底部 Sonar Spinner,删繁就简、加入动态文字与计时
- 滚动体验 — 修复长回复时进度条被遮挡的顽固性 bug
一、工具调用 UI 极简化 🔧
之前的样子:
每次工具调用都会渲染一个带有图标、三角形展开符、状态标签、分栏的完整卡片,信息密集、视觉嘈杂,尤其在 Agent 连续调用十几个工具时,界面几乎被工具卡堆满。
现在的样子:
read_file src/extension.js ← 单行灰色文本,点击展开
write_file media/chat.css ← 文件路径更淡、字更小
run_shell npm run package ← 无图标、无边框、无背景
具体改动:
- 隐藏所有图标(
display:none),彻底不占位 - 隐藏三角形展开符,用更自然的点击交互替代
- 隐藏状态标签(Running / Done / Error),状态通过动态小点暗示
- 工具名称:字体缩小至 10.5px,颜色使用
descriptionForeground,透明度降至 65% - 文件/目标路径:等宽字体 10px,透明度仅 42%,几乎退到背景
- 运行中小动画:工具名称后接一个琥珀色呼吸小点(
::after伪元素),静默指示执行中状态 - 点击展开:整行可点击,展开后显示完整参数与输出结果
- 思考气泡(Thought):移除所有"思考中 Xs"耗时标签,不再在每步工具调用前显示累计秒数——安静专注
视觉层级(文字颜色由深到浅):
| 元素 | 颜色/透明度 |
|---|---|
| 正文回复 | foreground(白色/深色) |
| 工具名称 | descriptionForeground × 65% |
| 文件路径 | descriptionForeground × 42% |
| 详情内容 | descriptionForeground × 68% |
二、底部进度动画全面重设计 🌊
底部的"正在思考"动画是用户感知 AI 状态的核心视觉元素,此版本对其进行了颠覆性重设计。
旧版问题:
- 带背景色、边框、光扫 shimmer 效果,视觉噪声过大
- 没有任何文字信息,用户不知道 AI 在做什么
- 计时信息散落在各思考气泡中,难以追踪
新版设计语言:
● Reasoning… 3s · Esc
↑蓝光波 ↑18px留白 ↑动词 ↑计时 ↑中断提示
Sonar 光波(保留并增强):
蓝色同心圆扩散动画完整保留,以 VS Code 主题色(button.background)为准,双层脉冲:
- 外层:环形扩散,从 scale(1) 放大至 scale(4),透明度渐出
- 内层:box-shadow 脉冲,延迟 0.7s,错峰制造连续感
- 停止时:两层动画同时冻结,透明度降至 25%
透明背景:
去除所有 background、border、shimmer 效果,整个 spinner 悬浮于内容之上,不遮挡视线、不增加视觉层级。
英文动词轮播:
20 个精心挑选的英文动词,每 3 秒随机切换一次,切换时触发 0.55s 渐显动画(opacity: 0.1 → 1 → 0.85):
Reasoning…·Synthesizing…·Cogitating…·Deliberating…·Computing…·Inferring…·Distilling…·Modeling…·Weaving…·Decoding…·Manifesting…·Orchestrating…·Ruminating…·Pondering…·Crafting…·Assembling…·Percolating…·Ideating…·Transmuting…·Conjuring…
实时计时器:
动词右侧显示已用时间,格式 1s / 2m5s,每秒刷新。让用户清晰感知每一步的耗时。
中断提示:
计时器后显示 · Esc 提示,窗口宽度不足时自动隐藏(Container Query)。
停止状态:
按下 Esc 后,动词立即变为 Stopping…,文字颜色切换至 errorForeground(红色),Sonar 动画冻结,边框变暗红。
空间设计:
光波与动词之间留有 18px 留白,给视觉以呼吸感,避免拥挤。
三、滚动体验修复 📜
问题: 在长回复生成过程中,底部进度条会随内容增加而下沉,最终被输入框遮挡,只露出上半部分,用户无法看到完整的动画与计时信息。
根本原因:
ascroll() 在内容刚插入 DOM 时立即读取 scrollHeight,而此时浏览器尚未完成布局计算,scrollHeight 返回旧值,导致滚动量不足。
修复方案(三管齐下):
requestAnimationFrame包裹:将msgs.scrollTop = msgs.scrollHeight推迟到浏览器完成当帧布局后执行,确保读取的是最新高度- 每秒兜底滚动:在
_renderStatus计时回调末尾追加ascroll()调用,每秒主动确认一次 spinner 可见性 - nearBottom 阈值扩大:从 80px 提高到 120px,给 spinner 自身高度留出余量,防止过早脱离吸底模式
受影响文件
| 文件 | 变更内容 |
|---|---|
media/chat.js |
DC_VERBS 动词表、setBusy 重构、_renderStatus 更新、ascroll rAF 修复、makeThinkChip 置空 |
media/chat.css |
工具卡片 CSS 全量重写、dc-spinner 新样式、dcTextFlash 动画 |
README.md |
版本徽章更新、v0.33.0 changelog 条目 |
src/ |
其他后端累积修复 |
🇺🇸 English Release Notes
Overview
v0.33.0 is the largest UI overhaul in DeepCopilot's history, built around the philosophy of less is more. Three major areas were redesigned from the ground up:
- Tool-call display — from verbose card-based layout to the same minimal single-line style used by Sema and GitHub Copilot
- Progress animation — completely redesigned Sonar Spinner with dynamic text and a live timer
- Scroll experience — fixed the long-standing bug where the spinner was obscured by the input box
1. Minimal Tool-Call UI 🔧
Before:
Every tool invocation rendered a full card with icons, a chevron toggle, status labels, and multi-column layout. With agents making a dozen+ tool calls, the chat window was effectively buried under cards.
After:
read_file src/extension.js ← single grey line, click to expand
write_file media/chat.css ← path dimmer, smaller font
run_shell npm run package ← no icon, no border, no background
What changed:
- Icons hidden (
display:none) — zero pixel footprint - Chevrons hidden — natural click-to-expand replaces the toggle
- Status badges hidden — running state indicated by a subtle amber breathing dot
- Tool name: 10.5px,
descriptionForegroundat 65% opacity - File/target path: monospace 10px, 42% opacity — almost invisible background detail
- Running indicator: an amber breathing dot via
::afterpseudo-element silently signals in-progress state - Click to expand: the entire row is clickable; expands to show full args and output
- Thought chips: removed all "Thinking Xs" elapsed labels — no more per-step countdown noise
Visual hierarchy (text colour, darkest to lightest):
| Element | Color / Opacity |
|---|---|
| AI reply text | foreground (full) |
| Tool name | descriptionForeground × 65% |
| File path | descriptionForeground × 42% |
| Expanded detail | descriptionForeground × 68% |
2. Sonar Spinner — Complete Redesign 🌊
The bottom progress indicator is the primary visual signal that the AI is working. This version delivers a ground-up redesign.
Old problems:
- Background colour, border, and shimmer effect added visual noise
- No text information — users had no idea what the AI was doing
- Elapsed time scattered across thinking chips, hard to track
New design:
● Reasoning… 3s · Esc
↑sonar ↑18px gap ↑verb ↑timer ↑interrupt hint
Sonar wave (retained and enhanced):
The blue concentric-ring pulse animation is fully preserved, using VS Code theme colour (button.background), with a two-layer pulse:
- Outer ring: expands from scale(1) to scale(4), fading out
- Inner glow:
box-shadowpulse with a 0.7s delay, creating a continuous wave effect - On stop: both layers freeze, opacity drops to 25%
Transparent background:
All background, border, and shimmer effects removed. The spinner floats over content with zero visual weight.
English verb carousel:
20 hand-picked English verbs rotate randomly every 3 seconds. Each transition triggers a 0.55s fade-in animation (opacity: 0.1 → 1 → 0.85):
Reasoning…·Synthesizing…·Cogitating…·Deliberating…·Computing…·Inferring…·Distilling…·Modeling…·Weaving…·Decoding…·Manifesting…·Orchestrating…·Ruminating…·Pondering…·Crafting…·Assembling…·Percolating…·Ideating…·Transmuting…·Conjuring…
Live elapsed timer:
Displayed to the right of the verb in 1s / 2m5s format, updating every second. Gives users a clear sense of how long each step is taking.
Interrupt hint:
· Esc displayed after the timer. Auto-hidden when the panel is too narrow (Container Query).
Stopping state:
On Esc, the verb immediately changes to Stopping…, text colour switches to errorForeground (red), the Sonar animation freezes, and the dot dims.
Breathing room:
An 18px gap between the sonar dot and the verb text gives the design room to breathe.
3. Scroll Fix 📜
Problem: During long streaming responses, the spinner sank toward the bottom of the chat area and was eventually hidden behind the input box — only the top half of the animation was visible.
Root cause:
ascroll() read scrollHeight immediately after DOM insertion, before the browser had completed layout. This returned a stale (shorter) height, causing the scroll to fall short.
Fix — three-pronged approach:
requestAnimationFramewrapper: defersmsgs.scrollTop = msgs.scrollHeightuntil after the browser finishes the current frame's layout, ensuring the height is fresh- Per-second safety net:
_renderStatusnow callsascroll()at the end of every 1-second tick, actively verifying spinner visibility - Wider nearBottom threshold: raised from 80px to 120px, leaving headroom for the spinner's own height and preventing premature detachment from sticky-scroll mode
Files Changed
| File | Change |
|---|---|
media/chat.js |
DC_VERBS array, setBusy rewrite, _renderStatus update, ascroll rAF fix, makeThinkChip no-op |
media/chat.css |
Tool card CSS fully rewritten, dc-spinner new styles, dcTextFlash keyframe |
README.md |
Version badge updated, v0.33.0 changelog entry added |
src/ |
Accumulated backend fixes |
📦 Installation
- Download
deep-copilot-0.33.0.vsixbelow - In VS Code:
Extensions→···→Install from VSIX… - Select the downloaded file and reload
Or via terminal:
code --install-extension deep-copilot-0.33.0.vsixv0.32.9 — run_shell OS launch + autopilot workspace bypass
累积更新:相对于 v0.32.7,包含 v0.32.8 和 v0.32.9 两个补丁版本,均为 bug 修复。
Cumulative update from v0.32.7: two bug-fix patches, v0.32.8 and v0.32.9.
v0.32.8 — 修复:Agent 拒绝打开桌面应用 / Fix: Agent refuses to open desktop apps
问题背景 / Background
在 autopilot 模式下,请求"请打开我的 CAD 软件"等桌面操作时,Agent 会回复"作为 AI 助手我无法打开桌面应用程序"——实际上根本没有尝试调用 run_shell(日志显示 tool_calls=0)。根本原因是模型训练先验("我只是编程助手")覆盖了对 run_shell 能力的认知。
In autopilot mode, requests like "please open my CAD software" caused the agent to reply "As an AI assistant I cannot open desktop applications" — without even attempting run_shell (logs showed tool_calls=0). The root cause was the model's training prior ("I'm just a coding assistant") overriding its awareness of run_shell capabilities.
修复内容 / Changes
在系统提示词的"Using tools"章节新增明确正向指令:声明 run_shell 拥有完整的操作系统访问权限;列出各平台应用启动命令(Windows: Start-Process,macOS: open,Linux: xdg-open);明确禁止以"无法启动应用"为由拒绝任务,要求始终先用 run_shell 尝试。
Added an explicit instruction in the "Using tools" section of the system prompt: declares run_shell has full OS-level access; lists platform launch commands (Start-Process / open / xdg-open); explicitly prohibits the agent from refusing with "I cannot launch applications" — it must always attempt with run_shell first.
受影响文件 / Affected file: src/prompts/system.js
v0.32.9 — 修复:Autopilot 模式下仍弹出工作区外访问对话框 / Fix: "Outside workspace" dialog in autopilot mode
问题背景 / Background
将审批模式设为 autopilot(无需人工确认)后,Agent 读写工作区外文件(如 ~/.deepcopilot/memory.md)时仍会弹出"Deep Copilot 想访问工作区之外的路径"对话框,需手动点击确认——与 autopilot 的语义相悖。
Even with approvalMode = autopilot, the "Deep Copilot wants to access a path outside the workspace" dialog still appeared when reading/writing files outside the workspace (e.g. ~/.deepcopilot/memory.md). This contradicted the intended semantics of autopilot mode.
修复内容 / Changes
在 ensurePathAllowed() 中,弹出对话框前先检测审批模式:autopilot 时静默放行并缓存路径至本轮会话集合(_outsideWsApprovals),后续不再重复检查;manual / auto-edit 模式行为不变。
In ensurePathAllowed(), added an approval-mode check before the dialog: when autopilot, silently allow the path and cache it in _outsideWsApprovals for the session. manual and auto-edit modes are unaffected.
受影响文件 / Affected file: src/tools/utils.js
Deep Copilot v0.32.7
Deep Copilot v0.32.7 — Release Notes
🇨🇳 中文说明
本次更新 (v0.32.6 → v0.32.7)
新功能:多语言字体 + Webview 界面全面本地化(Issue #53)
背景
之前 Webview 始终使用 VS Code 编辑器字体(var(--vscode-font-family)),在中文环境下汉字通常以等宽字体渲染,观感偏窄;英文环境下无系统级 UI 字体优化。同时,界面所有文案均为硬编码中文,英文 VS Code 用户看到的是中文界面。
改动内容
1. 自动字体切换
- 启动时读取
vscode.env.language,检测 VS Code 显示语言。 - 中文环境(
zh-*):字体栈优先使用Microsoft YaHei UI → Microsoft YaHei → PingFang SC → Hiragino Sans GB → Noto Sans CJK SC → Source Han Sans CN → WenQuanYi Micro Hei,在 Windows / macOS / Linux 均有合理兜底。 - 其他语言(
en等):字体栈切换为Segoe UI → Inter → system-ui → -apple-system → BlinkMacSystemFont → Helvetica Neue → Arial。 - 通过
html[data-locale]属性实现 CSS 条件覆盖,无运行时开销。
2. Webview 界面全面 i18n
- 将
src/webview/html.js中所有硬编码中文字符串(共 20 处)接入现有t()国际化系统。 - 涉及:欢迎页副标题、输入框 placeholder、侧边栏标签与按钮、会话列表空状态、思考中指示器、工具提示文本等。
- 中文 VS Code 保持原有中文界面;英文 VS Code 所有文案自动切换为英文。
效果对比
| 界面元素 | 中文 VSCode | 英文 VSCode |
|---|---|---|
| 字体 | 微软雅黑 UI / 苹方 | Segoe UI / system-ui |
| 欢迎副标题 | 让高质量 AI 生产力开放、公平、普惠 | Open, fair, and accessible AI productivity for all |
| 输入框提示 | 描述要构建的内容 | Describe what you want to build |
| 会话面板 | 历史会话 / 本工作区 / 全部 | Sessions / Workspace / All |
| 思考指示 | ● ● ● 思考中... | ● ● ● Thinking... |
受影响的文件
src/webview/html.js— 注入data-locale属性,接入t()翻译src/utils/i18n.js— 新增 20 条wv*前缀 Webview UI 字符串(中英两套)media/chat.css— 新增两条html[data-locale]条件字体规则
🇺🇸 English Release Notes
What's Changed (v0.32.6 → v0.32.7)
New: Locale-aware fonts + full webview i18n (Issue #53)
Background
The webview previously used VS Code's editor font (var(--vscode-font-family)) for all UI text — a monospaced code font that renders poorly for Chinese characters. Additionally, every string in the webview HTML template was hardcoded in Chinese, making the interface unusable in non-Chinese locales.
Changes
1. Automatic font switching
- Reads
vscode.env.languageat startup to detect the active VS Code display language. - Chinese locale (
zh-*): font stack prioritisesMicrosoft YaHei UI → Microsoft YaHei → PingFang SC → Hiragino Sans GB → Noto Sans CJK SC → Source Han Sans CN → WenQuanYi Micro Hei, with full fallback coverage on Windows / macOS / Linux. - Other locales (
en, etc.): font stack switches toSegoe UI → Inter → system-ui → -apple-system → BlinkMacSystemFont → Helvetica Neue → Arial. - Implemented via
html[data-locale]CSS attribute selectors — zero runtime overhead, no bundled font files added.
2. Full webview i18n
- All 20 hardcoded Chinese strings in
src/webview/html.jsare now routed through the existingt()i18n system. - Covers: welcome subtitle, input placeholder, session panel labels and buttons, empty-state text, thinking indicator, all button tooltips.
- Chinese VS Code users see the same Chinese interface as before; English VS Code users now see a fully English UI.
Affected files
src/webview/html.js— injectsdata-locale, usest()for all UI stringssrc/utils/i18n.js— adds 20wv*-prefixed webview UI strings (EN + ZH)media/chat.css— adds twohtml[data-locale]conditional font-family rules