十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

oh-my-pi 编码规则实战:TypeScript 静态查找表用 Record,动态集合用 Set/Map(ts-set-map 规则解析)

oh-my-pi 编码规则实战:TypeScript 静态查找表用 Record,动态集合用 Set/Map(ts-set-map 规则解析) oh-my-pi 编码规则实战TypeScript 静态查找表用 Record动态集合用 Set/Mapts-set-map 规则解析【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi本篇基于 oh-my-piCoding agent with the IDE wired in内置规则集中的ts-set-map规则系统讲解 TypeScript 开发中如何正确取舍RecordK, V与Set/Map静态字符串键查找表优先用Record动态、非字符串键、需要运行时增删与迭代能力的数据用Set/Map。读完你会掌握这套取舍标准理解它如何作为 TTSRTool-Triggered Stream Rules规则在 Agent 编辑/写入.ts/.tsx文件时自动触发提示并学会自定义、覆盖或关闭内置规则。规则定位一条随 Agent 内置的 TypeScript 数据容器规范ts-set-map是 oh-my-pi 打包在二进制里的默认规则之一源码位于 packages/coding-agent/src/discovery/builtin-rules/ts-set-map.md。它的description一句话概括了全部核心主张PreferRecordK, Vfor small static literals; useSet/Mapfor anything dynamic翻译过来就是小型的静态字面量查找表优先用RecordK, V凡是动态的场景一律用Set/Map。这条规则并不要求开发者背诵复杂的数据结构理论而是给出一个可快速执行的判断框架——静态与动态的边界就是选择Record还是Set/Map的分界线。核心取舍标准静态用 Record动态用 Set/Map规则正文给出了两条明确的适用边界使用RecordK, V/RecordK, true的场景小型的、静态的、字符串键查找表。所谓静态指表的内容在编写代码时就已经确定、不会在运行时增删条目键类型是字符串或可表示为字符串的枚举值。使用Set/Map的场景满足以下任一条件即应切换动态或非字符串的键例如以对象、数字、Symbol 为键运行时需要插入/删除条目add/delete/set需要依赖Set/Map独有的 API如.size、.clear()、稳定的插入顺序stable insertion order或迭代器 APIvalues()、entries()、forEach、for...of。从语言机制上看这个判断是有依据的对象/Record的键只能是字符串或经 ToPropertyKey 强转后的 Symbol其属性顺序对整数型键有特殊排序规则且没有内置的.size与迭代协议而Set/Map专为动态集合设计键可以是任意类型插入顺序即迭代顺序并且提供了O(1)级别的has/get语义。规则正是在强调让容器类型匹配数据的使用方式。规则附带的基准示例继承自原文档规则文件正文给出了一个最简对照示例这也是理解整条规则的最佳起点// Static literal → Record const LABEL_BY_KIND: Recordstring, string { text: Text, json: JSON, binary: Binary, }; // Dynamic membership → Set const seen new Setstring(); for (const item of items) { if (seen.has(item.id)) continue; seen.add(item.id); }第一个例子LABEL_BY_KIND三种类型映射到三种展示文案内容固定、键为字符串、仅需读取用Recordstring, string即可语义直白且类型安全。第二个例子seen运行过程中不断向集合里add元素、用has做去重判断是典型的动态成员关系场景Setstring是唯一合理选择。更多实战场景把判断标准用到真实代码里场景一枚举映射表用 Recordtype Severity info | warn | error; // 静态映射编译期就确定键为字符串只读 const SEVERITY_LABEL: RecordSeverity, string { info: 信息, warn: 警告, error: 错误, }; // 成员集合动态判定是否允许用 Set 表达允许的枚举值集合 const ALLOWED_SEVERITIES new SetSeverity([info, warn]);场景二布尔标记查找表用 RecordK, true当表只表达键是否存在这一层语义时RecordK, true比RecordK, boolean更贴合意图——你不需要false分支存在的键就是真const FEATURE_FLAGS: Recordstring, true { diff-view: true, inline-comments: true, }; // 配合 in 操作符做存在性判断 if (diff-view in FEATURE_FLAGS) { /* ... */ }场景三动态缓存用 Map运行期频繁读写、以对象为键或需要计数/排序都应切到Map// 以对象为键的缓存Record 做不到对象键会被强转为字符串 const cache new MapHTMLElement, string(); // 动态计数 稳定的插入顺序 const counter new Mapstring, number(); for (const word of words) { counter.set(word, (counter.get(word) ?? 0) 1); }场景四需要迭代与 clear 的动态集合用 Setconst pending new Setstring(); function enqueue(id: string) { pending.add(id); } function drain() { // 稳定插入顺序 size clear三者都是 Set 的强项 for (const id of pending) { console.log(processing ${id}); } pending.clear(); }规则是如何被 Agent 触发的frontmatter 的完整语义ts-set-map.md不只是给人看的规范文本它是一份带结构化 frontmatter 的规则文件Agent 运行时依赖这些元数据来决定何时介入。逐项拆解--- description: Prefer RecordK, V for small static literals; use Set/Map for anything dynamic condition: \\bnew\\s(Set|Map)\\b scope: tool:edit(**/*.{ts,tsx}), tool:write(**/*.{ts,tsx}) interruptMode: never ---description规则的一句话摘要。它决定了两件事一是当规则进入 rulebook 桶时以- name (globs): description的形式渲染到domain-rules块二是 Agent 在需要时通过rule://ts-set-map读取规则正文前的摘要信息。conditionTTSR 触发条件是一个正则表达式字符串。这里的\\bnew\\s(Set|Map)\\b匹配new Set或new Map的出现——也就是说只要 Agent 在编辑/写入代码时构造了新的Set或Map这条规则就有机会被触发。实现上condition支持字符串或字符串数组解析逻辑见 packages/coding-agent/src/capability/rule.ts 的parseRuleConditionAndScope编译时若遇到(?i)这类 PCRE 内联旗标还会被翻译成原生RegExp旗标compileRuleCondition避免规则因 JS 引擎不支持内联旗标而静默失效。scope把匹配面收窄到允许的流表面。tool:edit(**/*.{ts,tsx}), tool:write(**/*.{ts,tsx})表示仅在edit与write两个工具的、面向**/*.{ts,tsx}文件的参数流上匹配。合法的 scope 令牌包括text、thinking、tool或toolcall以及tool:name(path-glob)解析器在 packages/coding-agent/src/capability/rule.ts 的splitScopeTokens中处理edit/write是仅有的两个会被 glob 简写如condition: *.rs推断为工具 scope 的常量CONDITION_GLOB_SCOPE_TOOLS。关于 scope 语义的完整说明见 docs/rulebook-matching-pipeline.md 第 6 节。interruptMode: never本条规则明确不打断 Agent 的输出流。TTSR 有四种中断模式见 packages/coding-agent/src/config/settings-schema.ts 中ttsr.interruptMode的定义alwaysprose 与工具流都中断全局默认值、prose-only、tool-only、never。never的含义是绝不中断而是在完成之后注入一条警告。对ts-set-map这种建议性质的风格规范来说never是恰当的选择它提醒 Agent 检查用法但不打断编码流程。interruptMode的解析在 packages/coding-agent/src/discovery/helpers.ts 的buildRule中完成只接受上述四个枚举值之一。规则的生命周期从 markdown 文件到运行时规则ts-set-map.md并不是运行时从磁盘临时读取的它走了一条编译期嵌入 → 低优先级注册 → 桶分发的完整链路编译期嵌入在 packages/coding-agent/src/discovery/builtin-rules/index.ts 中所有内置规则通过import tsSetMap from ./ts-set-map.md with { type: text }以文本资源形式导入并汇总到BUILTIN_RULE_SOURCES数组ts-set-map在数组中的注册名为ts-set-map。这样bun build --compile产出的单二进制不携带松散的规则文件只有内嵌文本。低优先级注册这些规则由builtin-defaults提供方provider注册见 packages/coding-agent/src/discovery/builtin-defaults.ts。该提供方的PRIORITY 1是所有提供方中优先级最低的——这意味着任何用户级、项目级或工具级的同名规则都会覆盖内置副本按名称去重时先到先得。桶分发每个会话开始前所有已发现的规则会经过 packages/coding-agent/src/capability/rule-buckets.ts 的bucketRules单一漏斗处理。ts-set-map带有非空condition因此只要 TTSR 管理器addRule接受它就会注册为 TTSR 规则addRule内部packages/coding-agent/src/export/ttsr.ts会编译 condition、构建 scope并校验 scope 是否可达。规则分发优先级为disabledRules→builtinRules false丢弃 →agents作用域 → TTSR 注册 →alwaysApply→ rulebook有description才入册。自定义与覆盖三种方式管理内置规则ts-set-map只是默认建议你可以按团队规范调整方式有三种注释说明见 packages/coding-agent/src/discovery/builtin-defaults.ts配置项定义见 packages/coding-agent/src/config/settings-schema.ts方式一整体关闭内置规则集{ ttsr: { builtinRules: false } }ttsr.builtinRules默认为true设为false会丢弃整个builtin-defaults提供方下的规则。方式二单独禁用某条规则{ ttsr: { disabledRules: [ts-set-map] } }ttsr.disabledRules默认为空数组填入规则名后该规则在桶分发之前即被丢弃既不会被 TTSR 匹配也不会通过rule://暴露。方式三用同名规则覆盖内置副本在任何优先级高于builtin-defaults的来源例如项目.omp/rules/下的ts-set-map.md或用户级~/.omp/agent/rules/ts-set-map.md定义同名规则即可。按名称去重后你的版本会取代内置版本因此可以完全改写 condition、scope、interruptMode 甚至正文。原生配置目录的规则加载逻辑在 packages/coding-agent/src/discovery/builtin.ts 的loadRules中项目级从最近的.omp/rules/向上查找用户级从当前 profile 的 agent 目录读取均支持.md与.mdc两种后缀。结语让风格规范变成 Agent 的运行时直觉ts-set-map的价值在于把Record 还是 Set/Map这一高频 TypeScript 决策从人脑记忆下沉为 Agent 的运行时提示静态字符串键查找表 →RecordK, V动态、非字符串键、需要增删与迭代 →Set/Map。配合interruptMode: never的非侵入式设计与可覆盖的内置规则机制它既能在编码现场给出提醒又不会强迫团队接受统一的风格。参考同目录下其他内置规则如 ts-no-any.md、ts-import-type.md、ts-promise-with-resolvers.md你会发现同一套 frontmatter 结构支撑起了整个 TTSR 风格规则体系——理解了ts-set-map也就理解了如何为你的团队撰写自己的内置规则。【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表