Skip to content

feat: Product CLI v4 no-meego#759

Merged
yballul-bytedance merged 1 commit into
mainfrom
feat/cli_v4_product
May 20, 2026
Merged

feat: Product CLI v4 no-meego#759
yballul-bytedance merged 1 commit into
mainfrom
feat/cli_v4_product

Conversation

@yballul-bytedance

@yballul-bytedance yballul-bytedance commented May 6, 2026

Copy link
Copy Markdown
Collaborator

Change-Id: If08f236c8ae351f92683f2b861cc999eb6f1d22d

Summary

feat(base): add +form-detail and +form-submit shortcuts for Base form operations

Add two new Lark Base form shortcuts: +form-detail to retrieve form details by share token, and +form-submit to fill and submit form data with support for parallel
attachment uploads.

Changes

• Change 1: Add +form-detail shortcut (shortcuts/base/base_form_detail.go) — queries form detail via POST /open-apis/base/v3/bases/tables/forms/detail using a share
token.
• Change 2: Add +form-submit shortcut (shortcuts/base/base_form_submit.go) — submits form data with field values and optional attachments; supports concurrent file upload
(up to 5 goroutines) to Base Drive Media, with full validation of JSON input, file existence, size limits (2GB), and path deduplication across fields.
• Change 3: Register both new shortcuts in shortcuts/base/shortcuts.go and update the lark-base SKILL.md reference docs (lark-base-form-detail.md, lark-base-form-
submit.md, lark-base-form.md).
• Change 4: Add dry-run E2E test for +form-detail (tests/cli_e2e/base/base_form_detail_dryrun_test.go) and unit tests for dry-run ops
(shortcuts/base/base_dryrun_ops_test.go).

Test Plan

• Unit tests pass
• Manual local verification confirms the lark base +form-detail and lark base +form-submit commands work as expected

Related Issues

None

Summary by CodeRabbit

  • New Features

    • Add commands to fetch shared form details and submit forms via share links, supporting fields and attachments with concurrent uploads.
  • Tests

    • Added dry-run and execution tests for form-detail and form-submit flows, including payload validation and attachment handling.
  • Documentation

    • New and updated docs describing form-detail, form-submit JSON payloads, attachment upload workflow, and token requirements.
  • Chores

    • Ignore local env script in .gitignore.

@github-actions github-actions Bot added domain/base PR touches the base domain size/L Large or sensitive change across domains or core paths labels May 6, 2026
Comment thread shortcuts/base/base_dryrun_ops_test.go Outdated
Comment thread shortcuts/base/base_dryrun_ops_test.go Outdated
Comment thread shortcuts/base/base_dryrun_ops_test.go Outdated
@coderabbitai

coderabbitai Bot commented May 6, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds two new shortcuts: +form-detail (share-link form metadata read) and +form-submit (share-mode form submission with optional local-file attachments). Implements JSON validation/parsing, dry-run plan generation, bounded concurrent uploads, execution logic, tests, docs, and a minor .gitignore update.

Changes

Form Submission Feature

Layer / File(s) Summary
Shortcut defs & registration
shortcuts/base/base_form_detail.go, shortcuts/base/base_form_submit.go, shortcuts/base/shortcuts.go, shortcuts/base/base_shortcuts_test.go
Adds BaseFormDetail and BaseFormSubmit, registers BaseFormSubmit in Shortcuts(), and updates catalog test expectations.
Validation & Parsing
shortcuts/base/base_form_submit.go
validateFormSubmit enforces presence/shape of fields or attachments and --base-token when needed; parseFormSubmitJSON extracts fields and normalized attachment map.
Dry-run plan
shortcuts/base/base_form_submit.go
dryRunFormSubmit produces a dry-run API plan with per-attachment upload steps (when attachments exist) followed by the final submit.
Request body assembly
shortcuts/base/base_form_submit.go
buildFormSubmitBody assembles the submission request body with share_token and content.
Execution & uploads
shortcuts/base/base_form_submit.go
collectUniquePaths, uploadAttachmentsParallel, and uploadSingleAttachment de-duplicate paths and perform bounded-parallel uploads; executeFormSubmit merges upload tokens back into per-field cells and calls the submit API.
Tests / e2e dry-run
tests/..., shortcuts/base/base_dryrun_ops_test.go, tests/cli_e2e/base/base_form_detail_dryrun_test.go
Adds TestBaseFormDetailDryRun, missing-share-token test, adds TestDryRunFormSubmit, and updates dry-run expectations and shortcuts catalog test.
Documentation
skills/lark-base/SKILL.md, skills/lark-base/references/*
Adds SKILL navigation entries and full reference docs for +form-detail and +form-submit, with examples and JSON/attachment guidance.
Repo housekeeping
.gitignore
Adds lark-env.sh to .gitignore.

Sequence Diagram

sequenceDiagram
    participant User
    participant Parser
    participant Validator
    participant AttachmentCollector
    participant MediaAPI as Base Drive
    participant SubmitAPI as Form Submit API

    User->>Parser: Provide JSON (fields + attachments)
    Parser->>Validator: Parse & validate structure
    Validator->>AttachmentCollector: Return parsed fields & attachments
    AttachmentCollector->>AttachmentCollector: Collect & deduplicate paths
    par Parallel Upload
        AttachmentCollector->>MediaAPI: Upload attachment 1
        MediaAPI-->>AttachmentCollector: file_token 1
        AttachmentCollector->>MediaAPI: Upload attachment 2
        MediaAPI-->>AttachmentCollector: file_token 2
        AttachmentCollector->>MediaAPI: Upload attachment N
        MediaAPI-->>AttachmentCollector: file_token N
    end
    AttachmentCollector->>SubmitAPI: Merge tokens into fields & submit
    SubmitAPI-->>User: Form submission result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • larksuite/cli#466: Modifies the base shortcuts catalog (shortcuts/base/shortcuts.go) and its test (shortcuts/base/base_shortcuts_test.go) to append new shortcut entries and adjust TestShortcutsCatalog expectations.

Suggested reviewers

  • zhouyue-bytedance
  • zgz2048

Poem

🐰 I hop through JSON, fields in paw,
I send attachments with a bounded law,
Tokens weave back into every cell,
The submit hums — the form replies well,
A rabbit’s tiny CLI hurrah!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The PR title 'feat: Product CLI v4 no-meego' is vague and does not clearly describe the primary changes (adding +form-detail and +form-submit shortcuts). Consider updating the title to be more specific about the main feature, such as 'feat: Add +form-detail and +form-submit Base form shortcuts' to better reflect the actual changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The PR description follows the template structure with Summary, Changes, Test Plan, and Related Issues sections; all key changes are documented clearly.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/cli_v4_product

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 and usage tips.

@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

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

🧩 Skill update

npx skills add larksuite/cli#feat/cli_v4_product -y -g

@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

🤖 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 `@shortcuts/base/base_dryrun_ops_test.go`:
- Around line 274-290: TestDryRunFormSubmit contains assertions for an
unsupported table/view mode: remove the expectations for `"table_id":"tbl_1"`
and `"view_id":"viw_1"` (and, if desired, stop passing "table-id" and "view-id"
in the newBaseTestRuntime map) so the test only validates the share-token-only
contract; update the call using newBaseTestRuntime, dryRunFormSubmit, and
assertDryRunContains to no longer assert or rely on table_id/view_id payload
fields.

In `@shortcuts/base/base_form_submit.go`:
- Around line 138-141: The dry-run builder currently appends the same POST
operation twice, causing duplicate submit steps in the dry-run output; update
the dry-run construction (the variable dry created via
common.NewDryRunAPI().Desc(...)) to include only a single
POST("/open-apis/base/v3/bases/tables/forms/submit") call (remove the redundant
POST call later in the chain/flow), ensuring the submit endpoint is added once
in NewDryRunAPI → Desc → POST usage so the dry-run reflects a single submit
operation.
- Around line 234-236: The code in base_form_submit.go currently marshals and
prints the entire submission payload via fmt.Fprintf(runtime.IO().ErrOut, ...)
(bodyJSON) which can expose sensitive user data; remove that unconditional print
and either (a) delete the fmt.Fprintf call, or (b) wrap it behind a
debug/verbose flag or use a logger debug method and log a redacted/sanitized
version of the body instead; ensure the call site around baseV3Call and the
variable bodyJSON are updated so no sensitive data is written to stderr by
default.

In `@skills/lark-base/references/lark-base-form-submit.md`:
- Line 57: The markdown in references/lark-base-form-submit.md uses invalid
cross-links like `references/lark-base-cell-value.md` while already inside the
references/ directory; update the three occurrences (the link text to
lark-base-cell-value.md found around lines 57, 97, and 146-148) to correct
same-directory relative links (e.g., `./lark-base-cell-value.md` or
`lark-base-cell-value.md`), and scan the file for any other links prefixed with
`references/` and change them to same-dir relative paths.
- Line 76: Remove the blank line inside the blockquote that contains the shared
URL (the blockquote currently wrapping the form share link) so there are no
empty lines inside the > quoted paragraph, and update the fenced code block(s)
that contain the URL to include a language tag (use ```text) — apply the same
fix to the other fenced code block(s) with the URL later in the document so all
fenced blocks include the language tag and no blockquotes contain blank lines.
🪄 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: e9d85c23-0008-4a0a-adaf-626dc6949d21

📥 Commits

Reviewing files that changed from the base of the PR and between 15ae1fa and 7e2ceb6.

📒 Files selected for processing (7)
  • lark-env.sh
  • shortcuts/base/base_dryrun_ops_test.go
  • shortcuts/base/base_form_submit.go
  • shortcuts/base/base_shortcuts_test.go
  • shortcuts/base/shortcuts.go
  • skills/lark-base/SKILL.md
  • skills/lark-base/references/lark-base-form-submit.md

Comment thread shortcuts/base/base_dryrun_ops_test.go Outdated
Comment thread shortcuts/base/base_form_submit.go
Comment thread shortcuts/base/base_form_submit.go Outdated
Comment thread skills/lark-base/references/lark-base-form-submit.md Outdated
Comment thread skills/lark-base/references/lark-base-form-submit.md
Comment thread shortcuts/base/base_dryrun_ops_test.go Outdated
Comment thread shortcuts/base/base_dryrun_ops_test.go Outdated
Comment thread shortcuts/base/base_dryrun_ops_test.go Outdated
@yballul-bytedance yballul-bytedance changed the title feat: Product CLI 4期 no-meego feat: Product CLI v4 no-meego May 6, 2026

@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.

♻️ Duplicate comments (6)
shortcuts/base/base_form_submit.go (2)

233-236: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Full submission body (potential PII) still unconditionally logged to stderr.

Lines 234–235 marshal and print the entire request body — which includes user-supplied form field values — to stderr on every execution. This also makes encoding/json the sole consumer of that import; removing the log statement eliminates the unused import.

🔧 Proposed fix
 	body := buildFormSubmitBody(runtime, fields)
-	bodyJSON, _ := json.Marshal(body)
-	fmt.Fprintf(runtime.IO().ErrOut, "Final body: %s\n", bodyJSON)
 	data, err := baseV3Call(runtime, "POST",

Also remove "encoding/json" from the import block if it is no longer used elsewhere in the file.

🤖 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/base/base_form_submit.go` around lines 233 - 236, Remove the
unconditional logging of the full marshaled form body (which may contain PII) by
deleting the json.Marshal call and the fmt.Fprintf(runtime.IO().ErrOut, "Final
body: %s\n", bodyJSON) line in the code path that builds the submission (the
buildFormSubmitBody -> body variable before baseV3Call("POST", ...)). If you
still need debug output, log a redacted or summarized version of the body
instead. After removing the marshal/print, also remove the "encoding/json"
import from the file if it is no longer referenced anywhere in this file.

138-161: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Duplicate POST /form/submit still present in dry-run, in wrong position.

The first POST at line 140 appears before the upload operations, making the dry-run output logically incorrect (submit shown before uploads) and duplicating the final submit entry at lines 158–161.

🔧 Proposed fix
 	if len(attachmentMap) > 0 {
 		dry := common.NewDryRunAPI().
-			Desc("Form submit with attachments: upload local files per field → merge with fields → submit").
-			POST("/open-apis/base/v3/bases/tables/forms/submit")
+			Desc("Form submit with attachments: upload local files per field → merge with fields → submit")
🤖 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/base/base_form_submit.go` around lines 138 - 161, The dry-run is
creating a premature POST("/open-apis/base/v3/bases/tables/forms/submit") before
the upload POSTs, causing a duplicate and wrong ordering; change the initial dry
construction so it does not chain the submit POST (e.g., use
common.NewDryRunAPI().Desc("Form submit with attachments: upload local files per
field → merge with fields → submit") to create dry), then keep the loop that
appends drive upload POSTs for each attachment, and finally chain the single
POST("/open-apis/base/v3/bases/tables/forms/submit").Body(body).Desc(...) after
buildFormSubmitBody(runtime, fields); ensure only the final submit POST exists
and is appended after the uploads.
skills/lark-base/references/lark-base-form-submit.md (2)

57-57: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Broken relative links still present.

All three occurrences still use a references/ prefix from inside the references/ directory, making the links invalid.

🔧 Proposed fix
-`fields` 中的单元格值写法与 [`lark-base-cell-value.md`](references/lark-base-cell-value.md) 完全对齐,填写前应先阅读该文档了解各类型的构造规则:
+`fields` 中的单元格值写法与 [`lark-base-cell-value.md`](lark-base-cell-value.md) 完全对齐,填写前应先阅读该文档了解各类型的构造规则:

-> 与 [`lark-base-cell-value.md`](references/lark-base-cell-value.md) 中 Record 场景的附件写法不同:
+> 与 [`lark-base-cell-value.md`](lark-base-cell-value.md) 中 Record 场景的附件写法不同:

-- [lark-base-form](references/lark-base-form.md) — 表单管理总览
-- [lark-base-record-upload-attachment](references/lark-base-record-upload-attachment.md) — 给已有记录上传附件(不同场景)
+- [lark-base-form](lark-base-form.md) — 表单管理总览
+- [lark-base-record-upload-attachment](lark-base-record-upload-attachment.md) — 给已有记录上传附件(不同场景)

Also applies to: 97-97, 146-148

🤖 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-base/references/lark-base-form-submit.md` at line 57, The
markdown uses broken relative links that include an unnecessary "references/"
prefix; in skills/lark-base/references/lark-base-form-submit.md locate the three
occurrences referencing `references/lark-base-cell-value.md` (around the current
occurrence at line ~57 and also near lines ~97 and ~146-148) and fix them to use
the correct relative target (remove the "references/" prefix so the link points
to `lark-base-cell-value.md` or otherwise adjust to the correct relative path)
so the links resolve correctly from this references/ directory.

76-77: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

MD028 and MD040 warnings still unresolved.

Line 76 has a blank line inside a blockquote (MD028); Line 103 opens a fenced code block without a language tag (MD040).

🔧 Proposed fix
 > **注意:附件类型字段不要写在 `fields` 里。** `fields` 中不包含附件,附件有独立的填写方式,见下方「attachments(附件上传)」章节。
-
 > 自动编号、公式、创建/修改人、创建/修改时间等系统字段会自动填入,无需手动传入。

-```
+```text
 https://bitable-test.feishu-boe.cn/share/base/form/shrbcvST8eZy0vk8zjVZ1CAXNye
</details>


Also applies to: 103-105

<details>
<summary>🤖 Prompt for AI Agents</summary>

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-base/references/lark-base-form-submit.md around lines 76 - 77,
Remove the stray blank line inside the blockquote that contains
"自动编号、公式、创建/修改人、创建/修改时间等系统字段会自动填入,无需手动传入。" to resolve MD028, and add a language
tag to the fenced code block containing the URL
"https://bitable-test.feishu-boe.cn/share/base/form/shrbcvST8eZy0vk8zjVZ1CAXNye"
(e.g., change totext) to resolve MD040; apply the fenced-code fix for
the same block referenced around lines 103–105 as well.


</details>

</blockquote></details>
<details>
<summary>shortcuts/base/base_dryrun_ops_test.go (2)</summary><blockquote>

`274-290`: _⚠️ Potential issue_ | _🔴 Critical_ | _⚡ Quick win_

**Test will fail: `"table_id"` and `"view_id"` are never produced by `buildFormSubmitBody`.**

`tableModeRT` does not register a `share-token` flag, and `buildFormSubmitBody` only emits `{"share_token":"","content":{...}}` — it never reads `table-id` or `view-id`. The assertions on lines 287–288 (`"table_id":"tbl_1"` and `"view_id":"viw_1"`) will not match, causing `t.Fatalf` to fire. The shortcut itself (`BaseFormSubmit`) also has no `--table-id`/`--view-id` flags, so this mode is unsupported.



<details>
<summary>🔧 Proposed fix – remove the unsupported test case</summary>

```diff
-	// fields-only mode (table-id + view-id)
-	tableModeRT := newBaseTestRuntime(
-		map[string]string{
-			"base-token": "app_x",
-			"table-id":   "tbl_1",
-			"view-id":    "viw_1",
-			"json":       `{"fields":{"Name":"Alice","Score":95}}`,
-		},
-		nil, nil,
-	)
-	assertDryRunContains(t,
-		dryRunFormSubmit(ctx, tableModeRT),
-		"POST /open-apis/base/v3/bases/tables/forms/submit",
-		`"table_id":"tbl_1"`,
-		`"view_id":"viw_1"`,
-		`"Name":"Alice"`,
-		`"Score":95`)
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
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/base/base_dryrun_ops_test.go` around lines 274 - 290, The test is
asserting table_id/view_id but buildFormSubmitBody (and BaseFormSubmit) never
emit or read table-id/view-id; remove the unsupported "fields-only mode
(table-id + view-id)" case in the test (the tableModeRT setup and its
assertDryRunContains call) or alternatively update newBaseTestRuntime to
register a share-token flag and modify buildFormSubmitBody/BaseFormSubmit to
actually read and emit table_id/view_id; simplest fix: delete the tableModeRT
block and its assertions so tests only cover supported modes (keep other cases
calling dryRunFormSubmit, assertDryRunContains, and the fields/assertions that
buildFormSubmitBody actually produces).
```

</details>

---

`262-262`: _⚠️ Potential issue_ | _🟠 Major_ | _⚡ Quick win_

**Hardcoded share token flagged by Gitleaks as a generic API key.**

`shrcnkbanhog5cHymqg2VHp5Tth` appears at three locations (Lines 262, 270, and 296). If this is a real token for an existing form, it should be rotated and replaced with an obviously synthetic value (e.g. `shrcTEST_FAKE_TOKEN_NOT_REAL`) or added to `.gitleaksignore` with a justification comment if it is confirmed unreachable.





Also applies to: 270-270, 296-296

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
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/base/base_dryrun_ops_test.go` at line 262, Replace the hardcoded
share token string "shrcnkbanhog5cHymqg2VHp5Tth" in the test data with a clearly
synthetic value (e.g. "shrcTEST_FAKE_TOKEN_NOT_REAL") or move it to a test
fixture constant so all occurrences are updated; locate the literal in
shortcuts/base/base_dryrun_ops_test.go (the map/struct field named "share-token"
used in the tests) and update the three occurrences (lines shown in the review)
to use the synthetic constant or add the token to .gitleaksignore with a
justification comment if the token is truly unreachable. Ensure tests reference
the new constant (e.g., SHARE_TOKEN_TEST) to avoid duplicate literals.
```

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

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

Duplicate comments:
In @shortcuts/base/base_dryrun_ops_test.go:

  • Around line 274-290: The test is asserting table_id/view_id but
    buildFormSubmitBody (and BaseFormSubmit) never emit or read table-id/view-id;
    remove the unsupported "fields-only mode (table-id + view-id)" case in the test
    (the tableModeRT setup and its assertDryRunContains call) or alternatively
    update newBaseTestRuntime to register a share-token flag and modify
    buildFormSubmitBody/BaseFormSubmit to actually read and emit table_id/view_id;
    simplest fix: delete the tableModeRT block and its assertions so tests only
    cover supported modes (keep other cases calling dryRunFormSubmit,
    assertDryRunContains, and the fields/assertions that buildFormSubmitBody
    actually produces).
  • Line 262: Replace the hardcoded share token string
    "shrcnkbanhog5cHymqg2VHp5Tth" in the test data with a clearly synthetic value
    (e.g. "shrcTEST_FAKE_TOKEN_NOT_REAL") or move it to a test fixture constant so
    all occurrences are updated; locate the literal in
    shortcuts/base/base_dryrun_ops_test.go (the map/struct field named "share-token"
    used in the tests) and update the three occurrences (lines shown in the review)
    to use the synthetic constant or add the token to .gitleaksignore with a
    justification comment if the token is truly unreachable. Ensure tests reference
    the new constant (e.g., SHARE_TOKEN_TEST) to avoid duplicate literals.

In @shortcuts/base/base_form_submit.go:

  • Around line 233-236: Remove the unconditional logging of the full marshaled
    form body (which may contain PII) by deleting the json.Marshal call and the
    fmt.Fprintf(runtime.IO().ErrOut, "Final body: %s\n", bodyJSON) line in the code
    path that builds the submission (the buildFormSubmitBody -> body variable before
    baseV3Call("POST", ...)). If you still need debug output, log a redacted or
    summarized version of the body instead. After removing the marshal/print, also
    remove the "encoding/json" import from the file if it is no longer referenced
    anywhere in this file.
  • Around line 138-161: The dry-run is creating a premature
    POST("/open-apis/base/v3/bases/tables/forms/submit") before the upload POSTs,
    causing a duplicate and wrong ordering; change the initial dry construction so
    it does not chain the submit POST (e.g., use common.NewDryRunAPI().Desc("Form
    submit with attachments: upload local files per field → merge with fields →
    submit") to create dry), then keep the loop that appends drive upload POSTs for
    each attachment, and finally chain the single
    POST("/open-apis/base/v3/bases/tables/forms/submit").Body(body).Desc(...) after
    buildFormSubmitBody(runtime, fields); ensure only the final submit POST exists
    and is appended after the uploads.

In @skills/lark-base/references/lark-base-form-submit.md:

  • Line 57: The markdown uses broken relative links that include an unnecessary
    "references/" prefix; in skills/lark-base/references/lark-base-form-submit.md
    locate the three occurrences referencing references/lark-base-cell-value.md
    (around the current occurrence at line ~57 and also near lines ~97 and ~146-148)
    and fix them to use the correct relative target (remove the "references/" prefix
    so the link points to lark-base-cell-value.md or otherwise adjust to the
    correct relative path) so the links resolve correctly from this references/
    directory.
  • Around line 76-77: Remove the stray blank line inside the blockquote that
    contains "自动编号、公式、创建/修改人、创建/修改时间等系统字段会自动填入,无需手动传入。" to resolve MD028, and add a
    language tag to the fenced code block containing the URL
    "https://bitable-test.feishu-boe.cn/share/base/form/shrbcvST8eZy0vk8zjVZ1CAXNye"
    (e.g., change totext) to resolve MD040; apply the fenced-code fix for
    the same block referenced around lines 103–105 as well.

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: defaults

**Review profile**: CHILL

**Plan**: Pro

**Run ID**: `75664d00-9fa9-4e0c-b28c-67fe50b5a832`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 7e2ceb633487f0d0f7bbb931543f19cea57b4e5e and d037e584285e2ff5ceb8e01ad5779797b83aad3f.

</details>

<details>
<summary>📒 Files selected for processing (6)</summary>

* `shortcuts/base/base_dryrun_ops_test.go`
* `shortcuts/base/base_form_submit.go`
* `shortcuts/base/base_shortcuts_test.go`
* `shortcuts/base/shortcuts.go`
* `skills/lark-base/SKILL.md`
* `skills/lark-base/references/lark-base-form-submit.md`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment thread skills/lark-base/references/lark-base-form-submit.md
Comment thread form.md Outdated
Comment thread skills/lark-base/references/lark-base-form-detail.md Outdated
Comment thread tests/cli_e2e/base/base_form_detail_dryrun_test.go Outdated
Comment thread shortcuts/base/base_dryrun_ops_test.go Outdated
Comment thread shortcuts/base/base_dryrun_ops_test.go Outdated
Comment thread shortcuts/base/base_dryrun_ops_test.go Outdated
Comment thread tests/cli_e2e/base/base_form_detail_dryrun_test.go Outdated
Comment thread shortcuts/base/base_dryrun_ops_test.go Outdated
Comment thread shortcuts/base/base_dryrun_ops_test.go Outdated
Comment thread shortcuts/base/base_dryrun_ops_test.go Outdated
Comment thread skills/lark-base/references/lark-base-form-detail.md Outdated

@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: 1

♻️ Duplicate comments (5)
shortcuts/base/base_form_submit.go (2)

233-238: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid printing the full submission payload to stderr by default.

Lines 234–235 still marshal the entire request body (including user-provided field content and any merged attachment metadata) and write it to ErrOut unconditionally. This leaks user data into terminal/CI logs. Either remove the print, gate it behind a verbose/debug flag, or log a redacted summary (field names + counts only).

🛡️ Proposed fix
 	body := buildFormSubmitBody(runtime, fields)
-	bodyJSON, _ := json.Marshal(body)
-	fmt.Fprintf(runtime.IO().ErrOut, "Final body: %s\n", bodyJSON)
 	data, err := baseV3Call(runtime, "POST",
 		baseV3Path("bases", "tables", "forms", "submit"),
 		nil, body)

After removing this, the encoding/json import on Line 8 also becomes unused and should be dropped.

🤖 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/base/base_form_submit.go` around lines 233 - 238, The code is
printing the full form submission body to stderr (via
fmt.Fprintf(runtime.IO().ErrOut, ...)) which can leak user data; remove that
unconditional debug print (the fmt.Fprintf call and the bodyJSON marshaling
using json.Marshal) or gate it behind an explicit debug/verbose flag that must
be checked before marshaling/logging; update the buildFormSubmitBody/baseV3Call
usage to pass body directly without logging and remove the now-unused
encoding/json import if you delete the marshal/logging code.

137-161: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Duplicate submit POST still present in attachment dry-run path.

Line 140 and Line 158 both append POST /open-apis/base/v3/bases/tables/forms/submit, so the dry-run plan still emits two submit operations for one execution. The first .POST(...) on Line 140 should be dropped — the final submit is correctly added at Lines 158–160 with the body and description.

♻️ Proposed fix
 	if len(attachmentMap) > 0 {
 		dry := common.NewDryRunAPI().
-			Desc("Form submit with attachments: upload local files per field → merge with fields → submit").
-			POST("/open-apis/base/v3/bases/tables/forms/submit")
+			Desc("Form submit with attachments: upload local files per field → merge with fields → submit")
🤖 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/base/base_form_submit.go` around lines 137 - 161, The dry-run
branch for attachments currently calls
POST("/open-apis/base/v3/bases/tables/forms/submit") twice: once when
initializing dry (via common.NewDryRunAPI().Desc(...).POST(...)) and again
before submitting the merged body; remove the initial .POST call so that dry is
initialized with common.NewDryRunAPI().Desc("Form submit with attachments:
upload local files per field → merge with fields → submit") and then the loop
builds upload POSTs, and only the final POST for submit (the one that uses
buildFormSubmitBody(runtime, fields) and sets Body(...) and Desc(...)) remains;
update the code around the attachmentMap handling (variable dry, NewDryRunAPI,
and buildFormSubmitBody usage) to ensure a single submit POST is emitted.
skills/lark-base/references/lark-base-form-submit.md (3)

82-82: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Broken references/… relative links inside the references/ directory still present.

Lines 82, 122, 171, 172 all link to references/<file>.md from a file that already lives in skills/lark-base/references/, so they resolve to references/references/<file>.md and 404. Drop the leading references/ segment.

♻️ Proposed fix
-`fields` 中的单元格值写法与 [`lark-base-cell-value.md`](references/lark-base-cell-value.md) 完全对齐,填写前应先阅读该文档了解各类型的构造规则:
+`fields` 中的单元格值写法与 [`lark-base-cell-value.md`](lark-base-cell-value.md) 完全对齐,填写前应先阅读该文档了解各类型的构造规则:
@@
-> 与 [`lark-base-cell-value.md`](references/lark-base-cell-value.md) 中 Record 场景的附件写法不同:…
+> 与 [`lark-base-cell-value.md`](lark-base-cell-value.md) 中 Record 场景的附件写法不同:…
@@
-- [lark-base-form](references/lark-base-form.md) — 表单管理总览
-- [lark-base-record-upload-attachment](references/lark-base-record-upload-attachment.md) — 给已有记录上传附件(不同场景)
+- [lark-base-form](lark-base-form.md) — 表单管理总览
+- [lark-base-record-upload-attachment](lark-base-record-upload-attachment.md) — 给已有记录上传附件(不同场景)

Also applies to: 122-122, 171-172

🤖 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-base/references/lark-base-form-submit.md` at line 82, In
skills/lark-base/references/lark-base-form-submit.md the internal links
incorrectly include a redundant "references/" prefix (e.g.
`references/lark-base-cell-value.md`) causing them to resolve to
`references/references/...`; edit the links in this file (the occurrences
referencing lark-base-cell-value.md and the other referenced files at the noted
locations) to drop the leading "references/" so they point to
`lark-base-cell-value.md` (and similarly for the links at lines 122, 171, 172),
then save and verify the links resolve correctly within the references
directory.

100-102: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Resolve markdownlint warnings (MD028, MD040).

Line 101 still leaves a blank line inside the consecutive blockquote (MD028), and the URL fenced block at Line 128 still lacks a language tag (MD040).

♻️ Proposed fix
 > **注意:附件类型字段不要写在 `fields` 里。** ...
-
 > 自动编号、公式、创建/修改人、创建/修改时间等系统字段会自动填入,无需手动传入。
@@
-```
+```text
 https://bitable-test.feishu-boe.cn/share/base/form/shrbcvST8eZy0vk8zjVZ1CAXNye
</details>






Also applies to: 128-130

<details>
<summary>🤖 Prompt for AI Agents</summary>

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-base/references/lark-base-form-submit.md around lines 100 - 102,
Remove the stray blank line inside the consecutive blockquote that contains the
sentences "注意:附件类型字段不要写在 fields 里。 fields
中不包含附件,附件有独立的填写方式,见下方「attachments(附件上传)」章节。" and
"自动编号、公式、创建/修改人、创建/修改时间等系统字段会自动填入,无需手动传入。" so the two lines remain contiguous
(fixes MD028), and add a language tag (e.g., ```text) to the fenced code block
that contains the URL
"https://bitable-test.feishu-boe.cn/share/base/form/shrbcvST8eZy0vk8zjVZ1CAXNye"
(fixes MD040).


</details>

---

`5-5`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_

**Add an explanation of `share_token`, mirroring `baseToken` / `wikiToken`.**

Reviewer feedback (zgz2048) on the previous commit asked for an introduction of what `share_token` is, modeled after how `baseToken` / `wikiToken` are documented. Currently the doc jumps to “通过表单分享链接…” without ever defining the token: where it comes from, what it identifies, lifetime/scope, and revocation behavior. Consider a short subsection (or a sentence near Line 5) similar to the share-token extraction block at Lines 124–142 but framed as a definition.

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
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-base/references/lark-base-form-submit.md` at line 5, Add a short
explanatory paragraph/subsection in lark-base-form-submit.md that defines
share_token (similar to how baseToken/wikiToken are documented): state where the
share_token comes from (extracted from form share link), what it identifies (the
shared form instance and access mode), its expected lifetime/scope
(temporary/link-scoped vs. user-scoped) and revocation behavior (what happens
when the share link is disabled), and point readers to the existing share-token
extraction example (the share-token extraction block) for usage; keep wording
consistent with the baseToken/wikiToken style.
```

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🧹 Nitpick comments (1)</summary><blockquote>

<details>
<summary>skills/lark-base/references/lark-base-form-detail.md (1)</summary><blockquote>

`51-53`: _💤 Low value_

**Add a language tag to the fenced URL block.**

`markdownlint-cli2` flags Line 51 (MD040). Use `text` for plain URL examples.

<details>
<summary>♻️ Proposed fix</summary>

```diff
-```
+```text
 https://bitable-test.feishu-boe.cn/share/base/form/shrbcvST8eZy0vk8zjVZ1CAXNye
 ```
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

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-base/references/lark-base-form-detail.md around lines 51 - 53,
The fenced code block containing the plain URL
"https://bitable-test.feishu-boe.cn/share/base/form/shrbcvST8eZy0vk8zjVZ1CAXNye"
should include a language tag to satisfy markdownlint MD040; change the opening
triple backticks for that block from totext so the block is explicitly
marked as plain text (i.e., update the fenced block that wraps the URL).


</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

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 @shortcuts/base/base_form_submit.go:

  • Around line 46-48: The Execute handler is dropping the incoming ctx; update
    Execute to pass the received ctx into executeFormSubmit, then change
    executeFormSubmit to accept ctx and forward it into uploadAttachmentsParallel;
    inside uploadAttachmentsParallel use errgroup.WithContext(ctx) (capture and use
    the derived groupCtx) instead of context.Background(), return/carry that
    groupCtx into uploadSingleAttachment and uploadAttachmentToBase calls, and
    modify uploadSingleAttachment and uploadAttachmentToBase to accept ctx and pass
    it into any HTTP requests (e.g., use http.NewRequestWithContext or equivalent)
    so cancellation and short-circuiting on first error work correctly; also apply
    the same ctx plumbing to the other call sites mentioned (around lines 177-181
    and 269-300) so all uploads use the executor context.

Duplicate comments:
In @shortcuts/base/base_form_submit.go:

  • Around line 233-238: The code is printing the full form submission body to
    stderr (via fmt.Fprintf(runtime.IO().ErrOut, ...)) which can leak user data;
    remove that unconditional debug print (the fmt.Fprintf call and the bodyJSON
    marshaling using json.Marshal) or gate it behind an explicit debug/verbose flag
    that must be checked before marshaling/logging; update the
    buildFormSubmitBody/baseV3Call usage to pass body directly without logging and
    remove the now-unused encoding/json import if you delete the marshal/logging
    code.
  • Around line 137-161: The dry-run branch for attachments currently calls
    POST("/open-apis/base/v3/bases/tables/forms/submit") twice: once when
    initializing dry (via common.NewDryRunAPI().Desc(...).POST(...)) and again
    before submitting the merged body; remove the initial .POST call so that dry is
    initialized with common.NewDryRunAPI().Desc("Form submit with attachments:
    upload local files per field → merge with fields → submit") and then the loop
    builds upload POSTs, and only the final POST for submit (the one that uses
    buildFormSubmitBody(runtime, fields) and sets Body(...) and Desc(...)) remains;
    update the code around the attachmentMap handling (variable dry, NewDryRunAPI,
    and buildFormSubmitBody usage) to ensure a single submit POST is emitted.

In @skills/lark-base/references/lark-base-form-submit.md:

  • Line 82: In skills/lark-base/references/lark-base-form-submit.md the internal
    links incorrectly include a redundant "references/" prefix (e.g.
    references/lark-base-cell-value.md) causing them to resolve to
    references/references/...; edit the links in this file (the occurrences
    referencing lark-base-cell-value.md and the other referenced files at the noted
    locations) to drop the leading "references/" so they point to
    lark-base-cell-value.md (and similarly for the links at lines 122, 171, 172),
    then save and verify the links resolve correctly within the references
    directory.
  • Around line 100-102: Remove the stray blank line inside the consecutive
    blockquote that contains the sentences "注意:附件类型字段不要写在 fields 里。 fields
    中不包含附件,附件有独立的填写方式,见下方「attachments(附件上传)」章节。" and
    "自动编号、公式、创建/修改人、创建/修改时间等系统字段会自动填入,无需手动传入。" so the two lines remain contiguous
    (fixes MD028), and add a language tag (e.g., ```text) to the fenced code block
    that contains the URL
    "https://bitable-test.feishu-boe.cn/share/base/form/shrbcvST8eZy0vk8zjVZ1CAXNye"
    (fixes MD040).
  • Line 5: Add a short explanatory paragraph/subsection in
    lark-base-form-submit.md that defines share_token (similar to how
    baseToken/wikiToken are documented): state where the share_token comes from
    (extracted from form share link), what it identifies (the shared form instance
    and access mode), its expected lifetime/scope (temporary/link-scoped vs.
    user-scoped) and revocation behavior (what happens when the share link is
    disabled), and point readers to the existing share-token extraction example (the
    share-token extraction block) for usage; keep wording consistent with the
    baseToken/wikiToken style.

Nitpick comments:
In @skills/lark-base/references/lark-base-form-detail.md:


</details>

<details>
<summary>🪄 Autofix (Beta)</summary>

Fix all unresolved CodeRabbit comments on this PR:

- [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended)
- [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: defaults

**Review profile**: CHILL

**Plan**: Pro

**Run ID**: `de6c37f7-e997-4699-b7b5-7e38f735635d`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between d037e584285e2ff5ceb8e01ad5779797b83aad3f and d2a8fac9f21944df695f88653d187318af515d63.

</details>

<details>
<summary>📒 Files selected for processing (11)</summary>

* `.gitignore`
* `shortcuts/base/base_dryrun_ops_test.go`
* `shortcuts/base/base_form_detail.go`
* `shortcuts/base/base_form_submit.go`
* `shortcuts/base/base_shortcuts_test.go`
* `shortcuts/base/shortcuts.go`
* `skills/lark-base/SKILL.md`
* `skills/lark-base/references/lark-base-form-detail.md`
* `skills/lark-base/references/lark-base-form-submit.md`
* `skills/lark-base/references/lark-base-form.md`
* `tests/cli_e2e/base/base_form_detail_dryrun_test.go`

</details>

<details>
<summary>✅ Files skipped from review due to trivial changes (5)</summary>

* .gitignore
* skills/lark-base/references/lark-base-form.md
* shortcuts/base/base_form_detail.go
* tests/cli_e2e/base/base_form_detail_dryrun_test.go
* shortcuts/base/shortcuts.go

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (2)</summary>

* shortcuts/base/base_shortcuts_test.go
* shortcuts/base/base_dryrun_ops_test.go

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment thread shortcuts/base/base_form_submit.go
@github-actions github-actions Bot added the domain/ccm PR touches the ccm domain label May 20, 2026
Comment thread skills/lark-base/references/lark-base-form-detail.md Outdated
Comment thread skills/lark-base/references/lark-base-form-detail.md Outdated
Comment thread skills/lark-base/references/lark-base-form-detail.md Outdated
Comment thread skills/lark-base/references/lark-base-form-detail.md Outdated
Comment thread skills/lark-base/references/lark-base-form-detail.md Outdated
@codecov

codecov Bot commented May 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.16814% with 29 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.58%. Comparing base (13411d9) to head (eac7c3b).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
shortcuts/base/base_form_submit.go 90.16% 9 Missing and 9 partials ⚠️
shortcuts/base/base_form_detail.go 43.75% 9 Missing ⚠️
shortcuts/drive/drive_import_common.go 77.77% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #759      +/-   ##
==========================================
+ Coverage   67.39%   67.58%   +0.18%     
==========================================
  Files         572      575       +3     
  Lines       53659    54269     +610     
==========================================
+ Hits        36165    36679     +514     
- Misses      14486    14548      +62     
- Partials     3008     3042      +34     

☔ View full report in Codecov by Sentry.
📢 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.

Comment thread skills/lark-base/references/lark-base-form-detail.md Outdated
Comment thread skills/lark-base/references/lark-base-form-detail.md Outdated
Comment thread skills/lark-base/references/lark-base-form-detail.md Outdated
@yballul-bytedance
yballul-bytedance force-pushed the feat/cli_v4_product branch 2 times, most recently from 8cf807b to 8a330af Compare May 20, 2026 04:01
Comment thread shortcuts/base/base_shortcuts_test.go Outdated
Comment thread shortcuts/base/base_shortcuts_test.go Outdated
@yballul-bytedance
yballul-bytedance force-pushed the feat/cli_v4_product branch 2 times, most recently from e4938e3 to 1d17b9b Compare May 20, 2026 05:24
Change-Id: If08f236c8ae351f92683f2b861cc999eb6f1d22d
@yballul-bytedance
yballul-bytedance merged commit 69c3448 into main May 20, 2026
21 checks passed
@yballul-bytedance
yballul-bytedance deleted the feat/cli_v4_product branch May 20, 2026 06:02
@liangshuo-1 liangshuo-1 mentioned this pull request May 20, 2026
2 tasks
tuxedomm pushed a commit to zhumiaoxin/cli that referenced this pull request Jun 6, 2026
Change-Id: If08f236c8ae351f92683f2b861cc999eb6f1d22d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain/base PR touches the base domain 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