@movemama/opencode-legacy
v1.0.8
Published
OpenCode legacy text processing plugin for GB2312 and script-safe editing workflows.
Maintainers
Readme
@movemama/opencode-legacy
OpenCode legacy 文本处理插件,面向 GB2312 文本、脚本型 .txt 编辑和 legacy 规则路由场景。
当前主链路已经改为纯 JS 编码实现,不再依赖系统外部 iconv.exe。
v1.0.8 新增能力
- autoDetect 配置字段已暴露到
legacy-rules.json:新增autoDetectEncoding、rememberDetectedEncoding、autoDetectCandidates、autoDetectMinConfidence四个根级字段,每个字段均有内联_comment说明,不再需要猜测字段含义。 - 编码记忆持久化:自动探测到的高置信度编码现在会持久化写入
<worktree>/.opencode/detected-encodings.json,重启 OpenCode 后编码记忆不再丢失。 - 多规则字段继承合并:同一文件命中多条规则时,最高优先级规则字段优先,未定义的字段自动从低优先级规则继承补充,无需在高优先级规则中重复填写所有字段。
- glob 引擎升级(picomatch):内置 glob 引擎替换为
picomatch,全面支持!否定模式(如!backup/**)和[abc]字符类,排除子目录或文件名前缀等需求可以直接在 glob 中表达。 - 新建文件编码推断提示:autoDetect 开启时,若目标文件不存在,
write不再静默降级为 UTF-8,而是输出明确提示,告知用户需要在legacy-rules.json中配置显式规则。 - classic-tag 编辑后链接校验:编辑
classic-tag格式文件后,插件自动校验所有@跳转目标是否存在对应[@标签],存在悬空链接时在写入成功的结果中追加警告,不再静默放行。 - general-code fallback 明确标注:
applyFallbackEditChain对general-code文件新增专属返回分支,不再以no-match模糊提示,而是直接说明"无专属 fallback,建议改用精确锚点替换或配置显式规则",报错信息同步透出 reason。
规则注入
插件现在会在每轮对话自动读取并注入以下规则文件:
- 全局
AGENTS.md:根据当前环境变量USERPROFILE或HOME动态解析到~/.config/opencode/AGENTS.md - 项目
AGENTS.md:根据当前打开项目的worktree动态解析到<worktree>/AGENTS.md
注入后的硬规则会进入系统上下文,用于约束代理优先读取规则、完整读取目标文件、以及统一输出回执。
另外,插件已为以下编辑类工具增加前置守卫:
editwritescript-editlegacy_editlegacy_write
如果当前会话尚未完成 AGENTS.md 规则注入,上述工具会直接拒绝执行,以避免代理在未读取规则的情况下改文件。
安装
在 OpenCode 配置中加入:
{
"$schema": "https://opencode.ai/config.json",
"plugin": [
"@movemama/opencode-legacy@latest"
]
}首次未安装的用户会在 OpenCode 启动时自动安装当前 latest 版本。后续更新可由用户自行处理。
如果刚安装后没有生效,重新启动一次 OpenCode 即可让 npm 插件完成加载。
当前提供的工具
readwriteeditscript-editlegacy_readlegacy_writelegacy_editlegacy_status
其中同名工具 read、write、edit 会覆盖 OpenCode 内置工具,实现 legacy 路由。
规则文件
包内自带 legacy-rules.json 作为默认规则。
加载优先级:
<worktree>/.opencode/legacy-rules.json<worktree>/legacy-rules.json- 包内
legacy-rules.json
规则字段现在除编码外,还支持:
profileeditStrategyfallbackModescriptMarkers
这让插件可以按场景决定更合适的编辑策略,而不只是按编码读写。
同一文件命中多条规则时,最高优先级规则字段优先,低优先级规则的字段在未被覆盖时会自动继承,无需重复填写。
自定义扩展规则
如果用户希望让其他文件类型也走 GB2312 / GBK 的 legacy 读写链路,当前可以通过项目级规则扩展实现。
推荐在当前项目放置:
<worktree>/.opencode/legacy-rules.json
例如:
{
"rules": [
{
"glob": "**/*.{npc,msg,dialog}",
"encoding": "gb2312",
"strict": true,
"tool": "txt-gb2312",
"priority": 50,
"profile": "txt-gb2312-safe",
"editStrategy": "exact-first",
"fallbackMode": "legacy-safe-replace",
"scriptMarkers": []
}
]
}字段说明:
glob:匹配要走 legacy 读写链路的文件范围encoding:指定文件使用的编码,例如gb2312、gbkstrict:是否使用严格模式;通常脚本类文本建议保持truetool:建议使用的处理器名称,当前常见值为txt-gb2312或legacy-textpriority:规则优先级,数值越大越优先匹配profile:场景配置名,用于帮助策略层判断文件类型与处理方式editStrategy:主编辑策略,例如exact-first、widget-fieldfallbackMode:主策略失败后的回退方式,例如legacy-safe-replace、widget-field-updatescriptMarkers:用于辅助识别脚本型文件或 DSL 结构的关键标记数组
根级可选字段(用于未命中规则时的自动探测):
autoDetectEncoding:是否开启未命中规则文件的编码自动探测,默认falserememberDetectedEncoding:是否记忆探测结果并在后续read/write/edit复用,默认trueautoDetectCandidates:探测候选编码列表,默认['utf8','gb18030','gbk','gb2312']autoDetectMinConfidence:探测最小置信度,默认0.35
如果客户只是想让某类新文件按 GB2312 读写,最小配置通常只需要先关心:
globencodingstricttoolpriority
其余字段可以先参考现有示例再逐步细化。
如果希望不依赖文件后缀而在“未命中规则 + 疑似中文乱码”时自动进入 legacy 编码链路,可在规则文件根级增加:
{
"autoDetectEncoding": true,
"rememberDetectedEncoding": true,
"autoDetectCandidates": ["gb18030", "utf8"],
"autoDetectMinConfidence": 0.35,
"rules": [
{
"glob": "**/*.txt",
"encoding": "gb2312",
"strict": true,
"tool": "txt-gb2312",
"priority": 10
}
]
}说明:
- 自动探测仅在“未命中规则”时触发,已命中规则仍以规则编码为准。
- 自动探测命中后会在读取回执中显示
编码来源:auto-detect。 - 若启用记忆,后续同一路径写入会优先使用记忆编码(回执显示
来源:memory)。
当前规则加载优先级为:
<worktree>/.opencode/legacy-rules.json<worktree>/legacy-rules.json~/.config/opencode/legacy-rules.json- 包内
legacy-rules.json
这意味着用户现在既可以:
- 在
~/.config/opencode/legacy-rules.json中定义全局通用扩展规则 - 又可以在单个项目里通过
<worktree>/.opencode/legacy-rules.json或<worktree>/legacy-rules.json做更高优先级覆盖
自动探测 legacy 编码
当前版本除了按 glob 命中显式规则外,还支持通过配置开启“自动探测 legacy 编码”兜底。
这意味着某些文件即使没有命中 .txt、.npc、.cfg 之类的显式规则,只要内容看起来像中文文本且按 UTF-8 读取结果不合理,插件也可以在候选编码中自动寻找更可读的解码结果,并切换到 legacy 链路。
推荐配置示例:
{
"autoDetectEncoding": true,
"rememberDetectedEncoding": true,
"autoDetectCandidates": ["gb18030", "gbk", "gb2312", "utf8"],
"autoDetectMinConfidence": 0.2,
"rules": [
{
"glob": "**/*.txt",
"encoding": "gb2312",
"strict": true,
"tool": "txt-gb2312",
"priority": 10
}
]
}字段说明:
autoDetectEncoding:是否开启自动探测 legacy 编码rememberDetectedEncoding:是否记住某个文件上次探测成功的编码,便于后续写回继续沿用autoDetectCandidates:参与探测的编码候选列表,顺序可自定义autoDetectMinConfidence:最低探测置信度,低于该值则不自动接管
当前自动探测的行为特点:
- 不是只根据文件扩展名判断
- 不是简单地“看到乱码就一律当 GBK”
- 而是会对候选编码解码后的文本做可读性评分,选择更合理的结果
- 会优先保护合法且可读的 UTF-8 文本,避免把正常 UTF-8 中文误判成 legacy 编码
- 会比较候选编码之间的领先差值;若优势不明显,则不会自动接管
- 会尽量过滤明显非文本/二进制内容,降低误判率
- 对
general-code类型文件会启用更保守的保护策略 - 自动探测结果会区分
high / medium / low置信度等级 - 只有
high置信度结果才会写入编码记忆并影响后续write - 读取成功后会在回执中显示
编码来源:auto-detect - 如果开启了
rememberDetectedEncoding,后续write会复用记忆编码写回 legacy_status也会显示自动探测是否开启、候选编码列表和记忆编码
关于 general-code(如 C++ / C# / 强语法代码)的当前策略:
- 自动探测可以用于读取和判断编码
- 但如果文件是通过
auto-detect命中的general-code,默认会进入 conservative mode - 在这种模式下,不建议直接做宽泛
edit写入 - 更推荐:
- 添加显式规则后再改
- 使用更精确的小范围锚点替换
- 或后续接入语法感知层再做更复杂编辑
当前兼容性与执行力边界可以理解为:
- 未知扩展名但内容明显是脚本 / NPC / rich-ui-dsl:自动探测后执行力较强,可直接走
edit、script-edit或 widget 回退链 - 未知扩展名但内容是普通中文文本:自动探测后可直接读写,适合文本型替换
- 未知扩展名但内容是
general-code:当前更偏保守兼容,不承诺像脚本文本那样自动探测编码后稳定写回;如果需要更强执行力,建议添加显式规则或后续接语法感知层
legacy_status 当前会额外输出:
文本类型记忆编码编码来源置信度等级是否允许写入
这样可以更快判断当前文件是“可安全修改”还是“只建议保守处理”。
如果客户的目标只是“某类固定文件永久按某种编码处理”,仍然建议优先写显式规则;自动探测更适合作为未命中规则时的兜底方案。
自动策略层
当前 edit 已经接入自动策略层。
- 普通文本默认走
exact-first classic-tag文本可根据profile和scriptMarkers判断为更偏 block / line-normalized 的策略rich-ui-dsl文本会优先识别<Text|...>/<Button|...>组件,并在 exact 失败后尝试 widget 字段级更新- 失败时会返回当前策略、格式族和 fallback 提示,便于继续排障
支持的格式族
classic-tag- 例如
[@main]、<领取/@领取>、<关闭/@exit> - 当前已支持:菜单行宽松匹配、标签块替换、跳转目标校验
- 例如
rich-ui-dsl- 例如
<Text|x=...|text=...>、<Button|...|link=@...> - 当前已支持:多行 widget 定位、字段级更新、children 字段保留
- 例如
当前这两类是第一批重点支持对象。
general-code- 例如 C++ / C# / 强语法代码文本
- 当前仅做安全识别与保守回退,不做激进结构改写
诊断工具
可以使用 legacy_status 查看:
- 插件版本
- 规则来源
- 命中规则
- 格式族
- profile
- 建议策略
- fallback 模式
- 是否被判定为脚本型文件
- 自动探测是否开启、候选编码、最低置信度、记忆编码
如何确认已加载成功
最简单的方法是读取一个命中规则的 .txt 文件。
如果插件已接管成功,返回内容中会出现:
--- Legacy 读取回执 ---这说明 read 工具已经由插件覆盖并进入 legacy 规则链路。
也可以直接调用 legacy_status 检查当前文件会命中哪条规则、建议使用哪种策略。
如果检测为 general-code,当前插件会优先保持保守,不会像 rich-ui / classic-tag 那样做特化结构修改;这部分为未来语法感知层预留空间。
如果检测为 classic-tag,当前插件已能在 exact 失败后继续尝试:
- 菜单行 token 级匹配
- 标签块局部替换
- 编辑完成后自动校验悬空跳转目标(存在悬空
@link时,写入结果中追加警告)
如果检测为 rich-ui-dsl,当前插件已能在 exact 失败后继续尝试:
- widget 字段级更新
- 多行 widget 定位
- 保留
children={...}容器字段
兼容说明
txt-gb2312-tool.mjs目前仅保留为兼容遗留文件,不再是主链路依赖- 当前主运行时入口以
.js/.mjs文件为准
发布
npm login
npm publish --access public开发测试
npm test