@feihan-im/openclaw-plugin 0.1.0 → 0.1.2

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.en.md CHANGED
@@ -8,7 +8,9 @@
8
8
 
9
9
  [中文](./README.md) | English
10
10
 
11
- Feihan IM channel plugin for OpenClaw. Connects a Feihan bot to OpenClaw's AI agent pipeline so you can chat with your agent through Feihan.
11
+ Feihan is a secure, self-hosted productivity platform for teams, integrating instant messaging, organizational structures, video conferencing, and file storage.
12
+
13
+ Feihan IM channel plugin for OpenClaw. Connects a Feihan bot to OpenClaw's AI agent pipeline so you can chat with your agent through Feihan. See the [Setup Tutorial](https://feihanim.cn/docs/admin/bots/openclaw) for how to connect Feihan to OpenClaw.
12
14
 
13
15
  ## Features
14
16
 
@@ -50,7 +52,7 @@ Or manually edit `~/.openclaw/openclaw.json`:
50
52
  "feihan": {
51
53
  "appId": "your_app_id",
52
54
  "appSecret": "your_app_secret",
53
- "backendUrl": "http://your-feihan-backend:21000"
55
+ "backendUrl": "https://your-backend-url.com"
54
56
  }
55
57
  }
56
58
  }
@@ -70,13 +72,13 @@ openclaw gateway restart
70
72
  "feihan": {
71
73
  "appId": "111111",
72
74
  "appSecret": "secret-1",
73
- "backendUrl": "http://backend-1:21000",
75
+ "backendUrl": "https://your-backend-url.com",
74
76
  "accounts": {
75
77
  "bot2": {
76
78
  "enabled": true,
77
79
  "appId": "222222",
78
80
  "appSecret": "secret-2",
79
- "backendUrl": "http://backend-2:21000"
81
+ "backendUrl": "https://your-backend-url.com"
80
82
  }
81
83
  }
82
84
  }
package/README.md CHANGED
@@ -8,7 +8,9 @@
8
8
 
9
9
  中文 | [English](./README.en.md)
10
10
 
11
- 飞函 IM 频道插件,用于 OpenClaw。将飞函机器人接入 OpenClaw 的 AI Agent 管线,通过飞函与 Agent 对话。
11
+ 飞函,是安全稳定的私有化一站式办公平台,功能包括即时通讯、组织架构、音视频会议、网盘等。
12
+
13
+ 飞函 IM 频道插件,用于 OpenClaw。将飞函机器人接入 OpenClaw 的 AI Agent 管线,通过飞函与 Agent 对话。请参阅[配置教程](https://feihanim.cn/docs/admin/bots/openclaw)了解如何将飞函连接到 OpenClaw。
12
14
 
13
15
  ## 功能
14
16
 
@@ -50,7 +52,7 @@ openclaw channels add --channel feihan
50
52
  "feihan": {
51
53
  "appId": "your_app_id",
52
54
  "appSecret": "your_app_secret",
53
- "backendUrl": "http://your-feihan-backend:21000"
55
+ "backendUrl": "https://your-backend-url.com"
54
56
  }
55
57
  }
56
58
  }
@@ -70,13 +72,13 @@ openclaw gateway restart
70
72
  "feihan": {
71
73
  "appId": "111111",
72
74
  "appSecret": "secret-1",
73
- "backendUrl": "http://backend-1:21000",
75
+ "backendUrl": "https://your-backend-url.com",
74
76
  "accounts": {
75
77
  "bot2": {
76
78
  "enabled": true,
77
79
  "appId": "222222",
78
80
  "appSecret": "secret-2",
79
- "backendUrl": "http://backend-2:21000"
81
+ "backendUrl": "https://your-backend-url.com"
80
82
  }
81
83
  }
82
84
  }
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/setup-entry.ts
21
+ var setup_entry_exports = {};
22
+ __export(setup_entry_exports, {
23
+ default: () => setup_entry_default
24
+ });
25
+ module.exports = __toCommonJS(setup_entry_exports);
26
+ var import_core = require("openclaw/plugin-sdk/core");
27
+ var setup_entry_default = (0, import_core.defineSetupPluginEntry)({
28
+ async onSetup(context) {
29
+ const appId = await context.prompt({
30
+ type: "text",
31
+ message: "Enter your Feihan App ID:",
32
+ validate: (val) => val.length > 0 || "This field is required"
33
+ });
34
+ const appSecret = await context.prompt({
35
+ type: "password",
36
+ message: "Enter your Feihan App Secret:",
37
+ validate: (val) => val.length > 0 || "This field is required"
38
+ });
39
+ const backendUrl = await context.prompt({
40
+ type: "text",
41
+ message: "Enter Feihan backend server URL:",
42
+ validate: (val) => {
43
+ if (val.length === 0) return "This field is required";
44
+ try {
45
+ new URL(val);
46
+ return true;
47
+ } catch {
48
+ return "Please enter a valid URL";
49
+ }
50
+ }
51
+ });
52
+ const enableEncryption = await context.prompt({
53
+ type: "confirm",
54
+ message: "Enable message encryption?",
55
+ default: true
56
+ });
57
+ await context.updateConfig("channels.feihan.appId", appId);
58
+ await context.updateConfig("channels.feihan.appSecret", appSecret);
59
+ await context.updateConfig("channels.feihan.backendUrl", backendUrl);
60
+ await context.updateConfig("channels.feihan.enableEncryption", enableEncryption);
61
+ await context.updateConfig("channels.feihan.enabled", true);
62
+ console.log("\u2705 Feihan channel configuration saved successfully!");
63
+ console.log("\u{1F4C4} Config file: ~/.openclaw/openclaw.json");
64
+ console.log("\u{1F4D6} Deploy docs: https://feihanim.cn/docs/admin/bots/openclaw");
65
+ }
66
+ });
67
+ //# sourceMappingURL=setup-entry.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/setup-entry.ts"],"sourcesContent":["// Copyright (c) 2026 上海飞函安全科技有限公司 (Shanghai Feihan Security Technology Co., Ltd.)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { defineSetupPluginEntry } from \"openclaw/plugin-sdk/core\";\n\nexport default defineSetupPluginEntry({\n async onSetup(context) {\n const appId = await context.prompt({\n type: \"text\",\n message: \"Enter your Feihan App ID:\",\n validate: (val: string) => val.length > 0 || \"This field is required\",\n });\n\n const appSecret = await context.prompt({\n type: \"password\",\n message: \"Enter your Feihan App Secret:\",\n validate: (val: string) => val.length > 0 || \"This field is required\",\n });\n\n const backendUrl = await context.prompt({\n type: \"text\",\n message: \"Enter Feihan backend server URL:\",\n validate: (val: string) => {\n if (val.length === 0) return \"This field is required\";\n try {\n new URL(val);\n return true;\n } catch {\n return \"Please enter a valid URL\";\n }\n },\n });\n\n const enableEncryption = await context.prompt({\n type: \"confirm\",\n message: \"Enable message encryption?\",\n default: true,\n });\n\n // Write config to ~/.openclaw/openclaw.json\n await context.updateConfig(\"channels.feihan.appId\", appId);\n await context.updateConfig(\"channels.feihan.appSecret\", appSecret);\n await context.updateConfig(\"channels.feihan.backendUrl\", backendUrl);\n await context.updateConfig(\"channels.feihan.enableEncryption\", enableEncryption);\n await context.updateConfig(\"channels.feihan.enabled\", true);\n\n console.log(\"✅ Feihan channel configuration saved successfully!\");\n console.log(\"📄 Config file: ~/.openclaw/openclaw.json\");\n console.log(\"📖 Deploy docs: https://feihanim.cn/docs/admin/bots/openclaw\");\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,kBAAuC;AAEvC,IAAO,0BAAQ,oCAAuB;AAAA,EACpC,MAAM,QAAQ,SAAS;AACrB,UAAM,QAAQ,MAAM,QAAQ,OAAO;AAAA,MACjC,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU,CAAC,QAAgB,IAAI,SAAS,KAAK;AAAA,IAC/C,CAAC;AAED,UAAM,YAAY,MAAM,QAAQ,OAAO;AAAA,MACrC,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU,CAAC,QAAgB,IAAI,SAAS,KAAK;AAAA,IAC/C,CAAC;AAED,UAAM,aAAa,MAAM,QAAQ,OAAO;AAAA,MACtC,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU,CAAC,QAAgB;AACzB,YAAI,IAAI,WAAW,EAAG,QAAO;AAC7B,YAAI;AACF,cAAI,IAAI,GAAG;AACX,iBAAO;AAAA,QACT,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AAED,UAAM,mBAAmB,MAAM,QAAQ,OAAO;AAAA,MAC5C,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AAGD,UAAM,QAAQ,aAAa,yBAAyB,KAAK;AACzD,UAAM,QAAQ,aAAa,6BAA6B,SAAS;AACjE,UAAM,QAAQ,aAAa,8BAA8B,UAAU;AACnE,UAAM,QAAQ,aAAa,oCAAoC,gBAAgB;AAC/E,UAAM,QAAQ,aAAa,2BAA2B,IAAI;AAE1D,YAAQ,IAAI,yDAAoD;AAChE,YAAQ,IAAI,kDAA2C;AACvD,YAAQ,IAAI,qEAA8D;AAAA,EAC5E;AACF,CAAC;","names":[]}
@@ -0,0 +1,5 @@
1
+ import * as openclaw_plugin_sdk_core from 'openclaw/plugin-sdk/core';
2
+
3
+ declare const _default: openclaw_plugin_sdk_core.SetupPluginEntry;
4
+
5
+ export { _default as default };
@@ -0,0 +1,5 @@
1
+ import * as openclaw_plugin_sdk_core from 'openclaw/plugin-sdk/core';
2
+
3
+ declare const _default: openclaw_plugin_sdk_core.SetupPluginEntry;
4
+
5
+ export { _default as default };
@@ -0,0 +1,46 @@
1
+ // src/setup-entry.ts
2
+ import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
3
+ var setup_entry_default = defineSetupPluginEntry({
4
+ async onSetup(context) {
5
+ const appId = await context.prompt({
6
+ type: "text",
7
+ message: "Enter your Feihan App ID:",
8
+ validate: (val) => val.length > 0 || "This field is required"
9
+ });
10
+ const appSecret = await context.prompt({
11
+ type: "password",
12
+ message: "Enter your Feihan App Secret:",
13
+ validate: (val) => val.length > 0 || "This field is required"
14
+ });
15
+ const backendUrl = await context.prompt({
16
+ type: "text",
17
+ message: "Enter Feihan backend server URL:",
18
+ validate: (val) => {
19
+ if (val.length === 0) return "This field is required";
20
+ try {
21
+ new URL(val);
22
+ return true;
23
+ } catch {
24
+ return "Please enter a valid URL";
25
+ }
26
+ }
27
+ });
28
+ const enableEncryption = await context.prompt({
29
+ type: "confirm",
30
+ message: "Enable message encryption?",
31
+ default: true
32
+ });
33
+ await context.updateConfig("channels.feihan.appId", appId);
34
+ await context.updateConfig("channels.feihan.appSecret", appSecret);
35
+ await context.updateConfig("channels.feihan.backendUrl", backendUrl);
36
+ await context.updateConfig("channels.feihan.enableEncryption", enableEncryption);
37
+ await context.updateConfig("channels.feihan.enabled", true);
38
+ console.log("\u2705 Feihan channel configuration saved successfully!");
39
+ console.log("\u{1F4C4} Config file: ~/.openclaw/openclaw.json");
40
+ console.log("\u{1F4D6} Deploy docs: https://feihanim.cn/docs/admin/bots/openclaw");
41
+ }
42
+ });
43
+ export {
44
+ setup_entry_default as default
45
+ };
46
+ //# sourceMappingURL=setup-entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/setup-entry.ts"],"sourcesContent":["// Copyright (c) 2026 上海飞函安全科技有限公司 (Shanghai Feihan Security Technology Co., Ltd.)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { defineSetupPluginEntry } from \"openclaw/plugin-sdk/core\";\n\nexport default defineSetupPluginEntry({\n async onSetup(context) {\n const appId = await context.prompt({\n type: \"text\",\n message: \"Enter your Feihan App ID:\",\n validate: (val: string) => val.length > 0 || \"This field is required\",\n });\n\n const appSecret = await context.prompt({\n type: \"password\",\n message: \"Enter your Feihan App Secret:\",\n validate: (val: string) => val.length > 0 || \"This field is required\",\n });\n\n const backendUrl = await context.prompt({\n type: \"text\",\n message: \"Enter Feihan backend server URL:\",\n validate: (val: string) => {\n if (val.length === 0) return \"This field is required\";\n try {\n new URL(val);\n return true;\n } catch {\n return \"Please enter a valid URL\";\n }\n },\n });\n\n const enableEncryption = await context.prompt({\n type: \"confirm\",\n message: \"Enable message encryption?\",\n default: true,\n });\n\n // Write config to ~/.openclaw/openclaw.json\n await context.updateConfig(\"channels.feihan.appId\", appId);\n await context.updateConfig(\"channels.feihan.appSecret\", appSecret);\n await context.updateConfig(\"channels.feihan.backendUrl\", backendUrl);\n await context.updateConfig(\"channels.feihan.enableEncryption\", enableEncryption);\n await context.updateConfig(\"channels.feihan.enabled\", true);\n\n console.log(\"✅ Feihan channel configuration saved successfully!\");\n console.log(\"📄 Config file: ~/.openclaw/openclaw.json\");\n console.log(\"📖 Deploy docs: https://feihanim.cn/docs/admin/bots/openclaw\");\n },\n});\n"],"mappings":";AAGA,SAAS,8BAA8B;AAEvC,IAAO,sBAAQ,uBAAuB;AAAA,EACpC,MAAM,QAAQ,SAAS;AACrB,UAAM,QAAQ,MAAM,QAAQ,OAAO;AAAA,MACjC,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU,CAAC,QAAgB,IAAI,SAAS,KAAK;AAAA,IAC/C,CAAC;AAED,UAAM,YAAY,MAAM,QAAQ,OAAO;AAAA,MACrC,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU,CAAC,QAAgB,IAAI,SAAS,KAAK;AAAA,IAC/C,CAAC;AAED,UAAM,aAAa,MAAM,QAAQ,OAAO;AAAA,MACtC,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU,CAAC,QAAgB;AACzB,YAAI,IAAI,WAAW,EAAG,QAAO;AAC7B,YAAI;AACF,cAAI,IAAI,GAAG;AACX,iBAAO;AAAA,QACT,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AAED,UAAM,mBAAmB,MAAM,QAAQ,OAAO;AAAA,MAC5C,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AAGD,UAAM,QAAQ,aAAa,yBAAyB,KAAK;AACzD,UAAM,QAAQ,aAAa,6BAA6B,SAAS;AACjE,UAAM,QAAQ,aAAa,8BAA8B,UAAU;AACnE,UAAM,QAAQ,aAAa,oCAAoC,gBAAgB;AAC/E,UAAM,QAAQ,aAAa,2BAA2B,IAAI;AAE1D,YAAQ,IAAI,yDAAoD;AAChE,YAAQ,IAAI,kDAA2C;AACvD,YAAQ,IAAI,qEAA8D;AAAA,EAC5E;AACF,CAAC;","names":[]}
@@ -0,0 +1,69 @@
1
+ {
2
+ "id": "feihan",
3
+ "name": "Feihan Channel",
4
+ "description": "Connect OpenClaw with Feihan",
5
+ "version": "0.1.0",
6
+ "kind": "channel",
7
+ "channels": ["feihan"],
8
+ "configSchema": {
9
+ "type": "object",
10
+ "additionalProperties": false,
11
+ "required": ["appId", "appSecret", "backendUrl"],
12
+ "properties": {
13
+ "enabled": {
14
+ "type": "boolean",
15
+ "description": "Enable this channel",
16
+ "default": true
17
+ },
18
+ "appId": {
19
+ "type": "string",
20
+ "description": "Feihan application ID"
21
+ },
22
+ "appSecret": {
23
+ "type": "string",
24
+ "description": "Feihan application secret"
25
+ },
26
+ "backendUrl": {
27
+ "type": "string",
28
+ "description": "Feihan backend URL (e.g., https://your-backend-url.com)"
29
+ },
30
+ "enableEncryption": {
31
+ "type": "boolean",
32
+ "description": "Enable message encryption",
33
+ "default": true
34
+ },
35
+ "requestTimeout": {
36
+ "type": "number",
37
+ "description": "Request timeout in milliseconds",
38
+ "default": 30000
39
+ },
40
+ "requireMention": {
41
+ "type": "boolean",
42
+ "description": "Require @mention in group chats before responding",
43
+ "default": true
44
+ },
45
+ "accounts": {
46
+ "type": "object",
47
+ "description": "Multi-account configuration",
48
+ "additionalProperties": {
49
+ "type": "object",
50
+ "properties": {
51
+ "enabled": { "type": "boolean", "default": true },
52
+ "appId": { "type": "string" },
53
+ "appSecret": { "type": "string" },
54
+ "backendUrl": { "type": "string" },
55
+ "enableEncryption": { "type": "boolean" },
56
+ "requestTimeout": { "type": "number" },
57
+ "requireMention": { "type": "boolean" }
58
+ },
59
+ "required": ["appId", "appSecret", "backendUrl"]
60
+ }
61
+ }
62
+ }
63
+ },
64
+ "uiHints": {
65
+ "appId": { "label": "App ID" },
66
+ "appSecret": { "label": "App Secret", "sensitive": true },
67
+ "backendUrl": { "label": "Backend URL", "placeholder": "https://your-backend-url.com" }
68
+ }
69
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@feihan-im/openclaw-plugin",
3
- "version": "0.1.0",
4
- "description": "飞函 IM OpenClaw 频道插件",
3
+ "version": "0.1.2",
4
+ "description": "Feihan IM OpenClaw channel plugin",
5
5
  "author": "上海飞函安全科技有限公司",
6
6
  "type": "module",
7
7
  "main": "./dist/index.cjs",
@@ -22,9 +22,11 @@
22
22
  "sideEffects": false,
23
23
  "files": [
24
24
  "dist",
25
- "src"
25
+ "src",
26
+ "openclaw.plugin.json"
26
27
  ],
27
28
  "openclaw": {
29
+ "setup": "./dist/src/setup-entry.js",
28
30
  "extensions": [
29
31
  "./dist/index.js"
30
32
  ],
@@ -44,7 +46,7 @@
44
46
  "test:watch": "vitest",
45
47
  "clean": "rm -rf dist"
46
48
  },
47
- "keywords": ["openclaw", "channel", "plugin", "feihan", "飞函", "im"],
49
+ "keywords": ["openclaw", "channel", "plugin", "feihan", "im"],
48
50
  "engines": {
49
51
  "node": ">=18.0.0"
50
52
  },
@@ -58,7 +60,12 @@
58
60
  "url": "https://github.com/feihan-im/openclaw-feihan/issues"
59
61
  },
60
62
  "peerDependencies": {
61
- "openclaw": "*"
63
+ "openclaw": ">=2026.3.22"
64
+ },
65
+ "peerDependenciesMeta": {
66
+ "openclaw": {
67
+ "optional": true
68
+ }
62
69
  },
63
70
  "dependencies": {
64
71
  "@feihan-im/sdk": "0.28.108",
@@ -54,7 +54,7 @@ describe("resolveAccountConfig", () => {
54
54
  feihan: {
55
55
  appId: "app_1",
56
56
  appSecret: "secret_1",
57
- backendUrl: "https://api.feihan.im",
57
+ backendUrl: "https://your-backend-url.com",
58
58
  },
59
59
  },
60
60
  };
@@ -64,7 +64,7 @@ describe("resolveAccountConfig", () => {
64
64
  enabled: true,
65
65
  appId: "app_1",
66
66
  appSecret: "secret_1",
67
- backendUrl: "https://api.feihan.im",
67
+ backendUrl: "https://your-backend-url.com",
68
68
  enableEncryption: true,
69
69
  requestTimeout: 30_000,
70
70
  requireMention: true,
@@ -102,13 +102,13 @@ describe("resolveAccountConfig", () => {
102
102
 
103
103
  process.env.FEIHAN_APP_ID = "env_app";
104
104
  process.env.FEIHAN_APP_SECRET = "env_secret";
105
- process.env.FEIHAN_BACKEND_URL = "http://env.feihan.im";
105
+ process.env.FEIHAN_BACKEND_URL = "https://your-backend-url.com";
106
106
 
107
107
  try {
108
108
  const account = resolveAccountConfig({});
109
109
  expect(account.appId).toBe("env_app");
110
110
  expect(account.appSecret).toBe("env_secret");
111
- expect(account.backendUrl).toBe("http://env.feihan.im");
111
+ expect(account.backendUrl).toBe("https://your-backend-url.com");
112
112
  } finally {
113
113
  if (origId === undefined) delete process.env.FEIHAN_APP_ID;
114
114
  else process.env.FEIHAN_APP_ID = origId;
@@ -213,7 +213,7 @@ describe("resolveAndValidateAccountConfig", () => {
213
213
  feihan: {
214
214
  appId: "app_1",
215
215
  appSecret: "secret_1",
216
- backendUrl: "https://api.feihan.im",
216
+ backendUrl: "https://your-backend-url.com",
217
217
  },
218
218
  },
219
219
  };
@@ -29,7 +29,7 @@ function makeAccount(
29
29
  enabled: true,
30
30
  appId: "app_test",
31
31
  appSecret: "secret",
32
- backendUrl: "https://api.feihan.test",
32
+ backendUrl: "https://your-backend-url.com",
33
33
  enableEncryption: true,
34
34
  requestTimeout: 30_000,
35
35
  requireMention: true,
@@ -0,0 +1,51 @@
1
+ // Copyright (c) 2026 上海飞函安全科技有限公司 (Shanghai Feihan Security Technology Co., Ltd.)
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
5
+
6
+ export default defineSetupPluginEntry({
7
+ async onSetup(context) {
8
+ const appId = await context.prompt({
9
+ type: "text",
10
+ message: "Enter your Feihan App ID:",
11
+ validate: (val: string) => val.length > 0 || "This field is required",
12
+ });
13
+
14
+ const appSecret = await context.prompt({
15
+ type: "password",
16
+ message: "Enter your Feihan App Secret:",
17
+ validate: (val: string) => val.length > 0 || "This field is required",
18
+ });
19
+
20
+ const backendUrl = await context.prompt({
21
+ type: "text",
22
+ message: "Enter Feihan backend server URL:",
23
+ validate: (val: string) => {
24
+ if (val.length === 0) return "This field is required";
25
+ try {
26
+ new URL(val);
27
+ return true;
28
+ } catch {
29
+ return "Please enter a valid URL";
30
+ }
31
+ },
32
+ });
33
+
34
+ const enableEncryption = await context.prompt({
35
+ type: "confirm",
36
+ message: "Enable message encryption?",
37
+ default: true,
38
+ });
39
+
40
+ // Write config to ~/.openclaw/openclaw.json
41
+ await context.updateConfig("channels.feihan.appId", appId);
42
+ await context.updateConfig("channels.feihan.appSecret", appSecret);
43
+ await context.updateConfig("channels.feihan.backendUrl", backendUrl);
44
+ await context.updateConfig("channels.feihan.enableEncryption", enableEncryption);
45
+ await context.updateConfig("channels.feihan.enabled", true);
46
+
47
+ console.log("✅ Feihan channel configuration saved successfully!");
48
+ console.log("📄 Config file: ~/.openclaw/openclaw.json");
49
+ console.log("📖 Deploy docs: https://feihanim.cn/docs/admin/bots/openclaw");
50
+ },
51
+ });
@@ -0,0 +1,29 @@
1
+ // Copyright (c) 2026 上海飞函安全科技有限公司 (Shanghai Feihan Security Technology Co., Ltd.)
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /**
5
+ * Type declarations for openclaw/plugin-sdk/core.
6
+ *
7
+ * These types provide the minimal interface needed for the setup entry point.
8
+ * The actual implementation is provided by the OpenClaw runtime at plugin load time.
9
+ */
10
+
11
+ declare module "openclaw/plugin-sdk/core" {
12
+ export interface PromptOptions {
13
+ type: "text" | "password" | "confirm" | "select";
14
+ message: string;
15
+ default?: string | boolean;
16
+ validate?: (value: string) => boolean | string;
17
+ }
18
+
19
+ export interface SetupContext {
20
+ prompt: (options: PromptOptions) => Promise<string>;
21
+ updateConfig: (key: string, value: string | boolean | number) => Promise<void>;
22
+ }
23
+
24
+ export interface SetupPluginEntry {
25
+ onSetup: (context: SetupContext) => Promise<void>;
26
+ }
27
+
28
+ export function defineSetupPluginEntry(entry: SetupPluginEntry): SetupPluginEntry;
29
+ }
@@ -1,23 +0,0 @@
1
- // Copyright (c) 2026 上海飞函安全科技有限公司 (Shanghai Feihan Security Technology Co., Ltd.)
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- /**
5
- * Re-export types from @feihan-im/sdk used across the plugin.
6
- *
7
- * The published SDK ships its own type declarations. This file exists
8
- * only to keep the rest of the plugin importing from a single local
9
- * barrel, making future SDK swaps cheaper.
10
- */
11
- export type {
12
- FeihanClient,
13
- FeihanClientOptions,
14
- } from "@feihan-im/sdk";
15
-
16
- export {
17
- LoggerLevel,
18
- } from "@feihan-im/sdk";
19
-
20
- export type {
21
- Logger,
22
- EventHeader,
23
- } from "@feihan-im/sdk";