From 57212eaaa7fc83a77cdddd76ce05d5485be9e4e8 Mon Sep 17 00:00:00 2001 From: zgz2048 Date: Fri, 29 May 2026 16:26:06 +0800 Subject: [PATCH] docs: optimize base skill references --- shortcuts/base/base_advperm_disable.go | 4 + shortcuts/base/base_copy.go | 5 + shortcuts/base/base_create.go | 4 + shortcuts/base/base_execute_test.go | 2 +- shortcuts/base/base_form_delete.go | 1 + shortcuts/base/base_form_list.go | 2 +- shortcuts/base/base_form_questions_delete.go | 1 + shortcuts/base/base_role_create.go | 5 + shortcuts/base/base_role_delete.go | 5 + shortcuts/base/base_role_get.go | 4 + shortcuts/base/base_role_list.go | 4 + shortcuts/base/base_role_update.go | 6 + shortcuts/base/base_shortcut_helpers.go | 2 +- shortcuts/base/base_shortcuts_test.go | 19 + shortcuts/base/dashboard_arrange.go | 3 + shortcuts/base/dashboard_block_create.go | 5 + shortcuts/base/dashboard_block_delete.go | 1 + shortcuts/base/dashboard_block_list.go | 2 +- shortcuts/base/dashboard_block_update.go | 6 + shortcuts/base/dashboard_create.go | 2 +- shortcuts/base/dashboard_delete.go | 1 + shortcuts/base/dashboard_list.go | 2 +- shortcuts/base/dashboard_update.go | 2 +- shortcuts/base/field_delete.go | 1 + shortcuts/base/field_list.go | 2 +- shortcuts/base/field_search_options.go | 2 +- shortcuts/base/field_update.go | 1 + shortcuts/base/helpers_test.go | 8 +- shortcuts/base/high_risk.go | 6 + shortcuts/base/record_delete.go | 1 + shortcuts/base/record_history_list.go | 6 +- shortcuts/base/record_share_link_create.go | 4 +- shortcuts/base/record_upload_attachment.go | 1 + shortcuts/base/table_create.go | 5 + shortcuts/base/table_delete.go | 1 + shortcuts/base/table_list.go | 2 +- shortcuts/base/view_create.go | 5 +- shortcuts/base/view_delete.go | 1 + shortcuts/base/view_list.go | 2 +- shortcuts/base/view_set_card.go | 2 +- shortcuts/base/view_set_group.go | 2 +- shortcuts/base/view_set_sort.go | 5 +- shortcuts/base/view_set_timebar.go | 2 +- shortcuts/base/view_set_visible_fields.go | 2 +- shortcuts/base/workflow_create.go | 2 +- shortcuts/base/workflow_get.go | 2 +- shortcuts/base/workflow_list.go | 2 +- shortcuts/base/workflow_update.go | 2 +- skill-template/domains/base.md | 2 +- skills/lark-base/SKILL.md | 494 ++++++------------ skills/lark-base/references/examples.md | 140 ----- .../references/lark-base-advperm-disable.md | 83 --- .../references/lark-base-advperm-enable.md | 80 --- .../references/lark-base-base-copy.md | 74 --- .../references/lark-base-base-create.md | 68 --- .../references/lark-base-base-get.md | 39 -- .../references/lark-base-dashboard-arrange.md | 83 --- .../lark-base-dashboard-block-create.md | 108 ---- .../lark-base-dashboard-block-delete.md | 46 -- .../lark-base-dashboard-block-get-data.md | 6 +- .../lark-base-dashboard-block-get.md | 57 -- .../lark-base-dashboard-block-list.md | 53 -- .../lark-base-dashboard-block-update.md | 84 --- .../references/lark-base-dashboard-create.md | 73 --- .../references/lark-base-dashboard-delete.md | 44 -- .../references/lark-base-dashboard-get.md | 59 --- .../references/lark-base-dashboard-list.md | 52 -- .../references/lark-base-dashboard-update.md | 69 --- .../references/lark-base-dashboard.md | 49 +- .../references/lark-base-data-analysis-sop.md | 8 +- .../references/lark-base-field-create.md | 1 - .../references/lark-base-field-delete.md | 51 -- .../references/lark-base-field-get.md | 42 -- .../references/lark-base-field-list.md | 44 -- .../lark-base-field-search-options.md | 48 -- .../references/lark-base-field-update.md | 3 +- .../lark-base/references/lark-base-field.md | 23 - .../references/lark-base-form-create.md | 87 --- .../references/lark-base-form-delete.md | 64 --- .../references/lark-base-form-detail.md | 319 ----------- .../references/lark-base-form-get.md | 68 --- .../references/lark-base-form-list.md | 73 --- .../lark-base-form-questions-delete.md | 68 --- .../lark-base-form-questions-list.md | 84 --- .../references/lark-base-form-questions.md | 23 - .../references/lark-base-form-submit.md | 5 +- .../references/lark-base-form-update.md | 82 --- skills/lark-base/references/lark-base-form.md | 25 - .../lark-base/references/lark-base-history.md | 16 - .../lark-base-record-batch-create.md | 1 - .../lark-base-record-batch-update.md | 1 - .../references/lark-base-record-delete.md | 62 --- .../lark-base-record-history-list.md | 86 --- .../lark-base-record-share-link-create.md | 72 --- .../references/lark-base-record-upsert.md | 1 - .../lark-base/references/lark-base-record.md | 31 -- .../references/lark-base-role-create.md | 89 ---- .../references/lark-base-role-delete.md | 83 --- .../references/lark-base-role-get.md | 87 --- .../references/lark-base-role-list.md | 81 --- .../references/lark-base-role-update.md | 94 ---- .../references/lark-base-table-create.md | 62 --- .../references/lark-base-table-delete.md | 51 -- .../references/lark-base-table-get.md | 46 -- .../references/lark-base-table-list.md | 43 -- .../references/lark-base-table-update.md | 49 -- .../lark-base/references/lark-base-table.md | 20 - .../references/lark-base-view-create.md | 50 -- .../references/lark-base-view-delete.md | 48 -- .../references/lark-base-view-get-card.md | 38 -- .../references/lark-base-view-get-filter.md | 38 -- .../references/lark-base-view-get-group.md | 38 -- .../references/lark-base-view-get-sort.md | 38 -- .../references/lark-base-view-get-timebar.md | 38 -- .../lark-base-view-get-visible-fields.md | 28 - .../references/lark-base-view-get.md | 38 -- .../references/lark-base-view-list.md | 44 -- .../references/lark-base-view-rename.md | 44 -- .../references/lark-base-view-set-card.md | 55 -- .../references/lark-base-view-set-filter.md | 4 +- .../references/lark-base-view-set-group.md | 65 --- .../references/lark-base-view-set-sort.md | 63 --- .../references/lark-base-view-set-timebar.md | 51 -- .../lark-base-view-set-visible-fields.md | 46 -- skills/lark-base/references/lark-base-view.md | 44 -- .../references/lark-base-workflow-create.md | 180 ------- .../references/lark-base-workflow-disable.md | 94 ---- .../references/lark-base-workflow-enable.md | 94 ---- .../references/lark-base-workflow-get.md | 147 ------ .../references/lark-base-workflow-guide.md | 6 +- .../references/lark-base-workflow-list.md | 124 ----- .../references/lark-base-workflow-schema.md | 5 +- .../references/lark-base-workflow-update.md | 167 ------ .../references/lark-base-workflow.md | 23 - .../references/lark-base-workspace.md | 18 - skills/lark-base/references/role-config.md | 2 +- 136 files changed, 309 insertions(+), 5334 deletions(-) create mode 100644 shortcuts/base/high_risk.go delete mode 100644 skills/lark-base/references/examples.md delete mode 100644 skills/lark-base/references/lark-base-advperm-disable.md delete mode 100644 skills/lark-base/references/lark-base-advperm-enable.md delete mode 100644 skills/lark-base/references/lark-base-base-copy.md delete mode 100644 skills/lark-base/references/lark-base-base-create.md delete mode 100644 skills/lark-base/references/lark-base-base-get.md delete mode 100644 skills/lark-base/references/lark-base-dashboard-arrange.md delete mode 100644 skills/lark-base/references/lark-base-dashboard-block-create.md delete mode 100644 skills/lark-base/references/lark-base-dashboard-block-delete.md delete mode 100644 skills/lark-base/references/lark-base-dashboard-block-get.md delete mode 100644 skills/lark-base/references/lark-base-dashboard-block-list.md delete mode 100644 skills/lark-base/references/lark-base-dashboard-block-update.md delete mode 100644 skills/lark-base/references/lark-base-dashboard-create.md delete mode 100644 skills/lark-base/references/lark-base-dashboard-delete.md delete mode 100644 skills/lark-base/references/lark-base-dashboard-get.md delete mode 100644 skills/lark-base/references/lark-base-dashboard-list.md delete mode 100644 skills/lark-base/references/lark-base-dashboard-update.md delete mode 100644 skills/lark-base/references/lark-base-field-delete.md delete mode 100644 skills/lark-base/references/lark-base-field-get.md delete mode 100644 skills/lark-base/references/lark-base-field-list.md delete mode 100644 skills/lark-base/references/lark-base-field-search-options.md delete mode 100644 skills/lark-base/references/lark-base-field.md delete mode 100644 skills/lark-base/references/lark-base-form-create.md delete mode 100644 skills/lark-base/references/lark-base-form-delete.md delete mode 100644 skills/lark-base/references/lark-base-form-detail.md delete mode 100644 skills/lark-base/references/lark-base-form-get.md delete mode 100644 skills/lark-base/references/lark-base-form-list.md delete mode 100644 skills/lark-base/references/lark-base-form-questions-delete.md delete mode 100644 skills/lark-base/references/lark-base-form-questions-list.md delete mode 100644 skills/lark-base/references/lark-base-form-questions.md delete mode 100644 skills/lark-base/references/lark-base-form-update.md delete mode 100644 skills/lark-base/references/lark-base-form.md delete mode 100644 skills/lark-base/references/lark-base-history.md delete mode 100644 skills/lark-base/references/lark-base-record-delete.md delete mode 100644 skills/lark-base/references/lark-base-record-history-list.md delete mode 100644 skills/lark-base/references/lark-base-record-share-link-create.md delete mode 100644 skills/lark-base/references/lark-base-record.md delete mode 100644 skills/lark-base/references/lark-base-role-create.md delete mode 100644 skills/lark-base/references/lark-base-role-delete.md delete mode 100644 skills/lark-base/references/lark-base-role-get.md delete mode 100644 skills/lark-base/references/lark-base-role-list.md delete mode 100644 skills/lark-base/references/lark-base-role-update.md delete mode 100644 skills/lark-base/references/lark-base-table-create.md delete mode 100644 skills/lark-base/references/lark-base-table-delete.md delete mode 100644 skills/lark-base/references/lark-base-table-get.md delete mode 100644 skills/lark-base/references/lark-base-table-list.md delete mode 100644 skills/lark-base/references/lark-base-table-update.md delete mode 100644 skills/lark-base/references/lark-base-table.md delete mode 100644 skills/lark-base/references/lark-base-view-create.md delete mode 100644 skills/lark-base/references/lark-base-view-delete.md delete mode 100644 skills/lark-base/references/lark-base-view-get-card.md delete mode 100644 skills/lark-base/references/lark-base-view-get-filter.md delete mode 100644 skills/lark-base/references/lark-base-view-get-group.md delete mode 100644 skills/lark-base/references/lark-base-view-get-sort.md delete mode 100644 skills/lark-base/references/lark-base-view-get-timebar.md delete mode 100644 skills/lark-base/references/lark-base-view-get-visible-fields.md delete mode 100644 skills/lark-base/references/lark-base-view-get.md delete mode 100644 skills/lark-base/references/lark-base-view-list.md delete mode 100644 skills/lark-base/references/lark-base-view-rename.md delete mode 100644 skills/lark-base/references/lark-base-view-set-card.md delete mode 100644 skills/lark-base/references/lark-base-view-set-group.md delete mode 100644 skills/lark-base/references/lark-base-view-set-sort.md delete mode 100644 skills/lark-base/references/lark-base-view-set-timebar.md delete mode 100644 skills/lark-base/references/lark-base-view-set-visible-fields.md delete mode 100644 skills/lark-base/references/lark-base-view.md delete mode 100644 skills/lark-base/references/lark-base-workflow-create.md delete mode 100644 skills/lark-base/references/lark-base-workflow-disable.md delete mode 100644 skills/lark-base/references/lark-base-workflow-enable.md delete mode 100644 skills/lark-base/references/lark-base-workflow-get.md delete mode 100644 skills/lark-base/references/lark-base-workflow-list.md delete mode 100644 skills/lark-base/references/lark-base-workflow-update.md delete mode 100644 skills/lark-base/references/lark-base-workflow.md delete mode 100644 skills/lark-base/references/lark-base-workspace.md diff --git a/shortcuts/base/base_advperm_disable.go b/shortcuts/base/base_advperm_disable.go index 3266d9bca..59266bb19 100644 --- a/shortcuts/base/base_advperm_disable.go +++ b/shortcuts/base/base_advperm_disable.go @@ -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") diff --git a/shortcuts/base/base_copy.go b/shortcuts/base/base_copy.go index cb12e0e01..5e2210a85 100644 --- a/shortcuts/base/base_copy.go +++ b/shortcuts/base/base_copy.go @@ -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 --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) diff --git a/shortcuts/base/base_create.go b/shortcuts/base/base_create.go index af4286638..47d5e27ed 100644 --- a/shortcuts/base/base_create.go +++ b/shortcuts/base/base_create.go @@ -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) diff --git a/shortcuts/base/base_execute_test.go b/shortcuts/base/base_execute_test.go index 97e500e50..3ec741ae9 100644 --- a/shortcuts/base/base_execute_test.go +++ b/shortcuts/base/base_execute_test.go @@ -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") { diff --git a/shortcuts/base/base_form_delete.go b/shortcuts/base/base_form_delete.go index f6be4691e..e0fdb58fa 100644 --- a/shortcuts/base/base_form_delete.go +++ b/shortcuts/base/base_form_delete.go @@ -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"). diff --git a/shortcuts/base/base_form_list.go b/shortcuts/base/base_form_list.go index 07ead6e5b..34f5bfe0f 100644 --- a/shortcuts/base/base_form_list.go +++ b/shortcuts/base/base_form_list.go @@ -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(). diff --git a/shortcuts/base/base_form_questions_delete.go b/shortcuts/base/base_form_questions_delete.go index 4a3b03873..a1160aa46 100644 --- a/shortcuts/base/base_form_questions_delete.go +++ b/shortcuts/base/base_form_questions_delete.go @@ -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"). diff --git a/shortcuts/base/base_role_create.go b/shortcuts/base/base_role_create.go index 18b4cb2dc..29b579923 100644 --- a/shortcuts/base/base_role_create.go +++ b/shortcuts/base/base_role_create.go @@ -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") diff --git a/shortcuts/base/base_role_delete.go b/shortcuts/base/base_role_delete.go index 0c5627fc3..1ef361ef5 100644 --- a/shortcuts/base/base_role_delete.go +++ b/shortcuts/base/base_role_delete.go @@ -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") diff --git a/shortcuts/base/base_role_get.go b/shortcuts/base/base_role_get.go index ada1c9940..4d9fde715 100644 --- a/shortcuts/base/base_role_get.go +++ b/shortcuts/base/base_role_get.go @@ -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 --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") diff --git a/shortcuts/base/base_role_list.go b/shortcuts/base/base_role_list.go index 08bc29341..46f7dc463 100644 --- a/shortcuts/base/base_role_list.go +++ b/shortcuts/base/base_role_list.go @@ -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 `, + "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") diff --git a/shortcuts/base/base_role_update.go b/shortcuts/base/base_role_update.go index 8c05c4d89..a2c937544 100644 --- a/shortcuts/base/base_role_update.go +++ b/shortcuts/base/base_role_update.go @@ -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") diff --git a/shortcuts/base/base_shortcut_helpers.go b/shortcuts/base/base_shortcut_helpers.go index 67ea64c6e..8d42fe4da 100644 --- a/shortcuts/base/base_shortcut_helpers.go +++ b/shortcuts/base/base_shortcut_helpers.go @@ -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 { diff --git a/shortcuts/base/base_shortcuts_test.go b/shortcuts/base/base_shortcuts_test.go index 3e3926566..cf6c5ddb5 100644 --- a/shortcuts/base/base_shortcuts_test.go +++ b/shortcuts/base/base_shortcuts_test.go @@ -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{}) diff --git a/shortcuts/base/dashboard_arrange.go b/shortcuts/base/dashboard_arrange.go index 320b704a3..ab031add0 100644 --- a/shortcuts/base/dashboard_arrange.go +++ b/shortcuts/base/dashboard_arrange.go @@ -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) diff --git a/shortcuts/base/dashboard_block_create.go b/shortcuts/base/dashboard_block_create.go index e74671d9d..cd0f8dd34 100644 --- a/shortcuts/base/dashboard_block_create.go +++ b/shortcuts/base/dashboard_block_create.go @@ -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") { diff --git a/shortcuts/base/dashboard_block_delete.go b/shortcuts/base/dashboard_block_delete.go index 97d667a98..dfe36e330 100644 --- a/shortcuts/base/dashboard_block_delete.go +++ b/shortcuts/base/dashboard_block_delete.go @@ -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"). diff --git a/shortcuts/base/dashboard_block_list.go b/shortcuts/base/dashboard_block_list.go index 852dcc18b..9a9137a4d 100644 --- a/shortcuts/base/dashboard_block_list.go +++ b/shortcuts/base/dashboard_block_list.go @@ -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 { diff --git a/shortcuts/base/dashboard_block_update.go b/shortcuts/base/dashboard_block_update.go index 6f8a37dc9..cef72d75e 100644 --- a/shortcuts/base/dashboard_block_update.go +++ b/shortcuts/base/dashboard_block_update.go @@ -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") { diff --git a/shortcuts/base/dashboard_create.go b/shortcuts/base/dashboard_create.go index 214d8d175..6e8adb1b2 100644 --- a/shortcuts/base/dashboard_create.go +++ b/shortcuts/base/dashboard_create.go @@ -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{}{} diff --git a/shortcuts/base/dashboard_delete.go b/shortcuts/base/dashboard_delete.go index 5d6df0064..a685bc8fe 100644 --- a/shortcuts/base/dashboard_delete.go +++ b/shortcuts/base/dashboard_delete.go @@ -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"). diff --git a/shortcuts/base/dashboard_list.go b/shortcuts/base/dashboard_list.go index 8d270daa0..eacf9d63d 100644 --- a/shortcuts/base/dashboard_list.go +++ b/shortcuts/base/dashboard_list.go @@ -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 { diff --git a/shortcuts/base/dashboard_update.go b/shortcuts/base/dashboard_update.go index 5832e9021..f9dda81a4 100644 --- a/shortcuts/base/dashboard_update.go +++ b/shortcuts/base/dashboard_update.go @@ -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{}{} diff --git a/shortcuts/base/field_delete.go b/shortcuts/base/field_delete.go index d242763d1..264d9f067 100644 --- a/shortcuts/base/field_delete.go +++ b/shortcuts/base/field_delete.go @@ -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) diff --git a/shortcuts/base/field_list.go b/shortcuts/base/field_list.go index da487827b..7851a6f91 100644 --- a/shortcuts/base/field_list.go +++ b/shortcuts/base/field_list.go @@ -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 { diff --git a/shortcuts/base/field_search_options.go b/shortcuts/base/field_search_options.go index 674cfe6ba..b5671c593 100644 --- a/shortcuts/base/field_search_options.go +++ b/shortcuts/base/field_search_options.go @@ -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 { diff --git a/shortcuts/base/field_update.go b/shortcuts/base/field_update.go index f8e8a47d0..e74d2ca16 100644 --- a/shortcuts/base/field_update.go +++ b/shortcuts/base/field_update.go @@ -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 --table-id --field-id --json '{"name":"Status","type":"text"}'`, `Example: lark-cli base +field-update --base-token --table-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.", diff --git a/shortcuts/base/helpers_test.go b/shortcuts/base/helpers_test.go index 1038c33e9..a49f0efc4 100644 --- a/shortcuts/base/helpers_test.go +++ b/shortcuts/base/helpers_test.go @@ -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") { @@ -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"}) { @@ -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) } } diff --git a/shortcuts/base/high_risk.go b/shortcuts/base/high_risk.go new file mode 100644 index 000000000..dd34bf034 --- /dev/null +++ b/shortcuts/base/high_risk.go @@ -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." diff --git a/shortcuts/base/record_delete.go b/shortcuts/base/record_delete.go index 158ddcb50..10dd8a76c 100644 --- a/shortcuts/base/record_delete.go +++ b/shortcuts/base/record_delete.go @@ -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) }, diff --git a/shortcuts/base/record_history_list.go b/shortcuts/base/record_history_list.go index 3a2f08e6e..896de0d42 100644 --- a/shortcuts/base/record_history_list.go +++ b/shortcuts/base/record_history_list.go @@ -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 --table-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 { diff --git a/shortcuts/base/record_share_link_create.go b/shortcuts/base/record_share_link_create.go index 8baf3589a..02e875a70 100644 --- a/shortcuts/base/record_share_link_create.go +++ b/shortcuts/base/record_share_link_create.go @@ -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 --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) diff --git a/shortcuts/base/record_upload_attachment.go b/shortcuts/base/record_upload_attachment.go index 19ea464a7..33f7998b5 100644 --- a/shortcuts/base/record_upload_attachment.go +++ b/shortcuts/base/record_upload_attachment.go @@ -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 --table-id --record-id --field-id --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.`, diff --git a/shortcuts/base/table_create.go b/shortcuts/base/table_create.go index 3bb65a8a1..b1b1d09a0 100644 --- a/shortcuts/base/table_create.go +++ b/shortcuts/base/table_create.go @@ -22,6 +22,11 @@ var BaseTableCreate = common.Shortcut{ {Name: "view", Desc: "view JSON object/array for create"}, {Name: "fields", Desc: "field JSON array for create"}, }, + Tips: []string{ + `Example: lark-cli base +table-create --base-token --name "Tasks"`, + `Example with fields: --fields '[{"name":"Title","type":"text"},{"name":"Status","type":"select","options":[{"name":"Todo"},{"name":"Done"}]}]'`, + "Use lark-base-shortcut-field-properties.md for non-trivial field JSON; the first --fields item replaces the default field.", + }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { return validateTableCreate(runtime) }, diff --git a/shortcuts/base/table_delete.go b/shortcuts/base/table_delete.go index 58ad50100..72e5ce0b0 100644 --- a/shortcuts/base/table_delete.go +++ b/shortcuts/base/table_delete.go @@ -17,6 +17,7 @@ var BaseTableDelete = common.Shortcut{ Scopes: []string{"base:table:delete"}, AuthTypes: authTypes(), Flags: []common.Flag{baseTokenFlag(true), tableRefFlag(true)}, + Tips: []string{baseHighRiskYesTip}, DryRun: dryRunTableDelete, Execute: func(ctx context.Context, runtime *common.RuntimeContext) error { return executeTableDelete(runtime) diff --git a/shortcuts/base/table_list.go b/shortcuts/base/table_list.go index 01de1572d..6c5e58520 100644 --- a/shortcuts/base/table_list.go +++ b/shortcuts/base/table_list.go @@ -19,7 +19,7 @@ var BaseTableList = common.Shortcut{ Flags: []common.Flag{ baseTokenFlag(true), {Name: "offset", Type: "int", Default: "0", Desc: "pagination offset"}, - {Name: "limit", Type: "int", Default: "50", Desc: "pagination limit"}, + {Name: "limit", Type: "int", Default: "50", Desc: "pagination size, range 1-100"}, }, DryRun: dryRunTableList, Execute: func(ctx context.Context, runtime *common.RuntimeContext) error { diff --git a/shortcuts/base/view_create.go b/shortcuts/base/view_create.go index 6e38b0453..33807f75e 100644 --- a/shortcuts/base/view_create.go +++ b/shortcuts/base/view_create.go @@ -19,11 +19,12 @@ var BaseViewCreate = common.Shortcut{ Flags: []common.Flag{ baseTokenFlag(true), tableRefFlag(true), - {Name: "json", Desc: "view JSON object/array", Required: true}, + {Name: "json", Desc: "view JSON object/array; type defaults to grid; type range: grid, kanban, gallery, calendar, gantt", Required: true}, }, Tips: []string{ `Example: --json '{"name":"Main","type":"grid"}'`, - "Agent hint: use the lark-base skill's view-create guide for usage and limits.", + `Minimal: --json '{"name":"Main"}' creates a grid view.`, + `Use +view-set-visible-fields after creation when the user needs a specific field order or visibility.`, }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { return validateViewCreate(runtime) diff --git a/shortcuts/base/view_delete.go b/shortcuts/base/view_delete.go index 5db39902b..7ca2dd973 100644 --- a/shortcuts/base/view_delete.go +++ b/shortcuts/base/view_delete.go @@ -17,6 +17,7 @@ var BaseViewDelete = common.Shortcut{ Scopes: []string{"base:view:write_only"}, AuthTypes: authTypes(), Flags: []common.Flag{baseTokenFlag(true), tableRefFlag(true), viewRefFlag(true)}, + Tips: []string{baseHighRiskYesTip}, DryRun: dryRunViewDelete, Execute: func(ctx context.Context, runtime *common.RuntimeContext) error { return executeViewDelete(runtime) diff --git a/shortcuts/base/view_list.go b/shortcuts/base/view_list.go index 30fba37be..141b26152 100644 --- a/shortcuts/base/view_list.go +++ b/shortcuts/base/view_list.go @@ -20,7 +20,7 @@ var BaseViewList = 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: dryRunViewList, Execute: func(ctx context.Context, runtime *common.RuntimeContext) error { diff --git a/shortcuts/base/view_set_card.go b/shortcuts/base/view_set_card.go index 410a9b46e..1a422cf55 100644 --- a/shortcuts/base/view_set_card.go +++ b/shortcuts/base/view_set_card.go @@ -24,7 +24,7 @@ var BaseViewSetCard = common.Shortcut{ }, Tips: []string{ `Example: --json '{"cover_field":"fldCover"}'`, - "Agent hint: use the lark-base skill's view-set-card guide for usage and limits.", + "Use +view-get-card first when updating an existing card view configuration.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { return validateViewJSONObject(runtime) diff --git a/shortcuts/base/view_set_group.go b/shortcuts/base/view_set_group.go index b96df3942..1ea16ea59 100644 --- a/shortcuts/base/view_set_group.go +++ b/shortcuts/base/view_set_group.go @@ -24,7 +24,7 @@ var BaseViewSetGroup = common.Shortcut{ }, Tips: []string{ `Example: --json '{"group_config":[{"field":"fldStatus","desc":false}]}'`, - "Agent hint: use the lark-base skill's view-set-group guide for usage and limits.", + "Use +view-get-group first when modifying an existing grouping configuration.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { return validateViewJSONObject(runtime) diff --git a/shortcuts/base/view_set_sort.go b/shortcuts/base/view_set_sort.go index 5ce24a562..3d8798b86 100644 --- a/shortcuts/base/view_set_sort.go +++ b/shortcuts/base/view_set_sort.go @@ -20,11 +20,12 @@ var BaseViewSetSort = common.Shortcut{ baseTokenFlag(true), tableRefFlag(true), viewRefFlag(true), - {Name: "json", Desc: "sort_config JSON object", Required: true}, + {Name: "json", Desc: "sort_config JSON object; sort_config supports max 10 items", Required: true}, }, Tips: []string{ `Example: --json '{"sort_config":[{"field":"fldPriority","desc":true}]}'`, - "Agent hint: use the lark-base skill's view-set-sort guide for usage and limits.", + "sort_config supports max 10 sort items.", + "Use +view-get-sort first when modifying an existing sort configuration.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { return validateViewJSONObject(runtime) diff --git a/shortcuts/base/view_set_timebar.go b/shortcuts/base/view_set_timebar.go index 88f23a936..ecbf43cc3 100644 --- a/shortcuts/base/view_set_timebar.go +++ b/shortcuts/base/view_set_timebar.go @@ -24,7 +24,7 @@ var BaseViewSetTimebar = common.Shortcut{ }, Tips: []string{ `Example: --json '{"start_time":"fldStart","end_time":"fldEnd","title":"fldTitle"}'`, - "Agent hint: use the lark-base skill's view-set-timebar guide for usage and limits.", + "Use +view-get-timebar first when modifying an existing timebar configuration.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { return validateViewJSONObject(runtime) diff --git a/shortcuts/base/view_set_visible_fields.go b/shortcuts/base/view_set_visible_fields.go index 48c7b0fb9..d702626cd 100644 --- a/shortcuts/base/view_set_visible_fields.go +++ b/shortcuts/base/view_set_visible_fields.go @@ -24,7 +24,7 @@ var BaseViewSetVisibleFields = common.Shortcut{ }, Tips: []string{ `Example: --json '{"visible_fields":["fldXXX"]}'`, - "Agent hint: use the lark-base skill's view-set-visible-fields guide for usage and limits.", + "visible_fields controls both visibility and order; include every field that should remain visible.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { return validateViewJSONObject(runtime) diff --git a/shortcuts/base/workflow_create.go b/shortcuts/base/workflow_create.go index c2c3c8c9d..c49df1e87 100644 --- a/shortcuts/base/workflow_create.go +++ b/shortcuts/base/workflow_create.go @@ -19,7 +19,7 @@ var BaseWorkflowCreate = common.Shortcut{ AuthTypes: []string{"user", "bot"}, Flags: []common.Flag{ {Name: "base-token", Desc: "base token", Required: true}, - {Name: "json", Desc: `workflow body JSON, e.g. {"title":"My Workflow","steps":[...]}`, Required: true}, + {Name: "json", Desc: `workflow body JSON, e.g. {"title":"My Workflow","steps":[...]}; user_id_type defaults to open_id, enum open_id/union_id/user_id`, Required: true}, }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { if strings.TrimSpace(runtime.Str("base-token")) == "" { diff --git a/shortcuts/base/workflow_get.go b/shortcuts/base/workflow_get.go index 2a7517be2..2b8316c1f 100644 --- a/shortcuts/base/workflow_get.go +++ b/shortcuts/base/workflow_get.go @@ -20,7 +20,7 @@ var BaseWorkflowGet = common.Shortcut{ Flags: []common.Flag{ {Name: "base-token", Desc: "base token", Required: true}, {Name: "workflow-id", Desc: "workflow ID (wkf... prefix)", Required: true}, - {Name: "user-id-type", Desc: "user ID type for creator/updater fields", Enum: []string{"open_id", "union_id", "user_id"}}, + {Name: "user-id-type", Desc: "user ID type for creator/updater fields, default open_id", Enum: []string{"open_id", "union_id", "user_id"}}, }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { if strings.TrimSpace(runtime.Str("base-token")) == "" { diff --git a/shortcuts/base/workflow_list.go b/shortcuts/base/workflow_list.go index 92a405400..42dea27bb 100644 --- a/shortcuts/base/workflow_list.go +++ b/shortcuts/base/workflow_list.go @@ -20,7 +20,7 @@ var BaseWorkflowList = common.Shortcut{ Flags: []common.Flag{ {Name: "base-token", Desc: "base token", Required: true}, {Name: "status", Desc: "filter by status", Enum: []string{"enabled", "disabled"}}, - {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"}, }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { if strings.TrimSpace(runtime.Str("base-token")) == "" { diff --git a/shortcuts/base/workflow_update.go b/shortcuts/base/workflow_update.go index ff56a7be4..af589e2b6 100644 --- a/shortcuts/base/workflow_update.go +++ b/shortcuts/base/workflow_update.go @@ -20,7 +20,7 @@ var BaseWorkflowUpdate = common.Shortcut{ Flags: []common.Flag{ {Name: "base-token", Desc: "base token", Required: true}, {Name: "workflow-id", Desc: "workflow ID (wkf... prefix)", Required: true}, - {Name: "json", Desc: `workflow body JSON, e.g. {"title":"New Title","steps":[...]}`, Required: true}, + {Name: "json", Desc: `workflow body JSON, e.g. {"title":"New Title","steps":[...]}; user_id_type defaults to open_id, enum open_id/union_id/user_id`, Required: true}, }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { if strings.TrimSpace(runtime.Str("base-token")) == "" { diff --git a/skill-template/domains/base.md b/skill-template/domains/base.md index b914a74a2..f2aa3e3d7 100644 --- a/skill-template/domains/base.md +++ b/skill-template/domains/base.md @@ -116,4 +116,4 @@ lark-cli wiki spaces.get_node --params '{"token":"Pgrrwvr***********UnRb"}' - [lark-base-shortcut-field-properties.md](../../skills/lark-base/references/lark-base-shortcut-field-properties.md) — 字段类型 JSON 配置 - [lark-base-cell-value.md](../../skills/lark-base/references/lark-base-cell-value.md) — CellValue source of truth - [lark-base-view-set-filter.md](../../skills/lark-base/references/lark-base-view-set-filter.md) — 查询筛选指南(filter / operator / sort / 分页) -- [examples.md](../../skills/lark-base/references/examples.md) — 完整操作示例(建表、筛选、更新) +- 具体命令示例由命令 --help 内置 tips 承接;复杂 JSON 只读上方保留 reference diff --git a/skills/lark-base/SKILL.md b/skills/lark-base/SKILL.md index e398f2cf1..63af20caa 100644 --- a/skills/lark-base/SKILL.md +++ b/skills/lark-base/SKILL.md @@ -1,7 +1,7 @@ --- name: lark-base version: 1.2.2 -description: "当需要用 lark-cli 操作飞书多维表格(Base)时调用:搜索 Base、建表、字段管理、记录读写、记录分享链接、视图配置、历史查询,以及角色/表单/仪表盘管理/工作流;也适用于把旧的 +table / +field / +record 写法改成当前命令写法。涉及字段设计、公式字段、查找引用、跨表计算、行级派生指标、数据分析需求时也必须使用本 skill。" +description: "飞书多维表格(Base)操作:建表、字段、记录、视图、统计、公式/lookup、表单、仪表盘、workflow、角色权限;遇到 Base/多维表格/bitable 或 /base/ 链接时使用。文件导入转 lark-drive,认证/授权转 lark-shared。" metadata: requires: bins: ["lark-cli"] @@ -10,353 +10,151 @@ metadata: # base -> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../lark-shared/SKILL.md)。 -> **执行前必做:** 执行任何 `base` 命令前,必须先阅读对应命令的 reference 文档,再调用命令。 -> **查询类任务必做:** 涉及筛选、排序、Top/Bottom N、聚合、多表关联、查询后写入或判断全局结论时,必须先阅读 [`references/lark-base-data-analysis-sop.md`](references/lark-base-data-analysis-sop.md),再选择 `record / view / data-query` 路径。 -> **命名约定:** Base 业务命令仅使用 `lark-cli base +...` 形式;解析 Wiki 链接使用 `lark-cli wiki +node-get`。 -> **分流规则:** 如果用户要“把本地文件导入成 Base / 多维表格 / bitable”,第一步不是 `base`,而是 `lark-cli drive +import --type bitable`;导入完成后再回到 `lark-cli base +...` 做表内操作。 - -## 1. 何时使用本 Skill - -### 1.1 触发条件 - -以下场景应使用本 skill: - -- 用户明确要操作飞书多维表格 / Base。 -- 用户要建表、改表、查表、删表,或管理字段、记录、视图。 -- 用户要做公式字段、lookup 字段、派生指标、跨表计算。 -- 用户要做临时统计、聚合分析、比较排序、求最值。 -- 用户要管理 workflow、dashboard、表单、角色权限。 -- 用户给出 `/base/{token}` 链接。 -- 用户给出 `/wiki/{token}` 链接,且最终解析为 `bitable`。 -- 用户要把旧的 Base 聚合式写法改成当前原子命令写法,例如把旧 `+table / +field / +record / +view / +history / +workspace` 改写成当前命令。 - -以下场景不应使用本 skill: - -- 用户只是做认证、初始化配置、切换 `--as user/bot`、处理 scope。此时先读 `../lark-shared/SKILL.md`。 -- 用户只是泛化地讨论“数据分析 / 字段设计”,但并不在 Base 场景中。不要因为提到“统计 / 公式 / lookup”就误触发。 - -### 1.2 前置约束 - -1. 先阅读 [`../lark-shared/SKILL.md`](../lark-shared/SKILL.md)。 -2. Base 业务命令仅使用 `lark-cli base +...` 形式的 shortcut 命令。 -3. 如果输入是 Wiki 链接或 Wiki token,并且用户想读取/操作其中的 Base,先执行 `lark-cli wiki +node-get --node-token `;当返回 `data.obj_type=bitable` 时,把 `data.obj_token` 当作 `--base-token`。不要把 URL 里的 `/wiki/{token}` 当成 Base token。(旧的 `--token` flag 仍可用,但已 deprecated,会在 stderr 打印迁移提示。) -4. 定位到命令后,先读该命令对应的 reference,再执行命令。 -5. 如果用户要把本地 Excel / CSV / `.base` 快照导入成 Base / 多维表格 / bitable,第一步不是 `base`,而是 `lark-cli drive +import --type bitable`;导入完成后再回到 `lark-cli base +...` 做表内操作。 -6. 不要在 Base 场景改走 `lark-cli api /open-apis/bitable/v1/...`。 -7. 如果用户只给 Base 名称、关键词,或说“帮我找一个多维表格”,先通过 `lark-cli drive +search --query --doc-types bitable` 搜索 Base / 多维表格资源;拿到 Base URL 后再使用本 skill 的 `base +...` 命令。复杂搜索再读 [`../lark-drive/references/lark-drive-search.md`](../lark-drive/references/lark-drive-search.md):标题精确匹配、限定 owner(`--mine` / `--creator-ids`,owner 语义非"最初创建人")/群/文件夹/时间范围、只搜标题/评论、分页/全量搜索。 - -## 2. 模块与命令导航 - -本章按“先选模块,再选命令”的方式组织。先判断用户目标属于哪个大模块,再进入对应子模块,按要求阅读 reference 后执行命令。 - -### 2.1 模块地图 - -| 大模块 | 处理什么问题 | 包含的小模块 / 能力 | -|------|-------------|-------------------| -| Base 模块 | 管理 Base 本体,或从链接进入 Base 场景 | `base-create / base-get / base-copy`,Base / Wiki 链接解析 | -| 表与数据模块 | 管理 Base 内部结构与日常数据操作 | `table / field / record / view` | -| 公式 / Lookup 模块 | 处理派生字段、条件判断、跨表计算、固定查找引用 | `formula / lookup` 字段创建与更新 | -| 数据分析模块 | 做一次性筛选、分组、聚合分析 | `data-query` | -| Workflow 模块 | 管理自动化流程 | `workflow-list / get / create / update / enable / disable` | -| Dashboard 模块 | 管理仪表盘和图表组件 | `dashboard-* / dashboard-block-*` | -| 表单模块 | 管理表单和表单题目 | `form-* / form-questions-*` | -| 权限与角色模块 | 管理高级权限和自定义角色 | `advperm-* / role-*` | - -### 2.2 Base 模块 - -用于管理 Base 本体,或从用户给出的链接进入后续 Base 操作。 -模块索引:[`references/lark-base-workspace.md`](references/lark-base-workspace.md) - -| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 | -|------|------------------|----------------|----------| -| `lark-cli drive +search --query --doc-types bitable` | 按名称、关键词查找 Base / 多维表格 / bitable | 复杂搜索再读 [`../lark-drive/references/lark-drive-search.md`](../lark-drive/references/lark-drive-search.md) | 先定位资源,再回到 `base +...` 操作表内数据 | -| `+base-create` | 创建新的 Base | [`lark-base-base-create.md`](references/lark-base-base-create.md)、[`lark-base-workspace.md`](references/lark-base-workspace.md) | 写入操作;执行前先读 reference;`--folder-token`、`--time-zone` 都是可选项 | -| `+base-get` | 获取 Base 信息 | [`lark-base-base-get.md`](references/lark-base-base-get.md)、[`lark-base-workspace.md`](references/lark-base-workspace.md) | 适合确认 Base 本体信息,不替代表/字段结构读取 | -| `+base-copy` | 复制已有 Base | [`lark-base-base-copy.md`](references/lark-base-base-copy.md)、[`lark-base-workspace.md`](references/lark-base-workspace.md) | 写入操作;执行前先读 reference;复制成功后应主动返回新 Base 标识信息 | - -### 2.3 表与数据模块 - -这是最常用的大模块,包含 `table / field / record / view` 四类子模块。 -补充示例:[`references/examples.md`](references/examples.md),适合需要串联 table / record / view 完整操作链路时再读。 - -#### 2.3.1 Table 子模块 - -子模块索引:[`references/lark-base-table.md`](references/lark-base-table.md) - -| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 | -|------|------------------|----------------|----------| -| `+table-list / +table-get` | 列出数据表,或获取单个表详情 | [`lark-base-table-list.md`](references/lark-base-table-list.md)、[`lark-base-table-get.md`](references/lark-base-table-get.md) | `+table-list` 只能串行执行;`+table-get` 适合删除/修改前确认目标 | -| `+table-create / +table-update / +table-delete` | 创建、更新或删除数据表 | [`lark-base-table-create.md`](references/lark-base-table-create.md)、[`lark-base-table-update.md`](references/lark-base-table-update.md)、[`lark-base-table-delete.md`](references/lark-base-table-delete.md) | 创建适合一次性建表;更新前先确认目标表;删除时用户已明确目标可直接执行并带 `--yes` | - -#### 2.3.2 Field 子模块 - -普通字段管理走这里;如果字段类型是 `formula` 或 `lookup`,转到下方“公式 / Lookup 模块”。 -子模块索引:[`references/lark-base-field.md`](references/lark-base-field.md) - -| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 | -|------|------------------|----------------|----------| -| `+field-list / +field-get` | 列出字段结构,或获取单个字段详情 | [`lark-base-field-list.md`](references/lark-base-field-list.md)、[`lark-base-field-get.md`](references/lark-base-field-get.md) | 写记录、写字段、做分析前常先读 `+field-list`;`+field-list` 只能串行执行;`+field-get` 适合删除/更新前确认目标 | -| `+field-create / +field-update / +field-delete` | 创建、更新或删除普通字段 | [`lark-base-field-create.md`](references/lark-base-field-create.md)、[`lark-base-field-update.md`](references/lark-base-field-update.md)、[`lark-base-field-delete.md`](references/lark-base-field-delete.md)、[`lark-base-shortcut-field-properties.md`](references/lark-base-shortcut-field-properties.md) | 写字段前先看字段属性规范;如果涉及类型转换,直接按 `+field-update` 中的字段类型变更规则执行,只在安全白名单内考虑原地转换;如果类型是 `formula / lookup`,先转去读对应 guide;更新或删除时用户已明确目标可直接执行并带 `--yes` | -| `+field-search-options` | 查询字段可选项 | [`lark-base-field-search-options.md`](references/lark-base-field-search-options.md) | 适合单选/多选等选项型字段 | - -#### 2.3.3 Record 子模块 - -子模块索引:[`references/lark-base-record.md`](references/lark-base-record.md)、[`references/lark-base-history.md`](references/lark-base-history.md) - -| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 | -|------|------------------|----------------|----------| -| `+record-search / +record-list / +record-get` | 按关键词检索记录、读取记录明细 / 分页导出,或按 ID 获取一条或多条记录 | [`lark-base-data-analysis-sop.md`](references/lark-base-data-analysis-sop.md) | 记录读取统一先读 data analysis SOP:已知 `record_id` 用 `+record-get`;明确关键词用 `+record-search`;普通明细用 `+record-list`;明确筛选 / 排序 / Top N 用临时视图投影后 `+record-list --view-id`;统计聚合才分流到 `+data-query`;`+record-get` 支持重复 `--record-id` 或 `--json` 读取多条记录 | -| `+record-upsert / +record-batch-create / +record-batch-update` | 创建、更新或批量写入记录 | [`lark-base-record-upsert.md`](references/lark-base-record-upsert.md)、[`lark-base-record-batch-create.md`](references/lark-base-record-batch-create.md)、[`lark-base-record-batch-update.md`](references/lark-base-record-batch-update.md)、[`lark-base-cell-value.md`](references/lark-base-cell-value.md) | 写前先 `+field-list`;只写存储字段;`+record-batch-update` 为同值更新(同一 patch 应用到多条记录);批量单次不超过 `200` 条;附件不要走这里 | -| `+record-upload-attachment` | 给已有记录上传一个或多个附件 | 看 `lark-cli base +record-upload-attachment --help` | 附件上传专用链路,不要用 `+record-upsert` / `+record-batch-*` 伪造附件值;不支持 `--name` | -| `+record-download-attachment` | 下载一个或多个 Base 附件到本地 | 看 `lark-cli base +record-download-attachment --help` | Base 附件必须用这个命令下载;用其他下载入口可能失败 | -| `+record-remove-attachment` | 删除附件字段里的一个或多个附件 | 看 `lark-cli base +record-remove-attachment --help` | 删除操作;确认目标后带 `--yes` | -| `+record-delete` | 删除一条或多条记录 | [`lark-base-record-delete.md`](references/lark-base-record-delete.md) | 删除多条时重复传 `--record-id` 指定多个记录;用户已明确目标可直接执行并带 `--yes` | -| `+record-history-list` | 查询指定记录的变更历史 | [`lark-base-record-history-list.md`](references/lark-base-record-history-list.md) | 按 `table-id + record-id` 查询,不支持整表扫描;`+record-history-list` 只能串行执行 | -| `+record-share-link-create` | 为一条或多条记录生成分享链接 | [`lark-base-record-share-link-create.md`](references/lark-base-record-share-link-create.md) | 单次最多 100 条;重复 record_id 会自动去重;适合分享单条记录或批量分享场景 | - -#### 2.3.4 View 子模块 - -子模块索引:[`references/lark-base-view.md`](references/lark-base-view.md) - -| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 | -|------|------------------|----------------|----------| -| `+view-list / +view-get` | 列出视图,或获取视图详情 | [`lark-base-view-list.md`](references/lark-base-view-list.md)、[`lark-base-view-get.md`](references/lark-base-view-get.md) | `+view-list` 只能串行执行;`+view-get` 适合查看已有视图配置 | -| `+view-create / +view-delete / +view-rename` | 创建、删除或重命名视图 | [`lark-base-view-create.md`](references/lark-base-view-create.md)、[`lark-base-view-delete.md`](references/lark-base-view-delete.md)、[`lark-base-view-rename.md`](references/lark-base-view-rename.md) | 创建前先确认表和视图类型;删除前先确认目标;用户已明确新名字时可直接重命名 | -| `+view-get-filter / +view-set-filter` | 读取或配置筛选条件 | [`lark-base-view-get-filter.md`](references/lark-base-view-get-filter.md)、[`lark-base-view-set-filter.md`](references/lark-base-view-set-filter.md)、[`lark-base-data-analysis-sop.md`](references/lark-base-data-analysis-sop.md) | 常与 `+record-list` 组合,用于按视图筛选读取 | -| `+view-get-sort / +view-set-sort` | 读取或配置排序 | [`lark-base-view-get-sort.md`](references/lark-base-view-get-sort.md)、[`lark-base-view-set-sort.md`](references/lark-base-view-set-sort.md) | 字段名必须来自真实结构 | -| `+view-get-group / +view-set-group` | 读取或配置分组 | [`lark-base-view-get-group.md`](references/lark-base-view-get-group.md)、[`lark-base-view-set-group.md`](references/lark-base-view-set-group.md) | 字段名必须来自真实结构 | -| `+view-get-visible-fields / +view-set-visible-fields` | 读取或配置视图可见字段 | [`lark-base-view-get-visible-fields.md`](references/lark-base-view-get-visible-fields.md)、[`lark-base-view-set-visible-fields.md`](references/lark-base-view-set-visible-fields.md) | 用于控制视图中的字段顺序与可见性;字段名必须来自真实结构 | -| `+view-get-card / +view-set-card` | 读取或配置卡片视图 | [`lark-base-view-get-card.md`](references/lark-base-view-get-card.md)、[`lark-base-view-set-card.md`](references/lark-base-view-set-card.md) | 适合卡片展示场景 | -| `+view-get-timebar / +view-set-timebar` | 读取或配置时间轴视图 | [`lark-base-view-get-timebar.md`](references/lark-base-view-get-timebar.md)、[`lark-base-view-set-timebar.md`](references/lark-base-view-set-timebar.md) | 适合时间线展示场景 | - -### 2.4 公式 / Lookup 模块 - -只要用户诉求涉及派生指标、条件判断、文本处理、日期差、跨表计算、跨表筛选后取值,都要先判断是否进入本模块。 - -默认优先考虑 `formula`:适合常规计算、条件判断、文本处理、日期差、跨表聚合,以及需要长期显示在表里的派生结果。 -只有当用户明确要求 `lookup`,或场景天然符合 `from / select / where / aggregate` 这种固定查找建模时,再使用 `lookup`。 - -| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 | -|------|------------------|----------------|----------| -| `+field-create`(`type=formula`) | 创建公式字段 | [`formula-field-guide.md`](references/formula-field-guide.md)、[`lark-base-field-create.md`](references/lark-base-field-create.md)、[`lark-base-shortcut-field-properties.md`](references/lark-base-shortcut-field-properties.md) | 没读 guide 前不要直接创建 | -| `+field-update`(`type=formula`) | 更新公式字段 | [`formula-field-guide.md`](references/formula-field-guide.md)、[`lark-base-field-update.md`](references/lark-base-field-update.md)、[`lark-base-shortcut-field-properties.md`](references/lark-base-shortcut-field-properties.md) | 先拿当前表结构 | -| `+field-create`(`type=lookup`) | 创建 lookup 字段 | [`lookup-field-guide.md`](references/lookup-field-guide.md)、[`lark-base-field-create.md`](references/lark-base-field-create.md)、[`lark-base-shortcut-field-properties.md`](references/lark-base-shortcut-field-properties.md) | 没读 guide 前不要直接创建 | -| `+field-update`(`type=lookup`) | 更新 lookup 字段 | [`lookup-field-guide.md`](references/lookup-field-guide.md)、[`lark-base-field-update.md`](references/lark-base-field-update.md)、[`lark-base-shortcut-field-properties.md`](references/lark-base-shortcut-field-properties.md) | 跨表时还要拿目标表结构 | - -### 2.5 数据分析模块 - -用于一次性分析和临时聚合查询。用户要的是“这次算出来的结果”,而不是把结果沉淀成字段时,优先进入本模块。 - -进入本模块前先确认几件事: - -- `+data-query` 只做聚合查询(分组、过滤、排序、聚合计算),不用于列出原始记录或逐条明细。 -- 调用者必须是目标多维表格的管理员,拥有目标多维表格的 FA(Full Access / 完全访问权限),否则会返回权限错误。 -- `+data-query` 只支持白名单字段类型;`formula`、`lookup`、附件、系统字段、关联等字段不能用于 `dimensions / measures / filters / sort`。 - -| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 | -|------|------------------|----------------|----------| -| `+data-query` | 做分组统计、SUM / AVG / COUNT / MAX / MIN、条件筛选后的聚合分析 | [`lark-base-data-query.md`](references/lark-base-data-query.md) | 字段名必须精确匹配真实字段名;不要用 `+record-list` / `+record-search` 拉全量再手算;`+data-query` 不返回原始记录;使用前先确认权限和字段类型是否受支持 | - -### 2.6 Workflow 模块 - -这是高约束模块。执行任何 workflow 命令前,都必须先读对应命令文档和 schema。 -模块索引:[`references/lark-base-workflow.md`](references/lark-base-workflow.md) - -| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 | -|------|------------------|----------------|----------| -| `+workflow-list / +workflow-get` | 列出 workflow,或获取完整 workflow 结构 | [`lark-base-workflow-list.md`](references/lark-base-workflow-list.md)、[`lark-base-workflow-get.md`](references/lark-base-workflow-get.md)、[`lark-base-workflow-schema.md`](references/lark-base-workflow-schema.md) | `+workflow-list` 只返回摘要且只能串行执行;需要完整结构时用 `+workflow-get` | -| `+workflow-create / +workflow-update` | 创建或更新 workflow | [`lark-base-workflow-create.md`](references/lark-base-workflow-create.md)、[`lark-base-workflow-update.md`](references/lark-base-workflow-update.md)、[`lark-base-workflow-schema.md`](references/lark-base-workflow-schema.md) | 先读 schema;禁止凭自然语言猜 `type`;先确认真实表名和字段名 | -| `+workflow-enable / +workflow-disable` | 启用或停用 workflow | [`lark-base-workflow-enable.md`](references/lark-base-workflow-enable.md)、[`lark-base-workflow-disable.md`](references/lark-base-workflow-disable.md)、[`lark-base-workflow-schema.md`](references/lark-base-workflow-schema.md) | 启用或停用前先确认目标 workflow;`workflow_id` 与 `table_id` 需按前缀区分 | - -### 2.7 Dashboard 模块 - -当用户提到“仪表盘、dashboard、数据看板、图表、可视化、block、组件、添加组件、创建图表”等关键词时,进入本模块,并先阅读 [`lark-base-dashboard.md`](references/lark-base-dashboard.md)。 - -| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 | -|------|------------------|----------------|----------| -| `+dashboard-list / +dashboard-get` | 列出仪表盘,或获取仪表盘详情 | [`lark-base-dashboard-list.md`](references/lark-base-dashboard-list.md)、[`lark-base-dashboard-get.md`](references/lark-base-dashboard-get.md)、[`lark-base-dashboard.md`](references/lark-base-dashboard.md) | 进入仪表盘语义后先读 guide;`+dashboard-list` 只能串行执行 | -| `+dashboard-create / +dashboard-update / +dashboard-delete` | 创建、更新或删除仪表盘 | [`lark-base-dashboard-create.md`](references/lark-base-dashboard-create.md)、[`lark-base-dashboard-update.md`](references/lark-base-dashboard-update.md)、[`lark-base-dashboard-delete.md`](references/lark-base-dashboard-delete.md)、[`lark-base-dashboard.md`](references/lark-base-dashboard.md) | 创建前先明确看板目标和展示场景;更新前先读取当前配置;删除前先确认目标 | -| `+dashboard-block-list / +dashboard-block-get` | 列出图表组件,或获取单个 block 详情 | [`lark-base-dashboard-block-list.md`](references/lark-base-dashboard-block-list.md)、[`lark-base-dashboard-block-get.md`](references/lark-base-dashboard-block-get.md)、[`lark-base-dashboard.md`](references/lark-base-dashboard.md)、[`dashboard-block-data-config.md`](references/dashboard-block-data-config.md) | `+dashboard-block-list` 只能串行执行;查看配置细节时读 block config 文档 | -| `+dashboard-block-get-data` | 获取图表组件的计算结果 | [`lark-base-dashboard-block-get-data.md`](references/lark-base-dashboard-block-get-data.md)、[`lark-base-dashboard.md`](references/lark-base-dashboard.md)、[`dashboard-block-data-config.md`](references/dashboard-block-data-config.md) | 适合读取图表组件的最终计算结果;此命令不返回 block 元数据,只返回计算结果 | -| `+dashboard-block-create / +dashboard-block-update / +dashboard-block-delete` | 创建、更新或删除图表组件 | [`lark-base-dashboard-block-create.md`](references/lark-base-dashboard-block-create.md)、[`lark-base-dashboard-block-update.md`](references/lark-base-dashboard-block-update.md)、[`lark-base-dashboard-block-delete.md`](references/lark-base-dashboard-block-delete.md)、[`lark-base-dashboard.md`](references/lark-base-dashboard.md)、[`dashboard-block-data-config.md`](references/dashboard-block-data-config.md) | 涉及 `data_config`、图表类型、filter 时要读 block config 文档;删除前先确认目标 | - -### 2.8 表单模块 - -用于管理表单本体和表单题目。 -模块索引:[`references/lark-base-form.md`](references/lark-base-form.md)、[`references/lark-base-form-questions.md`](references/lark-base-form-questions.md) -表单问题相关操作依赖 `form-id`;具体获取方式见 `form-list` 和 `form-create` 的 reference。 - -| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 | -|------|------------------|----------------|----------| -| `+form-list / +form-get` | 列出表单,或获取单个表单 | [`lark-base-form-list.md`](references/lark-base-form-list.md)、[`lark-base-form-get.md`](references/lark-base-form-get.md) | `+form-list` 可用来获取 `form-id`;`+form-get` 适合查看已有表单配置 | -| `+form-detail` | 通过表单分享链接获取表单详情(含题目列表、字段类型、校验规则) | [`lark-base-form-detail.md`](references/lark-base-form-detail.md) | 只读;仅需 `--share-token`(从分享链接提取),不需要 base-token/table-id/form-id;返回的 `questions` 可直接用于 `+form-submit` 构造参数 | -| `+form-submit` | 通过表单分享链接填写并提交表单(支持普通字段 + 附件上传) | [`lark-base-form-submit.md`](references/lark-base-form-submit.md) | 写入操作;仅支持 share_token 模式;**当 `--json` 包含 attachments 时必须额外提供 `--base-token`**(附件上传到 Base Drive Media 需要);附件通过 `--json.attachments` 传入本地路径,CLI 自动并行上传 | -| `+form-create / +form-update / +form-delete` | 创建、更新或删除表单 | [`lark-base-form-create.md`](references/lark-base-form-create.md)、[`lark-base-form-update.md`](references/lark-base-form-update.md)、[`lark-base-form-delete.md`](references/lark-base-form-delete.md) | 创建后可继续进入表单问题相关操作;更新或删除前先确认目标表单 | -| `+form-questions-list` | 列出表单题目 | [`lark-base-form-questions-list.md`](references/lark-base-form-questions-list.md) | 适合查看已有题目结构 | -| `+form-questions-create / +form-questions-update / +form-questions-delete` | 创建、更新或删除题目 | [`lark-base-form-questions-create.md`](references/lark-base-form-questions-create.md)、[`lark-base-form-questions-update.md`](references/lark-base-form-questions-update.md)、[`lark-base-form-questions-delete.md`](references/lark-base-form-questions-delete.md) | 先确认 `form-id`;更新或删除前先确认题目目标 | - -### 2.9 权限与角色模块 - -用于启用高级权限,以及管理 Base 自定义角色。 -涉及 `+advperm-enable / +advperm-disable / +role-*` 时,操作用户必须为 Base 管理员,否则会返回权限错误。 - -| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 | -|------|------------------|----------------|----------| -| `+advperm-enable / +advperm-disable` | 启用或停用高级权限 | [`lark-base-advperm-enable.md`](references/lark-base-advperm-enable.md)、[`lark-base-advperm-disable.md`](references/lark-base-advperm-disable.md) | 管理角色前必须先启用;停用是高风险操作,会使已有自定义角色失效 | -| `+role-list / +role-get` | 列出角色,或获取角色详情 | [`lark-base-role-list.md`](references/lark-base-role-list.md)、[`lark-base-role-get.md`](references/lark-base-role-get.md)、[`role-config.md`](references/role-config.md) | `+role-list` 只能串行执行;`+role-get` 适合查看完整权限配置 | -| `+role-create / +role-update / +role-delete` | 创建、更新或删除角色 | [`lark-base-role-create.md`](references/lark-base-role-create.md)、[`lark-base-role-update.md`](references/lark-base-role-update.md)、[`lark-base-role-delete.md`](references/lark-base-role-delete.md)、[`role-config.md`](references/role-config.md) | `+role-create` 仅支持 `custom_role`;`+role-update` 采用 Delta Merge,`role_name` 和 `role_type` 即使不改也必须传当前值;`+role-delete` 不可逆 | - -## 3. 多维表格通用知识 - -飞书多维表格英文名是 `Base`,曾用名 `Bitable`;因此旧文档、返回字段、参数名或错误信息里出现 `bitable` 多属历史兼容,不代表应改用另一套命令体系。 - -### 3.1 字段分类与可写性 - -| 字段类型 | 含义 | 能否直接作为 `+record-upsert / +record-batch-create / +record-batch-update` 写入目标 | 说明 | -|----------|------|-----------------------------------------------------------|------| -| 存储字段 | 真实存用户输入的数据 | 可以 | 常见如文本、数字、日期、单选、多选、人员、关联 | -| 附件字段 | 存储文件附件 | 不应直接按普通字段写 | 上传附件走 `+record-upload-attachment`;下载附件走 `+record-download-attachment`;删除附件走 `+record-remove-attachment` | -| 地理位置字段 | 存储坐标并由平台解析地址 | 可以 | 写入必须使用 `{lng,lat}`;读取、筛选和转文本等场景使用 `full_address` 字符串;只有公式能访问坐标 | -| 系统字段 | 平台自动维护 | 不可以 | 常见如创建时间、更新时间、创建人、修改人、自动编号 | -| `formula` 字段 | 通过表达式计算 | 不可以 | 只读字段 | -| `lookup` 字段 | 通过跨表规则查找引用 | 不可以 | 只读字段 | - -### 3.2 任务选路心智模型 - -| 用户诉求 | 优先方案 | 不要误走 | -|---------|----------|----------| -| 一次性分析 / 临时统计 | `+data-query` | 不要用 `+record-list` / `+record-search` 拉全量后手算 | -| 要把结果长期显示在表里 | `formula` 字段 | 不要只给一次性手工分析结果 | -| 用户明确要求 lookup,或天然是固定查找配置 | `lookup` 字段 | 不要默认先上 lookup;先判断 formula 是否更合适 | -| 读取原始记录明细 / 关键词检索 / 导出 | `+record-search / +record-list / +record-get` | 不要拿 `+data-query` 当取数命令 | -| 上传附件到记录 | `+record-upload-attachment` | 不要用 `+record-upsert` / `+record-batch-*` 伪造附件值 | -| 下载记录里的附件文件 | `+record-download-attachment --record-id --output `,可加 `--file-token ` 只下指定附件 | Base 附件必须用这个命令下载;用其他下载入口可能失败 | -| 写入地理位置 | `+record-upsert` / `+record-batch-*` 传 `{lng,lat}` | 不要把纯地址文本当成 CellValue | -| 基于视图做筛选读取 | `+view-set-filter` + `+record-list` | 不要跳过视图筛选直接猜条件 | -| 本地 Excel / CSV / `.base` 导入为 Base | `lark-cli drive +import --type bitable` | 不要误走 `+base-create`、`+table-create` 或 `+record-upsert` | - -### 3.3 查询执行契约 - -涉及查询、统计或判断结论时,先阅读 [`references/lark-base-data-analysis-sop.md`](references/lark-base-data-analysis-sop.md),并遵守以下高优先级规则: - -1. `+record-list` 默认页、固定 `--limit` 和本地 `jq` 只能证明已读取范围内的事实,不能直接支撑全局最值、全量计数、Top/Bottom N、异常识别或分组结论。 -2. 能由 Base 表达的筛选、排序、投影、聚合、分组和限制,应在 Base 云端查询服务中执行;不要先拉明细到本地上下文再手工筛选排序。 +## 何时使用 + +使用本 skill: + +- 用户明确提到 Base / 多维表格 / bitable,或给出 `/base/` 链接。 +- 用户要在 Base 内建表、改表、管理字段、写记录、查记录、配视图。 +- 用户要在 Base 内做公式字段、lookup 字段、跨表计算、派生指标、筛选聚合、TopN、统计分析。 +- 用户要管理 Base 表单、仪表盘、workflow、高级权限或角色。 +- 用户要把旧 Base 聚合式命令或旧写法迁移到当前 `lark-cli base +...` shortcut。 + +不要使用本 skill: + +- 只是认证、初始化配置、切换身份、处理 scope 或权限授权恢复,转 `lark-shared`。 +- 把本地 Excel / CSV / `.base` 导入成 Base,转 `lark-drive +import --type bitable`。 +- 泛化数据分析、字段设计、公式讨论,但没有 Base/多维表格上下文。 + +## 使用边界 + +- Base 业务操作只使用 `lark-cli base +...` shortcut,不使用旧聚合式 `+table / +field / +record / +view / +history / +workspace`。 +- 本轮 Base 不依赖 `lark-cli schema`。SKILL 只保留路由、风险和复杂 JSON/DSL;简单命令由命令自身的参数、tips 和错误恢复承接。 +- 用户要把 Excel / CSV / `.base` 导入成 Base 时,先转 `lark-cli drive +import --type bitable`,导入完成后再回到 Base 命令。 +- 用户只给 Base 名称或关键词时,先用 `lark-cli drive +search --query --doc-types bitable` 定位资源。 +- Base 命令必须先有 `base_token` 或可解析出的 Base URL。没有 token 时:用户要新建就用 `+base-create`;用户给标题/关键词就搜 `lark-cli drive +search --query "" --doc-types bitable --only-title --as user`;仍无法定位时,反问用户具体是哪一个 Base。 +- 认证、初始化、scope、身份切换、权限不足恢复属于 `lark-shared`;Base 文档只保留会影响 Base 路径选择的权限规则。 + +## 快速路由 + +| 用户目标 | 优先命令 | 何时读 reference | +|---|---|---| +| 查 Base 本体 | `+base-get` | 用返回确认 Base 名称、owner、权限和可继续操作的 token | +| 创建/复制 Base | `+base-create` / `+base-copy` | 写入后报告新 Base 标识;注意返回中的 `permission_grant` | +| 管理表 | `+table-list/get/create/update/delete` | `+table-create --fields` 复杂时读 `lark-base-shortcut-field-properties.md` | +| 列/查/删字段 | `+field-list/get/delete/search-options` | 写入前用 list/get 确认字段类型、选项、ID;删除前确认目标字段 | +| 创建/更新字段 | `+field-create` / `+field-update` | 必读 `lark-base-shortcut-field-properties.md`;公式读 `formula-field-guide.md`;lookup 读 `lookup-field-guide.md`;命令细节读 `lark-base-field-create.md` / `lark-base-field-update.md` | +| 读记录明细 | `+record-get` / `+record-list` / `+record-search` | 涉及筛选、排序、Top/Bottom N、聚合、多表关联、全局结论时读 `lark-base-data-analysis-sop.md` | +| 写记录 | `+record-upsert` / `+record-batch-create` / `+record-batch-update` | 必读对应 record reference 和 `lark-base-cell-value.md` | +| 附件字段 | `+record-upload-attachment` / `+record-download-attachment` / `+record-remove-attachment` | 附件不要伪造成普通 CellValue;上传走本地文件,下载/删除按 file token 或字段定位 | +| 删除记录 / 分享记录链接 / 历史 | `+record-delete` / `+record-share-link-create` / `+record-history-list` | 删除前确认 record;分享链接最多 100 条;历史只查单条记录,不做整表审计 | +| 管理视图 | `+view-*` | `+view-set-filter` 读 `lark-base-view-set-filter.md`;其余配置先 get 现状,再按返回结构更新 | +| 一次性聚合统计 | `+data-query` | 必读 `lark-base-data-analysis-sop.md` 和 `lark-base-data-query.md` | +| 公式字段 | `+field-create/update --json '{"type":"formula",...}'` | 必读 `formula-field-guide.md`,读后再加隐藏确认 flag `--i-have-read-guide` | +| Lookup 字段 | `+field-create/update --json '{"type":"lookup",...}'` | 必读 `lookup-field-guide.md`,读后再加隐藏确认 flag `--i-have-read-guide` | +| 表单提交 | `+form-submit` | 必读 `lark-base-form-submit.md` | +| 表单题目创建/更新 | `+form-questions-create` / `+form-questions-update` | 读对应 form-questions reference | +| 其他表单管理 | `+form-list/get/detail/create/update/delete` / `+form-questions-list/delete` | 读表单结构时关注 share token、questions、filter;删除前确认目标表单 | +| 仪表盘与组件 | `+dashboard-*` / `+dashboard-block-*` | 提到图表/看板/block 时先读 `lark-base-dashboard.md`;组件 `data_config` 读 `dashboard-block-data-config.md`;读取图表计算结果用 `+dashboard-block-get-data` | +| Workflow | `+workflow-*` | 创建/更新或理解 steps 时读 `lark-base-workflow-guide.md` 和 `lark-base-workflow-schema.md`;list/get/enable/disable 只处理 workflow ID 与启停状态 | +| 高级权限与角色 | `+advperm-*` / `+role-*` | 角色 create/update 或解读完整配置读 `role-config.md`;关闭高级权限会影响自定义角色,先确认 | + +## Base 心智模型 + +- Base 曾用名 Bitable;返回字段、错误或旧文档里的 `bitable` 多为历史兼容,不代表应改走裸 API 或另一套命令。 +- 表、字段、视图、workflow、dashboard block 的名称和 ID 必须来自真实返回,不要凭用户口述猜。 +- 存储字段可写;系统字段、`formula`、`lookup` 只读;附件字段走专用 attachment 命令。 +- 一次性统计、筛选、TopN 优先用 `+data-query` 或临时视图;需要长期显示在表中时,才新增 `formula` / `lookup` 字段。 +- `formula` 适合常规计算、条件判断、文本/日期处理和长期派生指标;`lookup` 适合明确的跨表查找、筛选后取值或聚合引用。 +- 写入、分析、公式、lookup、workflow、dashboard 前,先读取真实结构:表、字段、视图、关联表和 dashboard block 名称都以命令返回为准。 +- 跨表场景必须读取目标表结构;link 单元格中的关联 `record_id` 只是连接键,最终回答要回查并展示用户可读字段。 + +## 身份与权限降级 + +- 默认显式使用 `--as user` 操作用户资源;只有用户明确要求应用身份时,才直接用 `--as bot`。 +- user 身份报 scope/授权不足,或错误中包含 `permission_violations` / `hint`,先转 `lark-shared` 做用户授权恢复,不要直接降级 bot。 +- user 身份报资源级无访问且无授权恢复提示时,才可用 `--as bot` 重试一次;bot 仍失败就停止重试并按权限错误处理。 +- `91403` 或明确不可访问错误不要循环换身份重试。 +- `+base-create` / `+base-copy` 若用 bot 身份执行,关注返回中的 `permission_grant`,并把用户是否可打开新 Base 告知用户。 + +## 查询与统计规则 + +涉及查询、统计或判断结论时,先阅读 `references/lark-base-data-analysis-sop.md`,并遵守: + +1. `+record-list` 的默认页、固定 `--limit` 和本地 `jq` 只能证明已读取范围内的事实,不能直接支撑全局最值、全量计数、Top/Bottom N、异常识别或分组结论。 +2. 能由 Base 表达的筛选、排序、投影、聚合、分组和限制,应在 Base 云端查询能力中执行;不要先拉明细到本地上下文再手工筛选排序。 3. `has_more=true` 或等价分页信号表示当前结果不是全量;除非用户只要样例/前 N 条,不能基于该页回答全局问题。 4. 多表查询必须先确认关系字段和连接键;link 单元格里的 `record_id` 是关系键,不是用户可读答案。 5. 最终答案必须能追溯到真实表、真实字段、查询范围、筛选/排序/聚合条件和必要的连接键。 - -### 3.4 表名、字段名与表达式引用 - -1. 表名、字段名必须精确匹配真实返回,来源应是 `+table-list / +table-get / +field-list`。 -2. 不要凭自然语言猜名称,不要自行改写用户口述中的表名、字段名。 -3. `formula / lookup / data-query / workflow` 中出现的名称同样必须精确匹配;表达式引用、where 条件、DSL 字段名、workflow 配置都遵守同一规则。 -4. 跨表场景必须额外读取目标表结构,不能只看当前表。 - -### 3.5 Token 与链接 - -这是高优先级章节。只要用户输入里出现链接、token,或报错涉及 `baseToken` / `wiki_token` / `obj_token`,都应优先回到这里检查。 - -| 输入类型 | 正确处理方式 | 说明 | -|---------|--------------|------| -| 直接 Base 链接 `/base/{token}` | 直接提取 token 作为 `--base-token` | 不要把完整 URL 直接作为 `--base-token` | -| Wiki 链接 `/wiki/{token}` | 先用下方 fast path 解析 `data.obj_token` | 不要把 `wiki_token` 直接当 `--base-token`;如果这一步失败,再看 [`lark-wiki-node-get.md`](../lark-wiki/references/lark-wiki-node-get.md) | -| URL 中的 `?table={id}` | 先按前缀判断对象类型 | `tbl` 开头表示数据表 `table-id`,可作为 `--table-id`;`blk` 开头表示仪表盘 `dashboard-ID`;`wkf` 开头表示 `workflow-ID`;`ldx` 开头表示内嵌文档,不要一律当成 `--table-id` | -| URL 中的 `?view={id}` | 提取为 `--view-id` | 适合直接定位视图 | - -Wiki Base fast path: - -```bash -BASE_TOKEN="$(lark-cli wiki +node-get --as user --node-token "" --jq '.data | select(.obj_type == "bitable") | .obj_token')" -``` - -| `lark-cli wiki +node-get` 返回的 `data.obj_type` | 后续路线 | 说明 | -|-----------------------------------------------|----------|------| -| `bitable` | 优先走 `lark-cli base +...` | 如果 shortcut 不覆盖,再用 `lark-cli base `;不要改走 `lark-cli api /open-apis/bitable/v1/...` | -| `docx` | 转到文档 / Drive 相关 skill | 不继续使用本 skill 的 Base 命令 | -| `sheet` | 转到 Sheets 相关 skill | 不继续使用本 skill 的 Base 命令 | -| `slides` | 转到 Drive 相关 skill | 不继续使用本 skill 的 Base 命令 | -| `mindnote` | 转到 Drive 相关 skill | 不继续使用本 skill 的 Base 命令 | - -### 3.6 身份选择与权限降级策略 - -多维表格通常属于用户的个人或团队资源。**默认应优先使用 `--as user`(用户身份)执行所有 Base 操作**,始终显式指定身份。 - -- **`--as user`(推荐)**:以当前登录用户身份操作其有权访问的 Base。执行前先完成用户授权: - -```bash -lark-cli auth login --domain base -``` - -- **`--as bot`(降级)**:仅当 user 身份权限不足、且 bot 身份确实拥有目标 Base 的访问权限时,才降级使用。bot 看不到用户私有资源,行为以应用身份执行。 - -**执行规则**: - -1. 所有操作默认先用 `--as user`。 -2. 若 user 身份返回权限错误,先判断是否为**不可重试错误码**(如 `91403`)。若是,**立即停止**,不做任何重试或降级,直接按 `lark-shared` 权限不足处理流程引导用户解决。 -3. 非不可重试错误码时,检查错误响应中是否包含 `permission_violations` / `hint` 等提权引导信息: - - **有提权引导**:按 `lark-shared` 权限不足处理流程,先引导用户完成 user 身份提权(`auth login --scope`);确认提权成功后,以 `--as user` 重试。 - - **无提权引导**(如资源级无访问权限、非 scope 不足):切换到 `--as bot` 重试**一次**。 -4. 若 bot 身份仍然返回权限错误,**立即停止重试**,根据错误响应按 `lark-shared` 流程引导用户解决(引导去开发者后台开通 scope 或确认资源访问权限)。 -5. 只有在用户明确要求"用应用身份 / bot 身份操作",才跳过 user 直接使用 `--as bot`。 - -## 4. 执行规则 - -### 4.1 标准执行顺序 - -1. 先判断任务属于哪个模块,选对命令族。 -2. 如果用户给了链接,先解析 token,不要把 wiki token、完整 URL 或其他对象 ID 误当成 `base_token`。 -3. 如果是查询类任务,先判断问题范围,阅读 data analysis SOP,再决定使用 `record / view / data-query`。 -4. 先拿结构,再写命令,避免猜表名、字段名、表达式引用。 -5. 定位到命令后,先读对应 reference,再执行命令。 -6. 执行命令,并按返回结果判断下一步。 -7. 回复时返回关键结果和后续可继续操作的信息,方便 agent 链式执行下一步。 - -### 4.2 不可违反规则 - -1. 先拿结构,再写命令;至少先拿当前表结构,跨表时还要拿目标表结构。 -2. 不要猜表名、字段名、表达式引用,一律以真实返回为准。 -3. 只使用原子命令;不要回退到旧的聚合式 `+table / +field / +record / +view / +history / +workspace`。 -4. 写记录前先读字段结构;先 `+field-list`,再按 [`lark-base-cell-value.md`](references/lark-base-cell-value.md) 构造 CellValue。 -5. 写字段前先看字段属性规范;先读 `lark-base-shortcut-field-properties.md`,再构造 `+field-create / +field-update` 的 JSON。 -6. 只写可写字段;系统字段、附件字段、`formula`、`lookup` 默认不作为普通记录写入目标。 -7. 聚合分析与取数分流;统计走 `+data-query`,关键词检索走 `+record-search`,明细走 `+record-list / +record-get`。 -8. 筛选查询按视图能力执行;先用 `+view-set-filter` 配置筛选,再结合 `+record-list` 读取。 -9. 全局查询不得基于默认分页、小 `--limit` 或未证明全量的本地 `jq` 结果下结论。 -10. Base 场景不要改走裸 API,不要切去 `lark-cli api /open-apis/bitable/v1/...`。 -11. 统一使用 `--base-token`。 -12. workflow 场景先读 schema,不要凭自然语言猜 `type`。 -13. dashboard 场景先读 guide;提到图表、看板、block 就先进入 dashboard 模块。 -14. formula / lookup 场景先读 guide;没读 guide 前不要直接创建或更新。 - -### 4.3 并发、分页与批量限制 - -- `+table-list / +field-list / +record-list / +view-list / +record-history-list / +role-list / +dashboard-list / +dashboard-block-list / +workflow-list` 禁止并发调用,只能串行执行。 -- `+record-list` 分页时,`--limit` 最大 `200`;先拉首批并检查 `has_more`,只有用户明确需要更多数据时再继续翻页。 -- 批量写入时,单批不超过 `200` 条。 -- 连续写入同一表时,必须串行写入,批次间延迟 `0.5–1` 秒。 - -### 4.4 确认与回复规则 - -- 视图重命名时,用户已明确“把哪个视图改成什么名字”时,`+view-rename` 直接执行即可。 -- 更新字段或删除记录 / 字段 / 表时,如果用户已经明确目标,`+field-update / +record-delete / +field-delete / +table-delete` 可直接执行,并带 `--yes`。 -- 删除目标仍有歧义时,先用 `+record-get / +field-get / +table-get` 或相应 list 命令确认。 -- `+base-create / +base-copy` 成功后,回复中必须主动返回新 Base 的标识信息;若结果带可访问链接,也应一并返回。 -- 若 Base 由 bot 身份创建或复制,shortcut 会自动尝试为当前 CLI 用户补授 `full_access`,并在输出中返回 `permission_grant`;agent 不需要再手动编排单独授权。owner 转移必须单独确认,禁止擅自执行。 - -## 5. 常见错误与恢复 - -| 错误 / 现象 | 含义 | 恢复动作 | -|-------------|------|----------| -| `1254064` | 日期格式错误 | 传 `YYYY-MM-DD HH:mm:ss` 字符串,不要写相对时间 | -| `1254068` | 超链接格式错误 | `"https://example.com"` 或 `"[文本](https://example.com)"` | -| `1254066` | 人员字段错误 | `[{ "id": "ou_xxx" }]` | -| `1254045` | 字段名不存在 | 检查字段名(含空格、大小写) | -| `1254015` | 字段值类型不匹配 | 先 `+field-list`,再按类型构造 | -| `param baseToken is invalid` / `base_token invalid` | 把 wiki token、workspace token 或其他 token 当成了 `base_token` | 如果输入来自 `/wiki/...`,先用 `lark-cli wiki +node-get --node-token ` 取真实 `data.obj_token`;当 `data.obj_type=bitable` 时,用 `data.obj_token` 作为 `--base-token` 重试,不要改走 `bitable/v1` | -| `not found` 且用户给的是 wiki 链接 | 常见于把 wiki token 当成 base token | 优先回退检查 wiki 解析,而不是改走 `bitable/v1` | -| formula / lookup 创建失败 | 指南未读或结构不合法 | 先读 `formula-field-guide.md` / `lookup-field-guide.md`,再按 guide 重建请求 | -| `ignored_fields` / `READONLY` | 只读字段被当成可写字段,常见于系统字段、formula、lookup | 移除只读字段,只写存储字段;计算结果交给 formula / lookup / 系统字段自动产出 | -| `1254104` | 批量超 200 条 | 分批调用 | -| `1254291` | 并发写冲突 | 串行写入 + 批次间延迟 | -| `91403` | 无权限访问该 Base | **不要重试**。按 `lark-shared` 权限不足处理流程引导用户解决权限问题 | +6. 一次性分析优先用 `+data-query` 或临时视图;要把结果长期显示在表里,才考虑新增 `formula` / `lookup` 字段。 +7. `+data-query` 返回聚合结果,不返回原始记录明细;需要输出实体字段时,用聚合结果中的业务 key 或 record_id 再走 record 路径回查。 + +## 写入前置规则 + +- 写记录前先读字段结构;只写存储字段。系统字段、附件字段、`formula`、`lookup` 不作为普通记录写入目标。 +- 附件上传、下载、删除走专用 `+record-*-attachment` 命令。 +- 写字段前先读 `lark-base-shortcut-field-properties.md`;涉及 `formula` / `lookup` 时必须读对应 guide。 +- 表名、字段名、视图名、workflow 配置中的名称必须来自真实返回;跨表场景还要读取目标表结构。 +- 删除、角色更新、字段更新等高风险操作遵循 CLI 的 confirmation gate;目标不明确时先用 get/list 消歧。 +- 批量写入单批最多 200 条;连续写同一表时串行执行,遇到 `1254291` 按短暂等待后重试处理。 +- `+record-batch-update` 是“同值批量更新”:同一份 patch 应用到全部 `record_id_list`,不要拿它做逐行不同值映射。 +- select/multiselect 写入未知选项可能触发平台新增选项;不是要新增时,先用 `+field-list` 或 `+field-search-options` 确认可选值。 + +## 表单与视图细节 + +- `+form-submit` 前必须先跑 `+form-detail`,读取 `questions[].type`、`required`、`filter` 和附件场景需要的 `base_token`;不要填写被 filter 隐藏的问题。 +- 表单附件不要写进 `fields`,放在 `--json.attachments`;提交附件时必须同时传表单所属 Base 的 `--base-token`。 +- `+view-set-filter` 是唯一保留的 view reference;sort/group/card/timebar/visible-fields 这类配置先用对应 get 命令读现状,保留未修改字段,只替换用户要求变更的配置。 +- 临时视图适合一次性筛选/排序后读取;如果筛选结果对用户后续查看有价值,应保留为持久视图并说明名称和用途。 + +## Token 与链接 + +| 输入类型 | 含义 / 正确处理方式 | +|---|---| +| `/base/{token}` | 普通 Base 链接;提取 `/base/` 后的 token 作为 `--base-token` | +| `/wiki/{token}` | Wiki 节点链接;先 `wiki +node-get`,当 `data.obj_type=bitable` 时使用 `data.obj_token` 作为 `--base-token` | +| `/base/{token}?table={id}` | `table` 参数用于定位 Base 内对象:`tbl` 开头是数据表 `--table-id`;`blk` 开头是 dashboard ID;`wkf` 开头是 workflow ID | +| `/base/{token}?view={id}` | `view` 参数用于定位表视图,提取为 `--view-id`;通常还需要确认 `table` 参数或先查表结构 | +| `/share/base/form/{shareToken}` | 表单分享链接;这是表单 share token,走 `+form-detail` / `+form-submit --share-token ` | +| `/share/base/view/{shareToken}` | 视图分享链接;具有分享权限语义,暂不支持用 CLI 直接访问,引导用户在浏览器或飞书客户端打开 | +| `/share/base/dashboard/{shareToken}` | 仪表盘分享链接;具有分享权限语义,暂不支持用 CLI 直接访问,引导用户在浏览器或飞书客户端打开 | +| `/record/{shareToken}` | 记录分享链接;暂不支持用 CLI 直接访问,引导用户在浏览器或飞书客户端打开。若用户想生成现有记录的分享链接,用 `+record-share-link-create --base-token --table-id --record-ids ` | +| `/base/workspace/{token}` | BaseApp / workspace 链接;暂不支持用 CLI 直接访问 | + +`wiki +node-get` 返回非 `bitable` 时,不继续使用 Base 命令:`docx` 转文档,`sheet` 转表格,其他云空间对象转对应 skill 或 drive。 + +## Dashboard / Workflow / Role + +- Dashboard 的复杂点是 block 的 `data_config`,不是 list/get/create/delete 命令参数。创建或更新 block 前先读 `dashboard-block-data-config.md`,组件必须串行创建;`+dashboard-arrange` 是服务端智能布局,只在用户明确要求重排/美化时执行。`+dashboard-block-get-data` 读取图表最终计算结果,不返回 block 名称、类型、布局或 `data_config`;需要元数据先用 `+dashboard-block-get`。 +- Workflow 的复杂点是 `steps` 结构。创建、更新或解释完整 workflow 时读 `lark-base-workflow-guide.md` 和 `lark-base-workflow-schema.md`;enable/disable/list 只需确认 workflow ID、当前启停状态和用户意图。 +- Role 的复杂点是权限 JSON。`+role-create` 只支持自定义角色;`+role-update` 是 delta merge;删除角色和关闭高级权限前必须确认目标和影响。 + +## 常见恢复 + +| 错误 / 现象 | 恢复动作 | +|---|---| +| `param baseToken is invalid` / `base_token invalid` | 检查是否把 wiki token、workspace token 或完整 URL 当成了 `--base-token`;按 `Token 与链接` 重新定位真实 Base token | +| `not found` 且输入来自 Wiki 链接 | 优先检查是否把 wiki token 当成 base token,不要立刻改走裸 API | +| `1254045` 字段名不存在 | 重新 `+field-list`,使用真实字段名或字段 ID;注意空格、大小写和跨表字段 | +| `1254015` 字段值类型不匹配 | 先 `+field-list`,再按 `lark-base-cell-value.md` 构造 CellValue | +| 日期 / 人员 / 超链接字段报格式错误 | 日期用 `YYYY-MM-DD HH:mm:ss`;人员用 `[{ "id": "ou_xxx" }]`;超链接用 URL 或 markdown link 字符串 | +| formula / lookup 创建失败 | 先读 `formula-field-guide.md` / `lookup-field-guide.md`,再按 guide 重建请求 | +| `ignored_fields` / `READONLY` | 移除只读字段,只写存储字段 | +| `1254104` | 批量超过 200,分批调用 | +| `1254291` | 并发写冲突,串行写入并在批次间短暂等待 | +| `91403` | 无权限访问该 Base,按 `lark-shared` 权限流程处理,不要盲目重试 | + +## 保留 Reference + +- `lark-base-data-analysis-sop.md`:查询/统计/全局结论的选路 SOP +- `lark-base-data-query.md`:聚合查询 DSL +- `lark-base-cell-value.md`:记录 CellValue 构造 +- `lark-base-shortcut-field-properties.md`:字段 JSON 构造 +- `formula-field-guide.md` / `lookup-field-guide.md`:公式与 lookup 字段 +- `lark-base-field-create.md` / `lark-base-field-update.md`:字段创建/更新命令级补充 +- `lark-base-record-upsert.md` / `lark-base-record-batch-create.md` / `lark-base-record-batch-update.md`:记录写入 JSON +- `lark-base-view-set-filter.md`:视图筛选 JSON +- `lark-base-form-submit.md` / `lark-base-form-questions-create.md` / `lark-base-form-questions-update.md`:表单复杂 JSON +- `lark-base-dashboard.md` / `dashboard-block-data-config.md` / `lark-base-dashboard-block-get-data.md`:仪表盘、组件配置与图表结果协议 +- `lark-base-workflow-guide.md` / `lark-base-workflow-schema.md`:workflow steps JSON +- `role-config.md`:角色权限 JSON diff --git a/skills/lark-base/references/examples.md b/skills/lark-base/references/examples.md deleted file mode 100644 index f98e956e8..000000000 --- a/skills/lark-base/references/examples.md +++ /dev/null @@ -1,140 +0,0 @@ -# 飞书多维表格使用场景完整示例(base) - -本文档提供基于 `lark-cli base +...` shortcut 的完整示例。 - -> **返回**: [SKILL.md](../SKILL.md) | **参考**: [shortcut 字段 JSON 规范](lark-base-shortcut-field-properties.md) · [CellValue 规范](lark-base-cell-value.md) - ---- - -## 场景 1:用 unified Shortcut 快速建表 - -适合已经明确字段结构、希望一次性完成建表的场景。 - -```bash -lark-cli base +table-create \ - --base-token bascnXXXXXXXX \ - --name "客户管理表" \ - --fields '[ - {"name":"客户名称","type":"text","description":"主标题字段"}, - {"name":"负责人","type":"user","multiple":false,"description":"用于标记客户跟进的直接负责人"}, - {"name":"签约日期","type":"datetime"}, - {"name":"状态","type":"select","multiple":false,"options":[{"name":"进行中"},{"name":"已完成"}]} - ]' -``` - ---- - -## 场景 2:创建数据表并查看字段 - -适合需要先建表、再确认字段结构的场景。 - -### 步骤 1:在已有 Base 中创建数据表 - -```bash -lark-cli base +table-create \ - --base-token bascnXXXXXXXX \ - --name "客户管理表" -``` - -### 步骤 2:列出字段 - -```bash -lark-cli base +field-list \ - --base-token bascnXXXXXXXX \ - --table-id tblXXXXXXXX \ - --limit 100 -``` - -> 提示:Base token 统一通过 `--base-token` 传入;表 ID 统一通过 `--table-id` 传入。 - ---- - -## 场景 3:创建、读取、更新单条记录 - -### 新增记录 - -```bash -lark-cli base +record-upsert \ - --base-token bascnXXXXXXXX \ - --table-id tblXXXXXXXX \ - --json '{ - "客户名称":"字节跳动", - "负责人":[{"id":"ou_xxx"}], - "状态":"进行中" - }' -``` - -### 列出记录 - -```bash -lark-cli base +record-list \ - --base-token bascnXXXXXXXX \ - --table-id tblXXXXXXXX \ - --limit 100 -``` - -### 更新记录 - -```bash -lark-cli base +record-upsert \ - --base-token bascnXXXXXXXX \ - --table-id tblXXXXXXXX \ - --record-id recXXXXXXXX \ - --json '{ - "状态":"已完成" - }' -``` - -### 删除记录 - -```bash -lark-cli base +record-delete \ - --base-token bascnXXXXXXXX \ - --table-id tblXXXXXXXX \ - --record-id recXXXXXXXX \ - --yes -``` - ---- - -## 场景 4:配置视图筛选后按视图读取记录 - -需要筛选查询时,推荐先写视图筛选,再通过 `view_id` 读取记录。 - -### 更新视图筛选条件 - -```bash -lark-cli base +view-set-filter \ - --base-token bascnXXXXXXXX \ - --table-id tblXXXXXXXX \ - --view-id vewXXXXXXXX \ - --json '{ - "logic":"and", - "conditions":[ - { - "field_name":"状态", - "operator":"is", - "value":["进行中"] - } - ] - }' -``` - -### 按视图读取记录 - -```bash -lark-cli base +record-list \ - --base-token bascnXXXXXXXX \ - --table-id tblXXXXXXXX \ - --view-id vewXXXXXXXX \ - --limit 100 -``` - ---- - -## 场景 5:什么时候优先用 Shortcut - -- 需要一次性建表并附带字段、视图时,优先 `lark-cli base +table-create` -- 需要按业务字段名做 upsert 时,优先 `lark-cli base +record-upsert` -- 需要配置筛选视图时,优先 `lark-cli base +view-set-filter` -- 需要记录历史时,优先 `lark-cli base +record-history-list` diff --git a/skills/lark-base/references/lark-base-advperm-disable.md b/skills/lark-base/references/lark-base-advperm-disable.md deleted file mode 100644 index 3781dd824..000000000 --- a/skills/lark-base/references/lark-base-advperm-disable.md +++ /dev/null @@ -1,83 +0,0 @@ -# base +advperm-disable - -> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。 - -停用指定 Base 的高级权限。停用后自定义角色等高级权限功能将不可用。 - -## 推荐命令 - -```bash -# 停用高级权限 -lark-cli base +advperm-disable \ - --base-token VwGhbYCXQaYGMzsWlEZcBbfMnod -``` - -## 参数 - -| 参数 | 必填 | 说明 | -|------|------|------| -| `--base-token ` | 是 | Base Token,27 位字母数字字符串 | - -## API 入参详情 - -**HTTP 方法和路径:** - -``` -PUT /open-apis/base/v3/bases/:base_token/advperm/enable?enable=false -``` - -**Path 参数:** - -| 参数 | 必填 | 说明 | -|------|------|------| -| `base_token` | 是 | Base 的唯一标识,27 位字母数字字符串 | - -**Query 参数:** - -| 参数 | 必填 | 类型 | 说明 | -|------|------|------|------| -| `enable` | 是 | bool | 固定为 `false`,表示停用高级权限 | - -## API 出参详情 - -**Response:** - -| 字段 | 类型 | 说明 | -|------|------|------| -| `code` | int32 | 错误码,0 表示成功 | -| `message` | string | 错误信息 | -| `data` | string | 成功时为空 | - -## 返回值 - -命令成功后输出 JSON: - -```json -{ - "ok": true, - "data": { - "success": true - } -} -``` - -## 工作流 - -> [!CAUTION] -> 这是**高风险写入操作** — 停用高级权限会影响所有已配置的自定义角色,执行前必须向用户确认。 - -1. 向用户确认 `--base-token`,并提醒停用会影响已有角色配置 -2. 执行命令 -3. 确认返回 `code: 0` 表示停用成功 - -## 坑点 - -- ⚠️ **操作用户必须为 Base 管理员**:非管理员调用会返回权限错误 -- ⚠️ **停用影响已有角色**:停用高级权限后,已创建的自定义角色将失效 -- ⚠️ **API 路径版本**:本接口使用 `base/v3`,路径必须从原始文档提取,不要用 WebSearch 补全 -- ⚠️ **data 字段是 JSON 字符串**:响应中 `data` 是 string 类型(非 object),需要双重解析 - -## 参考 - -- [lark-base](../SKILL.md) — 多维表格全部命令 -- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数 diff --git a/skills/lark-base/references/lark-base-advperm-enable.md b/skills/lark-base/references/lark-base-advperm-enable.md deleted file mode 100644 index 3dd2f4d61..000000000 --- a/skills/lark-base/references/lark-base-advperm-enable.md +++ /dev/null @@ -1,80 +0,0 @@ -# base +advperm-enable - -> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。 - -启用指定 Base 的高级权限。启用后可使用自定义角色等高级权限功能。 - -## 推荐命令 - -```bash -# 启用高级权限 -lark-cli base +advperm-enable \ - --base-token VwGh**************Mnod -``` - -## 参数 - -| 参数 | 必填 | 说明 | -|------|------|------| -| `--base-token ` | 是 | Base Token,27 位字母数字字符串 | - -## API 入参详情 - -**HTTP 方法和路径:** - -``` -PUT /open-apis/base/v3/bases/:base_token/advperm/enable?enable=true -``` - -**Path 参数:** - -| 参数 | 必填 | 说明 | -|------|------|------| -| `base_token` | 是 | Base 的唯一标识,27 位字母数字字符串 | - -**Query 参数:** - -| 参数 | 必填 | 类型 | 说明 | -|------|------|------|------| -| `enable` | 是 | bool | 固定为 `true`,表示启用高级权限 | - -## API 出参详情 - -**Response:** - -| 字段 | 类型 | 说明 | -|------|------|------| -| `code` | int32 | 错误码,0 表示成功 | -| `message` | string | 错误信息 | -| `data` | string | 成功时为空 | - -## 返回值 - -命令成功后输出 JSON: - -```json -{ - "ok": true, - "data": { - "success": true - } -} -``` - -## 工作流 - -1. 向用户确认 `--base-token` -2. 执行命令 -3. 确认返回 `code: 0` 表示启用成功 - -## 坑点 - -- ⚠️ **操作用户必须为 Base 管理员**:非管理员调用会返回权限错误 -- ⚠️ **API 路径版本**:本接口使用 `base/v3`,路径必须从原始文档提取,不要用 WebSearch 补全 -- ⚠️ **data 字段是 JSON 字符串**:响应中 `data` 是 string 类型(非 object),需要双重解析 -- ⚠️ **启用后才能管理角色**:`+role-create / +role-update / +role-delete` 等角色操作需要先启用高级权限 - -## 参考 - -- [lark-base](../SKILL.md) — 多维表格全部命令 -- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数 diff --git a/skills/lark-base/references/lark-base-base-copy.md b/skills/lark-base/references/lark-base-base-copy.md deleted file mode 100644 index 33f637509..000000000 --- a/skills/lark-base/references/lark-base-base-copy.md +++ /dev/null @@ -1,74 +0,0 @@ -# base +base-copy - -> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。 - -复制一个已有 Base;可选只复制结构,不复制内容。 - -## 推荐命令 - -```bash -lark-cli base +base-copy \ - --base-token app_xxx \ - --name "Copied Base" - -lark-cli base +base-copy \ - --base-token app_xxx \ - --name "Copied Base" \ - --folder-token fld_xxx \ - --time-zone Asia/Shanghai \ - --without-content -``` - -## 参数 - -| 参数 | 必填 | 说明 | -|------|------|------| -| `--base-token ` | 是 | 源 Base Token | -| `--name ` | 否 | 新 Base 名称 | -| `--folder-token ` | 否 | 目标文件夹 token | -| `--time-zone ` | 否 | 时区,如 `Asia/Shanghai` | -| `--without-content` | 否 | 只复制结构,不复制内容 | - -## API 入参详情 - -**HTTP 方法和路径:** - -``` -POST /open-apis/base/v3/bases/:base_token/copy -``` - -## 返回重点 - -- 返回 `base`。 -- CLI 会额外标记 `copied: true`。 -- 回复结果时,必须主动返回新 Base 的可访问链接: - - 优先使用返回结果中的 `base.url` - - 同时返回新 Base 的 token - - 如果本次返回没有 `url`,至少返回新 Base 的名称和 token - -> [!IMPORTANT] -> 如果 Base 是**以应用身份(bot)复制**出来的,shortcut 会在复制成功后自动尝试为当前 CLI 用户添加该 Base 的 `full_access`(管理员)权限,并在输出中附带 `permission_grant` 字段。 -> -> `permission_grant.status` 语义如下: -> - `granted`:当前 CLI 用户已获得该 Base 的管理员权限 -> - `skipped`:Base 已复制成功,但没有可授权的当前 CLI 用户,或复制结果缺少可授权 token -> - `failed`:Base 已复制成功,但自动授权失败;结果中会包含失败原因,用户可稍后重试授权,或继续使用应用身份(bot)处理该 Base -> -> 回复复制结果时,除 `base token` 和可访问链接外,还必须明确告知用户 `permission_grant` 的结果。 -> -> **仍然不要擅自执行 owner 转移。** 如果用户需要把 owner 转给自己,必须单独确认。 - -## 工作流 - -> [!CAUTION] -> 这是**写入操作** — 执行前必须向用户确认。 - -1. 先确认源 Base Token。 -2. `--name`、`--folder-token`、`--time-zone` 都是可选项;用户没要求时不要为这些可选参数额外追问。 -3. 只要结构时,显式传 `--without-content`。 -4. 复制成功后,整理并返回:新 Base 名称、token,以及响应中已有的可访问链接。 - -## 参考 - -- [lark-base-workspace.md](lark-base-workspace.md) — base / workspace 索引页 -- [lark-base-base-create.md](lark-base-base-create.md) — 创建全新 Base diff --git a/skills/lark-base/references/lark-base-base-create.md b/skills/lark-base/references/lark-base-base-create.md deleted file mode 100644 index 2544b037c..000000000 --- a/skills/lark-base/references/lark-base-base-create.md +++ /dev/null @@ -1,68 +0,0 @@ -# base +base-create - -> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。 - -创建一个新的 Base;可选指定父文件夹和时区。 - -## 推荐命令 - -```bash -lark-cli base +base-create \ - --name "New Base" - -lark-cli base +base-create \ - --name "项目管理" \ - --folder-token fld_xxx \ - --time-zone Asia/Shanghai -``` - -## 参数 - -| 参数 | 必填 | 说明 | -|------|------|------| -| `--name ` | 是 | 新 Base 名称 | -| `--folder-token ` | 否 | 目标文件夹 token | -| `--time-zone ` | 否 | 时区,如 `Asia/Shanghai` | - -## API 入参详情 - -**HTTP 方法和路径:** - -``` -POST /open-apis/base/v3/bases -``` - -## 返回重点 - -- 返回 `base`。 -- CLI 会额外标记 `created: true`。 -- 回复结果时,必须主动返回新 Base 的可访问链接: - - 优先使用返回结果中的 `base.url` - - 同时返回新 Base 的 token - - 如果本次返回没有 `url`,至少返回新 Base 的名称和 token - -> [!IMPORTANT] -> 如果 Base 是**以应用身份(bot)创建**的,shortcut 会在创建成功后自动尝试为当前 CLI 用户添加该 Base 的 `full_access`(管理员)权限,并在输出中附带 `permission_grant` 字段。 -> -> `permission_grant.status` 语义如下: -> - `granted`:当前 CLI 用户已获得该 Base 的管理员权限 -> - `skipped`:Base 已创建成功,但没有可授权的当前 CLI 用户,或创建结果缺少可授权 token -> - `failed`:Base 已创建成功,但自动授权失败;结果中会包含失败原因,用户可稍后重试授权,或继续使用应用身份(bot)处理该 Base -> -> 回复创建结果时,除 `base token` 和可访问链接外,还必须明确告知用户 `permission_grant` 的结果。 -> -> **仍然不要擅自执行 owner 转移。** 如果用户需要把 owner 转给自己,必须单独确认。 - -## 工作流 - -> [!CAUTION] -> 这是**写入操作** — 执行前必须向用户确认。 - -1. 先确认 Base 名称。 -2. `--folder-token`、`--time-zone` 都是可选项;用户没要求时不要为此额外追问。 -3. 创建成功后,整理并返回:Base 名称、token,以及响应中已有的可访问链接。 - -## 参考 - -- [lark-base-workspace.md](lark-base-workspace.md) — base / workspace 索引页 -- [lark-base-base-copy.md](lark-base-base-copy.md) — 复制 Base diff --git a/skills/lark-base/references/lark-base-base-get.md b/skills/lark-base/references/lark-base-base-get.md deleted file mode 100644 index 57791f332..000000000 --- a/skills/lark-base/references/lark-base-base-get.md +++ /dev/null @@ -1,39 +0,0 @@ -# base +base-get - -> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。 - -读取一个 Base 的详情。 - -## 推荐命令 - -```bash -lark-cli base +base-get \ - --base-token app_xxx -``` - -## 参数 - -| 参数 | 必填 | 说明 | -|------|------|------| -| `--base-token ` | 是 | Base Token | - -## API 入参详情 - -**HTTP 方法和路径:** - -``` -GET /open-apis/base/v3/bases/:base_token -``` - -## 返回重点 - -- 返回 `base`,通常包含 `base_token / name / url` 等信息。 - -## 坑点 - -- ⚠️ 先确认传入的是 `base_token`,不是 `workspace_token`。 -- ⚠️ 如果最初输入来自 `/wiki/...`,不要直接把 `wiki_token` 当 `--base-token`;若报 `param baseToken is invalid` / `base_token invalid`,先用 `lark-cli wiki spaces get_node` 取 `node.obj_token`,再重试 `+base-get`。 - -## 参考 - -- [lark-base-workspace.md](lark-base-workspace.md) — base 索引页 diff --git a/skills/lark-base/references/lark-base-dashboard-arrange.md b/skills/lark-base/references/lark-base-dashboard-arrange.md deleted file mode 100644 index 7a793137d..000000000 --- a/skills/lark-base/references/lark-base-dashboard-arrange.md +++ /dev/null @@ -1,83 +0,0 @@ -# base +dashboard-arrange - -> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流 - -自动重新排列仪表盘组件布局。服务端根据组件数量和类型进行智能布局优化。 - -## 使用场景 - -| 场景 | 说明 | -|------|------| -| **从 0 到 1 搭建后** | 使用 `+dashboard-create` 和 `+dashboard-block-create` 创建仪表盘后,默认布局可能不够工整美观,推荐使用本命令做一次整体重排 | -| **用户明确要求** | 用户主动要求对已有仪表盘进行布局重排或美化时 | - -> [!CAUTION] -> - **不建议**在已有仪表盘上自动调用此命令,除非用户明确要求 -> - 排列结果是**服务端智能推荐**,不一定完全符合用户预期 -> - 无法指定具体位置(如"第一排放 A,第二排放 B"),排列逻辑是**自适应**的 - -## 推荐命令 - -```bash -# 基础用法 -lark-cli base +dashboard-arrange \ - --base-token xxx \ - --dashboard-id blk_xxx -``` - -## 参数 - -| 参数 | 必填 | 说明 | -|------|------|------| -| `--base-token ` | 是 | Base Token | -| `--dashboard-id ` | 是 | 仪表盘 ID | -| `--user-id-type ` | 否 | 用户 ID 类型:open_id / union_id / user_id | -| `--dry-run` | 否 | 预览 API 调用,不执行 | - -## 返回示例 - -```json -{ - "dashboard_id": "blk_xxx", - "name": "数据分析", - "blocks": [ - { - "block_id": "chtbxxxx", - "block_name": "总销售额", - "block_type": "statistics", - "layout": { - "x": 0, - "y": 0, - "w": 6, - "h": 6 - } - }, - { - "block_id": "chtbcrxxxx", - "block_name": "月度趋势", - "block_type": "column", - "layout": { - "x": 6, - "y": 0, - "w": 6, - "h": 6 - } - } - ], - "arranged": true -} -``` - -## 返回重点 - -| 字段 | 说明 | -|------|------| -| `blocks[].layout` | 重排后的布局信息,包含 x/y/w/h | -| `arranged` | 是否重排成功 | - -> [!CAUTION] -> 这是**写入操作** — 执行前必须向用户确认。 - -## 参考 - -- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引 diff --git a/skills/lark-base/references/lark-base-dashboard-block-create.md b/skills/lark-base/references/lark-base-dashboard-block-create.md deleted file mode 100644 index 0e8aa1d2a..000000000 --- a/skills/lark-base/references/lark-base-dashboard-block-create.md +++ /dev/null @@ -1,108 +0,0 @@ -# base +dashboard-block-create - -> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流 -> **关键:** 创建前必须阅读 [dashboard-block-data-config.md](dashboard-block-data-config.md) 了解组件类型和 data_config 结构 - -在仪表盘中创建一个组件(Block)。 - -## 关键约束 - -- **`type` 创建后不可修改**,创建时务必选对 -- **`data_config` 结构随 `type` 变化**,不同组件类型字段不同,**⚠️ 必须阅读 [dashboard-block-data-config.md](dashboard-block-data-config.md) 了解如何构造** -- **组件创建必须串行执行**,不能并发 - -## 推荐命令 - -```bash -# 简单示例:创建一个指标卡(统计记录数) -lark-cli base +dashboard-block-create \ - --base-token xxx \ - --dashboard-id blk_xxx \ - --name "总记录数" \ - --type statistics \ - --data-config '{"table_name":"订单表","count_all":true}' - -# 文本组件示例(Markdown 富文本) -lark-cli base +dashboard-block-create \ - --base-token xxx \ - --dashboard-id blk_xxx \ - --name "说明文字" \ - --type text \ - --data-config '{"text":"# 标题\n## 副标题\n**加粗** *斜体* ~~删除~~\n1. 列表1\n2. 列表2"}' - -# 复杂配置用文件传入 -lark-cli base +dashboard-block-create \ - --base-token xxx \ - --dashboard-id blk_xxx \ - --name "销售额趋势" \ - --type line \ - --data-config @config.json -``` - -完整流程参考 [lark-base-dashboard.md](lark-base-dashboard.md) 的「场景 1:从 0 到 1 创建仪表盘」 - -## 参数 - -| 参数 | 必填 | 说明 | -|------|------|------| -| `--base-token ` | 是 | Base Token | -| `--dashboard-id ` | 是 | 仪表盘 ID(从 `+dashboard-list/get` 获取) | -| `--name ` | **是** | 组件名称(允许重名) | -| `--type ` | **是** | 组件类型,见下方枚举值。**不同 type 对应不同的 data_config 结构**,常用:`column`(柱状图)、`line`(折线图)、`pie`(饼图)、`statistics`(指标卡)、`text`(文本) | -| `--data-config ` | 否 | 数据配置 JSON,**结构随 type 变化**。**⚠️ 必须阅读 [dashboard-block-data-config.md](dashboard-block-data-config.md) 了解如何构造**。创建时会做本地校验,更新时由后端校验 | -| `--user-id-type ` | 否 | 用户 ID 类型,filter 涉及人员字段时使用 | -| `--dry-run` | 否 | 预览 API 调用,不执行 | - -### type 枚举值 - -| 值 | 说明 | -|----|------| -| `column` | 柱状图 | -| `bar` | 条形图 | -| `line` | 折线图 | -| `pie` | 饼图 | -| `ring` | 环形图 | -| `area` | 面积图 | -| `combo` | 组合图 | -| `scatter` | 散点图 | -| `funnel` | 漏斗图 | -| `wordCloud` | 词云 | -| `radar` | 雷达图 | -| `statistics` | 指标卡 | -| `text` | 文本(支持 Markdown) | - -## 返回示例 - -```json -{ - "block": { - "block_id": "chtxxxxxxxx", - "name": "总记录数", - "type": "statistics", - "data_config": { - "table_name": "电商交易明细", - "count_all": true - } - }, - "created": true -} -``` - -## 返回重点 - -| 字段 | 说明 | -|------|------| -| `block.block_id` | 组件 ID,后续编辑/删除需要用到,务必记录 | -| `block.name` | 组件名称 | -| `block.type` | 组件类型 | -| `block.data_config` | 实际创建的数据配置(可能包含后端自动添加的默认值)| -| `created` | 是否创建成功 | - -> [!CAUTION] -> 这是**写入操作** — 执行前必须向用户确认。 - - -## 参考 - -- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引 -- [dashboard-block-data-config.md](dashboard-block-data-config.md) — data_config 结构、图表类型、filter 规则 diff --git a/skills/lark-base/references/lark-base-dashboard-block-delete.md b/skills/lark-base/references/lark-base-dashboard-block-delete.md deleted file mode 100644 index d98939539..000000000 --- a/skills/lark-base/references/lark-base-dashboard-block-delete.md +++ /dev/null @@ -1,46 +0,0 @@ -# base +dashboard-block-delete - -> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流。 - -删除仪表盘中的一个组件(Block),不可恢复。 - -## 推荐命令 - -```bash -lark-cli base +dashboard-block-delete \ - --base-token bascn***************CtadY \ - --dashboard-id blkxxx \ - --block-id chtxxxxxxxx -``` - -## 参数 - -| 参数 | 必填 | 说明 | -|------|------|------| -| `--base-token ` | 是 | Base Token | -| `--dashboard-id ` | 是 | 仪表盘 ID | -| `--block-id ` | 是 | Block ID | -| `--dry-run` | 否 | 预览 API 调用,不执行 | - -## 返回示例 - -```json -{ - "block_id": "chtxxxxxxxx", - "deleted": true -} -``` - -## 返回重点 - -| 字段 | 说明 | -|------|------| -| `block_id` | 被删除的组件 ID | -| `deleted` | 是否删除成功 | - -> [!CAUTION] -> 这是**写入操作**且**不可逆** — 执行前必须向用户确认。 - -## 参考 - -- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引 diff --git a/skills/lark-base/references/lark-base-dashboard-block-get-data.md b/skills/lark-base/references/lark-base-dashboard-block-get-data.md index 757b5dd79..8470323f8 100644 --- a/skills/lark-base/references/lark-base-dashboard-block-get-data.md +++ b/skills/lark-base/references/lark-base-dashboard-block-get-data.md @@ -13,7 +13,7 @@ > [!IMPORTANT] > - 本命令返回的是**图表结果协议**,不是 block 元数据; -> - 如果你需要 `name`、`type`、`layout`、`data_config` 等配置,请先用 [`+dashboard-block-get`](lark-base-dashboard-block-get.md); +> - 如果你需要 `name`、`type`、`layout`、`data_config` 等配置,请先用 `+dashboard-block-get`; > - 文本组件(`text`)不涉及计算,不适用本命令; ## 一句话理解 @@ -668,7 +668,7 @@ lark-cli base +dashboard-block-get-data \ - `data_config` - 所属 dashboard 信息 -这些都应该通过 [`+dashboard-block-get`](lark-base-dashboard-block-get.md) 获取。 +这些都应该通过 `+dashboard-block-get` 获取。 ### 误区 2:以为它返回的是原始记录 @@ -713,5 +713,5 @@ GET /open-apis/base/v3/bases/bascn_example_token/dashboards/blocks/chtxxxxxxxx/d ## 参考 - [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块总指引 -- [lark-base-dashboard-block-get.md](lark-base-dashboard-block-get.md) — 获取 block 元数据 +- `+dashboard-block-get` — 获取 block 元数据 - [dashboard-block-data-config.md](dashboard-block-data-config.md) — data_config 结构和组件类型说明 diff --git a/skills/lark-base/references/lark-base-dashboard-block-get.md b/skills/lark-base/references/lark-base-dashboard-block-get.md deleted file mode 100644 index 0994f6059..000000000 --- a/skills/lark-base/references/lark-base-dashboard-block-get.md +++ /dev/null @@ -1,57 +0,0 @@ -# base +dashboard-block-get - -> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流。 - -获取仪表盘中单个组件的详情(包含 data_config 完整配置)。常用于:1) 查看组件的完整配置;2) 编辑组件前了解当前配置。 - -## 推荐命令 - -```bash -lark-cli base +dashboard-block-get \ - --base-token bascn***************CtadY \ - --dashboard-id blkxxx \ - --block-id chtxxxxxxxx -``` - -## 参数 - -| 参数 | 必填 | 说明 | -|------|------|------| -| `--base-token ` | 是 | Base Token | -| `--dashboard-id ` | 是 | 仪表盘 ID | -| `--block-id ` | 是 | Block ID | -| `--user-id-type ` | 否 | 用户 ID 类型:open_id / union_id / user_id | -| `--format ` | 否 | 输出格式 | -| `--dry-run` | 否 | 预览 API 调用,不执行 | - -## 返回示例 - -```json -{ - "block": { - "block_id": "chtxxxxxxxx", - "name": "柱状图", - "type": "column", - "data_config": { - "table_name": "电商交易明细", - "series": [{"field_name": "营销费用", "rollup": "SUM"}], - "group_by": [{"field_name": "品类", "mode": "integrated"}] - }, - "layout": {"x": 0, "y": 0, "w": 6, "h": 4} - } -} -``` - -## 返回重点 - -| 字段 | 说明 | -|------|-------------------------------| -| `block.block_id` | 组件 ID | -| `block.name` | 组件名称 | -| `block.type` | 组件类型(如 `column`/`line`/`pie`) | -| `block.data_config` | 数据配置(新建/编辑组件时可基于此字段修改) | -| `block.layout` | 布局信息(只读,x/y/w/h 坐标和尺寸) | - -## 参考 - -- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引 diff --git a/skills/lark-base/references/lark-base-dashboard-block-list.md b/skills/lark-base/references/lark-base-dashboard-block-list.md deleted file mode 100644 index ff8a0155a..000000000 --- a/skills/lark-base/references/lark-base-dashboard-block-list.md +++ /dev/null @@ -1,53 +0,0 @@ -# base +dashboard-block-list - -> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流。 - -分页列出仪表盘中的所有组件(Block)。常用于:1) 查看仪表盘有哪些组件;2) 获取组件 ID 和类型用于后续编辑/删除。 - -## 推荐命令 - -```bash -lark-cli base +dashboard-block-list \ - --base-token bascn***************CtadY \ - --dashboard-id blkxxx -``` - -## 参数 - -| 参数 | 必填 | 说明 | -|------|------|------| -| `--base-token ` | 是 | Base Token | -| `--dashboard-id ` | 是 | 仪表盘 ID | -| `--page-size ` | 否 | 每页数量,默认 20,最大 100 | -| `--page-token ` | 否 | 分页标记 | -| `--format ` | 否 | 输出格式:json / pretty / table / csv / ndjson | -| `--dry-run` | 否 | 预览 API 调用,不执行 | - -## 返回示例 - -```json -{ - "items": [ - {"block_id": "chtxxxxxxxx", "name": "图表", "type": "column"}, - {"block_id": "chtxxxxxxxx", "name": "总利润", "type": "statistics"} - ], - "total": 4, - "has_more": false -} -``` - -## 返回重点 - -| 字段 | 说明 | -|------|------| -| `items` | 组件列表,每项包含 `block_id`(ID)、`name`(名称)、`type`(类型)| -| `total` | 组件总数 | -| `has_more` | 是否有更多组件(为 `true` 时需用 `page_token` 继续获取)| - -## 坑点 - -- `+dashboard-block-list` 禁止并发调用;批量执行时只能串行。 - -## 参考 - -- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引 diff --git a/skills/lark-base/references/lark-base-dashboard-block-update.md b/skills/lark-base/references/lark-base-dashboard-block-update.md deleted file mode 100644 index 38cc39eda..000000000 --- a/skills/lark-base/references/lark-base-dashboard-block-update.md +++ /dev/null @@ -1,84 +0,0 @@ -# base +dashboard-block-update - -> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流 -> **关键:** 更新前必须阅读 [dashboard-block-data-config.md](dashboard-block-data-config.md) 了解 data_config 结构和更新规则 - -更新仪表盘中组件的名称或数据配置。 - -## 关键约束 - -- **不可修改 `type` 和 `layout`** — 只能更新 `name` 和 `data_config`。 -- **`data_config` 顶层按 key merge** — 只需传入要修改的顶层字段,未传的字段保留原值;但每个字段内部是全量替换(如传新 `filter` 会完整覆盖旧 `filter`)。 -- **`series` 与 `count_all` 二选一** — 且至少提供其一。 -- **表名用 name,不是 ID** — `table_name` 对应的是表名称(如「订单表」),不是 `table_id`。 -- **`user_id_type`** 仅在 filter 涉及人员字段时有意义。 - -> [!TIP] -> CLI 默认会对 `data_config` 做轻量校验与规范化;如需兼容特殊场景,可加 `--no-validate` 跳过。 - -## 推荐命令 - -```bash -# 示例 1:更新组件名称 -lark-cli base +dashboard-block-update \ - --base-token xxx \ - --dashboard-id blk_xxx \ - --block-id chtxxxxxxxx \ - --name "新名称" - -# 示例 2:更新数据配置(只传要改的字段,未传字段保留原值) -lark-cli base +dashboard-block-update \ - --base-token xxx \ - --dashboard-id blk_xxx \ - --block-id chtxxxxxxxx \ - --data-config '{"filter":{"conjunction":"and","conditions":[{"field_name":"状态","operator":"is","value":"已完成"}]}}' -``` - -## 参数 - -| 参数 | 必填 | 说明 | -|------|------|------| -| `--base-token ` | 是 | Base Token | -| `--dashboard-id ` | 是 | 仪表盘 ID | -| `--block-id ` | 是 | Block ID | -| `--name ` | 否 | 新名称 | -| `--data-config ` | 否 | 数据配置 JSON。**结构随 block 的 `type` 变化**。**⚠️ 必须阅读 [dashboard-block-data-config.md](dashboard-block-data-config.md) 了解如何构造** | -| `--user-id-type ` | 否 | 用户 ID 类型,filter 涉及人员字段时使用 | -| `--no-validate` | 否 | 跳过 data_config 本地校验(用于兼容特殊场景) | -| `--dry-run` | 否 | 预览 API 调用,不执行 | - -## 返回示例 - -```json -{ - "block": { - "block_id": "chtxxxxxxxx", - "name": "新名称", - "type": "column", - "data_config": { - "table_name": "订单表", - "series": [{"field_name": "金额", "rollup": "SUM"}], - "group_by": [{"field_name": "类别", "mode": "integrated"}] - } - }, - "updated": true -} -``` - -## 返回重点 - -| 字段 | 说明 | -|------|------| -| `block.block_id` | 组件 ID | -| `block.name` | 更新后的名称 | -| `block.type` | 组件类型(不可修改)| -| `block.data_config` | 更新后的数据配置 | -| `updated` | 是否更新成功 | - -> [!CAUTION] -> 这是**写入操作** — 执行前必须向用户确认。 - -## 参考 - -- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引 -- [dashboard-block-data-config.md](dashboard-block-data-config.md) — data_config 结构、图表类型、filter 规则 diff --git a/skills/lark-base/references/lark-base-dashboard-create.md b/skills/lark-base/references/lark-base-dashboard-create.md deleted file mode 100644 index 6215b4aac..000000000 --- a/skills/lark-base/references/lark-base-dashboard-create.md +++ /dev/null @@ -1,73 +0,0 @@ -# base +dashboard-create - -> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流。 - -创建空白仪表盘。创建成功后务必记录返回的 `dashboard_id`,后续添加组件和管理仪表盘都需要用到。 - -## 关键约束 - -- **dashboard_id** 在 create 返回中取得,后续 get/update/delete 使用。 - -## 推荐命令 - -```bash -# 创建仪表盘 -lark-cli base +dashboard-create \ - --base-token VwGhb**************fMnod \ - --name "销售报表" - -# 创建仪表盘(指定主题) -lark-cli base +dashboard-create \ - --base-token VwGhb**************fMnod \ - --name "销售报表" \ - --theme-style default -``` - -## 参数 - -| 参数 | 必填 | 说明 | -|------|------|------| -| `--base-token ` | 是 | Base Token | -| `--name ` | 是 | 仪表盘名称 | -| `--theme-style