本技能用于处理代码中反复出现的扩展机制问题:当新增或移除一种变体需要多处分散、协同修改时,可用它来设计、评审、重构或解释这类机制。其目标是让新增或移除一种变体所需的知识集中在清晰边界内,减少真实的修改传播和回归;结构按问题选择,而非套用固定模板。
一、先确定用户要什么
技能把请求分为四类模式:解释/命名/第一性原理,只解释当前机制、取舍和反例,不创建实现、README 或评审工程;只读评审,读取约定范围,报告当前伤害、证据和最小建议,不为验收删除插件或创建分支;设计,给出所需契约、落点、行为和验证方案,示例是建议,不声称已实现;实现/重构,检查工作树后修改授权范围,保留既有行为与标识,运行对应验证。解释、评审、设计不因加载本技能自动变成实现;已有授权继续有效,新增范围、外部动作、破坏性迁移仍需对应授权。用户只问一个变体的内部问题时,就处理那个问题,不扩成机制改造。
二、按需加载引用
默认只读主文件。仅当当前任务需要时加载对应引用:需要论证必要性、OCP/DIP/DDD 类比时读 first-principles.md;需要检查具体反模式时读 anti-patterns.md;有真实生命周期、订阅、缓存、异步加载或多账号状态时读 stateful-runtime.md;跨团队发布、第三方插件或版本兼容时读 governance.md;要迁移到 Rust/Tauri/Python 或框架插件 API 时读 cross-stack.md;需要多站点、弹窗或工具目录的参考形状时读 case-studies.md 的相关案例,示意代码不是当前仓库证据。
三、从变化出发选择结构
先沿最近一次新增或移除变体的路径,读现有 key、消费方、配置和测试,区分“同一事实必须同步改多处”与“实现、测试、文案各有合法职责”。文件数量、变体数量或出现 switch 本身都不是重构证据。检查能推翻方案的最便宜证据:真实变体是否共享输入、输出、生命周期;重复的是知识还是外观;现有框架是否已提供所需扩展点。能从代码查到的事实先查;普通可逆工程默认值自行选择,只有影响产品偏好、难回退取舍、授权或用户独有事实的问题才询问。
当前复杂度与合理起点对应如下:少量稳定分支、变化不传播,保留函数或 switch,不因未知未来需求建插件系统;同步静态条目、共享简单输入/输出,用类型明确的映射或函数表,无需 store、Provider、factory、缓存或异步边界;多变体确实共享订阅、调度、资源或状态转换,提取拥有这些生命周期的 Core,变体提供窄契约,按需分目录;框架已有注册和生命周期机制,使用现有机制,只补业务所需契约,不再复制一套 host;第三方独立安装或动态发现,先确认安装模型、兼容性与权限边界,静态注册无法自动满足这一要求。收益不成立时给出“保留现状”及证据;用户要求证明某种结构必然正确时,先检查前提,不制造证明。
四、五个概念,按需落地
Identity、Contract、Registry、Runtime Core、Convention Folder 是分析职责的词汇,不要求五个文件、五个模块或每次齐备。简单类型映射可同时表达前三项;没有生命周期就无需独立 Core;目录负责组织实现,不决定架构是否成立。
Identity:沿用最权威的稳定 key 和兼容语义;外部供应商 ID、埋点名、已发布路由不应为了命名整齐被重命名;本地目录可保留显式映射;外部字符串先校验,再查注册表。
Contract:写清输入、输出、失败、生命周期和能力;Identity 只标识条目,不能替代行为契约;共享字段确实适用于全部变体才必填;可选字段有明确默认值;互斥能力用可辨识联合或不同契约,不为“结构同质”堆可选字段。
Registry:给“有哪些条目”一个可追溯的组合入口;显式表、框架 manifest 或由模块贡献并汇总的表均可;单一事实来源不等于只许一个物理文件;保留重复 key、未知 key 和缺失能力的既有处理。
Runtime Core:只抽出真实共享的调度与生命周期,依赖 Contract,不硬编码具体插件的业务条件;单插件条件归变体,跨插件产品顺序归编排层;没有共享状态时,普通调用函数就够。
Convention Folder:当单变体有多份相关资源时聚拢;简单条目留在一个文件也成立;依赖方向应让移除一个变体不破坏无关变体;不为消除所有直接 import 而引入总线。
最小静态例子只表达共同函数签名和可追溯的名单:
type Formatter = (value: string) => string;
const formatters = { upper: (value: string) => value.toUpperCase(), lower: (value: string) => value.toLowerCase(), } satisfies Record<string, Formatter>;
type FormatterKey = keyof typeof formatters;
function format(key: FormatterKey, value: string): string { return formatterskey; }
示例假定 key 已由类型内调用方提供。若 key 来自 URL、网络或用户输入,必须在边界校验并保留原有未知值错误;TypeScript 类型不能验证运行时输入。
五、条件式工程细节
延迟加载:仅在加载成本和实际渲染路径支持收益时采用;它会引入等待、失败和首次使用延迟;保留 SSR、首屏与错误行为,不默认 ssr: false;用真实网络/产物证据确认收益,不凭 dynamic import 字样宣称成功。
命名与引导:存在反复找落点的成本时,给一个添加条目的例子、简短命名映射或仓内已有生成器;占位符、README、脚手架不是插件化的必要条件。
调试能力:优先复用已有日志、DevTools 或测试接口;只有实际诊断需要才增加开发环境探针;不默认暴露全局 store、用户数据或清缓存写入口。
有状态的机制:登录/权限变化必须重算相关意图;订阅、定时器、资源和异步结果必须有明确 owner 与清理;缓存按实际用户/租户边界隔离;静态机制不需要添加这些状态。具体边界见 stateful runtime 引用。
六、实现与验证
冻结本轮范围,说明要减少哪条修改传播以及保留哪些行为,不把纯命名整齐或新框架当目标。做一个最小、可回退的变体迁移,沿用既有 key、路由、持久化数据和错误契约;确认消费方不再重复同一判断后再移除旧路径。运行与变化对应的验证:静态表检查合法/未知 key 与已有输出;有状态的机制检查更新、卸载、重复挂载、失败和跨账号隔离;公共 UI 行为还需真实浏览器/渲染信号。用隔离 fixture 或只读依赖图验证新增/移除条目的传播,不在用户工作区为了“验收”真的删插件。只有用户要求实现且改动有回归风险时才补必要行为测试;解释和只读评审不生成测试工程。检索只能定位候选:字段不同、存在 switch、静态 import 或缺占位符都不能单独判失败;构建/typecheck 不能替代运行时清理、UI 加载或账号切换验收;未跑的必需验证写 UNVERIFIED。
七、交付
只交付用户要求的模式:解释给结论与必要例子;评审给证据、影响与最小修法;设计给适用边界、契约与验证;实现给修改和实际结果。迁移路径、目录树、README、调试探针仅在当前改造确实需要时提供,不固定凑齐产物。