opencode-windows-encoding 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![npm version](https://img.shields.io/npm/v/opencode-windows-encoding)](https://www.npmjs.com/package/opencode-windows-encoding)
4
4
  [![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
5
5
 
6
- OpenCode plugin that fixes UTF-8 encoding issues when executing PowerShell commands on Windows. Single-file, zero npm dependencies.
6
+ OpenCode plugin that fixes UTF-8 encoding issues when executing PowerShell commands on Windows. Single-file, zero npm runtime dependencies.
7
7
 
8
8
  ## The Problem
9
9
 
@@ -22,6 +22,7 @@ This plugin hooks into OpenCode's `tool.execute.before` event and injects UTF-8
22
22
  - **Idempotent** — skips commands that already contain `OutputEncoding` to avoid duplication
23
23
  - **`set` prefix aware** — preserves PowerShell `set VAR="value"` prefixes before injecting
24
24
  - **Zero config** — works out of the box with no options
25
+ - **Debug logging off by default** — set `OPENCODE_UTF8_DEBUG=1` to enable diagnostic logging to `$TMP/utf8-plugin.log`
25
26
 
26
27
  ## Installation
27
28
 
@@ -69,7 +70,7 @@ cp src/utf8-encoding.ts ~/.config/opencode/plugins/utf8-encoding.ts
69
70
 
70
71
  Restart OpenCode to apply. No `npm install`, no build step.
71
72
 
72
- `src/utf8-encoding.ts` uses only Node.js built-ins (`node:fs`, `node:os`, `node:path`) — zero npm dependencies.
73
+ `src/utf8-encoding.ts` uses only Node.js built-ins (`node:fs`, `node:os`, `node:path`) and a compile-time-only `import type` from `@opencode-ai/plugin` — zero npm runtime dependencies.
73
74
  ## Requirements
74
75
 
75
76
  - **OpenCode** (any recent version with plugin support)
@@ -12,7 +12,7 @@ function flog(msg) {
12
12
  } catch {
13
13
  }
14
14
  }
15
- var UTF8_ENC = "[Console]::OutputEncoding=[Console]::InputEncoding=[Text.Encoding]::UTF8;$OutputEncoding=[Text.Encoding]::UTF8;";
15
+ var UTF8_ENC = "[Console]::OutputEncoding=[Console]::InputEncoding=[Text.Encoding]::UTF8;$OutputEncoding=[Text.Encoding]::UTF8;$env:PYTHONIOENCODING='utf-8';";
16
16
  function stripSetPrefixes(cmd) {
17
17
  const m = cmd.match(/^((?:set\s+\w+="[^"]*"\s*&&\s*)+)/);
18
18
  if (m) return { prefixes: m[1], cleanCmd: cmd.slice(m[1].length) };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utf8-encoding.ts"],"sourcesContent":["/**\n * OpenCode Plugin — UTF-8 Encoding Fix for Windows + PowerShell\n *\n * 单文件插件,可直接复制到 ~/.config/opencode/plugins/ 使用,无需 npm install。\n *\n * 工作原理:拦截所有 bash/shell 工具调用,在命令前注入 PowerShell\n * UTF-8 编码配置,解决 Windows 下中文/非 ASCII 字符乱码问题。\n */\n\nimport { appendFileSync } from \"node:fs\"\nimport { tmpdir } from \"node:os\"\nimport { join } from \"node:path\"\nimport type { PluginInput } from \"@opencode-ai/plugin\"\n\n// 调试日志(写入临时目录,默认关闭,设 OPENCODE_UTF8_DEBUG=1 开启)\nconst DEBUG = process.env.OPENCODE_UTF8_DEBUG === \"1\"\nconst LOG = join(tmpdir(), \"utf8-plugin.log\")\nfunction flog(msg: string) {\n if (!DEBUG) return\n try { appendFileSync(LOG, `[${new Date().toISOString()}] ${msg}\\n`, \"utf8\") } catch {}\n}\n\n// ── PowerShell UTF-8 编码前缀 ──\nconst UTF8_ENC =\n \"[Console]::OutputEncoding=[Console]::InputEncoding=[Text.Encoding]::UTF8;$OutputEncoding=[Text.Encoding]::UTF8;\"\n\n/** 提取 opencode 在命令前追加的 set VAR=\"value\" && 前缀 */\nfunction stripSetPrefixes(cmd: string): { prefixes: string; cleanCmd: string } {\n const m = cmd.match(/^((?:set\\s+\\w+=\"[^\"]*\"\\s*&&\\s*)+)/)\n if (m) return { prefixes: m[1], cleanCmd: cmd.slice(m[1].length) }\n return { prefixes: \"\", cleanCmd: cmd }\n}\n\nexport const Utf8EncodingPlugin = async (_input: PluginInput) => {\n flog(\"=== LOADED ===\")\n\n return {\n \"tool.execute.before\": async (input: { tool: string; sessionID: string; callID: string }, output: { args: any }) => {\n const tool = String(input?.tool ?? \"\")\n flog(`[tool.before] tool=\"${tool}\"`)\n\n if (tool !== \"bash\" && tool !== \"shell\") return\n\n const args = output.args\n if (!args) { flog(\" no args\"); return }\n\n const cmd = args.command\n if (typeof cmd !== \"string\" || !cmd) {\n flog(` args keys: ${JSON.stringify(Object.keys(args))}`)\n return\n }\n\n const { prefixes, cleanCmd } = stripSetPrefixes(cmd)\n flog(` orig: ${cleanCmd.slice(0, 120)}`)\n\n // 防止重复注入\n if (cleanCmd.includes(\"OutputEncoding\")) { flog(\" skip (idempotent)\"); return }\n\n args.command = prefixes + UTF8_ENC + \"\\n\" + cleanCmd\n flog(\" INJECTED\")\n },\n }\n}\n\nexport default Utf8EncodingPlugin\n"],"mappings":";AASA,SAAS,sBAAsB;AAC/B,SAAS,cAAc;AACvB,SAAS,YAAY;AAIrB,IAAM,QAAQ,QAAQ,IAAI,wBAAwB;AAClD,IAAM,MAAM,KAAK,OAAO,GAAG,iBAAiB;AAC5C,SAAS,KAAK,KAAa;AACzB,MAAI,CAAC,MAAO;AACZ,MAAI;AAAE,mBAAe,KAAK,KAAI,oBAAI,KAAK,GAAE,YAAY,CAAC,KAAK,GAAG;AAAA,GAAM,MAAM;AAAA,EAAE,QAAQ;AAAA,EAAC;AACvF;AAGA,IAAM,WACJ;AAGF,SAAS,iBAAiB,KAAqD;AAC7E,QAAM,IAAI,IAAI,MAAM,mCAAmC;AACvD,MAAI,EAAG,QAAO,EAAE,UAAU,EAAE,CAAC,GAAG,UAAU,IAAI,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE;AACjE,SAAO,EAAE,UAAU,IAAI,UAAU,IAAI;AACvC;AAEO,IAAM,qBAAqB,OAAO,WAAwB;AAC/D,OAAK,gBAAgB;AAErB,SAAO;AAAA,IACL,uBAAuB,OAAO,OAA4D,WAA0B;AAClH,YAAM,OAAO,OAAO,OAAO,QAAQ,EAAE;AACrC,WAAK,uBAAuB,IAAI,GAAG;AAEnC,UAAI,SAAS,UAAU,SAAS,QAAS;AAEzC,YAAM,OAAO,OAAO;AACpB,UAAI,CAAC,MAAM;AAAE,aAAK,WAAW;AAAG;AAAA,MAAO;AAEvC,YAAM,MAAM,KAAK;AACjB,UAAI,OAAO,QAAQ,YAAY,CAAC,KAAK;AACnC,aAAK,gBAAgB,KAAK,UAAU,OAAO,KAAK,IAAI,CAAC,CAAC,EAAE;AACxD;AAAA,MACF;AAEA,YAAM,EAAE,UAAU,SAAS,IAAI,iBAAiB,GAAG;AACnD,WAAK,WAAW,SAAS,MAAM,GAAG,GAAG,CAAC,EAAE;AAGxC,UAAI,SAAS,SAAS,gBAAgB,GAAG;AAAE,aAAK,qBAAqB;AAAG;AAAA,MAAO;AAE/E,WAAK,UAAU,WAAW,WAAW,OAAO;AAC5C,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AACF;AAEA,IAAO,wBAAQ;","names":[]}
1
+ {"version":3,"sources":["../src/utf8-encoding.ts"],"sourcesContent":["/**\n * OpenCode Plugin — UTF-8 Encoding Fix for Windows + PowerShell\n *\n * 单文件插件,可直接复制到 ~/.config/opencode/plugins/ 使用,无需 npm install。\n *\n * 工作原理:拦截所有 bash/shell 工具调用,在命令前注入 PowerShell\n * UTF-8 编码配置,解决 Windows 下中文/非 ASCII 字符乱码问题。\n */\n\nimport { appendFileSync } from \"node:fs\"\nimport { tmpdir } from \"node:os\"\nimport { join } from \"node:path\"\nimport type { PluginInput } from \"@opencode-ai/plugin\"\n\n// 调试日志(写入临时目录,默认关闭,设 OPENCODE_UTF8_DEBUG=1 开启)\nconst DEBUG = process.env.OPENCODE_UTF8_DEBUG === \"1\"\nconst LOG = join(tmpdir(), \"utf8-plugin.log\")\nfunction flog(msg: string) {\n if (!DEBUG) return\n try { appendFileSync(LOG, `[${new Date().toISOString()}] ${msg}\\n`, \"utf8\") } catch {}\n}\n\n// ── PowerShell UTF-8 编码前缀 ──\n// Console 编码覆盖所有进程;PYTHONIOENCODING 解决 Python 子进程 I/O 乱码\nconst UTF8_ENC =\n \"[Console]::OutputEncoding=[Console]::InputEncoding=[Text.Encoding]::UTF8;\" +\n \"$OutputEncoding=[Text.Encoding]::UTF8;\" +\n \"$env:PYTHONIOENCODING='utf-8';\"\n\n/** 提取 opencode 在命令前追加的 set VAR=\"value\" && 前缀 */\nfunction stripSetPrefixes(cmd: string): { prefixes: string; cleanCmd: string } {\n const m = cmd.match(/^((?:set\\s+\\w+=\"[^\"]*\"\\s*&&\\s*)+)/)\n if (m) return { prefixes: m[1], cleanCmd: cmd.slice(m[1].length) }\n return { prefixes: \"\", cleanCmd: cmd }\n}\n\nexport const Utf8EncodingPlugin = async (_input: PluginInput) => {\n flog(\"=== LOADED ===\")\n\n return {\n \"tool.execute.before\": async (input: { tool: string; sessionID: string; callID: string }, output: { args: any }) => {\n const tool = String(input?.tool ?? \"\")\n flog(`[tool.before] tool=\"${tool}\"`)\n\n if (tool !== \"bash\" && tool !== \"shell\") return\n\n const args = output.args\n if (!args) { flog(\" no args\"); return }\n\n const cmd = args.command\n if (typeof cmd !== \"string\" || !cmd) {\n flog(` args keys: ${JSON.stringify(Object.keys(args))}`)\n return\n }\n\n const { prefixes, cleanCmd } = stripSetPrefixes(cmd)\n flog(` orig: ${cleanCmd.slice(0, 120)}`)\n\n // 防止重复注入\n if (cleanCmd.includes(\"OutputEncoding\")) { flog(\" skip (idempotent)\"); return }\n\n args.command = prefixes + UTF8_ENC + \"\\n\" + cleanCmd\n flog(\" INJECTED\")\n },\n }\n}\n\nexport default Utf8EncodingPlugin\n"],"mappings":";AASA,SAAS,sBAAsB;AAC/B,SAAS,cAAc;AACvB,SAAS,YAAY;AAIrB,IAAM,QAAQ,QAAQ,IAAI,wBAAwB;AAClD,IAAM,MAAM,KAAK,OAAO,GAAG,iBAAiB;AAC5C,SAAS,KAAK,KAAa;AACzB,MAAI,CAAC,MAAO;AACZ,MAAI;AAAE,mBAAe,KAAK,KAAI,oBAAI,KAAK,GAAE,YAAY,CAAC,KAAK,GAAG;AAAA,GAAM,MAAM;AAAA,EAAE,QAAQ;AAAA,EAAC;AACvF;AAIA,IAAM,WACJ;AAKF,SAAS,iBAAiB,KAAqD;AAC7E,QAAM,IAAI,IAAI,MAAM,mCAAmC;AACvD,MAAI,EAAG,QAAO,EAAE,UAAU,EAAE,CAAC,GAAG,UAAU,IAAI,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE;AACjE,SAAO,EAAE,UAAU,IAAI,UAAU,IAAI;AACvC;AAEO,IAAM,qBAAqB,OAAO,WAAwB;AAC/D,OAAK,gBAAgB;AAErB,SAAO;AAAA,IACL,uBAAuB,OAAO,OAA4D,WAA0B;AAClH,YAAM,OAAO,OAAO,OAAO,QAAQ,EAAE;AACrC,WAAK,uBAAuB,IAAI,GAAG;AAEnC,UAAI,SAAS,UAAU,SAAS,QAAS;AAEzC,YAAM,OAAO,OAAO;AACpB,UAAI,CAAC,MAAM;AAAE,aAAK,WAAW;AAAG;AAAA,MAAO;AAEvC,YAAM,MAAM,KAAK;AACjB,UAAI,OAAO,QAAQ,YAAY,CAAC,KAAK;AACnC,aAAK,gBAAgB,KAAK,UAAU,OAAO,KAAK,IAAI,CAAC,CAAC,EAAE;AACxD;AAAA,MACF;AAEA,YAAM,EAAE,UAAU,SAAS,IAAI,iBAAiB,GAAG;AACnD,WAAK,WAAW,SAAS,MAAM,GAAG,GAAG,CAAC,EAAE;AAGxC,UAAI,SAAS,SAAS,gBAAgB,GAAG;AAAE,aAAK,qBAAqB;AAAG;AAAA,MAAO;AAE/E,WAAK,UAAU,WAAW,WAAW,OAAO;AAC5C,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AACF;AAEA,IAAO,wBAAQ;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-windows-encoding",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "OpenCode plugin to fix UTF-8 encoding issues in PowerShell on Windows",
5
5
  "type": "module",
6
6
  "main": "./dist/utf8-encoding.js",