Skip to content

feat(sheets): add +formula-verify shortcut for verify_formula tool#1626

Merged
wenzhuozhen merged 1 commit into
feat/lark-sheets-developfrom
feat/sheets-formula-verify
Jun 29, 2026
Merged

feat(sheets): add +formula-verify shortcut for verify_formula tool#1626
wenzhuozhen merged 1 commit into
feat/lark-sheets-developfrom
feat/sheets-formula-verify

Conversation

@wenzhuozhen

@wenzhuozhen wenzhuozhen commented Jun 27, 2026

Copy link
Copy Markdown
Collaborator

Summary

sheet-skill-spec/canonical-spec/tool-schemas/tools-schema.json 新加的 verify_formula 工具落地为 lark-cli 薄壳 shortcut +formula-verify(read scope,invoke_read),供 AI 在批量公式写入(+cells-set / +csv-put / +batch-update / +workbook-import 等)之后做 R10 zero-error 自检。

PRD: https://bytedance.larkoffice.com/docx/DetAdncvKo0okNx7A08cVyeRngf

Changes

  • shortcuts/sheets/data/flag-defs.json: 新增 +formula-verify 命令 flag 定义
    • --url / --spreadsheet-token (XOR)
    • --sheet-id / --sheet-name(各自 string_slice,可重复或逗号分隔;两者互斥;都不传 = 扫描全部可见子表)
    • --rangestring_slice,可多段)
    • --max-locations(int,default 20)
    • --exit-on-error(bool)
  • shortcuts/sheets/flag_defs_gen.go: go generate 重新生成
  • shortcuts/sheets/lark_sheet_formula_verify.go: FormulaVerify shortcut 实现,把 CLI flag 翻成 verify_formula 工具入参;调 AIService.OpenAPIToolCallRead--exit-on-error 状态映射 → success / partial 静默通过,errors_founderrs.SubtypeFailedPrecondition 验证错误(带 hint 引导调用方修公式 / IFERROR 兜底后重跑),未知 status 转 SubtypeInvalidResponse 内部错误(避免静默零退出)
  • shortcuts/sheets/shortcuts.go: 注册 FormulaVerify,挂在 lark_sheet_search_replace 之后
  • shortcuts/sheets/lark_sheet_formula_verify_test.go: 单测覆盖 dry-run wire 形态、selector 互斥、cap > 0 守卫、exit-on-error 状态矩阵(success / partial / errors_found / unknown / non-object)的 typed-error 断言
  • tests/cli_e2e/sheets/sheets_formula_verify_dryrun_test.go: 通过外部 lark-cli 二进制做 dry-run 端到端校验

Test Plan

  • go test -race -count=1 ./shortcuts/... 全绿(含新增单测)
  • go test -run TestSheets_FormulaVerify ./tests/cli_e2e/sheets/... 全绿(dry-run E2E)
  • go vet ./... 干净
  • gofmt -l . 干净
  • go mod tidy 无 diff
  • Live E2E:依赖 upstream BE-1 (sheet.node.cmd_api 落地 VerifyFormula handler) + BE-2 (sheet.facade.agg 注册 ToolName 路由) merge 后再跑

Related Issues

Summary by CodeRabbit

  • New Features
    • Added sheets +formula-verify for zero-error formula self-check with sheet/range scoping, scan caps, and --exit-on-error.
    • Added sheets +changeset-get to retrieve revision-scoped changesets.
    • Added typed Arrow IPC/Feather v2 --dataframe / --dataframe-out options for relevant table/workbook shortcuts.
  • Bug Fixes
    • Strengthened CLI validation for selector exclusivity and non-positive scan limits; improved handling of success/partial/error statuses.
  • Documentation
    • Updated Sheets skill docs, references, and cheat sheets with the new commands and revised typed-write/verify guidance.
  • Tests
    • Added unit and CLI end-to-end dry-run/validation/exit-status coverage for +formula-verify.

@CLAassistant

CLAassistant commented Jun 27, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds +formula-verify and +changeset-get, extends typed Arrow IPC workbook/table flags, updates Sheets reference docs, and injects optional PPE routing headers from environment variables.

Changes

Sheets shortcuts and documentation

Layer / File(s) Summary
Shortcut contracts and metadata
shortcuts/sheets/data/flag-defs.json, shortcuts/sheets/data/flag-schemas.json, shortcuts/sheets/flag_defs_gen.go, shortcuts/sheets/shortcuts.go
+formula-verify and +changeset-get are added, typed workbook/table flags are expanded for Arrow IPC and revision ranges, and the related schema metadata and shortcut registry are updated.
Formula verify execution and tests
shortcuts/sheets/lark_sheet_formula_verify.go, shortcuts/sheets/lark_sheet_formula_verify_test.go, tests/cli_e2e/sheets/sheets_formula_verify_dryrun_test.go
The new shortcut validates selectors and limits, builds the verify_formula request, executes the read tool, and maps output statuses to CLI exit behavior; unit and e2e tests cover request shape and validation.
Sheets docs and references
skills/lark-sheets/SKILL.md, skills/lark-sheets/references/*, skills/lark-sheets/scripts/sheets_df.py
Sheets docs and references are updated for typed Arrow workflows, formula verification, changesets, workbook import/export, write rules, and related shortcut guidance; the old sheets_df.py helper module is removed.

CLI security headers

Layer / File(s) Summary
Environment header injection
internal/envvars/envvars.go, internal/cmdutil/secheader.go
Two new CLI environment variables are defined and conditionally forwarded as x-tt-env and x-use-ppe headers.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • larksuite/cli#516 — also changes internal/cmdutil/secheader.go to inject request routing headers.

Suggested labels

domain/base, size/XL

Suggested reviewers

  • fangshuyu-768
  • xiongyuanwen-byted

Poem

A bunny hopped through sheets at dawn,
with verify checks and changes drawn.
It sniffed the headers, soft and keen,
and left the CLI tidy and green.
🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding the +formula-verify shortcut for verify_formula.
Docstring Coverage ✅ Passed Docstring coverage is 92.86% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description follows the required template with Summary, Changes, Test Plan, and Related Issues sections filled in.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/sheets-formula-verify

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added domain/ccm PR touches the ccm domain size/M Single-domain feat or fix with limited business impact labels Jun 27, 2026
@codecov

codecov Bot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 75.29412% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.68%. Comparing base (d9330b7) to head (954042c).
⚠️ Report is 7 commits behind head on feat/lark-sheets-develop.

Files with missing lines Patch % Lines
shortcuts/sheets/lark_sheet_formula_verify.go 78.75% 14 Missing and 3 partials ⚠️
internal/cmdutil/secheader.go 0.00% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@                     Coverage Diff                      @@
##           feat/lark-sheets-develop    #1626      +/-   ##
============================================================
+ Coverage                     74.66%   74.68%   +0.02%     
============================================================
  Files                           804      809       +5     
  Lines                         81032    81569     +537     
============================================================
+ Hits                          60501    60922     +421     
- Misses                        16029    16107      +78     
- Partials                       4502     4540      +38     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Jun 27, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@954042ca64c7a3de04c589ae1446ac6d9fcc7ea1

🧩 Skill update

npx skills add larksuite/cli#feat/sheets-formula-verify -y -g

@wenzhuozhen
wenzhuozhen requested a review from liangshuo-1 as a code owner June 29, 2026 04:24
@github-actions github-actions Bot added size/XL Architecture-level or global-impact change and removed size/M Single-domain feat or fix with limited business impact labels Jun 29, 2026
@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown

PR Quality Summary

CI did not complete successfully. Use the failed check links below to decide whether this PR needs a code change or a rerun.

Failed checks

  • deterministic-gate — failure — details
  • results — failure — details

deterministic-gate

  • skill_command_referenceskills/lark-sheets/references/lark-sheets-changeset.md:89 — example references unknown command "sheets +changeset-get" — Action: update the example to use a command present in the command manifest
  • skill_command_referenceskills/lark-sheets/references/lark-sheets-changeset.md:92 — example references unknown command "sheets +changeset-get" — Action: update the example to use a command present in the command manifest

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
shortcuts/sheets/data/flag-defs.json (1)

607-631: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Wire --dataframe into +workbook-create or drop it from the command. +workbook-create only validates and consumes --values / --sheets; --dataframe is exposed in the flag schema but never participates in validation or payload construction, so the “mutually exclusive” wording is misleading and the flag can be accepted without doing anything useful.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/sheets/data/flag-defs.json` around lines 607 - 631, The
`--dataframe` flag is documented in the schema but not actually handled by
`+workbook-create`, so the mutual-exclusion claim is inconsistent. Update the
`workbook-create` flag validation and payload-building logic to either accept
and process `dataframe` alongside `values`/`sheets` using the existing
`dataframe` handling path, or remove `dataframe` from the command surface
entirely; make sure the relevant symbols in `+workbook-create` and the
`dataframe` flag definition stay aligned.
🧹 Nitpick comments (3)
skills/lark-sheets/references/lark-sheets-formula-verify.md (2)

18-18: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Clarify shortcut availability timing.

The doc states the calling entry point is "base 表的 +formula-verify shortcut", but notes "在 shortcut 上线前,调用 verify_formula 工具本身即可". Given the PR summary states "live end-to-end validation still depends on upstream backend changes being merged first", consider adding an explicit availability warning at the top (similar to backend dependency note) so readers don't attempt to use the shortcut before it's actually registered.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/lark-sheets/references/lark-sheets-formula-verify.md` at line 18, The
formula-verify doc currently mentions both the base table +formula-verify
shortcut and the verify_formula tool, but it does not clearly warn readers that
the shortcut is not available until the upstream backend change is merged and
the shortcut is registered. Update the opening guidance in
lark-sheets-formula-verify.md to add an explicit availability note, using the
existing shortcut/verify_formula wording, so readers know to call verify_formula
directly until +formula-verify is live.

12-12: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Verify tool/shortcut name consistency.

Line 12 lists set_cell_range / +cells-set — the first is a tool name, the second a shortcut. Other references in this doc use tool names (e.g., set_range_from_csv, import_sandbox_to_sheet). For consistency with the "调用契约" section which says "调用 verify_formula 工具本身即可", consider using tool names throughout or clarifying the mapping. The mixed usage could confuse readers about whether to call tools or shortcuts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/lark-sheets/references/lark-sheets-formula-verify.md` at line 12, The
formula verification doc mixes tool names and shortcut names, which can confuse
users about what to call. Update the wording around verify_formula and the
referenced action so the terminology is consistent throughout the document,
preferably using tool names like set_range_from_csv and import_sandbox_to_sheet
everywhere, or explicitly clarifying when a shortcut such as +cells-set maps to
a tool. Keep the “调用契约” section aligned with the same naming convention and make
sure the reference near the runtime error section uses the same style.
skills/lark-sheets/references/lark-sheets-write-cells.md (1)

21-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace brace expansion with explicit command names.

The notation +cells-{merge|unmerge} uses shell brace expansion which is unfamiliar in Chinese documentation and could confuse readers. Use explicit "+cells-merge+cells-unmerge" (or verify actual shortcut names) for clarity.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/lark-sheets/references/lark-sheets-write-cells.md` at line 21, Replace
the brace-expanded tool reference in the merged_cells guidance with explicit
command names so the docs are clearer and less ambiguous. Update the wording
around the +cells-{merge|unmerge} mention to use the actual tool names such as
+cells-merge and +cells-unmerge, and make sure the surrounding merged_cells
instructions still point readers to the correct merge-handling workflow in this
section.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@skills/lark-sheets/references/lark-sheets-batch-update.md`:
- Around line 29-35: The batch-only formula guidance currently mentions nested
+table-put inside +batch-update, but the --operations shortcut enum in this
document does not permit +table-put. Update the +batch-update examples and
wording to remove +table-put from the allowed batch formula flows, and keep the
guidance aligned with the existing +cells-set and +csv-put paths so the
documented command usage matches what the CLI accepts.

In `@skills/lark-sheets/references/lark-sheets-read-data.md`:
- Around line 155-156: The description of current_region is too strong here; it
should not be presented as the final or “真实数据边界” because later guidance in this
document explains it may include totals, signatures, notes, and separator rows.
Update the wording in the current_region and has_more section to describe
current_region as the auto-expanded non-empty region returned by the sheet, and
point readers to the “确定数据范围的正确流程” guidance for choosing the actual extraction
range.
- Around line 174-176: The `lark-sheets-read-data` docs for the typed protocol
should stay pandas-valid for `pd.DataFrame(...).astype(sheet["dtypes"])`. Update
the `read`/`+table-put` mirror description so `dtypes` documents only actual
pandas dtype strings (for example `datetime64[ns]`, `float64`, `bool`,
`object`), and if you want to keep logical types like `date`/`number`, add an
explicit conversion step in the docs before calling `astype`. Make sure the
guidance around `get_cell_ranges`, `get_range_as_csv`, and the
`sheets[]`/`columns`/`data`/`dtypes` schema remains consistent.

In `@skills/lark-sheets/references/lark-sheets-workbook.md`:
- Around line 142-144: The `--sheets` example is missing the required `name`
field for each sheet item, so the documented one-liner currently produces an
invalid payload. Update the `--sheets` documentation in the workbook reference
so the example construction includes `name` for each sheet object alongside
`columns`, `data`, and `dtypes`, matching the schema described for `+table-put`
and the `--sheets` contract.

In `@skills/lark-sheets/SKILL.md`:
- Around line 41-59: The quick-reference table in SKILL.md is missing the
image-related shortcuts, so restore the entries for cells-set-image and the
float-image commands alongside the existing spreadsheet actions. Update the
table and the surrounding note so these commands remain discoverable, and make
sure the wording points readers to the dedicated image docs without changing the
rest of the command guidance.

---

Outside diff comments:
In `@shortcuts/sheets/data/flag-defs.json`:
- Around line 607-631: The `--dataframe` flag is documented in the schema but
not actually handled by `+workbook-create`, so the mutual-exclusion claim is
inconsistent. Update the `workbook-create` flag validation and payload-building
logic to either accept and process `dataframe` alongside `values`/`sheets` using
the existing `dataframe` handling path, or remove `dataframe` from the command
surface entirely; make sure the relevant symbols in `+workbook-create` and the
`dataframe` flag definition stay aligned.

---

Nitpick comments:
In `@skills/lark-sheets/references/lark-sheets-formula-verify.md`:
- Line 18: The formula-verify doc currently mentions both the base table
+formula-verify shortcut and the verify_formula tool, but it does not clearly
warn readers that the shortcut is not available until the upstream backend
change is merged and the shortcut is registered. Update the opening guidance in
lark-sheets-formula-verify.md to add an explicit availability note, using the
existing shortcut/verify_formula wording, so readers know to call verify_formula
directly until +formula-verify is live.
- Line 12: The formula verification doc mixes tool names and shortcut names,
which can confuse users about what to call. Update the wording around
verify_formula and the referenced action so the terminology is consistent
throughout the document, preferably using tool names like set_range_from_csv and
import_sandbox_to_sheet everywhere, or explicitly clarifying when a shortcut
such as +cells-set maps to a tool. Keep the “调用契约” section aligned with the same
naming convention and make sure the reference near the runtime error section
uses the same style.

In `@skills/lark-sheets/references/lark-sheets-write-cells.md`:
- Line 21: Replace the brace-expanded tool reference in the merged_cells
guidance with explicit command names so the docs are clearer and less ambiguous.
Update the wording around the +cells-{merge|unmerge} mention to use the actual
tool names such as +cells-merge and +cells-unmerge, and make sure the
surrounding merged_cells instructions still point readers to the correct
merge-handling workflow in this section.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 242386fd-04eb-47f4-a76e-860dbb66a3d9

📥 Commits

Reviewing files that changed from the base of the PR and between 61e15e6 and b5d4a25.

📒 Files selected for processing (20)
  • internal/cmdutil/secheader.go
  • internal/envvars/envvars.go
  • shortcuts/sheets/data/flag-defs.json
  • shortcuts/sheets/data/flag-schemas.json
  • shortcuts/sheets/flag_defs_gen.go
  • skills/lark-sheets/SKILL.md
  • skills/lark-sheets/references/lark-sheets-batch-update.md
  • skills/lark-sheets/references/lark-sheets-changeset.md
  • skills/lark-sheets/references/lark-sheets-chart.md
  • skills/lark-sheets/references/lark-sheets-conditional-format.md
  • skills/lark-sheets/references/lark-sheets-core-operations.md
  • skills/lark-sheets/references/lark-sheets-float-image.md
  • skills/lark-sheets/references/lark-sheets-formula-translation.md
  • skills/lark-sheets/references/lark-sheets-formula-verify.md
  • skills/lark-sheets/references/lark-sheets-range-operations.md
  • skills/lark-sheets/references/lark-sheets-read-data.md
  • skills/lark-sheets/references/lark-sheets-sparkline.md
  • skills/lark-sheets/references/lark-sheets-workbook.md
  • skills/lark-sheets/references/lark-sheets-write-cells.md
  • skills/lark-sheets/scripts/sheets_df.py
💤 Files with no reviewable changes (1)
  • skills/lark-sheets/scripts/sheets_df.py
✅ Files skipped from review due to trivial changes (5)
  • skills/lark-sheets/references/lark-sheets-chart.md
  • skills/lark-sheets/references/lark-sheets-range-operations.md
  • skills/lark-sheets/references/lark-sheets-formula-translation.md
  • skills/lark-sheets/references/lark-sheets-changeset.md
  • shortcuts/sheets/flag_defs_gen.go

Comment on lines +29 to +35
`+batch-update` 的 `--operations` 中只要**任一**子操作落了公式(`+cells-set` 含 `formula`、`+csv-put` 子操作 CSV 含 `=` 开头字段、嵌套 `+table-put` 含公式列),整批提交完成后**必须**调用 `verify_formula` 自检直到 `status='success'`——`+batch-update` 是原子提交,但"原子写入成功"和"算对了"是两件事;编译失败 / 运行时错误依旧可能出现。

执行要点:
- 整批 `+batch-update` 成功后立即跑 `verify_formula`;`status='errors_found'` 时禁止把链路标完成。
- `compile_errors[]` 非空时先解决编译失败(通过下一次 `+cells-set` 或新一轮 `+batch-update` 修正公式),再做运行时自检。
- 同一处错误连续修 3 次仍未通过 → 改 `IFERROR` 兜底或退回纯值写入。
- 同 R10:**禁止**在 `errors_found` 状态下用 `+cells-set --copy-to-range` 继续扩展(错误会被复制放大)。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove +table-put from the batch-only formula examples.

Line 29 says +batch-update may contain a nested +table-put, but the --operations shortcut enum in this same file (Line 118) does not allow +table-put. As written, this documents a flow the CLI will reject.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/lark-sheets/references/lark-sheets-batch-update.md` around lines 29 -
35, The batch-only formula guidance currently mentions nested +table-put inside
+batch-update, but the --operations shortcut enum in this document does not
permit +table-put. Update the +batch-update examples and wording to remove
+table-put from the allowed batch formula flows, and keep the guidance aligned
with the existing +cells-set and +csv-put paths so the documented command usage
matches what the CLI accepts.

Comment on lines +155 to +156
- `current_region` — 自动扩展到非空连续区域的 A1 范围。它是**真实数据边界**,**优先于 `+workbook-info` 的 `row_count`**(`row_count` 是网格物理行数,常是 200 / 1000 等默认值、远大于实际数据;按它盲读会拉回大片空行)
- `has_more` — 是否截断;截断后续读用 `--range` 接着读

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Don’t describe current_region as the final data boundary here.

This same file later explains that current_region can include totals, signatures, notes, and separator rows. Calling it “真实数据边界” here invites exactly the range mistakes that the new “确定数据范围的正确流程” section is trying to prevent.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/lark-sheets/references/lark-sheets-read-data.md` around lines 155 -
156, The description of current_region is too strong here; it should not be
presented as the final or “真实数据边界” because later guidance in this document
explains it may include totals, signatures, notes, and separator rows. Update
the wording in the current_region and has_more section to describe
current_region as the auto-expanded non-empty region returned by the sheet, and
point readers to the “确定数据范围的正确流程” guidance for choosing the actual extraction
range.

Comment on lines +174 to +176
`+table-put`(写入侧,见 write-cells reference)的镜像:把表格读回与 `--sheets` 完全同构的 typed 协议(`sheets[]` + `columns:[列名]` + `data:[[行]]` + `dtypes:{列名:pandas_dtype}` + `formats?:{列名:number_format}`),可直接喂回 `+table-put` 或一行还原 DataFrame。

**默认(不带 `--range`)读取整张子表的完整 used range**:会跨过表中部的整行空行 / 整列空列,覆盖到真实数据边界。每个子表都回传实际读取的 `range`(如 `A1:F10`)——`+table-get` 不返回分页 / 截断标志,这个 `range` 是判断是否读全的唯一信号:拿它和源 xlsx 行列数、关键末行 / 末日期交叉核对,确认读取完整。仍要精确控制范围时显式传 `--range`。

列类型从每列 `number_format` 推断(日期格式→`date`/`datetime64[ns]`、数值→`number`/`float64`、bool→`bool`),`date` 列的序列号转回 ISO `yyyy-mm-dd`——日期、数字往返不丢类型。**列类型只在该列所有非空值一致时才定(`number` / `date` / `bool`);一列混了类型(如数字列混入「暂无」、日期列混入裸数字)会降为 `string`(dtypes 输出 `object`),让 `dtypes` 与 `data` 里每个值自洽——能 round-trip 回 `+table-put`、不让 pandas `astype` 崩。降级是无损的(脏值原样保留为文本);若要把零星脏值转成数值列,交给调用方在 pandas 侧做(`to_numeric(errors='coerce')`),那里原始值仍在、可追溯。** 默认读所有子表、第一行当表头(`--no-header` 把首行当数据、列名取 `col1` / `col2` …)。
列类型从每列 `number_format` 推断(日期格式→`date`/`datetime64[ns]`、数值→`number`/`float64`、bool→`bool`),`date` 列的序列号转回 ISO `yyyy-mm-dd`——日期、数字往返不丢类型。**列类型只在该列所有非空值一致时才定(`number` / `date` / `bool`);一列混了类型(如数字列混入「暂无」、日期列混入裸数字)会降为 `string`(dtypes 输出 `object`),让 `dtypes` 与 `data` 里每个值自洽——能 round-trip 回 `+table-put`、不让 pandas `astype` 崩。降级是无损的(脏值原样保留为文本);若要把零星脏值转成数值列,交给调用方在 pandas 侧做(`to_numeric(errors='coerce')`),那里原始值仍在、可追溯。** 底层复用 `get_cell_ranges` / `get_range_as_csv`。默认读所有子表、第一行当表头(`--no-header` 把首行当数据、列名取 `col1` / `col2` …)。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Keep dtypes documentation pandas-valid.

The surrounding docs advertise pd.DataFrame(...).astype(sheet["dtypes"]), but this sentence says the protocol may emit logical types like date / number. Those are not valid astype targets. Either document only the actual emitted pandas dtype strings, or add the translation step before the helper.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/lark-sheets/references/lark-sheets-read-data.md` around lines 174 -
176, The `lark-sheets-read-data` docs for the typed protocol should stay
pandas-valid for `pd.DataFrame(...).astype(sheet["dtypes"])`. Update the
`read`/`+table-put` mirror description so `dtypes` documents only actual pandas
dtype strings (for example `datetime64[ns]`, `float64`, `bool`, `object`), and
if you want to keep logical types like `date`/`number`, add an explicit
conversion step in the docs before calling `astype`. Make sure the guidance
around `get_cell_ranges`, `get_range_as_csv`, and the
`sheets[]`/`columns`/`data`/`dtypes` schema remains consistent.

Comment on lines +142 to +144
| `--sheets` | string + File + Stdin(复合 JSON) | optional | 建表后写入的 typed 表格协议 JSON(同 +table-put):顶层 sheets 数组,每项 `{name, start_cell?, mode?, header?, allow_overwrite?, columns:["colA","colB",...], data:[[...]], dtypes?:{colA:pandasDtype, ...}, formats?:{colA:numberFormat, ...}}`。Agents 通常用 `{**json.loads(df.to_json(orient="split")), "dtypes": df.dtypes.astype(str).to_dict()}` 一行构造。与 --values、--dataframe 互斥;新表默认子表复用为第一个子表,日期/数字类型保真。 |
| `--styles` | string + File + Stdin(复合 JSON) | optional | 建表时同时写入的视觉处理操作 JSON:顶层 `{styles:[...]}`,每项对应一个目标子表、含 `name`,并至少给 `cell_styles` / `row_sizes` / `col_sizes` / `cell_merges` 之一。`cell_styles` 用 A1 单元格 range + 扁平样式字段(字段同 +cells-set-style,含 number_format / 颜色 / 对齐 / border_styles);row/col sizes 用行/列范围 + type/size;merges 用单元格 range + 可选 merge_type。与 --sheets 搭配时 styles 数组长度/顺序/name 必须与 --sheets.sheets 对应;与 --values 搭配时只给一个 styles 项(其 name 忽略)。完整 cell_styles 字段结构跑 `+workbook-create --print-schema --flag-name styles`。 |
| `--dataframe` | string | optional | 单 sheet 类型保真表格的二进制入口,从一个 Arrow IPC 文件(Feather v2,pandas `df.to_feather()` 直接写出)读入,与 --values / --sheets 互斥。用 `@<path>` 传文件或 `-` 读二进制 stdin(同其他输入 flag 的约定)。Arrow 字节按原样读 —— 不做 TrimSpace / BOM strip,IPC magic 字节完整保留(区别于文本类输入 flag)。列类型从 Arrow schema 推导;每列的 `number_format` 可写在 Arrow Field metadata 里。建表后写入默认子表(`Sheet1` —— 直接复用,不残留空 Sheet1)。要多子表或换落点,请改用 `--sheets`。 |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

The advertised --sheets one-liner omits the required name.

This section says each item must be {name, ...}, but the sample constructor only adds dtypes. Copying it verbatim yields an invalid --sheets payload.

Suggested fix
- Agents 通常用 `{**json.loads(df.to_json(orient="split")), "dtypes": df.dtypes.astype(str).to_dict()}` 一行构造。
+ Agents 通常用 `{"name":"Sheet1", **json.loads(df.to_json(orient="split")), "dtypes": df.dtypes.astype(str).to_dict()}` 一行构造。
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
| `--sheets` | string + File + Stdin(复合 JSON) | optional | 建表后写入的 typed 表格协议 JSON(同 +table-put):顶层 sheets 数组,每项 `{name, start_cell?, mode?, header?, allow_overwrite?, columns:["colA","colB",...], data:[[...]], dtypes?:{colA:pandasDtype, ...}, formats?:{colA:numberFormat, ...}}`。Agents 通常用 `{**json.loads(df.to_json(orient="split")), "dtypes": df.dtypes.astype(str).to_dict()}` 一行构造。与 --values、--dataframe 互斥;新表默认子表复用为第一个子表,日期/数字类型保真。 |
| `--styles` | string + File + Stdin(复合 JSON) | optional | 建表时同时写入的视觉处理操作 JSON:顶层 `{styles:[...]}`,每项对应一个目标子表、含 `name`,并至少给 `cell_styles` / `row_sizes` / `col_sizes` / `cell_merges` 之一。`cell_styles` 用 A1 单元格 range + 扁平样式字段(字段同 +cells-set-style,含 number_format / 颜色 / 对齐 / border_styles);row/col sizes 用行/列范围 + type/size;merges 用单元格 range + 可选 merge_type。与 --sheets 搭配时 styles 数组长度/顺序/name 必须与 --sheets.sheets 对应;与 --values 搭配时只给一个 styles 项(其 name 忽略)。完整 cell_styles 字段结构跑 `+workbook-create --print-schema --flag-name styles`|
| `--dataframe` | string | optional | 单 sheet 类型保真表格的二进制入口,从一个 Arrow IPC 文件(Feather v2,pandas `df.to_feather()` 直接写出)读入,与 --values / --sheets 互斥。用 `@<path>` 传文件或 `-` 读二进制 stdin(同其他输入 flag 的约定)。Arrow 字节按原样读 —— 不做 TrimSpace / BOM strip,IPC magic 字节完整保留(区别于文本类输入 flag)。列类型从 Arrow schema 推导;每列的 `number_format` 可写在 Arrow Field metadata 里。建表后写入默认子表(`Sheet1` —— 直接复用,不残留空 Sheet1)。要多子表或换落点,请改用 `--sheets`|
| `--sheets` | string + File + Stdin(复合 JSON) | optional | 建表后写入的 typed 表格协议 JSON(同 +table-put):顶层 sheets 数组,每项 `{name, start_cell?, mode?, header?, allow_overwrite?, columns:["colA","colB",...], data:[[...]], dtypes?:{colA:pandasDtype, ...}, formats?:{colA:numberFormat, ...}}`。Agents 通常用 `{"name":"Sheet1", **json.loads(df.to_json(orient="split")), "dtypes": df.dtypes.astype(str).to_dict()}` 一行构造。与 --values、--dataframe 互斥;新表默认子表复用为第一个子表,日期/数字类型保真。 |
| `--styles` | string + File + Stdin(复合 JSON) | optional | 建表时同时写入的视觉处理操作 JSON:顶层 `{styles:[...]}`,每项对应一个目标子表、含 `name`,并至少给 `cell_styles` / `row_sizes` / `col_sizes` / `cell_merges` 之一。`cell_styles` 用 A1 单元格 range + 扁平样式字段(字段同 +cells-set-style,含 number_format / 颜色 / 对齐 / border_styles);row/col sizes 用行/列范围 + type/size;merges 用单元格 range + 可选 merge_type。与 --sheets 搭配时 styles 数组长度/顺序/name 必须与 --sheets.sheets 对应;与 --values 搭配时只给一个 styles 项(其 name 忽略)。完整 cell_styles 字段结构跑 `+workbook-create --print-schema --flag-name styles`|
| `--dataframe` | string | optional | 单 sheet 类型保真表格的二进制入口,从一个 Arrow IPC 文件(Feather v2,pandas `df.to_feather()` 直接写出)读入,与 --values / --sheets 互斥。用 `@<path>` 传文件或 `-` 读二进制 stdin(同其他输入 flag 的约定)。Arrow 字节按原样读 —— 不做 TrimSpace / BOM strip,IPC magic 字节完整保留(区别于文本类输入 flag)。列类型从 Arrow schema 推导;每列的 `number_format` 可写在 Arrow Field metadata 里。建表后写入默认子表(`Sheet1` —— 直接复用,不残留空 Sheet1)。要多子表或换落点,请改用 `--sheets`|
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/lark-sheets/references/lark-sheets-workbook.md` around lines 142 -
144, The `--sheets` example is missing the required `name` field for each sheet
item, so the documented one-liner currently produces an invalid payload. Update
the `--sheets` documentation in the workbook reference so the example
construction includes `name` for each sheet object alongside `columns`, `data`,
and `dtypes`, matching the schema described for `+table-put` and the `--sheets`
contract.

Comment thread skills/lark-sheets/SKILL.md Outdated
Comment on lines +41 to +59
| 读数据(纯值 / CSV) | `+csv-get`(范围用 `--range`) | |
| 读值 + 公式 / 样式 / 批注 | `+cells-get --include value,formula,style,comment,data_validation` | `--with-styles`、`--with-merges`、`--include-merged-cells` |
| 写纯文本值(整块 CSV 平铺,列里没有需保留的数值 / 日期语义) | `+csv-put`(定位用 `--start-cell`,单个左上角锚点格;也接受 `--range` 别名,区间自动取左上角) | — |
| 写带类型的数据到**已有**表(列里有数字 / 金额 / 百分比 / 日期 / 计数,要可排序 / 求和 / 入图表 / 透视) | `+table-put --sheets` 完整 payload `{"sheets":[{...}]}`(列名走 `columns`、二维数据走 `data`、列 pandas dtype 走 `dtypes`、列展示格式走 `formats`;来源不限 DataFrame——Counter / dict / list 同理,详见 write-cells) | 在本地把数字拼成 `"$1,234"` / `"30.5%"` 字符串再 `+csv-put`(会落成文本、丢失计算能力) |
| 写带类型的数据到**已有**表(列里有数字 / 金额 / 百分比 / 日期 / 计数,要可排序 / 求和 / 入图表 / 透视) | `+table-put`(列显式声明 `type` + `format`,类型保真;来源不限 DataFrame——Counter / dict / list 同理,详见 write-cells) | 在本地把数字拼成 `"$1,234"` / `"30.5%"` 字符串再 `+csv-put`(会落成文本、丢失计算能力) |
| **新建**电子表格并写带类型的数据(类型保真需求同上,但目标表还不存在) | `+workbook-create --sheets`(协议与 `+table-put` 同构、一步建表 + typed 写入,无需先建空表再 `+table-put`;date / number 不丢,详见 workbook) | 用 `--values` 灌日期 / 数字(会落成文本、丢类型) |
| 写值 / 公式 / 样式 | `+cells-set`(定位用 `--range`) | — |
| 插图:图片**绑定到某条记录**、随行走(凭证 / 证件照 / 商品图 / 头像 / 二维码 / 每行配图) | `+cells-set-image`(单格 `--range`,嵌入单元格内) | — |
| 插图:**自由摆放、不绑数据**的装饰 / 标识(logo / 水印 / 封面大图 / banner) | `+float-image-create`(浮动图片,自由定位 + 尺寸 + 层级) | — |
| 查找单元格 | `+cells-search`(关键字用 `--find`) | `+cells-find`、`+find`、`--query` |
| 查找并替换 | `+cells-replace` | — |
| 看子表结构(合并 / 行高列宽 / 冻结 / 隐藏) | `+sheet-info` | `+sheet-get`、`+structure-get`、`+sheet-structure-get` |
| 看工作簿 / 子表清单 | `+workbook-info` | `+sheet-list`、`+workbook-get`、`+workbook-list` |
| 看工作簿 / 子表清单 | `+workbook-info` | — |
| 复核某次(AI)编辑改了什么 / 取两个版本间的变更 | `+changeset-get --start-revision <编辑前版本>`(省略 `--end-revision` 取到最新;版本差 ≤ 20) | — |
| 导出 xlsx / 单表 csv | `+workbook-export` | — |
| 导入本地 xlsx/xls/csv 文件为飞书电子表格 | `+workbook-import --file ./x.xlsx`(本地表格文件 → 飞书电子表格的正解;仅要导成多维表格 bitable 时才用 `drive +import --type bitable`) | `drive +import`(导电子表格时绕了 drive 通道、还要多给 `--type`,应直接用 `+workbook-import`)、把 .xlsx 在本地读成数据再 `+workbook-create` 重灌 |
| 导入本地 xlsx/xls/csv 文件为新表格 | `+workbook-import --file ./x.xlsx`(仅导入为电子表格;要导成多维表格走 `drive +import --type bitable`) | 把 .xlsx 在本地读成数据再 `+workbook-create` 重灌(丢原格式、低效) |
| 清除内容 / 格式 | `+cells-clear`(范围维度用 `--scope`,取值 content / formats / all) | `--type` |
| 批量清除多区域 | `+cells-batch-clear`(`--scope`) | `--target` |
| 调整列宽 / 行高 | `+cols-resize` / `+rows-resize`(行、列是两个独立命令) | `--dimension`(无此 flag) |
| 分组汇总 / 透视 | `+pivot-create`(默认不传落点 flag → 自动新建子表,零覆盖) | 用 SUMIF / 本地脚本拼一张假透视表 |

> ⚠️ **两种图片别选错**:图若**绑定某条记录、要随行排序 / 筛选 / 增删**(凭证 / 证件照 / 每行配图,话里带「对应 / 每行 / 这列」等绑定词)→ 单元格图片 `+cells-set-image`;只是自由摆放的装饰(logo / 水印 / 封面)→ 浮动图片 `+float-image-create`。别因「浮动图更好控制 / 更熟」默认选浮动图。
> ⚠️ **纯文本还是数值语义**:要写的列里有数字 / 金额 / 百分比 / 日期 / 计数 → `+table-put`(写入已有表;外层 `{"sheets":[...]}` 包裹、列 pandas dtype 用 `dtypes`、展示格式用 `formats`,保留排序 / 求和 / 图表 / 透视能力;**目标表还不存在就用 `+workbook-create --sheets`**,同 typed 协议、一步建表 + 写入,别先建空表再 `+table-put`);只有纯文本才用 `+csv-put`。两者写完显示可以完全相同,但 `+csv-put` 落的是文本、不能参与计算——别把数值在本地拼成带 `$` / `%` 的字符串再走 `+csv-put`。
> ⚠️ **纯文本还是数值语义**:要写的列里有数字 / 金额 / 百分比 / 日期 / 计数 → `+table-put`(写入已有表;声明 `type` + `format`,保留排序 / 求和 / 图表 / 透视能力;**目标表还不存在就用 `+workbook-create --sheets`**,同 typed 协议、一步建表 + 写入,别先建空表再 `+table-put`);只有纯文本才用 `+csv-put`。两者写完显示可以完全相同,但 `+csv-put` 落的是文本、不能参与计算——别把数值在本地拼成带 `$` / `%` 的字符串再走 `+csv-put`。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if image-related shortcuts still exist in flag definitions
rg -n 'image' shortcuts/sheets/data/flag-defs.json | head -10
# Check SKILL.md for any image references
rg -n 'image' skills/lark-sheets/SKILL.md

Repository: larksuite/cli

Length of output: 1683


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- SKILL.md around the quick-reference table ---'
sed -n '35,65p' skills/lark-sheets/SKILL.md | cat -n

echo
echo '--- image-related shortcut entries in flag-defs.json ---'
python3 - <<'PY'
import json
from pathlib import Path

path = Path('shortcuts/sheets/data/flag-defs.json')
data = json.loads(path.read_text(encoding='utf-8'))
for k, v in data.items():
    text = json.dumps(v, ensure_ascii=False)
    if 'image' in k.lower() or 'image' in text.lower():
        print(k)
        if isinstance(v, dict):
            for kk in ('name', 'desc'):
                if kk in v:
                    print(f'  {kk}: {v[kk]}')
PY

Repository: larksuite/cli

Length of output: 3258


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- image mentions in skills/lark-sheets/SKILL.md ---'
rg -n 'cells-set-image|float-image|image' skills/lark-sheets/SKILL.md

echo
echo '--- image-related reference docs listed by SKILL.md ---'
sed -n '70,100p' skills/lark-sheets/SKILL.md | cat -n

echo
echo '--- image-related shortcut definitions in flag-defs.json (names only) ---'
python3 - <<'PY'
import json
from pathlib import Path
data = json.loads(Path('shortcuts/sheets/data/flag-defs.json').read_text(encoding='utf-8'))
for key in ['+cells-set-image', '+float-image-list', '+float-image-create', '+float-image-update', '+float-image-delete']:
    v = data.get(key)
    print(key, 'FOUND' if v else 'MISSING')
    if v:
        print(' ', v.get('name'))
        print(' ', v.get('desc'))
PY

Repository: larksuite/cli

Length of output: 5891


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- lines in SKILL.md that point to image-specific docs ---'
sed -n '80,96p' skills/lark-sheets/SKILL.md | cat -n

echo
echo '--- relevant image docs if present ---'
git ls-files 'skills/lark-sheets/references/*image*' 'skills/lark-sheets/references/*cells*' | sed -n '1,20p'

Repository: larksuite/cli

Length of output: 3654


Restore the image shortcuts in the quick-reference table. +cells-set-image and the float-image commands still exist, and this page already points to their dedicated docs; leaving them out makes the shortcuts harder to discover for no functional gain.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/lark-sheets/SKILL.md` around lines 41 - 59, The quick-reference table
in SKILL.md is missing the image-related shortcuts, so restore the entries for
cells-set-image and the float-image commands alongside the existing spreadsheet
actions. Update the table and the surrounding note so these commands remain
discoverable, and make sure the wording points readers to the dedicated image
docs without changing the rest of the command guidance.

@wenzhuozhen
wenzhuozhen changed the base branch from main to feat/lark-sheets-develop June 29, 2026 05:29
@wenzhuozhen
wenzhuozhen force-pushed the feat/sheets-formula-verify branch from 954042c to 08e6011 Compare June 29, 2026 06:43
@github-actions github-actions Bot added size/L Large or sensitive change across domains or core paths and removed size/XL Architecture-level or global-impact change labels Jun 29, 2026
@wenzhuozhen
wenzhuozhen force-pushed the feat/sheets-formula-verify branch from c3734ad to 5f7def5 Compare June 29, 2026 08:25
Wraps the new verify_formula read tool in a CLI shortcut so AI agents
can run write-then-zero-error verification end-to-end:

  lark-cli sheets +formula-verify --url <url>

Scans formulas + cell error states across one or more sub-sheets and
returns a JSON status report (success / errors_found / partial).
Aggregates all 7 Excel error categories (#REF! / #DIV/0! / #VALUE! /
#NAME? / #NULL! / #NUM! / #N/A) plus compile failures into one
envelope; the tool always reports every error in the scan window —
callers needing a subset filter the returned error_summary
client-side. The internal scan cap is hidden from callers; when it
trips the response sets has_more=true and includes a warning_message
asking the caller to narrow --range / split --sheet-id and continue.

Flags follow the lark-sheets convention:
- --url / --spreadsheet-token (XOR public)
- --sheet-id / --sheet-name (repeat or comma-separate; mutually
  exclusive)
- --range (repeatable A1)
- --max-locations (default 20)
- --exit-on-error (CI gate: status='errors_found' → exit 2 with
  failed_precondition)

Generated artifacts (skills/lark-sheets/{SKILL.md, references/
lark-sheets-formula-verify.md}, shortcuts/sheets/data/flag-defs.json,
shortcuts/sheets/flag_defs_gen.go) are mirrored from sheet-skill-spec
generated/ via 'npm run sync:cli'. shortcuts.go registers
FormulaVerify alongside the other lark_sheet_formula_verify skill
shortcuts so +formula-verify is discoverable from
'lark-cli sheets --help'.

Tests cover the dry-run wire shape (excel_id + sheet_ids/sheet_names/
ranges/max_locations packing), the read scope (invoke_read URL), the
mutually-exclusive selector validation, the non-positive
--max-locations guard, and the --exit-on-error status matrix
(success/partial/errors_found/unknown).
@wenzhuozhen
wenzhuozhen force-pushed the feat/sheets-formula-verify branch from 5f7def5 to 3e3f1bb Compare June 29, 2026 09:10
@wenzhuozhen
wenzhuozhen merged commit 4ace5ca into feat/lark-sheets-develop Jun 29, 2026
5 checks passed
@wenzhuozhen
wenzhuozhen deleted the feat/sheets-formula-verify branch June 29, 2026 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain/ccm PR touches the ccm domain size/L Large or sensitive change across domains or core paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants