@colinlu50/openclaw-lark-stream 2026.3.25 → 2026.3.27
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 +56 -0
- package/README.md +23 -104
- package/bin/openclaw-lark.js +51 -10
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/README.zh.md +0 -70
package/README.en.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
English | [中文](./README.md)
|
|
2
|
+
|
|
3
|
+
# OpenClaw Lark/Feishu Plugin — Stream Card Fork
|
|
4
|
+
|
|
5
|
+
Fork of the official [openclaw-larksuite](https://github.com/larksuite/openclaw-larksuite) plugin with **streaming block output** and **tool call indicators**.
|
|
6
|
+
|
|
7
|
+
## What's Changed
|
|
8
|
+
|
|
9
|
+
The official plugin delivers LLM block results all at once after completion. This fork enables:
|
|
10
|
+
|
|
11
|
+
- **Real-time block streaming** — each block's content is progressively appended to the streaming card as it's generated
|
|
12
|
+
- **Tool call indicators** — when the agent calls a tool, the card shows the current tool at the top in real-time, with a collapsible summary panel on completion
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
Requires [OpenClaw](https://openclaw.ai) (>= 2026.2.26) and Node.js (>= v22).
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
openclaw plugins install @colinlu50/openclaw-lark-stream
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Then restart the gateway:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
openclaw gateway restart
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
> If you had the official plugin installed, uninstall it first:
|
|
29
|
+
> ```bash
|
|
30
|
+
> openclaw plugins uninstall openclaw-lark --force
|
|
31
|
+
> ```
|
|
32
|
+
|
|
33
|
+
### From source (for development)
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
cd ~/.openclaw/extensions
|
|
37
|
+
git clone git@github.com:ColinLu50/openclaw-lark-stream.git openclaw-lark-stream
|
|
38
|
+
cd openclaw-lark-stream && npm install && npm run build
|
|
39
|
+
openclaw gateway restart
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Configuration
|
|
43
|
+
|
|
44
|
+
The card footer shows elapsed time and completion status by default. To disable:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
openclaw config set channels.feishu.footer.elapsed false # hide elapsed time
|
|
48
|
+
openclaw config set channels.feishu.footer.status false # hide completion status
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
- **elapsed** — displays total response time (e.g. `Elapsed 3.2s`) in the card footer
|
|
52
|
+
- **status** — displays completion state (`Completed` / `Error` / `Stopped`) in the card footer
|
|
53
|
+
|
|
54
|
+
## License
|
|
55
|
+
|
|
56
|
+
MIT — same as the upstream project.
|
package/README.md
CHANGED
|
@@ -1,76 +1,4 @@
|
|
|
1
|
-
[English](
|
|
2
|
-
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
<a id="english"></a>
|
|
6
|
-
|
|
7
|
-
# OpenClaw Lark/Feishu Plugin — Stream Card Fork
|
|
8
|
-
|
|
9
|
-
Fork of the official [openclaw-larksuite](https://github.com/larksuite/openclaw-larksuite) plugin with **streaming block output** and **tool call indicators**.
|
|
10
|
-
|
|
11
|
-
## What's Changed
|
|
12
|
-
|
|
13
|
-
The official plugin delivers LLM block results all at once after completion. This fork enables:
|
|
14
|
-
|
|
15
|
-
- **Real-time block streaming** — each block's content is progressively appended to the streaming card as it's generated
|
|
16
|
-
- **Tool call indicators** — when the agent calls a tool, the card shows tool call status in real-time
|
|
17
|
-
|
|
18
|
-
### Modified Files
|
|
19
|
-
|
|
20
|
-
- `src/card/reply-dispatcher.ts` — enable block streaming in streaming card mode; wire `onToolStart` callback
|
|
21
|
-
- `src/card/streaming-card-controller.ts` — append each delivered block to the card in real-time; add `onToolStart()` to display tool call status
|
|
22
|
-
- `src/card/builder.ts` — collapsible panel for tool call summary in completed cards
|
|
23
|
-
|
|
24
|
-
## Installation
|
|
25
|
-
|
|
26
|
-
Requires [OpenClaw](https://openclaw.ai) (>= 2026.2.26) and Node.js (>= v22).
|
|
27
|
-
|
|
28
|
-
### Option A: npm install (recommended)
|
|
29
|
-
|
|
30
|
-
1. Install the official plugin first to complete the guided setup (App ID, secret, OAuth, etc.):
|
|
31
|
-
```bash
|
|
32
|
-
npx -y @larksuite/openclaw-lark install
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
2. Replace with the stream fork:
|
|
36
|
-
```bash
|
|
37
|
-
openclaw plugins install @colinlu50/openclaw-lark-stream
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
If you already have the official plugin installed, skip step 1.
|
|
41
|
-
|
|
42
|
-
### Option B: From source (for development)
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
cd ~/.openclaw/extensions
|
|
46
|
-
rm -rf openclaw-lark
|
|
47
|
-
git clone git@github.com:ColinLu50/openclaw-lark-stream.git openclaw-lark
|
|
48
|
-
cd openclaw-lark && npm install
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Restart OpenClaw.
|
|
52
|
-
|
|
53
|
-
## Configuration
|
|
54
|
-
|
|
55
|
-
Enable optional card footer metadata:
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
openclaw config set channels.feishu.footer.elapsed true # show elapsed time
|
|
59
|
-
openclaw config set channels.feishu.footer.status true # show completion status
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
- **elapsed** — displays total response time (e.g. `Elapsed 3.2s`) in the card footer
|
|
63
|
-
- **status** — displays completion state (`Completed` / `Error` / `Stopped`) in the card footer
|
|
64
|
-
|
|
65
|
-
Both default to `false` (hidden).
|
|
66
|
-
|
|
67
|
-
## License
|
|
68
|
-
|
|
69
|
-
MIT — same as the upstream project.
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
<a id="中文"></a>
|
|
1
|
+
[English](./README.en.md) | 中文
|
|
74
2
|
|
|
75
3
|
# OpenClaw 飞书插件 — 流式卡片 Fork
|
|
76
4
|
|
|
@@ -80,57 +8,48 @@ MIT — same as the upstream project.
|
|
|
80
8
|
|
|
81
9
|
官方插件在 LLM 生成完一个 block 后才一次性推送结果。本 Fork 实现了:
|
|
82
10
|
|
|
83
|
-
- **实时流式追加** — 每个 block
|
|
84
|
-
- **工具调用状态** —
|
|
85
|
-
|
|
86
|
-
### 改动文件
|
|
87
|
-
|
|
88
|
-
- `src/card/reply-dispatcher.ts` — 在流式卡片模式下启用 block 流式输出;接入 `onToolStart` 回调
|
|
89
|
-
- `src/card/streaming-card-controller.ts` — 将每个已交付的 block 实时追加到卡片;添加 `onToolStart()` 显示工具调用状态
|
|
90
|
-
- `src/card/builder.ts` — 完成卡片中工具调用摘要的折叠面板
|
|
11
|
+
- **实时流式追加** — 每个 block 的内容在生成过程中逐步追加到流式卡片
|
|
12
|
+
- **工具调用状态** — agent 调用工具时,卡片顶部实时显示当前工具,完成后自动折叠为摘要面板
|
|
91
13
|
|
|
92
14
|
## 安装
|
|
93
15
|
|
|
94
16
|
需要 [OpenClaw](https://openclaw.ai)(>= 2026.2.26)和 Node.js(>= v22)。
|
|
95
17
|
|
|
96
|
-
|
|
18
|
+
```bash
|
|
19
|
+
openclaw plugins install @colinlu50/openclaw-lark-stream
|
|
20
|
+
```
|
|
97
21
|
|
|
98
|
-
|
|
99
|
-
```bash
|
|
100
|
-
npx -y @larksuite/openclaw-lark install
|
|
101
|
-
```
|
|
22
|
+
安装完成后重启网关:
|
|
102
23
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
```
|
|
24
|
+
```bash
|
|
25
|
+
openclaw gateway restart
|
|
26
|
+
```
|
|
107
27
|
|
|
108
|
-
|
|
28
|
+
> 如果之前安装过官方插件,先卸载:
|
|
29
|
+
> ```bash
|
|
30
|
+
> openclaw plugins uninstall openclaw-lark --force
|
|
31
|
+
> ```
|
|
109
32
|
|
|
110
|
-
###
|
|
33
|
+
### 从源码安装(开发用)
|
|
111
34
|
|
|
112
35
|
```bash
|
|
113
36
|
cd ~/.openclaw/extensions
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
37
|
+
git clone git@github.com:ColinLu50/openclaw-lark-stream.git openclaw-lark-stream
|
|
38
|
+
cd openclaw-lark-stream && npm install && npm run build
|
|
39
|
+
openclaw gateway restart
|
|
117
40
|
```
|
|
118
41
|
|
|
119
|
-
重启 OpenClaw。
|
|
120
|
-
|
|
121
42
|
## 配置
|
|
122
43
|
|
|
123
|
-
|
|
44
|
+
卡片底栏默认显示耗时和完成状态,如需关闭:
|
|
124
45
|
|
|
125
46
|
```bash
|
|
126
|
-
openclaw config set channels.feishu.footer.elapsed
|
|
127
|
-
openclaw config set channels.feishu.footer.status
|
|
47
|
+
openclaw config set channels.feishu.footer.elapsed false # 隐藏耗时
|
|
48
|
+
openclaw config set channels.feishu.footer.status false # 隐藏完成状态
|
|
128
49
|
```
|
|
129
50
|
|
|
130
|
-
- **elapsed** —
|
|
131
|
-
- **status** —
|
|
132
|
-
|
|
133
|
-
两者默认为 `false`(不显示)。
|
|
51
|
+
- **elapsed** — 卡片底栏显示总响应耗时(如 `耗时 3.2s`)
|
|
52
|
+
- **status** — 卡片底栏显示完成状态(`已完成` / `出错` / `已停止`)
|
|
134
53
|
|
|
135
54
|
## 许可证
|
|
136
55
|
|
package/bin/openclaw-lark.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { execFileSync } from "node:child_process";
|
|
4
|
-
import { existsSync, rmSync } from "node:fs";
|
|
4
|
+
import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
6
6
|
|
|
7
7
|
const SELF_PACKAGE = "@colinlu50/openclaw-lark-stream";
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
);
|
|
8
|
+
const STATE_DIR = process.env.OPENCLAW_STATE_DIR || join(process.env.HOME || process.env.USERPROFILE || "", ".openclaw");
|
|
9
|
+
const EXTENSIONS_DIR = join(STATE_DIR, "extensions");
|
|
10
|
+
const CONFIG_FILE = join(STATE_DIR, "openclaw.json");
|
|
11
|
+
// Tools installs official plugin as "openclaw-lark"; our manifest uses "openclaw-lark-stream"
|
|
12
|
+
const OFFICIAL_DIR = join(EXTENSIONS_DIR, "openclaw-lark");
|
|
13
|
+
const SELF_DIR = join(EXTENSIONS_DIR, "openclaw-lark-stream");
|
|
13
14
|
|
|
14
15
|
const args = process.argv.slice(2);
|
|
15
16
|
const subcommand = args[0];
|
|
@@ -28,12 +29,19 @@ if (subcommand === "install" || subcommand === "update") {
|
|
|
28
29
|
// Tools may fail on gateway restart etc. — that's OK, config is preserved.
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
// Step 2:
|
|
32
|
+
// Step 2: Clean up old plugin dirs + config references, then install ours
|
|
32
33
|
try {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
for (const dir of [OFFICIAL_DIR, SELF_DIR]) {
|
|
35
|
+
if (existsSync(dir)) {
|
|
36
|
+
console.log(`\nRemoving ${dir}...`);
|
|
37
|
+
rmSync(dir, { recursive: true, force: true });
|
|
38
|
+
}
|
|
36
39
|
}
|
|
40
|
+
// Remove stale "openclaw-lark" references from config so openclaw doesn't
|
|
41
|
+
// fail validation when the directory is gone.
|
|
42
|
+
cleanConfigReferences("openclaw-lark");
|
|
43
|
+
|
|
44
|
+
console.log(`\nInstalling ${SELF_PACKAGE}...`);
|
|
37
45
|
execFileSync("openclaw", ["plugins", "install", SELF_PACKAGE], {
|
|
38
46
|
stdio: "inherit",
|
|
39
47
|
});
|
|
@@ -54,6 +62,39 @@ try {
|
|
|
54
62
|
process.exit(error.status ?? 1);
|
|
55
63
|
}
|
|
56
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Remove stale plugin references from openclaw.json so that
|
|
67
|
+
* `openclaw plugins install` doesn't fail config validation.
|
|
68
|
+
*/
|
|
69
|
+
function cleanConfigReferences(pluginId) {
|
|
70
|
+
if (!existsSync(CONFIG_FILE)) return;
|
|
71
|
+
try {
|
|
72
|
+
const cfg = JSON.parse(readFileSync(CONFIG_FILE, "utf8"));
|
|
73
|
+
let changed = false;
|
|
74
|
+
if (cfg.plugins?.entries?.[pluginId]) {
|
|
75
|
+
delete cfg.plugins.entries[pluginId];
|
|
76
|
+
changed = true;
|
|
77
|
+
}
|
|
78
|
+
if (cfg.plugins?.installs?.[pluginId]) {
|
|
79
|
+
delete cfg.plugins.installs[pluginId];
|
|
80
|
+
changed = true;
|
|
81
|
+
}
|
|
82
|
+
if (Array.isArray(cfg.plugins?.allow)) {
|
|
83
|
+
const idx = cfg.plugins.allow.indexOf(pluginId);
|
|
84
|
+
if (idx !== -1) {
|
|
85
|
+
cfg.plugins.allow.splice(idx, 1);
|
|
86
|
+
changed = true;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (changed) {
|
|
90
|
+
writeFileSync(CONFIG_FILE, JSON.stringify(cfg, null, 2) + "\n", "utf8");
|
|
91
|
+
console.log(`Cleaned "${pluginId}" references from ${CONFIG_FILE}`);
|
|
92
|
+
}
|
|
93
|
+
} catch {
|
|
94
|
+
// Config parse failure — let openclaw handle it
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
57
98
|
function runTools(fwdArgs) {
|
|
58
99
|
let version = "latest";
|
|
59
100
|
const vIdx = fwdArgs.indexOf("--tools-version");
|
package/dist/index.js
CHANGED
|
@@ -114064,8 +114064,8 @@ var init_footer_config = __esm({
|
|
|
114064
114064
|
"src/core/footer-config.ts"() {
|
|
114065
114065
|
"use strict";
|
|
114066
114066
|
DEFAULT_FOOTER_CONFIG = {
|
|
114067
|
-
status:
|
|
114068
|
-
elapsed:
|
|
114067
|
+
status: true,
|
|
114068
|
+
elapsed: true
|
|
114069
114069
|
};
|
|
114070
114070
|
__name(resolveFooterConfig, "resolveFooterConfig");
|
|
114071
114071
|
}
|
|
@@ -147775,7 +147775,7 @@ init_gate();
|
|
|
147775
147775
|
init_dedup();
|
|
147776
147776
|
var log29 = larkLogger("plugin");
|
|
147777
147777
|
var plugin = {
|
|
147778
|
-
id: "openclaw-lark",
|
|
147778
|
+
id: "openclaw-lark-stream",
|
|
147779
147779
|
name: "Feishu",
|
|
147780
147780
|
description: "Lark/Feishu channel plugin with im/doc/wiki/drive/task/calendar tools",
|
|
147781
147781
|
configSchema: emptyPluginConfigSchema(),
|