lark-remote 0.3.0 → 0.4.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/CHANGELOG.md +17 -0
- package/README.en.md +6 -6
- package/README.md +8 -7
- package/dist/binder.d.ts +1 -1
- package/dist/binder.js +1 -1
- package/dist/bridge/final-usage.js +2 -2
- package/dist/bridge/inbound-media.js +7 -5
- package/dist/bridge/index.js +75 -75
- package/dist/clone.d.ts +1 -1
- package/dist/common/fs.js +1 -1
- package/dist/config/index.js +1 -1
- package/dist/connector/index.d.ts +6 -0
- package/dist/connector/index.js +76 -17
- package/dist/error-classification.d.ts +7 -0
- package/dist/error-classification.js +37 -1
- package/dist/index.js +12 -2
- package/dist/platform/command.js +1 -1
- package/dist/platform/sleep-blocker.d.ts +17 -0
- package/dist/platform/sleep-blocker.js +73 -0
- package/dist/platform/terminator-win32.js +1 -1
- package/dist/restart.d.ts +4 -4
- package/dist/restart.js +5 -5
- package/dist/router/config/kimi.js +4 -3
- package/dist/router/index.js +16 -6
- package/dist/runner/common/acp/base-acp-runner.js +7 -2
- package/dist/runner/common/acp/base-translator.d.ts +19 -0
- package/dist/runner/common/acp/base-translator.js +82 -0
- package/dist/runner/common/acp/protocol-types.d.ts +16 -2
- package/dist/runner/common/acp/protocol-types.js +3 -0
- package/dist/runner/kimi/acp/translator.js +60 -4
- package/dist/session/session-store.d.ts +1 -1
- package/dist/session/session-store.js +1 -1
- package/dist/workspace/index.d.ts +1 -1
- package/dist/workspace/index.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.4.0] - 2026-09-15
|
|
9
|
+
|
|
10
|
+
### 新增
|
|
11
|
+
|
|
12
|
+
- **运行期间阻止系统休眠**:运行中自动阻止系统休眠(macOS 用 `caffeinate`、Windows 用 `SetThreadExecutionState`)——典型用法是人不在电脑前远程使用,系统一旦休眠连接即断。只阻止系统休眠,不影响显示器睡眠;退出(含异常退出)后自动解除,helper 意外退出也会留痕兜底。注意:MacBook 合盖睡眠无法阻止(除非接电源并外接显示器)
|
|
13
|
+
- **入站媒体保存提示带完整路径**:收到的图片/文件落盘后,提示带目录完整路径,方便直接定位
|
|
14
|
+
|
|
15
|
+
### 修复
|
|
16
|
+
|
|
17
|
+
- **卡片更新瞬态失败自动重试**:飞书卡片更新遇到连接瞬时中断等瞬态传输错误时就地重试(最多 3 次),不再把失败直接落到未处理 rejection 上导致进程退出
|
|
18
|
+
- **Kimi 审批卡恢复完整 Bash 命令**:审批卡片按 `toolCallId` 关联流式参数,恢复展示完整命令而非截断片段
|
|
19
|
+
- **Kimi 权限模式文案对齐 kimi 0.40+ 语义**:`yolo` 现指「必要时询问」而非完全放行,完全自动请选 `auto`;README 与配置文档同步更新
|
|
20
|
+
|
|
21
|
+
### 变更
|
|
22
|
+
|
|
23
|
+
- **文档自称统一**:README、使用文档与架构文档中的自称统一为 lark-remote
|
|
24
|
+
|
|
8
25
|
## [0.3.0] - 2026-09-13
|
|
9
26
|
|
|
10
27
|
### 新增
|
package/README.en.md
CHANGED
|
@@ -16,7 +16,7 @@ Designed for a single-user, peer-to-peer private chat. The agent's system prompt
|
|
|
16
16
|
|
|
17
17
|
## ⚠️ Security Warning (read first)
|
|
18
18
|
|
|
19
|
-
This tool turns Feishu messages directly into local agent executions. **Out of the box, agents run without approval prompts**: Claude defaults to `bypassPermissions` (no approval card), but that permission mode is **configurable** — set it to anything other than `bypassPermissions` (`default` / `acceptEdits` / `auto` / `dontAsk` / `plan`) to enable interactive approval, where high-risk actions wait for your confirmation on the Feishu card. Codex uses the **app-server approval mode** (default `approvalPolicy=on-request` — command execution requires your confirmation on the Feishu card, sandbox defaults to `workspace-write`); Kimi defaults to `manual` (per-action approval); other agents run with their CLI defaults. **In any mode**, agents can read and write the local directories you specify. You MUST:
|
|
19
|
+
This tool turns Feishu messages directly into local agent executions. **Out of the box, agents run without approval prompts**: Claude defaults to `bypassPermissions` (no approval card), but that permission mode is **configurable** — set it to anything other than `bypassPermissions` (`default` / `acceptEdits` / `auto` / `dontAsk` / `plan`) to enable interactive approval, where high-risk actions wait for your confirmation on the Feishu card. Codex uses the **app-server approval mode** (default `approvalPolicy=on-request` — command execution requires your confirmation on the Feishu card, sandbox defaults to `workspace-write`); Kimi defaults to `manual` (per-action approval; note that since kimi 0.40, `yolo` means Ask-When-Needed rather than allow-everything — use `auto` for fully unattended, no-approval execution); other agents run with their CLI defaults. **In any mode**, agents can read and write the local directories you specify. You MUST:
|
|
20
20
|
|
|
21
21
|
- **Use it only in your own private (p2p) chat.** Never add the bot to any group chat; never let anyone else talk to it.
|
|
22
22
|
- Restrict the app's visibility to **yourself only** in the Feishu Open Platform.
|
|
@@ -52,7 +52,7 @@ git clone https://github.com/bungabungawoda/lark-remote.git
|
|
|
52
52
|
cd lark-remote
|
|
53
53
|
bun install
|
|
54
54
|
bun run build
|
|
55
|
-
bun install -g "$(pwd)" # install globally as
|
|
55
|
+
bun install -g "$(pwd)" # install globally as lark-remote command (bun parses `.` as an empty package name; use an absolute path)
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
## Configuration
|
|
@@ -94,7 +94,7 @@ lark-remote --config-dir ~/.lark-remote-test # custom config dir (multiple in
|
|
|
94
94
|
lark-remote --settings ~/.claude/settings.json # specify Claude settings file
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
lark-remote prints nothing to the terminal after startup; logs go to `~/.lark-remote/logs/YYYY-MM-DD/lark-remote-<pid>.log` (rotated daily, one subdirectory per day). Only one `lark-remote` instance is allowed per `configDir` — a duplicate start fails with the existing pid. After connecting to Feishu, a startup notification (with start time and pid) is sent to the most recent private chat.
|
|
98
98
|
|
|
99
99
|
Each agent run creates one CardKit 2.0 card that updates in place with thinking, body text, and tool summaries in real time.
|
|
100
100
|
Timestamps are read from the JSONL and shown in local time as `YYYY-MM-DD HH:mm` for thinking, body, tool call/result, and session history events.
|
|
@@ -117,12 +117,12 @@ Your original message also gets an emoji reaction: `Typing` while the run is in
|
|
|
117
117
|
| `/status` | `/s` | Current directory, session, model, process status |
|
|
118
118
|
| `/stop` | `/t` | Kill the current agent process (SIGKILL) |
|
|
119
119
|
| `/ps` | - | Whether a process is running |
|
|
120
|
-
| `/restart` | - | In-place
|
|
121
|
-
| `/clone [name]` | - | Clone
|
|
120
|
+
| `/restart` | - | In-place lark-remote self-restart (new process takes over with the same config) |
|
|
121
|
+
| `/clone [name]` | - | Clone lark-remote: copies the current config into a new directory and walks you through creating a brand-new Feishu app by QR scan; on success it binds, syncs state, and launches the new instance |
|
|
122
122
|
| `/config get\|set` | `/c` | View/change runtime config (agent-aware card) |
|
|
123
123
|
| `/order save\|list\|edit` | `/o` | Save, list, or edit frequently used prompts |
|
|
124
124
|
| `!<cmd>` | - | Run a bash command with streaming card output (bypasses the serial queue) |
|
|
125
|
-
| `/exit` | `/e` | Exit
|
|
125
|
+
| `/exit` | `/e` | Exit lark-remote |
|
|
126
126
|
|
|
127
127
|
Any message not starting with `/` is forwarded to the current default agent.
|
|
128
128
|
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
## ⚠️ 安全警告(必读)
|
|
18
18
|
|
|
19
|
-
本工具会把飞书消息直接转为本地 agent 执行。**开箱默认是不弹审批的**:Claude 默认以 `bypassPermissions` 运行(无审批卡),但该权限模式**可配置**——把它改成 `bypassPermissions` 以外的值(`default` / `acceptEdits` / `auto` / `dontAsk` / `plan`)即启用交互式审批,高风险操作会在飞书卡片上等你确认;Codex 采用 **app-server 审批模式**(默认 `approvalPolicy=on-request`,执行命令需在飞书卡片上确认,沙箱默认 `workspace-write`);Kimi 默认 `manual
|
|
19
|
+
本工具会把飞书消息直接转为本地 agent 执行。**开箱默认是不弹审批的**:Claude 默认以 `bypassPermissions` 运行(无审批卡),但该权限模式**可配置**——把它改成 `bypassPermissions` 以外的值(`default` / `acceptEdits` / `auto` / `dontAsk` / `plan`)即启用交互式审批,高风险操作会在飞书卡片上等你确认;Codex 采用 **app-server 审批模式**(默认 `approvalPolicy=on-request`,执行命令需在飞书卡片上确认,沙箱默认 `workspace-write`);Kimi 默认 `manual`(逐条审批;注意 kimi 0.40+ 起 `yolo` 已改为「必要时询问」而非全部放行,要完全不弹审批需选 `auto`);其他 agent 以各自 CLI 的默认权限运行。**无论哪种模式**,agent 都能读写你指定的本地目录,请务必:
|
|
20
20
|
|
|
21
21
|
- **仅限你自己的私聊(p2p)使用**。不要把机器人拉进任何群聊,不要让任何其他人能与它对话。
|
|
22
22
|
- 在飞书开放平台把应用可见范围限制到**只有你自己**。
|
|
@@ -94,7 +94,7 @@ lark-remote --config-dir ~/.lark-remote-test # 自定义配置目录(同机
|
|
|
94
94
|
lark-remote --settings ~/.claude/settings.json # 指定 Claude 配置文件
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
lark-remote 启动后不在终端输出,运行日志写入 `~/.lark-remote/logs/YYYY-MM-DD/lark-remote-<pid>.log`(按日期轮转,每天一个子目录)。同一 `configDir` 只允许一个 `lark-remote` 实例,重复启动会直接报错并提示已有 pid。连接飞书成功后会向最近私聊用户发送启动通知,包含启动时间和进程号。
|
|
98
98
|
|
|
99
99
|
每次 agent 运行会创建一张 CardKit 2.0 卡片,并在原地实时更新 thinking、正文和工具摘要。
|
|
100
100
|
卡片会读取 JSONL 的 `timestamp`,以本地时间 `YYYY-MM-DD HH:mm` 显示 thinking、正文、tool call/result 和会话历史事件。
|
|
@@ -117,20 +117,21 @@ bridge 启动后不在终端输出,运行日志写入 `~/.lark-remote/logs/YYY
|
|
|
117
117
|
| `/status` | `/s` | 当前目录、session、模型、进程状态 |
|
|
118
118
|
| `/stop` | `/t` | 终止当前 agent 进程(SIGKILL) |
|
|
119
119
|
| `/ps` | - | 是否有进程在跑 |
|
|
120
|
-
| `/restart` | - | 原地自重启
|
|
120
|
+
| `/restart` | - | 原地自重启 lark-remote(新进程同 config 接管) |
|
|
121
121
|
| `/clone [name]` | - | 复制分身:克隆当前配置到新目录并扫码创建新飞书应用,完成后自动绑定、同步状态并拉起新实例 |
|
|
122
122
|
| `/config get\|set` | `/c` | 查改运行时配置(agent-aware 卡片) |
|
|
123
123
|
| `/order save\|list\|edit\|alias` | `/o` | 收藏常用指令;`/order edit` 修改指令文本(保留别名/使用统计);`/order alias` 注册快捷别名(输入 `$name` 展开) |
|
|
124
124
|
| `!<cmd>` | - | 执行 bash 命令并流式输出到卡片(绕过串行队列) |
|
|
125
|
-
| `/exit` | `/e` | 退出
|
|
125
|
+
| `/exit` | `/e` | 退出 lark-remote |
|
|
126
126
|
|
|
127
127
|
直接发非 `/` 开头的消息即转发给当前默认 agent。
|
|
128
128
|
|
|
129
|
-
**复制分身(`/clone`)**:想在另一个项目/机器目录旁跑一个独立
|
|
129
|
+
**复制分身(`/clone`)**:想在另一个项目/机器目录旁跑一个独立 lark-remote 实例时,发 `/clone 名字` 即可——当前配置目录会被克隆为 `<configDir>-<名字>`(除飞书凭据外全部复制),二维码以图片消息发进私聊引导你扫码创建一个全新飞书应用;扫码成功后自动完成绑定,workspace 别名、常用指令、工作目录与会话状态一并迁移,新实例自动拉起并可直接续聊。也可直接点 `/help` 卡片上的「/clone」按钮。详见 [docs/zh/usage.md](docs/zh/usage.md)。
|
|
130
130
|
|
|
131
131
|
往飞书私聊发**图片/文件**会自动保存到当前目录的 `.lark-remote-temp/<YYYYMMDDHHmm>/`
|
|
132
|
-
(建议把 `.lark-remote-temp/` 加进项目 `.gitignore
|
|
133
|
-
|
|
132
|
+
(建议把 `.lark-remote-temp/` 加进项目 `.gitignore`),保存提示里会带上目录完整路径,
|
|
133
|
+
随后说「请处理刚才保存的文件」(或直接把提示转给 agent)即可让 agent 直接读本地文件。
|
|
134
|
+
更多用法见 [docs/zh/usage.md](docs/zh/usage.md)。
|
|
134
135
|
|
|
135
136
|
## 测试
|
|
136
137
|
|
package/dist/binder.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ type BindDecision = {
|
|
|
10
10
|
/**
|
|
11
11
|
* Owner 绑定器:首次私聊发送任意消息完成"认领",此后仅该 openId 可用。
|
|
12
12
|
*
|
|
13
|
-
* 设计依据:
|
|
13
|
+
* 设计依据:lark-remote 进程持有用户本机完整权限,唯一合法主体是 owner 本人。
|
|
14
14
|
* 飞书自建应用的私聊入口本身就是 owner 掌控的(应用只有 owner 能看到/使用,
|
|
15
15
|
* 分享出去属于 owner 的主动行为),因此首次消息即绑定,不再要求输入 PIN。
|
|
16
16
|
* 本类复用已有 startup-contact.json,不新增配置字段。
|
package/dist/binder.js
CHANGED
|
@@ -2,7 +2,7 @@ import { getLogger } from './logger/index.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Owner 绑定器:首次私聊发送任意消息完成"认领",此后仅该 openId 可用。
|
|
4
4
|
*
|
|
5
|
-
* 设计依据:
|
|
5
|
+
* 设计依据:lark-remote 进程持有用户本机完整权限,唯一合法主体是 owner 本人。
|
|
6
6
|
* 飞书自建应用的私聊入口本身就是 owner 掌控的(应用只有 owner 能看到/使用,
|
|
7
7
|
* 分享出去属于 owner 的主动行为),因此首次消息即绑定,不再要求输入 PIN。
|
|
8
8
|
* 本类复用已有 startup-contact.json,不新增配置字段。
|
|
@@ -26,7 +26,7 @@ export function resolveFinalUsage(registry, defaultAgent, sessionId, cwd, agentK
|
|
|
26
26
|
// EnterWorktree relocate (2026-08-04): jsonl read silently returned no
|
|
27
27
|
// usage (e.g. transcript moved mid-session). Surface it so token-stat
|
|
28
28
|
// fallback to per-run live usage is visible in logs, not silent.
|
|
29
|
-
getLogger().warn(`[
|
|
29
|
+
getLogger().warn(`[lark-remote] resolveFinalUsage: no usage from jsonl sessionId=${sessionId} cwd=${cwd} agent=${agentKind}, card falls back to per-run live usage`);
|
|
30
30
|
}
|
|
31
31
|
return content.usage
|
|
32
32
|
? {
|
|
@@ -48,7 +48,7 @@ export function resolveFinalUsage(registry, defaultAgent, sessionId, cwd, agentK
|
|
|
48
48
|
: undefined;
|
|
49
49
|
}
|
|
50
50
|
catch (err) {
|
|
51
|
-
getLogger().warn(`[
|
|
51
|
+
getLogger().warn(`[lark-remote] resolveFinalUsage failed sessionId=${sessionId}: ${errorMessage(err)}`);
|
|
52
52
|
return undefined;
|
|
53
53
|
}
|
|
54
54
|
}
|
|
@@ -266,11 +266,13 @@ export class InboundMediaHandler {
|
|
|
266
266
|
const lines = batch.saved.slice(0, MAX_PATHS_IN_NOTIFICATION).map((p) => `- ${p}`);
|
|
267
267
|
const overflow = batch.saved.length > MAX_PATHS_IN_NOTIFICATION ? `\n… 等 ${batch.saved.length} 个文件` : '';
|
|
268
268
|
const failures = batch.errors.length > 0 ? `\n⚠️ ${batch.errors.join(';')}` : '';
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
269
|
+
// 提示带上保存目录:用户把整句转给 agent 即可定位,无需靠目录约定反查。
|
|
270
|
+
// 合批窗口跨分钟时可能落在两个目录,此时全部列出。
|
|
271
|
+
const dirs = [...new Set(batch.saved.map((p) => path.dirname(p)))];
|
|
272
|
+
const hint = dirs.length === 1
|
|
273
|
+
? `\n💡 你可以直接说:请处理 ${dirs[0]} 下的文件`
|
|
274
|
+
: `\n💡 你可以直接说:请处理以下目录下的文件:${dirs.join('、')}`;
|
|
275
|
+
const text = `📎 已保存 ${batch.saved.length} 个文件:\n` + lines.join('\n') + overflow + failures + hint;
|
|
274
276
|
await this.deps.send({
|
|
275
277
|
userId: batch.payload.userId,
|
|
276
278
|
chatId: batch.payload.chatId,
|