Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions shortcuts/base/base_advperm_disable.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ var BaseAdvpermDisable = common.Shortcut{
Flags: []common.Flag{
{Name: "base-token", Desc: "base token", Required: true},
},
Tips: []string{
baseHighRiskYesTip,
"Disabling advanced permissions invalidates existing custom roles; confirm the target Base before passing --yes.",
},
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if strings.TrimSpace(runtime.Str("base-token")) == "" {
return common.FlagErrorf("--base-token must not be blank")
Expand Down
5 changes: 5 additions & 0 deletions shortcuts/base/base_copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ var BaseBaseCopy = common.Shortcut{
{Name: "without-content", Type: "bool", Desc: "copy structure only"},
{Name: "time-zone", Desc: "time zone, e.g. Asia/Shanghai"},
},
Tips: []string{
`Example: lark-cli base +base-copy --base-token <base_token> --name "Copy of Project Tracker"`,
"Use --without-content when the user wants only structure.",
"If copied as bot, output may include permission_grant; report it so the user knows whether they can open the new Base.",
},
DryRun: dryRunBaseCopy,
Execute: func(ctx context.Context, runtime *common.RuntimeContext) error {
return executeBaseCopy(runtime)
Expand Down
4 changes: 4 additions & 0 deletions shortcuts/base/base_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ var BaseBaseCreate = common.Shortcut{
{Name: "folder-token", Desc: "folder token for destination"},
{Name: "time-zone", Desc: "time zone, e.g. Asia/Shanghai"},
},
Tips: []string{
`Example: lark-cli base +base-create --name "Project Tracker" --time-zone Asia/Shanghai`,
"If created as bot, output may include permission_grant; report it so the user knows whether they can open the new Base.",
},
DryRun: dryRunBaseCreate,
Execute: func(ctx context.Context, runtime *common.RuntimeContext) error {
return executeBaseCreate(runtime)
Expand Down
2 changes: 1 addition & 1 deletion shortcuts/base/base_execute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ func TestBaseObjectJSONShortcutsRejectArrayInDryRun(t *testing.T) {
if !strings.Contains(err.Error(), "--json must be a JSON object") {
t.Fatalf("err=%v", err)
}
if !strings.Contains(err.Error(), "lark-base skill") {
if !strings.Contains(err.Error(), "match the documented shape") {
t.Fatalf("err=%v", err)
}
if strings.Contains(err.Error(), "array") {
Expand Down
1 change: 1 addition & 0 deletions shortcuts/base/base_form_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var BaseFormDelete = common.Shortcut{
{Name: "table-id", Desc: "table ID", Required: true},
{Name: "form-id", Desc: "form ID", Required: true},
},
Tips: []string{baseHighRiskYesTip},
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
return common.NewDryRunAPI().
DELETE("/open-apis/base/v3/bases/:base_token/tables/:table_id/forms/:form_id").
Expand Down
2 changes: 1 addition & 1 deletion shortcuts/base/base_form_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var BaseFormsList = common.Shortcut{
Flags: []common.Flag{
{Name: "base-token", Desc: "Base token (base_token)", Required: true},
{Name: "table-id", Desc: "table ID", Required: true},
{Name: "page-size", Type: "int", Default: "100", Desc: "page size per request (max 100)"},
{Name: "page-size", Type: "int", Default: "100", Desc: "page size per request, max 100"},
},
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
return common.NewDryRunAPI().
Expand Down
1 change: 1 addition & 0 deletions shortcuts/base/base_form_questions_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var BaseFormQuestionsDelete = common.Shortcut{
{Name: "form-id", Desc: "form ID", Required: true},
{Name: "question-ids", Desc: `JSON array of question IDs to delete, max 10 items, e.g. '["q_001","q_002"]'`, Required: true},
},
Tips: []string{baseHighRiskYesTip},
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
return common.NewDryRunAPI().
DELETE("/open-apis/base/v3/bases/:base_token/tables/:table_id/forms/:form_id/questions").
Expand Down
5 changes: 5 additions & 0 deletions shortcuts/base/base_role_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ var BaseRoleCreate = common.Shortcut{
{Name: "base-token", Desc: "base token", Required: true},
{Name: "json", Desc: `body JSON (AdvPermBaseRoleConfig), e.g. {"role_name":"Reviewer","role_type":"custom_role","table_rule_map":{...}}`, Required: true},
},
Tips: []string{
`Example: --json '{"role_name":"Reviewer","role_type":"custom_role","base_rule_map":{"copy":false,"download":false}}'`,
"Read role-config.md for table_rule_map, dashboard_rule_map, docx_rule_map, and filter permission JSON.",
"Create supports custom_role only.",
},
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if strings.TrimSpace(runtime.Str("base-token")) == "" {
return common.FlagErrorf("--base-token must not be blank")
Expand Down
5 changes: 5 additions & 0 deletions shortcuts/base/base_role_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ var BaseRoleDelete = common.Shortcut{
{Name: "base-token", Desc: "base token", Required: true},
{Name: "role-id", Desc: "role ID (e.g. rolxxxxxx4)", Required: true},
},
Tips: []string{
baseHighRiskYesTip,
"Only custom roles can be deleted; system roles cannot be deleted.",
"Use +role-get first if the role target is ambiguous, then pass --yes to confirm deletion.",
},
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if strings.TrimSpace(runtime.Str("base-token")) == "" {
return common.FlagErrorf("--base-token must not be blank")
Expand Down
4 changes: 4 additions & 0 deletions shortcuts/base/base_role_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ var BaseRoleGet = common.Shortcut{
{Name: "base-token", Desc: "base token", Required: true},
{Name: "role-id", Desc: "role ID (e.g. rolxxxxxx4)", Required: true},
},
Tips: []string{
`Example: lark-cli base +role-get --base-token <base_token> --role-id <role_id>`,
"Use before +role-update to inspect the current full permission config.",
},
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if strings.TrimSpace(runtime.Str("base-token")) == "" {
return common.FlagErrorf("--base-token must not be blank")
Expand Down
4 changes: 4 additions & 0 deletions shortcuts/base/base_role_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ var BaseRoleList = common.Shortcut{
Flags: []common.Flag{
{Name: "base-token", Desc: "base token", Required: true},
},
Tips: []string{
`Example: lark-cli base +role-list --base-token <base_token>`,
"Returns role summaries; use +role-get for the full permission config.",
},
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if strings.TrimSpace(runtime.Str("base-token")) == "" {
return common.FlagErrorf("--base-token must not be blank")
Expand Down
6 changes: 6 additions & 0 deletions shortcuts/base/base_role_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ var BaseRoleUpdate = common.Shortcut{
{Name: "role-id", Desc: "role ID (e.g. rolxxxxxx4)", Required: true},
{Name: "json", Desc: `body JSON (delta AdvPermBaseRoleConfig), e.g. {"role_name":"New Name","role_type":"custom_role","table_rule_map":{...}}`, Required: true},
},
Tips: []string{
baseHighRiskYesTip,
`Example: --json '{"role_name":"Reviewer","role_type":"custom_role","base_rule_map":{"copy":false,"download":false}}'`,
"Update is a delta merge: only changed fields are updated, others remain unchanged.",
"Read role-config.md before changing table, field, record, dashboard, or docx permissions.",
},
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
if strings.TrimSpace(runtime.Str("base-token")) == "" {
return common.FlagErrorf("--base-token must not be blank")
Expand Down
2 changes: 1 addition & 1 deletion shortcuts/base/base_shortcut_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func loadJSONInput(pc *parseCtx, raw string, flagName string) (string, error) {
}

func jsonInputTip(flagName string) string {
return fmt.Sprintf("tip: pass a valid JSON directly, or use --%s @file.json; use the lark-base skill or this command's reference to find the expected body", flagName)
return fmt.Sprintf("tip: pass a valid JSON directly, or use --%s @file.json; for complex JSON/DSL, read the lark-base reference and match the documented shape", flagName)
}

func formatJSONError(flagName string, target string, err error) error {
Expand Down
19 changes: 19 additions & 0 deletions shortcuts/base/base_shortcuts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,25 @@ func TestBaseDeleteShortcutsRisk(t *testing.T) {
}
}

func TestBaseHighRiskShortcutsTipsGuideAgents(t *testing.T) {
for _, shortcut := range Shortcuts() {
if shortcut.Risk != "high-risk-write" {
continue
}
parent := &cobra.Command{Use: "base"}
shortcut.Mount(parent, &cmdutil.Factory{})
cmd := parent.Commands()[0]
flag := cmd.Flags().Lookup("yes")
if flag == nil {
t.Fatalf("%s missing --yes flag", shortcut.Command)
}
tips := strings.Join(cmdutil.GetTips(cmd), "\n")
if !strings.Contains(tips, "pass --yes without asking again") {
t.Fatalf("%s tips missing agent guidance:\n%s", shortcut.Command, tips)
}
}
}

func TestBaseFieldCreateHelpHidesReadGuideFlag(t *testing.T) {
parent := &cobra.Command{Use: "base"}
BaseFieldCreate.Mount(parent, &cmdutil.Factory{})
Expand Down
3 changes: 3 additions & 0 deletions shortcuts/base/dashboard_arrange.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ var BaseDashboardArrange = common.Shortcut{
dashboardIDFlag(true),
{Name: "user-id-type", Desc: "user ID type: open_id / union_id / user_id"},
},
Tips: []string{
"Server-side smart layout is not deterministic or position-specific; use only when the user asks to arrange or beautify a dashboard.",
},
DryRun: dryRunDashboardArrange,
Execute: func(ctx context.Context, runtime *common.RuntimeContext) error {
return executeDashboardArrange(runtime)
Expand Down
5 changes: 5 additions & 0 deletions shortcuts/base/dashboard_block_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ var BaseDashboardBlockCreate = common.Shortcut{
{Name: "user-id-type", Desc: "user ID type: open_id / union_id / user_id"},
{Name: "no-validate", Type: "bool", Desc: "skip local data_config validation"},
},
Tips: []string{
`Example: --type statistics --data-config '{"table_name":"Orders","series":[{"field_name":"Amount","rollup":"SUM"}]}'`,
`Text blocks require --data-config '{"text":"# Title"}'.`,
"Read dashboard-block-data-config.md for chart-specific data_config templates and filter rules.",
},
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
pc := newParseCtx(runtime)
if runtime.Bool("no-validate") {
Expand Down
1 change: 1 addition & 0 deletions shortcuts/base/dashboard_block_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var BaseDashboardBlockDelete = common.Shortcut{
dashboardIDFlag(true),
blockIDFlag(true),
},
Tips: []string{baseHighRiskYesTip},
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
return common.NewDryRunAPI().
DELETE("/open-apis/base/v3/bases/:base_token/dashboards/:dashboard_id/blocks/:block_id").
Expand Down
2 changes: 1 addition & 1 deletion shortcuts/base/dashboard_block_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var BaseDashboardBlockList = common.Shortcut{
Flags: []common.Flag{
baseTokenFlag(true),
dashboardIDFlag(true),
{Name: "page-size", Desc: "page size (max 100)"},
{Name: "page-size", Desc: "page size, default 20, max 100"},
{Name: "page-token", Desc: "pagination token"},
},
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
Expand Down
6 changes: 6 additions & 0 deletions shortcuts/base/dashboard_block_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ var BaseDashboardBlockUpdate = common.Shortcut{
{Name: "user-id-type", Desc: "user ID type: open_id / union_id / user_id"},
{Name: "no-validate", Type: "bool", Desc: "skip local data_config validation"},
},
Tips: []string{
`Example: --data-config '{"series":[{"field_name":"Amount","rollup":"SUM"}]}'`,
"Block type cannot be changed; delete and recreate the block to change chart type.",
"data_config update merges top-level keys, but each provided key is replaced as a whole.",
"Read dashboard-block-data-config.md for chart-specific data_config templates and filter rules.",
},
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
pc := newParseCtx(runtime)
if runtime.Bool("no-validate") {
Expand Down
2 changes: 1 addition & 1 deletion shortcuts/base/dashboard_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var BaseDashboardCreate = common.Shortcut{
Flags: []common.Flag{
baseTokenFlag(true),
{Name: "name", Desc: "dashboard name", Required: true},
{Name: "theme-style", Desc: "theme style"},
{Name: "theme-style", Desc: "theme style, defaults to platform default when omitted"},
},
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
body := map[string]interface{}{}
Expand Down
1 change: 1 addition & 0 deletions shortcuts/base/dashboard_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ var BaseDashboardDelete = common.Shortcut{
baseTokenFlag(true),
dashboardIDFlag(true),
},
Tips: []string{baseHighRiskYesTip},
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
return common.NewDryRunAPI().
DELETE("/open-apis/base/v3/bases/:base_token/dashboards/:dashboard_id").
Expand Down
2 changes: 1 addition & 1 deletion shortcuts/base/dashboard_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var BaseDashboardList = common.Shortcut{
HasFormat: true,
Flags: []common.Flag{
baseTokenFlag(true),
{Name: "page-size", Desc: "page size (max 100)"},
{Name: "page-size", Desc: "page size, max 100"},
{Name: "page-token", Desc: "pagination token"},
},
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
Expand Down
2 changes: 1 addition & 1 deletion shortcuts/base/dashboard_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var BaseDashboardUpdate = common.Shortcut{
baseTokenFlag(true),
dashboardIDFlag(true),
{Name: "name", Desc: "new dashboard name"},
{Name: "theme-style", Desc: "theme style"},
{Name: "theme-style", Desc: "theme style, leave empty to keep current theme"},
},
DryRun: func(ctx context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
body := map[string]interface{}{}
Expand Down
1 change: 1 addition & 0 deletions shortcuts/base/field_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ var BaseFieldDelete = common.Shortcut{
Scopes: []string{"base:field:delete"},
AuthTypes: authTypes(),
Flags: []common.Flag{baseTokenFlag(true), tableRefFlag(true), fieldRefFlag(true)},
Tips: []string{baseHighRiskYesTip},
DryRun: dryRunFieldDelete,
Execute: func(ctx context.Context, runtime *common.RuntimeContext) error {
return executeFieldDelete(runtime)
Expand Down
2 changes: 1 addition & 1 deletion shortcuts/base/field_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var BaseFieldList = common.Shortcut{
baseTokenFlag(true),
tableRefFlag(true),
{Name: "offset", Type: "int", Default: "0", Desc: "pagination offset"},
{Name: "limit", Type: "int", Default: "100", Desc: "pagination size"},
{Name: "limit", Type: "int", Default: "100", Desc: "pagination size, range 1-200"},
},
DryRun: dryRunFieldList,
Execute: func(ctx context.Context, runtime *common.RuntimeContext) error {
Expand Down
2 changes: 1 addition & 1 deletion shortcuts/base/field_search_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var BaseFieldSearchOptions = common.Shortcut{
fieldRefFlag(true),
{Name: "keyword", Desc: "keyword for option query"},
{Name: "offset", Type: "int", Default: "0", Desc: "pagination offset"},
{Name: "limit", Type: "int", Default: "30", Desc: "pagination size"},
{Name: "limit", Type: "int", Default: "30", Desc: "pagination size, default 30"},
},
DryRun: dryRunFieldSearchOptions,
Execute: func(ctx context.Context, runtime *common.RuntimeContext) error {
Expand Down
1 change: 1 addition & 0 deletions shortcuts/base/field_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ var BaseFieldUpdate = common.Shortcut{
{Name: "i-have-read-guide", Type: "bool", Desc: "acknowledge reading formula/lookup guide before creating or updating those field types", Hidden: true},
},
Tips: []string{
baseHighRiskYesTip,
`Example: lark-cli base +field-update --base-token <base_token> --table-id <table_id> --field-id <field_id> --json '{"name":"Status","type":"text"}'`,
`Example: lark-cli base +field-update --base-token <base_token> --table-id <table_id> --field-id <field_id> --json '{"name":"Status","type":"select","multiple":false,"options":[{"name":"Todo"},{"name":"Done"}]}'`,
"Update uses full field-definition PUT semantics. Read the current field first with +field-get, then send the target state.",
Expand Down
8 changes: 4 additions & 4 deletions shortcuts/base/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestParseHelpers(t *testing.T) {
if err != nil || obj["name"] != "demo" {
t.Fatalf("obj=%v err=%v", obj, err)
}
if _, err := parseJSONObject(testPC, `[1]`, "json"); err == nil || !strings.Contains(err.Error(), "--json must be a JSON object") || !strings.Contains(err.Error(), "lark-base skill") || strings.Contains(err.Error(), "array") {
if _, err := parseJSONObject(testPC, `[1]`, "json"); err == nil || !strings.Contains(err.Error(), "--json must be a JSON object") || !strings.Contains(err.Error(), "match the documented shape") || strings.Contains(err.Error(), "array") {
t.Fatalf("err=%v", err)
}
if _, err := parseJSONObject(testPC, `null`, "json"); err == nil || !strings.Contains(err.Error(), "--json must be a JSON object") {
Expand Down Expand Up @@ -66,7 +66,7 @@ func TestParseHelpers(t *testing.T) {
if _, err := parseStringListFlexible(testPC, `[1]`, "fields"); err == nil || !strings.Contains(err.Error(), "invalid JSON string array") {
t.Fatalf("err=%v", err)
}
if _, err := parseJSONValue(testPC, "{", "json"); err == nil || !strings.Contains(err.Error(), "tip: pass a valid JSON directly") || !strings.Contains(err.Error(), "@file.json") || !strings.Contains(err.Error(), "lark-base skill") {
if _, err := parseJSONValue(testPC, "{", "json"); err == nil || !strings.Contains(err.Error(), "tip: pass a valid JSON directly") || !strings.Contains(err.Error(), "@file.json") || !strings.Contains(err.Error(), "complex JSON/DSL") {
t.Fatalf("err=%v", err)
}
if !reflect.DeepEqual(parseStringList("m,n"), []string{"m", "n"}) {
Expand Down Expand Up @@ -334,11 +334,11 @@ func TestJSONInputHelpers(t *testing.T) {
t.Fatalf("err=%v", err)
}
syntaxErr := formatJSONError("json", "object", &json.SyntaxError{Offset: 7})
if !strings.Contains(syntaxErr.Error(), "near byte 7") || !strings.Contains(syntaxErr.Error(), "tip: pass a valid JSON directly") || !strings.Contains(syntaxErr.Error(), "@file.json") || !strings.Contains(syntaxErr.Error(), "lark-base skill") {
if !strings.Contains(syntaxErr.Error(), "near byte 7") || !strings.Contains(syntaxErr.Error(), "tip: pass a valid JSON directly") || !strings.Contains(syntaxErr.Error(), "@file.json") || !strings.Contains(syntaxErr.Error(), "complex JSON/DSL") {
t.Fatalf("syntaxErr=%v", syntaxErr)
}
typeErr := formatJSONError("json", "object", &json.UnmarshalTypeError{Field: "filter_info"})
if !strings.Contains(typeErr.Error(), `field "filter_info"`) || !strings.Contains(typeErr.Error(), "tip: pass a valid JSON directly") || !strings.Contains(typeErr.Error(), "@file.json") || !strings.Contains(typeErr.Error(), "lark-base skill") {
if !strings.Contains(typeErr.Error(), `field "filter_info"`) || !strings.Contains(typeErr.Error(), "tip: pass a valid JSON directly") || !strings.Contains(typeErr.Error(), "@file.json") || !strings.Contains(typeErr.Error(), "complex JSON/DSL") {
t.Fatalf("typeErr=%v", typeErr)
}
}
Expand Down
6 changes: 6 additions & 0 deletions shortcuts/base/high_risk.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT

package base

const baseHighRiskYesTip = "This is a high-risk write command. If the user explicitly requested it and the target is unambiguous, pass --yes without asking again."
1 change: 1 addition & 0 deletions shortcuts/base/record_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var BaseRecordDelete = common.Shortcut{
{Name: "record-id", Type: "string_array", Desc: "record ID (repeatable)"},
{Name: "json", Desc: `JSON object with record_id_list, e.g. {"record_id_list":["rec_xxx"]}`},
},
Tips: []string{baseHighRiskYesTip},
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
return validateRecordSelection(runtime)
},
Expand Down
6 changes: 5 additions & 1 deletion shortcuts/base/record_history_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ var BaseRecordHistoryList = common.Shortcut{
tableRefFlag(true),
recordRefFlag(true),
{Name: "max-version", Type: "int", Desc: "max version for next page"},
{Name: "page-size", Type: "int", Default: "30", Desc: "pagination size"},
{Name: "page-size", Type: "int", Default: "30", Desc: "pagination size, max 50"},
},
Tips: []string{
`Example: lark-cli base +record-history-list --base-token <base_token> --table-id <table_id> --record-id <record_id>`,
"This reads one record's history only; it is not a table-wide audit scan.",
},
DryRun: dryRunRecordHistoryList,
Execute: func(ctx context.Context, runtime *common.RuntimeContext) error {
Expand Down
4 changes: 2 additions & 2 deletions shortcuts/base/record_share_link_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ var BaseRecordShareLinkCreate = common.Shortcut{
{Name: "record-ids", Type: "string_slice", Desc: "record IDs to generate share links for (comma-separated or repeatable, max 100)", Required: true},
},
Tips: []string{
`Single record: --base-token xxx --table-id tblxxx --record-ids recxxx`,
`Multiple records: --base-token xxx --table-id tblxxx --record-ids rec001,rec002,rec003`,
`Example: lark-cli base +record-share-link-create --base-token <base_token> --table-id <table_id> --record-ids rec_1,rec_2`,
"Max 100 record IDs per call; duplicate IDs are ignored.",
},
Validate: func(ctx context.Context, runtime *common.RuntimeContext) error {
return validateRecordShareBatch(runtime)
Expand Down
1 change: 1 addition & 0 deletions shortcuts/base/record_upload_attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ var BaseRecordRemoveAttachment = common.Shortcut{
{Name: "file-token", Type: "string_array", Desc: "attachment file_token to remove from the target cell; repeat to remove multiple attachments; max 50 tokens", Required: true},
},
Tips: []string{
baseHighRiskYesTip,
`Example: lark-cli base +record-remove-attachment --base-token <base_token> --table-id <table_id> --record-id <record_id> --field-id <attachment_field_id> --file-token <file_token> --yes`,
`Repeat --file-token to remove multiple attachments from the same cell in one call.`,
`This is a high-risk write command and requires --yes.`,
Expand Down
Loading
Loading