ARTICLE DETAIL

资讯详情

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

gsd-core ADR-457 迁移第三批次:10 个运行时模块转向严格 TypeScript 源码与 Build-at-Publish 构建流程

gsd-core ADR-457 迁移第三批次:10 个运行时模块转向严格 TypeScript 源码与 Build-at-Publish 构建流程 【免费下载链接】gsd-coreGit. Ship. Done - Core项目地址https://gitcode.com/gh_mirrors/ge/gsd-core点击查看免费下载本文为 gsd-coreGSD Core一个面向 AI 编码代理的元提示与上下文工程系统的运行时类型化工程实践解读围绕 changeset 记录 migration-batch-3-ts.md 描述的第三批次迁移说明 10 个gsd-core/bin/lib运行时模块如何从手写.cjs转为src/*.cts严格 TypeScript 源码、由tsc在发布前编译为 gitignored 的.cjs产物并解释“行为逐字节等价byte-for-behaviour”的工程约束、tsconfig.build.json的编译配置以及本地构建与测试时如何触发编译。读完后你能掌握该项目“源码为真、产物不入库”的完整迁移与构建机制并能在本地复现npm run build:lib的编译链路。一、这一批次做了什么changeset 原文的完整解读migration-batch-3-ts.md 是一个 changeset 变更记录frontmatter 标记type: Changed、pr: 537正文记录了第三批次batch 3迁移的完整范围。原文明言Migrate 10 moreget-shit-done/bin/libruntime modules to TypeScript sources of truth (ADR-457 build-at-publish, batch 3): event, workstream-inventory-builder, plan-scan, fallow-runner, project-root, installer-migration-authoring, update-context, 000-first-time-baseline, runtime-homes, model-catalog.即本批次将以下 10 个运行时模块迁移为 TypeScript 源码为真source of truth模块原文列名迁移后的源码位置eventsrc/observability/event.ctsworkstream-inventory-buildersrc/workstream-inventory-builder.ctsplan-scansrc/plan-scan.ctsfallow-runnersrc/fallow-runner.ctsproject-rootsrc/project-root.ctsinstaller-migration-authoringsrc/installer-migration-authoring.ctsupdate-contextsrc/update-context.cts000-first-time-baselinesrc/installer-migrations/000-first-time-baseline.ctsruntime-homessrc/runtime-homes.ctsmodel-catalogsrc/model-catalog.cts上述 10 个.cts源文件均已确认存在于当前仓库的src/目录中其中event位于src/observability/子目录、000-first-time-baseline位于src/installer-migrations/子目录说明源码树按职责保留了子目录分层。changeset 正文的后半句是本次迁移的核心约束Each moves tosrc/*.cts(strict TS), compiled bytscto a gitignored.cjsat the samerequire()path; behaviour preserved byte-for-behaviour.拆解为三点工程承诺迁移目标每个模块进入src/并以.cts扩展名承载严格 TypeScriptstrict: true构建方式由tsc编译为.cjs且产物被 gitignore不进入版本库落点不变编译产物输出到与原手写文件相同的require()路径即gsd-core/bin/lib/下同名.cjs因此所有通过require()消费这些模块的调用方完全无感行为等价“byte-for-behaviour” 表示迁移前后运行时行为必须逐点保持一致——这是一次纯源码形态的重构而非功能变更。changeset 末尾还附有一条docs-exempt注释说明理由这是 ADR-457 build-at-publish 的内部源码迁移产物在相同require()路径上行为等价、且不入库对用户无任何可见变化no user-facing change因此豁免用户文档更新要求。这一自我标注本身就体现了该仓库对“哪些变更需要对外说明”的严格分级。二、决策背景ADR-457 的 build-at-publish 模型本批次是 ADR-457Generation model for bin/lib/*.cjs type safety状态 Accepted落地过程中的一环。理解 ADR-457 的决策逻辑才能理解 changeset 中“gitignored .cjs”“同一 require() 路径”这些措辞的由来。2.1 问题起点类型安全是“二等公民”ADR-457 的 Context 部分核实了当时的仓库真实现状gsd-core/bin/lib/下有 84 个.cjs文件其中只有 1 个带// generated头package-identity.cjs且它是由脚本“烘焙值”生成的不是tsc产物没有 TS 源码树、没有 TS→CJS 转译管线。手写运行时表面的类型错误只能以 lint 发现项的形式若被发现浮现而不是编译错误。2.2 关键辨析两种都被叫作“生成”的技术ADR-457 指出决策的分水岭在于区分两种技术值烘焙value baking已存在且是被迫的package-identity.cjs必须生成因为安装后的目录树里不存在携带.name的package.json运行时根本读不到这些值只能在构建期烘焙进 CJS 模块。删除生成器复杂度会在每个消费方重新出现——这是一个“深接缝”deep seam。转译transpilation本迁移采用的把bin/lib逻辑用 TS 编写、经tsc输出.cjs。删除它不会让任何复杂度回归——手写.cjs与tsc输出的.cjs在运行时行为相同它的价值全部在于编写期与 CI 的类型检查。因此package-identity不构成转译工作的前例两者是不同的技术、不同的强制因素。2.3 三种生成模型的取舍与最终决策ADR-457 围绕“生成的.cjs是否入库”给出三个模型源码与产物双双入库——制造“两份必须一致”的永久不变量需要 parity 测试、双提交、预提交/CI 漂移门禁对转译而言没有任何东西迫使其成立代价最大。Build at publish推荐被采纳bin/lib/*.cjs成为 gitignored 构建产物由tsc从 TSsrc/树输出npm 发布构建后的输出。ADR 特别论证了可行性package.json的files数组本就携带gsd-core与scripts且已有prepublishOnly预发布构建步骤.cjs输出挂入同一链路即可npm pack包含磁盘上的产物与.gitignore无关。Build at install——被拒跨 Node 版本与平台脆弱CONTEXT.md 记录了 Windows / Node 24 的隐患且拖慢每次安装。最终决策要点见 docs/adr/457-generated-cjs-single-source.md 的 Decision 节通过 TSsrc/树 tsc编译追求类型安全采用模型 2build at publishTS 源码是唯一真源.cjs是 gitignored 产物——“这消解了漂移治理机制而不是建立它”值烘焙保持独立package-identity.cjs继续以提交入库的烘焙产物形式存在渐进迁移从耦合最低的模块开始先以一个试点 PR 建立src/树与构建接线再做批量迁移先把 lint 配置与现实对齐12 条GENERATED_CJS_IGNORES名单实际指向手写文件属“谎言”再逐步接入类型感知 lint。本 changeset 所属的“batch 3”正是第 3 条“渐进迁移”策略推进到第三批的产物每一批继续“10 more”源码与产物按模块逐一换轨。2.4 ADR 的代价与后果ConsequencesADR-457 明确记录的正面/负面后果直接解释了仓库现状正面迁移后的运行时代码可应用类型感知的typescript-eslint规则因为不提交生成的.cjs没有漂移不变量、没有parity 测试要维护新bin/lib代码有了唯一被强制的答案写 TS。负面编辑src/*.cts与运行bin/lib/*.cjs之间现在隔着一个构建步骤本地开发与 CI 都必须在运行前构建迁移会触及大量文件可能暴露潜在类型错误今天直接读取 checkout 中bin/lib/*.cjs的工具必须先构建。对测试导入bin/lib/*.cjs的测试只有在构建已运行时才有效因此测试命令必须依赖构建——这是相对“.cjs恒在树中”的旧状态最主要的行为变化。这一条“测试依赖构建”正是当前仓库package.json中pretest脚本存在的直接原因见下一节。三、构建管线实证编译配置、npm 脚本与 gitignore3.1tsconfig.build.json发布编译的完整配置编译产物由 tsconfig.build.json 驱动其文件头注释直接声明了归属ADR-457 build-at-publish: compile TS runtime sources in src/ to gitignored .cjs artifacts under gsd-core/bin/lib/. Source uses the .cts extension so tsc emits .cjs natively. As modules migrate, they move from hand-written bin/lib/.cjs into src/.cts here.关键编译选项如下可对照原文逐项核实选项取值含义rootDir/outDirsrc→gsd-core/bin/lib源码树与产物目录的映射关系保证编译输出落在原require()路径module/moduleResolutionnodenext按 Node 的模块解析规则处理 ESM/CJS 互操作target/libES2022含ES2025.RegExp运行时目标与正则能力上限stricttrue严格 TypeScript对应 changeset 中的 “strict TS”esModuleInteroptrue解决 ADR 开放问题中提到的 CJS 互操作__importDefaultshimnoEmitOnErrortrue类型错误时拒绝产出防止带错产物进入发布包declaration/sourceMapfalse不产出类型声明与 sourcemap保持产物面最小incremental/tsBuildInfoFiletrue/tsconfig.build.tsbuildinfo增量编译加速重复构建includesrc/**/*.cts只编译.cts源文件其中.cts扩展名是一个值得注意的细节在 Node 的nodenext语义下.cts文件按 CommonJS 解释tsc对其原生输出.cjssrc/a/b.cts→ 产物a/b.cjs无需任何重命名步骤即可维持“同一require()路径”。3.2 编辑器/CI 类型检查与发布构建的双 tsconfig 分工tsconfig.json 只有 8 行通过extends复用tsconfig.build.json并覆盖noEmit: trueinclude同为src/**/*.cts。其头部注释说明了分工Default editor/CI typecheck config. The emitting publish build stays in tsconfig.build.json.也就是说日常在编辑器或 CI 中做类型检查时用tsconfig.json只检查、不产出真正发布时产出.cjs的编译留在tsconfig.build.json。这正对应 ADR-457 决策第 5 条“随着模块转为 TS把类型感知 lint 接入真实的tsconfig.json”。3.3 npm 脚本链路构建何时触发package.jsonpackage.json中的相关脚本构成完整的触发链build:lib第 104 行tsc -p tsconfig.build.json—— 编译src/*.cts到gsd-core/bin/lib/*.cjs的核心命令prepare第 116 行npm run build:lib——npm install后自动构建保证从源码安装也能得到产物pretest第 119 行npm run build:lib npm run lint:skill-deps——测试前强制先构建落实 ADR-457 “测试命令必须依赖构建”的后果条款prepublishOnly第 118 行npm run build:lib npm run build:hooks—— 发布前编译产物npm 打包时npm pack会包含磁盘上这些未被 git 跟踪的.cjs文件build第 102 行聚合命令首段generate:identity对应的是 ADR-457 保持独立的值烘焙链路node scripts/generate-package-identity.cjs后接build:lib与各生成器。3.4.gitignore产物清单随迁移批次增长.gitignore 中有一整段 ADR-457 专用注释与逐条条目ADR-457 build-at-publish: TS-generated runtime artifacts (compiled from src/*.cts bynpm run build:lib). Source of truth is src/; these are emitted, never edited. Published via prepublishOnly; built before test via pretest. Grows as modules migrate.其下逐个列出gsd-core/bin/lib/*.cjs条目如mcp-server.cjs、state-io.cjs、model-adapter.cjs等并保留了带 issue 编号的迁移注记如# #2657: ADR-457 migration gap — these seven … never got a .gitignore entry when their modules moved into src/*.cts。这段注释“Grows as modules migrate”直接印证每完成一批模块迁移就在.gitignore增加对应产物条目——第三批次本 changeset 所记的 10 个模块即属于此增长过程。产物文件因此处于“磁盘存在、git 不跟踪”的状态与 changeset 中 “gitignored.cjs” 的表述完全一致。四、“同一 require() 路径”与“行为等价”意味着什么这两点是本批次对下游零影响的根基可从仓库结构直接验证路径映射由rootDir/outDir保证src为根、gsd-core/bin/lib为输出意味着src/model-catalog.cts编译为gsd-core/bin/lib/model-catalog.cjs、src/installer-migrations/000-first-time-baseline.cts编译为gsd-core/bin/lib/installer-migrations/000-first-time-baseline.cjs。目录层级与文件名在编译中一一对应消费方require(../lib/model-catalog)之类的调用无需任何改动。行为等价是验收标准而非口号changeset 以 “behaviour preserved byte-for-behaviour” 收尾与 ADR-457 对转译的定性一致“手写.cjs与tsc输出的.cjs在运行时行为相同”。因此本批次不需要新的用户文档docs-exempt注释也不需要 parity 测试——ADR 明确拒绝了模型 1 那种“双份必须一致”的机制类型检查与构建成功本身就是守门人。严格 TS 带来的增量价值迁入src/的模块从此受strict: true约束tsconfig.build.json并可通过noEmitOnError: true在构建期阻断类型错误进入发布包——这正是 ADR-457 所述“编写期与 CI 类型检查”价值的具体兑现。从源码结构看src/目录现已容纳大量.cts模块state.cts、phase.cts、install-engine.cts等且.gitignore的产物条目远多于本批次的 10 个可以推断第三批次前后还有多批模块相继完成迁移src/树正在逐步取代手写的bin/lib/*.cjs直至 ADR-457 规划的“最后一个手写.cjs消失”时退役tsconfig.lint.json。五、本地复现如何查看、构建与验证这批迁移产物当前仓库运行环境要求 Node24.0.0、npm10.0.0见 package.json 的engines字段。在源码 checkout 下# 1. 仅类型检查不产出文件使用 tsconfig.json 的 noEmit 配置 npx tsc -p tsconfig.json --noEmit # 2. 编译 src/*.cts - gsd-core/bin/lib/*.cjs使用发布构建配置 npm run build:lib # 等价于tsc -p tsconfig.build.json # 3. 直接跑测试——pretest 会先自动执行 build:lib npm test验证本批次成果的具体做法确认 10 个源码文件存在于src/逐一对照 src/observability/event.cts、src/workstream-inventory-builder.cts、src/plan-scan.cts、src/fallow-runner.cts、src/project-root.cts、src/installer-migration-authoring.cts、src/update-context.cts、src/installer-migrations/000-first-time-baseline.cts、src/runtime-homes.cts、src/model-catalog.cts执行npm run build:lib后检查gsd-core/bin/lib/下是否生成同名.cjs如gsd-core/bin/lib/model-catalog.cjs并确认这些产物不在 git 跟踪中对应 .gitignore 的 ADR-457 条目段检查tsconfig.build.tsbuildinfo生成增量编译标记它同样被 gitignore 忽略。需要注意的限制由于.cjs是构建产物而非提交文件直接克隆仓库而未执行构建时gsd-core/bin/lib/下的这批.cjs可能不存在任何依赖它们的工具测试、本地脚本必须先跑npm run build:lib或依赖prepare/pretest钩子自动构建。这正是 ADR-457 “Consequences → For testing” 一节预判的唯一主要行为变化。六、小结migration-batch-3-ts.md 这份简短的 changeset 背后是 gsd-core 一项系统性的工程决策按 ADR-457 的 build-at-publish 模型将gsd-core/bin/lib手写运行时模块渐进迁往src/*.cts严格 TypeScript 源码tsc按 tsconfig.build.json 的rootDir: src→outDir: gsd-core/bin/lib映射产出 gitignored 的.cjsrequire()路径与运行时行为保持不变。第三批次完成的 10 个模块event、workstream-inventory-builder、plan-scan、fallow-runner、project-root、installer-migration-authoring、update-context、000-first-time-baseline、runtime-homes、model-catalog是该策略“最低耦合模块先行、逐批推进”执行方式的一个可验证切片而pretest/prepublishOnly脚本链与.gitignore中随批次增长的产物条目则是该策略在仓库中的持久化证据。对贡献者而言实践规则只有一条新运行时逻辑写进src/并以.cts承载编译与发布交给npm run build:lib链路不再手写bin/lib下的.cjs。赞分享【免费下载链接】gsd-coreGit. Ship. Done - Core项目地址https://gitcode.com/gh_mirrors/ge/gsd-core点击查看免费下载相关推荐gsd-core 的 TypeScript 单源迁移ADR-457 下第 10 批 9 个命令路由模块从手写 CJS 到 build-at-publish 的落地gsd core 的 TypeScript 单源迁移ADR 457 下第 10 批 9 个命令路由模块从手写 CJS 到 build at publish 的gsd-core 的 ADR-457 build-at-publish 迁移从手写 CJS 到 TypeScript 单一事实源的批次化落地gsd core 的 ADR 457 build at publish 迁移从手写 CJS 到 TypeScript 单一事实源的批次化落地 本文基于 gsdgsd-core ADR-457 TypeScript 源码迁移实录10 个运行时模块从手写 CommonJS 到 tsc 构建产物gsd core ADR 457 TypeScript 源码迁移实录10 个运行时模块从手写 CommonJS 到 tsc 构建产物 本篇以归档 change上一篇SQLite-GUI 开源项目常见问题解决方案下一篇【亲测免费】 UxPlay 项目常见问题解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表