@lark-project/cli
Version:
飞书项目插件开发工具
118 lines (74 loc) • 7.68 kB
Markdown
# Phase 2:功能实现(点位配置 + 代码生成 + 本地调试确认)
Phase 2 把"**功能可运行**"作为交付目标,内部委托给 `feature phase`(Stage Config 点位配置 + Stage Code 前端代码),完成后引导用户本地调试确认。
> **Phase 2 只委托 `feature phase`,不自己加"检测后端"分支**:这个 feature 要不要后端那一半(webhook 形态点位 / 前端走 `fetch('/api/proxy/*')` 代理)由 `feature phase` 内部判断,需要时它会在末尾走「→ 后端那一半」产交接包甩给后端会话——对 Phase 2 是透明的。Phase 2 不预判、不替它决定跑哪些 stage。
> **Checkpoint**:本阶段每个子步骤执行前后都用 `lpm --cwd "<projectRoot>" ai state set '<完整 JSON>'` 更新 checkpoint,读用 `lpm --cwd "<projectRoot>" ai state get`,详见 SKILL.md「进度追踪」章节。
## 2.0 cwd 守卫(HARD GATE)
兜底断点恢复 / `phase=2` 单独调起 / 用户切终端等绕过 create [`apply.md` A3](create-apply.md) cwd-gate 的场景:
```bash
pwd && test -f plugin.config.json && echo "CWD_OK" || echo "CWD_FAIL"
```
- `CWD_OK`:进入 2.1,记下 `pwd` 作为 `context.projectRoot`;2.1 之后每条 lpm 命令都带 `--cwd "<projectRoot>"`([workflow-overview.md「cwd 锚定规则」](workflow-overview.md)),lpm 报"非插件目录"就是漏了 `--cwd`,补上重跑
- `CWD_FAIL` + checkpoint 有 `context.projectRoot`(`lpm ai state get` 拿):直接用 `--cwd "<context.projectRoot>"` 跑后续命令,无需 cd
- `CWD_FAIL` + 无:终止并提示用户给出插件工程绝对路径或回 Phase 1 重建
## 2.1 进入 feature 子阶段(Stage Config + Stage Code)
**进入 feature 子阶段**(**不要** Skill(),本 skill 内 Read 推进):
1. 先 Read [`feature-overview.md`](feature-overview.md)——含 **app_type 锚定 + 信号词对账(Step 2,必跑)**,对账失败时按 overview 模板停下问用户
2. **Stage Config**(意图涉及点位声明变更时):按序 Read [`feature-config-plan.md`](feature-config-plan.md) → [`feature-config-apply.md`](feature-config-apply.md)(A0–A3 不可跳)
3. **Stage Code**(该 feature 有渲染点位时;纯 webhook 形态整段跳过):按序 Read [`feature-code-setup.md`](feature-code-setup.md) → [`feature-code-plan.md`](feature-code-plan.md) → [`feature-code-apply.md`](feature-code-apply.md) → [`feature-code-verify.md`](feature-code-verify.md)
4. **需要后端那一半**:feature 子阶段会在其 reference 里自决(触发判据 = `feature-config-plan.md` 和 `feature-code-verify.md` 的权威源,**编排层不复述、不替它判**)。任一触发命中 → 按 feature 的「→ 后端那一半(relay)」编排走(A 后端就绪:汇总契约+scope就绪 → 产交接包【交接点】→ 联调收口 → 发布,详见 [`feature-overview.md`](feature-overview.md));其中后端代码「怎么写」由接手的后端会话取 `meegle-plugin-backend` skill(本 skill 不 Read),跑完再回到 Phase 2 完成态
**编排层不预判、不拉 schema、不填默认值、不替用户做选型**——点位识别(意图理解 / 术语消歧 / mentionedPointType 提取)、schema 切片、用户交互确认、MCP 业务语义查询、代码溯源、tsc 预检全部在 feature 子阶段的 references 里完成。编排层这里插手哪一项,那一项的护栏就会被绕过。
**Checkpoint 写入**:`{ "phase": 2, "step": "2.1", "stepName": "feature 子阶段", "nextStep": "2.1 走 feature 子阶段的 Stage Config + Stage Code" }`
**恢复检查**:若从 checkpoint 恢复,用 `lpm --cwd "<projectRoot>" ai state get` 读 feature 子阶段维护的子状态(step 可能是 `2.config.plan` / `2.config.apply` / `2.code.plan` / `2.code.apply` / `2.code.verify` 等)——由 feature 子阶段决定从哪一步继续,编排层不替它解读 `local-config set` / `tsc` 的成功与否。
feature 子阶段的 config.plan 用 `lpm --cwd "<projectRoot>" ai state get` 取 `context.originalRequirement` 读用户原话做意图识别(Phase 1.2 首次落盘时写入的版本,逐字保留、不受会话压缩影响),编排层不预消化、不传 hint 参数。
## 2.2 本地确认(`lpm start --auto`)
**Checkpoint 写入**:`{ "step": "2.2", "stepName": "本地确认", "nextCommand": "lpm --cwd \"<projectRoot>\" start --auto", "nextStep": "2.2 本地确认" }`
feature phase 交付完成后,引导用户:
```
✅ 点位配置已推送远端 + 代码生成完成 + tsc 通过
运行:lpm --cwd "<projectRoot>" start --auto
```
`lpm start` 会按插件实际形态自处理:
- 有前端产物 → 起 dev server + 自动打开浏览器调试页,用户检查功能是否符合预期
- 没有前端产物(webhook 形态——纯 `intercept` / `listen_event` / `ai_field` / 未开卡片的 `ai_node`)→ `lpm start` 不报错,会打印一句"本插件无前端产物可本地预览、确认 webhook 回调地址可达后去 publish"并干净退出(exit 0)。按它的提示让用户确认 webhook 地址就绪即可
按 CLI 给出的提示等用户反馈。**这是整个流程中的关键交互点——把用户推到 Phase 3 发布的唯一闸门。**
## 2.3 用户反馈处理
### 场景 A:功能 OK
```
用户:"可以了" / "没问题" / "功能正常"
```
→ 进入 Phase 3 发布
### 场景 B:需要调整
```
用户:"图表颜色换成蓝色" / "按钮文案改成 xxx" / "加一个筛选功能"
```
判断调整范围:
- **仅代码层面改动**(样式 / 文案 / 逻辑调整)→ 回到 feature 子阶段的 Stage Code(按序 Read [`feature-code-setup.md`](feature-code-setup.md) → [`feature-code-plan.md`](feature-code-plan.md) → [`feature-code-apply.md`](feature-code-apply.md) → [`feature-code-verify.md`](feature-code-verify.md),跳过 Stage Config)
- **涉及点位配置变更**(加属性 / 改字段 / 新增点位类型)→ 回到 feature 子阶段完整流程([`feature-config-plan.md`](feature-config-plan.md) → [`feature-config-apply.md`](feature-config-apply.md) → 然后 Stage Code 跟进)
修改完成后提示用户刷新浏览器查看(webpack 热更新自动生效)。
**循环直到用户满意。**
### 场景 C:方向有误
```
用户:"不是这个意思,我想要的是 xxx"
```
更新 checkpoint 的 `context.originalRequirement` 为用户新描述;回到 feature 子阶段完整重跑(Stage Config 重新识别点位 → Stage Code 重新生成代码,参见 §2.1 的 Read 序列)。
### 场景 D:暂时搁置
```
用户:"先这样,我改天再继续"
```
**Checkpoint 写入**:`{ "step": "2.3", "stepName": "用户调试中(暂停)", "lastCommand": "start --auto", "lastCommandStatus": "success", "nextStep": "2.3 等待用户反馈" }`
告知当前进度已保存,下次回来可以从断点继续:
- 代码在 `src/features/` 目录中
- 配置已推送远端
- 进度已记录到 checkpoint(`lpm ai state get` 可读回)
- 下次再 trigger 本 skill 时,router 的 Step 1.1 用 `lpm ai state get` 看到 step=`2.3`,引导你"从断点继续";或显式说"phase=3 直接发布"跳到 Phase 3
## 2.4 阶段完成标志
用户明确确认功能可以了 → 输出:
```
✅ 功能确认完成,准备发布
接下来我会:
1. 自动生成插件的正式名称 / 描述 / 分类(polish phase)
2. 向你展示发布清单,你确认后才实际发布(publish phase 不可逆)
3. 发布完成后输出分享链接
开始吗?
```
等待用户回复"开始" / "好" / "确认" 后进入 Phase 3。