feat!: 0.6.0 —— 侧边栏重组为 工程/库生态/缓存,并修完两轮真实验收问题 - #17
Open
Sunrisepeak wants to merge 49 commits into
Open
Sunrisepeak wants to merge 49 commits into
Sunrisepeak wants to merge 49 commits into
Conversation
- src/ 从 15 个平铺文件改为 cli/ projects/ toml/ mcppls/ commands/ workflows/ 分组 - test/ 与 src/ 镜像;e2e 套件改名 extension.e2e.ts,避免被 node --test 采集 - 删除 src/configureOnly.ts、src/ideWorkflow.ts(0.4.0 迁移后无生产调用者, 且与"不再解析 compile_commands.json"的职责边界冲突) - commands.ts 拆为 commands/ids.ts(命令 ID)与 commands/menu.ts(快捷菜单) - package.json test 脚本改用递归 glob dist/test/**/*.test.js - 纳入 .agents/docs 设计文档;.agents/reviews 保持 gitignore 行为零变化:179 个单测通过(原 188 个,减少的 9 个来自删除的死代码测试)。
i18n
- 英文原文即 key,data/i18n/*.json 是运行时文案的单一来源
- tools/generate-l10n.mjs 生成 l10n/bundle.l10n*.json;tools/l10n-check.mjs
阻止新增硬编码:任一 t("…") 缺翻译即 CI 失败,且校验 package.nls 双语 key 集合一致
- package.json 的用户可见字符串(displayName/description/16 个命令标题/category/
untrustedWorkspaces.description)改为 %key%,文案落在 package.nls.json 与 package.nls.zh-cn.json
- mcpp.ui.language 支持 auto/en/zh-cn 手动覆盖(逃生门;命令面板与原生设置页恒随 VS Code)
config
- data/config-registry.json 是全部设置的唯一事实源:64 项、10 组、29 项公开
- src/config/{registry,validate,access,migrate,presets}.ts:类型化读写、枚举/范围校验、
生效值来源(default/user/workspace/folder)、旧键别名与一次性迁移、四套预设
- tools/check-config.mjs 把 registry 与 package.json 做语义一致性门禁;
tools/generate-settings-docs.mjs 生成 docs/settings.md
- 激活时按设置同步语言偏好,并在设置变更时刷新
其他
- tsconfig 打开 resolveJsonModule;package.json test 脚本先跑两个一致性门禁
- .vscodeignore 排除 tools/ 与根 data/(JSON 已编译进 dist/data/)
验证:npm test 229 通过(含 check-config 与 l10n-check 门禁)
mcppls(方案 §2、§3.9) - src/mcppls/contract.ts:能力表(15 项),全部 required=false;不安全操作带 danger 与 confirmHint;契约自带断言(不得 required、forward 必须有候选命令、本扩展不得用 mcppls. 前缀) - src/mcppls/capabilities.ts:静态声明 + 惰性运行期分类。UI 命令不做探针调用(会弹窗); 记忆 missing 后不再打扰 VS Code;refresh 走候选链,上游哪天注册轻量重载即自动优先 - src/mcppls/state.ts:读取 mcppls 的 lastStatus() 并归一化。非契约通道,因此形状探测 + try/catch + state 白名单;未知形状只降级不报错;透出 S3 自带的 issue 修复命令 - src/mcppls/bridge.ts:结构化返回(不再拼文案),保留单飞刷新;新增 10 个转发命令 - src/mcppls/messages.ts:文案与逻辑分离,全部走 i18n cli - src/cli/protocol.ts:信封解析(解析 stdout,不看退出码)、协议能力探测、readData - src/cli/errors.ts:SPEC-003 错误分层(含 101 仅对 mcpp run、4 未就绪、127 未知命令)与 MCPP_* 诊断码提取 - src/cli/cache.ts:mcpp.cache 信封解析与聚合(按类型/标签/年龄分桶,incomplete,TopN) - src/cli/artifacts.ts:target/ 体积估算(不跟随符号链接,带条目/深度预算) 验证:npm test 294 通过;protocol.ts 已对真实 mcpp 2026.9.30.2 交叉验证 (--protocol-version / toolchain list --format json / 退出码 2 与 127)
- src/views/models.ts:工程/缓存/C++ Modules 三棵树以「标签即 key」的纯数据描述, 不依赖 vscode 也不依赖当前语言;渲染时才经 i18n 解析,测试断言稳定的 key - src/cli/clean.ts:全部清理动作作为计划表(argv + 危险级 + 是否预演 + 是否二次确认 + 是否需要受信工作区)。cache clean --all 可达但唯一为 3 级;--bmi-cache 只能通过 withSharedCache 显式升级危险级 - src/projects/summary.ts:从 mcpp.toml 读浅摘要(身份/toolchain/targets/profile), 行式解析、读不到就省略字段,绝不猜 验证:新增 38 个用例通过(视图模型 18、清理策略 12、工程摘要 8)
…intelligence
Mode A of §3.2 of the plugin-optimisation plan: `build.mcpp` keeps the
`mcpp-build` language id and the C++ language service never sees it, so this is
the intelligence layer that replaces it — pure data, scanning and analysis, no
clangd and no "module not found".
- tools/generate-buildscript-api.mjs reads the mcpp checkout (MCPP_REPO,
default ../mcpp) and writes data/buildscript-api.json: the 31-row kTable, the
five roles, kProtocolVersion/kCacheEpoch, the provision kinds, the SPEC-007
rule ids that mention each wire name, and a docs anchor per heading that
spells the wire name. Any unreadable source, a parse that yields zero rows or
a count that disagrees with the declared array size exits 1 without writing.
- src/buildscript/api.ts (snapshot + invariants), modules.ts (import scanner and
known modules), analysis.ts (the seven SPEC-007 static rules) never import
vscode.
- src/buildscript/providers.ts is the one-line integration: completion, hover
and a diagnostic collection for { language: "mcpp-build" }.
- test/buildscript/* matches the snapshot against the mcpp source (row count and
every wire name), covers import scanning through comments/strings, and has a
positive and negative case for each of the seven rules (28 tests).
tools/generate-toml-schema.mjs 从 mcpp 仓库生成 data/toml-schema.json: 段列表只来自 modules/manifest/src/toml.cppm,平面来自 SPEC-004 §2 的平面表, doc 锚点来自 docs/04 的小节标题;枚举词表是脚本里唯一手工维护的部分。 src/toml/schema.ts 是快照的纯数据读取层,src/toml/diagnostics.ts 是保守的 mcpp.toml 文本诊断(1 基行列、七条规则、可逐条关闭)。
- tools/check-generators.mjs:用 mcpp checkout 重新生成 buildscript-api.json 与 toml-schema.json,任何差异即失败;没有 checkout 时跳过并说明(不静默通过) - npm run check 现在包含 check:config + check:l10n + check:generated - 修正方案文档里两处 mcpp 实际不存在的键名(profile.opt_level -> opt、 bidi_schedule -> bmi_schedule),由生成脚本核对源码时发现 验证:npm test 390 通过;三个门禁脚本全绿
清单(package.json)
- 命令从 16 增至 42:缓存 9、C++ Modules 转发 14、工具 3(含设置面板与环境自检)
- 新增 Activity Bar 容器 mcpp 与三个视图(工程/缓存/C++ Modules),视图描述里写明
C++ Modules 的内容由 sunrisepeak.mcpp-language-server 提供,本视图只展示与转发
- 新增两个可覆盖颜色(mcpp.cacheOkForeground / mcpp.cacheStaleForeground)
- 激活面收敛:删除全部 onCommand:*(VS Code 1.74+ 由 contributes.commands 自动生成),
只留 workspaceContains:mcpp.toml 与 onLanguage:mcpp-toml / mcpp-build
- 全部命令标题与视图名走 %nls% 键,中英双语
代码
- src/views/treeProvider.ts:唯一的 TreeDataProvider,标签在渲染时翻译
- src/views/{projectView,cacheView,languageServerView}.ts:三棵视图与其命令
- src/cli/cacheView 的清理命令全部经由 src/cli/clean.ts 的计划表(预演 + 分级确认 +
受信检查),缓存面板给出本地 LRU 预估
- src/mcppls/stateSource.ts:唯一读取 mcppls extension.exports 的地方,全部防御
- src/config/{panel,panelHtml}.ts + media/settings.css:配置面板(严格 CSP、无外链、
主题变量、来源与生效时机、预设、搜索、仅显示已修改、边界提示)
- src/toml/providers.ts:mcpp.toml 补全 + 七条诊断;src/buildscript/providers.ts 接入
- src/cli/selfCheck.ts + mcpp.selfCheck:一份可复制的环境快照
- 0.4.x 的 5 个语言服务命令 ID 全部保留为转发别名
验证:npm test 420 通过;check-config / l10n-check / check-generators 全绿
- package.json / package-lock.json 升到 0.5.0 - CHANGELOG 增加英文 0.5.0 段(新增/变更/修复/移除/迁移),并在开头说明此版本起改用英文 - tools/dev-profile.mjs:隔离 profile(私有 extensions/ 与 user-data/),打包并安装本 VSIX、 解析 mcppls 依赖、准备一个可用的 mcpp 工程,最后打印可直接复制的启动命令与验收清单 - .gitignore 忽略 .dev-profile/ 验证:code --list-extensions 在隔离目录中显示 mcpp-community.mcpp-vscode@0.5.0 与 sunrisepeak.mcpp-language-server@0.0.9
文档
- README.md(英文,120 行)与 README.zh-CN.md(中文,同结构),顶部语言切换
- docs/{architecture,commands,mcpp-toml,build-script,cache,troubleshooting,compatibility}.md
七篇用户文档,52 条相对链接全部解析通过
- docs/settings.md 保持生成,未手改
e2e
- test/e2e/mcpplsStub.ts 生成五种 mcppls 变体(full / partial / renamed / noapi / throwing)
- runTest.ts 每个变体一次隔离的 Extension Host 运行;MCPP_E2E_STUB 可只跑一个
- 套件断言:42 个命令全部注册、视图容器与三视图存在、build 之后按候选链调用
reload(partial 时回退 restart、renamed 时不调用)、转发命令不抛异常、
旧 0.4.x ID 仍可用、自检与设置面板不抛异常
审计
- 文档子代理逐项核对代码后发现 13 处设置已声明但无人读取,已记入
.agents/docs/2026-10-02-implementation-plan.md §8 作为下一轮输入
- artifacts 测试改为断言 package.json / package-lock.json 版本一致,而不是钉死 0.4.0 - README 断言改为英文主文档 + 中文对照,并断言'不得声称启动第二个 LSP 客户端'等边界 - runTest.ts 支持 MCPP_E2E_CODE=<可执行文件>,可跳过 135 MB 的固定版下载(CI 仍用 version) - 记录 round 2 进展与本地 e2e 的限制
TOML(G1/G2/G3)
- src/toml/hover.ts、src/toml/navigation.ts:段/键/枚举悬停;workspace=true、
path="…"、features=[…] 三种跳转;纯逻辑,永不抛异常
- src/toml/completion.ts 改为快照驱动(键、枚举值、每类型占位符、openKeys 段不提示键),
并按 mcpp 接受但快照未建模的段合并手写清单([workspace.dependencies] 等仍可补全)
- src/cli/search.ts:mcpp search 的解析器(本项目唯一一处解析人类输出,已在注释里说明)
- providers.ts 注册 HoverProvider 与 DefinitionProvider,受 mcpp.toml.hover / navigation 控制
缓存面板(G4)
- src/views/cachePanelHtml.ts(纯)+ src/views/cachePanel.ts(宿主)+ media/cache.css
- 构成叠条、年龄分布、TopN、预算模拟器、不完整条目告警;严格 CSP、无外链、
只用主题变量、状态不靠颜色区分
- 替换原先把统计打成 Markdown 预览的实现;命令仍由 registerCachePanel 独占注册
设置接线(G8/G13)
- mcpp.task.{build,run,test,clean}Args、ui.statusBar.show、languageService.menuItems、
runtime.{concurrency,timeoutSeconds,maxOutputMiB}、languageService.refreshAfterBuild、
views.*.show(setContext)、diagnostics.selfCheckOnStartup、buildScript.intelligence、
ui.numberFormat(缓存状态栏与面板)
两条防倒退门禁
- test/config/wiring.test.ts:每个设置必须被读取,或在例外表里写明理由并指向 §8 编号;
例外表只允许缩小;已弃用设置反过来断言绝不被读取
- test/i18n/hardcoded.test.ts:未走 t() 的中文行数封顶 162,只允许下降
CI(T39)
- gates 矩阵(ubuntu + macos-14)、generated-drift(检出 mcpp 让漂移门禁真正生效)、
package(清单承诺 + VSIX 内容断言)、extension-host-e2e(五种 mcppls 变体)、
isolated-install(真实解析依赖并打印版本)
验证:npm test 471 通过;check-config / l10n-check / check-generators 全绿
文档里'已声明但未接线'的说明正是那几项缺口本身;它们补上之后,说明必须同步, 否则文档就变成了新的错误来源。53 条相对链接重新校验通过。
.vscodeignore 只排除了 .agents/**,没有排除 tools/dev-profile.mjs 生成的 .dev-profile/, 于是它把整个示例工程、私有 extensions/ 与 user-data/ 一起打进了产物。修复后 76 文件 211 KB。 - .vscodeignore 增加 .dev-profile/** 与 .vscode-test/** - CI 增加产物体积与目录守卫:文件数 > 200 或体积 > 1 MiB 即失败,并逐个断言 .dev-profile/ .agents/ test/ tools/ src/ node_modules/ 不得出现
G5 快捷键
- ctrl/cmd+alt + b/r/t/l/m 分别对应构建/运行/测试/清理工程产物/快捷菜单,
作用域 mcpp.inProject,并有断言锁定键位与作用域
视图可见性(G8 的一部分)
- extension.ts 通过 setContext 发布 mcpp.views.{project,cache,languageServer}
- package.json 的三个视图各自 when 到对应键
G10 重命名提示
- 激活时若 0.4.x 的旧键仍有值且新键还是默认值,提示一次(每工作区一次),
可移动到用户设置或工作区设置;旧键一律保留,删不删是用户的决定
G12 版本提示
- 已安装的 mcppls 低于已验证范围时,在 mcpp 输出频道写一句说明;
只是提示,不做门禁——能力探测已经保证旧版本可用
门禁
- test/config/wiring.test.ts 新增'已接线的设置必须从例外表删除',
防止例外表变成永久免责清单;据此清掉 9 条已接线的例外(42 → 31)
验证:npm test 474 通过;check-config / l10n-check 全绿
三个并行工作流(controller / views+mcppls / buildscript+toml)合计接线 24 项设置:
任务与界面
- mcpp.task.{revealTerminal,focusTerminal,clearTerminal} 控制任务终端的呈现方式
- mcpp.task.problemMatcher:任务按 $mcpp 关联问题匹配器,package.json 补上该匹配器
- mcpp.task.editorTitleButtons:setContext 控制编辑器标题按钮
- mcpp.task.confirmClean:任务路径与 mcpp.cleanProjectArtifacts 共用同一个答案
- mcpp.ui.notifications.{success,dedupeMinutes}:成功结果可静默/状态栏/弹窗,并可去重;
失败与取消永不降级
- mcpp.ui.confirmDestructiveOnly:默认只对不可撤销的操作弹模态;关掉只会更谨慎
- mcpp.ui.statusBar.showLanguageServer:状态栏附带 C++ Modules 状态
- mcpp.log.level:输出频道分级,错误与失败命令的原始输出永不被抑制
缓存与语言服务
- mcpp.cache.showLegacy:用 mcpp cache dir 的遗留路径做有界测量,非空才显示节点
- mcpp.cache.autoRefreshSeconds / mcpp.languageService.stateRefreshSeconds:仅在视图可见且
受信任时轮询,单飞刷新,随扩展一起释放
- mcpp.cache.warnAboveGiB:超过阈值时树里出现告警节点
- mcpp.cache.gc.confirmAboveGiB:预算越大,多一次显式确认;不削弱既有等级
- mcpp.languageService.{readState,notifyOnDegraded,confirmResetCache}
- 环境自检的 Cache 段不再永远是 'not read'
build.mcpp 与 mcpp.toml
- mcpp.buildScript.intelligence 现在真的是总开关(此前 completion/hover 从未被它控制)
- mcpp.buildScript.snippets 有了真正的 snippet 提供者
- mcpp.buildScript.imports.knownModules 只影响 import 补全列表;
std/std.compat/mcpp.* 永不被报缺失这条测量结论在所有开关关闭时仍有回归测试
- mcpp.toml.indexCompletion{TimeoutSeconds}:依赖版本补全,默认关闭,超时兜底,失败即静默
- 注册表里 mcpp.buildScript.imports.knownModules 的描述原先读起来像'未知 import 诊断',
与测量结论矛盾,已改写并同步 nls
门禁
- test/config/wiring.test.ts 的例外表清零:64 个设置全部被真实读取。剩下的 4 个
mcpp.task.*Args 通过 TASK_ARGUMENT_SETTINGS 表间接读取,改为带证据的 READ_INDIRECTLY,
证据必须仍在文件里,且表中项不得再被字面量读取
- tools/l10n-check.mjs 现在也能看见视图模型里的延迟标签键 { key: "…" }(仅限 src/views),
于是又暴露出 8 条此前静默回退英文的字符串,已全部翻译
文档
- docs/build-script.md 与 docs/mcpp-toml.md 的'本版未读取'表已改正;
troubleshooting 里自检缓存段的说明同步
验证:npm test 539 通过(round 3 为 474);check-config / l10n-check / check-generators 全绿
docs/settings.md 由注册表生成,此前只有英文描述——而中文描述其实早就存在于 package.nls.zh-cn.json(设置界面用的那份)。生成器改为读它,避免出现第三份译文, 64 个设置现在都是中英对照。 CI 的 generated-drift job 本来就会跑 gen:docs 并断言无 diff,所以这份文档不会漂移。
那个 64 MB 的 VSIX 事故如果发生在发布流程里,就直接进了 Release 附件。CI 已经加了守卫, 现在 release.yml 也加上:文件数 > 200 或体积 > 1 MiB 即失败,并逐个断言 .dev-profile/ .agents/ test/ tools/ src/ node_modules/ 不得出现,最后 unzip -t。
i18n
- 158 条用户可见字符串改为 t("..."),键用英文(仓库既有约定:英文即键,中文在
data/i18n/zh-cn.json)。162 行 -> 0,门禁改为断言 === 0,并保留'扫描仍在工作'的
反空转守卫(检查文件数下限 + 故意植入一条中文断言能被抓到)
- 显示与判定同源的常量合并到 src/cli/labels.ts 等单一定义处,避免'按标签比较'被翻译拆散
- src/i18n/t.ts 此前并非 vscode-free(顶层 import * as vscode),导致纯模块无法使用 t()。
改为 import type + 惰性 require,在编辑器外回退到英文键;这使'纯模块不依赖 vscode'
这条既有约定真正成立
- 5 行中文尾随注释移到独立行(非用户可见,不翻译)
架构门禁(新 test/architecture.test.ts)
- 41 个纯模块逐一断言:不得 import vscode(import type 允许),并且必须在没有编辑器的
进程里能被真正加载——源码检查证明'没有引用',加载检查证明'后果成立'
验证:npm test 549 通过;check-config / l10n-check (308 runtime strings) / check-generators 全绿
一条总原则落地:视图正文只呈现状态,动作与数据分区。 视图 - 三段:工程(树)/ mcpp 库生态(webview)/ 缓存(webview);C++ Modules 不再独立成视图, 折进工程·基本信息并默认折叠。**折叠行自带状态图标**,降级时不展开也能看见问题 - 工程视图分「基本信息」与「常用命令」两块;依赖显示为两级(mcpp.toml 声明 + mcpp.lock 解析值),**不画连线**,因为 lock 里没有父子边 - 总闸 mcpp.views.enabled:关闭后所有视图隐藏,Activity Bar 上的 mcpp 图标一并消失 (package.json 用否定式 when ,否则默认隐藏会导致永远无法激活) - 缓存视图从编辑器标签页改为侧边栏 webview:项目缓存常显,全局缓存默认折叠、 摘要一行;一条 6px 主条 + 单行图例取代原来的三层堆叠 mcpp 库生态(新增) - 离线浏览本机已有的包索引:搜索、命名空间/用法筛选、已添加/有更新 - 详情页在编辑器区:真实示例代码(索引 CI 实际构建运行的 172 个示例工程)、 按平台的版本矩阵、许可、仓库、一键 mcpp add(唯一会写 mcpp.toml 的路径) - 标签用官方索引站的词表 import / #include / tool / 上游 mcpp.toml,取自 mcpp xpkg parse --json - 跨 registry 搜索单独开关,默认关闭(那一档会联网且只有人类输出) 其它 - 扩展图标换成官方 mcpp-logo.png,与 mcppls 同一张 - 新增设置 4 项(共 68),新增命令 3 个 验证:npm test 636 通过;check-config / l10n-check(307 runtime, 201 manifest) / check-generators 全绿 VSIX: 92 文件 / 336 KiB
在 VS Code 1.132 源码里核实:扩展无法把自己的容器标记为 hideIfEmpty (该标志全仓库只有 registerGeneratedViewContainer 一处赋值为 true,安装包里的 24 处 全是内置容器)。因此把所有视图 when 设为 false 只会让**内容**消失,图标会留下。 - mcpp.views.enabled 的标题/描述改成实话:「隐藏 mcpp 视图内容」,并说明图标是否移除 由 VS Code 决定、要移除可在图标上右键(注册表 + 中英 nls 同步) - when 门控保留:内容隐藏是确定的(activeViewDescriptors.length === 0 那条路径) - mcpp.internal.markIndex 之前只注册不调用,导致 index update 装好索引后 viewsWelcome 不消失;改为 markIndexFound(),激活时与 index update 后都重算 - test/architecture.test.ts 补上库生态的 4 个纯模块 验证:npm test 638 通过;check-config / check-generators / l10n-check 全绿
每一条都先在一手源码或本机真实运行里定位根因,再改: - 工程视图:「常用命令」默认展开、图标按语义带色(树支持 ThemeIcon 颜色), 「基本信息」默认折叠,侧边栏打开时先看到"能做什么"。 - 快捷菜单:每条命令带 codicon,按 QUICK_MENU_GROUPS 插分隔符分组;补齐 20 条 中英译文,并加门禁(分组必须连续、每个 labelKey 必须有译文)。颜色不做—— 1.132 的 MainThreadQuickOpen.expandIconPath 会把 ThemeIcon 压成纯 codicon class。 - 库视图无反应的根因不是索引定位,而是 registerWebviewViewProvider 从未被调用 (src/library/ 里一次都没有),refresh() 永远打在 this.view === undefined 上。 改为在 registerLibraryView 内注册,并加"每个 webview 视图都必须注册 provider"的 门禁。索引定位改为 $MCPP_HOME → ~/.mcpp → mcpp self env --format json(信任工作区 才跑,每会话最多一次,且只在便宜 glob 全空时);刷新命令加进度与结果反馈。 删除已被证伪的 mcpp.library.indexFound 与 viewsWelcome.library(基类 ViewPane.shouldShowWelcome() 恒为 false,webview 视图不会渲染 welcome)。 - 缓存分布条全黑:样式选择器写成 rect[data-kind],而属性在 <g> 上,所有 rect 落到 SVG 默认填充(黑)。选择器改到 g(fill 继承),并加"文档与样式表互查"的测试。 - 活动栏 logo 是白块:VS Code 把自定义容器图标当 mask 用(画的是 alpha),而官方 logo 是不透明黑底徽章。新增派生的 images/activity-bar.png(透明底 + 白色字形), 由 tools/generate-activitybar-icon.mjs 从 logo.png 生成,check:icon 进门禁。 646 测试通过;check:config / l10n-check / check:icon / check:generators 全过; VSIX 93 文件 343 KiB。
- 库视图抖动/高 CPU 的根因是渲染死循环:文档 post `ready`,宿主答以 `paint()`, 而 `webview.html = …` 会重载文档;每次 paint 又生成新 nonce,所以文档永远不同、 永远重载(点不动、搜不了)。删掉 ready 握手、nonce 改为每视图一个、paint() 比对 文档相同就不重设、新解析的 webview 清空记忆;并加源码级门禁。 - 快捷菜单图标配色:VS Code 只在 iconPath 是 Uri 时按图片画(ThemeIcon 的颜色被丢), 所以新增 tools/generate-quick-menu-icons.mjs,从 @vscode/codicons(精确锁定 0.0.46-24)取字形、按对应 charts.* 令牌的默认明/暗值上色,生成 40 个 media/quick-menu/*.svg;check:icon 与 test/commands/menu.test.ts 双向对齐表格与资产。 顺带修:charts.orange 是 33% 透明(破坏性动作改 charts.red)、star 不是 codicon (改 star-full,那一行此前是空图标)、菜单与树统一 library 图标。 - cache 视图默认折叠(views[].visibility: collapsed),高度让给库列表。 - 状态栏背景:VS Code 的扩展主机只接受 warning/error 两种背景并强制配套前景色 (自建颜色会被静默丢弃),因此新增 mcpp.ui.statusBar.background(默认 warning) 与纯映射 src/cli/statusBar.ts;活动栏彩色与状态栏 logo 在 API 层面不存在,保留单色。 653 测试通过;check:config / l10n-check / check:icon / check:generators 全过; VSIX 134 文件 377 KiB。
- 状态栏背景默认改回 none(设置保留为可选项):常驻琥珀色块会被读成"出问题了"。 - 侧边栏默认配比:mcpp.library 设 initialSize: 40。清单里的 initialSize 会变成视图的 split-view weight,VS Code 按 weight 分配容器高度(默认每个 20),所以库视图拿下面 2/3、工程视图留 1/3,cache 折叠后其份额回流。 - 库标签去掉外框:徽标改成不带框不带底的安静元数据(相邻项用 · 分隔),只有 Added 与 不可读保留颜色+加粗;筛选 chip 换成 VS Code 原生 toggle 配色(未选中不描边)。 - 详情页重排:主操作(添加+命令预览)从页面最底提到标题之下,版本矩阵变成可点选的选择器 (去掉重复的 select),分区标题从大写微标签改成正常小标题 + hairline;并删掉详情页客户端 里同样是空实现的 ready 握手(库视图死循环的成因形状),补上内联脚本门禁。 - 年龄分布条改成冷→热渐变:渲染器按桶序算出 data-age-step(0..3),CSS 四档用 charts.blue/green/yellow/red(都实色,charts.orange 是 33% 透明),旧的 data-bucket 着色删除。 - 通用命令新增第九行「新建 mcpp project…」(排最前),无工程时的空状态也给出同一入口, 新建流程的目录选择默认指向当前工作区。「初始化当前目录」无法实现:mcpp new 拒绝已存在的 目标目录且无 --here/--force(见文档 §17.5)。 - 活动栏按工程状态换色同样不可行(清单静态字符串、无 when、mask 只取 alpha),文档 §17.6。 655 测试通过;四道门禁全过;VSIX 134 文件 380 KiB。
- 快捷菜单的 C++ Modules 分组新增四条:抓取日志(报告+压缩包)、查看诊断报告、
打开日志目录、定位最近抓取的压缩包。上游 mcppls 本来就有这些命令,只是我们一条都没挂。
- 新命令 mcpp.languageServer.openLogFolder 转发 mcppls.revealCacheDirectory("logs")
(上游用它 reveal paths.logDirectory),能力表新增 logsDirectory,参数由调用方传。
- 新命令 mcpp.languageServer.revealBundle:压缩包路径只有 exportDiagnosticBundle 的
【返回值】知道(<平台 cache>/bundles/*.zip),而我们此前在 CapabilityRegistry.invoke
里把返回值丢掉了。现在 InvokeResult 增加可选 value 原样透传,导出成功后记进 globalState,
再用 revealFileInOS 定位;没抓过或文件已删则给出提示与「现在抓取」按钮。
- 修一个刚要犯的错:把 exportDiagnosticBundle 改成手写 register 后忘了删旧的 forward,
重复 registerCommand 会在 activate() 抛异常、整个扩展起不来。加了
「no command id is registered twice」源码门禁,并把 bug 放回去验证过它确实会红。
658 测试通过;四道门禁全过;VSIX 142 文件 386 KiB。
- 库视图搜索框下的筛选 chip 行整行移除(在真实索引上是三行按钮压在列表上方),
并随之删掉只服务它的整条链路:LibraryChip / chips / activeChip / {type:"filter"} 消息
与解码分支 / 客户端 chip 逻辑 / chipsOf / 纯模型的 LibraryFilter、ALL_FILTER、
ADDED_FILTER、matchesFilter、visibleEntries、namespaceCounts、surfaceCounts、addedCount
及其测试与 .chip* CSS。命名空间仍在每行的 haystack 里,搜索 compat 即可过滤;
"已添加"是行上的徽标。
- 详情页把 Open the repository / Open on the index site 从事实行移进主操作块,与
Add to mcpp.toml 并排一行(后两颗为次要按钮),复用客户端已有的 [data-open-url] 分支。
- 活动栏 logo 是灰的不是故障:清单 icon 只能是字符串、容器图标被当 mask 画(只取 alpha,
颜色来自 icon.foreground),且无运行时 API。判据是文件里不透明像素 100% 纯白 #FFFFFF,
而实际显示 #C5C5C5 = Dark Modern 的 icon.foreground——颜色在文件与像素之间被换掉了;
hover 变亮可再证一次。三条独立理由写在文档 §19.3,未做代码改动。
657 测试通过;四道门禁全过;VSIX 142 文件 384 KiB。
- detailPanel 构建模型时读工程自己的答案:mcpp.toml 的声明版本优先(键是短名,实测 mcpp add compat.argparse@3.2 写 argparse = "3.2"),mcpp.lock 的 resolved 兜底。 - 版本矩阵给该版本加 data-installed + 文字标记 added;主按钮按"已有什么"和当前选择变化: 未添加=Add、选中即已装=Already added(禁用)、选中其他=Switch to <ver>(可点)。 标签随 clientState 下发,客户端在切换版本时重算,避免按钮含义与选择脱节。 - mcpp add 成功后不重建文档(刻意保留滚动与选择),改为结果消息带 added.version, 客户端用 createElement/textContent 就地移动标记并重算按钮,修掉"加完还显示 Add"。 - 外链点击:原来 void openExternal 丢掉返回值,失败时零反馈。现在客户端先写 pending 行, 宿主按结果回答;失败则复制链接到剪贴板并说明、写进 mcpp 输出通道。DetailResult 增加 pending 状态与对应 CSS。 660 测试通过;四道门禁全过;VSIX 142 文件 387 KiB。
- CHANGELOG 里那条『mcpp.views.enabled 关掉后图标消失』是错的(round 2 已用源码证伪): 改成实话——它隐藏视图内容,图标要右键移除。 - 补上验收轮次修掉的真 bug 及根因(库视图重载死循环、缓存条全黑、活动栏白块、 快捷菜单无色、重复注册、外链无声),并写上新增能力(菜单分组/图标、抓日志与定位、 新建工程行、详情页已添加/切换版本、缓存视图默认折叠、年龄渐变)。 - 原本写着库生态有『namespace/surface 筛选』与『有更新』状态:筛选已按反馈移除, 『有更新』从未实现,一并改正。 - README/README.zh-CN 的『三个视图』与『C++ Modules 视图』写法同步为现状。
generated-drift:两个生成器用 `git rev-parse --short HEAD` 写 sourceCommit, 而短哈希长度取决于**该 clone 的对象数量**——CI 的全新检出给 7 位、开发者的 clone 给 8 位, 于是同一份 mcpp 生成出两个不同文件,门禁在 API 毫无变化时变红(本次就是如此,内容完全一致)。 改成写完整 40 位哈希,并让 check-generators 只比较**数据**:sourceVersion/sourceCommit 以及由 commit 拼出的文档链接属于"出处",每次上游提交都会动,把它们当漂移等于门禁永远红。 package:`! grep -rqs "vscode-languageclient" dist/src` 会被"解释为什么不用语言客户端"的 **编译后注释**命中。改成匹配真正的模块说明符(require/from)。 两处都补了本地门禁,免得下次只能等 CI: - 快照的 sourceCommit 必须是 40 位十六进制(正是今天这个 bug 的类别); - src 里不得 import/require vscode-languageclient(CI 那条 grep 的本意)。 662 测试通过;四道门禁全过。
GitHub 的 ubuntu runner 不预装 VS Code,这个 job 从写下的第一天起就只可能红在 `code: command not found`(e2e 之所以能跑,是 @vscode/test-electron 自己下了 一份)。给 isolated-install 同样的待遇,而不是删掉它:它验证的正是 e2e 覆盖 不了的那一环——extensionDependencies 从市场端到端解析(e2e 用的是打桩的 mcppls)。 - tools/ci-vscode-cli.mjs:downloadAndUnzipVSCode() + CLI 路径解析,默认钉在 与 e2e / engines 相同的 1.91.0;缓存进 .vscode-test/(.gitignore 与 .vscodeignore 早已排除,不会进 VSIX,也不会进 git)。 - ci.yml:job 新增一步下载 CLI 存进 $CODE,原有两个步骤的裸 code 全部改为 "$CODE";profile 参数一字未动,测的东西没变。 - artifacts.test.ts:workflow 必须引用 tools/ci-vscode-cli.mjs,且不得再出现 裸 `code --` 调用——把 bug 改回去会让测试红。 本地已按 job 的原样命令端到端验证:VSIX 装进私有 profile 时依赖自动从市场解析 sunrisepeak.mcpp-language-server@0.0.9,--list-extensions 两条都在;headless 下 CLI 管理命令不需要 DISPLAY。npm test 662 通过。
- gates 加 windows-latest:663 个单测与四道门禁此前只有 Linux/macOS 在守。 - extension-host-e2e 扩三平台:Linux 仍走 xvfb-run,其余直接启动;fake-mcpp 在 Windows 上改为 .cmd 包装器(扩展宿主无法 execFile shebang 脚本),转调 同目录的 node 脚本。 - isolated-install 扩三平台:每个平台各自从市场拉对应平台的 mcpppls 构建, 这正是这个 job 要证明的解析行为;Windows 用 runner 自带的 Git Bash 跑同一 套 POSIX 步骤,CLI 路径转正斜杠、列表输出去 CR。 - src/cli/process.ts:Windows 上 .cmd/.bat 只能经 shell 启动(Node ≥20.12 对 无 shell 的 .cmd 直接 EINVAL);真实场景是用户把 mcpp.path 指到 npm 式 shim。 新增 spawnNeedsShell 判定 + 单测。 - artifacts.test.ts:三个 job 都必须是三平台矩阵(数出来恰好 3 份),防止 哪天又悄悄缩回单平台。 本地 npm test 663 通过。VS Code 下载钉在 1.91.0(engines 最低版本),与 e2e 一致。
isolated-install (macos-14) 首轮红在下载:update.code.visualstudio.com 的 CDN 边缘连续三次掐断连接(内建重试全部在 300ms 内 aborted),而一分钟前 同 OS 的 e2e job 下载同一 URL 成功——瞬态。两手加固: - tools/ci-vscode-cli.mjs:外层重试(30s/60s 退避,--retries 可调), 给边缘节点恢复时间;stdout 仍只输出 CLI 路径。 - e2e 与 isolated-install 两个 job 缓存 .vscode-test(key 含 OS+arch+版本), 命中即完全跳过 ~135 MB 下载,重复运行既快又免疫这类瞬断。 本地验证:脚本重跑命中缓存,路径输出不变。
… 自动跳过;同一只 VSIX 不重打包
…链接),修 4 处实错;superpowers 移至 .agents;architecture 补 i18n/l10n 两层说明
…迁移,门禁从锁实现细节改为锁不变量
…宿主不再裸赋值 webview.html(新门禁锁死)
….1/P1 落地);补 import/#include 引入方式行;命令与用法行可复制
…式;Already added 半透明绿
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
把
main上的 0.4.0 推到 0.6.0:一次交付「设置/国际化/CI 基线」+「侧边栏重组」+ 两轮真实实例验收修出来的问题。分支名是早期起的(
…-v0.5.0),版本已经走到 0.6.0,名字保留不改。一、这一版的核心设计不变式
视图正文只读/状态,动作与数据物理分区。 侧边栏从四个视图收到三个:
initialSize: 40,清单里的initialSize就是 split view 的 weight,默认每个视图 20)visibility: "collapsed"),把高度让给库列表C++ Modules 不再是一个视图:它的状态是 工程 → 基本信息 里的一行(默认折叠,但折叠时也带状态图标,降级一眼可见),它的操作在状态栏快捷菜单和工程视图里。
设置系统是注册表单一事实源:
data/config-registry.json→package.json+ 两份 nls + 文档,check-config校验一致性与分组内order递增;l10n-check要求每个t("…")字面量都有中文。二、验收轮次修掉的真 bug(每条都追到根因)
ready自我介绍,宿主拿paint()回答,而webview.html = …会重载文档;每次渲染又换新的 CSP nonce,于是没有任何两次文档相同。删掉握手、nonce 改为每视图一个、内容相同不重设文档;详情页里同样是空实现的ready一并删除。两处都有测试。rect[data-kind=…],而渲染器把属性打在包着它的<g>上 → 一条规则都没匹配,全部落到 SVG 默认填充。改成在<g>上设fill(rect继承),并加"文档 ↔ 样式表互查"的测试。logo.png派生的透明底字形,tools/generate-activitybar-icon.mjs+npm run check:icon作为漂移门禁。ThemeIcon(1.132 的MainThreadQuickOpen.expandIconPath会把它压成无颜色的 codicon class),所以改为随包生成彩色 SVG(每图标每配色词一份、明暗各一),由tools/generate-quick-menu-icons.mjs从@vscode/codicons生成。exportDiagnosticBundle差点注册两次(先进了通用转发表,后来手写 register 时没删旧行)。重复registerCommand会让activate()抛异常、整个扩展起不来。加了"任何命令 id 只能注册一次"的源码门禁,并把 bug 人为放回去验证过门禁确实会红。void vscode.env.openExternal(…)丢掉了"是否打开成功"的返回值,失败与死按钮无法区分。现在点击立刻写pending行,宿主再按结果回答;失败则把 URL 放进剪贴板并写进输出通道。顺手纠正的还有:
charts.orange其实是 33% 透明(破坏性动作改用charts.red)、star根本不是 codicon(那一行一直是空图标)、缓存年龄条四段同色(改成蓝→绿→黄→红四档渐变,因为桶数由mcpp.cache.staleDays决定,CSS 数不出桶,所以阶数在渲染器里算)。三、新增能力
mcppls.exportDiagnosticBundle)、查看诊断报告、打开日志目录、定位最近抓取的压缩包。mcpp.toml/mcpp.lock里的版本、标记added,按钮变成Switch to <ver>(mcpp add实测会就地改版本,退出码 0)。target/的 stale 拆分都保留。四、明确做不到的三件事(都有源码证据,欢迎复核)
icon只能是字符串({light,dark}会被isValidViewsContainer判非法)、容器图标被当 alpha 模板画、且没有运行时 API。判据:文件里不透明像素 100% 是纯白#FFFFFF,而实际显示#C5C5C5(Dark Modern 的icon.foreground)——颜色是在文件与像素之间被换掉的。paneCompositeBar.shouldBeHidden第一句就是if (viewContainer.hideIfEmpty) {…} else return false;,而hideIfEmpty在已安装包里 24 处全是内置容器。所以mcpp.views.enabled只隐藏内容,图标要右键移除。ALLOWED_BACKGROUND_COLORS白名单只有statusBarItem.warningBackground/errorBackground(并强制配套前景色),其他颜色会被静默丢弃;状态栏也放不了图片,只能 codicon。mcpp new拒绝任何已存在的目标目录且没有--here/--force,mcpp --help里也没有init。这是上游缺口。五、验证
npm test:660 通过 / 0 失败(check+clean+compile+node --test)。check-config(10 组 / 69 设置 / 32 public)、l10n-check(389 运行串 / 205 清单键)、check:icon(活动栏 1 + 菜单 48)、check:generators。tools/dev-profile.mjs装进隔离 profile 后启动,扩展主机日志确认 mcpp-vscode 与 mcppls 均激活、无错误。extension-host-e2e(五种 mcppls stub)才是它的第一次真实运行。e2e 是 smoke 级:它用contributedCommandIds()断言"每个贡献的命令都已注册",正好覆盖第二节第 5 条那个类别的错误。六、风险与已知缺口
data/i18n(380+ 条)与生成的图标资产(48 个 SVG,zip 后约 34 KiB);media/quick-menu/与images/activity-bar.png都由脚本生成并有--check门禁。mcpp xpkg parse,详情页 239/239)。mcpp clean --stale只有人类输出,没有可信数据源,需要时可删掉这行。$MCPP_HOME+~/.mcpp/mcpp self env --format json)是打桩vscode后跑编译产物验证的,不是通过编辑器 UI。mcppls.*只转发不重写;mcpp.path是 resource 作用域,探测索引前会检查工作区信任。完整决策与证据链(含每轮的源码片段与实测数据)在
.agents/docs/2026-10-02-ui-ux-optimisation-plan.md。