UNPKG

@lark-project/cli

Version:

飞书项目插件开发工具

375 lines (296 loc) 16.6 kB
# Meegle Plugin Skills 合并方案 > 把当前 7 个 `meegle-plugin-*` skill 合并为单一入口 `meegle-plugin`, > 保留 `meegle-plugin-cli`(独立活动)。 > 通过 `install-skills.js` postinstall 对称通道完成存量用户零感知迁移。 --- ## 1. 背景与决策 ### 1.1 现状 仓库 `skills/` 下当前有 **8 个 skill**: | skill | 角色 | 合并后去向 | | --- | --- | --- | | `meegle-plugin-create` | 创建空壳工程 | 合并 → `meegle-plugin` (phase=create) | | `meegle-plugin-feature` | 加 / 改 feature(前端 + 混合后端) | 合并 → `meegle-plugin` (phase=feature) | | `meegle-plugin-polish` | 完善插件元信息 | 合并 → `meegle-plugin` (phase=polish) | | `meegle-plugin-publish` | 构建 / 上传 / 发版 | 合并 → `meegle-plugin` (phase=publish) | | `meegle-plugin-workflow` | 从零做插件全流程 | 合并 → `meegle-plugin` (phase=workflow) | | `meegle-plugin-backend` | 后端 webhook / OpenAPI / lpm perm | 合并 → `meegle-plugin` (phase=backend) | | `meegle-plugin-shared` | 跨 skill 共享规则 | 合并 → `meegle-plugin/references/shared.md` | | `meegle-plugin-cli` | lpm CLI 命令查询 / 诊断 | **保留独立**(与开发流程是不同活动) | ### 1.2 已识别问题(来自 `2026-05-19` 复盘) - **路由失败无声**:5 段 description 重叠,模型挑错 skill 不会报错。复盘实证 `create` 截胡 `workflow`,导致 polish 缺席、publish 失败 5 次。 - **跨 skill 契约脆**:`orchestrated=true` 等隐性参数在 skill 间传递,无类型检查。 - **pipeline context 重复 reload**:全流程场景下 5 个 SKILL.md header 依次加载,且模型把"进入新 mode"误解为"重新 Skill()"导致 3 次重复 invoke 同一 skill。 - **task_create 反复重建**:`using-superpowers` default 行为 + 多次 invoke = 4 次 task_create(理想 1 次)。 - **publish pre-check 未卡 metadata**:绕开 workflow 直接 publish 时无护栏,被后端打回 5 次。 ### 1.3 决策 **3+→1 合并**:合并 7 个 `meegle-plugin-*`(`-cli` 除外)为单一 `meegle-plugin` skill。 理由(按权重): 1. 路由层从"5 段重叠 description LLM 概率挑"降级为"1 段 description 命中插件领域",路由错误率显著下降。 2. 阶段选择从隐式 skill 选择转为 skill 内确定性 SOP(`test -f` + 关键词表 + state 文件)。 3. 跨 skill 契约消失,变成 skill 内部状态机。 4. 前后端混合 feature 路径减少跨 skill 跳转。 5. 符合 Anthropic 官方"cohesive skill around an activity + progressive disclosure"模式。 6. `install-skills.js` postinstall 已是对称通道(add 默认执行),加 remove 即可零感知迁移。 **`meegle-plugin-backend` 一并合并**(不保留独立):外部后端仓场景靠 `context` 维度 + references 子文件区分,不需要 skill 边界。 --- ## 2. 目标终态 ### 2.1 仓库 `skills/` 结构 ``` skills/ ├── meegle-plugin/ ← 新主 skill │ ├── SKILL.md # < 500 行,含 phase router │ └── references/ │ ├── shared.md # 原 meegle-plugin-shared 内容 │ ├── checkpoint.md # state.json 协议 │ ├── errors.md │ ├── source-attribution.md │ │ │ ├── create-setup.md # 原 meegle-plugin-create/references/setup.md │ ├── create-plan.md │ ├── create-apply.md │ ├── create-verify.md │ │ │ ├── feature-code-setup.md # 原 meegle-plugin-feature/references/* │ ├── feature-code-plan.md │ ├── feature-code-apply.md │ ├── feature-code-verify.md │ ├── feature-config-plan.md │ ├── feature-config-apply.md │ ├── feature-point-types/ # 整目录搬迁 │ │ ├── button/index.md │ │ ├── componentSchedule/index.md │ │ ├── control/{form-control,index,table-cell}.md │ │ ├── customField/{index,value-shape}.md │ │ ├── dashboard/index.md │ │ ├── liteAppComponent/{index,read-props,write-outputs}.md │ │ ├── context-only.md │ │ └── shared-scenes.md │ │ │ ├── polish-analyze.md │ ├── polish-generate.md │ ├── polish-confirm.md │ ├── polish-apply.md │ │ │ ├── publish-pre-check.md # 含新增 PC0 metadata gate │ ├── publish-apply.md │ ├── publish-verify.md │ │ │ ├── workflow-phase-0-context.md │ ├── workflow-phase-1-scaffold.md │ ├── workflow-phase-2-feature.md │ ├── workflow-phase-3-release.md │ │ │ ├── backend-setup.md # 含目录解析 SOP │ ├── backend-contract.md │ ├── backend-impl.md │ ├── backend-perm.md │ └── backend-integ-test.md │ └── meegle-plugin-cli/ ← 保持不变 ├── SKILL.md └── references/{commands,diagnose}.md ``` ### 2.2 SKILL.md 顶层结构(草案) ```markdown --- name: meegle-plugin description: | Meegle / 飞书项目插件开发的统一入口。覆盖: - 插件工程内:创建空壳、加 / 改 feature(前端 / 后端 / 混合)、 完善插件元信息、构建发布、从零全流程编排 - 外部后端仓:处理 Meegle webhook、调 OpenAPI、申请 lpm perm scope 触发关键词: - 工程类:lpm、plugin.config.json、点位、builder_comp、视图配置、 工作项 UI 元素、字段类型、看板、详情区块 - 后端类:webhook、回调、验签、OpenAPI 数据、lpm perm、scope、 申请权限、自建后端、对接 Meegle - 流程类:从零做、新建插件、加功能、改功能、完善插件信息、 改名 / 描述 / 分类、发布插件、上线、release、publish 本 skill 自动检测 cwd 是否插件工程并路由到对应 phase; 断点续跑通过 .lpm-cache/state.json 恢复。 --- # Meegle Plugin > 本 skill 一次加载即完整。phase 切换通过 `Read references/<file>.md` 推进, > **不要再次 Skill(meegle-plugin)**。被异步中断(如 ask_user)后继续即可。 > > 本 skill 不主动 task_create。状态追踪走 `.lpm-cache/state.json` > (见 `references/checkpoint.md`)。已有 todo 时只 task_update。 ## 0. Always Read First - `references/shared.md` — 共享规则(认证、权限、安全) - `references/checkpoint.md` — state.json 协议 ## 1. Context Detection (确定性逻辑,不询问 LLM) ``` A. CWD 守卫 test -f ./plugin.config.json 存在 → context=plugin-project 不存在 → context=external-backend OR not-applicable (后续 phase 检测会再分流) B. 读 .lpm-cache/state.json 存在 .currentPhase → 优先使用(断点续跑) ``` ## 2. Phase Detection(关键词表,确定性匹配) 按以下优先级匹配用户原话,命中即停: | 关键词 / 句式 | phase | 适用 context | | --- | --- | --- | | "从零做""新建一个""我需要一个 xxx 插件""做个 xxx 插件" | workflow | plugin-project (cwd 不在工程内时先建) | | "创建空壳""初始化插件骨架" | create | not-applicable → 切到目标父目录 | | "发布""上线""release""publish""打包到市场" | publish | plugin-project | | "完善插件信息""改名""改描述""改分类" | polish | plugin-project | | "webhook""回调""验签""OpenAPI 调用""lpm perm""申请 scope" | backend | plugin-project OR external-backend | | "加功能""加点位""加按钮""加 Tab""加视图""实现 xxx 功能" | feature | plugin-project | 无命中 → 询问用户意图(4 选 1 + 自定义)。 ## 3. Phase Routing 按 phase 直接 `Read references/<phase>-*.md` 序列执行。 phase 间跳转走状态机(见 `references/checkpoint.md`),不重新 Skill()。 ### Phase 关键 SOP(细节在对应 references/) - **create**: setup → plan → apply → verify - **feature**: code-setup → code-plan → config-plan → config-apply → code-apply → code-verify - 内含"是否需要 backend 子分支"判断(关键词 + 用户确认) - **polish**: analyze → generate → confirm → apply - **publish**: pre-check (PC0/PC1/PC1.5/PC2) → apply → verify - **workflow**: phase-0-context → phase-1-scaffold → phase-2-feature → phase-3-release - **backend**: setup(含目录解析 SOP)→ contract → perm → impl → integ-test ## 4. Backend 目标目录解析(SOP 节选,详见 backend-setup.md) ``` 1. 读 .lpm-cache/state.json 的 backend.targetDir → 命中即用 2. context=external-backend → targetDir = cwd(确认即可) 3. context=plugin-project → 按优先级扫描候选目录: plugin.config.json: backend.dir 字段 ./server/ ./backend/ ./api/ ./packages/*-{be,server,api}/ ./apps/*-{server,api}/ 4. 1 候选 → 询问确认;多候选 → 让用户选;无候选 → 默认 ./server/ 询问 5. 写回 state.json,后续复用 ``` ``` --- ## 3. 迁移步骤(一次性切换,不灰度) ### Step 1:仓库内构建新 skill 目录(不影响线上) **3.1.1 拷贝并重命名 references** ```bash mkdir -p skills/meegle-plugin/references # shared cp skills/meegle-plugin-shared/references/{checkpoint,errors,source-attribution}.md \ skills/meegle-plugin/references/ # create for f in setup plan apply verify; do cp skills/meegle-plugin-create/references/$f.md \ skills/meegle-plugin/references/create-$f.md done # feature cp -r skills/meegle-plugin-feature/references/point-types \ skills/meegle-plugin/references/feature-point-types for f in code-setup code-plan code-apply code-verify config-plan config-apply; do cp skills/meegle-plugin-feature/references/$f.md \ skills/meegle-plugin/references/feature-$f.md done # polish / publish / workflow / backend 同理(前缀化) ``` **3.1.2 写新 SKILL.md** 按 §2.2 草案落地,重点: - description 是当前 7 段 description 触发词的**严格超集**(用脚本 grep 验证) - header < 500 行,符合 Anthropic 推荐 - 顶部加"一次加载不重复 invoke""不主动 task_create"两条约束(解决复盘 P0 问题 2、3) **3.1.3 references 内部链接重写** 原跨 skill 引用如 `meegle-plugin-create/references/setup.md` → `references/create-setup.md`,全仓 grep 替换。 ### Step 2:把复盘 P0 修复纳入新 SOP | P0 问题 | 修复位置 | | --- | --- | | publish 没卡 metadata | `references/publish-pre-check.md` 加 **PC0: metadata completeness**:检查 `name` 不是临时工作名、`shortDescription` / `detailDescription` / `categoryIds` 非空,缺失自动转 phase=polish | | skill 被重复 invoke | SKILL.md 顶部约束(合并后只有 1 个 skill,问题自然消失) | | task_create 反复重建 | SKILL.md 顶部"不主动 task_create"约束 | | 路由错误(create 截胡 workflow) | 合并消除,phase 检测靠关键词表确定性匹配 | ### Step 3:改造 `scripts/install-skills.js` 加 remove 通道 在 `main()` 内、`addArgs` 调用之前插入旧 skill 清理: ```js const LEGACY_SKILLS = [ 'meegle-plugin-create', 'meegle-plugin-feature', 'meegle-plugin-polish', 'meegle-plugin-publish', 'meegle-plugin-workflow', 'meegle-plugin-backend', 'meegle-plugin-shared', ]; function removeLegacy(cmdResolver) { for (const name of LEGACY_SKILLS) { runSkillsCommand( cmdResolver.cmd, [...cmdResolver.prefix, 'remove', name, '-g'], skillsDir, { ignoreFailure: true, silentNotFound: true, timeoutMs: 10_000 } ); } } ``` 要点: - 复用现有的 bundled / global / npx 兜底链 - 单条失败不阻断后续(`ignoreFailure: true`) - "skill not found" 不打 warning(对没装过旧版本的新用户是正常的) - 单条 timeout 缩短到 10s(本地操作) - 复用现有 `shouldSkip()` 跳过条件(`LPM_SKIP_SKILLS=1` / `CI=true` / `--ignore-scripts`) ### Step 4:行为等价性回归 **用复盘 session 当回归用例**: 1. 准备 fixture 工程(空目录 / 已有插件工程) 2. 跑当前 5-skill 架构下的 N 条典型 prompt,记录 stdout / 文件改动 / state.json 变化 3. 切到新 `meegle-plugin` 跑同样 prompt,diff 输出 4. 差异分类: - 等价(不同顺序但等效)→ 接受 - 优化(新流程更顺,如混合 feature 少跨 skill)→ 接受 - 退化(缺步骤 / 缺产物)→ 修 5. 必须覆盖的场景: - 从零做插件全流程(复盘场景) - 给已有插件加纯前端 feature - 给已有插件加前后端混合 feature - 直接发布(不走 workflow) - 完善元信息后发布 - 外部后端仓接 webhook - 断点续跑(state.json 恢复) ### Step 5:发版与 description 触发覆盖审计 发版前 checklist: - [ ] 新 description 包含原 7 段所有关键触发词(grep diff) - [ ] SKILL.md < 500 行 - [ ] references 路径无残留旧前缀 - [ ] `install-skills.js` 单测:模拟存量用户(已有 7 个旧 skill)→ 升级后 → `npx skills list | grep meegle-plugin` 只剩 `meegle-plugin` + `meegle-plugin-cli` - [ ] CHANGELOG / release notes 写明合并 + 自动清理 + 手动备选命令 - [ ] 文档(`docs/v2/architecture.md` `docs/v2/extending.md`)同步 --- ## 4. 风险与回滚 ### 4.1 风险矩阵 | 风险 | 严重度 | 缓解 | | --- | --- | --- | | 新 SOP 行为不等价(漏步骤) | 高 | Step 4 回归覆盖;保留 fixture 持续跑 | | description 漏触发词 | 中 | 发版前 grep diff + 灰度第一周观察新 skill 触发率 | | 用户在旧 skill references 里有本地修改 / 私货 | 中 | 文档明示"自定义请放 skill 目录之外";postinstall 不主动 grep(沿用 add 的隐式约定) | | `npx skills remove` 网络 / 权限失败 | 低 | 单条失败不阻断;打 manual hint;env var 跳过 | | 老会话已 load 旧 skill 进内存 | 低 | release notes 提示重启 AI 工具 | | 用户记忆的旧 slash 名(`/meegle-plugin-publish` 等)失效 | 中 | 新 description 包含旧关键词;自然语言触发覆盖;文档说明 | ### 4.2 回滚路径 **用户侧**:装回旧版本 `lpm`,旧 postinstall 自动 add 回 7 个 skill(天然回滚,单向锁不存在)。 **仓库侧**:revert 合并 PR,下个版本发出后用户升级即恢复。 回滚成本与"装新版本"对称——这是 postinstall 通道带来的最大红利。 --- ## 5. 不在本次范围 - `meegle-plugin-cli` 不动(属于独立活动:CLI 命令查询/诊断,不是开发流程) - `meego` skill 不动(飞书项目业务数据查询,与插件开发无关) - 不做灰度双轨期(postinstall 通道使其无必要) - 不写 forwarder skill(无外部死链需要兜的硬证据) - 不主动检测用户私货文件(沿用 add 的隐式约定即可) --- ## 6. 实施 checklist - [ ] **Step 1.1** 拷贝 references 到 `skills/meegle-plugin/references/` 并加前缀重命名 - [ ] **Step 1.2** 写 `skills/meegle-plugin/SKILL.md`(含 description 超集 + phase router + 顶部约束) - [ ] **Step 1.3** 重写所有 references 内部链接 - [ ] **Step 2** 把复盘 P0 的 4 条修复落进新 SOP(PC0 metadata gate 等) - [ ] **Step 3** 修改 `scripts/install-skills.js` 加 LEGACY_SKILLS 清理逻辑 - [ ] **Step 4** 准备并跑通 7 类回归 fixture - [ ] **Step 5** description 触发词 grep diff + SKILL.md 行数检查 + 文档同步 - [ ] **Step 6** 删除仓库内的旧 7 个 skill 目录(`skills/meegle-plugin-{create,feature,polish,publish,workflow,backend,shared}`) - [ ] **Step 7** 发版(含 release notes 说明) --- ## 7. 一句话 把 7 个 `meegle-plugin-*` 合并成 1 个 `meegle-plugin`,靠 `install-skills.js` 的 postinstall 对称通道(add 新 + remove 旧)做存量用户零感知迁移。 路由从"5 段重叠 description LLM 概率挑"降级为"1 段命中 + skill 内 SOP 确定性分流", 回到 Anthropic 官方推荐的 cohesive skill + progressive disclosure 模式。 回滚路径与升级路径对称,零额外运营复杂度。