opencode-windows-encoding 1.0.1 → 1.0.3

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
@@ -53,6 +53,23 @@ Or with a specific version:
53
53
 
54
54
  After adding the plugin, restart OpenCode. All subsequent shell commands will use UTF-8 encoding automatically.
55
55
 
56
+ ## 本地使用(复制即用)
57
+
58
+ 本项目是单文件插件,`src/utf8-encoding.ts` 可以直接复制到 OpenCode 插件目录使用,零依赖:
59
+
60
+ **PowerShell:**
61
+ ```powershell
62
+ Copy-Item src/utf8-encoding.ts $env:USERPROFILE/.config/opencode/plugins/utf8-encoding.ts
63
+ ```
64
+
65
+ **Bash / WSL:**
66
+ ```bash
67
+ cp src/utf8-encoding.ts ~/.config/opencode/plugins/utf8-encoding.ts
68
+ ```
69
+
70
+ 重启 OpenCode 即生效。无需 `npm install`,无需构建。
71
+
72
+ `src/utf8-encoding.ts` 仅使用 Node.js 内置模块(`node:fs`, `node:os`, `node:path`),无任何 npm 依赖。
56
73
  ## Requirements
57
74
 
58
75
  - **OpenCode** (any recent version with plugin support)
@@ -75,24 +92,14 @@ npm run typecheck
75
92
  npm run dev
76
93
  ```
77
94
 
78
- ### Local plugin testing
79
-
80
- To test locally without publishing, reference the build output in your `opencode.jsonc`:
81
-
82
- ```jsonc
83
- {
84
- "plugin": [
85
- "/path/to/opencode-windows-encoding/dist/index.js"
86
- ]
87
- }
88
- ```
95
+ ### 本地开发测试
89
96
 
90
- Or reference the TypeScript source directly:
97
+ 直接引用源码即可:
91
98
 
92
99
  ```jsonc
93
100
  {
94
101
  "plugin": [
95
- "/path/to/opencode-windows-encoding/src/index.ts"
102
+ "/path/to/opencode-windows-encoding/src/utf8-encoding.ts"
96
103
  ]
97
104
  }
98
105
  ```
@@ -0,0 +1,13 @@
1
+ /**
2
+ * OpenCode Plugin — UTF-8 Encoding Fix for Windows + PowerShell
3
+ *
4
+ * 单文件插件,可直接复制到 ~/.config/opencode/plugins/ 使用,无需 npm install。
5
+ *
6
+ * 工作原理:拦截所有 bash/shell 工具调用,在命令前注入 PowerShell
7
+ * UTF-8 编码配置,解决 Windows 下中文/非 ASCII 字符乱码问题。
8
+ */
9
+ declare const Utf8EncodingPlugin: () => Promise<{
10
+ "tool.execute.before": (input: Record<string, unknown>, output: Record<string, unknown>) => Promise<void>;
11
+ }>;
12
+
13
+ export { Utf8EncodingPlugin };
@@ -10,16 +10,15 @@ function flog(msg) {
10
10
  } catch {
11
11
  }
12
12
  }
13
+ var UTF8_ENC = "[Console]::OutputEncoding=[Console]::InputEncoding=[Text.Encoding]::UTF8;$OutputEncoding=[Text.Encoding]::UTF8;";
14
+ function stripSetPrefixes(cmd) {
15
+ const m = cmd.match(/^((?:set\s+\w+="[^"]*"\s*&&\s*)+)/);
16
+ if (m) return { prefixes: m[1], cleanCmd: cmd.slice(m[1].length) };
17
+ return { prefixes: "", cleanCmd: cmd };
18
+ }
13
19
  var Utf8EncodingPlugin = async () => {
14
20
  flog("=== LOADED ===");
15
- function stripSetPrefixes(cmd) {
16
- const m = cmd.match(/^((?:set\s+\w+="[^"]*"\s*&&\s*)+)/);
17
- if (m) return { prefixes: m[1], cleanCmd: cmd.slice(m[1].length) };
18
- return { prefixes: "", cleanCmd: cmd };
19
- }
20
- const UTF8_ENC = "[Console]::OutputEncoding=[Console]::InputEncoding=[Text.Encoding]::UTF8;$OutputEncoding=[Text.Encoding]::UTF8;";
21
21
  return {
22
- // ── LLM 工具调用 (bash/shell) ──
23
22
  "tool.execute.before": async (input, output) => {
24
23
  const tool = String(input?.tool ?? "");
25
24
  flog(`[tool.before] tool="${tool}"`);
@@ -41,11 +40,11 @@ var Utf8EncodingPlugin = async () => {
41
40
  return;
42
41
  }
43
42
  args.command = prefixes + UTF8_ENC + cleanCmd;
44
- flog(` INJECTED`);
43
+ flog(" INJECTED");
45
44
  }
46
45
  };
47
46
  };
48
47
  export {
49
48
  Utf8EncodingPlugin
50
49
  };
51
- //# sourceMappingURL=index.js.map
50
+ //# sourceMappingURL=utf8-encoding.js.map
@@ -0,0 +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\"\n\n// ── 调试日志(写入临时目录) ──\nconst LOG = join(tmpdir(), \"utf8-plugin.log\")\nfunction flog(msg: string) {\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 () => {\n flog(\"=== LOADED ===\")\n\n return {\n \"tool.execute.before\": async (input: Record<string, unknown>, output: Record<string, unknown>) => {\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 as Record<string, unknown> | undefined\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 + cleanCmd\n flog(\" INJECTED\")\n },\n }\n}\n"],"mappings":";AASA,SAAS,sBAAsB;AAC/B,SAAS,cAAc;AACvB,SAAS,YAAY;AAGrB,IAAM,MAAM,KAAK,OAAO,GAAG,iBAAiB;AAC5C,SAAS,KAAK,KAAa;AACzB,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,YAAY;AAC5C,OAAK,gBAAgB;AAErB,SAAO;AAAA,IACL,uBAAuB,OAAO,OAAgC,WAAoC;AAChG,YAAM,OAAO,OAAO,OAAO,QAAQ,EAAE;AACrC,WAAK,uBAAuB,IAAI,GAAG;AAEnC,UAAI,SAAS,UAAU,SAAS,QAAS;AAEzC,YAAM,OAAO,QAAQ;AACrB,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;AACrC,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AACF;","names":[]}
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "opencode-windows-encoding",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "OpenCode plugin to fix UTF-8 encoding issues in PowerShell on Windows",
5
5
  "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
6
+ "main": "./dist/utf8-encoding.js",
7
+ "types": "./dist/utf8-encoding.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js"
10
+ "types": "./dist/utf8-encoding.d.ts",
11
+ "import": "./dist/utf8-encoding.js"
12
12
  }
13
13
  },
14
14
  "files": [
@@ -34,9 +34,7 @@
34
34
  "url": "git+https://github.com/Cle2ment/opencode-windows-encoding.git"
35
35
  },
36
36
  "license": "AGPL-3.0",
37
- "dependencies": {
38
- "@opencode-ai/plugin": "^1.17.0"
39
- },
37
+ "dependencies": {},
40
38
  "devDependencies": {
41
39
  "@types/node": "^22.0.0",
42
40
  "tsup": "^8.0.0",
package/dist/index.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import { Plugin } from '@opencode-ai/plugin';
2
-
3
- declare const Utf8EncodingPlugin: Plugin;
4
-
5
- export { Utf8EncodingPlugin };
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utf8-encoding.ts"],"sourcesContent":["import type { Plugin } from \"@opencode-ai/plugin\"\nimport { appendFileSync } from \"node:fs\"\nimport { tmpdir } from \"node:os\"\nimport { join } from \"node:path\"\n\nconst LOG = join(tmpdir(), \"utf8-plugin.log\")\nfunction flog(msg: string) {\n try { appendFileSync(LOG, `[${new Date().toISOString()}] ${msg}\\n`, \"utf8\") } catch {}\n}\n\nexport const Utf8EncodingPlugin: Plugin = async () => {\n flog(\"=== LOADED ===\")\n\n function 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\n const UTF8_ENC = \"[Console]::OutputEncoding=[Console]::InputEncoding=[Text.Encoding]::UTF8;$OutputEncoding=[Text.Encoding]::UTF8;\"\n\n return {\n // ── LLM 工具调用 (bash/shell) ──\n \"tool.execute.before\": async (input, output) => {\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 as Record<string, unknown> | undefined\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 if (cleanCmd.includes(\"OutputEncoding\")) { flog(\" skip (idempotent)\"); return }\n\n args.command = prefixes + UTF8_ENC + cleanCmd\n flog(` INJECTED`)\n },\n }\n}\n"],"mappings":";AACA,SAAS,sBAAsB;AAC/B,SAAS,cAAc;AACvB,SAAS,YAAY;AAErB,IAAM,MAAM,KAAK,OAAO,GAAG,iBAAiB;AAC5C,SAAS,KAAK,KAAa;AACzB,MAAI;AAAE,mBAAe,KAAK,KAAI,oBAAI,KAAK,GAAE,YAAY,CAAC,KAAK,GAAG;AAAA,GAAM,MAAM;AAAA,EAAE,QAAQ;AAAA,EAAC;AACvF;AAEO,IAAM,qBAA6B,YAAY;AACpD,OAAK,gBAAgB;AAErB,WAAS,iBAAiB,KAAqD;AAC7E,UAAM,IAAI,IAAI,MAAM,mCAAmC;AACvD,QAAI,EAAG,QAAO,EAAE,UAAU,EAAE,CAAC,GAAG,UAAU,IAAI,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE;AACjE,WAAO,EAAE,UAAU,IAAI,UAAU,IAAI;AAAA,EACvC;AAEA,QAAM,WAAW;AAEjB,SAAO;AAAA;AAAA,IAEL,uBAAuB,OAAO,OAAO,WAAW;AAC9C,YAAM,OAAO,OAAO,OAAO,QAAQ,EAAE;AACrC,WAAK,uBAAuB,IAAI,GAAG;AAEnC,UAAI,SAAS,UAAU,SAAS,QAAS;AAEzC,YAAM,OAAO,QAAQ;AACrB,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;AAExC,UAAI,SAAS,SAAS,gBAAgB,GAAG;AAAE,aAAK,qBAAqB;AAAG;AAAA,MAAO;AAE/E,WAAK,UAAU,WAAW,WAAW;AACrC,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AACF;","names":[]}