@lark-apaas/coding-miaoda-sandbox-skills 0.1.0-dev.6f4e4bc → 0.1.0-dev.72ac425

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/miaoda/ai-data-processing/SKILL.md +4 -1
  2. package/miaoda/charts-skill/SKILL.md +1 -1
  3. package/miaoda/creative-to-fullstack/SKILL.md +38 -226
  4. package/miaoda/feishu/SKILL.md +4 -4
  5. package/miaoda/forms-skill/SKILL.md +9 -0
  6. package/miaoda/lark-apps-db/SKILL.md +6 -4
  7. package/miaoda/lark-apps-db/references/full-reference.md +13 -4
  8. package/miaoda/lark-apps-ops/SKILL.md +2 -1
  9. package/miaoda/lark-apps-ops/references/lark-apps-export.md +46 -0
  10. package/miaoda/lark-design-prototype/DESIGN.md +603 -0
  11. package/miaoda/lark-design-prototype/SKILL.md +85 -0
  12. package/miaoda/lark-design-prototype/references/assets/card-illustration-library.md +113 -0
  13. package/miaoda/lark-design-prototype/references/case-matching.md +53 -0
  14. package/miaoda/lark-design-prototype/references/cases/conversational-ai-home.md +27 -0
  15. package/miaoda/lark-design-prototype/references/cases/data-table.md +30 -0
  16. package/miaoda/lark-design-prototype/references/cases/official-home.md +26 -0
  17. package/miaoda/lark-design-prototype/references/cases/workspace-home.md +34 -0
  18. package/miaoda/lark-design-prototype/references/color-roles.md +163 -0
  19. package/miaoda/lark-design-prototype/references/component-selection.md +134 -0
  20. package/miaoda/lark-design-prototype/references/design-quality-checklist.md +156 -0
  21. package/miaoda/lark-design-prototype/references/form-shell-patterns.md +77 -0
  22. package/miaoda/lark-design-prototype/references/icon-semantics.md +237 -0
  23. package/miaoda/lark-design-prototype/references/layout-interaction.md +164 -0
  24. package/miaoda/lark-design-prototype/references/page-contract.md +281 -0
  25. package/miaoda/lark-design-prototype/references/product-patterns.md +93 -0
  26. package/miaoda/lark-design-prototype/references/prompt-expansion.md +107 -0
  27. package/miaoda/lark-design-prototype/references/restoration-traps.md +113 -0
  28. package/miaoda/lark-design-prototype/references/token-semantics.md +112 -0
  29. package/miaoda/lark-design-prototype/references/visual-brief.md +125 -0
  30. package/miaoda/lark-design-prototype/references/visual-style-prompts.md +61 -0
  31. package/miaoda/lark-design-prototype/scripts/icon-query.mjs +272 -0
  32. package/miaoda/lark-design-prototype/scripts/token-query.mjs +76 -0
  33. package/miaoda/lark-design-prototype/scripts/verify-static-html.mjs +117 -0
  34. package/miaoda/performance-review/SKILL.md +3 -3
  35. package/miaoda/semantic-search/SKILL.md +6 -3
  36. package/miaoda/testing-guide/SKILL.md +116 -12
  37. package/miaoda-modern/charts-skill/SKILL.md +1 -1
  38. package/miaoda-modern/forms-skill/SKILL.md +33 -3
  39. package/miaoda-modern/lark-apps-ops/SKILL.md +2 -1
  40. package/miaoda-modern/lark-apps-ops/references/lark-apps-export.md +46 -0
  41. package/miaoda-modern/lark-design-prototype/DESIGN.md +603 -0
  42. package/miaoda-modern/lark-design-prototype/SKILL.md +85 -0
  43. package/miaoda-modern/lark-design-prototype/references/assets/card-illustration-library.md +113 -0
  44. package/miaoda-modern/lark-design-prototype/references/case-matching.md +53 -0
  45. package/miaoda-modern/lark-design-prototype/references/cases/conversational-ai-home.md +27 -0
  46. package/miaoda-modern/lark-design-prototype/references/cases/data-table.md +30 -0
  47. package/miaoda-modern/lark-design-prototype/references/cases/official-home.md +26 -0
  48. package/miaoda-modern/lark-design-prototype/references/cases/workspace-home.md +34 -0
  49. package/miaoda-modern/lark-design-prototype/references/color-roles.md +163 -0
  50. package/miaoda-modern/lark-design-prototype/references/component-selection.md +134 -0
  51. package/miaoda-modern/lark-design-prototype/references/design-quality-checklist.md +156 -0
  52. package/miaoda-modern/lark-design-prototype/references/form-shell-patterns.md +77 -0
  53. package/miaoda-modern/lark-design-prototype/references/icon-semantics.md +237 -0
  54. package/miaoda-modern/lark-design-prototype/references/layout-interaction.md +164 -0
  55. package/miaoda-modern/lark-design-prototype/references/page-contract.md +281 -0
  56. package/miaoda-modern/lark-design-prototype/references/product-patterns.md +93 -0
  57. package/miaoda-modern/lark-design-prototype/references/prompt-expansion.md +107 -0
  58. package/miaoda-modern/lark-design-prototype/references/restoration-traps.md +113 -0
  59. package/miaoda-modern/lark-design-prototype/references/token-semantics.md +112 -0
  60. package/miaoda-modern/lark-design-prototype/references/visual-brief.md +125 -0
  61. package/miaoda-modern/lark-design-prototype/references/visual-style-prompts.md +61 -0
  62. package/miaoda-modern/lark-design-prototype/scripts/icon-query.mjs +272 -0
  63. package/miaoda-modern/lark-design-prototype/scripts/token-query.mjs +76 -0
  64. package/miaoda-modern/lark-design-prototype/scripts/verify-static-html.mjs +117 -0
  65. package/miaoda-modern/performance-review/SKILL.md +3 -3
  66. package/miaoda-modern/reviewer-usage/SKILL.md +2 -0
  67. package/package.json +1 -1
  68. package/shared/attachment/SKILL.md +5 -1
  69. package/miaoda/creative-to-fullstack/references/artifact-signals.md +0 -46
  70. package/miaoda/creative-to-fullstack/references/ui-to-function.md +0 -134
  71. package/miaoda-modern/testing-guide/SKILL.md +0 -218
@@ -8,6 +8,69 @@ gate-tools:
8
8
  when:
9
9
  subagent_type: E2E
10
10
  ---
11
+ {% if visualCheckEnabled %}
12
+ # 检查与验证:工具选择指南
13
+
14
+ 静态页面检查和功能验收使用不同工具。向用户只说「页面检查」或「用浏览器操作验证」,不要解释内部工具或 agent 名称。
15
+
16
+ ## 决策规则
17
+
18
+ ```
19
+ 用户想确认应用是否正常
20
+ ├─ 明确要求验证后端接口 / API / 请求响应 → api_request
21
+ ├─ 只检查静态视觉结果(白屏、布局、样式、文案、图片)→ visual_check
22
+ └─ 交互 / 业务流程 / 数据 / 网络 → Task(subagent_type="E2E")
23
+ ```
24
+
25
+ - **静态视觉检查**:调用 `visual_check`,一条路由一次调用;互不依赖的路由可同时发起。它只检查指定路由的最终静态画面,不用来点击、填写、提交或验证接口。
26
+ - **功能验收**:交互 / 业务流程 / 数据 / 网络都派 `Task(subagent_type="E2E")`。E2E 一律按标准语义执行,调用时不要额外指定运行方式。
27
+ - **接口验收**:只在用户明确要检查接口、API、请求或响应时调用 `api_request`;完成浏览器验收后不追加接口调用。
28
+ - **E2E 不可用时(Legacy)**:Task 的 `subagent_type` 没有 E2E 选项时,交互、业务、数据和网络验收改用 `api_request`、读代码和读运行时日志;不要尝试派 E2E。静态视觉仍使用 `visual_check`。
29
+
30
+ ## 调用方式
31
+
32
+ ```js
33
+ visual_check({
34
+ relative_path: "<路由相对路径>",
35
+ })
36
+ ```
37
+
38
+ `relative_path` 只填一个路由。一条路由检查完成后再根据结果决定是否修复;多个互不依赖的路由可以分别同时调用。
39
+
40
+ ```js
41
+ Task({
42
+ subagent_type: "E2E",
43
+ {% if e2eSemanticPlan %}
44
+ agent_options: { test_plan_file_path: ".spark/e2e-test/standard/<语义名>.json" },
45
+ {% endif %}
46
+ description: "验收<功能名称>",
47
+ prompt: "执行<具体交互或业务闭环>,断言<可观察终态>。",
48
+ })
49
+ ```
50
+
51
+ {% if e2eSemanticPlan %}
52
+ ### 验收计划文件
53
+
54
+ 每次派发都必须带 `agent_options.test_plan_file_path`,不传不执行。先列出 `.spark/e2e-test/standard/` 目录并**读**可能覆盖本需求的那份;同需求有变化就编辑那份,换功能或页面则新建。计划只包含交互、业务、数据和网络的可观察终态;`prompt` 只说明本轮执行范围和 Case 编号。
55
+
56
+ 格式(一条用例一行,`id` 必须是**正整数**、优先级小写,每卷 ≤10 条):
57
+
58
+ ```json
59
+ {"cases":[{"id":1,"priority":"p0","description":"打开首页,预期工单列表渲染出至少 1 行"}]}
60
+ ```
61
+ {% if e2eStructuredCases %}
62
+
63
+ 复测用 `agent_options.retest_case_ids: [1, 2]`(编号取计划文件里的 `id`,必须是正整数,不是 `"case-1"` 这类字符串)或 `agent_options.retest_all: true` 指定本轮范围;写在 `prompt` 里的自然语言范围不生效,两个都不传只跑 p0。
64
+ {% endif %}
65
+ {% endif %}
66
+
67
+ ## 验收要求
68
+
69
+ - 视觉检查写清可观察结果,例如「首页标题完整可见、卡片两列排列、主图不是裂图」,不要只写「看起来正常」。
70
+ - 功能验收必须走到终态:提交后记录出现、跳转后内容正确、删除后记录消失或 AI 输出出现;不要停在弹窗、按钮或表单字段出现。
71
+ - 写操作和资源加载要核对网络结果;非 2xx、空结果、错误兜底或白屏都应报失败。
72
+ - 不测试登录、认证、CAPTCHA,或会造成真实外部副作用的行为。
73
+ {% else %}
11
74
 
12
75
  # 检查与验证:工具选择指南
13
76
 
@@ -29,32 +92,40 @@ gate-tools:
29
92
  ├─ Task 工具定义的 subagent_type 选项里没有 E2E(E2E 被关闭/不可用,非"本轮没派过")→ api_request(接口级验收)+ 读代码/读日志兜底,不要尝试派 E2E
30
93
  ├─ 明确要求验证「后端接口」「API 返回值」「请求响应」 → api_request
31
94
  └─ 其他所有情况 → Task(subagent_type="E2E")(打开浏览器,以用户视角操作应用)
32
- ├─ 只看视觉(白屏/布局/样式/文案)→ agent_options.mode: "lite"
33
- └─ 涉及交互/业务流程/数据 → 不传或 agent_options.mode: "standard"
95
+ ├─ 基础视觉验证(白屏/布局/样式/文案)→ agent_options.mode: "lite"(只截图看视觉)
96
+ └─ 用户明确要求验证交互/业务流程/数据(点击/填写/提交/走一遍流程)→ agent_options.mode: "standard"
34
97
  ```
35
98
 
36
99
  - **E2E 不可用时改走 api_request(最高优先,先于下面所有规则判断)**:当 Task 工具定义的 subagent_type 选项里没有 E2E(用户关闭了浏览器验收 / 环境不支持;判断依据是工具定义中是否含 E2E 选项,不是"本轮有没有派过 E2E")时,下面"模糊需求一律派遣 E2E"不再适用——改用 `api_request` 做接口级验收,配合读代码 / 读运行时日志确认核心链路,**不要尝试派 E2E、也不要空等**;此时验收范围收敛到接口与数据层可判定结果,视觉类目标顺延到非核心降级范围
37
100
  - **模糊需求一律派遣 E2E**(仅当 E2E 可用):未明确提到「接口」「API」「后端」时必须派遣 E2E,不要主动选择 `api_request`
101
+ - **基础视觉验证走 lite,standard 需用户明确要求功能测试**:用户没有主动要求跑具体功能(只说"看看有没有问题"这类模糊需求也算没主动要求)时,显式传 `agent_options.mode: "lite"`;只有用户明确要验证交互 / 业务流程 / 数据(点击、填写、提交、走一遍流程等)时才显式传 `agent_options.mode: "standard"`
38
102
  - **`api_request` 仅限显式请求**:仅当明确提到接口 / API / 后端 / 请求 / 响应、且意图是验证接口逻辑而非页面功能时才使用
39
103
  - **E2E 结束后禁止追加 `api_request`**:浏览器操作的结果即为最终结果,**严禁**再自动补充验证
40
104
 
105
+ ### 低投入产出验收的停止边界
106
+
107
+ - 仅按“能否在 2 分钟、2 次观察内稳定看到结果”决定是否验收;短时且终态可观察的任务照常验收。
108
+ - 完整体验依赖真实设备、语音/视频生成等长媒体处理、第三方实时通道或后台长异步终态且无法稳定观察时,标注未验收边界。
109
+ - 有可观察部分时只选一种现有验证方式;达到时间或次数上限即停,标为部分验收/未验收,不新增验收专用工具,不跨轮等待不可控终态。
110
+
41
111
  ### E2E 的 mode 选择
42
112
 
43
- 通过 `agent_options.mode` 指定,**可选参数**,不传或非 `lite` 一律按 `standard` 处理:
113
+ 通过 `agent_options.mode` 指定,**必填参数**,且只允许 `lite` 或 `standard`;缺失或非法时 E2E 会拒绝执行:
44
114
 
45
- | mode | 适用场景 | 行为 | 总超时 | 录屏 |
46
- |------|---------|------|-------|------|
47
- | `standard`(缺省) | 涉及业务流程、数据流、交互后状态变化 | 完整交互(点击/输入/滚动/提交)+ Network 验证 + 录制 | 5 分钟 | ✅ |
48
- | `lite` | 只看视觉渲染(CSS/布局/文案/图标)或快速冒烟 | 仅 `open` / `goto` / `wait` / `snapshot` / `screenshot`,**禁止** `click` / `fill` / `type` / `scroll` / `select` / `press` / `drag` / `hover` | 2 分钟 | ❌ |
115
+ | mode | 适用场景 | 行为 | 录屏 |
116
+ |------|---------|------|------|
117
+ | `lite` | 基础视觉验证(白屏/布局/样式/文案)或快速冒烟 | 仅 `open` / `goto` / `wait` / `snapshot` / `screenshot`,**禁止** `click` / `fill` / `type` / `scroll` / `select` / `press` / `drag` / `hover` | ❌ |
118
+ | `standard` | **仅当用户明确要求**验证业务流程、数据流、交互后状态变化 | 完整交互(点击/输入/滚动/提交)+ Network 验证 + 录制 | ✅ |
49
119
 
50
- **仅改 CSS / 文案 / 图标 / 布局**(无事件处理、无状态、无数据获取)应直接选 `lite`——更快且 token 消耗显著低,不要默认走 standard 浪费配额;但 `lite` 不能触发 popup / toast / 提交后状态切换等需要操作的现象。testRequirements 里出现"点击"、"填写"、"提交"等动词,**禁止** `lite`,必须 `standard`。
120
+ **每次派发都必须显式传 mode**。基础视觉验证传 `lite`;`lite` 不能触发 popup / toast / 提交后状态切换等需要操作的现象。**用户明确要求跑功能**(testRequirements 里出现"点击"、"填写"、"提交"等动词,或用户直接要求验证某功能)时,传 `standard`。
51
121
 
52
122
  ## 工具选择速查表
53
123
 
54
124
  | 用户表达 | 选择 | 原因 |
55
125
  | --- | --- | --- |
56
- | "检查一下页面" / "看看有没有问题" / "走一遍流程" / "哪里出问题了" / "试试能不能用" / "XX 不好使" | E2E(standard) | 打开浏览器以用户视角操作 / 复现 |
57
- | "刚改了 CSS,看看样式对不对" | E2E(lite) | 仅视觉巡检,省时省 token |
126
+ | "检查一下页面" / "看看有没有问题" / "哪里出问题了" / "试试能不能用" / "XX 不好使" | E2E(显式 `mode: "lite"`) | 未主动要求跑功能,执行基础视觉验证 |
127
+ | "刚改了 CSS,看看样式对不对" | E2E(lite) | 仅视觉巡检 |
128
+ | "点提交试试能不能成功" / "帮我把下单流程走一遍" / "走一遍流程" / "验证一下这个功能" | E2E(standard) | 用户明确要求功能 / 交互验证 |
58
129
  | "测试一下这个接口的返回值对不对" / "调一下后端 API 看看响应" | `api_request` | 明确指定接口验证 |
59
130
 
60
131
  ## 派遣 E2E 时的 prompt / 用例规范
@@ -63,6 +134,25 @@ gate-tools:
63
134
 
64
135
  > **核心原则:agent 只「机械执行 + 报判断」,不做推理。** 判定标准全写死在断言里——别让它自己推断"该测什么"或定义"什么算正常 / 好看"。它的活只有:执行动作 → 看现象 → 报通过 / 不通过。
65
136
 
137
+ {% if e2eSemanticPlan %}
138
+ ### 验收计划文件:先写文件,再派发(首次与后续同一套)
139
+
140
+ 每次派发都必须带 `agent_options.test_plan_file_path`,不传不执行。**两种 mode 各一份卷**,目录必须与派发 mode 一致(串卷不执行):standard 卷写 `.spark/e2e-test/standard/<语义名>.json`(含点击 / 输入 / 提交),lite 卷写 `.spark/e2e-test/lite/<语义名>.json`(只放看得见的检查点)。
141
+
142
+ 1. **先看已有的**:`glob .spark/e2e-test/<mode>/*.json` → **读**可能覆盖本需求的那份(没读过不要传)
143
+ 2. **改还是新建**:同需求用例有变化 → 编辑那份;换了功能 / 页面 → 新建一份
144
+ 3. **派发**:`prompt` 只说跑哪些(`跑 Case 1、2` / `复测 p0 和 p1` / `测试全部用例`),**不点名默认只跑 p0**;一轮点名 ≤5 条
145
+
146
+ 格式(一条用例一行,优先级小写,每卷 ≤10 条;一轮只跑其中 ≤5 条):
147
+
148
+ ```json
149
+ {"cases":[{"id":1,"priority":"p0","description":"打开首页,预期工单列表渲染出至少 1 行"}]}
150
+ ```
151
+
152
+ - **用例正文只写在计划文件里**:本模式下 `prompt` 不写 `## 测试用例`(下面示例里的用例正文改为写进卷),只留应用结构与本次范围——两处都写会让计划外用例一条不跑、报告却全绿
153
+ - **复测只点名、不删用例**:「只传 failed + 未完成的 Case」指在 `prompt` 里点名,不是从卷里删掉已通过的用例
154
+ {% endif %}
155
+
66
156
  ### 调用结构
67
157
 
68
158
  ```js
@@ -109,7 +199,8 @@ task({
109
199
  - **跑到终态**:提交后出现在列表 / 跳转后内容正确 / 删除后从列表消失
110
200
  - **AI 功能看到输出**:翻译 / 摘要 / 生成等核心卖点,须断言到 AI 产出的内容,不停在"AI 弹窗打开"
111
201
  - **主链路 + AI 都覆盖**,不因"非主链路"遗漏
112
- - **Case ≤ 10**:过多会 token 膨胀、超时
202
+ - **一次最多 5 条 Case**:多出来的分下一轮跑,不塞进同一轮
203
+ - **单条 Case ≤ 8 步**:动作步 + 断言步合计,超了就拆 Case 或删断言
113
204
  - **不碰登录 / 认证**:应用无登录逻辑,禁止登录 / 注册 / OAuth / CAPTCHA 相关 Case
114
205
 
115
206
  | ❌ 停在中间状态 | ✅ 跑到最终结果 |
@@ -155,6 +246,16 @@ E2E agent 只在离散时刻抓快照 / 截图,**看不到瞬时过程、不
155
246
 
156
247
  断言对象若是瞬时中间态 / toast 本身 / 动效本身 / 需伪造网络的分支——改写成稳定终态断言,或直接删掉。
157
248
 
249
+ ### 高成本控件(最耗步数,按下表写)
250
+
251
+ | 控件 | 写法 |
252
+ |------|------|
253
+ | 日期 / 时间选择器 | 用默认值,不指定具体日期 |
254
+ | 下拉 / 搜索选择框(antd / MUI / Radix) | 选第一项,不搜关键词筛选;多级联动只验第一级 |
255
+ | 长表单 | 只写必填项 |
256
+
257
+ 必须验这些控件本身时,单独占一条 Case,本轮总数相应减少。
258
+
158
259
  ### 建议覆盖维度
159
260
 
160
261
  覆盖维度(按实际功能裁剪):
@@ -188,7 +289,7 @@ E2E 派遣是**昂贵操作**(每次消耗大量 token + 时间)。E2E agent
188
289
 
189
290
  **白屏 / 整页打不开 → 复测前先重启 devServer**:白屏多为 **devServer 编译挂死 / HMR 卡住**,非代码 bug,直接再派只会重复白屏、白吃一轮配额。顺序:**① 重启 devServer → ② 查编译输出 / runtime-log 确认无报错(不派 E2E)→ ③ 再正常复测**;真要肉眼确认用 `lite` 截图,别用 standard 探活。
190
291
 
191
- **测试范围**:首轮(spec 验收)总 Case **≤ 5**(单次派发上限 ≤10 见 Case 复杂度约束),一行一个 Case,必须含主链路流程测试。禁止测试有真实副作用的功能(发送飞书消息、飞书建群)。
292
+ **测试范围**:每次派发 **≤ 5 条 Case**(首轮 spec 验收同此上限),一行一个 Case,必须含主链路流程测试。禁止测试有真实副作用的功能(发送飞书消息、飞书建群)。
192
293
 
193
294
  **停止派遣 E2E 的触发条件**(满足任一即停止):
194
295
 
@@ -215,6 +316,9 @@ E2E 派遣是**昂贵操作**(每次消耗大量 token + 时间)。E2E agent
215
316
  | E2E 完成后又调 `api_request` 补充验证 | 浏览器操作结果即为最终结果,不追加 |
216
317
  | 用户说"看看有没有 bug"就同时调两个 | 只派遣 E2E |
217
318
  | 用户说"检查接口"时派遣 E2E | 明确提到接口时用 `api_request` |
319
+ | 派发 E2E 时不传 `mode` | 每次都显式传 `lite` 或 `standard`;缺失或非法时不会执行 |
320
+ | 用户没主动要求跑功能,却传 `standard` | 显式传 `lite`;仅用户明确要求交互 / 功能验证才传 `standard` |
218
321
  | 仅改 CSS / 文案,仍走 `standard` | 优先用 `lite`,速度快、token 消耗低 |
219
322
  | 达到停止条件(≥3 轮 / 同一错误未改代码连续失败)仍继续派 E2E | 停止派遣,转为根因分析(读代码 / 查日志) |
220
323
  | 复测时全量重测 / 白屏直接再派一轮 | 只传 failed + 未完成的 Case;白屏先重启 devServer 再复测 |
324
+ {% endif -%}
@@ -5,7 +5,7 @@ description: "shadcn/ui + ReactECharts 图表开发规范。Use when creating or
5
5
 
6
6
  ## L0 基础配置
7
7
 
8
- - **库**: `import ReactECharts from 'echarts-for-react'` (v5.6.0)
8
+ - **库**: `import ReactECharts from 'echarts-for-react'` (echarts v6.1.x)
9
9
  - **主题**: `theme="ud"`
10
10
  - **颜色**: 🚨 只能用 hex(如 `#1890ff`),禁止 hsl/rgb
11
11
  - **高度**: ≥300px (`className='h-[300px]'`)
@@ -9,10 +9,13 @@ Shadcn Form + React Hook Form + Zod 表单开发。
9
9
 
10
10
  ## Guidelines
11
11
 
12
- - 类型必须用 `z.infer` 推导,禁止手动定义
13
- - 所有字段必须有默认值
12
+ - 表单类型由 zod schema 推导;所有字段必须有 `defaultValues`;运行时校验用 `zodResolver`
13
+ - 提交到必填 API/service Request 时,submit 的类型边界用业务 Request:Request 类型可读就 `const payload: XxxRequest = { ... }` 逐字段补齐;不可读但函数签名可读用 `Parameters<typeof submit>[0]` 派生
14
+ - 补 `useForm<TFieldValues, TContext, TTransformedValues>` 的泛型参数解决不了这个问题
15
+ - API 合同允许字段可选的查询、筛选、搜索表单,继续提交 `z.infer` 值
14
16
  - 必须用 Shadcn 组件,禁止原生 input
15
17
  - 同行 FormField 必须等宽
18
+ - 表单提交到必填 API/DTO/Request/interface 前,先读目标 shared/server 类型,在 `handleSubmit` 回调里用 `data` 逐字段构造 typed request(见 Patterns);不要整体传 `data`、`schema.parse(data)` 或 `.required().parse(data)`,也不要用 `any`/`as` 绕过 TS2322。修完后跑 LSP 或 `typecheck`。
16
19
 
17
20
  ---
18
21
 
@@ -36,15 +39,34 @@ const studentSchema = z.object({
36
39
 
37
40
  type StudentFormData = z.infer<typeof studentSchema>;
38
41
 
42
+ interface CreateStudentRequest {
43
+ name: string;
44
+ age: number;
45
+ grade: string;
46
+ }
47
+
48
+ async function createStudent(payload: CreateStudentRequest) {
49
+ logger.info(payload);
50
+ }
51
+
39
52
  export function StudentForm() {
40
53
  const form = useForm<StudentFormData>({
41
54
  resolver: zodResolver(studentSchema),
42
55
  defaultValues: { name: "", age: 0, grade: "" },
43
56
  });
44
57
 
58
+ const handleSubmit = async (values: StudentFormData) => {
59
+ const payload: CreateStudentRequest = {
60
+ name: values.name,
61
+ age: values.age,
62
+ grade: values.grade,
63
+ };
64
+ await createStudent(payload);
65
+ };
66
+
45
67
  return (
46
68
  <Form {...form}>
47
- <form onSubmit={form.handleSubmit((data) => logger.info(data))} className="space-y-6">
69
+ <form onSubmit={form.handleSubmit(handleSubmit)} className="space-y-6">
48
70
  <div className="flex flex-wrap gap-4">
49
71
  <FormField control={form.control} name="name" render={({ field }) => (
50
72
  <FormItem className="flex-1">
@@ -100,6 +122,14 @@ const form = useForm<FormData>({ resolver: zodResolver(schema), defaultValues: {
100
122
  // 必填标记
101
123
  <FormLabel>字段 <span className="text-destructive">*</span></FormLabel>
102
124
 
125
+ // 必填 Request/DTO 桥接:zodResolver 负责运行时校验,DTO 边界负责静态类型匹配。
126
+ // 用 handleSubmit 回调的 data,不要用 getValues(拿到的是 coerce 前的原始值)。
127
+ import type { SaveRequest } from "@/shared/api";
128
+ form.handleSubmit(async (data) => {
129
+ const request: SaveRequest = { field: data.field };
130
+ await api.save(request);
131
+ });
132
+
103
133
  // 调试
104
134
  logger.info("errors:", form.formState.errors);
105
135
  ```
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: lark-apps-ops
3
- description: "Use when 在妙搭沙箱里用 `lark-cli apps +<cmd>` 操作【当前这个已存在的】妙搭应用:本地开发与部署发布上线(+release-*)、环境变量管理(+env-*)、线上日志/Trace/监控指标/PV-UV 查询(+log-*/+trace-*/+metric-list/+analytics-list)、运行时可见范围(+access-scope-*)、应用协作者与协作权限设置(+member-*)、AI 与飞书平台能力插件安装/卸载(+plugin-*)、改应用名或描述(+update)、开放 API Key 管理(+openapi-key-*)、运行时缓存调试(+cache-get/+cache-delete/+cache-clear)、妙搭 user_id 与飞书 open_id/union_id/user_id 互转(+user-id-convert);本 skill 也是 apps 命令族的意图路由入口——应用数据库走 lark-apps-db、应用文件存储走 lark-apps-file、角色与权限走 lark-apps-authz。触发词:部署, 上线, 发布, 环境变量, 线上日志, 接口请求量, 错误量, 延迟, CPU, 内存, PV, UV, 访问量, 可见范围, 分享链接, 协作者, 开发权限, 谁能改这个应用, 外部协作, 插件, 改名, API Key, 缓存, cache, 清缓存, 缓存没更新, ID 转换, open_id 转 user_id, +release-, +env-, +access-scope-, +member-, +plugin-, +openapi-key-, +cache-, +user-id-convert. NOT for 新建应用/应用列表/初始化/HTML 发布/会话/自动化等未开放命令(见「能力边界」),以及非 apps 域的飞书操作(走 lark-cli skill)。"
3
+ description: "Use when 在妙搭沙箱里用 `lark-cli apps +<cmd>` 操作【当前这个已存在的】妙搭应用:本地开发与部署发布上线(+release-*)、导出应用源码为 zip(+export)、环境变量管理(+env-*)、线上日志/Trace/监控指标/PV-UV 查询(+log-*/+trace-*/+metric-list/+analytics-list)、运行时可见范围(+access-scope-*)、应用协作者与协作权限设置(+member-*)、AI 与飞书平台能力插件安装/卸载(+plugin-*)、改应用名或描述(+update)、开放 API Key 管理(+openapi-key-*)、运行时缓存调试(+cache-get/+cache-delete/+cache-clear)、妙搭 user_id 与飞书 open_id/union_id/user_id 互转(+user-id-convert);本 skill 也是 apps 命令族的意图路由入口——应用数据库走 lark-apps-db、应用文件存储走 lark-apps-file、角色与权限走 lark-apps-authz。触发词:部署, 上线, 发布, 导出源码, 源码快照, 下载源码, zip, 环境变量, 线上日志, 接口请求量, 错误量, 延迟, CPU, 内存, PV, UV, 访问量, 可见范围, 分享链接, 协作者, 开发权限, 谁能改这个应用, 外部协作, 插件, 改名, API Key, 缓存, cache, 清缓存, 缓存没更新, ID 转换, open_id 转 user_id, +release-, +export, +env-, +access-scope-, +member-, +plugin-, +openapi-key-, +cache-, +user-id-convert. NOT for 新建应用/应用列表/初始化/HTML 发布/会话/自动化等未开放命令(见「能力边界」),以及非 apps 域的飞书操作(走 lark-cli skill)。"
4
4
  metadata:
5
5
  requires:
6
6
  bins: ["lark-cli"]
@@ -37,6 +37,7 @@ control-by-feature-ab: true
37
37
  | 本地开发:改代码、调试数据库(仅全栈应用有数据库)、提交推送(源码已在工作区),再走发布链路上线。**执行前必读**,含部署流程和领域规则 | 原生 `git`(提交推送)+ 下方发布链路 | [local-dev](references/lark-apps-local-dev.md) |
38
38
  | **部署/上线应用**("部署""上线""推上去并部署""发布到云端");查发布状态/历史 | `+release-create`(部署上线动作)、`+release-get`(轮询发布结果,finished 给 online_url / failed 给 error_logs)、`+release-list` | [release-create](references/lark-apps-release-create.md)、[release-get](references/lark-apps-release-get.md)、[release-list](references/lark-apps-release-list.md) |
39
39
  | 管理应用环境变量(查看/设置/删除) | `+env-list`、`+env-set`、`+env-delete` | [env](references/lark-apps-env.md) |
40
+ | 导出应用源码为 zip(要一份源码快照:读代码/审计/归档/静态分析;或取**别人分享给你的**创意应用源码,你对其仓库无权限)。仅取快照、不继续开发 | `+export`(下载 zip,只读;`--app-id` 与 `--meta-token` 恰传其一) | [export](references/lark-apps-export.md) |
40
41
  | 查线上日志、Trace、请求数、错误率、延迟、CPU、memory、PV/UV/访问量 | `+log-list`、`+log-get`、`+trace-list`、`+trace-get`、`+metric-list`、`+analytics-list` | [observability](references/lark-apps-observability.md) |
41
42
  | 应用数据库:看表/改表、执行 SQL、导入导出、多环境发布、审计、时间点恢复、DB 用量 | `+db-*` 命令族 | **→ [lark-apps-db](../lark-apps-db/SKILL.md)** |
42
43
  | 应用文件存储:上传/下载/列出/删除文件、临时分享链接、存储用量 | `+file-*` 命令族 | **→ [lark-apps-file](../lark-apps-file/SKILL.md)** |
@@ -0,0 +1,46 @@
1
+ # apps +export
2
+
3
+ 把妙搭应用的源码打成 zip 下载到本地。运行时命令事实以 `lark-cli apps +export --help` 为准。只读操作。
4
+
5
+ ## 何时用
6
+
7
+ 只要一份源码快照的场景:读代码、审计、归档、做静态分析、把源码喂给别的工具。
8
+
9
+ **跨应用是它的核心价值**:创意应用的分享链接(`/page/<token>`)指向别人的应用,你对那个仓库没有权限,`git clone` 走不通;`+export` 只要求你对该应用有下载权限。
10
+
11
+ ## 不要用它的时候
12
+
13
+ 当前应用要继续开发时不用它——当前应用源码通常已在工作区,直接改。`+export` 只给一个 zip:无 git 历史、无远端、无凭证、不拉环境变量,改完发不回去,只适合「拿一份只读快照」。
14
+
15
+ ## 导出的是「最后一次提交」,不是沙箱当前状态
16
+
17
+ 服务端对远端仓库跑 `git archive`,从不读沙箱文件系统。沙箱里改了文件但没提交或发布,**那些改动不在归档里**。若导出结果看起来"少了刚写的代码",先确认改动是否已提交,而不是重试导出。
18
+
19
+ ## 命令骨架
20
+
21
+ - `--app-id` 与 `--meta-token` **恰传其一**:前者是应用 ID(`$app_id`),后者是分享链接 `/page/<token>` 里的 token。两者作为独立字段走 `POST /apps/export`(`app_id` / `meta_token`),服务端按传入字段区分。
22
+ - 两者都只收**裸标识符**。拿到的是整条链接(`.../app/<app_id>` 或 `.../page/<token>`)时只传最后一段——整条 URL 传进来会被本地拦下并提示,不会变成看起来像"应用不存在"的 404。
23
+ - `--output` 可选,相对当前目录;省略时用服务端给的文件名(通常 `<app_id>.zip`)。
24
+
25
+ ## 示例
26
+
27
+ ```bash
28
+ lark-cli apps +export --app-id "$app_id" --output ./src.zip
29
+ lark-cli apps +export --app-id "$app_id" # 存成 ./<app_id>.zip
30
+ lark-cli apps +export --meta-token <share-token> # 别人分享给你的应用
31
+ lark-cli apps +export --app-id "$app_id" --dry-run
32
+ ```
33
+
34
+ ## 输出契约
35
+
36
+ - 成功时 stdout 是 JSON envelope,含 `output`(落盘的绝对路径)与 `size_bytes`;传了 `--app-id` 时还会回显 `app_id`。
37
+ - 归档以流式写盘,不会整包驻留内存,大仓库也安全。
38
+ - 失败时不会留下半个文件。
39
+
40
+ ## 错误处理
41
+
42
+ | 情况 | 怎么办 |
43
+ |---|---|
44
+ | 应用尚未发布(`code 40901 app not published`) | 该应用是产物托管形态(如静态 HTML 应用),导出的是「最新已发布产物」,而它还没有成功发布过版本,此刻没有可导的东西。**先发布应用再重试**——不是 app_id 写错,重试也没用 |
45
+ | 权限不足(403) | 需要该应用的下载权限。**持有分享 token 不等于有权限** |
46
+ | 应用不存在(404) | 核对 `--app-id` / `--meta-token` 传的是不是对应的裸标识符(不是整条 URL) |