mirror of
https://github.com/larksuite/cli.git
synced 2026-07-03 22:24:31 +08:00
Compare commits
4 Commits
feat/short
...
feat/eval_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ff9c84cd8 | ||
|
|
175c9f6ffc | ||
|
|
575bcc407b | ||
|
|
24ce3ec151 |
@@ -90,6 +90,7 @@ func NewCmdApiWithContext(ctx context.Context, f *cmdutil.Factory, runF func(*AP
|
||||
cmd.Flags().IntVar(&opts.PageLimit, "page-limit", 10, "max pages to fetch with --page-all (0 = unlimited)")
|
||||
cmd.Flags().IntVar(&opts.PageDelay, "page-delay", 200, "delay in ms between pages")
|
||||
cmd.Flags().StringVar(&opts.Format, "format", "json", "output format: json|ndjson|table|csv")
|
||||
cmd.Flags().Bool("json", false, "shorthand for --format json")
|
||||
cmd.Flags().StringVarP(&opts.JqExpr, "jq", "q", "", "jq expression to filter JSON output")
|
||||
cmd.Flags().BoolVar(&opts.DryRun, "dry-run", false, "print request without executing")
|
||||
cmd.Flags().StringVar(&opts.File, "file", "", "file to upload as multipart/form-data ([field=]path, supports - for stdin)")
|
||||
|
||||
@@ -718,3 +718,23 @@ func TestApiCmd_PermissionError_DerivesFirstClassFields(t *testing.T) {
|
||||
t.Errorf("LogID = %q, want %q", pe.LogID, "20260527-test-log")
|
||||
}
|
||||
}
|
||||
|
||||
func TestApiCmd_JsonFlag_Accepted(t *testing.T) {
|
||||
f, _, _, _ := cmdutil.TestFactory(t, &core.CliConfig{
|
||||
AppID: "test-app", AppSecret: "test-secret", Brand: core.BrandFeishu,
|
||||
})
|
||||
|
||||
var gotOpts *APIOptions
|
||||
cmd := NewCmdApi(f, func(opts *APIOptions) error {
|
||||
gotOpts = opts
|
||||
return nil
|
||||
})
|
||||
cmd.SetArgs([]string{"GET", "/open-apis/test", "--json"})
|
||||
err := cmd.Execute()
|
||||
if err != nil {
|
||||
t.Fatalf("--json should be accepted without error, got: %v", err)
|
||||
}
|
||||
if gotOpts.Method != "GET" {
|
||||
t.Errorf("expected method GET, got %s", gotOpts.Method)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +180,7 @@ func NewCmdServiceMethodWithContext(ctx context.Context, f *cmdutil.Factory, spe
|
||||
cmd.Flags().IntVar(&opts.PageLimit, "page-limit", 10, "max pages to fetch with --page-all (0 = unlimited)")
|
||||
cmd.Flags().IntVar(&opts.PageDelay, "page-delay", 200, "delay in ms between pages")
|
||||
cmd.Flags().StringVar(&opts.Format, "format", "json", "output format: json|ndjson|table|csv")
|
||||
cmd.Flags().Bool("json", false, "shorthand for --format json")
|
||||
cmd.Flags().StringVarP(&opts.JqExpr, "jq", "q", "", "jq expression to filter JSON output")
|
||||
cmd.Flags().BoolVar(&opts.DryRun, "dry-run", false, "print request without executing")
|
||||
if risk == "high-risk-write" {
|
||||
|
||||
@@ -765,3 +765,22 @@ func TestDetectFileFields(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestServiceMethod_JsonFlag_Accepted(t *testing.T) {
|
||||
f, _, _, _ := cmdutil.TestFactory(t, testConfig)
|
||||
|
||||
var captured *ServiceMethodOptions
|
||||
cmd := NewCmdServiceMethod(f, driveSpec(),
|
||||
map[string]interface{}{"description": "desc", "httpMethod": "GET"}, "list", "files",
|
||||
func(opts *ServiceMethodOptions) error {
|
||||
captured = opts
|
||||
return nil
|
||||
})
|
||||
cmd.SetArgs([]string{"--json"})
|
||||
if err := cmd.Execute(); err != nil {
|
||||
t.Fatalf("--json should be accepted without error, got: %v", err)
|
||||
}
|
||||
if captured == nil {
|
||||
t.Fatal("expected runF to be called")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1176,6 +1176,9 @@ func registerShortcutFlagsWithContext(ctx context.Context, cmd *cobra.Command, f
|
||||
cmdutil.RegisterFlagCompletion(cmd, "format", func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
|
||||
return []string{"json", "pretty", "table", "ndjson", "csv"}, cobra.ShellCompDirectiveNoFileComp
|
||||
})
|
||||
if cmd.Flags().Lookup("json") == nil {
|
||||
cmd.Flags().Bool("json", false, "shorthand for --format json")
|
||||
}
|
||||
}
|
||||
if s.Risk == "high-risk-write" {
|
||||
cmd.Flags().Bool("yes", false, "confirm high-risk operation")
|
||||
|
||||
@@ -96,3 +96,76 @@ func TestShortcutMount_FlagCompletionsDisabled(t *testing.T) {
|
||||
t.Fatal("did not expect completion func for --format when disabled")
|
||||
}
|
||||
}
|
||||
|
||||
func TestShortcutMount_JsonFlag_AcceptedWhenHasFormat(t *testing.T) {
|
||||
f, _, _, _ := cmdutil.TestFactory(t, nil)
|
||||
parent := &cobra.Command{Use: "root"}
|
||||
shortcut := Shortcut{
|
||||
Service: "test",
|
||||
Command: "+read",
|
||||
Description: "test read",
|
||||
HasFormat: true,
|
||||
Execute: func(context.Context, *RuntimeContext) error { return nil },
|
||||
}
|
||||
shortcut.Mount(parent, f)
|
||||
|
||||
cmd, _, err := parent.Find([]string{"+read"})
|
||||
if err != nil {
|
||||
t.Fatalf("Find() error = %v", err)
|
||||
}
|
||||
if flag := cmd.Flags().Lookup("json"); flag == nil {
|
||||
t.Fatal("expected --json flag to be registered on HasFormat shortcut")
|
||||
}
|
||||
}
|
||||
|
||||
func TestShortcutMount_JsonFlag_SkippedWhenConflict(t *testing.T) {
|
||||
f, _, _, _ := cmdutil.TestFactory(t, nil)
|
||||
parent := &cobra.Command{Use: "root"}
|
||||
shortcut := Shortcut{
|
||||
Service: "test",
|
||||
Command: "+update",
|
||||
Description: "test update",
|
||||
HasFormat: true,
|
||||
Flags: []Flag{
|
||||
{Name: "json", Desc: "body JSON object", Required: true},
|
||||
},
|
||||
Execute: func(context.Context, *RuntimeContext) error { return nil },
|
||||
}
|
||||
shortcut.Mount(parent, f)
|
||||
|
||||
cmd, _, err := parent.Find([]string{"+update"})
|
||||
if err != nil {
|
||||
t.Fatalf("Find() error = %v", err)
|
||||
}
|
||||
// --json flag exists (from custom Flags), but should be the string type, not bool.
|
||||
flag := cmd.Flags().Lookup("json")
|
||||
if flag == nil {
|
||||
t.Fatal("expected --json flag from custom Flags")
|
||||
}
|
||||
if flag.DefValue != "" {
|
||||
t.Errorf("expected empty default (string flag), got %q", flag.DefValue)
|
||||
}
|
||||
}
|
||||
|
||||
func TestShortcutMount_JsonFlag_RegisteredWithoutHasFormat(t *testing.T) {
|
||||
f, _, _, _ := cmdutil.TestFactory(t, nil)
|
||||
parent := &cobra.Command{Use: "root"}
|
||||
shortcut := Shortcut{
|
||||
Service: "test",
|
||||
Command: "+write",
|
||||
Description: "test write",
|
||||
HasFormat: false,
|
||||
Execute: func(context.Context, *RuntimeContext) error { return nil },
|
||||
}
|
||||
shortcut.Mount(parent, f)
|
||||
|
||||
cmd, _, err := parent.Find([]string{"+write"})
|
||||
if err != nil {
|
||||
t.Fatalf("Find() error = %v", err)
|
||||
}
|
||||
// --format is now registered for all shortcuts (regardless of HasFormat),
|
||||
// so --json should also be present.
|
||||
if flag := cmd.Flags().Lookup("json"); flag == nil {
|
||||
t.Fatal("expected --json flag to be registered even when HasFormat is false")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,10 @@ metadata:
|
||||
|
||||
Shortcut 是对常用操作的高级封装(`lark-cli {{service}} +<verb> [flags]`)。有 Shortcut 的操作优先使用。
|
||||
|
||||
| Shortcut | 说明 |
|
||||
|----------|------|
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| Shortcut | 说明 | Reference |
|
||||
|----------|------|-----------|
|
||||
{{shortcut_rows}}
|
||||
{{/shortcuts}}
|
||||
{{#actions}}
|
||||
|
||||
@@ -96,6 +96,8 @@ lark-cli auth login --domain apps
|
||||
|
||||
Shortcut 是对常用操作的高级封装(`lark-cli apps +<verb> [flags]`)。有 Shortcut 的操作优先使用。
|
||||
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| Shortcut | 说明 |
|
||||
|----------|------|
|
||||
| [`+create`](references/lark-apps-create.md) | 创建妙搭应用(name / description / icon-url) |
|
||||
|
||||
@@ -70,6 +70,8 @@ Calendar (日历)
|
||||
|
||||
Shortcut 是对常用操作的高级封装(`lark-cli calendar +<verb> [flags]`)。有 Shortcut 的操作优先使用。
|
||||
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| Shortcut | 说明 |
|
||||
|----------|------|
|
||||
| [`+agenda`](references/lark-calendar-agenda.md) | 查看日程安排(默认今天) |
|
||||
|
||||
@@ -14,6 +14,8 @@ metadata:
|
||||
|
||||
**user 身份和 bot 身份是两条完全独立的路径**。先确定当前身份,再按下表选命令:
|
||||
|
||||
**CRITICAL — 执行任何命令之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| 想做什么 | user 身份 | bot 身份 |
|
||||
|---|---|---|
|
||||
| 按姓名 / 邮箱搜员工拿 open_id | [`+search-user`](references/lark-contact-search-user.md) | 不支持 |
|
||||
|
||||
@@ -59,6 +59,8 @@ lark-cli docs +update --api-version v2 --doc "文档URL或token" --command appen
|
||||
|
||||
Shortcut 是对常用操作的高级封装(`lark-cli docs +<verb> [flags]`)。有 Shortcut 的操作优先使用。
|
||||
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| Shortcut | 说明 |
|
||||
|----------|------|
|
||||
| [`+create`](references/lark-doc-create.md) | Create a Lark document (XML / Markdown) |
|
||||
|
||||
@@ -260,6 +260,8 @@ lark-cli drive permission.members create \
|
||||
|
||||
Shortcut 是对常用操作的高级封装(`lark-cli drive +<verb> [flags]`)。有 Shortcut 的操作优先使用。
|
||||
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| Shortcut | 说明 |
|
||||
|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [`+search`](references/lark-drive-search.md) | Search Lark docs, Wiki, and spreadsheet files with flat filter flags. Natural-language-friendly: `--edited-since`, `--mine`, `--doc-types`, etc. |
|
||||
|
||||
@@ -70,6 +70,8 @@ Item types for feed-layer flags:
|
||||
|
||||
Shortcut 是对常用操作的高级封装(`lark-cli im +<verb> [flags]`)。有 Shortcut 的操作优先使用。
|
||||
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| Shortcut | 说明 |
|
||||
|----------|------|
|
||||
| [`+chat-create`](references/lark-im-chat-create.md) | Create a group chat or topic chat; user/bot; --chat-mode group|topic; private/public; invites users/bots; optionally sets bot manager |
|
||||
|
||||
@@ -464,6 +464,8 @@ lark-cli mail user_mailbox.folders create \
|
||||
|
||||
Shortcut 是对常用操作的高级封装(`lark-cli mail +<verb> [flags]`)。有 Shortcut 的操作优先使用。
|
||||
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| Shortcut | 说明 |
|
||||
|----------|------|
|
||||
| [`+message`](references/lark-mail-message.md) | Use when reading full content for a single email by message ID. Returns normalized body content plus attachments metadata, including inline images. |
|
||||
|
||||
@@ -41,6 +41,8 @@ metadata:
|
||||
|
||||
Shortcut 是对常用操作的高级封装(`lark-cli markdown +<verb> [flags]`)。有 Shortcut 的操作优先使用。
|
||||
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| Shortcut | 说明 |
|
||||
|----------|------|
|
||||
| [`+create`](references/lark-markdown-create.md) | Create a Markdown file in Drive |
|
||||
|
||||
@@ -111,6 +111,8 @@ Minutes (妙记) ← minute_token 标识
|
||||
|
||||
Shortcut 是对常用操作的高级封装(`lark-cli minutes +<verb> [flags]`)。有 Shortcut 的操作优先使用。
|
||||
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| Shortcut | 说明 |
|
||||
| -------------------------------------------------- | --------------------------------------------------------------- |
|
||||
| [`+search`](references/lark-minutes-search.md) | Search minutes by keyword, owners, participants, and time range |
|
||||
|
||||
@@ -16,6 +16,8 @@ metadata:
|
||||
|
||||
Shortcut 是对常用操作的高级封装(`lark-cli okr +<verb> [flags]`)。有 Shortcut 的操作优先使用。
|
||||
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| Shortcut | 说明 |
|
||||
|--------------------------------------------------------------|--------------------------|
|
||||
| [`+cycle-list`](references/lark-okr-cycle-list.md) | 获取特定用户的 OKR 周期列表,可以按时间筛选 |
|
||||
|
||||
@@ -123,6 +123,7 @@ lark-cli 命令执行后,如果检测到新版本,JSON 输出中会包含 `_
|
||||
|
||||
## 安全规则
|
||||
|
||||
- **文件路径只接受相对路径**:`--file`、`--output`、`--output-dir`、`@file` 等路径参数只接受 cwd 下的相对路径,传绝对路径会报 `unsafe file path`。数据输入(`@file`、大 JSON)优先用 stdin 传入,避免路径和转义问题。
|
||||
- **禁止输出密钥**(appSecret、accessToken)到终端明文。
|
||||
- **写入/删除操作前必须确认用户意图**。
|
||||
- 用 `--dry-run` 预览危险请求。
|
||||
|
||||
@@ -179,6 +179,8 @@ lark-cli sheets +write --url "URL" --sheet-id "sheetId" --range "C6" \
|
||||
|
||||
Shortcut 是对常用操作的高级封装(`lark-cli sheets +<verb> [flags]`)。有 Shortcut 的操作优先使用。
|
||||
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
### Spreadsheet Management
|
||||
|
||||
对应参考文档:[spreadsheet-management](references/lark-sheets-spreadsheet-management.md)
|
||||
|
||||
@@ -256,6 +256,8 @@ Slides (演示文稿)
|
||||
|
||||
Shortcut 是对常用操作的高级封装(`lark-cli slides +<verb> [flags]`)。有 Shortcut 的操作优先使用。
|
||||
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| Shortcut | 说明 |
|
||||
|----------|------|
|
||||
| [`+create`](references/lark-slides-create.md) | 创建 PPT(可选 `--slides` 一步添加页面,支持 `<img src="@./local.png">` 占位符自动上传) |
|
||||
|
||||
@@ -33,6 +33,8 @@ metadata:
|
||||
> Task OpenAPI 中用于更新/操作任务的 `guid` 是任务的全局唯一标识(GUID),不是客户端展示的任务编号(例如 `t104121` / `suite_entity_num`)。
|
||||
> 对于 Feishu 的任务 applink(例如 `.../client/todo/task?guid=...`),必须使用 URL query 里的 `guid` 参数作为 task guid。
|
||||
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| Shortcut | 说明 |
|
||||
|----------|------|
|
||||
| [`+create`](references/lark-task-create.md) | create a task |
|
||||
|
||||
@@ -94,6 +94,8 @@ lark-cli vc +notes --meeting-ids "$MID"
|
||||
|
||||
Shortcut 是对常用操作的高级封装(`lark-cli vc +<verb> [flags]`)。
|
||||
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| Shortcut | 类型 | 说明 |
|
||||
| --------------------------------------------------------------- | -- | -------------------------------------------------------------------------- |
|
||||
| [`+meeting-join`](references/lark-vc-agent-meeting-join.md) | 写 | Join an in-progress meeting by 9-digit meeting number |
|
||||
|
||||
@@ -137,6 +137,8 @@ Meeting (视频会议)
|
||||
|
||||
Shortcut 是对常用操作的高级封装(`lark-cli vc +<verb> [flags]`)。有 Shortcut 的操作优先使用。
|
||||
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| Shortcut | 说明 |
|
||||
|----------|------|
|
||||
| [`+search`](references/lark-vc-search.md) | Search meeting records (requires at least one filter) |
|
||||
|
||||
@@ -33,6 +33,8 @@ metadata:
|
||||
|
||||
## Shortcuts
|
||||
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| Shortcut | 说明 |
|
||||
|---|---|
|
||||
| [`+query`](references/lark-whiteboard-query.md) | 查询画板,导出为预览图片、代码或原始节点结构 |
|
||||
|
||||
@@ -59,6 +59,8 @@ metadata:
|
||||
|
||||
Shortcut 是对常用操作的高级封装(`lark-cli wiki +<verb> [flags]`)。有 Shortcut 的操作优先使用。
|
||||
|
||||
**CRITICAL — 执行任何 Shortcut 之前,MUST 先用 Read 工具读取下表中对应的说明文档;没有文档链接的命令须执行 -h 了解用法。禁止盲调。**
|
||||
|
||||
| Shortcut | 说明 |
|
||||
|----------|------|
|
||||
| [`+move`](references/lark-wiki-move.md) | Move a wiki node, or move a Drive document into Wiki |
|
||||
|
||||
Reference in New Issue
Block a user