UNPKG

@lark-project/cli

Version:

飞书项目插件开发工具

265 lines (187 loc) 13.5 kB
# Meegle 插件开发 CLI 命令详解 > 本文件是 [`../SKILL.md`](../SKILL.md) 的命令字典补充。SKILL.md 里 A 类速查表的"详见"列均指向本文。 ## CLI 基础 **命令前缀**:所有命令均通过以下方式调用: ```bash lpm <command> [options] ``` **工程识别**:大部分命令需要在插件工程目录下执行(存在 `plugin.config.json`)。以下命令例外,可在任意目录执行: - `login` — 全局认证 - `whoami` — 查看登录态 - `create` — 创建新插件工程 **配置来源**:`siteDomain``pluginId` 等信息自动从 `plugin.config.json` 读取,无需手动传入。 --- ## 命令详解 ### 登录认证 ```bash # 方式 A:浏览器 OAuth 授权(交互式) lpm login --site-domain <域名> # 方式 B:直接设置永久 Developer Token(推荐) lpm login --site-domain <域名> --token <developer_token> ``` | 参数 | 必填 | 说明 | |------|------|------| | `--site-domain` | 是 | Meegle 站点域名,含协议(如 `https://meego.feishu-boe.cn`) | | `--token` | 否 | 永久 Developer Token,有则跳过 OAuth | ### 查看登录态 ```bash lpm whoami ``` 只读,列出已登录的 Meegle 站点,并标记建议用于 `lpm create` 的站点(最近登录优先)。无参数,可在任意目录执行,**绝不打印 token**。AI 取 `siteDomain` 前可先跑它,按输出与用户确认。 ### 创建插件 ```bash lpm create --site-domain <域名> --name "<名称>" [--force] ``` | 参数 | 必填 | 说明 | |------|------|------| | `--site-domain` | 是 | 站点域名 | | `--name` | 是 | 插件名称 | | `--description` | 否 | 短描述 | | `--force` | 否 | 已在插件目录中时跳过确认 | **产出**:在当前目录创建插件工程,生成 `plugin.config.json` + `src/` + `node_modules/`### 启动调试 ```bash lpm start --auto ``` | 参数 | 必填 | 说明 | |------|------|------| | `--auto` | 否 | 自动打开浏览器调试页面(推荐) | | `--source-type` | 否 | `local`(用本地配置)或 `remote`(用远端配置,默认) | **行为**:启动 webpack-dev-server + 热更新,`--auto` 时自动拼接调试 URL 并在浏览器中打开。 ### 同步配置 ```bash # 本地 → 远端 + 拉回模板(推送本地点位配置 + 自动拉回远端配置和模板代码,一条命令完成) lpm update --source-type=local # 仅远端 → 本地(只拉取,不推送) lpm update ``` | 参数 | 必填 | 说明 | |------|------|------| | `--source-type` | 否 | `local`(推送到远端 + 自动拉回模板,常规配置流程用这个)或默认不传(仅从远端拉取) | | `--allow-delete` | 否 | 用户**明示同意删除**后才加:绕过 push 前的删除闸口(本地配置丢了远端点位时默认 exit 2 拦下)。删除不可逆,无用户明示同意不得加 | **行为**: - `--source-type=local`push 前先跑删除闸口(本地相比远端丢点位且未带 `--allow-delete`exit 2、不推送),通过后把 `point.config.local.json` 推到远端,再**自动**拉回远端最新配置 + 后端模板代码,刷新 `plugin.config.json.resources``src/features/<resourceId>/index.tsx` - 不传 `--source-type`:从远端拉取最新点位定义,生成/更新代码模板,更新 `plugin.config.json` 的 resources;仅在本地没有未推送的改动时使用 > Stage Config 配置流程:`local-config set --from <draft>`(本地校验 + 暂存到 `point.config.local.json`)→ `update --source-type=local`(推送 + 拉回模板代码)。两步跑完,本地 + 远端 + 模板代码都同步完成。 ### 构建 ```bash lpm build [--zip] ``` | 参数 | 必填 | 说明 | |------|------|------| | `--zip` | 否 | 构建后打包为 zip | | `--source-type` | 否 | `local``remote` | **产出**:`build/` 目录。 ### 构建发布 **完整发布是两步串行操作**,不可跳步: ```bash # 第 1 步:构建 + 上传产物 lpm release # 输出:Artifact version: <artifactVersion> # 第 2 步:版本发布(必须使用第 1 步输出的 artifactVersion) lpm publish \ --artifact-version <artifactVersion> \ --release-notes "<版本描述>" ``` **release 参数**: | 参数 | 必填 | 说明 | |------|------|------| | `--source-type` | 否 | `local``remote` | **publish 参数**: | 参数 | 必填 | 说明 | |------|------|------| | `--artifact-version` | **是** | 来自 `release` 输出的构建产物版本号 | | `--release-notes` | 是 | 版本描述 / release notes(中文) | | `--version` | 否 | 语义化版本号,不传则自动 patch +1 | | `--store` | 否 | `yes`(发布到商店)/ `no`(仅内部)。**不传则继承上一版本 visibility**;首次发布默认 `yes` | | `--upgrade` | 否 | CLI 默认 `manual`;AI 不主动传,仅当用户明确要求 `all`(自动升级所有安装)/ `limit`(按范围)时才显式传 | **关键**:`--artifact-version` 必须从 `release` 的 stdout 中提取(正则:`/Artifact version: (\S+)/`),不可编造。 ### 修改基本信息 ```bash lpm update-description \ --name "<插件名称>" \ --short-description "<短描述>" \ --detail-description "<详情描述>" \ --category-ids "<id1>,<id2>" ``` | 参数 | 必填 | 说明 | |------|------|------| | `--name` | 否 | 插件名称 | | `--short-description` | 否 | 短描述(纯文本) | | `--detail-description` | 否 | 详情描述(纯文本,CLI 自动转富文本) | | `--category-ids` | 否 | 分类 ID 列表,逗号分隔(从 `list-categories` 获取) | | `--icon` | 否 | 图标 URL | > 所有参数均为可选,只传需要修改的字段即可。 ### 点位配置管理 ```bash # 写入远端配置到 .lpm-cache/config/remote.json lpm local-config get --remote # 把 draft 写入本地 point.config.local.json(全量替换语义,本地 staging;不推送远端)。 # 写本地前跑删除闸口:draft 相比远端丢点位且未带 --allow-delete → exit 2、不写本地。 # 成功后 CLI 会: # 1) 把已消费的 draft 和 .lpm-cache/config/remote.json 基线移出活跃目录(你无需手动清理) # 2) 把新的完整配置写入工程根 point.config.local.json lpm local-config set --from .lpm-cache/config/draft-<timestamp>.json # 用户明示同意删除后才加 --allow-delete 绕过删除闸口: lpm local-config set --from .lpm-cache/config/draft-<timestamp>.json --allow-delete # 预览本地 vs 远端差异(CRITICAL — 推送前必跑) # stdout:[ADDED] / [MODIFIED] / [DELETED] 列表 # exit 0: 无删除,可直接推送 # exit 2: 有删除,stderr 打印 DELETION_REQUIRES_CONFIRMATION 清单 + 指引,AI 必须转呈用户获得明示确认 lpm local-config diff ``` - `get` / `schema` 的 stdout 只回一行相对路径,JSON 落在 `.lpm-cache/` 里;AI 用 `lpm ai peek` 按需取片段,不要把整份 JSON 带进对话 context - `set` 接受 `--from <path>`(相对或绝对路径)+ `--allow-delete`(删除确认后才加),不推送远端——推送走 `update --source-type=local` - `diff` 无参数,对比 `point.config.local.json` 与远端当前配置 > **CRITICAL — 全量提交 + 删除确认**:`local-config set` 是全量覆盖语义,减少点位不可逆。删除在 `set` / `diff` / `update --source-type=local` 三处都会 exit 2 硬拦——必须把 stderr 逐字转呈用户,等用户明示同意删除具体点位,才用 `--allow-delete`(set / update 支持)绕过那一步重跑。完整规则见 [`../../meegle-plugin/references/shared.md`](../../meegle-plugin/references/shared.md) 的"全量提交约束""删除点位前置检查协议"两节。 ### AI 辅助命令(`lpm ai *`) 完整列表跑 `lpm ai --help`。各命令具体用法在用到的 workflow doc 内 inline 展示(如 `lpm ai peek` 见 [`../../meegle-plugin/references/feature-config-plan.md`](../../meegle-plugin/references/feature-config-plan.md))。 **🔒 粒度铁律**(draft 编辑通用约定):peek 整点位 → AI 改 → set / Write 整点位回去;不钻 `extension[...].sub_comp[...]` 深叶子路径。 ### 生成 Schema ```bash lpm schema ``` CLI 把 JSON Schema 写入 `.lpm-cache/schema/point-schema.json` 并在 stdout 回显路径。用 `lpm ai peek` 按需切片,**不要 Read 整个文件**(约 30K tokens)。 ### 清理工作区(兜底) ```bash lpm workspace clean --scope=all # 清全部(保留 state.json) lpm workspace clean --scope=mcp # 只清 MCP 缓存 lpm workspace clean --include-state # 连 workflow checkpoint 一起清 ``` `.lpm-cache/` 的生命周期由 CLI 自动维护——`local-config set` / `publish` 成功时会按子目录清理。仅在中断后需要强制重置时才手动调用 `workspace clean`### 分类列表 ```bash lpm list-categories [--type plugin] ``` | 参数 | 必填 | 说明 | |------|------|------| | `--type` | 否 | `plugin`(默认)/ `ai` | 输出 JSON 数组,每项含 `id``name`,用于 `update-description --category-ids`### 权限管理 `lpm perm` 管理**本插件对应 app 的 OpenAPI 权限 scope**(不操作 Meegle 产品业务数据)。在自建后端要调 OpenAPI 时用 —— 调用前先把要用的 scope 申请上。 ```bash # 查:已开通可调的 scope(granted)+ 还能申请的(applicable),各含覆盖的 OpenAPI lpm perm list # 校验:要调的这些 OpenAPI 能不能调 / 缺哪些权限(接口 key / 短名 / 中文名均可) lpm perm check --apis <api1,api2,...> # 申请:把这些权限 key 加到本插件(已开通的自动跳过);先 perm check 看缺哪些 scope lpm perm apply --scopes <key1,key2,...> ``` | 命令 | 参数 | 说明 | |------|------|------| | `perm list` | `[--raw]``[--plugin <id> --site-domain <url>]`(均可选,成对) | 默认 stdout 输出 CLI 派生视图:`{ appType, granted: [{scope,name,openapis:[{key,name,url}]}]`(已开通、当前可调,= `perm_info ∩ perm_meta``, applicable: [{scope,name,openapis}]`(还能申请的,= `perm_meta − perm_info``ai_node`/`ai_field` 省略,固定集不可申请)`}`。可行性看 `granted ∪ applicable` 天花板;实行看 `granted`、缺的从 `applicable` 申请。`--raw` 出后端原始 `{ perm_info, perm_meta }`(调试用) | | `perm check` | `--apis <a,b,c>`(必填,逗号分隔的 OpenAPI 标识:resource key / 短名 / 中文名);`[--plugin <id> --site-domain <url>]`(可选,成对) | CLI 把每个接口反查到归属 scope 再比对已开通,stdout 输出判决 JSON:`satisfied`(归属 scope 已在 granted)/ `needApply: [{scope,name,apis}]`(normal 缺、可申请)/ `infeasible: [{api,reason}]`(AI 应用缺固定集 scope,做不了)/ `unknown`(此 app 目录里查无此接口)/ `ambiguous: [{api,candidates}]`(中文名撞多个 scope,改用 resource key 消歧) | | `perm apply` | `--scopes <a,b,c>`(必填,逗号分隔的权限 key);`[--plugin <id> --site-domain <url>]`(可选,成对) | 先本地对照可申请目录(`perm_meta`)校验,非法 key 直接 `exit 1` 并提示用 `perm list`;合法则申请(`operate_type=1` 新增),stdout 输出 `{ perm_info: [...] }` 的 JSON(申请后该插件已勾选的权限列表) | - **插件定位优先级**:`--plugin/--site-domain` 显式指定 > 插件工程目录的 `plugin.config.json` > 全局只读注册表(`~/.lpm/`,记录你碰过的插件,无 secret;单登录态 + 单插件时自动定位,多个时报错列出让你加 `--plugin`)。所以这几条命令**也能在插件工程目录之外跑**(如自己的后端代码仓);都是 token-only、不需 pluginSecret。从工程目录外定位时会在 stderr 回显 `perm <action>: plugin <id> @ <domain>`。鉴权走 `login` 拿到的 dev token,没登录会 stderr 提示。 - `perm apply` 是对 app 权限的真实变更——编排 skill(`meegle-plugin-backend`)调它前会先列出即将申请的 scope 等用户点头,见 [`../../meegle-plugin/references/shared.md`](../../meegle-plugin/references/shared.md) 的"必须先确认"清单。 - 需审核的 scope(`perm list --raw``perm_meta[].auditable_bit` 按位标记)申请后还要在开发者后台填申请原因、走审批;`perm apply` 只负责把 scope 加到草稿。AI 应用(`app_type=ai_node`/`ai_field`)的权限按点位类型自动管,`perm apply` 对它会报错。 --- ## 命令依赖关系 典型顺序(前置依赖 → 后置操作): 1. `login` — 全局认证(一次性) 2. `create` — 创建插件工程(一次性) 3. `schema``local-config set --from <draft>``local-config diff``update --source-type=local` — 配置点位(三步:set 本地校验 + 暂存;diff 预览 + 删除确认 gate;update --source-type=local 推远端 + 拉回模板) 4. `start --auto` — 本地调试(依赖 step 3`update`5. `update-description` — 修改基本信息(可随时) 6. `release``publish` — 构建发布(两步串行,不可跳) 按需(不在固定生命周期里):`perm check --apis ...`(要调的接口能不能调 / 缺哪些 scope)→ `perm apply --scopes ...` —— 自建后端要调某些 OpenAPI 时,先核可行性再把缺的 scope 申请上(编排见 `meegle-plugin-backend`)。