lark-coding-assistant 0.1.1
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/LICENSE +21 -0
- package/README.md +329 -0
- package/bin/lark-coding-assistant-hook.mjs +2 -0
- package/bin/lark-coding-assistant.mjs +2 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +963 -0
- package/dist/cli.js.map +1 -0
- package/dist/daemon-entry.d.ts +2 -0
- package/dist/daemon-entry.js +2794 -0
- package/dist/daemon-entry.js.map +1 -0
- package/dist/hook-entry.d.ts +2 -0
- package/dist/hook-entry.js +95 -0
- package/dist/hook-entry.js.map +1 -0
- package/package.json +55 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 YeFeng-Silence
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# lark-coding-assistant
|
|
2
|
+
|
|
3
|
+
`lark-coding-assistant` 是一个轻量的本地桥接工具:它把 Codex、Trae CLI 或 Claude Code 运行在受管 tmux session 中,让本地终端与飞书/Lark PersonalAgent 私聊操作同一个 coding agent 上下文。
|
|
4
|
+
|
|
5
|
+
远程消息、交互选择、查看输出和恢复现场都通过精确绑定的 tmux pane 完成;任务通知由 agent 原生 `Stop` hook 与终端停止输出状态共同确认。
|
|
6
|
+
|
|
7
|
+
## 主要能力
|
|
8
|
+
|
|
9
|
+
- Codex、Trae CLI 与 Claude Code 可混合运行,默认使用 Codex;
|
|
10
|
+
- 支持多个命名 session,一个飞书账号可在 `/sessions` 卡片中直接切换;
|
|
11
|
+
- 普通飞书消息默认发送到当前 active session;
|
|
12
|
+
- 支持 `/tail`、`/status`、`/stop`、远程处理审批与 Question,以及无法识别画面的手动遥控兜底;
|
|
13
|
+
- 本地终端保持 attach 时,飞书仍可操作同一个 TUI;
|
|
14
|
+
- 首次扫码后保存唯一 owner,后续通常无需绑定码;
|
|
15
|
+
- 交互卡点击后原地更新,保留操作结果与处理时间;
|
|
16
|
+
- daemon 单实例运行,升级 CLI 时自动更新 daemon,tmux session 不受影响。
|
|
17
|
+
|
|
18
|
+
远程审批不按 Codex、Trae CLI 或 Claude Code 版本号限制。bridge 只有在当前 TUI 被高置信度识别为结构化交互,并且选项、默认光标和提交按键映射完整时才发送飞书交互卡。
|
|
19
|
+
|
|
20
|
+
## 环境要求
|
|
21
|
+
|
|
22
|
+
- macOS 或 Linux
|
|
23
|
+
- Node.js 20.12+
|
|
24
|
+
- tmux
|
|
25
|
+
- Codex CLI、Trae CLI 和/或 Claude Code
|
|
26
|
+
- 可访问飞书或 Lark Open Platform
|
|
27
|
+
|
|
28
|
+
检查环境:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
node --version
|
|
32
|
+
tmux -V
|
|
33
|
+
codex --version
|
|
34
|
+
trae-cli --version
|
|
35
|
+
claude --version
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
只需安装实际使用的 coding agent。
|
|
39
|
+
|
|
40
|
+
## 一键安装与初始化
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install -g lark-coding-assistant@latest && lark-coding-assistant init
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
初始化向导会让你选择飞书或 Lark,并显示 PersonalAgent 注册二维码:
|
|
47
|
+
|
|
48
|
+
1. 保持 `init` 命令运行;
|
|
49
|
+
2. 使用飞书/Lark 扫描二维码;
|
|
50
|
+
3. 创建或选择 PersonalAgent;
|
|
51
|
+
4. 确认应用权限、事件和卡片回调;
|
|
52
|
+
5. 等待终端显示配置已保存。
|
|
53
|
+
|
|
54
|
+
二维码和链接是本次初始化临时生成的,请在有效期内完成。选择 Lark 后注册链接可能先显示飞书域名,识别账号后会自动切换授权域。
|
|
55
|
+
|
|
56
|
+
配置保存在 `~/.lark-coding-assistant`。App Secret 只写入本机 `secrets.json`,文件权限为 `0600`。
|
|
57
|
+
|
|
58
|
+
## 快速开始
|
|
59
|
+
|
|
60
|
+
默认启动 Codex,并立即 attach:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
cd ~/workspace/my-project
|
|
64
|
+
lark-coding-assistant start
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
启动 Trae CLI:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
lark-coding-assistant start --agent trae-cli
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
启动 Claude Code:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
lark-coding-assistant start --agent claude-code
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
程序会启动唯一 bridge daemon、创建 `default` tmux session、向 agent 注入 `Stop` hook,然后 attach 当前终端。打开 PersonalAgent 私聊直接发消息即可自动连接,不需要先 detach,通常也不需要绑定码。
|
|
80
|
+
|
|
81
|
+
Codex 与 Trae CLI 会使用其面向自动化的 `--dangerously-bypass-hook-trust` 参数运行 bridge 固定注入的 Stop hook,避免每次新建 session 都出现 hook 信任确认。这个参数只影响 hook 信任,不会关闭 agent 自身的命令审批。
|
|
82
|
+
|
|
83
|
+
## 多 agent、多 session
|
|
84
|
+
|
|
85
|
+
每个 session 必须使用唯一名称:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
lark-coding-assistant start --name api --agent codex --cwd ~/workspace/api
|
|
89
|
+
lark-coding-assistant start --name web --agent trae-cli --cwd ~/workspace/web
|
|
90
|
+
lark-coding-assistant start --name docs --agent claude-code --cwd ~/workspace/docs
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
名称只允许字母、数字、下划线和短横线,最长 40 个字符。不指定名称时使用 `default`。
|
|
94
|
+
|
|
95
|
+
一个 PersonalAgent 私聊同一时刻只连接一个 active session。在飞书发送:
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
/sessions
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
机器人会发送一张交互卡,按 Codex、Trae CLI、Claude Code 分组展示仍存活的 session。`● 当前` 表示 active session,点击其他 session 的“连接”按钮即可切换;成功后卡片会留下操作记录。也可使用:
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
/use web
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
切换只改变飞书消息和通知的路由,不会停止其他 session。普通消息、`/tail`、`/status`、审批、`/stop` 和停止输出通知都只作用于 active session。
|
|
108
|
+
|
|
109
|
+
## 恢复 agent 历史会话
|
|
110
|
+
|
|
111
|
+
恢复参数同时适用于三个 agent,bridge 会转换为各 CLI 的原生参数:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# 打开当前工作目录的历史会话选择器
|
|
115
|
+
lark-coding-assistant start --agent codex --resume
|
|
116
|
+
|
|
117
|
+
# 恢复最近会话
|
|
118
|
+
lark-coding-assistant start --agent trae-cli --resume-last
|
|
119
|
+
|
|
120
|
+
# 按 agent session ID 恢复
|
|
121
|
+
lark-coding-assistant start --agent trae-cli --resume <session-id>
|
|
122
|
+
|
|
123
|
+
# Claude Code:恢复最近会话
|
|
124
|
+
lark-coding-assistant start --agent claude-code --resume-last
|
|
125
|
+
|
|
126
|
+
# 选择器显示其他工作目录的会话
|
|
127
|
+
lark-coding-assistant start --agent codex --resume-all
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`--name` 是 bridge 管理的 tmux session 名;`--resume <session-id>` 是 coding agent 自己的历史 session ID,两者不是同一个概念。Claude Code 的 `--resume-all` 与 `--resume` 都会打开其原生恢复选择器。
|
|
131
|
+
|
|
132
|
+
## 本地终端与 tmux
|
|
133
|
+
|
|
134
|
+
本地保持 attach 不影响飞书操作。如果要暂时离开 tmux,按 `Ctrl-b`,松开后再按 `d`。这只会 detach 本地终端,不会停止 agent 或 daemon。
|
|
135
|
+
|
|
136
|
+
重新进入:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
lark-coding-assistant attach default
|
|
140
|
+
lark-coding-assistant attach web
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
不要把 tmux detach 与飞书 `/detach` 混淆:前者只离开本地界面,后者会解除私聊绑定并关闭自动重连。
|
|
144
|
+
|
|
145
|
+
## 飞书/Lark 私聊命令
|
|
146
|
+
|
|
147
|
+
- `/sessions`:按 agent 分组展示所有仍存活的 session,点击按钮直接切换。
|
|
148
|
+
- `/use <name>`:用文本命令切换 session。
|
|
149
|
+
- `/tail [20-300]`:返回当前 session 最近的终端输出,默认 80 行。
|
|
150
|
+
- `/manual`:打开当前 active session 的手动终端遥控卡。
|
|
151
|
+
- `/key up|down|left|right|enter|esc|tab|space|backspace|ctrl-c`:向当前终端发送一个手动按键。
|
|
152
|
+
- `/type <文本>`:向当前终端输入文本但不提交。
|
|
153
|
+
- `/submit <文本>`:向当前终端输入文本并按一次 Enter。
|
|
154
|
+
- `/status`:显示当前 session、agent、tmux pane、画面状态和工作目录。
|
|
155
|
+
- `/detach`:解除当前私聊绑定,agent 与 tmux 继续运行。
|
|
156
|
+
- `/stop`:发送二次确认卡,确认后停止当前 agent 和 tmux session。
|
|
157
|
+
- `/attach <code>`:使用一次性绑定码重新绑定私聊。
|
|
158
|
+
|
|
159
|
+
常见画面状态包括 `idle`、`running`、`approval`、`input`、`failed`、`exited` 和 `unknown`。审批、Question 和其他结构化编号选择会根据当前终端画面生成交互卡;画面无法安全识别时不会盲目提交操作。
|
|
160
|
+
|
|
161
|
+
## 本地命令
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
# 启动和进入
|
|
165
|
+
lark-coding-assistant start [--name <name>] [--agent codex|trae-cli|claude-code] [--cwd <path>] [--resume [session-id]|--resume-last|--resume-all]
|
|
166
|
+
lark-coding-assistant attach [name]
|
|
167
|
+
|
|
168
|
+
# 状态和停止
|
|
169
|
+
lark-coding-assistant status [name]
|
|
170
|
+
lark-coding-assistant stop [name]
|
|
171
|
+
|
|
172
|
+
# 私聊绑定
|
|
173
|
+
lark-coding-assistant bind-code
|
|
174
|
+
lark-coding-assistant reset-owner
|
|
175
|
+
|
|
176
|
+
# 日志
|
|
177
|
+
lark-coding-assistant logs
|
|
178
|
+
lark-coding-assistant logs --lines 300
|
|
179
|
+
|
|
180
|
+
# bridge daemon
|
|
181
|
+
lark-coding-assistant daemon status
|
|
182
|
+
lark-coding-assistant daemon start
|
|
183
|
+
lark-coding-assistant daemon stop
|
|
184
|
+
lark-coding-assistant daemon restart
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
`daemon stop/restart` 只断开或恢复飞书连接,不停止受管 tmux session。顶层 `stop [name]` 才会停止对应 agent 和 tmux session。
|
|
188
|
+
|
|
189
|
+
## 绑定规则
|
|
190
|
+
|
|
191
|
+
首次扫码会保存可信 owner。后续启动会自动沿用该 owner 和私聊,通常不再需要绑定码。
|
|
192
|
+
|
|
193
|
+
以下情况才需要 `lark-coding-assistant bind-code`:
|
|
194
|
+
|
|
195
|
+
- 曾在飞书发送 `/detach`;
|
|
196
|
+
- 需要迁移到另一个私聊;
|
|
197
|
+
- 当前配置没有保存 owner 身份。
|
|
198
|
+
|
|
199
|
+
绑定码是 10 分钟有效的一次性命令,只在本地保存 scrypt 哈希:
|
|
200
|
+
|
|
201
|
+
```text
|
|
202
|
+
/attach <一次性绑定码>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## 交互卡与消息排队
|
|
206
|
+
|
|
207
|
+
当 active agent 显示结构化编号选择时,bridge 会从当前终端画面识别标题、上下文、选项、光标位置、勾选状态和提交方式,并在飞书发送对应的审批、Question 或通用选择卡。卡片选项直接来自当前 TUI,不使用固定的按钮集合。
|
|
208
|
+
|
|
209
|
+
识别结果会先归一化为与 agent 无关的交互语义:单选或多选、选择切换键、最终提交方式,以及可选的补充内容编辑器。后续卡片渲染和 tmux 操作只消费这些语义,不按 Codex、Trae CLI 或 Claude Code 分别实现提交流程。各 agent 的适配层只负责识别终端文案与按键提示,因此未来版本只要仍能明确展示选项状态和提交方式,就可以复用同一套执行逻辑。
|
|
210
|
+
|
|
211
|
+
单选会直接提交所选答案;多选采用事务式表单,勾选、取消和修改自定义内容只保存在飞书卡片中,不会逐项操作本地终端。只有点击“提交答案”后,bridge 才会一次读取完整表单、同步本地 CLI 的最终选择和自定义内容,并执行一次提交。如果 agent 随后显示 `Submit answers / Cancel` 等二次确认,原卡片会继续刷新为新的确认卡。“继续对话”等非答案操作仍即时同步。远程操作引起的输入、光标移动和勾选变化只更新原卡片,不会重复推送新的交互卡。
|
|
212
|
+
|
|
213
|
+
点击卡片时会重新校验:
|
|
214
|
+
|
|
215
|
+
- 操作者仍是 owner;
|
|
216
|
+
- agent、active session 和 pane 没有变化;
|
|
217
|
+
- 交互内容、勾选状态和画面修订号仍与发卡时一致;
|
|
218
|
+
- 卡片签名和 nonce 有效。
|
|
219
|
+
|
|
220
|
+
交互卡不会仅因等待时间较长而失效;只要同一个选择画面仍在等待,即使隔夜也可处理。画面、pane、agent 或 active session 变化后旧卡会立即失效。停止和 session 选择卡仍使用短时有效期。
|
|
221
|
+
|
|
222
|
+
Codex、Trae CLI、Claude Code 的审批、Question 和其他编号选择统一使用同一套结构化识别与画面指纹校验;无法完整识别时不会盲目生成操作按钮。
|
|
223
|
+
|
|
224
|
+
## 手动遥控兜底
|
|
225
|
+
|
|
226
|
+
当 active pane 的输出稳定 3 秒、状态为 `input` 或 `unknown`,且 bridge 无法生成高置信度结构化操作卡时,会自动发送一张手动遥控卡。同一个 session、pane 和画面指纹只通知一次;也可以随时发送 `/manual` 主动打开。
|
|
227
|
+
|
|
228
|
+
手动遥控卡直接展示最近的终端输出,支持方向键、Enter、Esc、Tab、Space、Ctrl+C、仅输入文本和输入后提交。每次操作只向当前 tmux pane 发送一个原子动作,然后在原卡片刷新最新画面。除“刷新”外,所有操作都会校验 owner、active session、agent、pane 和画面指纹;画面已变化时不会执行旧操作,而是先刷新卡片让用户重新确认。
|
|
229
|
+
|
|
230
|
+
手动模式不会判断某个按键在当前 TUI 中是否安全,因此只应在确认终端画面后操作。点击“退出手动模式”只会禁用当前遥控卡,不会停止 coding agent 或 tmux。若重新识别到结构化审批或 Question,遥控卡会停止操作并恢复发送语义化交互卡。
|
|
231
|
+
|
|
232
|
+
agent 正在审批、本地输入框已有草稿或画面未知时,普通消息会进入最多 100 条的内存 FIFO 队列。恢复安全输入状态后按顺序发送;daemon 重启、`/detach`、切换或停止 session 时队列清空。
|
|
233
|
+
|
|
234
|
+
## “等待用户输入”通知
|
|
235
|
+
|
|
236
|
+
通知触发和通知内容提取是两条独立逻辑:
|
|
237
|
+
|
|
238
|
+
1. agent 原生 `Stop` hook 产生候选完成;
|
|
239
|
+
2. daemon 继续观察 active tmux pane;
|
|
240
|
+
3. 只有画面回到 `idle` 且连续 2.5 秒没有新输出,才确认 agent 已停止输出;
|
|
241
|
+
4. 多个中间完成事件会合并,只发送最新一条;
|
|
242
|
+
5. 确认发送时统一使用完成事件中的 `last-assistant-message` 作为最终回复。
|
|
243
|
+
|
|
244
|
+
因此终端画面只负责确认 agent 已停止输出,不再用于提取通知正文。非 active session 的完成事件不会推送。
|
|
245
|
+
|
|
246
|
+
## 升级与卸载
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
npm install -g lark-coding-assistant@latest
|
|
250
|
+
lark-coding-assistant daemon restart
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
如果升级后直接执行 `start`,CLI 会自动比较自身与 daemon 版本并优雅更新 daemon,不停止现有 tmux session。
|
|
254
|
+
|
|
255
|
+
卸载:
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
npm uninstall -g lark-coding-assistant
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## 数据目录
|
|
262
|
+
|
|
263
|
+
```text
|
|
264
|
+
~/.lark-coding-assistant/
|
|
265
|
+
├── config.json
|
|
266
|
+
├── secrets.json
|
|
267
|
+
├── state.json
|
|
268
|
+
├── logs/assistant.log
|
|
269
|
+
└── runtime/daemon.{pid,sock}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
daemon 的常规日志、stdout、stderr 和启动崩溃都会写入 `logs/assistant.log`。
|
|
273
|
+
|
|
274
|
+
## 常见问题
|
|
275
|
+
|
|
276
|
+
### 飞书消息进入了错误的 session
|
|
277
|
+
|
|
278
|
+
发送 `/sessions`,查看 `● 当前` 并点击目标 session。普通消息永远只进入 active session。
|
|
279
|
+
|
|
280
|
+
### 没收到某个 session 的完成通知
|
|
281
|
+
|
|
282
|
+
只有 active session 会主动推送。session 必须由当前 CLI 创建,才能注入统一的 `Stop` hook。
|
|
283
|
+
|
|
284
|
+
### 消息提示已排队
|
|
285
|
+
|
|
286
|
+
通常是 agent 正在审批、本地输入框已有草稿或画面无法识别。发送 `/tail` 查看当前状态。
|
|
287
|
+
|
|
288
|
+
### 审批卡显示已失效
|
|
289
|
+
|
|
290
|
+
说明 agent、active session、pane、审批画面或 nonce 已变化。发送 `/tail` 查看并等待新卡。
|
|
291
|
+
|
|
292
|
+
### 关闭本地终端后 session 还在吗
|
|
293
|
+
|
|
294
|
+
关闭 attach 的终端通常不会停止 tmux,可用 `lark-coding-assistant attach <name>` 恢复。电脑关机、tmux server 被终止或 agent 自身退出后无法继续。
|
|
295
|
+
|
|
296
|
+
agent 或对应 tmux pane 退出后,daemon 会在下一次轮询中自动从 `state.json` 移除该 session;如果退出的是 active session,会先发送退出通知,再切换到其他仍存活的 session。
|
|
297
|
+
|
|
298
|
+
### 完全重新配置 PersonalAgent
|
|
299
|
+
|
|
300
|
+
重新运行 `lark-coding-assistant init`。如果扫码账号发生变化,旧 chat 绑定会被清除,新用户成为 owner。
|
|
301
|
+
|
|
302
|
+
## 开发与发布
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
npm install
|
|
306
|
+
npm run typecheck
|
|
307
|
+
npm test
|
|
308
|
+
npm run build
|
|
309
|
+
npm link
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
源码安装:
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
git clone https://github.com/YeFeng-Silence/lark-coding-assistant.git
|
|
316
|
+
cd lark-coding-assistant
|
|
317
|
+
npm install
|
|
318
|
+
npm run build
|
|
319
|
+
npm link
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
发布前更新 `package.json` 和 `package-lock.json` 的版本号并提交。确认已登录公共 npm registry 后再发布:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
npm whoami --registry=https://registry.npmjs.org
|
|
326
|
+
npm publish
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
不要在仓库中保存 npm token;发布身份由开发机或 CI 的 npm 配置提供。
|
package/dist/cli.d.ts
ADDED