Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: d2learn/d2mcpp
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: mcpp-community/d2mcpp
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 17 commits
  • 688 files changed
  • 4 contributors

Commits on May 4, 2026

  1. chore: update xlings ecosystem references

    Update d2mcpp's xlings bootstrap, documentation links, and checker wording to use the current openxlings ecosystem references.
    Sunrisepeak authored May 4, 2026
    Configuration menu
    Copy the full SHA
    89bea6e View commit details
    Browse the repository at this point in the history

Commits on May 23, 2026

  1. Configuration menu
    Copy the full SHA
    58101ca View commit details
    Browse the repository at this point in the history

Commits on Jun 8, 2026

  1. Configuration menu
    Copy the full SHA
    909d64a View commit details
    Browse the repository at this point in the history

Commits on Jun 9, 2026

  1. docs(cpp11): authoring skill + vendored MSVC STL + ch00 auto/decltype…

    … overhaul (mcpp-community#52)
    
    * add msvc-stl
    
    * docs(authoring): add d2mcpp-authoring skill
    
    Bilingual chapter/exercise/solution templates + conventions for the
    d2mcpp tutorial: 5-section chapter layout, the '真实案例 / Real-World
    Case' section backed by the vendored msvc-stl/ basis, single entry
    checker command (d2x auto-advances), per-exercise Tips, and the
    collapsible tool-setup <details> block. Also ignore the throwaway
    upstream STL/ clone (the curated subset lives in msvc-stl/).
    
    * docs(cpp11/00): overhaul auto/decltype chapter (zh + en)
    
    - add section 二 真实案例 — verbatim std::begin/cbegin cited from the
      vendored msvc-stl/ basis
    - restructure to 5 sections; section 三 注意事项 now also covers auto's
      const/reference stripping
    - exercises: topic-specific Tips, add char-case asserts to exercise 0,
      new exercise -5 (const/reference stripping & preservation)
    - practice section: list all 6 exercises, single entry checker command,
      collapsible d2x setup, per-chapter discussion link
    - footer: add mcpp-community org + d2x tool links
    - fix typos (变得 / 显式)
    - register exercise -5 in dslings + solutions xmake
    
    * update xmake.lua
    Sunrisepeak authored Jun 9, 2026
    Configuration menu
    Copy the full SHA
    307dc8a View commit details
    Browse the repository at this point in the history

Commits on Jun 13, 2026

  1. docs(cpp11): add STL real-world case, exercise mapping, and tagged-un…

    …ion exercise for 16-generalized-unions (mcpp-community#57)
    
    * docs(cpp11): add STL real-world case and exercise mapping for 16-generalized-unions
    
    - add section 二 真实案例 — include std::variant _Variant_storage_ and
      std::any _Storage_t examples, both cited from vendored msvc-stl/
    
    - fill in 四 练习代码 — exercise descriptions, file links and
      d2x checker command
    
    - fix empty Code link in header table
    
    Case selection notes:
      Picked _Variant_storage_ over std::optional _Optional_destruct_base
      because the variant recursive union demonstrates both key C++11
      generalized-union capabilities — non-trivial members and manual
      destructor management — while the optional pattern is effectively
      a special case of variant. std::any adds a second typical use:
      union as type-erased storage. Both are directly traceable in the
      vendored msvc-stl/, consistent with how ch00 cites xutility.
    
    * docs(cpp11): fix exercise list format to match project convention
    
    * Potential fix for pull request finding
    
    Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
    
    * docs(cpp11): apply Copilot review suggestions — remove inaccurate noexcept, fix 类型安全 wording
    
    * feat(cpp11): add tagged-union exercise for 16-generalized-unions
    
    Add exercise 2 — tagged/discriminated union combining enum tag + union
    to implement a simplified std::variant-like Value type.
    
    Exercise progression:
      0. union default member initialization (static rule)
      1. non-trivial type + placement new + manual destructor
      2. enum tag + union → type-safe discriminated union
    
    Design rationale:
      ex 2 ties ex 0 and ex 1 together by adding a tag enum to track
      the active member — the exact pattern used by std::variant's
      internal _Variant_storage_, directly echoing the STL real-world
      case in the chapter. Learners construct/destruct/switch members
      based on tag, covering all three C++11 generalized-union
      capabilities in one practical exercise.
    
    * docs(cpp11): sync en book chapter with zh for 16-generalized-unions
    
    Apply the same updates to the English book chapter:
      - add section II Real-World Case (msvc-stl variant + any examples)
      - fill in section IV Exercise Code (exercise links + d2x checker command)
      - fix empty Code link in header table
      - add ex2 tagged-union exercise link
    
    ---------
    
    Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
    lczllx and Copilot authored Jun 13, 2026
    Configuration menu
    Copy the full SHA
    173f145 View commit details
    Browse the repository at this point in the history

Commits on Jun 14, 2026

  1. video(cpp11/00): manim animation for auto/decltype (mcpp-community#53)

    * video(cpp11/00): add manim animation for auto/decltype
    
    Manim Community v0.18.1 scene mirroring the existing videos/cpp11/*
    framework (MovingCameraScene + d2x mcpp_video_start/end, DHighlight,
    create_code_helper). Six scenes following the chapter:
    declaration, expression deduction, complex types (iterator),
    trailing-return + decltype, const/reference stripping, and the
    decltype parentheses pitfall.
    
    Run: uv run --with "manim==0.18.1" manim -pql videos/cpp11/00-auto-and-decltype.py
    
    * docs(cpp11/00): sync bilingual docs + add animation video link
    
    - Sync en doc to zh: iterator example (v.insert) and const/reference
      stripping example now match the zh version's code
    - Add Bilibili animation link (BV1EzJs6HEf7) alongside the existing
      explanation video in both book docs and videos/README.md
    - Add render.sh launcher and refine the manim animation script
    
    * docs(cpp11/00): correct video labels — 视频解读=BV1EzJs6HEf7, 练习讲解=BV1xkdYYUEyH
    Sunrisepeak authored Jun 14, 2026
    Configuration menu
    Copy the full SHA
    79ffbe6 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    c403bad View commit details
    Browse the repository at this point in the history

Commits on Jun 17, 2026

  1. Configuration menu
    Copy the full SHA
    e192f4b View commit details
    Browse the repository at this point in the history
  2. docs(cpp14): add 00-generic-lambdas book chapter, exercises, solution…

    …s, and build wiring (mcpp-community#71)
    
    * docs(cpp14): add 00-generic-lambdas book chapter and build wiring
    
    Add the first C++14 chapter covering generic lambdas — lambda parameters
    using auto, which the compiler expands into a functor with a templated
    operator().
    
    Book structure (zh + en):
      - 一/II: Basic usage — identity, multi-param, STL algorithms, captures,
        returning lambda (factory pattern)
      - 二/II: Notes — closure type uniqueness, perfect forwarding, non-variadic
      - 三/III: Exercise topics and d2x checker command
      - 四/IV: External resources
    
    Build wiring:
      - register cpp14 in dslings/xmake.lua, dslings/en/xmake.lua,
        solutions/xmake.lua
      - add cpp14 entry to zh/en SUMMARY.md and book/README.md
      - remove stale dslings/cpp14/README.md TODO placeholder
    
    Files: book/src/cpp14/, book/en/src/cpp14/, book/src/SUMMARY.md,
           book/en/src/SUMMARY.md, book/README.md,
           dslings/xmake.lua, dslings/en/xmake.lua, solutions/xmake.lua,
           dslings/cpp14/README.md (deleted)
    
    * feat(cpp14): add 00-generic-lambdas exercises and solutions
    
    Exercise progression:
      0. Basic generic lambda — auto parameter identity/comparison/type-size
         exercises. Learner fills auto param type, return expression, and
         sizeof argument. 4 D2X_YOUR_ANSWER.
      1. Generic lambda with STL algorithms — same lambda reused across
         vector<int> and vector<double> for sort/find_if, plus a factory
         pattern returning a lambda. 5 D2X_YOUR_ANSWER.
    
    Design rationale:
      Generic lambdas have three layers worth teaching independently:
      (1) syntax — auto in lambda parameters generates a templated operator();
      (2) reuse — a single lambda serves multiple container types, the
      primary motivation for the feature;
      (3) interaction — generic lambda returns + captures work naturally
      without extra syntax.
    
      ex 0 isolates layer (1). identity forces the learner to write auto
      in a parameter position. greater verifies the return expression is
      type-checked per instantiation. get_type_size confirms that sizeof
      on a generic parameter works correctly, reinforcing the "compiler
      stamps out per-type copies" mental model. Everything is self-contained
      and runnable without headers beyond <string>.
    
      ex 1 layers (2) and (3) on top. The desc lambda applied to both
      vector<int> and vector<double> makes the payoff tangible — contrast
      with the C++11 approach of duplicating the comparator. The find_if
      exercise adds a capture without complicating the generic parameter.
      The make_multiplier factory previews generic-lambda-returning-lambda,
      which is a pattern that only becomes practical with C++14 return type
      deduction.
    
      We deliberately limited this chapter to 2 exercises. A third exercise
      covering perfect forwarding + auto&& + decltype(auto) is better placed
      in the decltype(auto) chapter where the forwarding semantics are the
      primary topic, not a side note.
    
    Files: dslings/cpp14/00-generic-lambdas-{0,1}.cpp (zh),
           dslings/en/cpp14/00-generic-lambdas-{0,1}.cpp (en),
           dslings/cpp14/xmake.lua, dslings/en/cpp14/xmake.lua,
           solutions/cpp14/00-generic-lambdas-{0,1}.cpp,
           solutions/cpp14/xmake.lua
    
    * docs(cpp14): add STL real-world case and d2x setup block to 00-generic-lambdas
    
    - add transparent functor real-world case (std::greater<>) cited from
      vendored msvc-stl/stl/inc/functional
    - add collapsible d2x setup block in exercise section
    - sync en book chapter
    
    * docs(cpp14): fix Copilot review findings in 00-generic-lambdas
    
    - fix C++11 example using auto (C++14 feature) in EN Why-introduced
    - fix variadic claim: generic lambdas can be variadic in C++14
    - fix STL case: use greater<void> from xutility instead of greater_equal
    - fix is_transparent description: it signals associative containers,
      not sort algorithms
    lczllx authored Jun 17, 2026
    Configuration menu
    Copy the full SHA
    1c37ddd View commit details
    Browse the repository at this point in the history

Commits on Jul 23, 2026

  1. feat: 练习即测试——d2mcpp 全面重构(mcpp Provider/d2x 库/双入口) (mcpp-community#84)

    * feat(buildtools): 新增 mcpp Provider(C++26),替代 xmake 插件
    
    d2x 改为通用练习框架后,构建工具由具体课程实现。本 Provider 用
    C++26 + mcpp 编写——教 C++ 的仓库用 C++ 写自己的工具,且 mcpp 本就是
    必需品,零新增运行时依赖。
    
    发现方式刻意不引入声明文件:真相只有目录结构和练习文件自己的头部注释
    (// d2x:cxxflags:)。rustlings PR #1355 的教训是 edition 同时写在 rustc
    参数和 rust-project.json 里、两边漂移酿成 bug——任何独立声明文件都是
    第二套真相源。
    
    双 member 布局解决一个硬约束:dslings 的练习默认就编译不过,而 mcpp 的
    build/run 都会先全量构建整个包,一个坏兄弟拖垮全部且零产物。于是
    .d2x/build/<std>/ 持全量 target 供 clangd 拿到完整 compile_commands.json,
    .d2x/build/_current/ 每次只写当前一题供 checker。清单写入前做内容比对,
    不推进 mtime,mcpp 的快速路径得以保留。
    
    练习源文件原地不动:main 用 ../ 逃逸出包根。
    
    引导零脚本、Windows 安全:.d2x.json 指向
    `mcpp run -q -p d2x/buildtools/mcpp --`,从仓库根执行无需 cd,首次自动
    构建 Provider。
    
    runner 在每次 spawn 前清 LD_LIBRARY_PATH:mcpp run 会把它指向自己私有的
    glibc 并注入子进程,嵌套的 mcpp 被迫加载错配运行时后会在动态链接器里
    段错误(冷启动稳定复现)。d2x 侧对同一问题早有相同处理。
    
    tests/e2e.sh 断言每个参考答案通过、每个练习不通过——rustlings
    `dev check --require-solutions` 的等价物。实测 51/51 通过。
    
    * chore: 彻底移除 xmake,构建链路全部走 mcpp
    
    d2x 改为通用练习框架、构建由 mcpp Provider 承担后,xmake 已无调用方。
    
    删除 11 个 xmake.lua(根 / dslings / dslings/en / solutions 各级)、
    d2x/buildtools/xmake/ 插件、d2x/cpp/common.lua(xmake 侧的语言探测辅助,
    早已被 main.lua 读 .d2x.json 取代)、以及只写着 TODO 的 cmake 适配器占位。
    d2x/buildtools/README.md 一并删除——它描述的 list/build/run 契约已被
    Provider 协议(describe/exercises/check)取代,留着会误导。
    
    .xlings.json 去掉 xmake 3.0.7 的 pin(该版本已从 registry 移除,是 d2x CI
    里那条 "用真 xmake 而非 xlings shim" workaround 的根因),同时去掉 gcc 与
    mingw-w64 —— mcpp 自带工具链沙箱,Windows 侧由它的 MinGW/MSVC 覆盖。
    
    CI 重写:旧流水线只挑 `-ref` 结尾的 xmake target,而 solutions/ 在
    xmake.lua 里被注释掉,grep 返回空、循环全跳过、job 退出 0 —— 实际校验零个
    目标,且第 60 行的 wc -l 对空串仍打印 "Found 1 reference targets" 把空转
    掩盖了。新流水线跑 e2e.sh,断言每个参考答案通过、每个练习不通过,走的是
    `d2x checker` 内部同一条 Provider 路径。
    
    撰稿 skill 同步更新:练习不再需要注册,放进 dslings/<std>/ 即可被目录约定
    发现;per-exercise 编译选项改为练习文件头部的 // d2x:cxxflags: 指令。
    
    复验:Provider 枚举 52 题、端到端 51/51 参考答案通过 0 失败、d2x checker
    全链路正常。
    
    * feat(harness): 判定信号改走侧信道,练习脚手架独立成库
    
    判定原先 100% 是带内信号:断言失败并不改变退出码(实测退出码仍为 0),
    所以只能扫 stdout 找 ❌。这会误判——一个断言全过的正确解答,只要在说明
    文字里打了个 ❌ 就被判失败(已复现)。反过来,输出截断或 Windows 控制台
    代码页不对,判定同样失效。
    
    改为:stdout 回归「给人看」,判定走侧信道 NDJSON。
    
    harness 独立成 mcpp 库包 dslings/harness/,同时提供两条路径:
    
    - #include <d2x/cpp/common.hpp>  宏路径。可见输出与旧版逐字节一致,
      ✅/❌ 的逐条对照是教学的一部分,不动。
    - import d2x.harness;            模块路径。用 std::source_location 自动带
      file/line,比 __LINE__ 更准,正好是 Verdict.diagnostics 需要的东西。
    
    两条路径不等价,这是 C++ 的硬约束而非疏漏:宏无法跨模块导出,所以
    D2X_YOUR_ANSWER 没有模块等价物——它必须展开为空才能制造编译错误。
    模块化章节需要另一套填空约定。
    
    include/ 下保持 d2x/cpp/common.hpp 这个既有路径,104 个练习和书本一行
    不用改;路径改名可以以后单独做,不必和机制改造捆在一起。
    
    生成的 member 清单改用 [dependencies] path 依赖,干掉了
    include_dirs = ["../../.."] 那个把整个仓库根塞进搜索路径的 hack——
    原先练习能 #include 仓库里任何文件。
    
    侧信道逐条追加而非退出时统一写:练习段错误时崩溃前的断言结果照样保留。
    D2X_RESULT_FILE 未设置时 harness 只打印不写文件,学员直接跑二进制零摩擦。
    
    Provider 判定顺序:有 ok:false → Fail 且每条失败转成一个 Diagnostic;
    无失败但有 wait → Blocked;侧信道文件不存在 → 退回「编译通过 + 退出 0」。
    最后一条让 harness 自动变成可选的——纯观察型练习(现有 18 个只用
    D2X_WAIT)可以写成零依赖的纯 C++ 文件,学员能原样拷进 Compiler Explorer。
    
    顺带删掉死代码 d2x_is_invocable(104 个练习中 0 处使用)和坏掉的模块桩
    d2x/mcpp/common.cppm(宏不能跨模块导出,import 进去什么也拿不到)。
    
    e2e.sh 的清理钩子收窄为逐个练习目录:harness 现在也住在 dslings/ 下,
    原先的 `git checkout -- dslings/` 会把开发中的改动一起抹掉(已踩过)。
    
    实测:51/51 参考答案通过;四态判定正确(未完成→fail、参考答案→pass、
    答案对且输出含❌→pass、答案对留路障→blocked);真实断言失败产出带
    行号与期望/实际值的 diagnostics;模块路径与「无 harness 退回退出码」均通过。
    
    * fix: 堵住 id 注入、修复英文答案空转、让教学漂移可被 CI 检测
    
    三个真缺陷,都不是理论风险:
    
    1. 练习 id 注入。id 直接取自文件名,有两个危险去向:d2x 把它拼进 shell
       命令,我们把它写进生成的 TOML([targets.<id>])。带反引号、`]` 或引号
       的文件名在任一处都能越界 —— 对社区课程仓库来说,一个恶意 PR 文件名就
       足以在任何跑 checker 的人机器上执行命令。
    
       在 discovery 源头做白名单校验并拒绝,而不是在两个下游各自转义:这类
       文件名本就是笔误或恶意,与其想办法安全地传递,不如让作者改名。
       实测:`99-evil`touch pwned_marker`.cpp` 被拒绝,命令未执行。
    
    2. e2e.sh 把所有英文参考答案静默 SKIP。前缀剥离顺序错了 —— `${sol#en/}`
       执行时 sol 已经以 "solutions/" 开头,匹配不到任何东西,是个静默 no-op,
       于是每道英文练习都因找不到 solutions/en/... 而跳过。
    
       这正是本脚本头部注释里说要防的那种空转,和旧 CI 一模一样的毛病。
       除了修顺序,另加一道防线:pass==0 时直接判失败,杜绝「0 失败」蒙混。
       实测修复后 en 也是 51/51 真验证(此前是 0 通过 / 52 跳过)。
    
    3. d2x_assert_eq 的日志分支仍用裸 std::to_string,而上报分支已改用
       SFINAE 安全的 show()。std::to_string 没有 std::string / const char* /
       scoped enum 的重载,下一个比较字符串或强类型枚举的练习会直接编译失败 ——
       show() 存在的意义就是避免这个,却只用了一半。
    
    教学漂移(04-rvalue-references):
    
    C++17 起 prvalue 直接初始化目标(保证复制省略),-fno-elide-constructors
    再也无法让 `Object obj = Object();` 产生移动构造。全仓库改按 c++23 编译后,
    这节课的核心观测点被静默抹掉。
    
    改成从具名对象 std::move —— 这在任何标准下都必然调用移动构造。更重要的是
    补了一条 d2x_assert(move_ctor_calls >= 1):漂移之所以能静默发生,正是因为
    从前没有任何断言检查它,输出少一行没人发现。现在它是 CI 可检测的事实。
    
    * fix(dslings): 04-rvalue-references 练习侧同步修复,并给 e2e 加脏树防护
    
    上一次提交只带上了 solutions/ 侧 —— 练习侧的补丁被 e2e.sh 的清理钩子
    还原掉了,我没复查就提交了。
    
    清理钩子会把参考答案覆盖到练习上再还原,所以它天然会吃掉练习目录里未提交
    的改动。这个陷阱已经咬过两次(一次丢了脚手架,一次丢了刚修好的练习),
    所以加一道前置检查:练习目录不干净就拒绝运行,并列出是哪些文件。
    宁可拒绝,也不能悄悄丢掉别人的工作。
    
    * fix(provider): 报错路径改为相对仓库根,协议里仍给绝对路径
    
    学员看到的断言报错原先顶着一长串 /home/... 前缀 —— mcpp 传给编译器的是
    绝对路径,__FILE__ 便是绝对的。生成的清单加上 -fmacro-prefix-map 让它
    相对仓库根,噪声消失。
    
    但协议要求绝对路径:d2x 靠 diagnostics.file 打开编辑器、监听文件变更。
    所以在协议边界上还原成绝对。展示归展示,定位归定位。
    
    * docs: 添加 Provider 与练习脚手架参考(目录约定、判定机制、已知缺口)
    
    * docs: 练习即测试重设计稿(双入口、无宏 harness、mcpp 上游三改动)
    
    * docs: 练习即测试迁移计划(试点先行)
    
    * feat(harness+pilot): 无宏 harness 包 + cpp14 试点迁移(练习即测试链路验证通过)
    
    * feat(provider): 瘦身为 mcpp test JSON 薄壳——清单生成/自建判定/unsetenv workaround 全部删除
    
    * feat: dslings 全量迁移到「练习即测试」布局(104 练习 + 51 答案 + 7 成员工程)
    
    * fix: 迁移清尾——hello-mcpp 教学文本重写+答案、NULL/int8_t/dont_delete_this、harness formattable 探测
    
    * test(e2e): 重写为 mcpp test 驱动——pristine 0-pass + 52/52 答案全绿(zh/en),防线保留
    
    * docs: book/撰稿技能/CI/gitignore 全面同步「练习即测试」布局
    
    * docs(skill): chapter 模板路径同步
    
    * docs: 迁移后参考文档 + 旧文档标记取代 + 计划勾选
    
    * refactor: harness→d2x 库(import d2x)、课程工程收进 src/、日志标识去 HONLY 重设计
    
    * docs: 术语统一(学员→学习者) + 判定顺序注释与实现对齐
    
    * fix: hello-mcpp 恢复未完成态(体验时的通关改动被误提交,pristine 断言抓出) + 参考文档同步新布局
    
    * refactor: Provider 拍平到 d2x/buildtools(去掉冗余的 mcpp 目录层)
    
    * docs: 注释与教学文案专业化(消除口语化表达)
    
    * chore: mcpp pin 0.0.99 -> 0.0.104(测试能力批次已发布,CI 依赖满足)
    
    * chore: d2x pin 0.1.5 -> 2026.07.24.1(协议层分库/稳定性批次已发布)
    
    * docs: 获取与使用对齐 d2x 2026.07.24.1(status/原生模式双入口;d2x update 幽灵命令改为 git 说明;三语 README 快速开始)
    Sunrisepeak authored Jul 23, 2026
    Configuration menu
    Copy the full SHA
    247f7d6 View commit details
    Browse the repository at this point in the history

Commits on Jul 24, 2026

  1. docs+devcontainer: 快速开始重排(在线可用/本地两步走/fork 保存进度),Codespaces 环境修复

    - devcontainer: xlings 升至 v0.4.68;xlings install 加 -y(非交互环境不再挂起);
      postAttach 显式补 PATH;postCreate 预热 Provider,首次进入 checker 不再长时间无反馈
    - README(en/zh/zh.hant): 本地流程拆为 安装 d2x 工具 -> 获取课程(d2x install / git clone 二选一)
      -> 开始练习;新增 fork 后用 git commit/push 保存练习进度的建议
    Sunrisepeak committed Jul 24, 2026
    Configuration menu
    Copy the full SHA
    f165924 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    76b2a36 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    252a11b View commit details
    Browse the repository at this point in the history

Commits on Jul 28, 2026

  1. fix(cpp14): replace d2x.harness with d2x in 00-generic-lambdas exerci…

    …se (mcpp-community#86)
    
    * fix(cpp14): replace d2x.harness with d2x in 00-generic-lambdas exercise
    
    * fix(cpp14): replace d2x.harness with d2x in 00-generic-lambdas exercise
    
    d2x.harness module does not exist in d2x/src/. The exercise import
    was failing at module resolution before reaching any exercise code.
    Changed to import d2x which is the existing module, consistent with
    the exercise template in .agents/skills/d2mcpp-authoring/assets/exercise.cpp.
    lczllx authored Jul 28, 2026
    Configuration menu
    Copy the full SHA
    d0a7fbe View commit details
    Browse the repository at this point in the history

Commits on Aug 1, 2026

  1. sync: 工具链 pin 跟进 — mcpp → 2026.8.1.1,d2x → 2026.08.02.1 (mcpp-communi…

    …ty#87)
    
    * sync: 工具链 pin 跟进 —— mcpp 0.0.104 → 2026.8.1.1,d2x → 2026.08.02.1
    
    mcpp 侧不是升级偏好,是必须:mcpplibs 依赖索引已把 index floor 抬到 0.0.109,
    钉在 0.0.104 的工程一律 E0006「index requires mcpp >= 0.0.109」而拒绝解析依赖。
    d2x 仓库的 CI 因此一度全平台红,并为本课程加了一步「安装前把 pin 对齐」的
    workaround —— 本次同步之后那步就可以撤掉了。
    
    d2x 侧跟到刚发布的 2026.08.02.1:Win10 / Win11 CI(完整测试段 + 以本课程做
    checker 真实冒烟)、Windows 上练习页路径显示修复、Windows 活性超时补齐。
    
    CI 头部注释一并更新:原文只写了「依赖 mcpp >= 0.0.104」,而真实下限已被上游
    抬到 0.0.109,不写清楚下一个人会以为 0.0.104 还能用。
    
    * fix(provider): Windows 上 capture_stdout 的 2>/dev/null 让 mcpp test 根本没跑
    
    Windows 上每道练习都判不出结果,现象是 Provider 报「mcpp test 没有返回
    '<test>' 的记录」,看起来像 mcpp 不支持 --message-format json —— 实际是本仓库
    Provider 自己的问题。
    
    capture_stdout 无条件给命令尾巴上接 ` 2>/dev/null`。Windows 上 _popen 走的是
    cmd.exe,那里没有 /dev/null:cmd 把它当成「重定向到 \dev\null 这个路径」,而
    \dev 不存在,于是直接报
    
        The system cannot find the path specified.
    
    并且整条命令根本不执行。mcpp test 一条 JSON 都没吐,解析侧 saw_any 为假,判定
    链退化成「没有该测试的记录」,那句「mcpp 可能不支持 --message-format json」的
    提示把锅指错了方向。
    
    证据(d2x 的 Win10 / Win11 checker 冒烟实测):
      外层 `mcpp run -q -p d2x/buildtools -- check hello-mcpp` 本身跑得通 —— 说明
      mcpp 在 PATH 上(不在的话 cmd 会报 'mcpp' is not recognized,是另一句话);
      只有内层带 2>/dev/null 的 mcpp test 挂掉。两者唯一的差别就是这个重定向。
    
    空设备在 cmd 下叫 NUL,按平台分开写即可。POSIX 分支拼出的字符串与改前逐字节
    相同,linux 行为不变;本地实测 check hello-mcpp 仍是 stage → output(真实编译
    错误)→ verdict fail。
    Sunrisepeak authored Aug 1, 2026
    Configuration menu
    Copy the full SHA
    f14391a View commit details
    Browse the repository at this point in the history

Commits on Aug 2, 2026

  1. fix(provider): 构建期发心跳,避免冷机首次被 d2x 活性超时误杀 (mcpp-community#88)

    有反馈说 d2x checker 在 Windows 10 上会卡住。除了已修的 cmd.exe 重定向,还有
    一条与平台无关、冷机才撞得到的:
    
      mcpp test --message-format json 在整个构建期一个字节都不产出。
    
    这是实测结论,不是推断 —— 带不带 -q 都一样:stdout 只有末尾那两行 JSON,
    stderr 全空(机器可读模式把人读输出整个收编进 JSON 了)。所以从 d2x 的视角看,
    Provider 从 stage("compile") 之后就彻底沉默,直到构建结束。
    
    冷机第一次要在这段沉默里备工具链与 std 模块。一旦超过 d2x 的活性超时
    (provider_idle_timeout,默认 120s),正常构建会被当成挂死而终止;更糟的是学习者
    改一次文件就重试一次、每次都在同一处被杀,表现为「怎么改都过不去」——
    与「卡住」难以区分。
    
    做法:capture_stdout 把读取交给工作线程(fgets 是阻塞的,单线程在沉默期根本回
    不到我们手里),主线程每 20s 发一条 output 事件。一举两得:持续喂活 d2x 的计时
    器,并让学习者看见首次构建正在进行,而不是对着黑屏干等。
    
    比单纯调大 120s 阈值更对症 —— 阈值调多大都是猜,心跳把「有进展」变成可观测
    事实。runner 保持协议无关:回调由 main.cpp 注入,发射逻辑不下沉。
    
    验证:
    - 心跳会发 —— 临时把间隔设为 0 跑一次,确认 output 事件出现(改回 20s 后
      热构建 0 条,不打扰正常路径)
    - 无回归 —— d2x/buildtools/tests/e2e.sh zh:协议冒烟 52 练习 ✓ /
      pristine 全部保持未通过 ✓ / 52/52 参考答案全部通过 ✓
    Sunrisepeak authored Aug 2, 2026
    Configuration menu
    Copy the full SHA
    32a7a3e View commit details
    Browse the repository at this point in the history
  2. docs+ci: 本地使用优化 + 平台矩阵拆分(linux/macos/win10/win11/win 无 MSVC STL) (mcp…

    …p-community#89)
    
    * docs+ci: 本地上手三步走 + 平台矩阵拆分(linux/macos/win10/win11/win 无 MSVC STL)
    
    README(三语 + book 两语)重写「本地练习环境」段,改成明确的三步:
    
      1. 装工具 —— `xlings install d2x mcpp -y`,两个工具名都链到各自仓库
      2. 取课程并验证环境 —— 默认 `d2x install d2mcpp` → `cd d2mcpp` → `mcpp test`;
         clone 源码那条路收进 <details>,作为可选项而不是与默认路径并列的「二选一」
      3. 开始练习 —— `d2x checker` / `d2x status`
    
    第 2 步把 `mcpp test` 摆到台面上是有意的:练习就是测试,新环境跑一遍
    「全部不通过」既是练习的起点,也已经证明工具链是通的。
    
    CI 从单个 ubuntu job 拆成五档平台矩阵,每档都跑完整两层验证:
    
      linux / macos / windows-10 线(windows-2022)/ windows-11 线(windows-2025)
      / windows 且无 MSVC STL
    
    最后一档把 runner 上的 Visual Studio 藏掉(改名 vswhere.exe 与 VC 目录 +
    清空 VS* 环境变量,并就地检查后置条件),模拟学习者的干净 Windows —— 这
    才是多数人的机器。mcpp 应当自动回落到自带的 winlibs MinGW,产物 target
    目录名(x86_64-windows-gnu)就是断言依据。
    
    两层验证:
      - `mcpp test`(已有 e2e.sh)—— pristine 全不过 + 覆盖答案后全过
      - `d2x checker`(新增 checker-e2e.sh)—— 答案就位后 checker 必须自己走完
        52 道题并退 0
    
    加第二层是因为 checker 在 mcpp test 之上还叠了 Provider 的 NDJSON 协议、
    进度持久化、文件监听三层;这三层断掉时 mcpp test 照样全绿,Windows 上就
    出过这种静默回归(mcpp-community#87)。checker-e2e.sh 的看门狗自己用 shell 轮询实现,
    不依赖 timeout(1)(macOS 默认没有)。
    
    顺带:
    - .xlings.json pin 上抬 —— mcpp 2026.8.1.1 → 2026.8.2.1(裸 Windows 自动
      回落 MinGW 是这个版本才有的能力,无 MSVC STL 那一档依赖它),
      d2x 2026.08.02.1 → 2026.08.02.2
    - 修复文件名核对 job:它还在按迁移前的布局找 `intro/tests cpp*/tests`,
      练习早已搬进 src/,于是一个文件都没扫到、永远绿。现在真的核对 52 对。
    - 工作流触发路径补上 .xlings.json
    
    本地已验:e2e.sh all(zh/en 各 52/52)、checker-e2e.sh zh 与 en 均全过。
    
    * docs(book): chapter_1 补上工具安装与环境验证,与 README 三步对齐
    
    chapter_1 是三份 README 的「更多细节」落点,但它的 §0 只装 xlings,
    接着就直接 `d2x install d2mcpp` —— 一台干净的机器照着做会在第二条命令
    上失败,因为 d2x 这个二进制根本还没装。
    
    补两处,与 README 新的三步保持同一套说法:
    - §0 结尾加 `xlings install d2x mcpp -y`,两个工具名链到各自仓库
    - §1 加「验证环境」小节:`cd d2mcpp` + `mcpp test`,并说明「刚拿到课程
      时全部未通过」既是起点也是工具链已通的证据
    
    * docs: 改掉 step 2 里「每道练习都能编译并运行」这句错话
    
    原话把 `mcpp test` 说成「验证每道练习都能编译并运行」,正好说反了:练习发
    下来就是没做完的,`std:endl`、`D2X_YOUR_ANSWER` 这类东西**必然编不过**,
    pristine 状态下 0 passed 才是对的(e2e.sh 的断言 1 就是在守这条)。
    
    顺带澄清一个容易误会的点:`solutions/` 不是工作区成员(mcpp.toml 的
    members 里没有它),`mcpp test` 从头到尾不碰它。要它变绿得先覆盖到练习
    文件上——那是 CI 的动作,不是学习者跑一条命令就会发生的事。
    
    改成说清楚它到底验了什么:工具链解析成功、d2x 库编译通过、运行器逐题都
    跑到了;练习本身红着是设计如此。README 三语 + book 两语 + chapter_1 两语
    共 7 处同步。
    
    * feat(solutions): 参考答案自己成为一个 mcpp 工程,`mcpp test -p solutions` 直接跑
    
    在此之前 solutions/ 只是一堆躺在磁盘上的 .cpp:不是工作区成员,mcpp 从头到
    尾不认识它。想验证答案对不对,唯一的办法是把 52 个文件覆盖到 src/*/tests/
    上、跑一遍、再 git 还原 —— 一套带副作用、要求工作树干净、只有 CI 脚本会用
    的流程。学习者或贡献者想确认「答案是好的」,没有一条命令可以跑。
    
    现在 solutions/ 是一个正经工程:
    
        solutions/mcpp.toml            name=solutions, c++23, 依赖 d2x
        solutions/tests/<std>/...      52 份答案,就是它的测试
    
    于是:
    
        mcpp test -p solutions          # 52 passed; 0 failed
        mcpp test -p solutions cpp11    # 按子串筛
    
    零副作用、不碰练习目录、任何人随手可跑。布局与练习一一对应,测试名
    (intro/hello-mcpp、cpp11/00-auto-and-decltype/0) 直接对回练习文件。
    配置刻意与练习工程一致(c++23 + d2x),否则「答案能过」推不出「答案放进
    练习里也能过」。
    
    覆盖-还原那套 e2e 保留 —— 它验的是另一件事:答案放到练习的位置上也成立,
    且练习在未完成时确实不通过。两条互补:新的这条挂了说明答案本身是错的,
    旧的那条挂了说明答案与练习对不上。
    
    - e2e.sh 新增 solutions_selftest(),并核对测试条数 == 答案文件数:测试发现
      是按 tests/**/*.cpp 自动扫的,布局一改就可能一个都没扫到,而「0 个测试」
      在 mcpp 眼里同样是 "test result ok"
    - CI 每档平台新增独立一段 `mcpp test -p solutions`,排在覆盖-还原之前,
      失败定位最短
    - e2e.sh / checker-e2e.sh / 文件名核对 job 的路径映射跟随改为 solutions/tests/
    
    * docs: step 2 的环境验证改用 `mcpp test -p solutions`
    
    上一版让 step 2 跑裸 `mcpp test`,然后解释「全红是对的」。这在逻辑上站不住:
    工具链坏掉时也是全红,学习者看着同样的输出,分辨不出是自己还没做题还是环境
    没装好——一个只会红的命令没法用来验证环境。
    
    solutions/ 成为工程之后就有了确定的绿:
    
        mcpp test -p solutions       # 验证环境: 52 份参考答案, 应当全绿
        mcpp test                    # 你的进度表: 练习还没做, 此刻全红
    
    两条命令各自含义明确:第一条绿 = 工具链没问题;第二条红 = 你的起点。
    
    README 三语 + book 两语 + chapter_1 两语同步。chapter_1 里另外写清了答案与
    练习靠 tests/ 相对路径配对,以及 `mcpp test -p solutions cpp11` 的筛选用法。
    
    撰稿技能(.agents/skills/d2mcpp-authoring)的路径与「答案怎么验」也跟随更新:
    新增答案后可以直接 `mcpp test -p solutions <slug>` 自查,不必再走覆盖流程。
    
    * docs: step 2 只留环境验证,进度表挪到 step 3 的可选 note
    
    step 2 摆两条命令、再解释「第一条绿第二条红」,等于在验证环境这一步塞了
    一个当下用不上的概念。step 2 现在只做一件事:
    
        mcpp test -p solutions       # 验证环境: 52 份参考答案, 应当全绿
    
    裸 `mcpp test`(你自己的进度表)本来就属于「不经过 d2x 怎么练」这一类,
    归到 step 3 已有的那条可选 note 里,和 `mcpp test -p src/cpp11` 放一起:
    
        > 不想经过 d2x? 练习就是测试 —— `mcpp test` 打印你的完整进度表(动手前
        > 全红), `mcpp test -p src/cpp11` 只跑某一章。
    
    同步的地方:
    - README 三语 + book 两语:step 2 收敛为一条命令;<details> 里 clone 那条
      路的环境验证也跟着改成 `mcpp test -p solutions`(原来还是裸 mcpp test)
    - chapter_1 两语:「验证环境」节同样只留参考答案那条;裸 `mcpp test` 落到
      已有的「原生模式(可选)」节,作为该节三条命令里的第一条
    Sunrisepeak authored Aug 2, 2026
    Configuration menu
    Copy the full SHA
    6bcf5db View commit details
    Browse the repository at this point in the history
Loading