ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

gsd-core 修复实战:`init.milestone-op` 与 `roadmap.analyze` 的 Workstream 作用域解析修复(PR 3196)

gsd-core 修复实战:`init.milestone-op` 与 `roadmap.analyze` 的 Workstream 作用域解析修复(PR 3196) 【免费下载链接】gsd-coreGit. Ship. Done - Core项目地址https://gitcode.com/gh_mirrors/ge/gsd-core点击查看免费下载本指南围绕 gsd-core 仓库中的变更记录文档 fix-3196-workstream-milestone-op.md 展开。该文档记录了一次真实 Bug 修复PR 3196类型Fixed在启用 Workstream工作流分支的项目中init.milestone-op与roadmap.analyze两个命令处理器此前会从错误的根级.planning/目录读取数据导致phase_count: 0进而误报All phases complete — Nothing left to do。读完本文你将掌握 gsd-core 中 Workstream 作用域的三级解析优先级--ws标志 →GSD_WORKSTREAM环境变量 →.planning/active-workstream指针文件、两个命令的修复前后行为差异以及如何基于源码验证与规避此类作用域错配问题。一、问题背景Workstream 作用域与错误的.planning/目录gsd-core 的规划数据默认存放在仓库根目录的.planning/目录下。当启用Workstream工作流分支时规划数据被隔离到嵌套的作用域目录中其物理路径由 planning-workspace.cts 中的planningDir()计算cwd/.planning/ # 根级规划目录planningRoot cwd/.planning/project/ # GSD_PROJECT 作用域 cwd/.planning/project/workstreams/ws/ # Workstream 作用域GSD_WORKSTREAM从源码可见planningDir()优先读取GSD_PROJECT环境变量默认取process.env[GSD_PROJECT]?.trim()再读取GSD_WORKSTREAM环境变量resolveEnvWorkstream()planning-workspace.cts并严格拒绝包含/、\或..的非法路径段。也就是说一旦环境变量指向某个 Workstream所有规划读取都必须落在workstreams/ws/目录内。PR 3196 修复的 Bug 正发生在这里init.milestone-op与roadmap.analyze两个处理器在统计阶段数时使用了未经作用域解析的根级.planning/目录。当仓库启用了 Workstream 时真实的阶段目录位于workstreams/ws/phases/而处理器却从根级.planning/phases/读取——结果自然读到空目录得到phase_count: 0最终触发误导性的退出信息All phases complete — Nothing left to do。二、修复内容两个处理器统一接入 Workstream 解析变更记录原文fix-3196-workstream-milestone-op.md将修复描述为Workstream resolution ininit.milestone-opandroadmap.analyze— both handlers now respect the--wsflag,GSD_WORKSTREAMenv, and the.planning/active-workstreamfile; workstream-scoped repos no longer exit with All phases complete — Nothing left to do due tophase_count: 0caused by reading from the wrong (root).planning/directory.两个处理器现在都尊重--ws标志、GSD_WORKSTREAM环境变量以及.planning/active-workstream文件启用 Workstream 的仓库不再因为从错误的根级.planning/目录读取导致phase_count: 0而退出 All phases complete — Nothing left to do。2.1init.milestone-op作用域感知的阶段统计init.milestone-op的入口在 init.ctsfunction cmdInitMilestoneOp(cwd: string, raw: boolean): void { const config loadConfig(cwd); const milestone milestoneRecord(cwd); let phaseCount 0; let completedPhases 0; const phasesDir path.join(planningDir(cwd), phases); // ← 关键修复点 ...planningDir(cwd)在未显式传入ws参数时会自行从GSD_WORKSTREAM环境变量解析作用域见 planning-workspace.cts。因此修复后phasesDir会正确指向workstreams/ws/phases/。随后处理器从ROADMAP.md当前里程碑标题段中提取Phase N:标题extractCurrentMilestone排除哨兵阶段号isSentinelPhaseId并对照磁盘上的阶段目录listAllPhaseDirs与阶段摘要文件listPhaseSummaryFiles统计phase_count与completed_phases——全部在正确的作用域内完成。2.2roadmap.analyze作用域感知的里程碑/阶段枚举roadmap.analyze的实现位于 roadmap.ctsfunction cmdRoadmapAnalyze(cwd: string, raw: boolean): void { const roadmapPath planningPaths(cwd).roadmap; ... const { value: content, scope } extractCurrentMilestoneScoped(rawContent, cwd); const phasesDir planningPaths(cwd).phases; ...planningPaths(cwd)同样是 Workstream 感知的路径解析与planningDir同源保证ROADMAP.md与phases目录均定位到当前作用域。修复还配套了 #3165 的恢复逻辑当作用域扫描窗口为空且磁盘上确实存在阶段目录时会剥离已发布里程碑重新扫描stripShippedMilestones把静默的 0升级为带标记的、可区分的非零结果避免phase_count: 0与真正空的里程碑无法区分。三、作用域解析的完整链路三级优先级变更记录提到的三个解析来源--ws、GSD_WORKSTREAM环境变量、.planning/active-workstream文件并非并列而是有严格优先级。核心实现在 active-workstream-store.cts 的resolveActiveWorkstream()if (parsed.value) { // 1. CLI --ws 标志最高优先级 ws parsed.value; source parsed.source ?? cli; } else if (env[GSD_WORKSTREAM] 非空) { // 2. GSD_WORKSTREAM 环境变量 ws env[GSD_WORKSTREAM].trim(); source env; } else { // 3. 存储的活动工作流指针 ws getStored(cwd) || null; // .planning/active-workstream source ws ? store : none; }解析结果随后通过applyResolvedWorkstreamEnv()active-workstream-store.cts回写到GSD_WORKSTREAM环境变量使下游所有planningDir/planningPaths读取都能拿到一致的作用域。这正是修复前读错目录与修复后正确解析的分水岭只要任一环节CLI 标志、环境变量、指针文件解析出了 Workstream 名就必须让所有路径计算看到它。3.1--ws标志的两种书写形式parseCliWorkstream()active-workstream-store.cts支持两种写法--wsmy-workstream # 等号形式 --ws my-workstream # 空格分隔形式解析器还会把--ws及其值从参数列表中剥离只把剩余参数传给下游处理器。3.2 指针文件的写入与自愈.planning/active-workstream指针由setActiveWorkstream()写入active-workstream-store.cts它先校验名称合法性isValidActiveWorkstreamName仅允许字母、数字、连字符、下划线、点再创建workstreams/ws/目录并写入名称。读取侧resolveFromChain()active-workstream-store.cts实现了自愈语义当指针指向的名称无效或目录已不存在时getActiveWorkstream()会自动清空该指针selfHeal true而只读的peekActiveWorkstream()如状态栏 hook 使用则绝不清空指针避免渲染副作用污染跨会话状态。四、作用域错配的典型症状与排查方法修复前启用 Workstream 的仓库会遇到以下症状症状根因阶段明明存在却输出phase_count: 0从根级.planning/phases/读取而非workstreams/ws/phases/误报All phases complete — Nothing left to dophase_count: 0触发了全部完成的退出判定roadmap.analyze返回空 phases 列表extractCurrentMilestoneScoped作用域窗口与磁盘目录不一致排查时可依次确认三件事当前是否处于 Workstream 作用域查看环境变量GSD_WORKSTREAM以及.planning/active-workstream文件内容规划目录是否被正确解析对照 planning-workspace.cts 的planningDir()公式确认phasesDir落在workstreams/ws/下阶段目录是否真实存在检查workstreams/ws/phases/下是否有阶段目录及对应的summary文件listPhaseSummaryFiles是completed_phases的判定依据。从源码结构看仓库还为作用域解析提供了完整的测试支撑如active-workstream-store.unit.test.cjs、active-workstream-store.test.cjs涉及指针自愈、会话隔离、链式回退等边界场景可作为回归验证的参考。五、总结PR 3196 是一次典型的作用域解析缺失修复两个命令处理器在统计阶段数时绕过了 Workstream 作用域解析直接从根级.planning/读取数据导致phase_count: 0与误导性退出信息。修复的关键在于让init.milestone-op与roadmap.analyze统一走planningDir/planningPaths的作用域感知路径并完整遵循--ws→GSD_WORKSTREAM→.planning/active-workstream的三级优先级。对于 gsd-core 的开发者而言这一案例说明任何涉及规划数据读取的命令都必须先解析 Workstream 作用域再定位.planning/下的子目录否则就会静默读取错误数据。赞分享【免费下载链接】gsd-coreGit. Ship. Done - Core项目地址https://gitcode.com/gh_mirrors/ge/gsd-core点击查看免费下载相关推荐JuiceFS 容器化部署实战Docker 卷插件与容器内挂载两种方案详解JuiceFS 容器化部署实战Docker 卷插件与容器内挂载两种方案详解 本文介绍在 Docker 环境中使用 JuiceFS 分布式 POSIX 文件系统gsd-core 更新检查修复解析scoped 包名 opengsd/gsd-core 与 update_available 的正确实现gsd core 更新检查修复解析scoped 包名 opengsd/gsd core 与 update_available 的正确实现 导读 本文以 .cVitest includeTaskLocation 配置详解为任务注入源码定位并启用按行号过滤测试Vitest includeTaskLocation 配置详解为任务注入源码定位并启用按行号过滤测试 includeTaskLocation 是 Vitest上一篇如何快速实现Vue3项目打印功能vue3-print-nb插件的终极指南 下一篇如何快速搭建多人协作表格EtherCalc开源神器让团队协作效率飙升创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表