@lark-apaas/coding-miaoda-sandbox-skills 0.1.0-dev.28c4f05 → 0.1.0-dev.4e64c13

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 (140) hide show
  1. package/miaoda/animation-skill/SKILL.md +348 -0
  2. package/miaoda/authz-cli/SKILL.md +1 -0
  3. package/miaoda/charts-skill/SKILL.md +264 -0
  4. package/miaoda/creative-to-fullstack/SKILL.md +157 -0
  5. package/miaoda/creative-to-fullstack/references/artifact-signals.md +46 -0
  6. package/miaoda/creative-to-fullstack/references/ui-to-function.md +134 -0
  7. package/miaoda/data-analysis/SKILL.md +151 -0
  8. package/miaoda/data-analysis/references/json-output-specification.md +277 -0
  9. package/miaoda/data-analysis/references/post-analysis-guide.md +77 -0
  10. package/miaoda/data-analysis/references/python-analysis-reference.md +272 -0
  11. package/miaoda/data-analysis/references/tmp-file-management-guide.md +100 -0
  12. package/miaoda/debug-investigation/SKILL.md +21 -18
  13. package/miaoda/extract-json-schema/SKILL.md +147 -0
  14. package/miaoda/lark-apps/SKILL.md +37 -0
  15. package/miaoda/lark-apps/references/openapi-key.md +80 -0
  16. package/miaoda/lark-apps-authz/SKILL.md +292 -0
  17. package/miaoda/lark-apps-authz/references/permission-points.md +39 -0
  18. package/miaoda/lark-apps-authz/references/role.md +122 -0
  19. package/miaoda/lark-apps-db/SKILL.md +226 -0
  20. package/miaoda/lark-apps-db/references/full-reference.md +302 -0
  21. package/miaoda/lark-apps-file/SKILL.md +216 -0
  22. package/miaoda/lark-apps-ops/SKILL.md +62 -0
  23. package/miaoda/lark-apps-ops/references/lark-apps-access-scope-get.md +30 -0
  24. package/miaoda/lark-apps-ops/references/lark-apps-access-scope-set.md +40 -0
  25. package/miaoda/lark-apps-ops/references/lark-apps-cache.md +62 -0
  26. package/miaoda/lark-apps-ops/references/lark-apps-env.md +46 -0
  27. package/miaoda/lark-apps-ops/references/lark-apps-local-dev.md +25 -0
  28. package/miaoda/lark-apps-ops/references/lark-apps-member.md +93 -0
  29. package/miaoda/lark-apps-ops/references/lark-apps-observability.md +46 -0
  30. package/miaoda/lark-apps-ops/references/lark-apps-plugin-install.md +36 -0
  31. package/miaoda/lark-apps-ops/references/lark-apps-plugin-list.md +23 -0
  32. package/miaoda/lark-apps-ops/references/lark-apps-plugin-uninstall.md +25 -0
  33. package/miaoda/lark-apps-ops/references/lark-apps-release-create.md +30 -0
  34. package/miaoda/lark-apps-ops/references/lark-apps-release-get.md +28 -0
  35. package/miaoda/lark-apps-ops/references/lark-apps-release-list.md +31 -0
  36. package/miaoda/lark-apps-ops/references/lark-apps-update.md +30 -0
  37. package/miaoda/lark-apps-ops/references/openapi-key.md +80 -0
  38. package/miaoda/miaoda-file/SKILL.md +1 -0
  39. package/miaoda/miaoda-sql/SKILL.md +6 -2
  40. package/miaoda/performance-review/SKILL.md +144 -0
  41. package/miaoda/performance-review/references/business-analyzer.md +139 -0
  42. package/miaoda/performance-review/references/examples.md +107 -0
  43. package/miaoda/reviewer-usage/SKILL.md +111 -0
  44. package/miaoda/testing-guide/SKILL.md +218 -0
  45. package/miaoda-design/lark-apps-comment/SKILL.md +110 -0
  46. package/miaoda-design/lark-apps-ops/SKILL.md +45 -0
  47. package/miaoda-design/lark-apps-ops/references/lark-apps-release-create.md +51 -0
  48. package/miaoda-design/lark-apps-ops/references/lark-apps-release-get.md +28 -0
  49. package/miaoda-design/lark-apps-ops/references/lark-apps-release-list.md +31 -0
  50. package/miaoda-design/lark-apps-ops/references/lark-apps-update.md +33 -0
  51. package/{shared → miaoda-modern}/lark-apps/SKILL.md +5 -5
  52. package/miaoda-modern/lark-apps/references/openapi-key.md +80 -0
  53. package/miaoda-modern/lark-apps-ops/SKILL.md +62 -0
  54. package/miaoda-modern/lark-apps-ops/references/lark-apps-access-scope-get.md +30 -0
  55. package/miaoda-modern/lark-apps-ops/references/lark-apps-access-scope-set.md +40 -0
  56. package/miaoda-modern/lark-apps-ops/references/lark-apps-cache.md +62 -0
  57. package/miaoda-modern/lark-apps-ops/references/lark-apps-env.md +46 -0
  58. package/miaoda-modern/lark-apps-ops/references/lark-apps-local-dev.md +25 -0
  59. package/miaoda-modern/lark-apps-ops/references/lark-apps-member.md +93 -0
  60. package/miaoda-modern/lark-apps-ops/references/lark-apps-observability.md +46 -0
  61. package/miaoda-modern/lark-apps-ops/references/lark-apps-plugin-install.md +36 -0
  62. package/miaoda-modern/lark-apps-ops/references/lark-apps-plugin-list.md +23 -0
  63. package/miaoda-modern/lark-apps-ops/references/lark-apps-plugin-uninstall.md +25 -0
  64. package/miaoda-modern/lark-apps-ops/references/lark-apps-release-create.md +30 -0
  65. package/miaoda-modern/lark-apps-ops/references/lark-apps-release-get.md +28 -0
  66. package/miaoda-modern/lark-apps-ops/references/lark-apps-release-list.md +31 -0
  67. package/miaoda-modern/lark-apps-ops/references/lark-apps-update.md +30 -0
  68. package/{shared/lark-apps → miaoda-modern/lark-apps-ops}/references/openapi-key.md +3 -3
  69. package/miaoda-modern/memory/SKILL.md +86 -0
  70. package/package.json +1 -1
  71. package/shared/lark-cli/SKILL.md +221 -0
  72. package/shared/lark-cli/lark-base/README.md +56 -0
  73. package/shared/lark-cli/lark-base/references/lark-base-commands.md +108 -0
  74. package/shared/lark-cli/lark-calendar/README.md +158 -0
  75. package/shared/lark-cli/lark-calendar/references/lark-calendar-meeting.md +30 -0
  76. package/shared/lark-cli/lark-calendar/references/lark-calendar-room-find.md +108 -0
  77. package/shared/lark-cli/lark-calendar/references/lark-calendar-suggestion.md +120 -0
  78. package/shared/lark-cli/lark-contact/README.md +35 -0
  79. package/shared/lark-cli/lark-contact/references/lark-contact-get-user.md +13 -0
  80. package/shared/lark-cli/lark-contact/references/lark-contact-search-user.md +121 -0
  81. package/shared/lark-cli/lark-doc/README.md +67 -0
  82. package/shared/lark-cli/lark-doc/references/lark-doc-fetch.md +138 -0
  83. package/shared/lark-cli/lark-doc/references/lark-doc-history.md +61 -0
  84. package/shared/lark-cli/lark-drive/README.md +129 -0
  85. package/shared/lark-cli/lark-drive/references/lark-drive-files-list.md +183 -0
  86. package/shared/lark-cli/lark-im/README.md +84 -0
  87. package/shared/lark-cli/lark-im/references/lark-im-chat-list.md +140 -0
  88. package/shared/lark-cli/lark-im/references/lark-im-chat-members-list.md +84 -0
  89. package/shared/lark-cli/lark-im/references/lark-im-chat-search.md +135 -0
  90. package/shared/lark-cli/lark-im/references/lark-im-reactions.md +232 -0
  91. package/shared/lark-cli/lark-minutes/README.md +51 -0
  92. package/shared/lark-cli/lark-minutes/references/lark-minutes-download.md +130 -0
  93. package/shared/lark-cli/lark-sheets/README.md +173 -0
  94. package/shared/lark-cli/lark-sheets/references/lark-sheets-changeset.md +105 -0
  95. package/shared/lark-cli/lark-sheets/references/lark-sheets-chart.md +45 -0
  96. package/shared/lark-cli/lark-sheets/references/lark-sheets-conditional-format.md +42 -0
  97. package/shared/lark-cli/lark-sheets/references/lark-sheets-filter-view.md +49 -0
  98. package/shared/lark-cli/lark-sheets/references/lark-sheets-filter.md +42 -0
  99. package/shared/lark-cli/lark-sheets/references/lark-sheets-float-image.md +43 -0
  100. package/shared/lark-cli/lark-sheets/references/lark-sheets-formula-verify.md +64 -0
  101. package/shared/lark-cli/lark-sheets/references/lark-sheets-history.md +70 -0
  102. package/shared/lark-cli/lark-sheets/references/lark-sheets-pivot-table.md +44 -0
  103. package/shared/lark-cli/lark-sheets/references/lark-sheets-read-data.md +216 -0
  104. package/shared/lark-cli/lark-sheets/references/lark-sheets-search-replace.md +67 -0
  105. package/shared/lark-cli/lark-sheets/references/lark-sheets-sheet-structure.md +52 -0
  106. package/shared/lark-cli/lark-sheets/references/lark-sheets-sparkline.md +47 -0
  107. package/shared/lark-cli/lark-sheets/references/lark-sheets-workbook.md +69 -0
  108. package/shared/lark-cli/lark-sheets/scripts/sheets_df.py +32 -0
  109. package/shared/lark-cli/lark-slides/README.md +86 -0
  110. package/shared/lark-cli/lark-slides/references/lark-slides-history.md +105 -0
  111. package/shared/lark-cli/lark-slides/references/lark-slides-xml-presentation-slide-get.md +108 -0
  112. package/shared/lark-cli/lark-slides/references/lark-slides-xml-presentations-get.md +77 -0
  113. package/shared/lark-cli/lark-task/README.md +93 -0
  114. package/shared/lark-cli/lark-task/references/lark-task-get-my-tasks.md +57 -0
  115. package/shared/lark-cli/lark-task/references/lark-task-get-related-tasks.md +49 -0
  116. package/shared/lark-cli/lark-task/references/lark-task-search.md +36 -0
  117. package/shared/lark-cli/lark-task/references/lark-task-tasklist-search.md +35 -0
  118. package/shared/lark-cli/lark-vc/README.md +40 -0
  119. package/shared/lark-cli/lark-vc/references/lark-vc-recording.md +31 -0
  120. package/shared/lark-cli/lark-whiteboard/README.md +35 -0
  121. package/shared/lark-cli/lark-whiteboard/references/lark-whiteboard-export.md +59 -0
  122. package/shared/lark-cli/lark-wiki/README.md +50 -0
  123. package/shared/lark-cli/lark-wiki/references/lark-wiki-node-get.md +59 -0
  124. package/shared/lark-cli/lark-wiki/references/lark-wiki-node-list.md +95 -0
  125. package/shared/lark-cli/lark-wiki/references/lark-wiki-space-list.md +68 -0
  126. package/miaoda-design/attachment/SKILL.md +0 -58
  127. /package/{shared → miaoda}/memory/SKILL.md +0 -0
  128. /package/{shared → miaoda-modern}/animation-skill/SKILL.md +0 -0
  129. /package/{shared → miaoda-modern}/charts-skill/SKILL.md +0 -0
  130. /package/{shared → miaoda-modern}/data-analysis/SKILL.md +0 -0
  131. /package/{shared → miaoda-modern}/data-analysis/references/json-output-specification.md +0 -0
  132. /package/{shared → miaoda-modern}/data-analysis/references/post-analysis-guide.md +0 -0
  133. /package/{shared → miaoda-modern}/data-analysis/references/python-analysis-reference.md +0 -0
  134. /package/{shared → miaoda-modern}/data-analysis/references/tmp-file-management-guide.md +0 -0
  135. /package/{shared → miaoda-modern}/extract-json-schema/SKILL.md +0 -0
  136. /package/{shared → miaoda-modern}/performance-review/SKILL.md +0 -0
  137. /package/{shared → miaoda-modern}/performance-review/references/business-analyzer.md +0 -0
  138. /package/{shared → miaoda-modern}/performance-review/references/examples.md +0 -0
  139. /package/{shared → miaoda-modern}/reviewer-usage/SKILL.md +0 -0
  140. /package/{shared → miaoda-modern}/testing-guide/SKILL.md +0 -0
@@ -0,0 +1,216 @@
1
+ # Lark Sheet Read Data
2
+
3
+ ## 列格式多样性预探(写公式 / 排序 / 筛选前必做)
4
+
5
+ > 本节给出"写公式 / 排序 / 筛选前先探清列格式多样性"的正确流程,是「读全再写」原则在 read_data 工具层的落地。
6
+
7
+ 对参与后续**计算 / 排序 / 筛选 / 公式提取**的列,**必须**先 sample **至少 50 行**(小表则全量),识别该列所有值类型变体后再设计公式 / 条件。只看前 10 行不够,因为下列差异通常潜伏在表尾或中段:
8
+
9
+ - **日期列同时出现多种格式**:`YYYYMM`、`YYYY-MM-DD`、`YYYY/M/D`、带时间戳、文本"未知"
10
+ - **数值列混入公式文本 / 单位 / 注释**:`1000+200=1200`、`100元`、`/(合同未明确)`、`#N/A`
11
+ - **空值与 0 / "0" 混杂**
12
+ - **大小写 / 全角半角差异**("办公费" vs "办公费 "、"Sales" vs "sales")
13
+
14
+ 预探后必须在公式 / 筛选条件里用 `IFERROR` / `IFS` / 提取数值的辅助列处理所有变体;不能为了通过 head(10) 的样本就直接落地。一旦设计的逻辑只覆盖 sample 中出现的格式,就属于违规。
15
+
16
+ ⚠️ **大数字(15 位以上的身份证 / 参考号 / 流水号)做去重 / 比较时禁止用 `+csv-get` 的显示值**:`+csv-get` 返回的是**格式化显示值**,15 位以上数字会被显示成 `1.04E+14` 这类科学计数法——多个本不相同的号在显示层全变成同一个 `1.04E+14`,拿去判重会**整列误判为重复**。比较 / 去重 / 匹配大数字时必须改用 `+cells-get`(取原始精确值)或把该列读为文本,禁止用 csv-get 的科学计数显示值(反例:大批长参考号被显示成科学计数后,互不相同的号全变成同一个值,被当成整列重复并错误高亮)。
17
+
18
+ ## 使用场景
19
+
20
+ 读取。从飞书表格中读取单元格数据。本 reference 覆盖 4 个 shortcut,按读取目的选择:
21
+
22
+ | 读取目的 | 用这个 shortcut | 数据去向 | 说明 |
23
+ |---------|----------------|---------|------|
24
+ | 快速查看纯值数据、批量处理 | `+csv-get` | 对话上下文 | 返回 CSV 文本(每行带 `[row=N]` 前缀);大表请按 `--range` 行窗口分批读(截断时看 `has_more`) |
25
+ | 按列类型结构化读出(喂 DataFrame) | `+table-get` | 对话上下文 | 返回 typed 协议(`columns:[列名]` + `data` + `dtypes`/`formats` + `range`),输出形状对齐 pandas split;可一行 `pd.DataFrame(sheet["data"], columns=sheet["columns"]).astype(sheet["dtypes"])` 还原 DataFrame。不带 `--range` 时读**完整 used range**(跨过表中部空行 / 空列),每个子表回传实际读取范围 `range` 供完整性校验;被 `max_chars` 裁掉时该子表还会带 `truncated: true` 与 `truncation_warning`,**先看这两个字段再用数据**。注意这与下文 `current_region` "遇表中部空行截断"不矛盾:`+table-get` 读的是子表物理 used range(飞书记录的已用矩形,含中间空行),`current_region` 是从锚点连通扩展、遇整行空行就断 |
26
+ | 查看公式、样式、批注、数据验证 | `+cells-get` | 对话上下文 | 返回单元格完整信息,token 开销较大 |
27
+ | 查看某区域的下拉框(数据验证)选项 | `+dropdown-get` | 对话上下文 | 返回该 A1 范围已配置的下拉列表选项 |
28
+
29
+ **选择原则**:
30
+ - 只看值或做数据处理 → `+csv-get`;大表分批读取,避免一次拉全表撑爆上下文
31
+ - 要按列类型结构化读出(喂 DataFrame)→ `+table-get`
32
+ - 需要公式/样式/批注 → `+cells-get`
33
+ - 只想知道某区域下拉框有哪些选项 → `+dropdown-get`
34
+
35
+ ⚠️ **大数据优先落盘、别灌进上下文**:`+csv-get` / `+cells-get` 都受调用方 Bash / 终端的单命令 stdout 输出上限约束(常见默认约 30000 字符,超过会被截断或转存为文件)。纯值分析优先 `+csv-get --format csv` 按 `--range` 行窗口(`A1:Z500` / `A501:Z1000` …)分批重定向到文件 + 本地脚本处理;若确实要让结果直接进上下文又不想触发转存,给任一命令把 `--max-chars`(默认 500000)调小到略低于该上限(如 `25000`),CLI 改为优雅截断 + `has_more` 分页。
36
+
37
+ > **落盘不等于读全**:`--output-path` 只是把上限从 stdout 口径放宽到有界的 2000 万字符(读取链路非流式,该上限是内存保护),不是无限。stdout 回执带 `complete` 字段——`complete:false` 时另有 `truncated` 与提示,文件里只有半截数据;多子表读取还会给 `unread_sheets` 列出预算耗尽前没读到的子表。**拿到回执先看 `complete`,不要默认整表已落全。**
38
+
39
+ **`+csv-get` 返回值核心设计**:
40
+ - `annotated_csv` — **CSV 数据唯一入口**。每一逻辑行前加 `[row=N] ` 前缀(N = 真实表格行号)。任何需要行号的下游操作(合并、写入、清空、格式化、插入/删除、条件格式、筛选、图表/透视表范围、搜索替换等),**行号一律直接从 `[row=N]` 读取**。若需要纯 CSV(如喂给本地脚本做解析),去前缀即可:`line.replace(/^\[row=\d+\] /, '')`。
41
+ - `col_indices` — **定位列字母唯一入口**。在表头中找到目标字段是第 j 个(0-based),用 `col_indices[j]` 取列字母。**禁止手数逗号**——列数超过 10 时极易 off-by-one(例如把 W 误判为 X)。
42
+ - `row_indices` — 程序化引用的备用数组。LLM 推理请用 `annotated_csv` 的前缀,不要查这个数组里的 index(把行号当数值用容易心算出错)。
43
+ - `current_region` — 从请求范围扩展到被空行空列包围的连续数据区域(等价于 Excel Ctrl+Shift+*),适合先读少量行探表头。⚠️ 它**遇表中部整行空行 / 整列空列就截断**,可能小于真实数据范围(漏掉空行之后的行);**不能**直接当整表末行用,判断整表是否读全要拿 `+workbook-info` 的物理 `row_count` / `column_count` 当上界交叉核对(见下方「按 row_count 盲读空行」与「确定数据范围的正确流程」)。
44
+
45
+ 注意:
46
+
47
+ - `+csv-get` 和 `+cells-get` 支持分页/截断,注意检查 `has_more` / `truncated` 标志;两者在处理返回数据之前都必须先读 `warning_message`(上游 schema 要求先读它再用其它字段,内含定位与截断续读提示),`+cells-get` 还要用每个 range 的 `actual_range` / `row_indices` / `col_indices` 判断真实位置
48
+ - 隐藏行列默认包含在返回结果中(`--skip-hidden=false`),如需只看可见数据设为 `true`。读取原语本身不标注哪些行列被隐藏:若要识别隐藏区间(以决定是否过滤、或如何解读混入的隐藏数据),用 `+sheet-info --include hidden_rows,hidden_cols` 取隐藏行列集合,再结合 `+csv-get` / `+cells-get` 返回的 `row_indices` / `col_indices` 判断每行 / 每列是否隐藏
49
+
50
+ **常见配置错误(必须注意)**:
51
+ - **全量读取导致上下文溢出**:不要对大表(数百行以上)直接用 `+csv-get` 或 `+cells-get` 读取全部数据到上下文。大表场景必须分批读取:用 `--range` 切行窗口逐块读(`+csv-get` / `+cells-get` 单次返回量由 `--max-chars` 自动兜底,截断时返回 `has_more`);过大时考虑导出到本地文件后用脚本处理再分批回写
52
+ - **了解结构 ≠ 读取全量数据**:探表不用读全表,但必须同时探两个方向的表头:
53
+ - **横向(列头)**:先读前几行,且**列范围必须覆盖所有列**——用 `+workbook-info` 拿总列数,`range` 末列填到最后一列(例如总列数是 N,则 `range: "A1:[列N]10"`)。列范围截短会遗漏右侧字段、后续写入列定位错误。
54
+ - **纵向(行标)**:若左侧 1-2 列是行标签(日期/类别/编号枚举每行含义,典型交叉表/透视布局),**必须再读 `A:A` 或 `A:B` 把行标列读到底**,拿全部行标。只读前几行会看不全表尾的行,导致批量写入漏改——这是"只改前 N 行、其余未更新"的主要成因。扁平列表(每行独立记录、列是字段)可跳过这一步,但仍要按下方「确定数据范围的正确流程」用 `+workbook-info` 的物理 `row_count` 交叉核对末行(`current_region` 遇空行会截断,不能单独兜底)。
55
+ - 数据量大或会进入上下文上限时,分批读 + 本地处理 + 分批回写,不要一口气拉全表到上下文。
56
+ - **`+cells-get` 滥用**:当只需要数据值时,使用 `+csv-get`(token 开销约为 `+cells-get` 的 1/5)。只有确实需要公式、样式或批注时才用 `+cells-get`
57
+ - **忽略分页标志**:读取返回 `has_more=true` 时,说明还有更多数据。如果任务需要完整数据,必须继续分页读取,不能只处理第一页就开始写入
58
+ - **直接按 `+cells-get` 返回二维数组下标推导真实位置**:`ranges[n].cells[i][j]` 里的 `i/j` 只是返回数组下标,不等于真实表格行列。定位真实行号必须用 `ranges[n].row_indices[i]`,定位真实列字母必须用 `ranges[n].col_indices[j]`;若 `--skip-hidden=true`、请求范围越界被裁剪,或最后一行是部分返回,错误地自己数下标会立刻错位
59
+ - **CSV 行号计数错误**:`+csv-get` 返回的 CSV 遵循 RFC 4180 标准,被双引号 `"..."` 包裹的字段中的换行符属于**字段内容的一部分**(即单元格内换行),不代表新的一行。计算行号时必须按**逻辑记录**计数,而非按物理换行符 `\n` 计数
60
+ - **手动数列确定列号**:禁止通过在 CSV 表头中手动数逗号/字段来确定目标列的列字母。当列数超过 10 时,手动计数极易产生 off-by-one 偏移(例如把 W 列误判为 X 列)。**必须使用 `col_indices`**:先在 CSV 表头中找到目标字段名是第 j 个字段(0-based),再用 `col_indices[j]` 获取该列的实际列字母
61
+ - **用数据列的值推导行号(常被巧合掩盖)**:CSV 中常见"序号 / ID / 编号 / No."等形似行号的列,其值与实际表格行号**没有任何绑定关系**——序号可能跳号(1,2,3,5,6...)、可能从非 1 开始、可能有重复或被中途重置。此规则适用于**所有需要行号的下游操作**:合并单元格、区间写入/清空/格式化、插入/删除行、条件格式范围、筛选器范围、图表数据源、透视表范围、搜索替换范围等等——**凡是要把行号填进任何工具参数的场景,行号一律从 `annotated_csv` 中目标行开头的 `[row=N]` 前缀直接读取**,禁止用"序号=行号"、"表头占 1 行所以数据从第 2 行开始"、"第 N 个序号就在第 N+1 行"等心算,也禁止先心算再"事后核对"。**危险特征**:前几十行中序号恰好等于表格行号(典型成因:表头 +1 与一次跳号 -1 的偏移互相抵消形成巧合),模型一旦把这个巧合当作规律,会在后续所有行沿用;而中间再出现跳号时,从该行起整块区域全部错位,且错位不自查很难发现。**正确工作流**:①在 `annotated_csv` 里定位目标逻辑行(按字段内容匹配);②直接读取该行开头的 `[row=N]` 前缀得到真实表格行号;③把这个行号填进下游工具参数。区间操作时,起始行用 start 行的 `[row=N]`、结束行用 end 行的 `[row=N]`。**自检**:动手前,在 `annotated_csv` 靠后位置再抽 1~2 行,核对 `[row=N]` 是否与首列"序号"一致——不一致(典型:`[row=57] 58,...`)即说明有跳号/隐藏行,更要严格从 `[row=N]` 取值,不要被序号列迷惑
62
+ - **`row_count` 与 `current_region` 都不能单独定末行**:`+workbook-info` 的 `row_count` 是 sheet 的**网格物理行数**(常是 200 / 1000 等默认值),通常**大于**真实数据末行——直接按它把 `--range` 拉到 `S200` 会读回大片空行,浪费上下文。反过来,`+csv-get` 返回的 `current_region` 是从锚点扩展、被空行空列围住的连续块,**遇表中部整行空行就截断**,可能**小于**真实数据范围(漏掉空行之后的行,典型反例:1–80 行有数据、81 行空、82 行起还有数据,`current_region` 只到 80,82 行起整段被漏读)。正确做法:把 `row_count` 当**上界**、`current_region` 当**起点参考**,在二者之间按下方「确定数据范围的正确流程」确认真实末行(含跨过中间空行的核对),不要只信其一。
63
+ - **current_region 当作纯数据范围**:`current_region` 返回的是从请求范围向四周扩展到被空行空列包围的**连续非空区域**,等价于 Excel 的 Ctrl+Shift+\*。它包含该区域内**所有非空行**——不仅包含数据行,还可能包含标题行、汇总行(如"总计")、签名行(如"编制人/审批人")、脚注等非数据内容。**严禁直接将 `current_region` 的末尾行作为数据范围的结束行**。正确做法见下方「确定数据范围的正确流程」
64
+
65
+ ### 确定数据范围的正确流程(排序、筛选、批量写入等操作前必做)
66
+
67
+ 当后续操作需要精确的数据范围(如排序、筛选、删除、批量写入)时,仅靠 `current_region` 探测到的范围是不够的——它**两头都可能不准**:表中部有整行空行时会被截断(末行偏小、漏数据),表尾有汇总 / 签名行时又会偏大。必须同时确认数据的**起始行**和**结束行**。具体步骤:
68
+
69
+ 1. **确认起始行**:读取前 5~10 行,识别表头行位置,数据起始行 = 表头行 + 1
70
+ 2. **确认结束行**(关键步骤,不可跳过):
71
+ - **先防截断(漏数据)**:拿 `+workbook-info` 的物理 `row_count` 当上界,与 `current_region` 末行对比。若 `current_region` 末行 **远小于** `row_count`(差出很多空间),不要直接采信——在 `current_region` 末行之后再探一段(如往下读到 `row_count`,或分段扫到首个连续空白区),确认空行之后确实没有数据;典型反例:`row_count=327`、`current_region` 只到第 80 行,第 81 行空、82 行起还有数据,只读到 80 就漏了一大段。
72
+ - **再排尾部非数据行**:读取确认到的末行附近若干行(建议末尾 5~10 行),逐行排除:
73
+ - **汇总行**:内容为"合计"、"总计"、"小计"、"总计:"等
74
+ - **签名/审批行**:内容为"编制人"、"审核人"、"部门负责人"等
75
+ - **空行或分隔行**:整行为空或仅有边框
76
+ - **备注/脚注行**:注释性文字、说明文字等
77
+ 3. **最终数据范围** = 起始行 ~ 最后一条有效数据行(跨过中间空行、排除尾部非数据行)
78
+
79
+ **示例**:`current_region` 返回 `A1:N51`,读取 Row 48~51 发现:
80
+
81
+ - Row 49: 序号=47, 姓名=xxx, 有正常数据 → ✅ 数据行
82
+ - Row 50: "总计", 有合并单元格 → ❌ 汇总行
83
+ - Row 51: "总经理:...", "编制人:..." → ❌ 签名行
84
+ - **正确数据范围 = A3:N49**(而非 A3:N51)
85
+
86
+ ## Shortcuts
87
+
88
+ | Shortcut | Risk | 分组 |
89
+ | --- | --- | --- |
90
+ | `+cells-get` | read | 单元格 |
91
+ | `+dropdown-get` | read | 对象 |
92
+ | `+csv-get` | read | 单元格 |
93
+ | `+table-get` | read | 单元格 |
94
+
95
+ ## Flags
96
+
97
+ ### `+cells-get`
98
+
99
+ _公共四件套 · 系统:`--dry-run`_
100
+
101
+ | Flag | Type | 必填 | 说明 |
102
+ | --- | --- | --- | --- |
103
+ | `--range` | string | required | A1 范围,如 `A1:F10`(不带 sheet 前缀;用 `--sheet-id` / `--sheet-name` 指定 sheet) |
104
+ | `--include` | string_slice | optional | 要返回的信息类别,逗号分隔多个(可选值:`value` / `formula` / `style` / `comment` / `data_validation`) |
105
+ | `--max-chars` | int | optional | 单次返回字符上限,默认 500000(兜底防爆)。要整表无截断直接用 `--output-path` 落盘(上限自动放宽到 2000 万字符);仅当要让结果直接进上下文、又不落盘时才调小(如 25000),按 has_more 分页。传 `0` 表示「不自设上限」,等价于不传(仍是 500000 / 落盘时 2000 万),不会退回底层工具那个更小的默认截断 |
106
+ | `--output-path` | string | optional | 把完整读取结果写入本地路径(如 `./out.json`),文件内容为 data 载荷的 JSON;stdout 只回一个含 output_path / 字节数的确认信息。**一旦设置,字符上限自动放宽到有界的 2000 万字符**(覆盖 `--max-chars` 默认),并非无限——读取链路非流式,该上限是内存保护;显式 `--max-chars` 优先。stdout 回执带 `complete` 字段(命中上限时另有 `truncated` 与提示),据此判断文件是否完整,不要默认整表已落全。省略时按常规把结果打到 stdout |
107
+ | `--skip-hidden` | bool | optional | 跳过隐藏行列,默认 `false` |
108
+
109
+ ### `+dropdown-get`
110
+
111
+ _公共四件套 · 系统:`--dry-run`_
112
+
113
+ | Flag | Type | 必填 | 说明 |
114
+ | --- | --- | --- | --- |
115
+ | `--range` | string | required | A1 范围,如 `A2:A100`(不带 sheet 前缀;用 `--sheet-id` / `--sheet-name` 指定 sheet) |
116
+
117
+ ### `+csv-get`
118
+
119
+ _公共四件套 · 系统:`--dry-run`_
120
+
121
+ | Flag | Type | 必填 | 说明 |
122
+ | --- | --- | --- | --- |
123
+ | `--range` | string | required | A1 范围,如 `A1:F30`(不带 sheet 前缀;用 `--sheet-id` / `--sheet-name` 指定 sheet) |
124
+ | `--max-chars` | int | optional | 单次返回字符上限,默认 500000(兜底防爆)。要整表无截断直接用 `--output-path` 落盘(上限自动放宽到 2000 万字符);仅当要让结果直接进上下文、又不落盘时才调小(如 25000),按 has_more 分页。传 `0` 表示「不自设上限」,等价于不传 |
125
+ | `--output-path` | string | optional | 把完整读取结果写入本地路径,文件内容为 data 载荷的 JSON;stdout 只回一个含 output_path / 字节数的确认信息。**一旦设置,字符上限自动放宽到有界的 2000 万字符**;stdout 回执带 `complete` 字段(命中上限时另有 `truncated`),据此判断文件是否完整。⚠️ 落盘的是 data 载荷的 **JSON**(CSV 文本是 JSON 里的一个字段),不是直接可用的 `.csv` 文件;要纯 CSV 文件请把 stdout 重定向到文件 |
126
+ | `--include-row-prefix` | bool | optional | 是否在每行前加 `[row=N]` 前缀,默认 `true` |
127
+ | `--skip-hidden` | bool | optional | 跳过隐藏行列,默认 `false` |
128
+
129
+ ### `+table-get`
130
+
131
+ _公共:URL/token(无 sheet 定位) · 系统:`--dry-run`_
132
+
133
+ | Flag | Type | 必填 | 说明 |
134
+ | --- | --- | --- | --- |
135
+ | `--sheet-id` | string | optional | 只读该子表(按 id);省略则读所有子表 |
136
+ | `--sheet-name` | string | optional | 只读该子表(按名);省略则读所有子表 |
137
+ | `--range` | string | optional | 读取的 A1 范围;省略则读每个子表的完整 used range(会跨过表中部的整行空行 / 整列空列,不会被截断) |
138
+ | `--max-chars` | int | optional | 单次返回字符上限,默认 500000(兜底防爆)。底层工具即使不传也有约 50000 的默认截断,故此处显式发送以放宽;要整表读取请用 `--output-path` 落盘(上限自动放宽到有界的 2000 万字符,非无限;回执 `complete` 字段说明是否完整)。传 `0` 表示「不自设上限」,等价于不传 |
139
+ | `--output-path` | string | optional | 把完整读取结果写入本地路径,文件内容为 data 载荷的 JSON;stdout 只回一个含 output_path / 字节数的确认信息。**一旦设置,字符上限自动放宽到有界的 2000 万字符**(覆盖 `--max-chars` 默认);stdout 回执带 `complete` 字段(命中上限时另有 `truncated` 与提示),据此判断文件是否完整,不要默认整表已落全 |
140
+ | `--no-header` | bool | optional | 把第一行当数据而非表头(列名取 col1/col2 …) |
141
+
142
+ ## Examples
143
+
144
+ ### `+csv-get`
145
+
146
+ 公共四件套:`--url` / `--spreadsheet-token` / `--sheet-id` / `--sheet-name`(前两者 XOR,后两者 XOR)。
147
+
148
+ 示例:
149
+
150
+ ```bash
151
+ # 简单读(sheet 定位必填:--sheet-name 或 --sheet-id 必给一个;range 的 Sheet1! 前缀不能替代它)
152
+ lark-cli sheets +csv-get --url "https://example.feishu.cn/sheets/shtXXX" --sheet-name "Sheet1" --range "A1:F30"
153
+
154
+ # 用 sheet-name 模糊定位(运行时框架会先解析到 sheet-id)
155
+ lark-cli sheets +csv-get --spreadsheet-token shtXXX --sheet-name "销售明细" --range "A1:F30"
156
+ ```
157
+
158
+ 输出契约(envelope.data):
159
+
160
+ - `annotated_csv` — 含 `[row=N]` 前缀的 CSV 主入口
161
+ - `col_indices` / `row_indices` — 列字母 / 行号映射数组
162
+ - `current_region` — 从锚点扩展到被空行空列包围的连续区域的 A1 范围。⚠️ **它不是整表真实边界**:遇表中部整行空行 / 整列空列会截断、可能小于真实数据范围;表尾的汇总 / 签名 / 脚注又可能让它大于纯数据范围。判断整表是否读全须拿 `+workbook-info` 的物理 `row_count` 当上界交叉核对(见上方「`row_count` 与 `current_region` 都不能单独定末行」)
163
+ - `row_count` / `col_count` — **本次返回的行 / 列数**(= `actual_range` 的尺寸,随 `--range` 变),**不是整表物理总行列数**;整表物理尺寸取 `+workbook-info`
164
+ - `has_more` — 当前 `--range` 是否因 `--max-chars` 被截断(截断后续读接着用 `--range`);它**只反映本次 range 内是否读完**,`has_more=false` **不代表整表已读全**(range 之外的数据不在判断内)
165
+
166
+ > 要按列类型结构化读出(喂 DataFrame)用 `+table-get`(见下);`+csv-get` 给的是带 `[row=N]` 前缀的纯值快照,下游需要行号/列坐标时直接从前缀与 `col_indices` 取。
167
+
168
+ ### `+cells-get`
169
+
170
+ 示例:
171
+
172
+ ```bash
173
+ # 读 A1:F10 的公式 + 样式(sheet 定位必填)
174
+ lark-cli sheets +cells-get --url "https://example.feishu.cn/sheets/shtXXX" --sheet-name "Sheet1" \
175
+ --range "A1:F10" --include formula,style
176
+ ```
177
+
178
+ > ⚠️ 调用方在 `cells[i][j]` 中**不能**用下标推真实行列:必须读 `ranges[n].row_indices[i]` / `ranges[n].col_indices[j]`。
179
+
180
+ ### `+table-get`(飞书 → DataFrame,类型保真读出)
181
+
182
+ 把表格读回一份 typed 协议(`sheets[]` + `columns:[列名]` + `data:[[行]]` + `dtypes:{列名:pandas_dtype}` + `formats?:{列名:number_format}` + `range`),可一行还原 DataFrame。
183
+
184
+ **默认(不带 `--range`)读取整张子表的完整 used range**:会跨过表中部的整行空行 / 整列空列,覆盖到真实数据边界。每个子表都回传实际读取的 `range`(如 `A1:F10`):拿它和源 xlsx 行列数、关键末行 / 末日期交叉核对,确认读取完整。子表被 `max_chars` 裁掉时会带 `truncated: true` 与 `truncation_warning`——**先读这两个字段再用数据**,需要整表就改用 `--output-path` 落盘(回执看 `complete`)。仍要精确控制范围时显式传 `--range`。
185
+
186
+ 列类型从每列 `number_format` 推断(日期格式→`date`/`datetime64[ns]`、数值→`number`/`float64`、bool→`bool`),`date` 列的序列号转回 ISO `yyyy-mm-dd`——日期、数字往返不丢类型。**列类型只在该列所有非空值一致时才定(`number` / `date` / `bool`);一列混了类型(如数字列混入「暂无」、日期列混入裸数字)会降为 `string`(dtypes 输出 `object`),让 `dtypes` 与 `data` 里每个值自洽——不让 pandas `astype` 崩。降级是无损的(脏值原样保留为文本);若要把零星脏值转成数值列,交给调用方在 pandas 侧做(`to_numeric(errors='coerce')`),那里原始值仍在、可追溯。** 默认读所有子表、第一行当表头(`--no-header` 把首行当数据、列名取 `col1` / `col2` …)。
187
+
188
+ ```bash
189
+ # 默认读所有子表 → sheets[](typed 协议,可直接转 DataFrame)
190
+ lark-cli sheets +table-get --url "<表URL>"
191
+ # 可选:--sheet-name / --sheet-id 限定只读某一个子表(不给则读全部)
192
+ lark-cli sheets +table-get --url "<表URL>" --sheet-name "销售"
193
+ ```
194
+
195
+ #### 输出 → DataFrame(用 `sheet_to_df` helper)
196
+
197
+ 输出形状对齐 pandas split:`columns` 是列名数组、`data` 是二维数据、`dtypes` 是 `{列名: pandas_dtype_str}` 映射。直接喂给 `pd.DataFrame(...).astype(...)` 就能一次性还原所有列类型(不必逐列 `to_datetime` / `to_numeric`)。本 skill 把这段还原 helper 打包成可 import 的 [`scripts/sheets_df.py`](../scripts/sheets_df.py)(用 `sheet_to_df` 把读回的子表还原成 DataFrame):
198
+
199
+ ```python
200
+ from sheets_df import sheet_to_df
201
+
202
+ # 单 sheet
203
+ df = sheet_to_df(out["data"]["sheets"][0])
204
+
205
+ # 多 sheet——按名字取
206
+ sheets = {s["name"]: sheet_to_df(s) for s in out["data"]["sheets"]}
207
+ df_sales = sheets["销售"]
208
+ ```
209
+
210
+ > 显示格式(千分位、百分比、自定义日期)在 `sheet["formats"]`,pandas 不消费;`sheet_to_df(sheet)` 消费 `(columns, data, dtypes)` 还原 DataFrame,读出后即可在本地分析。
211
+
212
+ ### Validate / DryRun / Execute 约束
213
+
214
+ - `Validate` 阶段只做 XOR 检查、Enum 合法性、防爆参数上限校验;**禁止**联网(如不能用 `--sheet-name` 提前去查 `sheet-id`)。
215
+ - `DryRun` 输出请求模板:`--sheet-name` 在 dry-run 输出里生成为 `<resolve:销售明细>` 占位符,不实际解析。
216
+ - `Execute` 阶段才进行 sheet-name → sheet-id 解析与 API 调用。
@@ -0,0 +1,67 @@
1
+ # Lark Sheet Search
2
+
3
+ ## 使用场景
4
+
5
+ 在飞书表格中搜索 / 定位文本。本 reference 覆盖 1 个只读 shortcut:
6
+
7
+ | 操作需求 | 使用工具 | 说明 |
8
+ |---------|---------|------|
9
+ | 搜索/定位文本 | `+cells-search` | 返回匹配的单元格位置,支持正则、精确匹配、范围限定等 |
10
+
11
+ **常见配置错误(必须注意)**:
12
+ - **不要把操作动词当搜索词**:用户说"汇总金额"是一个操作动作(求和),不是要搜索"汇总金额"这个文本。只有当确实需要定位某个文本值的位置时才用 `+cells-search`
13
+ - **不要用搜索来了解表格结构**:要了解表头和数据结构时,应使用 `+csv-get` 读取前几行,而不是用 `+cells-search` 逐个猜测字段名
14
+ - **注意正则特殊字符**:使用正则匹配时,`.`、`*`、`(`、`)` 等特殊字符需要转义
15
+
16
+ ## Shortcuts
17
+
18
+ | Shortcut | Risk | 分组 |
19
+ | --- | --- | --- |
20
+ | `+cells-search` | read | 单元格 |
21
+
22
+ ## Flags
23
+
24
+ ### `+cells-search`
25
+
26
+ _公共四件套 · 系统:`--dry-run`_
27
+
28
+ | Flag | Type | 必填 | 说明 |
29
+ | --- | --- | --- | --- |
30
+ | `--find` | string | required | 待查找文本(与 `--regex` 配合时按正则解释) |
31
+ | `--range` | string | optional | 查找范围(A1 格式);省略时整表 |
32
+ | `--match-case` | bool | optional | 大小写敏感 |
33
+ | `--match-entire-cell` | bool | optional | 完全匹配整个单元格 |
34
+ | `--regex` | bool | optional | 把 `--find` 按正则解释 |
35
+ | `--include-formulas` | bool | optional | 也在公式文本中搜索 |
36
+ | `--max-matches` | int | optional | 防爆,默认 5000(隐藏 flag:不在 `--help` 列出,但可正常传入) |
37
+ | `--offset` | int | optional | 跳过前 N 个匹配(分页用),默认 0 |
38
+
39
+ ## Examples
40
+
41
+ 公共四件套:所有 shortcut 顶部排列 `--url` / `--spreadsheet-token` / `--sheet-id` / `--sheet-name`(XOR 规则)。
42
+
43
+ ### `+cells-search`
44
+
45
+ 示例:
46
+
47
+ ```bash
48
+ # 普通查找
49
+ lark-cli sheets +cells-search --url "https://example.feishu.cn/sheets/shtXXX" \
50
+ --sheet-name "Sheet1" --find "张三"
51
+
52
+ # 正则 + 范围限定
53
+ lark-cli sheets +cells-search --spreadsheet-token shtXXX --sheet-id "$SID" \
54
+ --find "^[A-Z]{2}-\\d{4}$" --regex --range "A2:A1000"
55
+ ```
56
+
57
+ 输出契约(envelope.data):
58
+
59
+ - `matches` — 命中 cell 列表,每条含 `address`(A1)+ `value` + `sheet_id`
60
+ - `total_matches` — 匹配总数
61
+ - `has_more` / `next_offset` — 分页游标(命中数超过单页上限时用于继续读取)
62
+
63
+ ### Validate / DryRun / Execute 约束
64
+
65
+ - `Validate`:XOR 公共四件套;`--find` 非空;正则模式下 `--find` 必须是合法正则。
66
+ - `DryRun`:`+cells-search` 输出请求模板。
67
+ - `Execute`:发起搜索查询。
@@ -0,0 +1,52 @@
1
+ # Lark Sheet Sheet Structure
2
+
3
+ ## 使用场景
4
+
5
+ 查看飞书表格子表的结构与布局。本 reference 覆盖 1 个只读 shortcut:
6
+
7
+ | 操作需求 | 使用工具 | 说明 |
8
+ |---------|---------|------|
9
+ | 查看子表布局 | `+sheet-info` | 获取行高、列宽、隐藏行列、行列分组、合并单元格、冻结等布局信息 |
10
+
11
+ 注意:
12
+
13
+ - 当表格存在合并单元格时,应结合返回的 `merged_cells` 判断表头、分组标题和区域语义
14
+ - 不要把合并区域中非左上角的空白单元格理解为"无内容";通常应将左上角单元格的内容视为整个合并区域的语义内容
15
+ - 要识别隐藏行列(以决定是否过滤、或如何解读混入的隐藏数据),用 `+sheet-info --include hidden_rows,hidden_cols` 取隐藏行列集合,再结合 `+csv-get` / `+cells-get`(见 `lark-sheets-read-data`)返回的 `row_indices` / `col_indices` 判断每行 / 每列是否隐藏
16
+
17
+ ## Shortcuts
18
+
19
+ | Shortcut | Risk | 分组 |
20
+ | --- | --- | --- |
21
+ | `+sheet-info` | read | 工作表 |
22
+
23
+ ## Flags
24
+
25
+ ### `+sheet-info`
26
+
27
+ _公共四件套 · 系统:`--dry-run`_
28
+
29
+ | Flag | Type | 必填 | 说明 |
30
+ | --- | --- | --- | --- |
31
+ | `--include` | string_slice | optional | 要返回的结构信息类别,逗号分隔多个(可选值:`merges` / `row_heights` / `col_widths` / `hidden_rows` / `hidden_cols` / `groups` / `frozen`) |
32
+ | `--range` | string | optional | 限定只返回该 A1 范围的结构信息;省略时返回整表 |
33
+
34
+ ## Examples
35
+
36
+ 公共四件套:所有 shortcut 顶部排列 `--url` / `--spreadsheet-token` / `--sheet-id` / `--sheet-name`(XOR)。
37
+
38
+ ### `+sheet-info`
39
+
40
+ ```bash
41
+ # 读子表的合并区 + 行高 + 冻结信息
42
+ lark-cli sheets +sheet-info --url "https://example.feishu.cn/sheets/shtXXX" \
43
+ --sheet-id "$SID" --include merges,row_heights,frozen
44
+ ```
45
+
46
+ 输出契约:返回子表的行高 / 列宽 / 隐藏 / 合并 / 分组 / 冻结等布局元信息。
47
+
48
+ ### Validate / DryRun / Execute 约束
49
+
50
+ - `Validate`:XOR 公共四件套;`--range` 必须是合法 A1 范围。
51
+ - `DryRun`:输出请求模板,零网络副作用。
52
+ - `Execute`:发起子表结构查询。
@@ -0,0 +1,47 @@
1
+ # Lark Sheet Sparkline
2
+
3
+ ## 使用场景
4
+
5
+ 查看飞书表格中已有迷你图(单元格内嵌的小型图表)对象的配置。本 reference 覆盖 1 个只读 shortcut:
6
+
7
+ | 操作需求 | 使用工具 | 说明 |
8
+ |---------|---------|------|
9
+ | 查看已有迷你图 | `+sparkline-list` | 获取迷你图的类型、数据源和样式配置 |
10
+
11
+ > 迷你图用**两层 id** 管理——`group_id` 选组(一组同形态的迷你图共享类型 / 样式 / 数据源映射),`sparkline_id` 在组内选具体某一项。注意:不等同于已禁用的 `SPARKLINE()` 公式函数。
12
+
13
+ ## Shortcuts
14
+
15
+ | Shortcut | Risk | 分组 |
16
+ | --- | --- | --- |
17
+ | `+sparkline-list` | read | 对象 |
18
+
19
+ ## Flags
20
+
21
+ ### `+sparkline-list`
22
+
23
+ _公共四件套 · 系统:`--dry-run`_
24
+
25
+ | Flag | Type | 必填 | 说明 |
26
+ | --- | --- | --- | --- |
27
+ | `--group-id` | string | optional | 按 group_id 过滤 |
28
+
29
+ ## Examples
30
+
31
+ 公共四件套:所有 shortcut 顶部排列 `--url` / `--spreadsheet-token` / `--sheet-id` / `--sheet-name`(XOR)。
32
+
33
+ ### `+sparkline-list`
34
+
35
+ ```bash
36
+ # 列出整张子表的所有迷你图组
37
+ lark-cli sheets +sparkline-list --url "..." --sheet-id "$SID"
38
+
39
+ # 钉到单组:返回该组每一项的 sparkline_id
40
+ lark-cli sheets +sparkline-list --url "..." --sheet-id "$SID" --group-id "grpA"
41
+ ```
42
+
43
+ ### Validate / DryRun / Execute 约束
44
+
45
+ - `Validate`:XOR 公共四件套。
46
+ - `DryRun`:输出请求模板,零网络副作用。
47
+ - `Execute`:发起迷你图列表查询(返回 `config` / `sparklines`)。
@@ -0,0 +1,69 @@
1
+ # Lark Sheet Workbook
2
+
3
+ ## 使用场景
4
+
5
+ 查看飞书表格的工作簿结构与版本号。本 reference 覆盖 2 个只读 shortcut:
6
+
7
+ | 操作需求 | 使用工具 | 说明 |
8
+ |---------|---------|------|
9
+ | 查看工作簿结构 | `+workbook-info` | 获取子表列表、名称、行列数、可见性等元数据 |
10
+ | 获取当前 revision | `+revision-get` | 获取当前文档 revision(版本号),可作为 `+changeset-get` 复核的版本锚点 |
11
+
12
+ 注意:
13
+
14
+ - **获取结构是第一步**:任何表格操作前必须先调用 `+workbook-info`,不要跳过直接操作。返回的行列数、子表列表是后续所有操作的基础
15
+ - **优先使用 `sheet_id`**:从 `+workbook-info` 返回值中精确获取 `sheet_id`(稳定标识符),不要手动拼写或从 URL 中猜测
16
+ - 若 `+workbook-info` 返回包含 `warning_message`,说明部分 `sheet_id` 已失效(被删除/改名或输入错误),应停止复用这些 id,重新不带 `sheet_ids` 全量获取结构后再继续操作
17
+ - **导入 / 导出属文件级写操作,当前沙箱不可用**:把本地 `.xlsx` / `.xls` / `.csv` 导入成新的飞书电子表格(或导成多维表格 bitable)、导出下载工作簿,当前沙箱均不可用(lark-drive 域仅开放只读查询,不含导入 / 导出能力);不要用本 skill 或其它域命令替代。
18
+
19
+ ## Shortcuts
20
+
21
+ | Shortcut | Risk | 分组 |
22
+ | --- | --- | --- |
23
+ | `+workbook-info` | read | 工作簿 |
24
+ | `+revision-get` | read | 工作簿 |
25
+
26
+ ## Flags
27
+
28
+ ### `+workbook-info`
29
+
30
+ _公共:URL/token(无 sheet 定位) · 系统:`--dry-run`_
31
+
32
+ _仅含公共 / 系统 flag。_
33
+
34
+ ### `+revision-get`
35
+
36
+ _公共:URL/token(无 sheet 定位) · 系统:`--dry-run`_
37
+
38
+ _仅含公共 / 系统 flag。_
39
+
40
+ ## Examples
41
+
42
+ 公共定位:所有 shortcut 顶部排列 `--url` / `--spreadsheet-token`(XOR,二选一,无 sheet 定位)。
43
+
44
+ ### `+workbook-info`
45
+
46
+ ```bash
47
+ lark-cli sheets +workbook-info --url "https://example.feishu.cn/sheets/shtXXX"
48
+ ```
49
+
50
+ 输出契约:返回 `sheets[]`,每个含 `sheet_id` / `title`(工作表显示名;旧 payload 用 `sheet_name`,读取时优先取 `title`、缺失再回退 `sheet_name`)/ `index` / `resource_type` / `row_count` / `column_count` / `is_hidden`,以及计数字段 `merged_cells_count` / `chart_count` / `pivot_table_count` / `float_image_count`(无 `frozen_*` 字段,冻结信息请用 `+sheet-info` 读取)。是操作飞书表格的第一步——任何后续 sheet 级动作都需要先拿这里的 sheet_id。
51
+
52
+ > **子表类型 `resource_type`**:`sheet`(普通网格子表)/ `bitable`(内嵌的多维表格子表)/ `#UNSUPPORTED_TYPE`(其它暂不支持的嵌入子表)。
53
+ > - 网格类读取(读单元格 / 区域 / 样式 / CSV / 对象配置等)**仅适用于 `sheet`**。对 `bitable` / `#UNSUPPORTED_TYPE` 子表执行网格操作会被直接拒绝并返回明确报错。
54
+ > - 要读 `bitable` 子表里的数据:该子表条目会附带 `bitable_app_token` + `bitable_table_id` 两个字段,直接用多维表格命令操作,例如 `lark-cli base +record-list --base-token <bitable_app_token> --table-id <bitable_table_id>`。不要走 sheets 网格命令。
55
+ > - `bitable` / `#UNSUPPORTED_TYPE` 子表条目**只含** `sheet_id` / `sheet_name` / `index` / `resource_type`(bitable 另加上述两个 token)以及 `is_hidden` / `tab_color`;**不输出** `row_count` / `column_count` / 各类 `*_count` / `frozen_*` 等网格指标(对非网格子表无意义)。
56
+
57
+ ### `+revision-get`
58
+
59
+ ```bash
60
+ lark-cli sheets +revision-get --url "https://example.feishu.cn/sheets/shtXXX"
61
+ ```
62
+
63
+ 输出契约:返回单个 `revision` 字段,即当前文档版本号。它是 `+changeset-get` 的版本锚点:如果刚执行过一次读操作,也可以直接复用那次响应里的 `revision`;当只想单独取当前版本号、且不需要其它结构信息时,用 `+revision-get` 最直接。
64
+
65
+ ### Validate / DryRun / Execute 约束
66
+
67
+ - `Validate`:`--url` / `--spreadsheet-token` XOR 必填。
68
+ - `DryRun`:输出请求模板,零网络副作用。
69
+ - `Execute`:发起工作簿结构 / revision 查询。
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env python3
2
+ # Copyright (c) 2026 Lark Technologies Pte. Ltd.
3
+ # SPDX-License-Identifier: MIT
4
+ """DataFrame ↔ Feishu Sheet typed-JSON helpers.
5
+
6
+ Shared helper pulled out so callers can `import` it instead of copy-pasting.
7
+ `sheet_to_df` supports the read command `+table-get`(见 `lark-sheets-read-data`
8
+ "输出 → DataFrame");`df_to_sheet` 是打包 payload 的通用工具(沙箱只读子集里
9
+ 不作为推荐入口,保留仅为 helper 完整性):
10
+
11
+ from sheets_df import df_to_sheet, sheet_to_df
12
+
13
+ Callers run lark-cli themselves; this file is a library, not a CLI.
14
+ """
15
+ import json
16
+
17
+ import pandas as pd
18
+
19
+
20
+ def df_to_sheet(df, name, formats=None):
21
+ """Pack one DataFrame into one entry of a `+table-put --sheets` payload."""
22
+ return {
23
+ "name": name,
24
+ **json.loads(df.to_json(orient="split", date_format="iso")),
25
+ "dtypes": df.dtypes.astype(str).to_dict(),
26
+ **({"formats": formats} if formats else {}),
27
+ }
28
+
29
+
30
+ def sheet_to_df(sheet):
31
+ """Restore one `+table-get` sheet dict into a typed DataFrame."""
32
+ return pd.DataFrame(sheet["data"], columns=sheet["columns"]).astype(sheet["dtypes"])
@@ -0,0 +1,86 @@
1
+ # slides
2
+
3
+ ## 身份
4
+
5
+ - slides 相关的读取操作默认以 `--as user`(用户身份)执行,下文示例统一显式带 `--as user`。
6
+
7
+ ## 能力边界
8
+
9
+ 本 skill 在沙箱内是**只读**的:用于读取和检查已有演示文稿,不生成、不修改幻灯片内容。
10
+
11
+ - 读取整份演示文稿的完整 XML(`slides xml_presentations get`)。
12
+ - 按 `slide_id` 读取单页 XML,可指定历史版本(`slides xml_presentation.slide get`)。
13
+ - 列出历史版本、查询回滚任务状态(`slides xml_presentation.history list` /
14
+ `revert_status`)。
15
+
16
+ ## 核心概念
17
+
18
+ ### URL 格式与 Token
19
+
20
+ | URL 格式 | 示例 | Token 类型 | 处理方式 |
21
+ |----------|------|-----------|----------|
22
+ | `/slides/` | `https://example.larkoffice.com/slides/xxxxxxxxxxxxx` | `xml_presentation_id` | URL 路径中的 token 直接作为 `xml_presentation_id` 使用 |
23
+ | `/wiki/` | `https://example.larkoffice.com/wiki/wikcnxxxxxxxxx` | `wiki_token` | ⚠️ **不能直接使用**,需要先查询获取真实的 `obj_token` |
24
+
25
+ ### Wiki 链接特殊处理(关键!)
26
+
27
+ 知识库链接(`/wiki/TOKEN`)不能直接当 `xml_presentation_id`。调用 slides 原生 API 前,先查询
28
+ wiki 节点,确认 `node.obj_type == "slides"`,再用 `node.obj_token` 作为真实 presentation ID。
29
+
30
+ ```bash
31
+ lark-cli wiki spaces get_node --as user --params '{"token":"wiki_token"}'
32
+ ```
33
+
34
+ ### 资源关系
35
+
36
+ ```text
37
+ Wiki Space (知识空间)
38
+ └── Wiki Node (知识库节点, obj_type: slides)
39
+ └── obj_token → xml_presentation_id
40
+
41
+ Slides (演示文稿)
42
+ ├── xml_presentation_id (演示文稿唯一标识)
43
+ ├── revision_id (版本号)
44
+ └── Slide (幻灯片页面)
45
+ └── slide_id (页面唯一标识)
46
+ ```
47
+
48
+ ## References
49
+
50
+ - 读取整份 XML:[`lark-slides-xml-presentations-get.md`](references/lark-slides-xml-presentations-get.md)
51
+ - 读取单页 XML:[`lark-slides-xml-presentation-slide-get.md`](references/lark-slides-xml-presentation-slide-get.md)
52
+ - 历史版本与回滚状态:[`lark-slides-history.md`](references/lark-slides-history.md)
53
+
54
+ ## API(沙箱内仅以下原生 API 调用可用)
55
+
56
+ 本沙箱内**仅**以下原生 `<service> <resource> <method>` 组合可用(全部只读),不要再自行拼其它
57
+ service/api 组合去试。调用前先用 `lark-cli schema slides.<resource>.<method>` 查看最新参数结构。
58
+
59
+ ### xml_presentations
60
+
61
+ - `get` — 读取演示文稿的完整 XML 内容(返回 `data.xml_presentation.content`)
62
+
63
+ ```bash
64
+ lark-cli slides xml_presentations get --as user --params '{"xml_presentation_id":"<id>","revision_id":-1}'
65
+ ```
66
+
67
+ ### xml_presentation.slide
68
+
69
+ - `get` — 按 `slide_id` 读取单页 XML,可指定历史版本
70
+
71
+ ```bash
72
+ lark-cli slides xml_presentation.slide get --as user --params '{"xml_presentation_id":"<id>","slide_id":"<slide_id>","revision_id":-1}'
73
+ ```
74
+
75
+ ### xml_presentation.history
76
+
77
+ - `list` — 分页列出历史版本,返回 `entries[]`(含 `history_version_id`、`revision_id`、`edit_time`)
78
+ - `revert_status` — 查询回滚任务状态(`status`、`failed_block_tokens`)
79
+
80
+ ```bash
81
+ lark-cli slides xml_presentation.history list --as user --params '<json_params>'
82
+ lark-cli slides xml_presentation.history revert_status --as user --params '<json_params>'
83
+ ```
84
+
85
+ > 参数结构以 `lark-cli schema slides.xml_presentation.history.list` /
86
+ > `lark-cli schema slides.xml_presentation.history.revert_status` 输出为准。