npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

cursor-feishu

v1.1.0

Published

Cursor 飞书集成 — 通过飞书 WebSocket 长连接与 Cursor Headless CLI 交互

Readme

cursor-feishu

npm

Cursor 飞书集成 — 通过飞书 WebSocket 长连接将飞书消息接入 Cursor Headless CLI。

传输模式(FEISHU_TRANSPORT / createFeishuService({ transport })

| 值 | 说明 | |----|------| | http(默认) | 由宿主(如 Express)提供 Webhook;飞书选「发送到开发者服务器」,需公网/ngrok | | ws | Lark.WSClient 长连接;飞书选「使用长连接接收事件」,无需配置请求地址 | | both | 同时启用 WS + HTTP;请勿在飞书对同一事件重复订阅,否则依赖包内 message_id 去重 |

特性

  • 🚀 WebSocket 长连接transport: ws 时实时收消息,无需公网 Webhook
  • 🌐 HTTP Webhooktransport: http 时由宿主提供 POST 回调
  • 🤖 多媒体支持 — 图片、文件、音频、富文本消息自动处理
  • 👥 智能群聊 — 仅 @提及时回复,其他消息静默监听作为上下文
  • 💬 流式响应 — 支持实时更新消息(流式输出)
  • 🔧 灵活配置 — 支持环境变量注入和配置文件加载
  • 📝 完整类型 — TypeScript 类型定义,开发友好

快速开始

1. 安装依赖

npm install cursor-feishu

2. 创建飞书配置文件

创建 ~/.config/cursor/plugins/feishu.json

{
  "appId": "cli_xxxxxxxxxxxx",
  "appSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

也支持通过环境变量注入敏感值(适合容器部署):

{
  "appId": "${FEISHU_APP_ID}",
  "appSecret": "${FEISHU_APP_SECRET}"
}

3. 配置飞书应用

飞书开放平台 创建自建应用,然后:

  1. 添加机器人能力
  2. 事件订阅 — 添加 im.message.receive_v1im.chat.member.bot.added_v1
  3. 订阅方式(与 FEISHU_TRANSPORT 一致)
    • 使用 ws:选「使用长连接接收事件
    • 使用 http:选「发送到开发者服务器」并填写你的 Webhook URL
  4. 权限 — 开通 im:messageim:message:send_as_botim:chat
  5. 发布应用

4. 使用

import { createFeishuService } from 'cursor-feishu'

const service = await createFeishuService({
  transport: process.env.FEISHU_TRANSPORT === 'ws' ? 'ws' : 'http', // 或 'both'
  onMessage: async (msgCtx) => {
    console.log(`收到消息: ${msgCtx.content}`)
    // 调用 cursor-agent 处理消息
    // const result = await execCursor(msgCtx.content)
    // 发送结果回飞书
    // await service.getSender().sendText(msgCtx.chatId, result)
  },
  onBotAdded: async (chatId) => {
    console.log(`Bot 已加入群聊: ${chatId}`)
  }
})

await service.run()

API 文档

createFeishuService(options)

创建飞书服务实例。

参数

interface FeishuServiceOptions {
  /** 飞书配置,可从 ~/.config/cursor/plugins/feishu.json 自动加载 */
  config?: Partial<ResolvedConfig>
  appId?: string
  appSecret?: string
  /** `http` | `ws` | `both`,默认读 `FEISHU_TRANSPORT` */
  transport?: 'http' | 'ws' | 'both'
  /** 消息处理回调 */
  onMessage?: (msgCtx: FeishuMessageContext) => Promise<void>
  /** Bot 入群回调 */
  onBotAdded?: (chatId: string) => Promise<void>
  /** 卡片交互回调 */
  onCardAction?: (action: any) => Promise<void>
  /** 自定义日志函数 */
  log?: LogFn
}

返回

interface FeishuService {
  readonly transport: 'http' | 'ws' | 'both'
  run: () => Promise<void>           // 启动并运行服务
  shutdown: () => Promise<void>      // 关闭服务
  getSender: () => FeishuSender      // 获取消息发送器
  getClient: () => LarkClient        // 获取 Lark SDK 客户端
}

FeishuMessageContext

收到的消息上下文:

interface FeishuMessageContext {
  chatId: string           // 聊天 ID
  messageId: string        // 消息 ID
  messageType: string      // 消息类型(text, image, file 等)
  content: string          // 提取的文本内容
  rawContent: string       // 原始 JSON content
  chatType: "p2p" | "group"  // 聊天类型
  senderId: string         // 发送者 ID
  rootId?: string          // 回复的消息 ID
  createTime?: string      // 消息创建时间
  shouldReply: boolean     // 是否需要回复
}

FeishuSender

消息发送器:

class FeishuSender {
  // 发送文本消息
  sendText(chatId: string, text: string): Promise<boolean>

  // 发送富文本卡片
  sendCard(chatId: string, card: any): Promise<boolean>

  // 更新消息(用于流式响应)
  updateMessage(messageId: string, text: string): Promise<boolean>
}

配置说明

完整配置字段(~/.config/cursor/plugins/feishu.json):

| 字段 | 类型 | 必填 | 默认值 | 说明 | |------|------|:----:|--------|------| | appId | string | ✅ | — | 飞书应用 App ID | | appSecret | string | ✅ | — | 飞书应用 App Secret | | timeout | number | ❌ | 120000 | AI 响应超时(毫秒) | | logLevel | string | ❌ | "info" | 日志级别:fatal/error/warn/info/debug/trace | | maxHistoryMessages | number | ❌ | 200 | 入群时拉取历史消息的最大条数 | | pollInterval | number | ❌ | 1000 | 轮询响应的间隔(毫秒) | | stablePolls | number | ❌ | 3 | 连续几次轮询内容不变视为回复完成 | | dedupTtl | number | ❌ | 600000 | 消息去重缓存过期时间(毫秒) | | directory | string | ❌ | "" | 默认工作目录,支持 ~${ENV_VAR} 展开 |

群聊行为

| 场景 | 接收消息 | 回复 | |------|:---:|:---:| | 单聊 | ✅ | ✅ | | 群聊 + @bot | ✅ | ✅ | | 群聊未 @bot | ✅ (静默) | ❌ | | bot 入群 | ✅ (历史) | ❌ |

环境变量

# 启用调试日志(结构化 JSON 输出到 stderr)
FEISHU_DEBUG=1

# Feishu 应用凭证(如配置文件中使用 ${VAR} 占位符)
FEISHU_APP_ID=cli_xxxxxxxxxxxx
FEISHU_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# HTTP/HTTPS 代理支持
HTTP_PROXY=http://proxy.company.com:8080
HTTPS_PROXY=http://proxy.company.com:8080

开发

npm install           # 安装依赖
npm run build         # 构建
npm run dev           # 开发模式(监听变更)
npm run typecheck     # 类型检查
npm run release       # 交互式版本发布
npm publish           # 发布到 npm

项目结构

src/
├── index.ts           # 主入口,导出 createFeishuService
├── types.ts           # 类型定义
├── feishu/
│   ├── gateway.ts     # WebSocket 网关,连接飞书
│   └── sender.ts      # 消息发送器

常见问题

Q: 消息无法接收?

检查以下几点:

  1. 飞书应用凭证是否正确(在飞书开放平台验证)
  2. 是否订阅了 im.message.receive_v1 事件
  3. 是否使用「长连接」方式(不是 Webhook)
  4. 查看调试日志:FEISHU_DEBUG=1 node app.js 2>&1 | grep error

Q: 群聊消息无法回复?

群聊中必须 @bot,否则消息只会静默监听。这是设计行为,可以避免 bot 过度回复。

Q: 如何支持代理?

设置环境变量即可:

HTTP_PROXY=http://proxy:8080 npm start

Q: 如何与 cursor-agent 容器集成?

在 Dockerfile 中安装 cursor-feishu,然后启动一个长期运行的 Node.js 服务来处理飞书消息,再调用 cursor-agent 容器执行任务。

示例见 cursor-agent 仓库的 docs/feishu/ 目录。

许可证

MIT

相关项目