@lark-project/cli
Version:
飞书项目插件开发工具
1,351 lines (1,281 loc) • 141 kB
YAML
integrate_point_schema:
type: object
additionalProperties: false
properties:
page:
$ref: '#/integrate_point_schema/definitions/SinglePage'
$comment: 导航配置,用于定义插件在页面上的图标、名称和国际化信息
view:
$ref: '#/integrate_point_schema/definitions/SingleView'
$comment: 视图位配置,用于定义插件的视图展示,包含工作项类型
dashboard:
$ref: '#/integrate_point_schema/definitions/SingleDashboard'
$comment: 详情页位配置,用于定义插件的详情页展示
configuration:
$ref: '#/integrate_point_schema/definitions/SingleConfiguration'
$comment: 插件管理配置页位配置,用于定义插件的配置页面入口
control:
$ref: '#/integrate_point_schema/definitions/MultiControl'
$comment: >
控件配置(Control),用于定义插件的自定义 UI 组件,可嵌入表格列、详情页表单、节点表单。
⚠️ 选型指南(control vs customField):
控件适用于「展示/交互优先、数据由开发者自行存储」的场景。
平台不存储控件数据,因此不支持筛选、排序、分组、度量、条件流转、OpenAPI 读写。
同一工作项中每个控件只能出现一次。
如需「数据存储在飞书项目、可被筛选/排序/度量/用于流转条件」,请选择 customField(扩展字段-字段类型)。
详见下方 ControlPoint 与 CustomFieldPoint 的 $comment。
button:
$ref: '#/integrate_point_schema/definitions/MultiButton'
$comment: 按钮位配置,用于定义插件的按钮功能
intercept:
$ref: '#/integrate_point_schema/definitions/SingleIntercept'
$comment: 拦截位配置,用于定义插件的请求拦截功能
listen_event:
$ref: '#/integrate_point_schema/definitions/SingleListenEvent'
$comment: 监听事件位配置,用于定义插件的事件监听功能
component:
$ref: '#/integrate_point_schema/definitions/SingleComponentSchedule'
$comment: 组件位配置,用于定义插件的组件(定时任务等)
customField:
$ref: '#/integrate_point_schema/definitions/MultiCustomField'
$comment: >
扩展字段-字段类型(CustomField),用于定义插件的自定义字段类型。
⚠️ 选型指南(customField vs control):
字段模板适用于「需要平台存储数据、可被筛选/排序/分组/度量/用于节点流转条件」的场景。
它等同于飞书项目一方字段类型,管理员可像普通字段一样在字段管理中创建、拖拽配置。
同一工作项可以拥有多个该类型下的字段实例(如同一个「评分」类型可创建「技术评分」和「设计评分」两个字段)。
必须同时实现 web 和 mobile 双端。
如仅需「自定义 UI 展示、数据由开发者自行存储、无需平台级筛选/度量」,请选择 control(控件)。
详见下方 ControlPoint 与 CustomFieldPoint 的 $comment。
liteAppComponent:
$ref: '#/integrate_point_schema/definitions/MultiLiteAppComponent'
$comment: 轻应用组件位配置,用于定义插件的轻应用组件(拖拽式布局等)
aiNode:
$ref: '#/integrate_point_schema/definitions/AINodePoint'
$comment: >
AI 节点位配置(单对象,非数组)。仅 app_type=ai_node 的插件可使用,
且全工程恰好一个;与所有非 AI 点位互斥。CLI preflight 会按 plugin.config.json 的 app_type 硬卡。
aiField:
$ref: '#/integrate_point_schema/definitions/AIFieldPoint'
$comment: >
AI 字段位配置(单对象,非数组)。仅 app_type=ai_field 的插件可使用,
且全工程恰好一个;与所有非 AI 点位互斥。CLI preflight 会按 plugin.config.json 的 app_type 硬卡。
definitions:
# -----------------------------
# Common atoms
# -----------------------------
NonEmptyString:
type: string
minLength: 1
$comment: 非空字符串,用于需要用户输入且不能为空的字段
PointKey:
type: string
minLength: 1
description: 点位 key,新增时生成(只读),只要当前不存在重复的即可
ResourceId:
type: string
minLength: 1
pattern: '^[a-zA-Z0-9_-]+$'
description: 平台资源 ID(resource),不能重复。
UrlHttp:
type: string
minLength: 1
pattern: '^https?://'
description: 需以 http(s):// 开头的 URL。
TokenString:
type: string
anyOf:
- const: ''
- minLength: 36
maxLength: 36
$comment: Token 字符串;留空串或省略字段时 CLI 在 local-config set 自动生成 36 位随机数/UUID 填入,提供非空值则固定 36 位
PageIconSchema:
type: string
description: >
导航点位图标配置(JSON 字符串),格式为 {"color": "#RRGGBB", "type": "<图标标识符>"}。
color 为 hex 颜色值,必须为 ALL_COLOR 中的值;
type 为图标标识符,对应代码中的 allDeveloperIcon 或默认图标。
dslSchema:
type: object
required: [color, type]
properties:
color:
type: string
enum: ["#B449C2", "#6F5FF4", "#5E6FC4", "#30ACF1", "#2CB8C5", "#5AC262", "#A7DA2C", "#F3C641", "#FDA633", "#EF57AD"]
description: 图标颜色,对应代码中的 ALL_COLOR。
type:
type: string
enum: [
"icon-openapp_integrate_points", "icon-openapp_automation_points", "icon-openapp_publish", "icon-openapp_perm_select",
"icon-openapp_developer", "icon-openapp_app_key", "icon-openapp_base_info", "icon-openapp_doc", "icon-openapp_shop",
"icon-openapp_approval", "icon-openapp_share", "icon-openapp_listen", "icon-openapp_mcp", "icon-openapp_test",
"work_object_icon_version"
]
description: 图标标识符,对应代码中的 allDeveloperIcon 或默认图标。
$comment: 导航点位图标配置
ViewIconSchema:
type: string
description: >
视图点位图标配置(JSON 字符串),格式为 {"color": "#RRGGBB", "type": "<图标标识符>"}。
color 为 hex 颜色值,必须为 ALL_COLOR 中的值;
type 为视图特有图标标识符,对应代码中的 ALL_VIEW_ICONS。
dslSchema:
type: object
required: [color, type]
properties:
color:
type: string
enum: ["#B449C2", "#6F5FF4", "#5E6FC4", "#30ACF1", "#2CB8C5", "#5AC262", "#A7DA2C", "#F3C641", "#FDA633", "#EF57AD"]
description: 图标颜色,对应代码中的 ALL_COLOR。
type:
type: string
enum: [
"icon-openapp_view_chart", "icon-openapp_view_flow", "icon-openapp_view_pie", "icon-openapp_view_pie2",
"icon-openapp_view_line", "icon-openapp_view_graph", "icon-openapp_view_ecg"
]
description: 图标标识符,对应代码中的 ALL_VIEW_ICONS。
$comment: 视图点位图标配置
I18nInfo:
type: object
minProperties: 1
description: |
多语言名称配置(board/view/dashboard/control/button/intercept 点位使用)。
结构:key 为语言标识(如 zh-cn、en-us),value 为 { name, description }。
⚠️ 注意:不同点位的 i18n_info 结构不同,共三种形态——
1. 本定义(I18nInfo):Record<langKey, {name, description}>,langKey 为任意字符串。
2. customField:平铺对象 {name, description},无语言 key,存储时固定映射到 zh-cn。
3. liteAppComponent:语言 key 固定为 zh-cn / en-us / ja-jp(横线格式,非下划线)。
additionalProperties:
type: object
additionalProperties: false
required: [name]
properties:
name:
$ref: '#/integrate_point_schema/definitions/NonEmptyString'
maxLength: 100
description: 国际化名称,用于显示在界面上(与顶层 name 保持一致上限 100)
description:
type: string
maxLength: 50
description: 国际化描述,用于说明点位的用途
WorkItemTypeArray:
description: 工作项类型;_all 与其它互斥。
oneOf:
- type: array
minItems: 1
maxItems: 1
items:
const: _all
$comment: 使用 _all 表示支持所有工作项类型
- type: array
minItems: 1
uniqueItems: true
items:
enum: [story, issue, version, sprint, work_object]
$comment: 使用枚举值指定支持的工作项类型列表
$comment: 工作项类型配置,_all 表示支持所有类型,否则为枚举值数组
CustomWorkItemTypeArray:
type: array
uniqueItems: true
items:
type: string
minLength: 1
maxLength: 255
pattern: '^[a-z0-9_]+$'
$comment: 自定义工作项类型数组,用于 work_object 类型
# 各点位类型的工作项类型定义
WorkItemTypeForControl:
description: 控件工作项类型配置
oneOf:
- type: array
minItems: 1
maxItems: 1
items:
const: _all
description: 全部 - 支持所有工作项类型
- type: array
minItems: 1
uniqueItems: true
items:
oneOf:
- const: story
description: 需求
- const: issue
description: 缺陷
- const: version
description: 版本
- const: sprint
description: 迭代
- const: work_object
description: 其他工作项
$comment: 控件工作项类型,支持全部或指定类型
WorkItemTypeForButton:
description: 按钮位工作项类型配置
oneOf:
- type: array
minItems: 1
maxItems: 1
items:
const: _all
description: 全部 - 支持所有工作项类型
- type: array
minItems: 1
uniqueItems: true
items:
oneOf:
- const: story
description: 需求
- const: issue
description: 缺陷
- const: version
description: 版本
- const: sprint
description: 迭代
- const: work_object
description: 其他工作项
$comment: 按钮位工作项类型,支持全部或指定类型
WorkItemTypeForDashboard:
description: 详情页位工作项类型配置
oneOf:
- type: array
minItems: 1
maxItems: 1
items:
const: _all
description: 全部 - 支持所有工作项类型
- type: array
minItems: 1
uniqueItems: true
items:
oneOf:
- const: story
description: 需求
- const: issue
description: 缺陷
- const: version
description: 版本
- const: sprint
description: 迭代
- const: work_object
description: 其他工作项
$comment: 详情页位工作项类型,支持全部或指定类型
WorkItemTypeForView:
description: 视图位工作项类型配置
oneOf:
- type: array
minItems: 1
maxItems: 1
items:
const: _all
description: 全部 - 支持所有工作项类型
- type: array
minItems: 1
uniqueItems: true
items:
oneOf:
- const: story
description: 需求
- const: issue
description: 缺陷
- const: version
description: 版本
- const: sprint
description: 迭代
- const: work_object
description: 其他工作项
$comment: 视图位工作项类型,支持全部或指定类型
WorkItemTypeForIntercept:
description: 拦截位工作项类型配置
oneOf:
- type: array
minItems: 1
maxItems: 1
items:
const: _all
description: 全部 - 支持所有工作项类型
- type: array
minItems: 1
uniqueItems: true
items:
oneOf:
- const: story
description: 需求
- const: issue
description: 缺陷
- const: version
description: 版本
- const: sprint
description: 迭代
- const: work_object
description: 其他工作项
$comment: 拦截位工作项类型,支持全部或指定类型
WorkItemTypeForListenEvent:
description: 监听事件位工作项类型配置
oneOf:
- type: array
minItems: 1
maxItems: 1
items:
const: _all
description: 全部 - 支持所有工作项类型
- type: array
minItems: 1
uniqueItems: true
items:
oneOf:
- const: story
description: 需求
- const: issue
description: 缺陷
- const: version
description: 版本
- const: sprint
description: 迭代
- const: work_object
description: 其他工作项
$comment: 监听事件位工作项类型,支持全部或指定类型
WorkItemTypeForComponentSchedule:
description: 组件位(定时任务)工作项类型配置
oneOf:
- type: array
minItems: 1
maxItems: 1
items:
const: _all
description: 全部 - 支持所有工作项类型
- type: array
minItems: 1
uniqueItems: true
items:
oneOf:
- const: story
description: 需求
- const: work_object
description: 其他工作项
$comment: 组件位(定时任务)工作项类型,仅支持全部、需求、其他工作项
WorkItemTypeForLiteAppComponent:
type: array
minItems: 1
maxItems: 1
items:
const: _all
description: 全部 - 支持所有工作项类型
$comment: 轻应用组件位工作项类型,仅支持全部
WorkItemTypeForCustomField:
type: array
minItems: 1
maxItems: 1
items:
const: _all
description: 全部 - 支持所有工作项类型
$comment: 字段模板位工作项类型,仅支持全部
SceneArray:
type: array
uniqueItems: true
items:
type: integer
$comment: 场景数组,用于指定插件适用的场景编号
SceneArrayRequired:
type: array
minItems: 1
uniqueItems: true
items:
type: integer
$comment: 场景数组(必填),用于指定插件适用的场景编号,至少包含一个场景
# 各点位类型的场景定义
SceneForControlWeb:
type: array
uniqueItems: true
items:
oneOf:
- const: 1
description: 表格页
- const: 2
description: 表单页
- const: 6
description: 节点表单
$comment: 控件 Web 平台场景数组
SceneForControlMobile:
type: array
uniqueItems: true
items:
oneOf:
- const: 2
description: 表单页
- const: 6
description: 节点表单
$comment: 控件 Mobile 平台场景数组
SceneForButtonWeb:
type: array
minItems: 1
uniqueItems: true
items:
oneOf:
- const: 3
description: 工作项 - 更多
- const: 4
description: 节点 - 更多
- const: 5
description: 新增工作项实例
- const: 7
description: 节点流转
- const: 8
description: 计划表节点-更多
$comment: 按钮位 Web 平台场景数组(必填)
SceneForButtonMobile:
type: array
minItems: 1
uniqueItems: true
items:
oneOf:
- const: 3
description: 工作项 - 更多
- const: 4
description: 节点 - 更多
- const: 7
description: 节点流转
$comment: 按钮位 Mobile 平台场景数组(必填)
SceneForComponentSchedule:
type: array
minItems: 1
uniqueItems: true
description: >
组件位场景数组,必填。可选值:0(全部)、1(节点排期)、2(计划表排期)。
⚠️ 互斥规则:0(全部)与具体场景值不能共存,选 0 时数组只能是 [0],不能同时包含 1 或 2。
items:
oneOf:
- const: 0
description: 全部(与 1/2 互斥,选此项时数组只能为 [0])
- const: 1
description: 节点排期
- const: 2
description: 计划表排期
$comment: 组件位(定时任务)场景数组(必填),0 与 1/2 互斥
allOf:
- if:
contains:
const: 0
then:
maxItems: 1
$comment: 包含 0(全部)时,数组长度最多为 1,即不能再包含其他场景值
# 控件专用平台定义
PlatformWebForControl:
type: object
additionalProperties: true
properties:
resource:
$ref: '#/integrate_point_schema/definitions/ResourceId'
description: 网页端 resourceId
$comment: 网页端 resourceId
scene:
$ref: '#/integrate_point_schema/definitions/SceneForControlWeb'
table_cell:
oneOf:
- type: object
- type: string
minLength: 1
description: 向后兼容:老 yaml 中为 JSON 字符串;CLI 会在归一化阶段 JSON.parse 一次
description: |
网页端表格页展示态布局配置,当 scene 包含 1(表格页)时必填。
支持两种写法(CLI 会自动归一化,等价后再发往后端):
1. 裸 template:直接写根节点对象(必含顶层 `type` 字段),CLI 自动包成 { definitions: {data:{}, $i18n:{}, $colorTokens:{}}, template: <你写的> };
2. 完整对象:形如 { definitions: {data, $i18n, $colorTokens}, template },缺失的 definitions 子键会被补成空对象 {}。
⚠️ 硬规则(CLI 不会自动声明,运行时缺失会报错):
- 裸 template 仅限"零变量引用"场景;template 中只要出现 {{varName}} / {{$colorTokens.x}} / {{$i18n.x}} 任一引用,必须改用完整对象形式,并在 definitions 对应分类下显式声明该 key。
- {{$container.width/height}}、{{$fieldValue}}(仅 CustomField 场景)由平台注入,无需声明。
⚠️ 与"编辑态"的关系(scene 同时包含 1 与 2/6 时):
- scene 仅 [1]:表格列纯展示,双击不可编辑;用户只能通过 OpenAPI 或其他入口改值。
- scene 包含 [1, 2] 或 [1, 6]:控件同时实现了表单产物(resource 指向的 JS 入口),表格列双击会以模态框形式加载该表单产物,提供"表格内编辑"体验。
* 是否允许某一行被双击编辑,由展示态数据接口响应中的 editable 字段逐行控制(true 才唤起弹窗)。
* 此时 platform.web.resource 必填(表单产物入口),同时本字段(table_cell)依然必填(决定展示态外观)。
- scene 仅 [2]/[6]:不需要写本字段(table_cell 不会生效)。
template 树最大嵌套深度 ≤ 5(由 validateDefinitionJSON 校验)。
兼容老版本:本字段也接受 JSON 字符串,CLI 会自动 JSON.parse 一次。
dslSchema:
type: object
properties:
definitions:
type: object
description: 可选
properties:
data:
type: object
description: 数据变量声明,可在 template 中用 {{varName}} 引用
additionalProperties:
type: object
properties:
name:
type: string
description: 显示名
type:
type: string
enum: [string, number]
description: 类型,仅支持 string / number(数据接口返回值类型也仅限这两种)
mockValue:
description: 预览值(开发调试时用,需与 type 匹配)
$i18n:
type: object
description: 国际化文案,每个 key 对应多语言字符串
additionalProperties:
type: object
properties:
zh_CN:
type: string
en_US:
type: string
ja_JP:
type: string
$colorTokens:
type: object
description: 颜色 token,支持亮/暗色模式,值为 hex 或 rgba 格式
additionalProperties:
type: object
properties:
light:
type: string
description: "#RRGGBB 或 rgba(...)"
dark:
type: string
description: "#RRGGBB 或 rgba(...)"
template:
type: object
description: 必填,渲染节点树,最大深度 5 层
required: [type]
properties:
type:
type: string
enum: [view, text, image, popover]
description: |
节点类型:
- view: 容器节点,支持 children 嵌套;display 仅支持 flex(不支持 block/grid)
- text: 文本节点,使用 props.content
- image: 图片节点,使用 props.src,必须设置 width/height 否则不可见
- popover: 容器节点,点击/悬浮触发弹层;style 作用于 trigger 子元素,弹层内容由 props.entry 指定
props:
type: object
properties:
hidden:
type: boolean
description: 可选,是否隐藏该节点,默认 false
default: false
content:
description: text 节点的文本内容(支持模板表达式 {{...}}),允许 string 或 number
oneOf:
- type: string
- type: number
src:
type: string
description: image 节点的图片地址,image 节点必填;支持 png/jpeg/svg,不支持 gif
entry:
type: string
description: popover 节点的弹层入口,必填;指向打包产物中导出的入口函数名(用于渲染弹层内容)
width:
type: number
description: popover 弹窗宽度(像素),可选;不填时按弹层产物内容自适应
height:
type: number
description: popover 弹窗高度(像素),可选;不填时按弹层产物内容自适应
style:
type: object
description: |
数值类样式(width/height/margin/padding/borderWidth/borderRadius/font*/flex*)**同时接受** number 与字符串模板表达式(如 "{{$container.width}}"、"{{progress * 100}}")。
字符串值将在运行时由模板引擎求值为 number;颜色类(borderColor/backgroundColor/color)字符串值支持 hex / rgba / {{$colorTokens.x}}。
properties:
width:
description: 尺寸(像素)或模板表达式字符串
oneOf: [{ type: number }, { type: string }]
height:
oneOf: [{ type: number }, { type: string }]
marginTop:
oneOf: [{ type: number }, { type: string }]
marginBottom:
oneOf: [{ type: number }, { type: string }]
marginLeft:
oneOf: [{ type: number }, { type: string }]
marginRight:
oneOf: [{ type: number }, { type: string }]
paddingTop:
oneOf: [{ type: number }, { type: string }]
paddingBottom:
oneOf: [{ type: number }, { type: string }]
paddingLeft:
oneOf: [{ type: number }, { type: string }]
paddingRight:
oneOf: [{ type: number }, { type: string }]
borderWidth:
oneOf: [{ type: number }, { type: string }]
borderColor:
type: string
description: hex / rgba / 模板表达式(如 {{$colorTokens.xxx}})
borderRadius:
type: object
properties:
topLeft:
oneOf: [{ type: number }, { type: string }]
topRight:
oneOf: [{ type: number }, { type: string }]
bottomLeft:
oneOf: [{ type: number }, { type: string }]
bottomRight:
oneOf: [{ type: number }, { type: string }]
backgroundColor:
type: string
description: hex / rgba / 模板表达式
color:
type: string
description: 字体颜色,hex / rgba / 模板表达式
fontSize:
oneOf: [{ type: number }, { type: string }]
fontWeight:
oneOf: [{ type: number }, { type: string }]
flexDirection:
type: string
enum: [row, column]
alignItems:
type: string
enum: [stretch, flex-start, flex-end, center]
justifyContent:
type: string
enum: [stretch, flex-start, flex-end, center, space-between, space-around]
flexBasis:
oneOf: [{ type: number }, { type: string }]
flexGrow:
oneOf: [{ type: number }, { type: string }]
flexShrink:
oneOf: [{ type: number }, { type: string }]
overflow:
type: string
enum: [visible, hidden, scroll, auto]
textOverflow:
type: string
enum: [clip, ellipsis, visible, wrap]
description: text 节点文本溢出处理,默认 ellipsis
cursor:
type: string
enum: [default, none, pointer, wait, help, auto]
onClick:
type: object
description: 可选,点击事件
properties:
action:
type: string
enum: [openLink, httpRequest, writeTextToClipboard, openWorkItemCreatePage, openWorkItemDetailPage, openModal]
description: |
事件触发的动作类型:
- openLink: 新标签页打开 URL
- httpRequest: 发起网络请求;请求完成后平台会**自动重新拉取展示态数据接口**刷新本单元格;请求**不携带浏览器 Cookies**,需自行做鉴权(可校验 token/signature)
- writeTextToClipboard: 写入剪贴板
- openWorkItemCreatePage: 打开工作项新建页
- openWorkItemDetailPage: 打开工作项详情页
- openModal: 打开自定义弹窗(加载产物中导出的入口函数)
params:
type: object
description: |
- openLink: { "url": "..." }
- httpRequest: { "method": "GET|POST|PUT|DELETE", "url": "...", "headers"?: {...}, "params"?: {...}, "body"?: {...} }
- writeTextToClipboard: { "content": "..." }
- openWorkItemCreatePage: { "spaceSimpleName": "...", "workObjectId": "...", "supportedWorkObjectIds"?: ["..."] }
- openWorkItemDetailPage: { "spaceSimpleName": "...", "workObjectId": "...", "workItemId": number }
- openModal: { "entry": "...", "width"?: number, "height"?: number, "fullScreen"?: false, "maskClosable"?: true }
* entry:必填,产物中导出的入口函数名(用于渲染弹窗内容)
* fullScreen:默认 false;maskClosable:默认 true
eventParams:
type: object
properties:
stopPropagation:
type: boolean
description: 可选,是否阻止冒泡,默认 false
onDoubleClick:
type: object
description: 可选,双击事件,结构与 onClick 完全一致(action / params / eventParams)
properties:
action:
type: string
enum: [openLink, httpRequest, writeTextToClipboard, openWorkItemCreatePage, openWorkItemDetailPage, openModal]
params:
type: object
eventParams:
type: object
properties:
stopPropagation:
type: boolean
children:
type: array
description: 子节点数组,结构同 template,递归,总深度 ≤ 5
items:
$ref: '#/integrate_point_schema/definitions/PlatformWebForControl/properties/table_cell/dslSchema/properties/template'
templateExpressions:
description: |
props / style 中的字符串值支持 Mustache 风格模板表达式 {{expression}}:
【可引用的变量】
- {{varName}}:definitions.data 中声明的自定义变量(值由展示态数据接口返回)
- {{$container.width}} / {{$container.height}}:当前单元格的宽/高(像素)
- {{$colorTokens.tokenName}}:自定义颜色 token(自动适配亮/暗色模式)
- {{$i18n.key}}:自定义多语言词条(自动使用当前用户语言)
【支持的操作符】
- 分组:( )
- 属性 / 数组访问:x.y、a[i]
- 算术:+ - * / %
- 比较:== != >= <= > <
- 三元:x ? y : z
【示例】
- {{$container.height * 0.5}} // 容器高度的一半
- {{list[0].status == 1 ? 'done' : 'todo'}} // 三元 + 属性访问
- {{openRate * 100}}% // 算术
- 颜色:{{$colorTokens.font_color}}
availableVariables:
description: |
变量分两类:
【A. 平台注入(无需声明,直接引用)】
- {{$container.width}} / {{$container.height}}:当前单元格宽高(像素)
- {{$fieldValue}}:仅 CustomField 场景下可用,结构见下方"CustomField 场景"
【B. 必须在 definitions 中显式声明,否则运行时报错】
- {{varName}} → definitions.data.<varName> (必填 type/name/mockValue)
- {{$colorTokens.x}} → definitions.$colorTokens.<x> (必填 light / dark)
- {{$i18n.x}} → definitions.$i18n.<x> (必填 zh_CN / en_US / ja_JP)
CLI 仅兜底"补三个空对象壳子",不会替你声明 key;裸 template 简写仅在零引用时可用。
【Control(控件)场景】
仅支持上面列出的平台变量;业务数据全部来自 data 声明 + 展示态数据接口返回。
【CustomField(扩展字段-字段类型)场景】
额外支持 {{$fieldValue}}:当前单元格对应字段的实例值,类型为数组
(为何是数组:参见 CustomFieldValue 文档),结构为:
$fieldValue: Array<{ [subFieldKey: string]: SubFieldValue }>
其中 subFieldKey 为开发者后台中"子字段"的 key。
五种子字段类型对应的 SubFieldValue 结构:
- 数字: number
- 多行文本: string
- 日期+时间: number(毫秒时间戳)
- 多选人员: Array<{ name: string; userKey: string }>
- 级联多选: Array<{ label: string; value: string }>
常见用法(以子字段 key 为 sub_field_xxx 为例):
// 文本/数字
"{{($fieldValue && $fieldValue[0] && $fieldValue[0].sub_field_xxx) ? $fieldValue[0].sub_field_xxx : '空'}}"
// 级联多选取首个 label
"{{($fieldValue && $fieldValue[0] && $fieldValue[0].sub_field_xxx && $fieldValue[0].sub_field_xxx[0]) ? $fieldValue[0].sub_field_xxx[0].label : '空'}}"
// 多选人员取首个 name
"{{($fieldValue && $fieldValue[0] && $fieldValue[0].sub_field_xxx && $fieldValue[0].sub_field_xxx[0]) ? $fieldValue[0].sub_field_xxx[0].name : '空'}}"
tableDataInterface:
description: |
展示态数据接口(control.table_url.url 或 customfield.platform.web.table_data_url)协议:
【请求】POST Content-Type: application/json
Body: {
"request_time": 1733381298,
"signature": "...", // 用于校验来源(结合 token 计算)
"project_key": "...", // 当前空间 ID
"user_language": "zh-cn|en-us|ja-jp",
"plugin_info": { "plugin_key", "plugin_version", "point_type", "point_key" },
"user_info": { "user_key", "name_cn", "name_en", "email" },
"work_item_infos": [ // 当前可视区域的行,单次最多 20 条
{ "work_item_id": 5165731777, "work_item_type_key": "story" }
]
}
【响应】Status 200
Body: {
"code": 0, // 0 成功,非 0 异常(整体丢弃)
"msg": "",
"data": {
"work_item_datas": [
{
"work_item_id": 5165731777, // 对应请求里的 work_item_id
"result": true, // false 时该行数据被丢弃
"err_msg": "...", // result=false 时显示给用户
"editable": true, // true 且控件实现了表单场景,则双击可唤起编辑弹窗
"work_item_data": { // 仅 string / number 字面值,对应 definitions.data 中声明的变量
"openRate": 0.3,
"label": "进行中"
}
}
]
}
}
【性能要求】
- 单次请求响应时间 < 3s
- 单次响应体体积 < 100kB
$comment: 网页端表格页展示态布局 DSL(对象),scene=[1] 时必填;支持裸 template 或完整 {definitions, template},CLI 自动归一化;最大嵌套深度 ≤ 5
table_url:
type: object
additionalProperties: false
properties:
url:
$ref: '#/integrate_point_schema/definitions/UrlHttp'
description: 网页端表格页展示态数据接口(可选);填写后 token 由 CLI 自动生成,无需手动校验
$comment: 网页端表格页展示态数据接口,填写后 token 由 CLI 自动生成
token:
$ref: '#/integrate_point_schema/definitions/TokenString'
description: 网页端表格页展示态数据接口 Token;当 url 填写时由 CLI 自动生成(36 位 UUID),无需手动填写
$comment: 网页端表格页展示态数据接口 Token,url 有值时由 CLI 自动生成(schema 不强校验)
$comment: 控件 Web 平台配置
allOf:
# 当 scene 包含表单页(2)或节点表单(6)时,resource 和 scene 必填
- if:
properties:
scene:
type: array
contains:
oneOf:
- const: 2
- const: 6
then:
required: [resource, scene]
# 当 scene 包含表格页(1)时,table_cell 必填
- if:
properties:
scene:
type: array
contains:
const: 1
then:
required: [table_cell]
PlatformMobileForControl:
type: object
additionalProperties: true
required: [resource, scene, mobile_block_style]
properties:
resource:
$ref: '#/integrate_point_schema/definitions/ResourceId'
description: 移动端 resourceId
$comment: 移动端 resourceId
scene:
$ref: '#/integrate_point_schema/definitions/SceneForControlMobile'
mobile_block_style:
type: string
enum: [not_display, small, medium, big]
description: 移动端概览,控制移动端展示尺寸
$comment: 移动端概览,控制移动端展示尺寸
$comment: 控件 Mobile 平台配置,包含资源 ID、场景数组和移动端概览
# 组件排期专用平台定义
PlatformWebForComponentSchedule:
type: object
additionalProperties: true
required: [resource, scene]
properties:
resource:
$ref: '#/integrate_point_schema/definitions/ResourceId'
scene:
$ref: '#/integrate_point_schema/definitions/SceneForComponentSchedule'
$comment: 组件排期 Web 平台配置,必须包含资源 ID 和场景数组
PlatformWebForButton:
type: object
additionalProperties: true
required: [resource, scene, mode]
properties:
resource:
$ref: '#/integrate_point_schema/definitions/ResourceId'
scene:
$ref: '#/integrate_point_schema/definitions/SceneForButtonWeb'
mode:
type: string
enum: [ui, script]
description: 点击后效果:ui(弹窗)或 script(执行脚本)
$comment: 点击后效果
init_size:
type: object
required: [width, height, width_type, height_type]
properties:
width:
type: integer
minimum: 1
description: 弹窗宽度(px),必须为正整数,默认 448
height:
type: integer
minimum: 1
description: 弹窗高度(px),必须为正整数,默认 400
width_type:
type: string
enum: [static, dynamic]
description: 宽度类型,如 static
height_type:
type: string
enum: [static, dynamic]
description: 高度类型,如 static
description: 弹窗初始尺寸,当 mode 为 ui 时必填;默认值为 {width_type:static, height_type:static, width:448, height:400}
$comment: 弹窗初始尺寸配置,width/height 必须为正整数
$comment: 按钮位 Web 平台配置,必须包含资源 ID、场景数组和点击后效果
allOf:
# 当 mode 为 ui(弹窗)时,init_size 必填;否则不允许携带 init_size
- if:
properties:
mode:
const: ui
then:
required: [init_size]
else:
properties:
init_size: false
PlatformMobileForButton:
type: object
additionalProperties: true
required: [resource, scene]
properties:
resource:
$ref: '#/integrate_point_schema/definitions/ResourceId'
scene:
$ref: '#/integrate_point_schema/definitions/SceneForButtonMobile'
$comment: 按钮位 Mobile 平台配置,必须包含资源 ID 和场景数组
PlatformWebWithScene:
type: object
additionalProperties: true
required: [resource]
properties:
resource:
$ref: '#/integrate_point_schema/definitions/ResourceId'
scene:
$ref: '#/integrate_point_schema/definitions/SceneArray'
$comment: Web 平台配置,包含资源 ID 和场景数组
PlatformMobileWithScene:
type: object
additionalProperties: true
required: [resource]
properties:
resource:
$ref: '#/integrate_point_schema/definitions/ResourceId'
scene:
$ref: '#/integrate_point_schema/definitions/SceneArray'
$comment: Mobile 平台配置,包含资源 ID 和场景数组
PlatformWebNoScene:
type: object
additionalProperties: true
required: [resource]
properties:
resource:
$ref: '#/integrate_point_schema/definitions/ResourceId'
$comment: Web 平台配置(无场景),仅包含资源 ID
PlatformMobileNoScene:
type: object
additionalProperties: true
required: [resource]
properties:
resource:
$ref: '#/integrate_point_schema/definitions/ResourceId'
$comment: Mobile 平台配置(无场景),仅包含资源 ID
PlatformWebWithRequiredScene:
type: object
additionalProperties: true
required: [resource, scene]
properties:
resource:
$ref: '#/integrate_point_schema/definitions/ResourceId'
scene:
$ref: '#/integrate_point_schema/definitions/SceneArrayRequired'
$comment: Web 平台配置,必须包含资源 ID 和场景数组
PlatformMobileWithRequiredScene:
type: object
additionalProperties: true
required: [resource, scene]
properties:
resource:
$ref: '#/integrate_point_schema/definitions/ResourceId'
scene:
$ref: '#/integrate_point_schema/definitions/SceneArrayRequired'
$comment: Mobile 平台配置,必须包含资源 ID 和场景数组
# -----------------------------
# Board
# -----------------------------
PagePoint:
type: object
additionalProperties: false
required: [name, key, icon, i18n_info, platform]
properties:
key:
allOf:
- $ref: '#/integrate_point_schema/definitions/PointKey'
- pattern: '^board_'
description: 导航唯一标识(Key),生成规则:不能重复,前缀为 board_,后面默认随机生成6位
icon:
$ref: '#/integrate_point_schema/definitions/PageIconSchema'
default: '{"color":"#B449C2","type":"work_object_icon_version"}'
name:
type: string
maxLength: 15
description: 页面名称,用于在导航菜单中显示
description:
type: string
maxLength: 50
description: 描述,用于说明导航页面的用途
i18n_info:
$ref: '#/integrate_point_schema/definitions/I18nInfo'
$comment: 多语言信息,包含页面名称(name)和可选的描述(description)
platform:
type: object
additionalProperties: false
anyOf:
- required: [web]
- required: [mobile]
properties:
web:
$ref: '#/integrate_point_schema/definitions/PlatformWebNoScene'
$comment: 网页端配置,仅包含 resourceId
$description: 网页端配置,仅包含 resourceId
mobile:
$ref: '#/integrate_point_schema/definitions/PlatformMobileNoScene'
$comment: 移动端配置,仅包含 resourceId
$description: 移动端配置,仅包含 resourceId
$comment: 导航配置,用于定义插件在侧边栏或顶部导航的入口,包含页面名称、图标、适用端等
SinglePage:
type: array
maxItems: 1
items:
$ref: '#/integrate_point_schema/definitions/PagePoint'
$comment: 单个板块位配置数组,最多只能有一个
# -----------------------------
# View
# -----------------------------
ViewPoint:
type: object
additionalProperties: false
required: [name, key, icon, i18n_info, work_item_type, platform]
properties:
key:
allOf:
- $ref: '#/integrate_point_schema/definitions/PointKey'
- pattern: '^view_'
description: 视图唯一标识(Key),生成规则:不能重复,前缀为 view_,后面默认随机生成6位
icon:
$ref: '#/integrate_point_schema/definitions/ViewIconSchema'
default: '{"color":"#B449C2","type":"icon-openapp_view_chart"}'
name:
type: string
maxLength: 15
description: 视图名称,用于在列表中显示
description:
type: string
maxLength: 50
description: 描述,用于说明视图的用途
i18n_info:
$ref: '#/integrate_point_schema/definitions/I18nInfo'
$comment: 多语言信息,包含视图名称(name)和可选的描述(description)
work_item_type:
$ref: '#/integrate_point_schema/definitions/WorkItemTypeForView'
$comment: 工作项类型配置,支持全部或指定类型
platform:
type: object
additionalProperties: false
required: [web]
properties:
web:
$ref: '#/integrate_point_schema/definitions/PlatformWebNoScene'
$comment: 网页端配置,仅包含 resourceId
$description: 网页端配置,仅包含 resourceId
$comment: 视图配置,用于定义插件的工作项视图页面,包含视图名称、图标、工作项类型和适用端等
SingleView:
type: array
maxItems: 1
items:
$ref: '#/integrate_point_schema/definitions/ViewPoint'
$comment: 单个视图位配置数组,最多只能有一个
# -----------------------------
# Dashboard
# -----------------------------
DashboardPoint:
type: object
additionalProperties: false
required: [name, key, i18n_info, work_item_type, platform]
properties:
key:
allOf:
- $ref: '#/integrate_point_schema/definitions/PointKey'
- pattern: '^dashboard_'
description: 详情页唯一标识(Key),生成规则:不能重复,前缀为 dashboard_,后面默认随机生成6位
name:
type: string
maxLength: 15
description: 详情页名称,用于在列表中显示
description:
type: string
maxLength: 50
description: 描述,用于说明详情页的用途
i18n_info:
$ref: '#/integrate_point_schema/definitions/I18nInfo'
$comment: 多语言信息,包含详情页名称(name)和可选的描述(description)
work_item_type:
$ref: '#/integrate_point_schema/definitions/WorkItemTypeForDashboard'
$comment: 工作项类型配置,支持全部或指定类型
custom_work_item_type:
$ref: '#/integrate_point_schema/definitions/CustomWorkItemTypeArray'
$comment: 自定义工作项类型配置,当 work_item_type 包含 work_object 时使用
platform:
type: object
additionalProperties: false
anyOf:
- required: [web]
- required: [mobile]
properties:
web:
$ref: '#/integrate_point_schema/definitions/PlatformWebNoScene'
$comment: 网页端配置,仅包含 resourceId
$description: 网页端配置,仅包含 resourceId
mobile:
$ref: '#/integrate_point_schema/definitions/PlatformMobileNoScene'
$comment: 移动端配置,仅包含 resourceId
$description: 移动端配置,仅包含 resourceId
$comment: 详情页配置,用于定义插件的详情页展示、工作项类型和适用端等
# 动态联动:仅当 work_item_type 包含 work_object 时,custom_work_item_type 才出现且必填
allOf:
- if:
properties:
work_item_type:
type: array
contains:
const: work_object
then:
required: [custom_work_item_type]
properties:
custom_work_item_type:
allOf:
- $ref: '#/integrate_point_schema/definitions/CustomWorkItemTypeArray'
- minItems: 1
else:
not:
required: [custom_work_item_type]
SingleDashboard:
type: array
maxItems: 1
items:
$ref: '#/integrate_point_schema/definitions/DashboardPoint'
$comment: 单个仪表盘位配置数组,最多只能有一个
# -----------------------------
# Config (plugin config page)
# -----------------------------
ConfigurationPoint:
type: object
additionalProperties: false
required: [key, platform]
properties:
key:
allOf:
- $ref: '#/integrate_point_schema/definitions/PointKey'
- pattern: '^config_'
description: 插件配置唯一标识(Key),生成规则:不能重复,前缀为 config_,后面默认随机生成6位
platform:
type: object
additionalProperties: false
required: [web]
properties:
web:
$ref: '#/integrate_point_schema/definitions/PlatformWebNoScene'
$comment: 网页端配置,仅包含 resourceId
$description: 网页端配置,仅包含 resourceId
$comment: 插件配置,用于定义插件的配置页面入口和适用端等
SingleConfiguration:
type: array
maxItems: 1
items:
$ref: '#/integrate_point_schema/definitions/ConfigurationPoint'
$comment: 单个配置页位配置数组,最多只能有一个
# -----------------------------
# Control
# -----------------------------
ControlPoint:
type: object
additionalProperties: false
required: [key, i18n_info, work_item_type, platform]
properties:
key:
allOf:
- $ref: '#/integrate_point_schema/definitions/PointKey'
- pattern: '^control_'
description: 控件唯一标识(Key),生成规则:不能重复,前缀为 control_,后面默认随机生成6位
name:
type: string
maxLength: 100
description: 控件名称,用于在列表中显示。maxLength 为 100(其他点位为 15),因控件名用作字段标签,允许更长的描述性名称。
description:
type: string
maxLength: 50
description: 描述,用于说明控件的用途
i18n_info:
$ref: '#/integrate_point_schema/definitions/I18nInfo'
$comment: 多语言信息,包含控件名称(name)和可选的描述(description)
work_item_type:
$ref: '#/integrate_point_schema/definitions/WorkItemTypeForControl'
$comment: 工作项类型配置,支持全部或指定类型
# Control 表单有"新建页可见"逻辑;后端字段仍是 url/token
url:
$ref: '#/integrate_point_schema/definitions/UrlHttp'
description: Webhook 回调地址,开启"新建页可见"时必填,需以 http(s):// 开头
$comment: Webhook 回调地址,开启"新建页可见"时必填,需以 http(s):// 开头
token:
$ref: '#/integrate_point_schema/definitions/TokenString'
description: Webhook 回调地址 Token;当 url 填写时自动生成(36 位 UUID),无需手动填写。
$comment: Webhook 回调地址 Token,url 有值时自动生成
platform:
type: object
additionalProperties: false
required: [web]
properties:
web:
$ref: '#/integrate_point_schema/definitions/PlatformWebForControl'
$comment: 网页端配置,包含资源 ID、场景和表格页展示态相关配置
mobile:
$ref: '#/integrate_point_schema/definitions/PlatformMobileForControl'
$comment: 移动端配置,包含资源 ID、场景和移动端概览配置
$comment: >
控件(Control)点位配置。
【什么是控件】
控件是由开发者自定义的页面表单组件,可嵌入表格列视图、详情页表单、节点表单中。
开发者可自定义控件的展示样式,并通过客户端/服务端 API 消费平台数据,但平台不提供控件相关数据的存储。
适用场景:评分组件、进度条组件、POI 地址组件、审批面板等「展示/交互优先」的场景。
JSSDK 命名空间:window.JSSDK.control.*
【control vs customField 能力对比】
| 能力维度 | control(控件) | customField(扩展字段-字段类型) |
|---------------------|--------------------------------------|---------------------------------------------|
| 数据存储 | ❌ 平台不存储,开发者自行管理 | ✅ 存储在飞书项目,系统可感知 |
| 工作项实例数量 | 每个控件只能出现 1 次 | 同类型可创建多个字段实例 |
| 工作项类型范围 | schema 强校(_all 或指定类型,admin 不能改) | schema 仅 _all;admin 装字段时按一方流程,可挂任意工作项类型 |
| 字段配置(有效性等)| ❌ | ✅ 响应有效性、授权角色、权限配置 |
| 布局配置(必填等) | ❌ | ✅ 响应新建页可见性、新建页必填 |
| 条件配置(流转条件)| ❌ | ✅ 可用于节点流转条件 |
| 视图筛选/排序/分组 | ❌ 仅可添加为自定义列 | ✅ 可筛选、可排序、可分组、可设为预置列 |
| 度量 | ❌ | ✅(即将上线) |
| OpenAPI 读写 | ❌ | ✅ 任意插件可读,开发插件可写 |
| 新建页支持 | 需自建 Webhook 存储逻辑 | 原生支持,与一方字段一致 |
【选型决策树】(三层:术语明示 → 独家信号 → 歧义停下问)
—— Step 0:用户**字面**写出点位名?(不靠语义引申)
题面字面包含 "扩展字段 / 拓展字段 / 字段模板 / 自定义字段 / customField" → customField
题面字面包含 "控件 / 控件组件 / control" → control
字面**没出现**这些词(如题面只说 "客户备注 / 打分 / 进度" 等业务词)→ **不命中 Step 0**,进 Step 1
⚠️ 例外:术语与需求描述冲突(如"控件 + 进视图筛选")→ stop-and-ask 不盲从
—— Step 1:题面是否有 customField / control 独家能力的强信号?
【明确 customField 独家信号】(任一命中即定 customField):
- admin 在字段配置面 / 配置弹窗自定义 X(如颜色 / 文案 / 阈值)
- 同字段挂多个实例("3 档评分各一个" / 联系人列表)
- 字段值要进流转条件 / 度量 / 视图自定义列
- 受 admin 必填 / 可见性 / 授权角色 / 权限管控
【明确 control 独家信号】(任一命中即定 control):
- UI 组件语义(审批面板 / 进度条 / 状态切换器 / 历史时间线 / 操作按钮组),不是字段值
- 嵌新建页 + webhook 关联自建后端
- 仅表格列纯展示(DSL only 零 React,无字段值绑定)
- 数据只存储在业务后端,不会存储在飞书项目中
—— Step 2:Step 0/1 都未命中 OR 题面同时有 customField 和 control 都说得通的描述 → 题面歧义
【铁律】(违反 = process 错,HARD 失败):
- **禁止预先表态选型**("应选 customField" / "候选点位类型 customField" 都算违规)
- **必须列两个候选并列展开**(单个不算列)
- **必须扫题面 3 类歧义信号全套**——① 数据来源 / ② 数据存储归属 / ③ 数据形态——每条命中信号对应一个用户决策问题,不漏(端支持差异不在此列:mobile 不展示两路径都能搞定,非真歧义)
典型歧义点(每条都要查一遍):
- 数据来源是外部系统(CRM / ERP)→ 是否落地飞项被筛 / 排 / 度量?(落地 → customField;不落地 → control)
- 没有需要作为一方字段的能力,单纯在表单/表格上自定义展示和交互 → control
强制流程(echo 完整能力对比表 → 3 类信号扫描 → 双候选并列展开 → 决策问题清单 → 用户拍板)由 plan 工作流的 §P2.5.1(customField vs control 选型边界特例分支)执行,全做完才能向用户拍板。
MultiControl:
type: array
items:
$ref: '#/integrate_point_schema/definitions/ControlPoint'
$comment: 多个控件配置数组
# -----------------------------
# Button
# -----------------------------
ButtonPoint:
type: object
additionalProperties: false
required: [key, i18n_info, work_item_type, platform]
properties:
key:
allOf:
- $ref: '#/integrate_point_schema/definitions/PointKey'
- pattern: '^button_'
description: 点位唯一标识,生成规则:不能重复,前缀为 button_,后面默认随机生成6位
$comment: 点位唯一标识,生成规则:不能重复,前缀为 button_,后面默认随机生成6位
name:
type: string
maxLength: 15
$comment: 按钮名称,用于在列表中显示
descr