From e525beb8d6ddecbde68ea3b2df292f1d70a66fa5 Mon Sep 17 00:00:00 2001 From: zhaoleibd Date: Fri, 21 Aug 2026 10:49:46 +0800 Subject: [PATCH] feat(skills): unify meeting related skills (#2387) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(skills): unify meeting guidance * fix(meeting): restore domain boundary guidance * docs(meeting): remove agent rollout qualification guidance * docs(meeting): front-load skill routing description * docs(meeting): refine identity and command guidance * docs(meeting): clarify identity and pagination guidance * docs(meeting): fix minutes todo detail command * fix(meeting): clarify artifact query routing * fix(meeting): improve live meeting skill recall * fix(qualitygate): generate valid minute token placeholders * fix(meeting): address unified skill review findings * docs(meeting): add minutes permission guidance * docs(lark-meeting): 更新SKILL.md并新增会议问答引导脚本 1. 优化SKILL.md表格排版与快速行动章节内容,新增批量获取当日会议脚本的使用说明 2. 新增meeting_qa_bootstrap.py脚本,实现一站式采集当日进行中、已结束会议及未来日程,生成可直接执行的命令引导 * docs(calendar): clarify today's meeting lookup * revert(meeting): remove meeting Q&A bootstrap guidance * fix(skills): register lark-meeting suite keywords --------- Co-authored-by: maozhixiang --- README.md | 5 +- README.zh.md | 5 +- affordance/minutes.md | 51 +++++ affordance/note.md | 12 + affordance/vc.md | 44 ++++ internal/affordance/meeting_source_test.go | 26 +++ internal/qualitygate/rules/dryrun.go | 2 +- internal/qualitygate/rules/dryrun_test.go | 30 +++ scripts/domain-map.json | 2 + scripts/e2e_domains.test.js | 9 + shortcuts/minutes/skill_docs_test.go | 47 ++-- shortcuts/note/skill_docs_test.go | 48 +++- shortcuts/vc/skill_docs_test.go | 56 +++-- skill-template/lark-suite-business-info.json | 9 +- skills/lark-calendar/SKILL.md | 13 +- skills/lark-doc/references/lark-doc-fetch.md | 2 +- skills/lark-meeting/SKILL.md | 146 ++++++++++++ .../lark-minutes-apply-permission.md | 7 +- .../references/lark-minutes-detail.md | 52 +++++ .../references/lark-minutes-download.md | 8 +- .../references/lark-minutes-search.md | 38 +--- .../lark-minutes-speaker-replace.md | 7 +- .../references/lark-minutes-summary.md | 7 +- .../references/lark-minutes-todo.md | 20 +- .../references/lark-minutes-update.md | 5 +- .../references/lark-minutes-upload.md | 65 ++++++ .../references/lark-note-detail.md | 15 ++ .../references/lark-note-transcript.md | 19 ++ .../references/lark-vc-agent-meeting-join.md | 59 +---- .../references/lark-vc-agent-meeting-leave.md | 43 +--- .../lark-meeting/references/lark-vc-detail.md | 31 +++ .../references/lark-vc-meeting-events.md | 106 +-------- .../references/lark-vc-meeting-list-active.md | 33 +-- .../lark-vc-meeting-message-send.md | 8 +- .../references/lark-vc-recording.md | 67 +----- .../references/lark-vc-search.md | 37 +-- .../scenes/create-and-edit-minutes.md | 125 +++++++++++ .../scenes/live-meeting-attend.md | 107 +++++++++ .../scenes/live-meeting-interact.md | 72 ++++++ .../scenes/query-meeting-and-artifacts.md | 90 ++++++++ .../scenes/query-minutes-and-artifacts.md | 70 ++++++ .../scenes/query-note-and-artifacts.md | 127 +++++++++++ skills/lark-minutes/SKILL.md | 208 +---------------- .../references/lark-minutes-detail.md | 63 ------ .../references/lark-minutes-upload.md | 104 --------- skills/lark-note/SKILL.md | 93 +------- .../lark-note/references/lark-note-detail.md | 29 --- .../references/lark-note-transcript.md | 25 --- skills/lark-task/SKILL.md | 2 +- skills/lark-vc-agent/SKILL.md | 211 +----------------- skills/lark-vc/SKILL.md | 210 +---------------- skills/lark-vc/references/lark-vc-detail.md | 49 ---- .../references/vc-domain-boundaries.md | 203 ----------------- skills/lark-workflow-meeting-summary/SKILL.md | 24 +- .../cli_e2e/vc/meeting_skill_embedded_test.go | 72 ++++++ .../vc/vc_skill_routing_contract_test.go | 39 ++-- 56 files changed, 1403 insertions(+), 1654 deletions(-) create mode 100644 affordance/minutes.md create mode 100644 affordance/note.md create mode 100644 affordance/vc.md create mode 100644 internal/affordance/meeting_source_test.go create mode 100644 skills/lark-meeting/SKILL.md rename skills/{lark-minutes => lark-meeting}/references/lark-minutes-apply-permission.md (95%) create mode 100644 skills/lark-meeting/references/lark-minutes-detail.md rename skills/{lark-minutes => lark-meeting}/references/lark-minutes-download.md (96%) rename skills/{lark-minutes => lark-meeting}/references/lark-minutes-search.md (82%) rename skills/{lark-minutes => lark-meeting}/references/lark-minutes-speaker-replace.md (94%) rename skills/{lark-minutes => lark-meeting}/references/lark-minutes-summary.md (95%) rename skills/{lark-minutes => lark-meeting}/references/lark-minutes-todo.md (88%) rename skills/{lark-minutes => lark-meeting}/references/lark-minutes-update.md (91%) create mode 100644 skills/lark-meeting/references/lark-minutes-upload.md create mode 100644 skills/lark-meeting/references/lark-note-detail.md create mode 100644 skills/lark-meeting/references/lark-note-transcript.md rename skills/{lark-vc-agent => lark-meeting}/references/lark-vc-agent-meeting-join.md (62%) rename skills/{lark-vc-agent => lark-meeting}/references/lark-vc-agent-meeting-leave.md (63%) create mode 100644 skills/lark-meeting/references/lark-vc-detail.md rename skills/{lark-vc => lark-meeting}/references/lark-vc-meeting-events.md (86%) rename skills/{lark-vc => lark-meeting}/references/lark-vc-meeting-list-active.md (69%) rename skills/{lark-vc => lark-meeting}/references/lark-vc-meeting-message-send.md (95%) rename skills/{lark-vc => lark-meeting}/references/lark-vc-recording.md (57%) rename skills/{lark-vc => lark-meeting}/references/lark-vc-search.md (79%) create mode 100644 skills/lark-meeting/scenes/create-and-edit-minutes.md create mode 100644 skills/lark-meeting/scenes/live-meeting-attend.md create mode 100644 skills/lark-meeting/scenes/live-meeting-interact.md create mode 100644 skills/lark-meeting/scenes/query-meeting-and-artifacts.md create mode 100644 skills/lark-meeting/scenes/query-minutes-and-artifacts.md create mode 100644 skills/lark-meeting/scenes/query-note-and-artifacts.md delete mode 100644 skills/lark-minutes/references/lark-minutes-detail.md delete mode 100644 skills/lark-minutes/references/lark-minutes-upload.md delete mode 100644 skills/lark-note/references/lark-note-detail.md delete mode 100644 skills/lark-note/references/lark-note-transcript.md delete mode 100644 skills/lark-vc/references/lark-vc-detail.md delete mode 100644 skills/lark-vc/references/vc-domain-boundaries.md create mode 100644 tests/cli_e2e/vc/meeting_skill_embedded_test.go diff --git a/README.md b/README.md index 4f89edb9..db720a63 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ The official [Lark/Feishu](https://www.larksuite.com/) CLI tool, maintained by t | 📚 Wiki | Create and manage knowledge spaces, nodes, and documents | | 👤 Contact | Search users by name/email/phone, get user profiles | | 📧 Mail | Browse, search, read emails, send, reply, forward, manage drafts, watch new mail | -| 🎥 Meetings | Search meeting records, query meeting minutes artifacts and recordings | +| 🎥 Meetings | Search live and historical meetings, inspect participants and artifacts, analyze transcripts, manage Minutes, and assist in meetings | | 🕐 Attendance | Query personal attendance check-in records | | ✍️ Approval | Query approval tasks, approve/reject/transfer tasks, cancel and CC instances | | 🎯 OKR | Query, create, update OKRs; manage objective & key results, alignments, indicators and progress. | @@ -151,9 +151,8 @@ lark-cli auth status | `lark-contact` | Search users by name/email/phone, get user profiles | | `lark-wiki` | Knowledge spaces, nodes, documents | | `lark-event` | Real-time event subscriptions (WebSocket), regex routing & agent-friendly format | -| `lark-vc` | Search meeting records, query meeting minutes (summary, todos, transcript) | +| `lark-meeting` | Search live or historical meetings, inspect participants and artifacts, analyze transcripts, manage Minutes, and assist in meetings | | `lark-whiteboard` | Whiteboard/chart DSL rendering | -| `lark-minutes` | Minutes metadata & AI artifacts (summary, todos, chapters); upload audio/video to create minutes, download media | | `lark-openapi-explorer` | Explore underlying APIs from official docs | | `lark-skill-maker` | Custom skill creation framework | | `lark-attendance` | Query personal attendance check-in records | diff --git a/README.zh.md b/README.zh.md index 5d23cc48..95722b39 100644 --- a/README.zh.md +++ b/README.zh.md @@ -45,7 +45,7 @@ | 📚 知识库 | 创建和管理知识空间、节点和文档 | | 👤 通讯录 | 按姓名/邮箱/手机号搜索用户、获取用户信息 | | 📧 邮箱 | 浏览、搜索、阅读邮件,发送、回复、转发邮件,管理草稿,监听新邮件 | -| 🎥 视频会议 | 搜索会议记录、查询会议纪要产物与会议录制 | +| 🎥 视频会议 | 查询进行中或历史会议、参会人和会议产物,分析逐字稿,管理妙记并提供会中协助 | | 🕐 考勤打卡 | 查询个人考勤打卡记录 | | ✍️ 审批 | 查询审批任务、同意/拒绝/转交审批任务、撤回与抄送审批实例 | | 🎯 OKR | 查询、创建、更新 OKR,管理目标、关键结果、对齐、指标和进展记录 | @@ -152,9 +152,8 @@ lark-cli auth status | `lark-contact` | 按姓名/邮箱/手机号搜索用户,获取用户信息 | | `lark-wiki` | 知识空间、节点、文档 | | `lark-event` | 实时事件订阅(WebSocket),支持正则路由与 Agent 友好格式 | -| `lark-vc` | 搜索会议记录、查询会议纪要产物(总结、待办、逐字稿) | +| `lark-meeting` | 查询进行中或历史会议、参会人和会议产物,分析逐字稿,管理妙记并提供会中协助 | | `lark-whiteboard` | 画板/图表 DSL 渲染 | -| `lark-minutes` | 妙记元数据与 AI 产物(总结、待办、章节),上传音视频生成妙记,下载音视频文件 | | `lark-openapi-explorer` | 从官方文档探索底层 API | | `lark-skill-maker` | 自定义 skill 创建框架 | | `lark-attendance` | 查询个人考勤打卡记录 | diff --git a/affordance/minutes.md b/affordance/minutes.md new file mode 100644 index 00000000..dcd6ec69 --- /dev/null +++ b/affordance/minutes.md @@ -0,0 +1,51 @@ +# minutes +> skill: lark-meeting + +## +search + +### Skills +- lark-meeting/references/lark-minutes-search.md + +## minutes get + +## +detail + +### Skills +- lark-meeting/references/lark-minutes-detail.md + +## +download + +### Skills +- lark-meeting/references/lark-minutes-download.md + +## +upload + +### Skills +- lark-meeting/references/lark-minutes-upload.md + +## +update + +### Skills +- lark-meeting/references/lark-minutes-update.md + +## +speaker-replace + +### Skills +- lark-meeting/references/lark-minutes-speaker-replace.md + +## +word-replace + +## +summary + +### Skills +- lark-meeting/references/lark-minutes-summary.md + +## +todo + +### Skills +- lark-meeting/references/lark-minutes-todo.md + +## +apply-permission + +### Skills +- lark-meeting/references/lark-minutes-apply-permission.md diff --git a/affordance/note.md b/affordance/note.md new file mode 100644 index 00000000..53caf02b --- /dev/null +++ b/affordance/note.md @@ -0,0 +1,12 @@ +# note +> skill: lark-meeting + +## +detail + +### Skills +- lark-meeting/references/lark-note-detail.md + +## +transcript + +### Skills +- lark-meeting/references/lark-note-transcript.md diff --git a/affordance/vc.md b/affordance/vc.md new file mode 100644 index 00000000..8934a74c --- /dev/null +++ b/affordance/vc.md @@ -0,0 +1,44 @@ +# vc +> skill: lark-meeting + +## +search + +### Skills +- lark-meeting/references/lark-vc-search.md + +## +detail + +### Skills +- lark-meeting/references/lark-vc-detail.md + +## meeting get + +## +recording + +### Skills +- lark-meeting/references/lark-vc-recording.md + +## +meeting-list-active + +### Skills +- lark-meeting/references/lark-vc-meeting-list-active.md + +## +meeting-events + +### Skills +- lark-meeting/references/lark-vc-meeting-events.md + +## +meeting-message-send + +### Skills +- lark-meeting/references/lark-vc-meeting-message-send.md + +## +meeting-join + +### Skills +- lark-meeting/references/lark-vc-agent-meeting-join.md + +## +meeting-leave + +### Skills +- lark-meeting/references/lark-vc-agent-meeting-leave.md diff --git a/internal/affordance/meeting_source_test.go b/internal/affordance/meeting_source_test.go new file mode 100644 index 00000000..81bd45b5 --- /dev/null +++ b/internal/affordance/meeting_source_test.go @@ -0,0 +1,26 @@ +// Copyright (c) 2026 Lark Technologies Pte. Ltd. +// SPDX-License-Identifier: MIT + +package affordance + +import ( + "os" + "testing" +) + +func TestMeetingDomainsDeclareUnifiedSkill(t *testing.T) { + previousSource := mdSource + t.Cleanup(func() { SetSource(previousSource) }) + SetSource(os.DirFS("../../affordance")) + + for _, domain := range []string{"vc", "minutes", "note"} { + t.Run(domain, func(t *testing.T) { + if got, ok := DomainSkill(domain); !ok || got != "lark-meeting" { + t.Fatalf("DomainSkill(%s) = (%q, %v), want (lark-meeting, true)", domain, got, ok) + } + if got, ok := DomainSkills(domain); !ok || len(got) != 1 || got[0] != "lark-meeting" { + t.Fatalf("DomainSkills(%s) = (%v, %v), want ([lark-meeting], true)", domain, got, ok) + } + }) + } +} diff --git a/internal/qualitygate/rules/dryrun.go b/internal/qualitygate/rules/dryrun.go index aeeadff6..a3e8d459 100644 --- a/internal/qualitygate/rules/dryrun.go +++ b/internal/qualitygate/rules/dryrun.go @@ -382,7 +382,7 @@ func fakeValueFromPlaceholderName(name string) (string, bool) { case hasPlaceholderToken(tokens, "meeting"): return "meeting_test123", true case hasPlaceholderToken(tokens, "minute"): - return "obcn_test123", true + return "obcntest123", true case hasPlaceholderToken(tokens, "task"): return "task_test123", true case hasPlaceholderToken(tokens, "item"): diff --git a/internal/qualitygate/rules/dryrun_test.go b/internal/qualitygate/rules/dryrun_test.go index dcf28043..3a197cd0 100644 --- a/internal/qualitygate/rules/dryrun_test.go +++ b/internal/qualitygate/rules/dryrun_test.go @@ -165,6 +165,36 @@ func TestRunDryRunsMaterializesTypedPlaceholderFlagValues(t *testing.T) { } } +func TestRunDryRunsMaterializesValidMinuteTokenPlaceholder(t *testing.T) { + cliBin, argsPath := fakeDryRunCLI(t, `{"api":[{"method":"GET","url":"/open-apis/minutes/v1/minutes/obcntest123"}]}`) + m := manifest.Manifest{Commands: []manifest.Command{{ + Path: "minutes +detail", + Runnable: true, + Flags: []manifest.Flag{ + {Name: "minute-tokens", TakesValue: true}, + {Name: "dry-run"}, + }, + }}} + ex := skillscan.Example{ + Raw: "lark-cli minutes +detail --minute-tokens ", + SourceFile: "skills/lark-meeting/scenes/create-and-edit-minutes.md", + Line: 28, + HasPlaceholder: true, + } + + diags, facts := RunDryRuns(context.Background(), cliBin, m, []skillscan.Example{ex}) + if len(diags) != 0 { + t.Fatalf("RunDryRuns() diagnostics = %#v", diags) + } + if len(facts) != 1 || !facts[0].Executable || facts[0].SkipReason != "" { + t.Fatalf("placeholder example should be executable after materialization: %#v", facts) + } + wantArgs := []string{"minutes", "+detail", "--minute-tokens", "obcntest123", "--dry-run"} + if gotArgs := readArgs(t, argsPath); !reflect.DeepEqual(gotArgs, wantArgs) { + t.Fatalf("fake CLI args = %#v, want %#v", gotArgs, wantArgs) + } +} + func TestRunDryRunsIgnoresTrailingShellComment(t *testing.T) { cliBin, argsPath := fakeDryRunCLI(t, `{"api":[{"method":"GET","url":"/open-apis/docx/v1/documents/doccnxxxx"}]}`) m := manifest.Manifest{Commands: []manifest.Command{{ diff --git a/scripts/domain-map.json b/scripts/domain-map.json index e7e37fd2..5328280f 100644 --- a/scripts/domain-map.json +++ b/scripts/domain-map.json @@ -20,7 +20,9 @@ { "prefix": "shortcuts/event/", "labelDomains": [], "e2eDomains": ["event"] }, { "prefix": "skills/lark-im/", "labelDomains": ["im"], "e2eDomains": ["im"] }, + { "prefix": "skills/lark-meeting/", "labelDomains": ["vc"], "e2eDomains": ["vc", "minutes", "note"] }, { "prefix": "skills/lark-vc/", "labelDomains": ["vc"], "e2eDomains": ["vc"] }, + { "prefix": "skills/lark-vc-agent/", "labelDomains": ["vc"], "e2eDomains": ["vc"] }, { "prefix": "skills/lark-doc/", "labelDomains": ["ccm"], "e2eDomains": ["docs"] }, { "prefix": "skills/lark-wiki/", "labelDomains": ["ccm"], "e2eDomains": ["wiki"] }, { "prefix": "skills/lark-drive/", "labelDomains": ["ccm"], "e2eDomains": ["drive"] }, diff --git a/scripts/e2e_domains.test.js b/scripts/e2e_domains.test.js index 5657d7f5..9114d2e7 100644 --- a/scripts/e2e_domains.test.js +++ b/scripts/e2e_domains.test.js @@ -87,6 +87,15 @@ test("uses shared map for skill domain changes", () => { assert.match(output.live_packages, /github\.com\/larksuite\/cli\/tests\/cli_e2e\/sheets/); }); +test("runs every meeting package for the consolidated meeting skill", () => { + const output = runDomains(["skills/lark-meeting/scenes/query-meeting-and-artifacts.md"]); + assert.equal(output.mode, "subset"); + assert.equal(output.domains, "minutes,note,vc"); + assert.match(output.live_packages, /github\.com\/larksuite\/cli\/tests\/cli_e2e\/minutes/); + assert.match(output.live_packages, /github\.com\/larksuite\/cli\/tests\/cli_e2e\/note/); + assert.match(output.live_packages, /github\.com\/larksuite\/cli\/tests\/cli_e2e\/vc/); +}); + test("falls back to full when a mapped path has no e2e package", () => { const output = runDomains(["shortcuts/whiteboard/export.go"]); assert.equal(output.mode, "full"); diff --git a/shortcuts/minutes/skill_docs_test.go b/shortcuts/minutes/skill_docs_test.go index 4bdcbbf7..7edf9e48 100644 --- a/shortcuts/minutes/skill_docs_test.go +++ b/shortcuts/minutes/skill_docs_test.go @@ -37,31 +37,34 @@ func readSkillDoc(t *testing.T, relPath string) string { } // TestMinutesBotShortcutsIdentityDocsMatchAuthTypes pins that every minutes -// shortcut declared bot-capable in code is documented as such in the main -// SKILL.md identity line, so the two sources can't silently diverge again. +// shortcut declared bot-capable in code is documented as such in the +// lark-meeting reference that owns the command guidance. func TestMinutesBotShortcutsIdentityDocsMatchAuthTypes(t *testing.T) { - skill := readSkillDoc(t, "skills/lark-minutes/SKILL.md") + skill := readSkillDoc(t, "skills/lark-meeting/SKILL.md") for _, cmd := range []struct { name string authTypes []string + reference string }{ - {"+search", MinutesSearch.AuthTypes}, - {"+detail", MinutesDetail.AuthTypes}, - {"+download", MinutesDownload.AuthTypes}, - {"+apply-permission", MinutesApplyPermission.AuthTypes}, + {"+search", MinutesSearch.AuthTypes, "lark-minutes-search.md"}, + {"+detail", MinutesDetail.AuthTypes, "lark-minutes-detail.md"}, + {"+download", MinutesDownload.AuthTypes, "lark-minutes-download.md"}, + {"+apply-permission", MinutesApplyPermission.AuthTypes, "lark-minutes-apply-permission.md"}, } { if !hasAuthType(cmd.authTypes, "bot") { t.Errorf("%s AuthTypes = %v, want bot included", cmd.name, cmd.authTypes) continue } - token := "`" + cmd.name + "`" - if !strings.Contains(skill, token) { - t.Errorf("skills/lark-minutes/SKILL.md identity section must mention %s alongside its bot support", token) + if !strings.Contains(skill, "references/"+cmd.reference) { + t.Errorf("skills/lark-meeting/SKILL.md must link %s to %s", cmd.name, cmd.reference) + } + reference := readSkillDoc(t, "skills/lark-meeting/references/"+cmd.reference) + for _, identity := range []string{"--as user", "--as bot"} { + if !strings.Contains(reference, identity) { + t.Errorf("%s must document %s support for %s", cmd.reference, identity, cmd.name) + } } - } - if !strings.Contains(skill, "也支持 `--as bot`") { - t.Error("skills/lark-minutes/SKILL.md identity section must state which commands also support --as bot") } } @@ -74,16 +77,28 @@ func TestMinutesApplyPermissionHasReference(t *testing.T) { t.Fatalf("MinutesApplyPermission.AuthTypes = %v, want bot included (this PR's contract)", MinutesApplyPermission.AuthTypes) } - reference := readSkillDoc(t, "skills/lark-minutes/references/lark-minutes-apply-permission.md") + reference := readSkillDoc(t, "skills/lark-meeting/references/lark-minutes-apply-permission.md") for _, must := range []string{"--as bot", "--as user", "身份", "missing scope"} { if !strings.Contains(reference, must) { t.Errorf("lark-minutes-apply-permission.md must cover %q (user/bot identity + scope-vs-ACL guidance)", must) } } + skill := readSkillDoc(t, "skills/lark-meeting/SKILL.md") + if !strings.Contains(skill, "references/lark-minutes-apply-permission.md") { + t.Error("skills/lark-meeting/SKILL.md command table must link +apply-permission to its reference doc") + } +} + +func TestLegacyMinutesSkillRoutesToMeetingSkill(t *testing.T) { skill := readSkillDoc(t, "skills/lark-minutes/SKILL.md") - if !strings.Contains(skill, "[`+apply-permission`](references/lark-minutes-apply-permission.md)") { - t.Error("skills/lark-minutes/SKILL.md Shortcuts table must link +apply-permission to its reference doc") + for _, must := range []string{ + "本技能只用于兼容旧名称,不直接处理业务。", + "../lark-meeting/SKILL.md", + } { + if !strings.Contains(skill, must) { + t.Errorf("skills/lark-minutes/SKILL.md must preserve compatibility routing %q", must) + } } } diff --git a/shortcuts/note/skill_docs_test.go b/shortcuts/note/skill_docs_test.go index ce5a6324..cb74fffd 100644 --- a/shortcuts/note/skill_docs_test.go +++ b/shortcuts/note/skill_docs_test.go @@ -42,12 +42,12 @@ func TestNoteIdentityDocsMatchAuthTypes(t *testing.T) { t.Fatalf("NoteTranscript.AuthTypes = %v now includes bot; update the bot+unified stop-path guidance below (and this test) instead of leaving it stale", NoteTranscript.AuthTypes) } - skill := readSkillDoc(t, "skills/lark-note/SKILL.md") - if !strings.Contains(skill, "`+detail` 支持 `--as user` / `--as bot`") { - t.Error("skills/lark-note/SKILL.md must state that +detail supports both user and bot") + scene := readSkillDoc(t, "skills/lark-meeting/scenes/query-note-and-artifacts.md") + if !strings.Contains(scene, "`note +detail` 支持 `--as user` / `--as bot`") { + t.Error("query-note-and-artifacts.md must state that note +detail supports both user and bot") } - if !strings.Contains(skill, "`+transcript` 仅支持 `--as user`") { - t.Error("skills/lark-note/SKILL.md must state that +transcript is user-only (matches NoteTranscript.AuthTypes)") + if !strings.Contains(scene, "`note +transcript` 仅支持 `--as user`") { + t.Error("query-note-and-artifacts.md must state that note +transcript is user-only (matches NoteTranscript.AuthTypes)") } } @@ -57,9 +57,9 @@ func TestNoteIdentityDocsMatchAuthTypes(t *testing.T) { // letting an agent silently drop --as and switch identity. func TestNoteUnifiedBotStopPathIsDocumented(t *testing.T) { for _, path := range []string{ - "skills/lark-note/SKILL.md", - "skills/lark-note/references/lark-note-detail.md", - "skills/lark-note/references/lark-note-transcript.md", + "skills/lark-meeting/scenes/query-note-and-artifacts.md", + "skills/lark-meeting/references/lark-note-detail.md", + "skills/lark-meeting/references/lark-note-transcript.md", } { content := readSkillDoc(t, path) if !strings.Contains(content, "bot") || !strings.Contains(content, "user") { @@ -67,3 +67,35 @@ func TestNoteUnifiedBotStopPathIsDocumented(t *testing.T) { } } } + +func TestLegacyNoteSkillRoutesToMeetingSkill(t *testing.T) { + skill := readSkillDoc(t, "skills/lark-note/SKILL.md") + for _, must := range []string{ + "本技能只用于兼容旧名称,不直接处理业务。", + "../lark-meeting/SKILL.md", + } { + if !strings.Contains(skill, must) { + t.Errorf("skills/lark-note/SKILL.md must preserve compatibility routing %q", must) + } + } +} + +func TestMeetingNoteCoverHandlingIsReachable(t *testing.T) { + noteScene := readSkillDoc(t, "skills/lark-meeting/scenes/query-note-and-artifacts.md") + for _, must := range []string{ + "第一个 `/cover", + "--as ", + } { + if !strings.Contains(noteScene, must) { + t.Errorf("query-note-and-artifacts.md must preserve note cover handling %q", must) + } + } + + meetingScene := readSkillDoc(t, "skills/lark-meeting/scenes/query-meeting-and-artifacts.md") + if !strings.Contains(meetingScene, "query-note-and-artifacts.md") { + t.Error("query-meeting-and-artifacts.md must route intelligent-note body handling to the owning Note scene") + } +} diff --git a/shortcuts/vc/skill_docs_test.go b/shortcuts/vc/skill_docs_test.go index a6bc20a6..b936a791 100644 --- a/shortcuts/vc/skill_docs_test.go +++ b/shortcuts/vc/skill_docs_test.go @@ -35,18 +35,18 @@ func readSkillDoc(t *testing.T, relPath string) string { } // TestVCSearchIdentityDocsMatchAuthTypes pins that `+search` stays user-only -// in both code and docs. If AuthTypes ever gains "bot", this test forces a -// deliberate update to the SKILL.md/reference wording below instead of +// in both code and the reference owned by lark-meeting. If AuthTypes ever +// gains "bot", this test forces a deliberate documentation update instead of // letting the docs silently fall out of sync. func TestVCSearchIdentityDocsMatchAuthTypes(t *testing.T) { - skill := readSkillDoc(t, "skills/lark-vc/SKILL.md") - reference := readSkillDoc(t, "skills/lark-vc/references/lark-vc-search.md") + skill := readSkillDoc(t, "skills/lark-meeting/SKILL.md") + reference := readSkillDoc(t, "skills/lark-meeting/references/lark-vc-search.md") if hasAuthType(VCSearch.AuthTypes, "bot") { - t.Fatalf("VCSearch.AuthTypes = %v now includes bot; update skills/lark-vc/SKILL.md and lark-vc-search.md wording (and this test) to reflect the new support instead of leaving the user-only claims below", VCSearch.AuthTypes) + t.Fatalf("VCSearch.AuthTypes = %v now includes bot; update skills/lark-meeting/references/lark-vc-search.md wording (and this test) to reflect the new support instead of leaving the user-only claim below", VCSearch.AuthTypes) } - if !strings.Contains(skill, "`+search` 仅支持 `--as user`") { - t.Error("skills/lark-vc/SKILL.md must state that `+search` only supports --as user (matches VCSearch.AuthTypes)") + if !strings.Contains(skill, "references/lark-vc-search.md") { + t.Error("skills/lark-meeting/SKILL.md must link to the vc +search reference") } if !strings.Contains(reference, "仅支持 `user` 身份") && !strings.Contains(reference, "仅 `--as user`") { t.Error("lark-vc-search.md must state that +search only supports user identity (matches VCSearch.AuthTypes)") @@ -55,27 +55,51 @@ func TestVCSearchIdentityDocsMatchAuthTypes(t *testing.T) { // TestVCBotShortcutsIdentityDocsMatchAuthTypes pins that the VC shortcuts this // PR opened to bot (`+detail`, `+recording`) are both declared bot-capable in -// code and documented as such in the main SKILL.md identity line. +// code and documented as such in their lark-meeting references. func TestVCBotShortcutsIdentityDocsMatchAuthTypes(t *testing.T) { - skill := readSkillDoc(t, "skills/lark-vc/SKILL.md") + skill := readSkillDoc(t, "skills/lark-meeting/SKILL.md") for _, cmd := range []struct { name string authTypes []string + reference string }{ - {"+detail", VCDetail.AuthTypes}, - {"+recording", VCRecording.AuthTypes}, + {"+detail", VCDetail.AuthTypes, "lark-vc-detail.md"}, + {"+recording", VCRecording.AuthTypes, "lark-vc-recording.md"}, } { if !hasAuthType(cmd.authTypes, "bot") { t.Errorf("%s AuthTypes = %v, want bot included (this PR's contract)", cmd.name, cmd.authTypes) continue } - token := "`" + cmd.name + "`" - if !strings.Contains(skill, token) { - t.Errorf("skills/lark-vc/SKILL.md identity section must mention %s alongside its bot support", token) + if !strings.Contains(skill, "references/"+cmd.reference) { + t.Errorf("skills/lark-meeting/SKILL.md must link %s to %s", cmd.name, cmd.reference) + } + reference := readSkillDoc(t, "skills/lark-meeting/references/"+cmd.reference) + for _, identity := range []string{"--as user", "--as bot"} { + if !strings.Contains(reference, identity) { + t.Errorf("%s must document %s support for %s", cmd.reference, identity, cmd.name) + } } } - if !strings.Contains(skill, "也支持 `--as bot`") { - t.Error("skills/lark-vc/SKILL.md identity section must state which commands also support --as bot") +} + +func TestMeetingArtifactSceneDelegatesToDomainOwners(t *testing.T) { + scene := readSkillDoc(t, "skills/lark-meeting/scenes/query-meeting-and-artifacts.md") + for _, target := range []string{ + "query-note-and-artifacts.md", + "query-minutes-and-artifacts.md", + } { + if !strings.Contains(scene, target) { + t.Errorf("query-meeting-and-artifacts.md must delegate to %s", target) + } + } + + for _, duplicatedCommand := range []string{ + "lark-cli note +detail", + "lark-cli minutes +detail", + } { + if strings.Contains(scene, duplicatedCommand) { + t.Errorf("query-meeting-and-artifacts.md must not duplicate downstream command %q", duplicatedCommand) + } } } diff --git a/skill-template/lark-suite-business-info.json b/skill-template/lark-suite-business-info.json index 4ed03a03..989b9dfe 100644 --- a/skill-template/lark-suite-business-info.json +++ b/skill-template/lark-suite-business-info.json @@ -11,8 +11,9 @@ "lark-im": ["即时通讯", "消息", "群聊"], "lark-mail": ["邮箱", "邮件"], "lark-markdown": ["Markdown 文档", ".md", "MD 文件"], - "lark-minutes": ["妙记", "音视频转写", "/minutes/"], - "lark-note": ["会议纪要"], + "lark-meeting": ["视频会议", "会议记录", "会议产物", "智能纪要", "妙记", "会议录制", "会议内容", "智能体入会", "/minutes/"], + "lark-minutes": ["lark-minutes"], + "lark-note": ["lark-note"], "lark-okr": ["OKR"], "lark-openapi-explorer": ["开放平台文档", "OpenAPI"], "lark-shared": ["授权", "配置", "登录", "登录态", "身份", "版本", "更新"], @@ -20,8 +21,8 @@ "lark-skill-maker": ["CLI Skill", "自定义 Skill", "能力封装"], "lark-slides": ["演示文稿", "幻灯片", "PPT", "/slides/"], "lark-task": ["任务", "待办", "任务智能体", "父任务", "子任务", "负责人", "截止时间", "任务清单", "任务搜索", "多步任务", "任务提醒"], - "lark-vc": ["视频会议", "会议纪要"], - "lark-vc-agent": ["会中能力", "视频会议机器人"], + "lark-vc": ["lark-vc"], + "lark-vc-agent": ["lark-vc-agent"], "lark-whiteboard": ["画板", "图表"], "lark-wiki": ["知识库", "知识空间", "空间目录", "/wiki/"], "lark-workflow-meeting-summary": ["会议纪要工作流", "会议纪要", "会议周报"], diff --git a/skills/lark-calendar/SKILL.md b/skills/lark-calendar/SKILL.md index 2df4aefa..444addcf 100644 --- a/skills/lark-calendar/SKILL.md +++ b/skills/lark-calendar/SKILL.md @@ -1,7 +1,7 @@ --- name: lark-calendar version: 1.0.0 -description: "飞书日历:管理日历日程和会议室。查看/搜索日程、创建/更新日程、管理参会人、查询忙闲和推荐时段、预定会议室。当用户需要查看日程安排、创建/修改会议、查询/预定会议室时使用。不负责:查询过去的视频会议记录(走 lark-vc)、待办任务(走 lark-task)。" +description: "飞书日历:管理日历日程和会议室。查看/搜索日程、创建/更新日程、管理参会人、查询忙闲和推荐时段、预定会议室。当用户需要查看日程安排、创建/修改会议、查询/预定会议室时使用。不负责:查询过去的视频会议记录(走 lark-meeting)、待办任务(走 lark-task)。" metadata: requires: bins: ["lark-cli"] @@ -127,11 +127,12 @@ lark-cli calendar +freebusy --start 2026-03-11 --end 2026-03-12 --user-id ou_xxx | 用户意图 | 路由到 | |----------|--------| -| 查询过去的会议("昨天的会议""上周的会") | [`../lark-vc/SKILL.md`](../lark-vc/SKILL.md)(会议数据含即时会议,仅查日程会遗漏) | +| 查询过去的会议("昨天的会议""上周的会") | [`../lark-meeting/SKILL.md`](../lark-meeting/SKILL.md)(会议数据含即时会议,仅查日程会遗漏) | +| 今天有哪些会议| 需要合并两部分内容:[`../lark-meeting/SKILL.md`](../lark-meeting/SKILL.md) 中的 `vc +search` 查询今天已结束的会议, `calendar +agenda` 查询进行中或未开始的日程。| | 查询日历/日程或未来时间的会议 | 本 skill | | 按关键词搜索日程 | 本 skill(`+search-event`) | | 从日程获取关联的视频会议 ID 或用户绑定的会议纪要文档 | 本 skill(`+meeting`) | -| 从日程进一步拿 AI 智能纪要 / 逐字稿 / 妙记产物 | 先 `+meeting` 取 `meeting_id`,再 [`vc +detail`](../lark-vc/references/lark-vc-detail.md) → [`note +detail`](../lark-note/references/lark-note-detail.md) / [`minutes +detail`](../lark-minutes/references/lark-minutes-detail.md) | +| 从日程进一步拿 AI 智能纪要 / 逐字稿 / 妙记产物 | 先 `+meeting` 取 `meeting_id`,再进入 [`lark-meeting`](../lark-meeting/SKILL.md):[`vc +detail`](../lark-meeting/references/lark-vc-detail.md) → [`note +detail`](../lark-meeting/references/lark-note-detail.md) / [`minutes +detail`](../lark-meeting/references/lark-minutes-detail.md) | | 预约/改约日程、调整时间、添加/更换会议室、查会议室 | 先判断新建 vs 编辑,再进入 [schedule-meeting 工作流](references/lark-calendar-schedule-meeting.md) | | 仅编辑日程字段(标题/描述)或增删参会人(不涉及时间和会议室) | 先定位 `event_id`,再读 [+update](references/lark-calendar-update.md) 执行变更 | | 编辑/删除重复性日程(「改这个重复日程」「删掉后面的」「全部取消」等) | 先读 [重复性日程操作规范](references/lark-calendar-recurring.md),确认操作范围后执行 | @@ -165,8 +166,8 @@ lark-cli calendar [flags] # 查询用户主日历 lark-cli calendar calendars primary -# 获取日程分享链接 -lark-cli calendar events share_info --calendar-id --event-id +# 获取日程详情及 app_link +lark-cli calendar events get --calendar-id --event-id # 删除日程 lark-cli calendar events delete --calendar-id --event-id @@ -196,7 +197,7 @@ lark-cli im +chat-search --query --as user ## 不在本 skill 范围 -- 查询过去的视频会议记录 → [lark-vc](../lark-vc/SKILL.md) +- 查询过去的视频会议记录 → [lark-meeting](../lark-meeting/SKILL.md) - 待办任务管理 → [lark-task](../lark-task/SKILL.md) - 通讯录 → [lark-contact](../lark-contact/SKILL.md) - 即时通讯 → [lark-im](../lark-im/SKILL.md) diff --git a/skills/lark-doc/references/lark-doc-fetch.md b/skills/lark-doc/references/lark-doc-fetch.md index 5f490ea0..ab6d5cc0 100644 --- a/skills/lark-doc/references/lark-doc-fetch.md +++ b/skills/lark-doc/references/lark-doc-fetch.md @@ -127,7 +127,7 @@ lark-cli docs +fetch --doc Z1Fj...tnAc --scope section --start-block-id blkTitle |``|提取 `token`,使用 `docs +media-download`| |``、``|提取 `token` 和 `sheet-id`,转到 [`lark-sheets`](../../lark-sheets/SKILL.md)| |``、``|提取 `token` 和 `table-id`,转到 [`lark-base`](../../lark-base/SKILL.md)| -|``|提取 `vc-node-id`,使用 [`lark-note`](../../lark-note/SKILL.md) 的 `note +detail`| +|``|提取 `vc-node-id`,使用 [`lark-meeting`](../../lark-meeting/SKILL.md) 的 `note +detail`| |``|提取 `src-token` 和 `src-block-id`,读取源文档并定位 block| ## 参考 diff --git a/skills/lark-meeting/SKILL.md b/skills/lark-meeting/SKILL.md new file mode 100644 index 00000000..d280306e --- /dev/null +++ b/skills/lark-meeting/SKILL.md @@ -0,0 +1,146 @@ +--- +name: lark-meeting +version: 1.0.0 +description: "飞书视频会议:查询会议记录与会议产物(纪要/逐字稿/妙记)、妙记搜索/上传/下载/编辑、机器人参与会议;查询进行中的会议、实时会议内容(发言/聊天/共享文档)问答(会上/会里)、发送会中聊天/表情;基于 meeting_id、meeting_no、event_id、note_id、minute_token、vc-node-id 或妙记 URL 查询相关信息。预约会议、忙闲和会议室管理走 lark-calendar。" +metadata: + requires: + bins: ["lark-cli"] + cliHelp: "lark-cli vc --help;lark-cli minutes --help;lark-cli note --help" +--- + +# lark-meeting + +飞书视频会议业务的统一入口,支持查询会议记录、实时会议互动、管理妙记、阅读智能纪要等操作。本技能负责领域关系、任务路由和跨命令编排。 + +无需预读 [`lark-shared`](../lark-shared/SKILL.md) 或预跑 `auth status --verify`,仅遇到未认证、token / 身份或 scope 错误时读取该 Skill,修复后重试。认证、身份或 scope 管理请求则直接使用该 Skill。 + +## 身份初始化与延续 + +把 `source_identity` 作为跨命令工作流的状态: + +1. 上下文已有来源身份:严格沿用。用户要求切换时先说明身份连续性和权限影响,不静默切换。 +2. 没有来源身份,用户明确指定身份:使用用户指定的 `--as`。 +3. 没有来源身份且用户未指定:操作语义明确要求应用机器人时使用 `--as bot`,否则显式使用 `--as user`。 + +确定 `source_identity` 后,再检查目标命令是否支持该身份: + +- 支持:显式传入并继续执行。 +- 不支持:说明限制并停止;不要为了让命令成功而替换身份。 +- 只有用户明确同意切换身份后,才以新身份重新开始一条工作流。 + +## 领域模型与概念 + +```text +[会议来源] + +Calendar 日程 (event_id) ──预约或关联──┐ +即时会议(无 event_id)────────────────┴──► 会议 (meeting_id) + +Calendar 日程 ──meeting_note────────────► Doc(用户纪要,独立于 AI 智能纪要) + +[会议产物] + +会议 (meeting_id) +├── AI 总结 ──► Note 智能纪要 (note_id) +│ ├── 智能纪要文档 ───────────► Doc (note_doc_token) +│ ├── 逐字稿 +│ │ ├── normal ──────────► Doc (verbatim_doc_token) +│ │ └── unified ──────────► note +transcript(非独立 Doc) +│ └── 共享文档 ──────────────► Doc (shared_doc_tokens) +│ +└── 录制 ──► Minutes 妙记 (minute_token) + ├── AI 产物:Summary / Todo / Chapter / Keyword + ├── Transcript(文字记录) + └── 原始音视频 + +本地音视频 ─────────────────────────────► Minutes 妙记 (minute_token) +``` + +| 对象 | 主标识 | 概念与关系 | +|---|---|---| +| Calendar 日程 | `event_id` | 日历上的日程,包含时间、参与人、会议室和 RSVP,可预约或关联 VC 会议;不是完整的会议记录。日程上的 `meeting_note` 是用户手工绑定的 Doc,与 AI 智能纪要无关。 | +| Meeting 会议 | `meeting_id` | 实际发生的视频会议,可以来自 Calendar,也可以是没有日程的即时会议。会议主题、时间、参会人快照和会中事件属于会议数据;Note 与 Minutes 是它可能关联的会后产物。 | +| Note 智能纪要 | `note_id` | 开启 AI 总结后形成的逻辑产物集合。`note_display_type` 决定获取逐字稿中文字记录的不同方式。 | +| Minutes 妙记 | `minute_token` | 由会议录制或本地音视频上传生成,包含总结、待办、章节、关键词、文字记录和原始音视频;可以关联 VC 会议,也可以独立存在。 | +| Doc 文档 | Doc token | 内容载体,不是会议标识。`note_doc_token`、`shared_doc_tokens` 和部分 `verbatim_doc_token` 指向 Doc;Doc token 不能当作 `note_id` 或 `meeting_id`。 | + +### 核心标识 + +- `meeting_id`:会议 ID。长数字字符串,不是 9 位会议号。 +- `meeting_no`:会议号。9 位纯数字;CLI 参数名为 `--meeting-number`。 +- `minute_token`:妙记 Token。小写字母数字串,通常取自妙记 URL `/minutes/`。 + +以上标识均按字符串原样传递,不能相互替代。 + +### 领域不变量 + +- Note 与 Minutes 分别来自 AI 总结和录制两条独立链路。一场会议可能同时有两类产物、只有其中一类,也可能都没有;不能根据 `note_id` 推断必然存在 `minute_token`,反之亦然。 +- Minutes 可以由本地音视频直接生成,因此不一定关联 `meeting_id` 或 Calendar `event_id`。 +- Calendar `meeting_note`、Note `note_id`、Minutes `minute_token` 和各类 Doc token 标识不同对象,不能互换、代入其他域的命令或从一者反推另一者。 + +## 快速行动 + +### 查询进行中的会议内容 + +```bash +# 当前用户所在会议 +lark-cli vc +meeting-list-active --as user + +# 应用机器人可见的目标用户会议 +lark-cli vc +meeting-list-active --as bot --user-id + +# 确定唯一 meeting_id 后沿用来源身份 +lark-cli vc +meeting-events --as --meeting-id --page-all --format pretty +``` + +同时有多场会议时,需要先选择要查询的会议;只有一场会议时,直接查询该场会议的会议事件。 + +应用身份只返回“目标用户正在参会、且应用机器人也在同一会议中”的会议;返回空不代表目标用户没有在开会。向用户说明结果时使用“用户身份”或“应用身份”,不要暴露 `user` / `bot` 这类内部缩写。 + +## 场景手册 + +当任务目标与场景匹配时,阅读对应的场景手册,按流程执行任务。 + +- [查询会议及其产物](scenes/query-meeting-and-artifacts.md):按主题、时间、参会人或 `meeting_id` / `meeting_no` / `event_id` 定位历史会议;查询参会人、录像和会议关联的智能纪要或妙记;基于会议记录总结或复盘。 +- [查询妙记及其产物](scenes/query-minutes-and-artifacts.md):已有妙记 URL / `minute_token`,或按标题、所有者、参与者搜索妙记;读取总结、待办、章节、关键词、逐字稿,下载原始音视频,或查询关联智能纪要。 +- [生成和修改妙记、管理妙记权限](scenes/create-and-edit-minutes.md):将本地音视频生成妙记、逐字稿、总结、待办或章节;修改妙记标题、总结、待办、关键词或说话人;申请妙记权限,或查看、分配妙记协作者权限。 +- [查询智能纪要及关联产物](scenes/query-note-and-artifacts.md):已有 `note_id`、智能纪要 Docx URL/token,或需要查询纪要正文、逐字稿、妙记和共享文档等关联产物。 +- [应用机器人参会与会中互动](scenes/live-meeting-attend.md):完整编排应用机器人的活跃会议发现、真实入会、事件拉取、文本/表情互动和明确授权后的离会。 +- [会中事件与会中互动](scenes/live-meeting-interact.md):在不触发新的入会/离会操作时,使用用户身份或已在会中的应用身份查询活跃会议、查看发言/聊天/共享内容,或发送文本和表情。 + +## 命令参考 + +| 命令 | 用途 | 参考方式 | +|---|---|---| +| `vc +search` | 搜索历史会议 | [lark-vc-search](references/lark-vc-search.md) | +| `vc +detail` | 查询会议信息及关联的 Note、Minutes 标识 | [lark-vc-detail](references/lark-vc-detail.md) | +| `vc meeting get` | 查询会议基础信息和参会人快照 | `lark-cli vc meeting get --help` | +| `vc +recording` | 从会议定位录制及妙记 | [lark-vc-recording](references/lark-vc-recording.md) | +| `vc +meeting-list-active` | 发现当前可见的进行中会议 | [lark-vc-meeting-list-active](references/lark-vc-meeting-list-active.md) | +| `vc +meeting-events` | 读取会中事件和共享内容 | [lark-vc-meeting-events](references/lark-vc-meeting-events.md) | +| `vc +meeting-message-send` | 发送会中文本消息或表情 | [lark-vc-meeting-message-send](references/lark-vc-meeting-message-send.md) | +| `vc +meeting-join` | 让应用机器人加入会议 | [lark-vc-agent-meeting-join](references/lark-vc-agent-meeting-join.md) | +| `vc +meeting-leave` | 让应用机器人离开会议 | [lark-vc-agent-meeting-leave](references/lark-vc-agent-meeting-leave.md) | +| `minutes +search` | 搜索妙记 | [lark-minutes-search](references/lark-minutes-search.md) | +| `minutes minutes get` | 查询妙记基础信息 | `lark-cli minutes minutes get --help` | +| `minutes +detail` | 读取妙记信息和指定产物 | [lark-minutes-detail](references/lark-minutes-detail.md) | +| `minutes +download` | 下载妙记原始音视频 | [lark-minutes-download](references/lark-minutes-download.md) | +| `minutes +upload` | 从云空间音视频生成妙记 | [lark-minutes-upload](references/lark-minutes-upload.md) | +| `minutes +update` | 修改妙记标题 | [lark-minutes-update](references/lark-minutes-update.md) | +| `minutes +speaker-replace` | 替换妙记逐字稿说话人 | [lark-minutes-speaker-replace](references/lark-minutes-speaker-replace.md) | +| `minutes +summary` | 替换妙记 AI 总结 | [lark-minutes-summary](references/lark-minutes-summary.md) | +| `minutes +todo` | 增删改妙记 AI 待办 | [lark-minutes-todo](references/lark-minutes-todo.md) | +| `minutes +apply-permission` | 申请妙记查看或编辑权限 | [lark-minutes-apply-permission](references/lark-minutes-apply-permission.md) | +| `drive +member-list` | 查看妙记协作者及其权限 | [lark-drive-member-list](../lark-drive/references/lark-drive-member-list.md) | +| `drive +member-add` | 给指定成员分配妙记查看或编辑权限 | [lark-drive-member-add](../lark-drive/references/lark-drive-member-add.md) | +| `minutes +word-replace` | 批量替换妙记逐字稿关键词 | `lark-cli minutes +word-replace --help` | +| `note +detail` | 查询智能纪要及关联文档标识 | [lark-note-detail](references/lark-note-detail.md) | +| `note +transcript` | 获取 unified 智能纪要逐字稿 | [lark-note-transcript](references/lark-note-transcript.md) | + +## 渐进加载规则 + +按“快速行动 → 场景手册 → 命令参考”渐进加载: + +1. 用户目标符合“快速行动”的进入条件时,直接执行对应 CLI;不要预读场景手册、命令参考、`--help` 或 schema。 +2. 不符合快速行动条件,或缺少关键标识、需要消歧、涉及写操作时,读取与目标匹配的一个主场景手册;主场景明确转交到下游场景时,只继续读取被引用的场景或章节,并按其中流程执行 CLI。 +3. 仅当缺少具体参数、返回字段、特殊约束或异常处理方式时:有参考手册的命令读取对应文件;没有参考手册的命令运行表中列出的精确 `lark-cli ... --help`。场景或 reference 已给出精确命令时,不再调用 `--help`;仅在参数缺失、命令不识别或文档与运行结果冲突时调用。 diff --git a/skills/lark-minutes/references/lark-minutes-apply-permission.md b/skills/lark-meeting/references/lark-minutes-apply-permission.md similarity index 95% rename from skills/lark-minutes/references/lark-minutes-apply-permission.md rename to skills/lark-meeting/references/lark-minutes-apply-permission.md index 6d17d72e..f95cc6ac 100644 --- a/skills/lark-minutes/references/lark-minutes-apply-permission.md +++ b/skills/lark-meeting/references/lark-minutes-apply-permission.md @@ -88,8 +88,5 @@ lark-cli minutes +apply-permission --minute-token obcnxxxxxxxxxxxxxxxxxxxx --per | `missing required scope(s)` | 当前身份缺少 `minutes:permission:apply` | 见上方「missing scope 与资源 ACL」 | | 申请后仍无权限 | 所有者尚未同意 | 这是异步申请,需等待所有者处理;不代表命令执行失败 | -## 参考 - -- [lark-minutes](../SKILL.md) — 妙记全部命令 -- [minutes +detail](lark-minutes-detail.md) — 妙记内容与产物查询 -- [lark-shared](../../lark-shared/SKILL.md) — 身份延续与权限管理 +## 相关场景 +- [生成和修改妙记](../scenes/create-and-edit-minutes.md) diff --git a/skills/lark-meeting/references/lark-minutes-detail.md b/skills/lark-meeting/references/lark-minutes-detail.md new file mode 100644 index 00000000..25582190 --- /dev/null +++ b/skills/lark-meeting/references/lark-minutes-detail.md @@ -0,0 +1,52 @@ + +# minutes +detail + +通过 `minute_token` 查询妙记详情,按需获取 AI 产物(总结/待办/章节/逐字稿/关键词)。只读,支持 `--as user` / `--as bot`。 + +`minute_token` 由某个身份取得时,本命令及后续 `note +detail`、`docs +fetch` 都必须显式沿用同一个 `--as`。 + +> `--summary` / `--todo` / `--chapter` / `--keyword` / `--transcript` 都是可选项;请求相应产物时必须显式传入,不传任何产物 flag 时只返回基础信息(如 `title`),AI 产物字段都不会出现。一次性获取所有产物:`--summary --todo --chapter --keyword --transcript`。 + +## 命令 + +```bash +# 仅基础信息 +lark-cli minutes +detail --as --minute-tokens obcxxxxxxxxxx + +# 批量(逗号分隔,最多 50 个) +lark-cli minutes +detail --as --minute-tokens obcxxx,obcyyy --summary --todo + +# 全产物 +lark-cli minutes +detail --as --minute-tokens obcxxx --summary --todo --chapter --keyword --transcript + +# 仅逐字稿,覆盖已有文件,指定输出目录 +lark-cli minutes +detail --as --minute-tokens obcxxx --transcript --overwrite --output-dir ./out +``` + +## 输出 + +`minutes` 数组每条含 `minute_token`、`title`、`note_id`、`artifacts`。`note_id` 仅在该妙记关联了会议纪要时返回,可直接传给 [`note +detail`](lark-note-detail.md) 拿纪要文档 token,无需再绕回 `vc +detail`。`artifacts` 中**只包含本次请求的产物**: + +| 字段 | 类型 | 说明 | +|------|------|------| +| `artifacts.summary` | string | AI 总结。 | +| `artifacts.todos` | array | 待办事项列表。 | +| `artifacts.chapters` | array | 章节列表。 | +| `artifacts.keywords` | array | 关键词列表。 | +| `artifacts.transcript_file` | string | 逐字稿本地文件路径。 | + +逐字稿默认落地 `./minutes/{minute_token}/transcript.txt`,与 `minutes +download` 同目录便于聚合。指定 `--output-dir ` 时改写到 `/artifact-{title}-{minute_token}/transcript.txt`。 + +## minute_token 来源 + +| 来源 | 取值字段 | +|------|---------| +| 妙记 URL `https://*.feishu.cn/minutes/obcxxx` | 截路径最后一段 `obcxxx` | +| `vc +detail --meeting-ids` | `minute_token` | +| `vc +recording --meeting-ids` | `minute_token` | +| `minutes +search` | `minute_token` | + +`minute_token` 不要直接传给 `note +detail`:需要关联 Note 时,先从本命令结果读取 `note_id`。跨产物流程由 [`query-minutes-and-artifacts`](../scenes/query-minutes-and-artifacts.md) 编排。 + +## 相关场景 +- [查询妙记及其产物](../scenes/query-minutes-and-artifacts.md) diff --git a/skills/lark-minutes/references/lark-minutes-download.md b/skills/lark-meeting/references/lark-minutes-download.md similarity index 96% rename from skills/lark-minutes/references/lark-minutes-download.md rename to skills/lark-meeting/references/lark-minutes-download.md index c4540b68..1ef367d4 100644 --- a/skills/lark-minutes/references/lark-minutes-download.md +++ b/skills/lark-meeting/references/lark-minutes-download.md @@ -126,12 +126,10 @@ API 限流 5 次/秒,批量下载时需注意控制频率。 ## 提示 - 音视频文件可能较大,下载无固定超时限制(由用户 Ctrl+C 控制取消)。 -- 默认落点 `./minutes/{minute_token}/` 与 `minutes +detail` 的逐字稿共享同一目录,方便 Agent 聚合同一会议的所有产物。 +- 默认落点 `./minutes/{minute_token}/` 与 `minutes +detail` 的逐字稿共享同一目录,方便 Agent 聚合同一妙记的原始音视频和逐字稿。 - 单 token 模式下 `--output` 若传入已存在目录(如 `--output ./existing-dir`),等价于 `--output-dir`,文件落入该目录(cp 语义)。 - 批量模式下 `--output` 不接受已存在的文件路径(会报错),应改用 `--output-dir`。 - 如需获取妙记的纪要内容(逐字稿、AI 总结等),请使用 [minutes +detail](lark-minutes-detail.md)。 -## 参考 - -- [lark-minutes](../SKILL.md) — 妙记全部命令 -- [lark-minutes-detail](lark-minutes-detail.md) — 妙记详情与 AI 产物查询 +## 相关场景 +- [查询妙记及其产物](../scenes/query-minutes-and-artifacts.md) diff --git a/skills/lark-minutes/references/lark-minutes-search.md b/skills/lark-meeting/references/lark-minutes-search.md similarity index 82% rename from skills/lark-minutes/references/lark-minutes-search.md rename to skills/lark-meeting/references/lark-minutes-search.md index be698869..eec4e627 100644 --- a/skills/lark-minutes/references/lark-minutes-search.md +++ b/skills/lark-meeting/references/lark-minutes-search.md @@ -117,19 +117,6 @@ CLI 会先按输入的本地日历日语义解析,再标准化为 RFC3339 时 如果用户说“昨天的妙记”“今天的妙记”“某一天内的妙记”,应把 `--start` 和 `--end` 都设置为同一天,而不是把 `--end` 设成下一天。 -### 7. 会议的妙记先定位会议 - -如果用户明确要找某场会议的妙记,或同时提到“会议 / 开会 / 会”和“妙记”,应优先使用 `vc +search` 先定位会议,再按需通过 `vc +recording` 获取 `minute_token`,不要直接按妙记时间范围或关键词搜索。 -只有在无法通过会议搜索定位目标会议,或用户明确要求按妙记维度检索时,才回退到 `minutes +search`。 - -如果用户要的是"某场会议的妙记信息""某个日程对应的妙记详情""minute\_token""妙记链接""标题""时长""owner",正确链路是: - -1. `vc +search` 或 `calendar +agenda` 先定位会议 / 日程 -2. `vc +recording` 获取 `minute_token` -3. `minutes minutes get` 查询妙记基础信息 - -
- ## 时间格式 `--start` 和 `--end` 支持以下时间格式: @@ -149,7 +136,8 @@ CLI 会先按输入的本地日历日语义解析,再标准化为 RFC3339 时 - 当结果中返回 `has_more=true` 时,说明还有更多页可继续获取。 - 继续翻页时,使用响应中的 `page_token` 搭配 `--page-token` 发起下一次查询。 - 不要假设调大 `--page-size` 就能拿全结果;分页遍历时应以 `has_more` 和 `page_token` 为准。 -- 当 `has_more=true` 时,逐页累计已读取的 `items` 数:累计不到 50 条之前可自动继续翻页;超过 50 条后应停下来向用户确认是否获取全部结果。 +- 用户未明确要求全量时,逐页累计已读取的 `items` 数:累计不到 50 条之前可自动继续翻页;超过 50 条且仍有更多结果时,先向用户确认是否继续获取全部结果。 +- 用户明确说“全部 / 所有 / 统计 / 排序”时,该全量意图优先于 50 条确认门槛;直接按 `has_more` 翻完所有分页,按结果中的 `token` 去重后再返回、排序或统计。 ```bash # First page @@ -159,21 +147,6 @@ lark-cli minutes +search --query "预算复盘" --page-size 20 lark-cli minutes +search --query "预算复盘" --page-size 20 --page-token '' ``` -## 搜索结果中的下一步 - -搜索结果中的 `token` 可直接作为 `minute_token` 用于继续查询妙记产物: -通常先用搜索结果中的 `token` 获取妙记基础信息,确认描述、链接等元数据是否命中目标;只有需要进一步查看逐字稿、总结、待办、章节时,再继续查询关联的纪要产物。 - -如果你已经确定目标妙记,优先直接复用搜索结果中的 `token`,避免重复搜索。 - -```bash -# 首先查询妙记元信息(标题、时长、封面) → 用本 skill -lark-cli minutes minutes get --params '{"minute_token": "obcn***************"}' - -# 查妙记关联的产物(--summary --todo --chapter --keyword --transcript 按需返回) -lark-cli minutes +detail --minute-tokens --summary -``` - ## 常见错误与排查 | 错误现象 | 根本原因 | 解决方案 | @@ -194,8 +167,5 @@ lark-cli minutes +detail --minute-tokens --summary - 排查参数与请求结构时优先使用 `--dry-run`。 - 搜索的时间范围最大为 1 个月,如果需要搜索更长时间范围的妙记,需要拆分为多次时间范围为一个月查询。 -## 参考 - -- [lark-minutes](../SKILL.md) -- 妙记相关命令 -- [lark-minutes-detail](lark-minutes-detail.md) -- 基于 `minute_token` 获取逐字稿、总结、待办、章节等产物 -- [lark-vc](../../lark-vc/SKILL.md) -- 视频会议全部命令 +## 相关场景 +- [查询妙记及其产物](../scenes/query-minutes-and-artifacts.md) diff --git a/skills/lark-minutes/references/lark-minutes-speaker-replace.md b/skills/lark-meeting/references/lark-minutes-speaker-replace.md similarity index 94% rename from skills/lark-minutes/references/lark-minutes-speaker-replace.md rename to skills/lark-meeting/references/lark-minutes-speaker-replace.md index 82492ac1..8faadf06 100644 --- a/skills/lark-minutes/references/lark-minutes-speaker-replace.md +++ b/skills/lark-meeting/references/lark-minutes-speaker-replace.md @@ -39,7 +39,7 @@ 3. **解析 `--from-speaker-id`** - 根据用户描述的原说话人(展示名,如「说话人1」「张三」),在 `speakers[]` 里按 `name` **精确匹配**,取对应的 **`speaker_id`** 作为 `--from-speaker-id` 的值。 - **`--from-speaker-id` 只传 `speaker_id`,不传展示名。** - - 若同名有多条(`name` 相同、`speaker_id` 不同):**不要擅自挑选**。可结合 [`vc +notes --minute-tokens`](../../lark-vc/references/lark-vc-notes.md) 对照各人发言内容,请用户确认后再用精确的 `speaker_id`。 + - 若同名有多条(`name` 相同、`speaker_id` 不同):**不要擅自挑选**。可用 [`minutes +detail --transcript`](lark-minutes-detail.md) 对照各人发言内容,请用户确认后再用精确的 `speaker_id`。 - 若列表中无匹配展示名:告知用户并核对拼写,或请用户在妙记页面确认标签。 4. **解析 `--to-user-id`** @@ -102,6 +102,5 @@ Agent 必须先 `lark-cli api GET .../speakerlist`,再 `+speaker-replace`;`- | `from_speaker_id` | 实际用于替换的不透明说话人标识 | | `to_user_id` | 替换后的新说话人 open_id,与输入的 `--to-user-id` 一致 | -## 参考 - -- [lark-minutes](../SKILL.md) -- 妙记相关功能说明 +## 相关场景 +- [生成和修改妙记](../scenes/create-and-edit-minutes.md) diff --git a/skills/lark-minutes/references/lark-minutes-summary.md b/skills/lark-meeting/references/lark-minutes-summary.md similarity index 95% rename from skills/lark-minutes/references/lark-minutes-summary.md rename to skills/lark-meeting/references/lark-minutes-summary.md index 29b03d39..1d618fd8 100644 --- a/skills/lark-minutes/references/lark-minutes-summary.md +++ b/skills/lark-meeting/references/lark-minutes-summary.md @@ -113,8 +113,5 @@ lark-cli minutes +summary --minute-token obcnxxxxxxxxxxxxxxxxxxxx --summary @sum | 参数无效 | — | `minute_token` 缺失或格式错误 | 检查 token 是否完整 | | 权限不足 | — | 缺少 `minutes:minutes:update` | 运行 `auth login --scope "minutes:minutes:update"` | -## 参考 - -- [lark-minutes](../SKILL.md) — 妙记全部命令 -- [minutes +todo](lark-minutes-todo.md) — 替换待办项 -- [minutes +detail](lark-minutes-detail.md) — 读取总结、待办等 AI 产物 +## 相关场景 +- [生成和修改妙记](../scenes/create-and-edit-minutes.md) diff --git a/skills/lark-minutes/references/lark-minutes-todo.md b/skills/lark-meeting/references/lark-minutes-todo.md similarity index 88% rename from skills/lark-minutes/references/lark-minutes-todo.md rename to skills/lark-meeting/references/lark-minutes-todo.md index ad4c0232..81eea268 100644 --- a/skills/lark-minutes/references/lark-minutes-todo.md +++ b/skills/lark-meeting/references/lark-minutes-todo.md @@ -1,6 +1,6 @@ # minutes +todo -> **路由**:本命令操作**妙记内的 AI 待办**,不是飞书任务(Task)。用户说「在妙记里新建待办」时**必须**用本命令,**禁止**走 `lark-cli task` / `tasklists list` / `task +create`。详见 [lark-minutes/SKILL.md](../SKILL.md) 第 6 节。 +> **路由**:本命令操作**妙记内的 AI 待办**,不是飞书任务(Task)。用户说「在妙记里新建待办」时**必须**用本命令,**禁止**走 `lark-cli task` / `tasklists list` / `task +create`。详见 [生成和修改妙记](../scenes/create-and-edit-minutes.md)。 对妙记中的待办做新增 / 更新 / 删除(单条或批量)。写操作。 @@ -24,17 +24,10 @@ lark-cli minutes +todo --minute-token obcnxxxxxxxxxxxxxxxxxxxx --operation add --todo "跟进预算审批" --is-done=false --as user # 批量:一次新增两条 -lark-cli minutes +todo --minute-token obcnxxxxxxxxxxxxxxxxxxxx --as user --todos '[ - {"operation":"add","content":"晚上好1","is_done":true}, - {"operation":"add","content":"晚上好2","is_done":false} -]' +lark-cli minutes +todo --minute-token obcnxxxxxxxxxxxxxxxxxxxx --as user --todos '[{"operation":"add","content":"晚上好1","is_done":true},{"operation":"add","content":"晚上好2","is_done":false}]' # 批量:混合增删改 -lark-cli minutes +todo --minute-token obcnxxxxxxxxxxxxxxxxxxxx --as user --todos '[ - {"operation":"add","content":"新待办","is_done":false}, - {"operation":"update","todo_id":"1234567890","content":"已更新","is_done":true}, - {"operation":"delete","todo_id":"9876543210"} -]' +lark-cli minutes +todo --minute-token obcnxxxxxxxxxxxxxxxxxxxx --as user --todos '[{"operation":"add","content":"新待办","is_done":false},{"operation":"update","todo_id":"1234567890","content":"已更新","is_done":true},{"operation":"delete","todo_id":"9876543210"}]' # 从文件读取 lark-cli minutes +todo --minute-token obcnxxxxxxxxxxxxxxxxxxxx --as user --todos @todos.json @@ -129,8 +122,5 @@ lark-cli minutes +todo --minute-token obcnxxxxxxxxxxxxxxxxxxxx --operation add - | `error.subtype` = `permission_denied` | **妙记资源无编辑权**:向妙记所有者申请该妙记的编辑/协作权限;**不要**走 `auth login --scope` | | 缺少 OAuth scope(`error.missing_scopes` 含 `minutes:minutes:update`) | `lark-cli auth login --scope "minutes:minutes:update"` | -## 参考 - -- [lark-minutes](../SKILL.md) -- [minutes +summary](lark-minutes-summary.md) -- [minutes +detail](lark-minutes-detail.md) +## 相关场景 +- [生成和修改妙记](../scenes/create-and-edit-minutes.md) diff --git a/skills/lark-minutes/references/lark-minutes-update.md b/skills/lark-meeting/references/lark-minutes-update.md similarity index 91% rename from skills/lark-minutes/references/lark-minutes-update.md rename to skills/lark-meeting/references/lark-minutes-update.md index 7baa2948..b1be3692 100644 --- a/skills/lark-minutes/references/lark-minutes-update.md +++ b/skills/lark-meeting/references/lark-minutes-update.md @@ -34,6 +34,5 @@ lark-cli minutes +update --minute-token xxx --topic "周会纪要 2026-05-18" | `minute_token` | 被修改的妙记 Token,与输入的 `--minute-token` 一致,可继续用于查询妙记信息、下载媒体或获取纪要产物 | | `topic` | 修改后的妙记标题,与输入的 `--topic` 一致 | -## 参考 - -- [lark-minutes](../SKILL.md) -- 妙记相关功能说明 +## 相关场景 +- [生成和修改妙记](../scenes/create-and-edit-minutes.md) diff --git a/skills/lark-meeting/references/lark-minutes-upload.md b/skills/lark-meeting/references/lark-minutes-upload.md new file mode 100644 index 00000000..d8bf9026 --- /dev/null +++ b/skills/lark-meeting/references/lark-minutes-upload.md @@ -0,0 +1,65 @@ +# minutes +upload + + +上传音视频文件到飞书妙记并生成妙记(Minute)。 + +本 skill 对应 shortcut:`lark-cli minutes +upload`。 + +## 典型触发表达 + +- "把这个音视频文件转成妙记" +- "把这个音视频文件转成纪要" +- "把这个音视频文件转成逐字稿、文字稿或撰写文字" +- "把这个音视频文件转成总结、待办或章节" + +## 命令示例 + +```bash +# 通过已上传到云空间(云盘/云存储)的 file_token 生成妙记 +lark-cli minutes +upload --file-token boxcnxxxxxxxxxxxxxxxx + +``` + +## 参数 + +| 参数 | 必填 | 说明 | +|------|------|------| +| `--file-token ` | 是 | 已经上传到飞书云空间(云盘/云存储)的音视频文件的 file_token | + +## 支持的格式与限制 + +待上传到妙记的原始音视频文件必须满足以下要求: + +- 支持音频格式:`wav`、`mp3`、`m4a`、`aac`、`ogg`、`wma`、`amr` +- 支持视频格式:`avi`、`wmv`、`mov`、`mp4`、`m4v`、`mpeg`、`ogg`、`flv` +- 音视频时长不能超过 `6` 小时 +- 文件大小不能超过 `6 GB` + +> 说明:本 shortcut 只接收 `file_token`,不会直接读取本地文件内容,因此这些格式、时长和大小限制对应的是**原始上传文件**本身。若妙记生成失败,请先回查源文件是否满足上述要求。 + +## 核心约束 + +### 1. 必须提供 file_token + +本接口不直接处理本地文件的上传,必须先使用 `drive +upload` 将文件上传到云空间(云盘/云存储)获取 `file_token`,然后再调用本接口。 + +### 2. 异步生成 + +API 会立即返回 `minute_url`,但妙记可能仍在异步生成中。`minutes +upload` 不返回处理状态,命令成功只表示异步创建请求已提交;只有后续执行 `minutes +detail` 并确认就绪,才能声称妙记产物已生成或可用。上传与后续产物获取由 [`create-and-edit-minutes`](../scenes/create-and-edit-minutes.md) 编排;上传后立即查询产物时,`minutes +detail` 必须使用 `--wait-ready`。 + +## 输出结果示例 + +```json +{ + "minute_url": "http(s):///minutes/", + "minute_token": "" +} +``` + +| 字段 | 说明 | +|------|------| +| `minute_url` | 生成的妙记访问链接 | +| `minute_token` | 从 `minute_url` 提取出的妙记 Token,可直接传给 `minutes +detail --minute-tokens` | + +## 相关场景 +- [生成和修改妙记](../scenes/create-and-edit-minutes.md) diff --git a/skills/lark-meeting/references/lark-note-detail.md b/skills/lark-meeting/references/lark-note-detail.md new file mode 100644 index 00000000..ed11768e --- /dev/null +++ b/skills/lark-meeting/references/lark-note-detail.md @@ -0,0 +1,15 @@ +# note +detail + +通过 `note_id` 查询会议纪要详情,获取下挂文档 Token(AI 智能纪要、逐字稿、会中共享文档)。只读,支持 `--as user` 或 `--as bot`。 + +## 命令 + +```bash +lark-cli note +detail --note-id +lark-cli note +detail --note-id --as bot +``` + +`note_id` 由其他命令取得时,必须显式沿用来源身份。应用身份能否读到数据取决于应用对纪要主文档的查看权限。若 `--as bot` 返回 `note_display_type=unified`,不要静默切换到用户身份执行 `note +transcript`;先向用户说明该命令仅支持用户身份。 + +## 相关场景 +- [基于 note_id 查询纪要、逐字稿、共享文档等](../scenes/query-note-and-artifacts.md) diff --git a/skills/lark-meeting/references/lark-note-transcript.md b/skills/lark-meeting/references/lark-note-transcript.md new file mode 100644 index 00000000..e0707182 --- /dev/null +++ b/skills/lark-meeting/references/lark-note-transcript.md @@ -0,0 +1,19 @@ +# note +transcript + +只在 `note +detail` 已确认 `note_display_type=unified` 时使用。普通纪要逐字稿是独立 Docx 文档,应回到 [lark-doc](../../lark-doc/SKILL.md) 读取 `verbatim_doc_token`。 + +`note +transcript` 仅支持 `--as user`,不支持 `--as bot`。如果 `note +detail --as bot` 返回 `unified`,不要静默省略 `--as` 或改用用户身份继续;先说明该限制,只有用户明确同意后才切换身份重试。 + +```bash +lark-cli note +transcript --note-id +``` + +## 行为契约 + +- CLI 会先校验该 Note 是否为 `unified`;不是 unified 时不拉取 transcript。 +- CLI 内部自动翻页并拼接完整内容;任一页失败时整体报错,不保存半截 transcript。 +- 默认保存到 `./notes/{note_id}/unified_transcript.md`;`--transcript-format plain_text` 时保存为 `.txt`。 +- 目标文件已存在时会失败;用户明确要覆盖时才加 `--overwrite`。 + +## 相关场景 +- [基于 note_id 查询纪要、逐字稿、共享文档等](../scenes/query-note-and-artifacts.md) diff --git a/skills/lark-vc-agent/references/lark-vc-agent-meeting-join.md b/skills/lark-meeting/references/lark-vc-agent-meeting-join.md similarity index 62% rename from skills/lark-vc-agent/references/lark-vc-agent-meeting-join.md rename to skills/lark-meeting/references/lark-vc-agent-meeting-join.md index 3248c87b..bf9e15a8 100644 --- a/skills/lark-vc-agent/references/lark-vc-agent-meeting-join.md +++ b/skills/lark-meeting/references/lark-vc-agent-meeting-join.md @@ -5,25 +5,13 @@ 本 skill 对应 shortcut:`lark-cli vc +meeting-join`(调用 `POST /open-apis/vc/v1/bots/join`)。 -> **不要把 9 位会议号等同于入会意图。** 用户给出 9 位会议号并询问“会议讲了什么 / 查会中事件”时,先用 `+meeting-list-active` 查当前 active meetings 并按 `meeting_no` 匹配;只有用户明确要求“入会 / 让应用机器人旁听 / 代我参会”时才调用本命令。 +> **不要把 9 位会议号等同于入会意图。** 用户给出 9 位会议号并询问“会议讲了什么 / 查会中事件”时,先用 `vc +meeting-list-active` 查当前 active meetings 并按 `meeting_no` 匹配;只有用户明确要求“入会 / 让应用机器人旁听 / 代我参会”时才调用本命令。 ## 命令 ```bash # 仅指定会议号(无密码) lark-cli vc +meeting-join --as bot --meeting-number 123456789 - -# 指定会议号 + 密码 -lark-cli vc +meeting-join --as bot --meeting-number 123456789 --password 8888 - -# 从邀请事件透传 call_id(参见「如何获取输入参数」) -lark-cli vc +meeting-join --as bot --meeting-number 123456789 --call-id a08e06bf-9a41-44e4-a89c-a7871899e783 - -# 输出格式 -lark-cli vc +meeting-join --as bot --meeting-number 123456789 --format json - -# 预览 API 调用(不实际加入会议) -lark-cli vc +meeting-join --as bot --meeting-number 123456789 --dry-run ``` ## 参数 @@ -81,36 +69,6 @@ lark-cli vc +meeting-join --as bot --meeting-number 123456789 --dry-run | `password` | 若会议设置了入会密码,由主持人提供 | | `call-id` | 由 `vc.bot.meeting_invited_v1` 邀请事件的 `call_id` 字段携带,Agent 收到事件时透传过来;无邀请事件场景(如 Agent 主动入会)不传 | -## Agent 组合场景 - -### 场景 1:加入会议 → 监听会中事件 - -```bash -# 第 1 步:加入会议,记录返回的 meeting.id -lark-cli vc +meeting-join --as bot --meeting-number 123456789 - -# 第 2 步:使用返回的 meeting.id 查询会中事件 -lark-cli vc +meeting-events --as bot --meeting-id --page-all --format pretty -``` - -如果 bot 已经在会中,也可以通过 active meeting 找回 `meeting_id`: - -```bash -lark-cli vc +meeting-list-active --as bot --user-id --format json -``` - -### 场景 2:加入会议 → 会后进入 lark-vc 获取会议产物信息 - -```bash -# 第 1 步:加入并参会 -lark-cli vc +meeting-join --as bot --meeting-number 123456789 - -# 第 2 步:会议结束后,先查询会议产物 -lark-cli vc +detail --meeting-ids -``` - -后续按 `lark-vc` 的产物决策处理:根据 `note_display_type`、`note_id`、`minute_token` 和用户意图选择纪要正文、逐字稿或妙记。 - ## 常见错误与排查 | 错误现象 | 根本原因 | 解决方案 | @@ -119,7 +77,7 @@ lark-cli vc +detail --meeting-ids | 会议密码错误 | `--password` 错误或未提供 | 向主持人确认会议密码 | | 会议不存在 / 已结束 | 会议号错误或会议未进行中 | 确认会议正在进行中 | | `HTTP 403: no permission` / `121003` | 入会前置条件不满足,通常不是单纯 scope 问题 | 依次确认:1)会议允许智能体加入;2)会议号正确;3)如有密码,已正确传入 `--password`;4)会议已开始;5)等候室 / 入会审批已放行;6)会议未禁止当前身份加入(如限制外部、限制应用机器人、仅特定成员可入会);确认后重试 | -| 应用身份权限不足 | 应用权限、租户安装、权限可访问的数据范围或 VC Agent privilege 未配置完整 | 不要执行 `auth login`。以 CLI 返回的 metadata / error envelope 为准确认缺失权限;检查应用发布/安装,以及开放平台“权限可访问的数据范围”:选择“按条件筛选”,条件为“会议的归属者 包含 与应用的可用范围一致”;仍失败再排查内测 privilege / 灰度 | +| 应用身份权限不足 | 应用权限、租户安装或权限可访问的数据范围未配置完整 | 不要执行 `auth login`。以 CLI 返回的 metadata / error envelope 为准确认缺失权限;检查应用发布/安装,以及开放平台“权限可访问的数据范围”:选择“按条件筛选”,条件为“会议的归属者 包含 与应用的可用范围一致”;配置正确仍失败时,保留错误码和 `log_id`,按服务端权限异常排查 | | 入会被拒绝 | 等候室 / 入会审批 / 限制外部入会 | 联系主持人放行或调整会议设置 | ## 提示 @@ -128,14 +86,5 @@ lark-cli vc +detail --meeting-ids - 入会会让机器人立即出现在参会列表;若用户要求退出 / 离开 / 结束参会,直接使用 `+meeting-leave --as bot --meeting-id `。参数格式不确定时可选 `--dry-run` 预览,但不是必经步骤。 - 执行成功后,立即记录返回的 `meeting.id`,用于后续 `+meeting-leave` / `+meeting-events`。 -## 参考 - -- [lark-vc-agent-meeting-leave](lark-vc-agent-meeting-leave.md) — 对应的离会命令 -- [lark-vc-meeting-list-active](../../lark-vc/references/lark-vc-meeting-list-active.md) — 发现当前可读事件的进行中会议 ID -- [lark-vc-meeting-events](../../lark-vc/references/lark-vc-meeting-events.md) — 会中事件流 -- [lark-vc-search](../../lark-vc/references/lark-vc-search.md) — 搜索历史会议记录 -- [lark-vc-recording](../../lark-vc/references/lark-vc-recording.md) — 查询 minute_token -- [lark-vc-detail](../../lark-vc/references/lark-vc-detail.md) — 获取会议详情 -- [lark-vc-agent](../SKILL.md) — Agent 参会能力(本 skill) -- [lark-vc](../../lark-vc/SKILL.md) — 视频会议原子域(Meeting / Note 等核心概念) -- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数 +## 相关场景 +- [应用机器人参会与会中互动](../scenes/live-meeting-attend.md) diff --git a/skills/lark-vc-agent/references/lark-vc-agent-meeting-leave.md b/skills/lark-meeting/references/lark-vc-agent-meeting-leave.md similarity index 63% rename from skills/lark-vc-agent/references/lark-vc-agent-meeting-leave.md rename to skills/lark-meeting/references/lark-vc-agent-meeting-leave.md index cb8bf75d..d0e5f889 100644 --- a/skills/lark-vc-agent/references/lark-vc-agent-meeting-leave.md +++ b/skills/lark-meeting/references/lark-vc-agent-meeting-leave.md @@ -10,12 +10,6 @@ ```bash # 通过 meeting_id 离会 lark-cli vc +meeting-leave --as bot --meeting-id 69xxxxxxxxxxxxx28 - -# 输出格式 -lark-cli vc +meeting-leave --as bot --meeting-id 69xxxxxxxxxxxxx28 --format json - -# 预览 API 调用(不实际离会) -lark-cli vc +meeting-leave --as bot --meeting-id 69xxxxxxxxxxxxx28 --dry-run ``` ## 参数 @@ -54,30 +48,6 @@ lark-cli vc +meeting-leave --as bot --meeting-id 69xxxxxxxxxxxxx28 --dry-run |---------|---------| | `meeting-id` | `+meeting-join --as bot` 返回的 `meeting.id`;或应用身份 `+meeting-list-active --as bot --user-id ` 返回的 `meeting_id` | -## Agent 组合场景 - -### 场景 1:加入 → 用户明确要求时离开 - -```bash -# 第 1 步:加入会议,记录 meeting.id -lark-cli vc +meeting-join --as bot --meeting-number 123456789 - -# 第 2 步:在会中处理用户请求(如监听发言、记录信息等) -# ... - -# 第 3 步:仅在用户明确要求退出 / 离开 / 结束参会时,使用上一步记录的 meeting.id 离会 -lark-cli vc +meeting-leave --as bot --meeting-id -``` - -### 场景 2:会后补拉产物(不需要离会) - -如果用户只是要求会议结束后拉录制、纪要或逐字稿,不要先调用 `+meeting-leave`;直接跨到 `lark-vc` 查询会后产物。 - -```bash -# 第 1 步:会议结束后进入 lark-vc 获取会议产物信息 -lark-cli vc +detail --meeting-ids -``` - ## 常见错误与排查 | 错误现象 | 根本原因 | 解决方案 | @@ -92,14 +62,5 @@ lark-cli vc +detail --meeting-ids - `+meeting-leave` 优先使用 `+meeting-join --as bot` 返回的 `meeting.id`,但不是每次 join 后都必须调用 leave。 - `meeting_id` 如果来自 `+meeting-list-active`,必须来自应用身份,并确认应用机器人就在该会议中。不要用 9 位会议号。 -## 参考 - -- [lark-vc-agent-meeting-join](lark-vc-agent-meeting-join.md) — 对应的入会命令 -- [lark-vc-meeting-list-active](../../lark-vc/references/lark-vc-meeting-list-active.md) — 发现当前可读事件的进行中会议 ID -- [lark-vc-meeting-events](../../lark-vc/references/lark-vc-meeting-events.md) — 会中事件流 -- [lark-vc-search](../../lark-vc/references/lark-vc-search.md) — 搜索历史会议(获取 meeting_id) -- [lark-vc-recording](../../lark-vc/references/lark-vc-recording.md) — 查询 minute_token -- [lark-vc-detail](../../lark-vc/references/lark-vc-detail.md) — 获取会议详情 -- [lark-vc-agent](../SKILL.md) — Agent 参会能力(本 skill) -- [lark-vc](../../lark-vc/SKILL.md) — 视频会议原子域(Meeting / Note 等核心概念) -- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数 +## 相关场景 +- [应用机器人参会与会中互动](../scenes/live-meeting-attend.md) diff --git a/skills/lark-meeting/references/lark-vc-detail.md b/skills/lark-meeting/references/lark-vc-detail.md new file mode 100644 index 00000000..a946321b --- /dev/null +++ b/skills/lark-meeting/references/lark-vc-detail.md @@ -0,0 +1,31 @@ + +# vc +detail + +通过会议 ID 获取会议详情,包括基本信息、关联的纪要 ID(`note_id`)和妙记 Token(`minute_token`)。只读,支持 `--as user` / `--as bot`。 + +## 命令 + +```bash +# 单个 / 批量(逗号分隔,最多 50 个) +lark-cli vc +detail --meeting-ids , + +# 应用身份(只能查应用有权限的会议) +lark-cli vc +detail --meeting-ids , --as bot +``` + +## 输出字段 + +| 字段 | 说明 | +|------|------| +| `meeting_id` | 会议 ID | +| `meeting_no` | 会议 9 位号码 | +| `topic` | 会议主题 | +| `start_time` | 开始时间 | +| `end_time` | 结束时间 | +| `note_id` | 关联的纪要 ID。 | +| `minute_token` | 关联的妙记 Token。 | + +跨产物选择和后续命令链由 [`query-meeting-and-artifacts`](../scenes/query-meeting-and-artifacts.md) 统一编排。`note_id` / `minute_token` 由本命令取得后,后续 `note +detail`、`minutes +detail` 和 Doc 读取命令必须显式沿用同一个 `--as`。 + +## 相关场景 +- [查询会议及其产物](../scenes/query-meeting-and-artifacts.md) diff --git a/skills/lark-vc/references/lark-vc-meeting-events.md b/skills/lark-meeting/references/lark-vc-meeting-events.md similarity index 86% rename from skills/lark-vc/references/lark-vc-meeting-events.md rename to skills/lark-meeting/references/lark-vc-meeting-events.md index 13212e2c..6b74e40c 100644 --- a/skills/lark-vc/references/lark-vc-meeting-events.md +++ b/skills/lark-meeting/references/lark-vc-meeting-events.md @@ -56,31 +56,7 @@ lark-cli vc +meeting-events --as --meeting-id --page-token - 应用身份路径:应用机器人必须在会中或参会过;不要拿任意 `meeting_id` 直接查。 - 不要在拿到 `meeting_id` 后随意切换身份。身份不一致时,常见结果是空列表、`no permission` 或 `bot is not in meeting`。 -### 3. 读取事件前必须先拿到可见的 meeting_id - -最稳妥的调用顺序通常是: - -```bash -# 方式 1:先入会,直接记录返回的 meeting.id -lark-cli vc +meeting-join --as bot --meeting-number 123456789 - -# 再查询事件 -lark-cli vc +meeting-events --as bot --meeting-id --page-all --format pretty -``` - -如果应用机器人已经在会中,也可以先通过 active meeting 找会: - -```bash -lark-cli vc +meeting-list-active --as bot --user-id --format json -lark-cli vc +meeting-events --as bot --meeting-id --page-all --format pretty -``` - -如果要查询当前登录用户所在会议: - -```bash -lark-cli vc +meeting-list-active --as user --format json -lark-cli vc +meeting-events --as user --meeting-id --page-all --format pretty -``` +### 3. 应用身份的可见性窗口 若应用机器人已离会、未入会、或会议已经无法再判断身份,后端通常会报: - `bot is not in meeting, no permission` @@ -110,8 +86,8 @@ lark-cli vc +meeting-events --as user --meeting-id --page-all --format pret ### 5. 输出格式差异 -- `--format json`:结构化契约,顶层包含 `meeting`、`identity`、`events`、`has_more`、`page_token`。`identity` 表示当前读取身份;事件 actor 统一含 `participant_type`、`role`、`label`;每条事件保留 `payload` 便于追溯细节。 - `--format pretty`:默认推荐格式,输出当前身份和逐条时间线,适合快速理解“发生了什么”。 +- `--format json`:结构化契约,顶层包含 `meeting`、`identity`、`events`、`has_more`、`page_token`。`identity` 表示当前读取身份;事件 actor 统一含 `participant_type`、`role`、`label`;每条事件保留 `payload` 便于追溯细节。 - `--format ndjson`:输出事件行,并带 metadata 行,适合流式消费。 **选型原则**:默认先用 `--format pretty`;仅当 `pretty` 缺少完成任务所必需的结构化字段时,才改用 `--format json`。用户明确要求 JSON 或规则明确要求结构化字段时可直接用 `--format json`;需要流式消费时用 `--format ndjson`。 @@ -324,74 +300,16 @@ lark-cli vc +meeting-events \ | `start` / `end` | 用户给出的时间范围;如未给出则默认取全量可见事件 | | `page-token` | 上一页或上一次查询结果中保存的 `page_token`;建议持久化保存,便于下次继续拉取新增事件 | -## Agent 组合场景 - -### 场景 1:入会后读取会中发生了什么 - -```bash -# 第 1 步:加入会议,记录返回的 meeting.id -JOIN=$(lark-cli vc +meeting-join --as bot --meeting-number 123456789 --format json) -MID=$(echo "$JOIN" | jq -r '.data.meeting.id') - -# 第 2 步:用 meeting.id 读取当前可见事件 -lark-cli vc +meeting-events --as bot --meeting-id "$MID" --page-all --format pretty -``` - -### 场景 1b:应用机器人已在会中,先发现 meeting_id 再读事件 - -```bash -lark-cli vc +meeting-list-active --as bot --user-id --format json -lark-cli vc +meeting-events --as bot --meeting-id --page-all --format pretty -``` - -### 场景 1c:当前登录用户正在会中,先发现 meeting_id 再读事件 - -```bash -lark-cli vc +meeting-list-active --as user --format json -lark-cli vc +meeting-events --as user --meeting-id --page-all --format pretty -``` - -### 场景 2:过滤某段时间内的事件 - -```bash -lark-cli vc +meeting-events \ - --as \ - --meeting-id \ - --start 2026-04-17T15:00:00+08:00 \ - --end 2026-04-17T16:00:00+08:00 \ - --page-all \ - --format pretty -``` - -### 场景 3:基于上一次的 `page_token` 继续查新增事件 - -```bash -# 上一次查询结束后,保留最后返回的 page_token -# 这次直接从该游标继续拉新增事件 -lark-cli vc +meeting-events \ - --as \ - --meeting-id \ - --page-token \ - --page-all \ - --format pretty -``` - -适用规则: - -- 当用户说“继续看新事件”“看上次之后新增了什么”时,优先使用上一次保存的 `page_token`。 -- 如果这次返回里仍有 `has_more=true`、pretty 里出现 `more available`,或又返回了新的 `page_token`,说明新增事件还没拉完,应继续分页,而不是把当前页误当成完整增量结果。 -- 只有在用户明确要求“从头回放全部事件”时,才忽略已有 `page_token`,重新从第一页开始。 - ## 常见错误与排查 | 错误现象 | 根本原因 | 解决方案 | |---------|---------|---------| | `--meeting-id is required` | 未传入 `--meeting-id` | 传入长数字 `meeting.id` | -| `10005 bot is not in meeting` | 使用应用身份读取,但应用机器人从未真实入会该会议;或会议已结束但应用机器人从未在会中出现过 | 如果 `meeting_id` 来自用户身份发现,改回 `--as user`;如果确实要应用身份读取,先让应用机器人入会或确认它曾参会后再用 `--as bot`。**如果只是想看参会人快照,改用 `lark-cli vc meeting get --params '{"meeting_id":""}' --with-participants`** | +| `10005 bot is not in meeting` | 使用应用身份读取,但应用机器人从未真实入会该会议;或会议已结束但应用机器人从未在会中出现过 | 如果 `meeting_id` 来自用户身份发现,改回 `--as user`;如果确实要应用身份读取,先让应用机器人入会或确认它曾参会后再用 `--as bot`。**如果只是想看参会人快照,改用 `lark-cli vc meeting get --params '{"meeting_id":"","with_participants":true}'`** | | 用户身份无权限 / 不可见 | 当前用户不是该会议的可见参与者,或 `meeting_id` 不是从用户身份路径获得 | 不要反复执行 `auth login`。先确认 `meeting_id` 是否来自 `+meeting-list-active --as user`;如果用户明确要切到应用身份,再通过 `+meeting-list-active --as bot --user-id ` 获取应用身份可读的 `meeting_id`,或在用户明确同意后让应用机器人入会,再用 `+meeting-events --as bot` 读取 | | `20001 meeting_status_MEETING_END` | 会议已结束且已超出后端允许的 5 分钟宽限窗口 | 本接口不再适合继续拉取事件。先用 `lark-cli vc +detail --meeting-ids ` 获取会议产物信息,再根据 `note_display_type` / `note_id` / `minute_token` 和用户意图选择纪要正文、逐字稿或妙记;参会人请用 `lark-cli vc meeting get --params '{"meeting_id":""}' --with-participants` | | `20002 meeting not exist` | `meeting_id` 错误,或会议实例当前已不可获取(常见于把 9 位会议号当 meeting_id 传) | 确认传入的是长数字 `meeting_id`,不是 9 位会议号 | -| 应用身份权限不足 | 应用权限、租户安装、权限可访问的数据范围或 VC Agent privilege 未配置完整 | 不要执行 `auth login`。请应用开发者开通 `vc:meeting.bot.join:write`;再检查应用发布/安装和权限可访问的数据范围,均正确仍失败时再排查内测灰度权限 | +| 应用身份权限不足 | 应用权限、租户安装或权限可访问的数据范围未配置完整 | 不要执行 `auth login`。请应用开发者开通 `vc:meeting.bot.join:write`;再检查应用发布/安装和权限可访问的数据范围;配置正确仍失败时,保留错误码和 `log_id`,按服务端权限异常排查 | | `HTTP 404` / `HTTP 500` | 服务端当前无法找到或处理该会议实例 | 换一个正在进行且 bot 可见的 meeting_id,或排查后端问题 | ## 提示 @@ -399,18 +317,10 @@ lark-cli vc +meeting-events \ - 这是**会中事件流**查询,不适合拿来搜历史会议记录;搜历史会议请用 `+search`。 - 如果会议已经结束,不要卡在 `+meeting-events`: - 先用 `lark-cli vc +detail --meeting-ids ` 获取会议产物信息。 - - 再根据 `note_display_type`、`note_id`、`minute_token` 和用户意图,按 `lark-vc` 的产物决策读取纪要正文、逐字稿或妙记。 + - 再根据 `note_display_type`、`note_id`、`minute_token` 和用户意图,按 `lark-meeting` 的产物决策读取纪要正文、逐字稿或妙记。 - 事件列表是否完整,取决于应用机器人何时入会、何时离会,以及后端当前可见的会中事件范围。对于已结束会议,通常只在**结束后 5 分钟内**、且应用机器人**曾经在会中**时还能继续拉到事件。 - 查询"谁参加过某会议"请用 `vc meeting get --params '{"meeting_id":"","with_participants":true}'`——这是参会人**快照** API,不依赖 bot 是否参会,对已结束会议也可查;**不要** 用 `+meeting-events` 做参会人查询。 -## 参考 - -- [lark-vc-agent-meeting-join](../../lark-vc-agent/references/lark-vc-agent-meeting-join.md) — 先真实入会 -- [lark-vc-meeting-list-active](lark-vc-meeting-list-active.md) — 发现当前可读事件的进行中会议 ID -- [lark-vc-agent-meeting-leave](../../lark-vc-agent/references/lark-vc-agent-meeting-leave.md) — 用户明确要求时离会 -- [lark-vc-search](lark-vc-search.md) — 搜索历史会议(获取 meeting_id) -- [lark-vc-recording](lark-vc-recording.md) — 查询 minute_token -- [lark-vc-detail](lark-vc-detail.md) — 获取会议详情 -- [lark-vc-agent](../../lark-vc-agent/SKILL.md) — Agent 参会能力 -- [lark-vc](../SKILL.md) — 视频会议原子域(Meeting / Note 等核心概念) -- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数 +## 相关场景 +- [会中事件与会中互动](../scenes/live-meeting-interact.md) +- [应用机器人参会与会中互动](../scenes/live-meeting-attend.md) diff --git a/skills/lark-vc/references/lark-vc-meeting-list-active.md b/skills/lark-meeting/references/lark-vc-meeting-list-active.md similarity index 69% rename from skills/lark-vc/references/lark-vc-meeting-list-active.md rename to skills/lark-meeting/references/lark-vc-meeting-list-active.md index 08cd7286..0ca3ae69 100644 --- a/skills/lark-vc/references/lark-vc-meeting-list-active.md +++ b/skills/lark-meeting/references/lark-vc-meeting-list-active.md @@ -33,22 +33,6 @@ lark-cli vc +meeting-list-active --as bot --user-id ou_xxx --format json 应用身份返回空,不代表目标用户不在任何会议中,只能说明没有找到“目标用户在会中且应用机器人也在会中”的当前会。 -常见流程: - -```bash -# 方式 1:先让应用机器人入会,直接从 join 响应拿 meeting.id -lark-cli vc +meeting-join --as bot --meeting-number 123456789 --format json -lark-cli vc +meeting-events --as bot --meeting-id --page-all --format pretty - -# 方式 2:应用机器人已经在会中时,用应用身份发现 meeting_id -lark-cli vc +meeting-list-active --as bot --user-id --format json -lark-cli vc +meeting-events --as bot --meeting-id --page-all --format pretty - -# 方式 3:查询当前登录用户所在会议发生了什么 -lark-cli vc +meeting-list-active --as user --format json -lark-cli vc +meeting-events --as user --meeting-id --page-all --format pretty -``` - ## 多会议选择 - 如果返回多个会议,不要自动挑第一个。 @@ -59,14 +43,6 @@ lark-cli vc +meeting-events --as user --meeting-id --page-all --format pret 用户提供 9 位会议号但没有明确要求应用机器人入会时,把会议号当作 active meeting 的筛选条件,而不是写操作指令。 -```bash -# 用户问“我当前这个会讲了什么” -lark-cli vc +meeting-list-active --as user --format json - -# 用户问“让应用机器人所在/可见的这个会讲了什么” -lark-cli vc +meeting-list-active --as bot --user-id --format json -``` - 匹配规则: - 在返回会议中匹配 `meeting_no == <9位会议号>`。 @@ -83,9 +59,8 @@ lark-cli vc +meeting-list-active --as bot --user-id --format json | 用户身份无权限 / 不可见 | 当前登录用户没有可见的进行中会议,或当前身份无法读取该会议 | 不要反复执行 `auth login`。确认用户是否在会中、是否切错 profile;用户明确要查询应用机器人可见的会议时,再拿目标用户 open_id 执行 `+meeting-list-active --as bot --user-id ` | | 应用身份返回空列表 | 没有满足“目标用户在会中且应用机器人也在会中”的当前会 | 先让应用机器人入会,或确认 `user_id` 和会议状态 | | `--user-id` 格式错误 | 传入了 internal user_id 或其他非 `ou_...` 值 | 改传目标用户 open_id | -| 应用身份权限不足 | 应用权限、租户安装、权限可访问的数据范围或 VC Agent privilege 未配置完整 | 不要执行 `auth login`。请应用开发者开通 `vc:meeting.bot.join:write`;再检查应用发布/安装和权限可访问的数据范围,均正确仍失败时再排查内测灰度权限 | +| 应用身份权限不足 | 应用权限、租户安装或权限可访问的数据范围未配置完整 | 不要执行 `auth login`。请应用开发者开通 `vc:meeting.bot.join:write`;再检查应用发布/安装和权限可访问的数据范围;配置正确仍失败时,保留错误码和 `log_id`,按服务端权限异常排查 | -## 参考 - -- [lark-vc-agent-meeting-join](../../lark-vc-agent/references/lark-vc-agent-meeting-join.md) — 让应用机器人真实入会并拿 `meeting.id` -- [lark-vc-meeting-events](lark-vc-meeting-events.md) — 使用 `meeting_id` 读取会中事件 +## 相关场景 +- [会中事件与会中互动](../scenes/live-meeting-interact.md) +- [应用机器人参会与会中互动](../scenes/live-meeting-attend.md) diff --git a/skills/lark-vc/references/lark-vc-meeting-message-send.md b/skills/lark-meeting/references/lark-vc-meeting-message-send.md similarity index 95% rename from skills/lark-vc/references/lark-vc-meeting-message-send.md rename to skills/lark-meeting/references/lark-vc-meeting-message-send.md index 69fd43be..77b90240 100644 --- a/skills/lark-vc/references/lark-vc-meeting-message-send.md +++ b/skills/lark-meeting/references/lark-vc-meeting-message-send.md @@ -127,8 +127,6 @@ VC_CanNotSee, VC_NoSound, VC_LooksGood, VC_SoundsClear 应用身份权限错误时,不要引导用户反复 `auth login`。按主 skill 的“应用身份权限配置检查”处理。 -## 相关 - -- [lark-vc-meeting-list-active](lark-vc-meeting-list-active.md) — 发现当前进行中会议 ID -- [lark-vc-meeting-events](lark-vc-meeting-events.md) — 读取会中事件 -- [lark-vc-agent-meeting-join](../../lark-vc-agent/references/lark-vc-agent-meeting-join.md) — 应用机器人入会 +## 相关场景 +- [会中事件与会中互动](../scenes/live-meeting-interact.md) +- [应用机器人参会与会中互动](../scenes/live-meeting-attend.md) diff --git a/skills/lark-vc/references/lark-vc-recording.md b/skills/lark-meeting/references/lark-vc-recording.md similarity index 57% rename from skills/lark-vc/references/lark-vc-recording.md rename to skills/lark-meeting/references/lark-vc-recording.md index f28f3f03..c692e899 100644 --- a/skills/lark-vc/references/lark-vc-recording.md +++ b/skills/lark-meeting/references/lark-vc-recording.md @@ -42,9 +42,7 @@ lark-cli vc +recording --meeting-ids 69xxxxxxxxxxxxx28 --dry-run ### 2. 身份支持 -`--meeting-ids` 和 `--calendar-event-ids` 两种模式都支持 `--as user` 和 `--as bot`。user token 只能查自己有权限的录制;bot 使用 tenant_access_token,只能查 bot 有权限的录制。 - -拿到的 `minute_token` 是在某个身份下解析出来的:下一步传给 `minutes minutes get` / `minutes +detail` / `minutes +download` 时必须显式沿用同一个 `--as`,不要省略让身份被 profile 默认值悄悄换掉(完整规则见 [lark-shared](../../lark-shared/SKILL.md) 的「身份延续」)。 +`--meeting-ids` 和 `--calendar-event-ids` 都支持 `--as user` / `--as bot`。用户身份只能查自己有权限的录制;应用身份只能查应用有权限的录制。拿到 `minute_token` 后,传给 `minutes minutes get`、`minutes +detail` 或 `minutes +download` 时必须显式沿用同一个 `--as`。 ### 3. 批量上限 @@ -74,62 +72,6 @@ lark-cli vc +recording --meeting-ids 69xxxxxxxxxxxxx28 --dry-run | `meeting_id` | 使用 `lark-cli vc +search` 搜索历史会议,取结果中的 `id` 字段 | | `calendar_event_id` | 使用 `lark-cli calendar +agenda` 查看日程,取结果中的 `event_id` 字段 | -## Agent 组合场景 - -### 场景 1:知道 meeting_id,想下载录制 - -```bash -# 第 1 步:通过 meeting_id 查询录制,拿到 minute_token -lark-cli vc +recording --meeting-ids xxx --as bot - -# 第 2 步:使用上一步返回的 minute_token 下载妙记文件,沿用第 1 步的身份 -lark-cli minutes +download --minute-tokens obcnxxxxxxxxxxxxxxxxxxxx --as bot -``` - -### 场景 2:知道 meeting_id,想查询妙记基础信息 - -```bash -# 第 1 步:通过 meeting_id 查询录制,拿到 minute_token -lark-cli vc +recording --meeting-ids xxx - -# 第 2 步:使用上一步返回的 minute_token 查询妙记基础信息 -lark-cli minutes minutes get --params '{"minute_token":""}' -``` - -### 场景 3:知道 meeting_id,想获取完整纪要(含 AI 产物) - -```bash -# 第 1 步:通过 meeting_id 查询录制,拿到 minute_token -lark-cli vc +recording --meeting-ids xxx - -# 第 2 步:使用上一步返回的 minute_token 获取完整纪要 -# ⚠️ 必须显式指定要获取的产物 flag(--summary, --keyword, --todo, --chapter, --transcript) -lark-cli minutes +detail --minute-tokens --summary --todo --chapter --transcript -``` - -### 场景 4:先搜索会议,再获取录制并下载 - -```bash -# 第 1 步:搜索历史会议,拿到 meeting_ids -lark-cli vc +search --query "周会" --start 2026-03-10 - -# 第 2 步:使用上一步返回的 meeting_ids 查询录制,拿到 minute_tokens -lark-cli vc +recording --meeting-ids - -# 第 3 步:使用其中一个 minute_token 下载妙记文件 -lark-cli minutes +download --minute-tokens -``` - -### 场景 5:从日历事件获取录制 - -```bash -# 第 1 步:通过日历 event_id 查询录制,拿到 minute_token -lark-cli vc +recording --calendar-event-ids - -# 第 2 步:使用上一步返回的 minute_token 下载妙记文件 -lark-cli minutes +download --minute-tokens -``` - ## 常见错误与排查 | 错误现象 | 根本原因 | 解决方案 | @@ -147,8 +89,5 @@ lark-cli minutes +download --minute-tokens - `minute_token` 从录制 URL 尾段解析(`https://meetings.feishu.cn/minutes/{minute_token}`)。 - 拿到 `minute_token` 后,如果要妙记基础信息,优先传给 `minutes minutes get`;如果要下载媒体文件,传给 `minutes +download`;如果要逐字稿、总结、待办、章节,再传给 `minutes +detail --minute-tokens`。 -## 参考 - -- [lark-vc](../SKILL.md) — 视频会议全部命令 -- [lark-vc-search](lark-vc-search.md) — 搜索历史会议(获取 meeting_id) -- [lark-minutes-detail](../../lark-minutes/references/lark-minutes-detail.md) — 获取会议纪要 +## 相关场景 +- [查询会议及其产物](../scenes/query-meeting-and-artifacts.md) diff --git a/skills/lark-vc/references/lark-vc-search.md b/skills/lark-meeting/references/lark-vc-search.md similarity index 79% rename from skills/lark-vc/references/lark-vc-search.md rename to skills/lark-meeting/references/lark-vc-search.md index 7aaa3160..bd77c24f 100644 --- a/skills/lark-vc/references/lark-vc-search.md +++ b/skills/lark-meeting/references/lark-vc-search.md @@ -5,7 +5,7 @@ ## 关键词使用边界 -`--query` 只用于真实会议关键词,例如会议主题、项目名、评审名、客户名。用户只是说"我这月参加的所有视频会议"、"最近两周我组织的所有视频会议"、"总结主要议题 / 看看参会情况"时,本质是历史会议列表和后续总结,不要把"回顾"、"所有视频会议"、"总结主要议题"等动作词放进 `--query`。这类请求应先用时间范围 + `--participant-ids` / `--organizer-ids` 搜全量候选,再按结果继续取纪要或录制信息。 +`--query` 只用于 9 位会议号或真实会议关键词,例如会议主题、项目名、评审名、客户名。用户只是说"我这月参加的所有视频会议"、"最近两周我组织的所有视频会议"、"总结主要议题 / 看看参会情况"时,本质是历史会议列表和后续总结,不要把"回顾"、"所有视频会议"、"总结主要议题"等动作词放进 `--query`。这类请求应先用时间范围 + `--participant-ids` / `--organizer-ids` 搜全量候选,再按结果继续取纪要或录制信息。 列表阶段只负责找会议记录;总结阶段必须继续取证。若用户要求"主要议题"、"主要决策"、"参会情况",先确认搜索结果的 `meeting_id`、时间、组织者/参与者符合过滤条件,然后用 `vc +detail` 或 `minutes` 读取纪要、妙记或录制信息。没有纪要或妙记时,如实说明只能基于会议标题/参会数据汇总,不要编造议题。 @@ -26,6 +26,9 @@ # 关键词搜索 lark-cli vc +search --query "周会" +# 通过 9 位会议号查询会议 ID +lark-cli vc +search --query "123456789" --format json --as user + # 查询某一天开过的会(单日查询时,start 和 end 必须填写同一天) lark-cli vc +search --start 2026-03-10 --end 2026-03-10 @@ -48,7 +51,7 @@ lark-cli vc +search --query "周会" --page-token "" | 参数 | 必填 | 说明 | |------|------|------| -| `--query ` | 否 | 搜索关键词 | +| `--query ` | 否 | 9 位会议号或搜索关键词 | | `--start