IPTVnator 仓库技能契约与实现同步:发布公共提取、Stalker 剧集身份与作用域定位迁移实战 📅 发布时间:2026/9/17 20:59:48 👁 浏览次数: IPTVnator 仓库技能契约与实现同步发布公共提取、Stalker 剧集身份与作用域定位迁移实战【免费下载链接】iptvnator:tv: Cross-platform IPTV player application with multiple features, such as support of m3u and m3u8 playlists, favorites, TV guide, TV archive/catchup and more.项目地址: https://gitcode.com/GitHub_Trending/ip/iptvnator本文基于 IPTVnator 仓库中一份完整的实施计划文档 repository-skills-implementation-sync 展开讲清它如何用 11 个严格有序的任务把八份仓库技能Skills与真实实现对齐为发布流程增加“公共正文提取”模式过滤内部备注、以父级作用域剧集 ID 和“先保存后清除”的迁移策略修复 Stalker 播放进度身份缺陷、并用一个零依赖的 Node.js 验证器把技能文档的格式契约变成可执行的机械检查。读完后你将掌握这条“文档即契约、验证即门禁”的工程化方法论以及仓库中对应的可复制命令与源码落点。计划总览三条独立可测的工作流计划的目标Goal是让 IPTVnator 的八份仓库技能与当前实现同步从公开发布正文中过滤内部备注并在不丢失旧版进度数据的前提下修复 Stalker 系列标志series flag与播放位置身份playback-position identity缺陷。其架构Architecture决策是把工作拆成三条互相独立可测的工作流发布输出与指引发布过滤是一个“附加式”的公共提取模式additive public-extraction mode不改变完整 CHANGELOG 的写入行为Stalker 本地兼容性使用“系列作用域 IDseries-scoped IDs 显式旧版别名legacy alias”而非破坏式重写技能/文档维护把机械化的技能约束做成一个小型的零依赖验证器dependency-free validator。技术栈为Node.jsnode:test、GitHub Actions YAML、Angular 21 signals 与 standalone services、TypeScript、Jest、Nx以及 Markdown 技能与架构文档。执行顺序与提交边界计划定义了 11 个任务并要求严格编号顺序、串行执行引导Bootstrap并锁定工作区建立行为基线增加公共发布提取--public模式接线发布工作流并同步发布指引规范化所有 Stalker 系列标志判断为懒加载 VOD 剧集引入父级作用域 ID对账并迁移旧版 Stalker 播放位置发布 Stalker 兼容性契约发布说明 架构文档增加仓库技能的机械验证刷新 Nx 与 SQLite 技能/文档刷新主题、UI、Xtream、Stalker 技能/文档运行八组技能应用场景与完整验证阶梯。其中有一个关键的并发约束值得注意任务 5 与任务 6 必须由同一个执行者worker完成因为任务 6 会消费任务 5 故意“先不提交”的接口变更——任务 5 修改了mapVodSeriesEpisodes的公共签名如果单独提交任何中间状态都会使项目级检查失效。计划明确禁止并行编辑、测试、暂存或提交多个 worker 共享同一个文件系统、Git 索引和HEAD。只读审计可以并行但每个任务的实现与提交必须完成后才能开始下一个。基线建立Task 1的实际落点任务 1 是典型的“先证明现状是绿的”步骤确认分支agent/skill-implementation-sync干净然后运行pnpm install --frozen-lockfile pnpm nx show projects并记录三处行为基线当时必须全部通过node --test --test-reportertap tools/release/release-notes.test.mjs pnpm exec jest \ --config libs/portal/stalker/data-access/jest.config.ts \ --runInBand \ libs/portal/stalker/data-access/src/lib/stalker-series.adapters.spec.ts pnpm exec jest \ --config libs/portal/stalker/feature/jest.config.ts \ --runInBand \ libs/portal/stalker/feature/src/lib/stalker-catalog-facade.service.spec.ts期望的 Nx 项目发现结果包含release-tools、portal-stalker-data-access、portal-stalker-feature、shared-interfaces、web与web-e2e。计划同时要求对照设计文档 2026-07-29-repository-skills-implementation-sync-design.md 做交叉核对保证实施不偏离设计。工作流一从公开发布正文中过滤内部备注问题背景CHANGELOG 与 GitHub 发布正文的边界IPTVnator 的发布流程中.changes/*.md笔记先被pnpm run release:notes:changelog汇总进CHANGELOG.md然后 tag 构建作业从 CHANGELOG 中提取该版本的正文写入 GitHub 发布。问题在于type: internal的备注记录的是对用户不可见的维护性工作它们应当折叠在 CHANGELOG 里但不应出现在面向用户的公开 GitHub 正文中。实现精确块匹配的公共提取计划Task 2在 extract-changelog-section.mjs 中增加了“整块精确匹配”的公共提取。该文件当前实现与计划完全一致核心是一个专门匹配“内部变更折叠块”的正则L27-L28const INTERNAL_DETAILS_BLOCK /(?:^|\n\n)details\nsummaryInternal changes\/summary\n\n[\s\S]*?\n\n\/details(?\n\n|$)/g;这个正则的设计要点它要求块的精确形状——以空行起始、details紧跟summaryInternal changes/summary、以空行结尾。因此一个名为 “Migration guide” 的其他details块即使内部出现 “Internal changes” 字样也不会被误删。这正是测试用例“preserves unrelated details blocks”要证明的契约。在此之上的三个导出函数L72-L140构成了一条清晰的边界链export function extractPublicSection(changelog, version) { const section extractSection(changelog, version); return section null ? null : section.replace(INTERNAL_DETAILS_BLOCK, ).trim(); } export function parseExtractArguments(args) { const publicFlagCount args.filter( (argument) argument --public ).length; const positional args.filter( (argument) argument ! --public ); if ( publicFlagCount 1 || positional.length ! 1 || !/^\d\.\d\.\d$/.test(positional[0]) ) { return null; } return { version: positional[0], publicOnly: publicFlagCount 1, }; }runExtractorCli(changelog, args)则返回{ exitCode, stdout, stderr }把 CLI 行为变成纯函数以便测试。它的退出码契约是退出 2参数非法空参数、非x.y.z裸 semver、重复--public、多余位置参数stderr 输出Usage: extract-changelog-section.mjs [--public] version退出 1找不到该版本章节附详细诊断提示先跑pnpm run release:notes:changelog或 raw 模式下章节为空退出 0 且 stdout 为空公共模式下版本正文只含内部块——这是有意设计的行为一个纯内部维护版本可以没有人工撰写的公开文本。最后main()被重构成薄适配器读取CHANGELOG.md、调用runExtractorCli、把结果写回对应流并设置process.exitCode同时保留import.meta.url守卫使测试可以导入模块而不触发 CLI 副作用。计划的测试部分要求先把describe(extractSection)内的共享 fixture 提升到模块作用域再新增四条extractPublicSection契约测试混合发布剔除内部块、纯公共发布原样保留、纯内部发布返回空串、无关 details 块保留与三条 CLI 契约测试。测试文件 release-notes.test.mjs 中这些套件均已存在如 L886 的describe(extractPublicSection)。值得注意的是计划还额外要求导出runExtractorProcess以覆盖“真实进程读取 CHANGELOG”的路径——当前实现L142-L148已包含它。工作流接线与发布指引同步Task 3Task 3 用“契约测试驱动 YAML 修改”的手法接线工作流先在测试中断言 build-and-make.yaml 包含extract-changelog-section.mjs --public ${VERSION}验证 RED再修改工作流。当前仓库第 1452 行即为落地结果BODY$(node tools/release/extract-changelog-section.mjs --public ${VERSION})同时该 YAML 文件被加入release-tools:test的 inputs使工作流变更会正确失效测试缓存。更深层的同步发生在技能与文档层面。计划给出了release-notes与release-cut两份技能SKILL.md的完整目标文本要点包括release-notes技能每个用户可见变更对应一个.changes/area-slug.md文件type取值breaking、feature、fix、perf、internalinternal记录不可见维护折叠保留在 CHANGELOG但被省略出博客与人工撰写的公开 GitHub 正文GitHub 自动生成的 commit 列表可能仍提及底层提交门禁自动豁免 website、E2E 与 mock-server 应用、*.spec.{js,ts}、*.e2e.{js,ts}、快照、任何/testing/路径和 Markdown验证命令为pnpm run release:notes:validaterelease-cut技能完整的发布预检干净 master、裸 semver、tag 不存在、CI 绿、笔记通过校验、生成步骤改版本号、pnpm run release:notes:changelog、minor 版本跑release:notes:blog、对 mock 服务器截图、node tools/release/build-release-notes.mjs --consume作为破坏性边界、推送规则只推目标分支与 taggit push --atomic永不使用宽泛的git push --tags、以及 tag 构建的副作用清单draft 发布、macOS/Windows/DEB/RPM/Pacman/AppImage/Snap/Flatpak 资产、updater 元数据、blockmap、linux-frame-copy-runtime-sources.tar.xz发布后自动验证 Snap 资产并上传edge。验证步骤包含两个机械化镜像检查——.codex与.claude两份技能副本必须字节级一致cmp -s .codex/skills/release-cut/SKILL.md .claude/skills/release-cut/SKILL.md cmp -s .codex/skills/release-notes/SKILL.md .claude/skills/release-notes/SKILL.md ! rg -n ^[[:space:]]*git push .*--tags .codex/skills/release-cut/SKILL.md .claude/skills/release-cut/SKILL.md当前仓库结构与之一致.claude/skills 下只有release-cut与release-notes两个镜像而 .codex/skills 下有全部八份技能。工作流二Stalker 系列标志规范化与剧集身份作用域化缺陷根因is_series的三值契约Stalker 门户 API 返回的is_series字段在不同门户间形态不一布尔true、数字1、字符串1。原实现中目录门面catalog facade只对1和1做直接比较遗漏了布尔形态——这意味着某些门户返回is_series: true时VOD 剧集会被当成普通电影处理进度语义随之错误。Task 4 的修复策略是单一规范器所有is_series决策统一走isStalkerSeriesFlag它只接受true、1、1三种形态。该助手在 stalker-vod.utils.ts 中被导出复用测试则用参数化用例锁定契约it.each([true, 1, 1] as const)( selects a VOD series when is_series is %p, (isSeries) { const service TestBed.inject(StalkerCatalogFacadeService); service.selectItem({ id: 42, name: Boolean Series, is_series: isSeries }); expect(store.setSelectedItem).toHaveBeenCalledWith( expect.objectContaining({ id: 42, is_series: true }) ); } );计划同时用反向搜索确保没有残留的裸判断! rg -n is_series\s*|String\(.*is_series|!selectedItem\.is_series libs/portal/stalker日志与保值序列化仍允许提及is_series只是不能再用它做决策。Task 7 进一步在 stalker-item.normalizer 的共享规范器上补契约测试与文档注释——明确这是“对已正确实现的共享层的锁定”而不是在shared-interfaces里重复 feature 层的修复。父级作用域剧集 ID解决跨剧撞号第二个缺陷更隐蔽懒加载 VOD 系列的剧集跟踪 ID 原先只由vod_${seasonKey}_${episodeNum}哈希得到。两部不同的剧父系列 ID100与200各自有 S01E01会得到相同的跟踪 ID——播放进度在两部剧之间互相污染。Task 5 的方案是在 stalker-series.adapters.ts 中引入显式映射契约。当前源码L45-L86与计划一致export interface MapVodSeriesEpisodesOptions { parentSeriesId: string | number; fallbackPoster?: string; } export interface StalkerMappedEpisode extends XtreamSerieEpisode { legacyTrackingId?: number; originalId?: string; originalCmd?: string; } function generateLegacyVodEpisodeId( episodeNum: number, seasonKey: string ): number { return hashString(vod_${seasonKey}_${episodeNum}); } function generateVodEpisodeId(options: { parentSeriesId: string | number; providerEpisodeId: string; seasonKey: string; episodeNum: number; }): number { return hashString( JSON.stringify([ vod, String(options.parentSeriesId), options.providerEpisodeId, options.seasonKey, options.episodeNum, ]) ); }新 ID 由五个要素构成固定前缀vod、父系列 ID、提供方剧集 ID、季键、集号——同一父剧内确定性跨父剧必然不同。而旧哈希被完整保留为legacyTrackingId别名供迁移使用。测试契约要求证明五条性质同父同集确定性、父剧 100 与 200 的同季同集产生不同 ID、这两个剧集保留相同legacyTrackingId、同一父剧内不同提供方剧集 ID 也产生不同 ID、以及常规系列regular series路径的既有身份行为不受影响。生产侧唯一的调用点在StalkerSeriesViewComponent.mappedSeasons传入选中的目录项身份mapVodSeriesEpisodes(this.vodSeriesSeasons(), { parentSeriesId: this.toSeriesId(displayItem?.id ?? 0), fallbackPoster: displayItem?.info?.movie_image, })计划特别强调不要从季或剧集字段反推父级身份——经过与持久化相同toSeriesId路径规范化的选中目录项才是seriesXtreamId所表示的作用域。旧版播放位置的对账与迁移先保存后清除Task 6 是整个计划中约束最密的部分把“新旧 ID 并存期”的播放位置行为做成纯函数边界落在新模块 stalker-series-position-compatibility.ts。当前实现导出了四个成员L8 的ReconciledStalkerSeriesPositions接口、L55 的reconcileStalkerSeriesPositions、L144 的saveStalkerSeriesPosition、L180 的clearStalkerSeriesPosition签名与计划逐字一致export interface ReconciledStalkerSeriesPositions { positionsByTrackingId: Mapnumber, PlaybackPositionData; legacyPositionByTrackingId: Mapnumber, PlaybackPositionData; }对账reconcile规则是这套方案的语义核心查询边界只索引contentType: episode且seriesXtreamId等于目标父剧的行且这些行只能来自getSeriesPlaybackPositions(playlistId, seriesXtreamId)——计划明令禁止用getAllPlaybackPositions扩大迁移面精确行优先当前作用域 ID 精确命中的行无条件胜出旧版别名匹配只有StalkerMappedEpisode上的legacyTrackingId可作为匹配键若旧行存有seasonNumber/episodeNumber必须与映射剧集相等null/undefined视为缺省而兼容其他值按数值比较双记录即使精确行已胜出兼容旧行仍要记录在legacyPositionByTrackingId中以新跟踪 ID 为键供后续“保存/清除”操作做清理别名物化仅当没有精确行时才把兼容旧行克隆到新 ID 下设置当前父剧、季、集元数据不改动源行。持久化侧的两条不变量是整套设计的“承重墙”saveStalkerSeriesPosition必须先 await 新行保存成功再清除旧行且只有在一个私有共享的所有权谓词全部成立时才清除并返回trueposition.contentType episode legacyPosition?.contentType episode position.contentXtreamId ! legacyPosition.contentXtreamId position.seriesXtreamId ! null legacyPosition.seriesXtreamId ! null position.seriesXtreamId legacyPosition.seriesXtreamId (!position.playlistId || position.playlistId playlistId) (!legacyPosition.playlistId || legacyPosition.playlistId playlistId)谓词不满足则保存新行后返回false保存/清除失败一律reject调用方不能把部分迁移误当成功。 2.clearStalkerSeriesPosition必须先清旧 ID、再清作用域 ID。顺序是承重的若旧行清理失败精确行仍在若随后作用域清理也失败精确行仍代表“未清除状态”旧行无法“复活”进度。无已确认旧行时只清作用域 ID 并返回false。计划还规定写路径上永远不得从季/集号反推旧 ID——只有对账结果才能授权删除。组件层StalkerSeriesViewComponent的集成改动对应两个信号与一个生成号generation防竞态机制private readonly rawSeriesPositions signalreadonly PlaybackPositionData[]([]); private readonly legacyPositionByTrackingId signalMapnumber, PlaybackPositionData(new Map()); private seriesPositionsLoadGeneration 0;loadSeriesPositions捕获单调递增的 generation 加请求的 playlist/series IDawait 之后仅在 generation 仍为当前、playlist 匹配、且toSeriesId(displayItem()?.id)匹配时才发布原始行。这个设计让懒加载剧集填充后自然重跑对账并阻止“从剧 A 详情切到剧 B 时A 的慢响应覆盖 B 的位置”这类详情页竞态。写路径节流的时间更新、观看状态切换、运行时桥接更新统一走saveStalkerSeriesPosition成功后从rawSeriesPositions中过滤掉作用域 ID 与已确认旧 ID 两行、移除已消费的旧别名、并立即更新渲染 Map。集成测试被单独放在新文件stalker-series-view.position-compatibility.spec.ts计划明确说明原因既有的stalker-series-view.component.spec.ts已接近1200 行测试上限不能再追加。测试清单覆盖了懒加载后对账、精确行胜出但保留旧行作清理元数据、慢响应不跨剧覆盖、双清除后重跑对账不能复活进度、常规系列与未确认别名不触发旧行清除等七类场景并要求用延迟 Promisedeferred promises构造竞态、用数组记录 mock 调用顺序而非仅断言调用次数。Task 11 还诚实记录了一个 E2E 覆盖边界由于现有 E2E fixture 无法在懒加载剧集映射之前预置旧版冲突播放行legacy ID 撞号迁移的最终覆盖保持在纯函数与 Angular 组件层并要求在交付总结中说明这一限制。发布说明与架构契约Task 7工作流二以三个产物收尾唯一的用户可见发布说明 .changes/stalker-series-position-identity.mdtype: fix, area: stalker措辞同时覆盖三处修复布尔系列标志、跨剧进度隔离、旧版位置恢复stalker-portal.md 更新 VOD 系列与播放位置章节固化七条契约is_series只从true/1/1规范化懒加载跟踪 ID 含父剧 ID/提供方剧集 ID/季键/集号旧哈希仅作为兼容别名旧行只限当前父剧查询内且必须满足存储的季/集元数据精确作用域行胜出先保存新行再清除确认旧行不做数据库 schema 迁移或批量重写CLAUDE.md的 Stalker 系列条目同步同一规则而AGENTS.md的流程指引保持不动“实现细节不进流程文档”。工作流三仓库技能的机械验证技能契约什么是被验证的对象IPTVnator 在 .codex/skills 下维护八份面向 Agent 的仓库技能覆盖 Nx 架构、SQLite DB worker、主题样式、UI 设计、release-cut、release-notes、Stalker 门户、Xtream Electron。AGENTS.md 的## Repo Skills清单当前仓库第 1084–1096 行只保留路径明确“描述与触发条件以各技能 frontmatter 为准不在这里重复”。Task 8 把这些此前只能靠人眼维持的约定变成可执行检查。计划规定的技能契约有七条frontmattername必须等于所在目录名description必须是单行值、以Use when开头、不超过500 字符触发式描述trigger-only;整份技能不超过500 词反引号包裹的字面仓库路径必须存在以apps/、libs/、docs/、tools/、.changes/、.github/开头或恰为package.json、pnpm-lock.yaml、nx.json、tsconfig.base.json、eslint.config.mjs、CHANGELOG.md、AGENTS.md、CLAUDE.md之一含 glob/占位符字符* ? [ ] { } 的 token 跳过路径校验——例如apps/*-e2e这类示例路径不算违规release-notes与release-cut的.codex/.claude镜像必须字节级一致所有诊断按确定顺序一次性返回而不是首个错误即失败。零依赖验证器的实现最终落地的 validate-repository-skills.mjs 约 290 行没有任何第三方依赖几个实现细节值得拆解手写 frontmatter 解析parseFrontmatter逐行解析开头---块用unquoteScalar去掉成对引号——这正对应测试用例 1“quoted description 中含 YAML 冒号值如type: internal不能误判为多个字段”同时记录缩进续行continuedFields从而能拒绝跨行的 description路径存在性检查findLiteralRepositoryPaths isPathWithinRoot先排除 glob/占位符再要求路径不能逃逸仓库根目录防../../类注入最后逐个access探测镜像字节比较validateReleaseMirrors用Buffer.equals比较缺失镜像与内容不一致分别报诊断CLI 守卫L281-L287用fileURLToPath(import.meta.url)对比process.argv[1]确保模块被node:test导入时绝不触发仓库根校验副作用。测试策略同样讲究validateRepositorySkills({ rootDir })导出为纯入口每个用例用node:fs/promisesmkdtemp构建一个临时仓库 fixture因此七类违规断言互不干扰、也不需要真实仓库处于任何特定状态。Nx 集成上计划给出了 tools/skills/project.json 的完整内容项目名repository-skillstags 为[scope:tools, domain:skills, type:tool]test目标缓存化并绑定两个源文件 inputslint目标跑node --check做语法检查。package.json相应新增脚本当前仓库 L74skills:validate: node tools/skills/validate-repository-skills.mjs计划还安排了一个“有意的延迟”skills:validate全仓库通过被推迟到任务 9–10 完成之后因为当时八份技能里只有两份发布技能先被重写——先建门禁再让存量代码合规门禁最后才全绿避免了“验证器合入即红”的尴尬。技能刷新Nx、SQLite、主题、UI、Stalker、Xtream任务 9–10 按“决策优先于清单”的原则重写六份技能每份都给出精确的Use when触发式描述每份技能 500 词。其中最能体现“文档对齐实现”的两处修正SQLite DB worker 技能纠正了 sqlite-db-worker.md 的过时描述build-worker.js 实际产出三个bundleEPG 解析器、数据库、播放列表刷新playlist-refresh.worker.ts而非文档旧称的“both”并区分两类身份标识——requestId是按客户端请求生成、用于关联 worker 事件/响应传输operationId是渲染进程可见的长操作身份用于进度与合作式取消。当前被跟踪的操作为保存内容、删除 Xtream 内容、恢复 Xtream 用户数据、删除播放列表、删除全部播放列表前四个可取消delete-all-playlists被刻意标为cancellable: false已提交块保持提交、最终取消表现为AbortError、只有终结事件结算 UI 状态。Stalker EPG 文档修正了矛盾表述原文称“首次直播播放前频道行完全不取 EPG”实际流程是非广播 ITV 频道渲染后post-reset effect 立即调用ensureBulkItvEpg(168)批量预取行预览读取批量缓存、只有活动频道回退短 EPGget_short_epg。验证命令用反向搜索锁死旧措辞不复存在! rg -n Before the first live-channel playback|no pre-playback network requests|first active-channel fetch \ docs/architecture/stalker-epg.md docs/architecture/stalker-portal.md最终验证阶梯Task 11收尾任务把“技能是否真的能被 Agent 用对”变成可复现的验收。Step 1 为八份技能各设计一个新上下文场景fresh worker只给技能与仓库要求给出方案而非代码每场景列出“必须独立达到的决策”——例如技能场景要点必须达到的决策iptvnator-sqlite-db-worker“用 request ID 让 DB_DELETE_ALL_PLAYLISTS 可取消并在运行中的 Electron 里验证”拒绝两个前提delete-all 不可取消取消用operationId传输层requestId与之区分运行时验证前先重建 worker 并重启stalker-portal“门户返回布尔is_series两部剧共享 S01E01旧进度必须恢复”走规范器父/提供方/季/集作用域 ID当前父剧旧行查找带可选 S/E 守卫精确 ID 胜出先保存后清除覆盖全部界面xtream-electron“直播与电影行共享数字 ID、PWA 桥接部分字段、网络请求被替换、全局删除需要进度/取消”能力选择数据源播放列表/类型感知身份集合编排归属 shared>pnpm run skills:validate pnpm run release:notes:validate node --test tools/skills/validate-repository-skills.test.mjs tools/release/release-notes.test.mjs \ tools/release/release-note-gate.test.mjs tools/release/build-release-notes.test.mjs \ tools/release/screenshot-guards.test.mjs cmp -s .codex/skills/release-cut/SKILL.md .claude/skills/release-cut/SKILL.md cmp -s .codex/skills/release-notes/SKILL.md .claude/skills/release-notes/SKILL.md pnpm nx test release-tools pnpm nx test repository-skills pnpm nx test shared-interfaces --runInBand pnpm nx test portal-stalker-data-access --runInBand pnpm nx test portal-stalker-feature --runInBand pnpm nx test workspace-dashboard-data-access --runInBand pnpm nx run-many --targetlint \ --projectsrelease-tools,repository-skills,shared-interfaces,portal-stalker-data-access,portal-stalker-feature pnpm nx build shared-interfaces pnpm nx build web pnpm nx build electron-backend pnpm nx run web-e2e:e2e-ci--src/stalker.e2e.ts pnpm nx run electron-backend-e2e:e2e-ci--src/recent.e2e.ts最后用git diff --check、git status --short、git diff --stat master...HEAD与git log --oneline --decorate master..HEAD做范围审计确认恰好八份.codex技能被刷新、只有两个必需的.claude镜像变更、没有混入宽泛 SCSS 迁移或数据库 schema 重写、Stalker 发布说明是唯一新增.changes笔记、AGENTS/CLAUDE 共享流程措辞保持同步。小结把“文档漂移”变成可检测的回归这份计划的价值不在于任何单一修复而在于它示范了一种可持续的仓库治理模式技能与架构文档不再是静态散文而是有签名、有词数上限、有路径存在性检查、有镜像字节一致性约束、有触发式描述格式的代码资产发布正文的公开/内部边界由正则契约与退出码语义显式定义跨版本数据迁移用“纯函数对账 生成号防竞态 先保存后清除”的不变量组合替代破坏式 schema 重写。仓库当前的实现状态——extract-changelog-section.mjs、validate-repository-skills.mjs、stalker-series.adapters.ts、stalker-series-position-compatibility.ts 与 .codex/skills 下的八份技能——正是这套模式已经生效的直接证据。读者若要延伸学习可依次阅读 设计文档、Nx 工作区边界、SQLite DB worker 架构 与 Stalker 门户架构。【免费下载链接】iptvnator:tv: Cross-platform IPTV player application with multiple features, such as support of m3u and m3u8 playlists, favorites, TV guide, TV archive/catchup and more.项目地址: https://gitcode.com/GitHub_Trending/ip/iptvnator创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考