opencode-chat-channel 1.2.13 → 1.2.15

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
@@ -35,7 +35,12 @@ Since this is an **opencode plugin**, opencode handles installation automaticall
35
35
 
36
36
  #### Step 1: Add to `opencode.json`
37
37
 
38
- Edit `~/.config/opencode/opencode.json` and add the plugin:
38
+ Edit the opencode config file and add the plugin:
39
+
40
+ | Platform | Path |
41
+ |----------|------|
42
+ | macOS / Linux | `~/.config/opencode/opencode.json` |
43
+ | Windows | `%APPDATA%\opencode\opencode.json` |
39
44
 
40
45
  ```json
41
46
  {
@@ -49,7 +54,12 @@ opencode will pull and install the package automatically on next startup.
49
54
 
50
55
  #### Step 2: Select channels to enable
51
56
 
52
- Add `CHAT_CHANNELS` to `~/.config/opencode/.env` to control which channels are active:
57
+ Add `CHAT_CHANNELS` to your opencode `.env` file to control which channels are active:
58
+
59
+ | Platform | Path |
60
+ |----------|------|
61
+ | macOS / Linux | `~/.config/opencode/.env` |
62
+ | Windows | `%APPDATA%\opencode\.env` |
53
63
 
54
64
  ```bash
55
65
  # ~/.config/opencode/.env
@@ -92,7 +102,8 @@ See the [Feishu Configuration](#feishu-configuration) section below.
92
102
  **App ID** (non-sensitive, store in `.env`):
93
103
 
94
104
  ```bash
95
- # ~/.config/opencode/.env
105
+ # macOS / Linux: ~/.config/opencode/.env
106
+ # Windows: %APPDATA%\opencode\.env
96
107
  FEISHU_APP_ID=cli_xxxxxxxxxxxxxxxx
97
108
 
98
109
  # Optional: custom opencode API URL (default: http://localhost:4321)
@@ -101,17 +112,19 @@ FEISHU_APP_ID=cli_xxxxxxxxxxxxxxxx
101
112
 
102
113
  **App Secret** — choose the method for your platform:
103
114
 
104
- | Platform | Method | Command |
105
- |----------|--------|---------|
115
+ | Platform | Method | Command / Location |
116
+ |----------|--------|--------------------|
106
117
  | macOS | Keychain (recommended) | `security add-generic-password -a chat-channel -s opencode-chat-channel -w <secret> -U` |
107
- | Windows / Linux | `.env` file | Add `FEISHU_APP_SECRET=<secret>` to `~/.config/opencode/.env` |
118
+ | Windows | `.env` file | Add `FEISHU_APP_SECRET=<secret>` to `%APPDATA%\opencode\.env` |
119
+ | Linux | `.env` file | Add `FEISHU_APP_SECRET=<secret>` to `~/.config/opencode/.env` |
108
120
  | All platforms | Environment variable | Set `FEISHU_APP_SECRET=<secret>` before launching opencode |
109
121
 
110
122
  > **Priority**: environment variable → macOS Keychain → `.env` file value (already loaded as env var).
111
123
  > The plugin tries each in order and uses the first one found.
112
124
 
113
125
  > ⚠️ If you store the secret in `.env`, ensure the file has restricted permissions:
114
- > `chmod 600 ~/.config/opencode/.env`
126
+ > - macOS/Linux: `chmod 600 ~/.config/opencode/.env`
127
+ > - Windows: right-click the file → Properties → Security → restrict to your user only
115
128
 
116
129
  **macOS Keychain** (verify):
117
130
 
@@ -212,7 +225,12 @@ opencode AI (Sisyphus)
212
225
 
213
226
  #### 第一步:添加到 `opencode.json`
214
227
 
215
- 编辑 `~/.config/opencode/opencode.json`,在 `plugin` 数组中添加:
228
+ 编辑 opencode 配置文件,在 `plugin` 数组中添加:
229
+
230
+ | 平台 | 路径 |
231
+ |------|------|
232
+ | macOS / Linux | `~/.config/opencode/opencode.json` |
233
+ | Windows | `%APPDATA%\opencode\opencode.json` |
216
234
 
217
235
  ```json
218
236
  {
@@ -226,7 +244,12 @@ opencode AI (Sisyphus)
226
244
 
227
245
  #### 第二步:选择要启用的渠道
228
246
 
229
- `~/.config/opencode/.env` 中配置 `CHAT_CHANNELS`,指定要开启哪些渠道:
247
+ 在 opencode 的 `.env` 文件中配置 `CHAT_CHANNELS`,指定要开启哪些渠道:
248
+
249
+ | 平台 | 路径 |
250
+ |------|------|
251
+ | macOS / Linux | `~/.config/opencode/.env` |
252
+ | Windows | `%APPDATA%\opencode\.env` |
230
253
 
231
254
  ```bash
232
255
  # ~/.config/opencode/.env
@@ -269,7 +292,8 @@ CHAT_CHANNELS=feishu
269
292
  **App ID**(非敏感,明文存 `.env`):
270
293
 
271
294
  ```bash
272
- # ~/.config/opencode/.env
295
+ # macOS / Linux: ~/.config/opencode/.env
296
+ # Windows: %APPDATA%\opencode\.env
273
297
  FEISHU_APP_ID=cli_xxxxxxxxxxxxxxxx
274
298
 
275
299
  # 可选:自定义 opencode API 地址(默认:http://localhost:4321)
@@ -278,19 +302,21 @@ FEISHU_APP_ID=cli_xxxxxxxxxxxxxxxx
278
302
 
279
303
  **App Secret**—按使用的平台选择存储方式:
280
304
 
281
- | 平台 | 方式 | 命令 |
282
- |------|------|------|
283
- | macOS | 钒匙串(推荐,不落盘明文) | `security add-generic-password -a chat-channel -s opencode-chat-channel -w <secret> -U` |
284
- | Windows / Linux | 写入 `.env` 文件 | 在 `~/.config/opencode/.env` 中添加 `FEISHU_APP_SECRET=<secret>` |
305
+ | 平台 | 方式 | 命令 / 路径 |
306
+ |------|------|-------------|
307
+ | macOS | 钥匙串(推荐,不落盘明文) | `security add-generic-password -a chat-channel -s opencode-chat-channel -w <secret> -U` |
308
+ | Windows | 写入 `.env` 文件 | 在 `%APPDATA%\opencode\.env` 中添加 `FEISHU_APP_SECRET=<secret>` |
309
+ | Linux | 写入 `.env` 文件 | 在 `~/.config/opencode/.env` 中添加 `FEISHU_APP_SECRET=<secret>` |
285
310
  | 所有平台 | 环境变量 | 启动 opencode 前设置 `FEISHU_APP_SECRET=<secret>` |
286
311
 
287
- > **读取优先级**:环境变量 → macOS 钒匙串 → `.env` 文件(已在插件启动时自动读入环境变量)。
312
+ > **读取优先级**:环境变量 → macOS 钥匙串 → `.env` 文件(已在插件启动时自动读入环境变量)。
288
313
  > 插件依次尝试,找到第一个有效值即停止。
289
314
 
290
315
  > ⚠️ 如果将 Secret 写入 `.env`,建议限制文件权限:
291
- > `chmod 600 ~/.config/opencode/.env`
316
+ > - macOS/Linux:`chmod 600 ~/.config/opencode/.env`
317
+ > - Windows:右键文件 → 属性 → 安全,限制为仅当前用户可读
292
318
 
293
- **macOS 钒匙串**验证:
319
+ **macOS 钥匙串**验证:
294
320
 
295
321
  ```bash
296
322
  security find-generic-password -a chat-channel -s opencode-chat-channel -w
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAiUlD,eAAO,MAAM,iBAAiB,EAAE,MA8K/B,CAAC;AAEF,eAAe,iBAAiB,CAAC;AAMjC,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAiUlD,eAAO,MAAM,iBAAiB,EAAE,MA4K/B,CAAC;AAEF,eAAe,iBAAiB,CAAC;AAMjC,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,9 +1,31 @@
1
1
  // src/index.ts
2
- import { join } from "path";
2
+ import { join as join2 } from "path";
3
3
 
4
4
  // src/session-manager.ts
5
5
  import { readFileSync, appendFileSync, mkdirSync } from "fs";
6
- var LOG_DIR = `${process.env["HOME"] ?? "/tmp"}/.local/share/opencode/log`;
6
+ import { join } from "path";
7
+ import { homedir } from "os";
8
+ function getOpencodeConfigDir() {
9
+ if (process.platform === "win32") {
10
+ const appdata = process.env["APPDATA"];
11
+ if (appdata)
12
+ return join(appdata, "opencode");
13
+ return join(homedir(), "AppData", "Roaming", "opencode");
14
+ }
15
+ const xdgConfig = process.env["XDG_CONFIG_HOME"];
16
+ return join(xdgConfig ?? join(homedir(), ".config"), "opencode");
17
+ }
18
+ function getOpencodeDataDir() {
19
+ if (process.platform === "win32") {
20
+ const localappdata = process.env["LOCALAPPDATA"];
21
+ if (localappdata)
22
+ return join(localappdata, "opencode");
23
+ return join(homedir(), "AppData", "Local", "opencode");
24
+ }
25
+ const xdgData = process.env["XDG_DATA_HOME"];
26
+ return join(xdgData ?? join(homedir(), ".local", "share"), "opencode");
27
+ }
28
+ var LOG_DIR = join(getOpencodeDataDir(), "log");
7
29
  var LOG_FILE = `${LOG_DIR}/chat-channel.log`;
8
30
  function fileLog(level, message) {
9
31
  try {
@@ -522,8 +544,7 @@ async function waitForSessionAndReply(client, channel, sessionId, replyTarget, t
522
544
  log("info", `[${channel.name}] session 完成,卡片已更新,跳过文本回复`);
523
545
  }
524
546
  var ChatChannelPlugin = async ({ client }) => {
525
- const configDir = join(process.env["HOME"] ?? `/Users/${process.env["USER"] ?? "unknown"}`, ".config", "opencode");
526
- loadDotEnv(join(configDir, ".env"));
547
+ loadDotEnv(join2(getOpencodeConfigDir(), ".env"));
527
548
  const enabledNames = resolveEnabledChannels(client);
528
549
  const factories = enabledNames ? enabledNames.map((name) => [name, CHANNEL_REGISTRY[name]]) : Object.entries(CHANNEL_REGISTRY);
529
550
  if (enabledNames) {
@@ -5,6 +5,20 @@
5
5
  * 与具体渠道无关,所有 channel 实现共享同一套逻辑。
6
6
  */
7
7
  import type { PluginClient } from "./types.js";
8
+ /**
9
+ * 复现 opencode 使用的 xdg-basedir 路径逻辑,无需额外依赖。
10
+ * - Windows : %APPDATA%\opencode (xdgConfig = APPDATA)
11
+ * - macOS/Linux: $XDG_CONFIG_HOME/opencode 或 ~/.config/opencode
12
+ *
13
+ * 与 opencode 源码 packages/opencode/src/global/index.ts 保持一致。
14
+ */
15
+ export declare function getOpencodeConfigDir(): string;
16
+ /**
17
+ * 复现 opencode 使用的 xdg-basedir 数据目录逻辑。
18
+ * - Windows : %LOCALAPPDATA%\opencode (xdgData = LOCALAPPDATA)
19
+ * - macOS/Linux: $XDG_DATA_HOME/opencode 或 ~/.local/share/opencode
20
+ */
21
+ export declare function getOpencodeDataDir(): string;
8
22
  /**
9
23
  * 写日志到文件(同步追加),同时调用 client.app.log()。
10
24
  * 用于替代纯依赖 client.app.log() 的场景,确保日志落盘可查。
@@ -34,8 +48,9 @@ export declare class SessionManager {
34
48
  */
35
49
  export declare function extractResponseText(parts: unknown[]): string;
36
50
  /**
37
- * 从 ~/.config/opencode/.env 读取环境变量并注入 process.env。
51
+ * 从 opencode 配置目录下的 .env 文件读取环境变量并注入 process.env。
38
52
  * opencode 不会自动加载该文件,需插件自行调用。
53
+ * 使用 getOpencodeConfigDir() 获取正确路径(跨平台)。
39
54
  */
40
55
  export declare function loadDotEnv(envPath: string): void;
41
56
  //# sourceMappingURL=session-manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAO/C;;;GAGG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAQ/E;AAgBD,qBAAa,cAAc;IAOvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAR1B;;;;OAIG;gBAEgB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MACxB;IAGxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAE3D,wCAAwC;IAClC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA6BlD,2BAA2B;IAC3B,OAAO,IAAI,IAAI;IASf,oDAAoD;IACpD,gBAAgB,CAAC,UAAU,SAAiB,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC;CAG9E;AAID;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,CAO5D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAiBhD"}
1
+ {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C;;;;;;GAMG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAU7C;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAQ3C;AAOD;;;GAGG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAQ/E;AAgBD,qBAAa,cAAc;IAOvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAR1B;;;;OAIG;gBAEgB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MACxB;IAGxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAE3D,wCAAwC;IAClC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA6BlD,2BAA2B;IAC3B,OAAO,IAAI,IAAI;IASf,oDAAoD;IACpD,gBAAgB,CAAC,UAAU,SAAiB,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC;CAG9E;AAID;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,CAO5D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAiBhD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-chat-channel",
3
- "version": "1.2.13",
3
+ "version": "1.2.15",
4
4
  "description": "opencode plugin — multi-channel bot (Feishu/Lark, WeCom) with extensible ChatChannel interface",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",