开源 · MIT · 为企业飞书而生

一句话,生成可审计的
飞书 basekit 插件

自然语言一句话描述需求 → 生成可人工逐行审计的真实飞书 basekit 插件(TypeScript),直接上传到飞书使用。NL → DSL → auditable TS → real Feishu.

生成物=人类可读源码,可自行审计后送审 三道编译期护栏,绝不 eval 端到端已真上传飞书并上线运行 飞书 OAuth 登录 · 插件归属个人 · 持久化
使用演示 · See it in action

一句话,半分钟拿到可上传的插件

下面是平台的真实生成全过程(实机录屏,仅做加速展示):输入自然语言 → 调用模型生成并校验 → 产出带「出网域名白名单 / 鉴权 / 输出列映射」的可审计 src/index.ts,再一键下载工程 zip。Real screen recording — not a mockup.

真实录屏:从「人民币按实时汇率换算美元」一句话,到可审计的 TypeScript 工程;并演示切换到自动化(addAction)再生成一个动作。
1 用一句话描述需求
在输入框用自然语言描述需求
2 自动生成 + 校验,给出结构化概览
生成结果概览:输入字段、出网域名白名单、需要的凭证、输出列映射
3 产出可逐行审计的源码,一键下载工程
可审计的 src/index.ts 源码与「下载工程 / 下载 DSL」按钮
4 切到「自动化」,同样一句话生成动作
自动化动作(addAction)生成结果与 register.ts 源码
真实效果 · Plugin in action

两类插件,每类都「生成 → 使用」一一对应

字段捷径与自动化各一对录屏:左为一句话生成,右为在真实多维表格中使用——同一个插件,从生成到落地。Each plugin type: generate (left) → use it in a real Bitable (right).

① 字段捷径 · 城市 → 天气

在数据表里加一列「天气」,对每行的「城市」自动算出温度/风速(数据来自自托管 execute 运行时)。

字段捷径生成:一句话→AI生成addField源码→下载工程
生成 — 一句「输入城市名,查实时天气」→ 生成可审计的 addField 源码 + 下载工程。
字段捷径使用:真实多维表格里城市列→天气列
使用 — 真实多维表格里「城市」列 → 自动渲染「温度/风速」列(Beijing 22.8℃、Tokyo 20.8℃…)。

② 自动化 · 汇率换算

在自动化流程里调汇率接口,把人民币金额换算成美元 + 汇率,供后续步骤消费。

自动化生成:一句话→AI生成addAction源码→汇率换算动作
生成 — 一句「输入人民币金额,按汇率换算成美元」→ 生成可审计的 addAction 源码(汇率换算动作)。
自动化使用:真实多维表格自动化中心选用汇率换算自动化
使用 — 真实多维表格自动化中心 → 创建流程 → 选用「汇率换算自动化」→ 配置触发并启用。
自托管执行 + 一键发版部署 · Self-hosted runtime & one-click ship

不依赖任何外部托管,自己的服务器上跑起来

「连接器 / 字段捷径」这类要调外部 API 的插件,执行逻辑跑在你自己部署的 execute-runner 上——自托管、出网集中可审计、无外部函数托管;改完代码到上线,一条命令完成。这是企业选型的关键之一。

自托管执行运行时

插件要调外部接口时,经 api → execute-runner 执行(解释声明式 DSL,绝不 eval)。三道硬护栏:不执行用户 JS · 出网域名白名单 + SSRF 防护 · 只读不写宿主。整条出网集中一处,便于审计。

真机实测:城市 → 天气

多维表格里「城市」一列,插件自动算出「温度 / 风速」一列,数据来自自托管运行时(无外部函数托管)。实测:Beijing 21.4℃、Tokyo 20.6℃、London 26.4℃、Paris 27.7℃。

一键发版 + 部署

后端(api / generator / execute-runner / caddy)+ 容器插件 widget,一条命令构建、上传、滚动重启。compose 单机或 k8s 皆可,平滑切换。

多维表格即存储 · 零外部数据库

平台自身的数据(插件定义 / 归属)也存进多维表格——不引入 Postgres/Redis 等外部数据库,企业自托管少一个要部署、加固、备份的组件;durability 由飞书托管,管理员还能在表里直接查看、审计每条定义。读路径带 TTL 缓存 + 按表查询,适配读密集的大规模使用。

改完代码 → 上线,一条命令:

# 一次性配置:cp scripts/deploy.example.env scripts/deploy.env(填服务器/域名/appId)
$ scripts/release.sh "城市天气字段捷径"
═══ ① 部署后端 ═══   api · generator · execute-runner · caddy  →  滚动重启 + 健康检查 ✓
═══ ② 发版 widget ═══ 注入后端地址 → webpack 构建 → opdev 上传新版本 ✓
# 末步:控制台「选版本 + 发应用版本」(免审租户即时;可进一步 API 全自动)

已端到端部署上线:生产为单机 docker compose + Caddy 自动 TLS(经 <ip>.sslip.io 魔法 DNS 由 Let's Encrypt 签发,STORE=bitable)跑在一台 AWS EC2 上;k8s 为可选的横向扩展路径。脚本与完整手册见仓库 scripts/OPERATIONS.md;部署细节见 deploy/compose/DEPLOY.mddeploy/k8s/

为谁打造 · Who it's for

为企业飞书而生

你有多维表格和插件能力,却没有插件市场、也没有专职开发团队。这套平台把「想要一个插件」到「拿到一份可上线、可审计的源码,并一键发版部署」之间的距离,压缩成一句话。Built for enterprise Feishu.

强合规 / 可审计送审

源码自带 provenance,是人类可读的 TypeScript 而非黑盒——可在内部完成代码审计后再送审上线;执行运行时自托管在你自己的服务器上,出网集中可审计。

无开发团队的业务方

运营、HR、财务想接一个外部 API 到表格里,却不会写 TypeScript。用自然语言描述即可。

缺少插件市场的环境

没有现成插件可装?把需求口述出来,平台直接产出一份可上传的 basekit 工程 zip。

两套生成器 · Two generators

字段捷径 与 自动化,覆盖两类插件

无论是「在表格里加一列、自动算出来」,还是「在自动化流程里调一个 API」,都能从一句话生成。

字段捷径

field shortcut · basekit addField

选输入字段 → 调外部 API → 把结果写回输出列。4 种鉴权、GET/POST/PUT/PATCH/DELETE + 嵌套 JSON body、多步链式(后一步用前一步响应)、条件逻辑(if/eq/gt/coalesce)、多列 Object 输出。

一句话示例

"读取『金额(USD)』列,调汇率 API 换算成人民币,结果写到『金额(CNY)』,保留两位小数。"

  • 鉴权:HeaderBearer / QueryParam / CustomHeader / Basic
  • 表达式映射:in.<输入> · res.<路径> · 算术 · 函数(trim/upper/round…) · 条件(if/eq/gt) · split
  • 13 种结果列类型(含 Url 可点击 / MultiSelect 多选)+ NumberFormatter
→ 产出:可上传的 addField 插件工程(src/index.ts + meta.json)

自动化

automation action · basekit addAction

配置输入 → 调一个外部 API → 返回结果对象,供后续自动化步骤消费。接入飞书 Base 的自动化流水线。

一句话示例

"输入城市名,调天气 API,返回温度和天气状况,供后续『发送通知』步骤使用。"

  • 鉴权:APIKey / OAuth2,支持 GET/POST + body
  • 结构化返回对象,可被下游自动化节点直接引用
  • 已端到端验证:上传 → 发布 → 在真飞书 Base 安装启用 ✓
→ 产出:可上传的 addAction 插件工程(block-basekit-cli upload ✓)

两类插件的「生成 → 在真实多维表格中使用」录屏,见上方「插件在飞书多维表格中的实际使用」

能力总览 · What it generates(全部真机验证)

从「读数据」到「写回记录」,逐项真机验证

每一项都经 testField/testAction 真调外部 API,或对真飞书 Base 写读确认——不是只编译通过。Every capability verified on a real machine, not just compiled.

读取与变换

GET→JSON 取数 · AI 入格(POST 嵌套 body,如 DeepSeek)· 文本/数学函数(trim/upper/substr/round/floor…)· compute-only「URL 即结果」。

条件逻辑

比较 / 布尔 / 分支以函数形式表达(eq/gt/and/if/coalesce)——语法绝不放原始 < > ? :,从不 eval。例:身份证按第 17 位奇偶判性别。

写路径 + 多步链式

GET/POST/PUT/PATCH/DELETE + 自定义请求头 + 嵌套 body;多步链式——后一步用前一步的响应(如「取 token → 带 token 调 API」)。

自动化写回多维表格记录

自动化动作调飞书 OpenAPI(取 token → batch_create)把数据写成多维表格记录——已真机写入一条并读回确认。不生成数据连接器

13 种结果列类型

Text / Number / DateTime / Checkbox / SingleSelect / Phone / Email / Currency / Progress / Rating / Barcode / Url(可点击) / MultiSelect(多选)

用户身份 + 个人归属

飞书 OAuth 登录;每个人创建的插件按 open_id 归属个人、可持久化(Bitable,重启不丢);源码与 dsl.json创建者署名

工作流程 · Pipeline

自然语言 → DSL → 可审计 TS → 真飞书

DSL 只是 LLM 的结构化中间表示,不是运行时;真正交付的是一份你看得懂、改得动的 TypeScript 工程。

1

自然语言

NL · 一句话

描述输入字段、要调的 API、要写回的输出。中文即可。

2

受约束 DSL

DSL · JSON

LLM 经强制 function 调用产出结构化 JSON;schema 与校验器同源,失败自动修复 ≤2 轮。

3

可审计 TS

src/index.ts

Go 渲染出带 provenance 的 basekit 工程;对真 SDK 类型编译通过。

4

真飞书

testField / upload

本地真调外部 API 验证,再上传飞书,安装启用即用。

架构 · Architecture

Go 后端(仅标准库),LLM 只产 DSL

LLM 永远不写最终代码——它只产出受约束的 DSL;可审计的 TypeScript 由确定性的 Go 渲染器生成。Deterministic codegen, LLM stays in the planning lane.

INPUT LLM · PLANNING Go · CODEGEN FEISHU 自然语言 "一句话需求" 受约束 DSL JSON 中间表示 DeepSeek / Claude function call · 自修复≤2 basekit TS 工程 src/index.ts 3 道护栏 + provenance testField / testAction Feishu FaaS basekit 运行时 addField / addAction infer render upload validate ↺ 校验失败自动修复 cmd/api (BFF·OAuth·PluginStore) · cmd/generator (持 LLM key) · internal/shortcut (DSL·校验·渲染·zip)
用户输入 / 飞书侧 LLM 规划层(只产 DSL) Go 确定性代码生成(可审计产物)
安全模型 · Security model

三道编译期护栏,源码可审计

护栏在生成阶段静态生效,不依赖运行时沙箱;加上人类可读的源码,让政企客户能在送审前自行核验每一行。

01

出网域名白名单

每个外部请求的目标域名在生成时做静态预检;不在白名单内则拒绝产出,杜绝意外出网。

02

表达式 allowlist

映射表达式走受限白名单文法(in. / res. / 算术 / 函数 / 条件(if/eq/gt) / split),绝不 eval、绝不执行任意代码

03

URL 占位符校验

URL 模板中的占位符与字段、鉴权参数严格对应;非法或悬空占位符在生成期即被拦下。

04

出网 + 操作审计账本

每一次出网调用都向专用的 audit_log 多维表格写入一条只追加(append-only)的 execute.egress 审计事件(含 actor / 目标域名 / 方法 / 结果;SSRF / 重定向拦截记为 error);管理员经 GET /api/audit 查询。热路径安全:始终落 stdout + 异步缓冲单 worker,关停时优雅排空不丢记录。

可审计源码 · Auditable by design

生成物是带 provenance 的人类可读 TypeScript,而非黑盒二进制——对信创 / 政企是正面卖点:可自行审计后再送审上线。

代码展示 · From one sentence to code

输入一句话,产出 src/index.ts

下面是字段捷径生成器的代表性产物片段——你拿到的就是这样一份可读、可改、可审计的 basekit 源码。

// 自然语言输入

"读取『金额(USD)』列,调汇率 API 把美元换算成人民币,结果写到『金额(CNY)』,保留两位小数。"

NL → DSL → render

生成器先经 LLM 产出受约束 DSL,再由 Go 渲染器输出右侧 TypeScript。每个 basekit API 都是真实 SDK 调用,可对 @lark-opdev/block-basekit-server-api 类型直接编译。

src/index.ts TypeScript · basekit addField
// generated by feishu-plugin-platform · provenance: dsl@usd2cny
import { basekit, FieldType, AuthorizationType } from '@lark-opdev/block-basekit-server-api';
const { t } = basekit;

// guardrail #1 — 出网域名白名单(生成期静态预检)
basekit.addDomainList(['api.exchangerate.host']);

basekit.addField({
  formItems: [{
    key: 'amountUsd',
    label: '金额(USD)',
    component: { type: 'FieldSelect', props: { supportType: [FieldType.Number] } },
  }],
  authorizations: [{
    id: 'rateAuth',
    type: AuthorizationType.HeaderBearerToken,   // 4 选 1 鉴权
  }],
  // guardrail #3 — URL 占位符对齐已校验字段/鉴权
  execute: async (formItemParams, context) => {
    const usd = formItemParams.amountUsd?.[0]?.value;
    const res = await context.fetch(
      `https://api.exchangerate.host/convert?from=USD&to=CNY&amount=${usd}`,
      { method: 'GET' },
    ).then(r => r.json());

    // guardrail #2 — 受限表达式 allowlist(绝不 eval)
    // dsl: out.cny = res.result ; round(2)
    const cny = Number(res.result.toFixed(2));

    return { code: FieldCode.Success, data: { cny } };
  },
  resultType: {
    type: FieldType.Number,
    extra: { formatter: '0.00' },   // NumberFormatter
  },
});

export default basekit;