Skip to content

feat: Product CLI v4 no-meego#759

Open
yballul-bytedance wants to merge 1 commit intomainfrom
feat/cli_v4_product
Open

feat: Product CLI v4 no-meego#759
yballul-bytedance wants to merge 1 commit intomainfrom
feat/cli_v4_product

Conversation

@yballul-bytedance
Copy link
Copy Markdown
Collaborator

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

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
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 2026

Review Change Stack

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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/cli_v4_product

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

🚀 PR Preview Install Guide

🧰 CLI update

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

🧩 Skill update

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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


> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。

通过表单分享链接填写并提交多维表格表单。仅支持分享模式(share_token),支持填写普通字段值和上传本地文件作为附件。
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

没有看到介绍什么是 share_token 的地方,参考 baseToken / wikiToken 补上

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

有的

Image

Comment thread form.md Outdated
Comment thread skills/lark-base/references/lark-base-form-detail.md
result, err := clie2e.RunCmd(ctx, clie2e.Request{
Args: []string{
"base", "+form-detail",
"--share-token", "shrcnkbanhog5cHymqg2VHp5Tth",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Gitleaks has detected a secret with rule-id generic-api-key in commit 6d4c896.
If this secret is a true positive, please rotate the secret ASAP.

If this secret is a false positive, you can add the fingerprint below to your .gitleaksignore file and commit the change to this branch.

echo 6d4c8963283905f043f57465de859e1db6a29c58:tests/cli_e2e/base/base_form_detail_dryrun_test.go:generic-api-key:26 >> .gitleaksignore

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
withAttachmentsRT := newBaseTestRuntime(
map[string]string{
"base-token": "app_x",
"share-token": "shrcnkbanhog5cHymqg2VHp5Tth",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Gitleaks has detected a secret with rule-id generic-api-key in commit 6d4c896.
If this secret is a true positive, please rotate the secret ASAP.

If this secret is a false positive, you can add the fingerprint below to your .gitleaksignore file and commit the change to this branch.

echo 6d4c8963283905f043f57465de859e1db6a29c58:shortcuts/base/base_dryrun_ops_test.go:generic-api-key:296 >> .gitleaksignore

result, err := clie2e.RunCmd(ctx, clie2e.Request{
Args: []string{
"base", "+form-detail",
"--share-token", "shrcnkbanhog5cHymqg2VHp5Tth",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Gitleaks has detected a secret with rule-id generic-api-key in commit d2a8fac.
If this secret is a true positive, please rotate the secret ASAP.

If this secret is a false positive, you can add the fingerprint below to your .gitleaksignore file and commit the change to this branch.

echo d2a8fac9f21944df695f88653d187318af515d63:tests/cli_e2e/base/base_form_detail_dryrun_test.go:generic-api-key:26 >> .gitleaksignore

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
withAttachmentsRT := newBaseTestRuntime(
map[string]string{
"base-token": "app_x",
"share-token": "shrcnkbanhog5cHymqg2VHp5Tth",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Gitleaks has detected a secret with rule-id generic-api-key in commit d2a8fac.
If this secret is a true positive, please rotate the secret ASAP.

If this secret is a false positive, you can add the fingerprint below to your .gitleaksignore file and commit the change to this branch.

echo d2a8fac9f21944df695f88653d187318af515d63:shortcuts/base/base_dryrun_ops_test.go:generic-api-key:296 >> .gitleaksignore

{
"ok": true,
"data": {
"base_token": "DEAabEZVXaV1AasQn4bb6VFRcPd",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Gitleaks has detected a secret with rule-id generic-api-key in commit d2a8fac.
If this secret is a true positive, please rotate the secret ASAP.

If this secret is a false positive, you can add the fingerprint below to your .gitleaksignore file and commit the change to this branch.

echo d2a8fac9f21944df695f88653d187318af515d63:skills/lark-base/references/lark-base-form-detail.md:generic-api-key:209 >> .gitleaksignore

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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
{
"ok": true,
"data": {
"base_token": "DEAabEZVXaV1AasQn4bb6VFRcPd",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Gitleaks has detected a secret with rule-id generic-api-key in commit 8fa0948.
If this secret is a true positive, please rotate the secret ASAP.

If this secret is a false positive, you can add the fingerprint below to your .gitleaksignore file and commit the change to this branch.

echo 8fa0948d0e5d76660fabb38d8bb61f8cf6380ef2:skills/lark-base/references/lark-base-form-detail.md:generic-api-key:209 >> .gitleaksignore

Change-Id: If08f236c8ae351f92683f2b861cc999eb6f1d22d
{
"ok": true,
"data": {
"base_token": "DEAabEZVXaV1AasQn4bb6VFRcPd",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Gitleaks has detected a secret with rule-id generic-api-key in commit b5eb4c6.
If this secret is a true positive, please rotate the secret ASAP.

If this secret is a false positive, you can add the fingerprint below to your .gitleaksignore file and commit the change to this branch.

echo b5eb4c643d112e5b637e344cf151255beb5e88c5:skills/lark-base/references/lark-base-form-detail.md:generic-api-key:209 >> .gitleaksignore

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (4)
shortcuts/base/base_form_submit.go (1)

47-49: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

ctx is dropped in Execute and the errgroup's derived context is discarded — cancellation is broken.

This was previously flagged and remains unaddressed:

  1. Line 48 — executeFormSubmit(runtime) ignores the ctx passed to Execute, so parent cancellation (e.g., SIGINT) cannot reach the upload path.
  2. Line 281 — g, _ := errgroup.WithContext(runtime.Ctx()): the derived gctx is discarded, so sibling upload goroutines cannot observe first-failure cancellation.
♻️ Sketch of the fix
-	Execute: func(ctx context.Context, runtime *common.RuntimeContext) error {
-		return executeFormSubmit(runtime)
-	},
+	Execute: func(ctx context.Context, runtime *common.RuntimeContext) error {
+		return executeFormSubmit(ctx, runtime)
+	},
-func executeFormSubmit(runtime *common.RuntimeContext) error {
+func executeFormSubmit(ctx context.Context, runtime *common.RuntimeContext) error {
     ...
-    resultMap, err := uploadAttachmentsParallel(runtime, allPaths, baseToken, sizeMap)
+    resultMap, err := uploadAttachmentsParallel(ctx, runtime, allPaths, baseToken, sizeMap)
-func uploadAttachmentsParallel(runtime *common.RuntimeContext, paths []string, baseToken string, sizeMap map[string]int64) (map[string]interface{}, error) {
+func uploadAttachmentsParallel(ctx context.Context, runtime *common.RuntimeContext, paths []string, baseToken string, sizeMap map[string]int64) (map[string]interface{}, error) {
     ...
-    g, _ := errgroup.WithContext(runtime.Ctx())
+    g, gctx := errgroup.WithContext(ctx)
     ...
     g.Go(func() error {
+        if gctx.Err() != nil { return gctx.Err() }
         ...
     })

Also applies to: 281-281

🤖 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 47 - 49, The Execute handler
drops the provided ctx and the errgroup's derived context (gctx) is discarded,
breaking cancellation; change the Execute closure to pass the incoming ctx into
executeFormSubmit (i.e., call executeFormSubmit(ctx, runtime)) and update
executeFormSubmit signature to accept a context and use that context for
operations instead of runtime.Ctx(); inside executeFormSubmit replace g, _ :=
errgroup.WithContext(runtime.Ctx()) with g, gctx := errgroup.WithContext(ctx)
(or similar) and use gctx for spawning goroutines and context checks so sibling
uploads observe first-failure cancellation.
skills/lark-base/references/lark-base-form-submit.md (2)

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

Broken cross-links in ## 参考references/ prefix is wrong from inside the references/ directory.

Both links resolve to skills/lark-base/references/references/*.md which doesn't exist. This was previously flagged and marked resolved but the fix wasn't applied.

📄 Proposed fix
-- [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) — 给已有记录上传附件(不同场景)
🤖 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` around lines 171 - 172,
The two markdown links "[lark-base-form](references/lark-base-form.md)" and
"[lark-base-record-upload-attachment](references/lark-base-record-upload-attachment.md)"
in the "## 参考" section incorrectly include a redundant "references/" prefix
causing them to resolve to "references/references/..."; update each link to the
correct relative target inside the references directory by removing the extra
"references/" prefix so they read "[lark-base-form](lark-base-form.md)" and
"[lark-base-record-upload-attachment](lark-base-record-upload-attachment.md)"
respectively.

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

Persistent markdownlint warnings (MD028, MD040) — fix not applied despite being marked resolved.

  • MD028 (Line 101): blank line between two consecutive blockquote blocks — remove it to merge the notes or keep them as one visually unified block.
  • MD040 (Line 128): fenced code block is missing a language tag — add ```text.
📄 Proposed fix
 > **注意:附件类型字段不要写在 `fields` 里。** `fields` 中不包含附件,附件有独立的填写方式,见下方「attachments(附件上传)」章节。
-
 > 自动编号、公式、创建/修改人、创建/修改时间等系统字段会自动填入,无需手动传入。
-```
+```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 extra blank line between the two consecutive blockquote blocks so
they become a single unified blockquote (the lines containing "注意:附件类型字段不要写在
fields 里..." and "自动编号、公式、创建/修改人..." in the lark-base-form-submit.md note
section), and add a language tag to the fenced code block(s) referenced (change
the triple-backtick fences around the URL example to use ```text) — apply the
same fenced-code fix to the other occurrence noted (lines ~128-130) to resolve
MD028 and MD040 warnings.


</details>

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

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

**Replace the real-looking Base token in the example JSON with an obvious placeholder.**

`"base_token": "DEAabEZVXaV1AasQn4bb6VFRcPd"` has been flagged by Gitleaks (`generic-api-key`) in every commit since this file was introduced. Even if this is a false positive, the value looks indistinguishable from a live token; replace it with a clearly synthetic value such as `"BASEXxxxxxxxxxxxxxxxxxxxxxxx"` and, if it originated from a real environment, rotate the token.

<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` at line 209, Replace
the real-looking example value for the JSON key "base_token" in the example
block (the line containing "base_token": "DEAabEZVXaV1AasQn4bb6VFRcPd") with an
obviously synthetic placeholder such as "BASEXxxxxxxxxxxxxxxxxxxxxxxx"; if that
value came from a real environment, ensure the real token has been rotated
before committing the change.
```

</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 @skills/lark-base/references/lark-base-form-detail.md:

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

  • Around line 164-165: The permissions tip only lists "base:form:update" but the
    handler BaseFormSubmit (base_form_submit.go) requires both "base:form:update"
    and "docs:document.media:upload"; update the docs line to include the missing
    docs:document.media:upload scope so users submitting attachments have the
    required media upload permission.

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

  • Around line 47-49: The Execute handler drops the provided ctx and the
    errgroup's derived context (gctx) is discarded, breaking cancellation; change
    the Execute closure to pass the incoming ctx into executeFormSubmit (i.e., call
    executeFormSubmit(ctx, runtime)) and update executeFormSubmit signature to
    accept a context and use that context for operations instead of runtime.Ctx();
    inside executeFormSubmit replace g, _ := errgroup.WithContext(runtime.Ctx())
    with g, gctx := errgroup.WithContext(ctx) (or similar) and use gctx for spawning
    goroutines and context checks so sibling uploads observe first-failure
    cancellation.

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

  • Line 209: Replace the real-looking example value for the JSON key "base_token"
    in the example block (the line containing "base_token":
    "DEAabEZVXaV1AasQn4bb6VFRcPd") with an obviously synthetic placeholder such as
    "BASEXxxxxxxxxxxxxxxxxxxxxxxx"; if that value came from a real environment,
    ensure the real token has been rotated before committing the change.

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

  • Around line 171-172: The two markdown links
    "lark-base-form" and
    "lark-base-record-upload-attachment"
    in the "## 参考" section incorrectly include a redundant "references/" prefix
    causing them to resolve to "references/references/..."; update each link to the
    correct relative target inside the references directory by removing the extra
    "references/" prefix so they read "lark-base-form" and
    "lark-base-record-upload-attachment"
    respectively.
  • Around line 100-102: Remove the extra blank line between the two consecutive
    blockquote blocks so they become a single unified blockquote (the lines
    containing "注意:附件类型字段不要写在 fields 里..." and "自动编号、公式、创建/修改人..." in the
    lark-base-form-submit.md note section), and add a language tag to the fenced
    code block(s) referenced (change the triple-backtick fences around the URL
    example to use ```text) — apply the same fenced-code fix to the other occurrence
    noted (lines ~128-130) to resolve MD028 and MD040 warnings.

</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**: `dc9f51fa-f691-4335-bb9a-8dc1b7202ed2`

</details>

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

Reviewing files that changed from the base of the PR and between 8fa0948d0e5d76660fabb38d8bb61f8cf6380ef2 and b5eb4c643d112e5b637e344cf151255beb5e88c5.

</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 (4)</summary>

* .gitignore
* skills/lark-base/references/lark-base-form.md
* shortcuts/base/shortcuts.go
* skills/lark-base/SKILL.md

</details>

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

* shortcuts/base/base_form_detail.go
* shortcuts/base/base_shortcuts_test.go
* tests/cli_e2e/base/base_form_detail_dryrun_test.go

</details>

</details>

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

Comment on lines +51 to +53
```
https://bitable-test.feishu-boe.cn/share/base/form/shrbcvST8eZy0vk8zjVZ1CAXNye
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language specifier to the fenced code block (MD040).

The bare ``` block at Line 51 triggers a markdownlint MD040 warning.

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

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.22.1)</summary>

[warning] 51-51: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</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 URL
"https://bitable-test.feishu-boe.cn/share/base/form/shrbcvST8eZy0vk8zjVZ1CAXNye"
should include a language specifier to satisfy markdownlint MD040; update the
opening fence from totext (or another appropriate language) so the block
reads as a labeled code block (e.g., ```text) while keeping the URL content
unchanged.


</details>

<!-- fingerprinting:phantom:poseidon:churro -->

<!-- d98c2f50 -->

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

Comment on lines +164 to +165
- 限流:单应用 20 QPS,单用户 5 QPS
- 权限要求:`base:form:update`
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Missing docs:document.media:upload scope in the permissions tip.

Line 165 documents only base:form:update, but BaseFormSubmit in base_form_submit.go (line 30) declares both "base:form:update" and "docs:document.media:upload". Users submitting forms with attachments need the media upload scope and will get a permissions error without it.

📄 Proposed fix
-- 权限要求:`base:form:update`
+- 权限要求:`base:form:update`(附件场景额外需要 `docs:document.media:upload`)
🤖 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` around lines 164 - 165,
The permissions tip only lists "base:form:update" but the handler BaseFormSubmit
(base_form_submit.go) requires both "base:form:update" and
"docs:document.media:upload"; update the docs line to include the missing
docs:document.media:upload scope so users submitting attachments have the
required media upload permission.

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 size/L Large or sensitive change across domains or core paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants