lark-acp 1.0.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/README.md +242 -0
- package/dist/index.js +122 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# Lark ACP Bridge
|
|
2
|
+
|
|
3
|
+
Bridge Lark/Feishu messages to any ACP-compatible AI agent.
|
|
4
|
+
|
|
5
|
+
`lark-acp` connects to the Lark/Feishu messaging platform via WebSocket, polls incoming direct messages and group mentions, forwards them to an ACP agent over stdio, and sends agent replies back to Lark.
|
|
6
|
+
|
|
7
|
+
Inspired by [wechat-acp](https://github.com/formulahendry/wechat-acp), but for Lark/Feishu.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Lark/Feishu WebSocket event streaming (not polling)
|
|
12
|
+
- One ACP agent session per Lark conversation (1:1 DM or group chat)
|
|
13
|
+
- Built-in ACP agent presets for common CLIs
|
|
14
|
+
- Custom raw agent command support
|
|
15
|
+
- Agent thinking/reasoning display in Lark (optional)
|
|
16
|
+
- File system access for agents (read/write)
|
|
17
|
+
- Auto-approve tool permission requests
|
|
18
|
+
- Group chat support with `@mention` filtering
|
|
19
|
+
- Real-time typing indicator (emoji reaction)
|
|
20
|
+
- Built with Bun + TypeScript for speed
|
|
21
|
+
|
|
22
|
+
## Requirements
|
|
23
|
+
|
|
24
|
+
- [Bun](https://bun.sh) 1.0.0+
|
|
25
|
+
- Lark/Feishu bot app credentials (App ID + App Secret)
|
|
26
|
+
- An ACP-compatible agent available locally or through `bunx`
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
Start with a built-in agent preset:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Install from npm (recommended)
|
|
34
|
+
npm install -g lark-acp
|
|
35
|
+
# or via Bun
|
|
36
|
+
bun install -g lark-acp
|
|
37
|
+
|
|
38
|
+
# Initialize config
|
|
39
|
+
lark-acp init # creates lark-acp.json, configure with your Lark credentials
|
|
40
|
+
|
|
41
|
+
# Start the bridge
|
|
42
|
+
lark-acp start # or: lark-acp start --agent copilot
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Or use a raw custom command:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
lark-acp start --agent "bunx my-agent --acp"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
On first run, the bridge will:
|
|
52
|
+
|
|
53
|
+
1. Load config from `lark-acp.json` (or `~/.lark-acp/config.json`)
|
|
54
|
+
2. Connect to Lark via WebSocket
|
|
55
|
+
3. Begin polling for direct messages and group mentions
|
|
56
|
+
4. Route each message to an isolated ACP session per chat
|
|
57
|
+
|
|
58
|
+
## Configuration
|
|
59
|
+
|
|
60
|
+
### Config File
|
|
61
|
+
|
|
62
|
+
Create or edit `lark-acp.json` (search order: `$LARK_ACP_CONFIG` → `./lark-acp.json` → `~/.lark-acp/config.json`):
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"lark": {
|
|
67
|
+
"appId": "cli_xxxxxxxxxxxx",
|
|
68
|
+
"appSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
69
|
+
"botName": "AI Assistant",
|
|
70
|
+
"encryptKey": "",
|
|
71
|
+
"verificationToken": ""
|
|
72
|
+
},
|
|
73
|
+
"agent": "claude",
|
|
74
|
+
"acp": {
|
|
75
|
+
"cwd": "",
|
|
76
|
+
"idleTimeoutMs": 1800000,
|
|
77
|
+
"maxConcurrent": 10,
|
|
78
|
+
"showThoughts": false,
|
|
79
|
+
"mcpServers": []
|
|
80
|
+
},
|
|
81
|
+
"autoApprovePermissions": true
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
See `lark-acp.example.json` for the full schema.
|
|
86
|
+
|
|
87
|
+
### CLI Options
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
lark-acp init [options] initialize config file
|
|
91
|
+
lark-acp agents list built-in agent presets
|
|
92
|
+
lark-acp start [options] start the bridge
|
|
93
|
+
lark-acp --help show help
|
|
94
|
+
lark-acp --version show version
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Start options:
|
|
98
|
+
|
|
99
|
+
- `--agent <preset|command>`: Built-in preset name (e.g., `claude`, `copilot`) or raw command string
|
|
100
|
+
- `--cwd <dir>`: Working directory for the agent process
|
|
101
|
+
- `--config <file>`: Load JSON config file (overrides default search)
|
|
102
|
+
- `--idle-timeout <minutes>`: Session idle timeout in minutes (default: 30; use 0 for unlimited)
|
|
103
|
+
- `--max-concurrent <count>`: Maximum concurrent agent sessions (default: 10)
|
|
104
|
+
- `--show-thoughts`: Display agent thinking/reasoning in Lark (default: off)
|
|
105
|
+
|
|
106
|
+
Examples:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
lark-acp start --agent copilot
|
|
110
|
+
lark-acp start --agent claude --cwd ~/my-project
|
|
111
|
+
lark-acp start --agent "bunx my-agent --acp" --show-thoughts
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Built-in Agent Presets
|
|
115
|
+
|
|
116
|
+
List available presets:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
lark-acp agents
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Current presets:
|
|
123
|
+
|
|
124
|
+
| Preset | Agent | Command |
|
|
125
|
+
|--------|-------|---------|
|
|
126
|
+
| `claude` | Claude Code | `bunx @zed-industries/claude-code-acp` |
|
|
127
|
+
| `copilot` | GitHub Copilot | `bunx @github/copilot --acp --yolo` |
|
|
128
|
+
| `gemini` | Google Gemini | `bunx @google/gemini-cli --experimental-acp` |
|
|
129
|
+
| `qwen` | Qwen Code | `bunx @qwen-code/qwen-code --acp --experimental-skills` |
|
|
130
|
+
| `codex` | OpenAI Codex | `bunx @zed-industries/codex-acp` |
|
|
131
|
+
| `opencode` | OpenCode | `bunx opencode-ai acp` |
|
|
132
|
+
| `pi` | Pi | `bunx -y pi-acp` |
|
|
133
|
+
|
|
134
|
+
## Getting Lark Credentials
|
|
135
|
+
|
|
136
|
+
1. Go to [Lark Open Platform](https://open.larkoffice.com/)
|
|
137
|
+
2. Create a new app → enable "Bot" capability
|
|
138
|
+
3. Get App ID and App Secret from "Credentials & Basic Info"
|
|
139
|
+
4. Subscribe to `im.message.receive_v1` events
|
|
140
|
+
5. Configure the webhook URL to your bridge's public address (if using WebSocket mode)
|
|
141
|
+
|
|
142
|
+
## Architecture
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
src/
|
|
146
|
+
├── config/ # Config loading, validation, singleton
|
|
147
|
+
├── services/
|
|
148
|
+
│ ├── lark.ts # Lark SDK: event dispatcher, reply handling, dedup
|
|
149
|
+
│ └── acp.ts # ACP session manager: spawn, queue, evict
|
|
150
|
+
├── agents.ts # Built-in agent preset registry and resolver
|
|
151
|
+
├── cli.ts # CLI arg parsing (init, agents, start)
|
|
152
|
+
└── index.ts # Entry point: boot sequence
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## How It Works
|
|
156
|
+
|
|
157
|
+
1. **Event Dispatcher**: Listens for incoming messages via Lark WebSocket
|
|
158
|
+
- Filters duplicates, validates mentions (for group chats)
|
|
159
|
+
- Routes to ACP session manager
|
|
160
|
+
2. **Session Manager**: One ACP agent process per chat (group or DM)
|
|
161
|
+
- Queues messages and processes them sequentially per user
|
|
162
|
+
- Auto-evicts oldest sessions when max concurrent reached
|
|
163
|
+
- Spawns fresh process on first message, reuses for subsequent messages
|
|
164
|
+
3. **ACP Protocol**: Bidirectional communication over stdin/stdout ndjson
|
|
165
|
+
- Streams message chunks in real-time
|
|
166
|
+
- Handles tool calls with permission gating
|
|
167
|
+
- Captures and displays agent thinking (if enabled)
|
|
168
|
+
4. **Reply Handler**: Sends agent responses back to Lark
|
|
169
|
+
- Splits long replies into Lark-safe chunks (≤4000 chars at paragraph breaks)
|
|
170
|
+
- Removes typing indicator emoji reaction
|
|
171
|
+
5. **Idle Cleanup**: Every 5 minutes, kills sessions idle for `idleTimeoutMs`
|
|
172
|
+
|
|
173
|
+
## Runtime Behavior
|
|
174
|
+
|
|
175
|
+
- Each Lark conversation (1:1 DM or group) gets a dedicated ACP session and subprocess
|
|
176
|
+
- Messages are processed serially per conversation
|
|
177
|
+
- Replies are formatted for Lark before sending (markdown → text)
|
|
178
|
+
- A thinking emoji (💭) is added while processing; removed when reply is sent
|
|
179
|
+
- Sessions are cleaned up after inactivity (set `idleTimeoutMs` to `0` to disable)
|
|
180
|
+
- Tool calls are logged in real-time for debugging
|
|
181
|
+
|
|
182
|
+
## Storage
|
|
183
|
+
|
|
184
|
+
By default, runtime files are stored at:
|
|
185
|
+
|
|
186
|
+
```text
|
|
187
|
+
~/.lark-acp/config.json # fallback config location
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The bridge does NOT persist any conversation history or state — each session is ephemeral.
|
|
191
|
+
|
|
192
|
+
## Current Limitations
|
|
193
|
+
|
|
194
|
+
- **Text messages only** — Non-text messages (images, files, voice) are rejected with a friendly message
|
|
195
|
+
- **Sequential processing** — Messages per conversation are processed one-by-one (not in parallel)
|
|
196
|
+
- **No group context reuse** — Group chats do not share agent context with 1:1 DMs with the same user
|
|
197
|
+
- **No MCP server support yet** — `mcpServers` config is parsed but not wired to the ACP protocol
|
|
198
|
+
- **Permission requests are auto-approved** — No user confirmation dialog (configurable via `autoApprovePermissions`)
|
|
199
|
+
- **Agent communication is subprocess-only over stdio** — No network-based agent support
|
|
200
|
+
- **Some preset agents may require separate auth** — e.g., Claude Code requires API key setup
|
|
201
|
+
|
|
202
|
+
## Development
|
|
203
|
+
|
|
204
|
+
### Local Setup
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
git clone <repo-url>
|
|
208
|
+
cd lark-acp
|
|
209
|
+
bun install
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Development Commands
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
bun run dev # start with file watching
|
|
216
|
+
bun run start # start without watching
|
|
217
|
+
bun run build # compile to single binary at dist/lark-acp
|
|
218
|
+
bun run typecheck # run TypeScript type checker
|
|
219
|
+
bun run check # run Biome lint + format check
|
|
220
|
+
bun run format # auto-format code in place
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Installing Locally
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
bun run install-bin # build and install to ~/.local/bin/lark-acp
|
|
227
|
+
~/.local/bin/lark-acp --help
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Contributing
|
|
231
|
+
|
|
232
|
+
Contributions are welcome! Please ensure:
|
|
233
|
+
|
|
234
|
+
- `bun run check` passes (lint + format)
|
|
235
|
+
- `bun run typecheck` passes
|
|
236
|
+
- Code follows the existing style in `CLAUDE.md`
|
|
237
|
+
|
|
238
|
+
For release/publishing workflow, see [.github/RELEASE.md](.github/RELEASE.md).
|
|
239
|
+
|
|
240
|
+
## License
|
|
241
|
+
|
|
242
|
+
MIT
|