Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ src/
plugins/ β€” All plugins (adapters + services)
telegram/ β€” Telegram adapter (grammY)
slack/ β€” Slack adapter (@slack/bolt)
lark/ β€” Lark / Feishu adapter (REST + WebSocket event stream)
speech/ β€” TTS/STT (Edge TTS, Groq STT)
tunnel/ β€” Port forwarding (Cloudflare, ngrok, Bore, Tailscale)
security/ β€” Access control, rate limiting
Expand Down Expand Up @@ -227,3 +228,7 @@ Users who installed and ran older versions will have config, data, and storage i
- **CLI flags & commands**: Do not remove or rename existing commands/flags. If deprecating, keep them working and log a warning.
- **Plugin API**: When changing interfaces that plugins use, must maintain backward compat or bump major version.
- **General rule**: New code must work with old data/config without requiring user action. If migration is needed, run it automatically on startup.

## Local OpenACP Workspace

The `.openacp/` directory contains a local OpenACP workspace with secrets (bot tokens, API keys). Do not read, commit, or reference files inside it.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ That's it. Send a message to your bot and start coding.
| **Telegram** | Stable | Forum topics per session, streaming, permission buttons, voice |
| **Discord** | Stable | Thread-based sessions, slash commands, button interactions |
| **Slack** | Stable | Socket Mode, channel-based sessions, thread organization |
| **Lark / Feishu** | Beta | Single-chat + thread-per-session model, interactive cards, WebSocket event stream, voice |

### Core

Expand Down
1 change: 1 addition & 0 deletions docs/gitbook/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* [Telegram](platform-setup/telegram.md)
* [Discord](platform-setup/discord.md)
* [Slack](platform-setup/slack.md)
* [Lark / Feishu](platform-setup/lark.md)

## Using OpenACP

Expand Down
1 change: 1 addition & 0 deletions docs/gitbook/platform-setup/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ OpenACP connects to your team's messaging platform and routes messages to AI cod
| [Telegram](telegram.md) | Personal use, solo developers, mobile-first workflows | ~5 minutes |
| [Discord](discord.md) | Developer teams with existing Discord servers | ~10 minutes |
| [Slack](slack.md) | Enterprise teams, organizations on Slack | ~15 minutes |
| [Lark / Feishu](lark.md) | Teams using Feishu (China) or Lark (international) | ~10 minutes |

Each platform requires you to create a bot or app in that platform's developer portal, then paste the credentials into `<workspace>/.openacp/config.json`. The interactive setup wizard (`openacp`) guides you through the process step by step.

Expand Down
110 changes: 110 additions & 0 deletions docs/gitbook/platform-setup/lark.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Lark / Feishu Setup

OpenACP supports both Feishu (the Chinese deployment, `open.feishu.cn`) and Lark (the international deployment, `open.larksuite.com`). The adapter uses a single group chat where each session lives under its own message thread, and connects to Lark's event API over a long-lived WebSocket β€” no public webhook URL or tunnel is required.

## Prerequisites

- A Lark or Feishu account with admin rights to create custom apps in the developer console.
- A Lark/Feishu group chat that the bot will join. Sessions are scoped to this single chat.
- Node.js 20+ on the machine running OpenACP.

## Step 1 β€” Create the Lark Open Platform app

1. Visit the developer console:
- Feishu (China): [https://open.feishu.cn/app](https://open.feishu.cn/app)
- Lark (international): [https://open.larksuite.com/app](https://open.larksuite.com/app)
2. Click **Create Custom App**, give it a name (e.g. "OpenACP"), and pick an icon.
3. Open the new app and enable the **Bot** capability under "Add Features".
4. Under **Permissions & Scopes**, grant the following scopes:
- `im:message` β€” receive messages
- `im:message:send_as_bot` β€” send messages as the bot
- `im:chat:readonly` β€” read group chat metadata (required for the install validator)
- `im:resource` β€” download images, audio, and files attached to messages
- `im:message.group_at_msg` β€” receive `@bot` mentions in group chats
5. Apply for version review if your tenant requires it (most internal apps can skip this step).
6. Copy your `App ID` (starts with `cli_…`) and `App Secret` from the **Credentials & Basic Info** page.

## Step 2 β€” Add the bot to your group

1. Open the target group chat in Lark/Feishu.
2. Tap the chat name β†’ **Group Settings** β†’ **Group Bot** β†’ **Add Bot**.
3. Search for your custom app and add it.
4. Copy the chat ID. The easiest way is via the Lark API explorer:
- In the developer console, open **API Explorer** β†’ `im/v1/chats` β†’ call `GET /open-apis/im/v1/chats` with the bot's tenant token.
- The response includes a list of chats the bot is a member of, each with its `chat_id` (starts with `oc_…`).

## Step 3 β€” Run the OpenACP setup wizard

```bash
npx @openacp/cli plugins install @openacp/lark
```

This is the same wizard the Telegram and Slack adapters use. You will be prompted for:

| Prompt | What to enter |
|--------|---------------|
| Domain | `feishu` for Chinese deployments, `lark` for international |
| App ID | The `cli_…` ID from the developer console |
| App Secret | The matching secret (input is masked) |
| Group chat ID | The `oc_…` ID from Step 2 |

The wizard validates each value before saving:

- The credentials are exchanged for a tenant access token.
- The token is used to fetch the chat info β€” confirming the bot has joined.

If validation fails, you can choose to retry or skip and fix the issue later. Saved settings live at `<instance>/.openacp/plugins/@openacp/lark/settings.json`.

## Step 4 β€” First boot

Start OpenACP normally:

```bash
npx @openacp/cli start
```

On first boot the adapter creates two anchor messages in your group:

- πŸ“‹ **Notifications** β€” cross-session updates (session completed, permission needed, budget warnings).
- πŸ€– **Assistant** β€” the OpenACP conversational entry point. Reply to this message to chat with the assistant.

Both anchor message IDs are persisted to plugin settings so they are reused on every restart.

To start a coding session, create one through the **Assistant** thread (e.g. "create a session for the foo project") or via the API/CLI; OpenACP posts a new session anchor in the chat and threads agent activity under it.

## How sessions map to Lark threads

Lark does not have first-class "topics" like Telegram, but it does support threaded replies via the `reply_in_thread` flag. OpenACP uses this to give every session its own collapsible thread:

```
Group chat
β”œβ”€β”€ πŸ“‹ Notifications (root message β€” stays at the top)
β”‚ β”œβ”€β”€ βœ… session-1 completed
β”‚ └── πŸ” session-2 needs permission
β”œβ”€β”€ πŸ€– Assistant (root message)
β”‚ └── (assistant chat)
β”œβ”€β”€ 🟒 session-1 (session anchor card)
β”‚ β”œβ”€β”€ user prompt
β”‚ β”œβ”€β”€ πŸ”„ Read Β· src/foo.ts
β”‚ └── βœ… Done
└── 🟒 session-2
└── …
```

When you reply to a session anchor, OpenACP looks up the session by the root message ID and forwards your message to the agent. Direct top-level messages (not in a thread) are gently redirected to the **Assistant** thread.

## Permissions, control panels, and command buttons

Rich UI is rendered as Lark interactive cards (`update_multi: true`) so the adapter can edit them in place:

- **Permission requests** appear as orange-templated cards with one button per option. Clicks come back over the WebSocket and resolve the agent's blocked prompt.
- **Tool activity** is shown as cards summarizing reads, edits, and shell commands, with optional "View file" / "View diff" links if the [tunnel plugin](../features/tunnel.md) is enabled.
- **Slash commands** (`/help`, `/agents`, etc.) are dispatched through the same `CommandRegistry` used by the other adapters; results are rendered as cards or plain text replies inside the originating thread.

## Limitations & roadmap

- HTTP webhook callbacks are not implemented yet β€” the adapter currently uses Lark's WebSocket event stream exclusively. (Plugin settings retain encrypt/verification token fields so a future release can switch transports without re-running setup.)
- Skill commands (per-session interactive command lists shown in the Telegram bot menu) are not yet surfaced in the Lark UI. They are accepted by the adapter but rendered as no-ops.
- Renaming a session changes the anchor card; Lark does not allow renaming threads themselves.

If you hit issues, see [Lark issues](../troubleshooting/lark-issues.md) or open a discussion at [github.com/Open-ACP/OpenACP](https://github.com/Open-ACP/OpenACP/discussions).
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"openacp": "dist/cli.js"
},
"scripts": {
"build": "tsc && mkdir -p dist/data && cp src/data/registry-snapshot.json dist/data/",
"build": "tsx scripts/build.ts",
"build:publish": "tsx scripts/build-publish.ts",
"dev": "./scripts/dev-loop.sh",
"dev:loop": "./scripts/dev-loop.sh",
Expand Down Expand Up @@ -46,6 +46,7 @@
"@fastify/rate-limit": "^10.3.0",
"@fastify/swagger": "^9.7.0",
"@fastify/swagger-ui": "^5.2.5",
"@larksuiteoapi/node-sdk": "^1.62.0",
"diff": "^8.0.3",
"fastest-levenshtein": "^1.0.16",
"fastify": "^5.8.4",
Expand Down
Loading