From 7c4f500f668d68148d081e4e8e063e2792736752 Mon Sep 17 00:00:00 2001 From: renaocheng Date: Mon, 6 Jul 2026 14:54:30 +0800 Subject: [PATCH] fix(vc): rename meeting events participants field --- shortcuts/vc/vc_meeting_events.go | 76 +++++++++---------- shortcuts/vc/vc_meeting_events_test.go | 72 +++++++++--------- skills/lark-vc-agent/SKILL.md | 2 +- .../lark-vc-agent-meeting-events.md | 4 +- 4 files changed, 77 insertions(+), 77 deletions(-) diff --git a/shortcuts/vc/vc_meeting_events.go b/shortcuts/vc/vc_meeting_events.go index 888172f74..79ef2454b 100644 --- a/shortcuts/vc/vc_meeting_events.go +++ b/shortcuts/vc/vc_meeting_events.go @@ -103,15 +103,15 @@ var VCMeetingEvents = common.Shortcut{ } events = compactMeetingEvents(events) identity, identityWarning := meetingEventsCurrentIdentity(runtime) - currentRoster, rosterWarning := fetchMeetingEventsCurrentRoster(runtime) - outData := buildMeetingEventsOutput(data, events, currentRoster, identity, identityWarning, rosterWarning) + currentParticipants, participantsWarning := fetchMeetingEventsCurrentParticipants(runtime) + outData := buildMeetingEventsOutput(data, events, currentParticipants, identity, identityWarning, participantsWarning) metadata := map[string]interface{}{ - "row_type": "metadata", - "meeting": outData.Meeting, - "identity": outData.Identity, - "current_roster": outData.CurrentRoster, - "has_more": outData.HasMore, - "page_token": outData.PageToken, + "row_type": "metadata", + "meeting": outData.Meeting, + "identity": outData.Identity, + "current_participants": outData.CurrentParticipants, + "has_more": outData.HasMore, + "page_token": outData.PageToken, } if len(outData.Warnings) > 0 { metadata["warnings"] = outData.Warnings @@ -137,13 +137,13 @@ var VCMeetingEvents = common.Shortcut{ } type meetingEventsOutput struct { - Meeting meetingEventsMeeting `json:"meeting"` - Identity meetingEventsIdentity `json:"identity"` - CurrentRoster []meetingEventsIdentity `json:"current_roster"` - Events []meetingEventsEvent `json:"events"` - Warnings []string `json:"warnings,omitempty"` - HasMore bool `json:"has_more"` - PageToken string `json:"page_token,omitempty"` + Meeting meetingEventsMeeting `json:"meeting"` + Identity meetingEventsIdentity `json:"identity"` + CurrentParticipants []meetingEventsIdentity `json:"current_participants"` + Events []meetingEventsEvent `json:"events"` + Warnings []string `json:"warnings,omitempty"` + HasMore bool `json:"has_more"` + PageToken string `json:"page_token,omitempty"` } type meetingEventsMeeting struct { @@ -172,7 +172,7 @@ type meetingEventsEvent struct { Payload map[string]interface{} `json:"payload,omitempty"` } -func buildMeetingEventsOutput(data map[string]interface{}, events []interface{}, currentRoster []interface{}, identity meetingEventsIdentity, warnings ...string) meetingEventsOutput { +func buildMeetingEventsOutput(data map[string]interface{}, events []interface{}, currentParticipants []interface{}, identity meetingEventsIdentity, warnings ...string) meetingEventsOutput { output := meetingEventsOutput{ Meeting: meetingEventsMeetingFromPayload(nil), Identity: identity, @@ -195,7 +195,7 @@ func buildMeetingEventsOutput(data map[string]interface{}, events []interface{}, } output.Events = append(output.Events, meetingEventsEventFromPayload(event, output.Identity)) } - output.CurrentRoster = enrichMeetingEventsCurrentRoster(meetingEventsCurrentRoster(currentRoster, output.Identity), output.Events) + output.CurrentParticipants = enrichMeetingEventsCurrentParticipants(meetingEventsCurrentParticipants(currentParticipants, output.Identity), output.Events) return output } @@ -222,12 +222,12 @@ func meetingEventsCurrentIdentity(runtime *common.RuntimeContext) (meetingEvents return identity, "" } -func fetchMeetingEventsCurrentRoster(runtime *common.RuntimeContext) ([]interface{}, string) { +func fetchMeetingEventsCurrentParticipants(runtime *common.RuntimeContext) ([]interface{}, string) { meetingID := strings.TrimSpace(runtime.Str("meeting-id")) data, err := runtime.CallAPITyped(http.MethodGet, fmt.Sprintf("/open-apis/vc/v1/meetings/%s", validate.EncodePathSegment(meetingID)), map[string]interface{}{"with_participants": "true", "query_mode": "0", "user_id_type": "open_id"}, nil) if err != nil { - return nil, fmt.Sprintf("current_roster unavailable: %v", err) + return nil, fmt.Sprintf("current_participants unavailable: %v", err) } if meeting := common.GetMap(data, "meeting"); meeting != nil { return common.GetSlice(meeting, "participants"), "" @@ -284,9 +284,9 @@ func meetingEventsEventFromPayload(event map[string]interface{}, selfIdentity me return out } -func meetingEventsCurrentRoster(rawRoster []interface{}, selfIdentity meetingEventsIdentity) []meetingEventsIdentity { - roster := make([]meetingEventsIdentity, 0, len(rawRoster)) - for _, raw := range rawRoster { +func meetingEventsCurrentParticipants(rawParticipants []interface{}, selfIdentity meetingEventsIdentity) []meetingEventsIdentity { + participants := make([]meetingEventsIdentity, 0, len(rawParticipants)) + for _, raw := range rawParticipants { item, _ := raw.(map[string]interface{}) if item == nil { continue @@ -295,12 +295,12 @@ func meetingEventsCurrentRoster(rawRoster []interface{}, selfIdentity meetingEve if nested := common.GetMap(item, "participant"); nested != nil { participant = nested } - roster = append(roster, meetingEventsIdentityFromParticipant(participant, selfIdentity)) + participants = append(participants, meetingEventsIdentityFromParticipant(participant, selfIdentity)) } - return roster + return participants } -func enrichMeetingEventsCurrentRoster(roster []meetingEventsIdentity, events []meetingEventsEvent) []meetingEventsIdentity { +func enrichMeetingEventsCurrentParticipants(participants []meetingEventsIdentity, events []meetingEventsEvent) []meetingEventsIdentity { typeByID := make(map[string]string) nameByID := make(map[string]string) for _, event := range events { @@ -320,25 +320,25 @@ func enrichMeetingEventsCurrentRoster(roster []meetingEventsIdentity, events []m } } } - for i := range roster { + for i := range participants { changed := false - if roster[i].Name == "" { - if name := nameByID[roster[i].ID]; name != "" { - roster[i].Name = name + if participants[i].Name == "" { + if name := nameByID[participants[i].ID]; name != "" { + participants[i].Name = name changed = true } } - if isUnknownParticipantType(roster[i].ParticipantType) { - if participantType := typeByID[roster[i].ID]; participantType != "" { - roster[i].ParticipantType = participantType + if isUnknownParticipantType(participants[i].ParticipantType) { + if participantType := typeByID[participants[i].ID]; participantType != "" { + participants[i].ParticipantType = participantType changed = true } } if changed { - roster[i].Label = identityLabel(roster[i]) + participants[i].Label = identityLabel(participants[i]) } } - return roster + return participants } func eventActors(eventType string, payload map[string]interface{}, selfIdentity meetingEventsIdentity) []meetingEventsIdentity { @@ -419,7 +419,7 @@ func meetingEventsParticipantTypeFromParticipantType(raw string) string { } func meetingEventsParticipantRole(participant map[string]interface{}) string { - if raw := meetingEventsRoleFromRosterRole(fieldValueString(participant, "role")); raw != "" { + if raw := meetingEventsRoleFromParticipantRole(fieldValueString(participant, "role")); raw != "" { return raw } return meetingEventsRoleFromEventUserRole(fieldValueString(participant, "user_role")) @@ -452,7 +452,7 @@ func isUnknownParticipantType(participantType string) bool { return participantType == "" || participantType == "unknown" } -func meetingEventsRoleFromRosterRole(raw string) string { +func meetingEventsRoleFromParticipantRole(raw string) string { raw = strings.ToLower(strings.TrimSpace(raw)) switch raw { case "1", "host": @@ -580,9 +580,9 @@ func renderMeetingEventsCompactPretty(w io.Writer, data meetingEventsOutput, tim if data.Identity.Label != "" { fmt.Fprintf(w, "当前身份:%s\n", escapePrettyText(data.Identity.Label)) } - if len(data.CurrentRoster) > 0 { + if len(data.CurrentParticipants) > 0 { fmt.Fprintln(w, "当前名单:") - for _, participant := range data.CurrentRoster { + for _, participant := range data.CurrentParticipants { fmt.Fprintf(w, "- %s\n", escapePrettyText(participant.Label)) } fmt.Fprintln(w) diff --git a/shortcuts/vc/vc_meeting_events_test.go b/shortcuts/vc/vc_meeting_events_test.go index 900ff87c7..04fa3c87c 100644 --- a/shortcuts/vc/vc_meeting_events_test.go +++ b/shortcuts/vc/vc_meeting_events_test.go @@ -82,7 +82,7 @@ func botInfoErrorStub() *httpmock.Stub { } } -func meetingDetailRosterStub(roster []interface{}) *httpmock.Stub { +func meetingDetailParticipantsStub(participants []interface{}) *httpmock.Stub { return &httpmock.Stub{ Method: "GET", URL: "/open-apis/vc/v1/meetings/7628568141510692381", @@ -92,14 +92,14 @@ func meetingDetailRosterStub(roster []interface{}) *httpmock.Stub { "data": map[string]interface{}{ "meeting": map[string]interface{}{ "id": "7628568141510692381", - "participants": roster, + "participants": participants, }, }, }, } } -func meetingDetailRosterErrorStub() *httpmock.Stub { +func meetingDetailParticipantsErrorStub() *httpmock.Stub { return &httpmock.Stub{ Method: "GET", URL: "/open-apis/vc/v1/meetings/7628568141510692381", @@ -555,7 +555,7 @@ func TestMeetingEvents_ExecuteJSON_PageAll(t *testing.T) { reg.Register(meetingEventsStub([]interface{}{participantJoinedEvent()}, true, "pt_2")) reg.Register(meetingEventsStub([]interface{}{participantJoinedEvent()}, false, "")) reg.Register(botInfoStub()) - reg.Register(meetingDetailRosterStub(nil)) + reg.Register(meetingDetailParticipantsStub(nil)) err := mountAndRun(t, VCMeetingEvents, []string{ "+meeting-events", @@ -597,7 +597,7 @@ func TestMeetingEvents_ExecuteJSON(t *testing.T) { f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig()) reg.Register(meetingEventsStub([]interface{}{participantJoinedEvent()}, true, "1710000000000000000")) reg.Register(botInfoStub()) - reg.Register(meetingDetailRosterStub([]interface{}{ + reg.Register(meetingDetailParticipantsStub([]interface{}{ map[string]interface{}{"id": "bot_001", "user_name": "Demo Bot", "participant_type": "2", "role": "4"}, map[string]interface{}{"id": "u1", "user_name": "Alice", "participant_type": "1", "role": "1"}, })) @@ -617,7 +617,7 @@ func TestMeetingEvents_ExecuteJSON(t *testing.T) { out = strings.ReplaceAll(out, "\n", "") for _, want := range []string{ `"identity":{"id":"bot_001","name":"DemoBot","participant_type":"bot","role":"bot","is_self":true,"label":"DemoBot[bot]"}`, - `"current_roster":[`, + `"current_participants":[`, `"role":"host"`, `"is_self":true`, `"event_type":"participant_joined"`, @@ -641,11 +641,11 @@ func TestMeetingEvents_ExecuteJSON(t *testing.T) { } } -func TestMeetingEvents_ExecuteJSON_RosterErrorDoesNotBlockEvents(t *testing.T) { +func TestMeetingEvents_ExecuteJSON_ParticipantsErrorDoesNotBlockEvents(t *testing.T) { f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig()) reg.Register(meetingEventsStub([]interface{}{participantJoinedEvent()}, false, "")) reg.Register(botInfoStub()) - reg.Register(meetingDetailRosterErrorStub()) + reg.Register(meetingDetailParticipantsErrorStub()) err := mountAndRun(t, VCMeetingEvents, []string{ "+meeting-events", @@ -662,9 +662,9 @@ func TestMeetingEvents_ExecuteJSON_RosterErrorDoesNotBlockEvents(t *testing.T) { out = strings.ReplaceAll(out, "\n", "") for _, want := range []string{ `"event_type":"participant_joined"`, - `"current_roster":[]`, + `"current_participants":[]`, `"warnings":[`, - `current_rosterunavailable`, + `current_participantsunavailable`, } { if !strings.Contains(out, want) { t.Fatalf("json output missing %q: %s", want, stdout.String()) @@ -676,7 +676,7 @@ func TestMeetingEvents_ExecuteJSON_BotIdentityErrorDoesNotBlockEvents(t *testing f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig()) reg.Register(meetingEventsStub([]interface{}{participantJoinedEvent()}, false, "")) reg.Register(botInfoErrorStub()) - reg.Register(meetingDetailRosterStub(nil)) + reg.Register(meetingDetailParticipantsStub(nil)) err := mountAndRun(t, VCMeetingEvents, []string{ "+meeting-events", @@ -706,7 +706,7 @@ func TestMeetingEvents_ExecuteJSON_BotIdentityErrorDoesNotBlockEvents(t *testing func TestMeetingEvents_ExecuteJSON_UserIdentitySkipsBotInfo(t *testing.T) { f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig()) reg.Register(meetingEventsStub([]interface{}{participantJoinedEvent()}, false, "")) - reg.Register(meetingDetailRosterStub([]interface{}{ + reg.Register(meetingDetailParticipantsStub([]interface{}{ map[string]interface{}{"id": "ou_testuser", "user_name": "Current User", "participant_type": "1", "role": "1"}, map[string]interface{}{"id": "u1", "user_name": "Alice", "participant_type": "1", "role": "1"}, })) @@ -726,7 +726,7 @@ func TestMeetingEvents_ExecuteJSON_UserIdentitySkipsBotInfo(t *testing.T) { out = strings.ReplaceAll(out, "\n", "") for _, want := range []string{ `"identity":{"id":"ou_testuser","participant_type":"human","role":"user","is_self":true,"label":"ou_testuser[human,user]"}`, - `"current_roster":[`, + `"current_participants":[`, `"id":"ou_testuser"`, `"is_self":true`, `"event_type":"participant_joined"`, @@ -742,7 +742,7 @@ func TestMeetingEvents_ExecuteJSON_OngoingMeetingOmitsEndTime(t *testing.T) { f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig()) reg.Register(meetingEventsStub([]interface{}{participantJoinedEventOngoing()}, false, "")) reg.Register(botInfoStub()) - reg.Register(meetingDetailRosterStub(nil)) + reg.Register(meetingDetailParticipantsStub(nil)) err := mountAndRun(t, VCMeetingEvents, []string{ "+meeting-events", @@ -798,7 +798,7 @@ func TestMeetingEvents_ExecuteNDJSONIncludesMetadataRow(t *testing.T) { f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig()) reg.Register(meetingEventsStub([]interface{}{participantJoinedEvent()}, true, "1710000000000000000")) reg.Register(botInfoStub()) - reg.Register(meetingDetailRosterStub([]interface{}{ + reg.Register(meetingDetailParticipantsStub([]interface{}{ map[string]interface{}{"id": "bot_001", "user_name": "Demo Bot", "participant_type": "2", "role": "4"}, })) @@ -833,7 +833,7 @@ func TestMeetingEvents_ExecuteNDJSONIncludesMetadataRow(t *testing.T) { `"has_more":true`, `"page_token":"1710000000000000000"`, `"identity":`, - `"current_roster":[`, + `"current_participants":[`, } { if !strings.Contains(lines[1], want) { t.Fatalf("metadata ndjson row missing %q: %s", want, lines[1]) @@ -845,7 +845,7 @@ func TestMeetingEvents_ExecuteJSON_PrunesEmptySlices(t *testing.T) { f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig()) reg.Register(meetingEventsStub([]interface{}{chatReceivedEvent()}, false, "")) reg.Register(botInfoStub()) - reg.Register(meetingDetailRosterStub(nil)) + reg.Register(meetingDetailParticipantsStub(nil)) err := mountAndRun(t, VCMeetingEvents, []string{ "+meeting-events", @@ -879,7 +879,7 @@ func TestMeetingEvents_ExecuteJSON_PreservesReactionItems(t *testing.T) { f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig()) reg.Register(meetingEventsStub([]interface{}{mixedChatAndReactionEvent()}, false, "")) reg.Register(botInfoStub()) - reg.Register(meetingDetailRosterStub(nil)) + reg.Register(meetingDetailParticipantsStub(nil)) err := mountAndRun(t, VCMeetingEvents, []string{ "+meeting-events", @@ -913,7 +913,7 @@ func TestMeetingEvents_ExecutePretty(t *testing.T) { f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig()) reg.Register(meetingEventsStub([]interface{}{participantJoinedEventOngoing(), multiChatReceivedEvent(), magicShareStartedEvent()}, true, "1710000000000000000")) reg.Register(botInfoStub()) - reg.Register(meetingDetailRosterStub([]interface{}{ + reg.Register(meetingDetailParticipantsStub([]interface{}{ map[string]interface{}{"id": "bot_001", "user_name": "Demo Bot", "participant_type": "2", "role": "4"}, map[string]interface{}{"id": "u1", "user_name": "Alice", "participant_type": "1", "role": "1"}, })) @@ -960,7 +960,7 @@ func TestMeetingEvents_ExecutePretty_PrintsPageTokenWithoutHasMore(t *testing.T) f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig()) reg.Register(meetingEventsStub([]interface{}{participantJoinedEventOngoing()}, false, "pt_last")) reg.Register(botInfoStub()) - reg.Register(meetingDetailRosterStub(nil)) + reg.Register(meetingDetailParticipantsStub(nil)) err := mountAndRun(t, VCMeetingEvents, []string{ "+meeting-events", @@ -986,7 +986,7 @@ func TestMeetingEvents_ExecuteEmpty(t *testing.T) { f, stdout, _, reg := cmdutil.TestFactory(t, defaultConfig()) reg.Register(meetingEventsStub(nil, false, "")) reg.Register(botInfoStub()) - reg.Register(meetingDetailRosterStub(nil)) + reg.Register(meetingDetailParticipantsStub(nil)) err := mountAndRun(t, VCMeetingEvents, []string{ "+meeting-events", @@ -1317,7 +1317,7 @@ func TestMeetingEventsIdentityFromParticipant_UnknownUserType(t *testing.T) { } } -func TestBuildMeetingEventsOutput_EnrichesUnknownRosterTypeFromActors(t *testing.T) { +func TestBuildMeetingEventsOutput_EnrichesUnknownParticipantTypeFromActors(t *testing.T) { event := participantJoinedEvent() payload := common.GetMap(event, "payload") items := common.GetSlice(payload, "participant_joined_items") @@ -1333,21 +1333,21 @@ func TestBuildMeetingEventsOutput_EnrichesUnknownRosterTypeFromActors(t *testing map[string]interface{}{"id": "ou_bot", "user_type": 0, "role": "3"}, }, meetingEventsIdentity{}) - if got := len(out.CurrentRoster); got != 1 { - t.Fatalf("current_roster len = %d, want 1", got) + if got := len(out.CurrentParticipants); got != 1 { + t.Fatalf("current_participants len = %d, want 1", got) } - if got := out.CurrentRoster[0].ParticipantType; got != "bot" { - t.Fatalf("current_roster participant_type = %q, want bot: %#v", got, out.CurrentRoster[0]) + if got := out.CurrentParticipants[0].ParticipantType; got != "bot" { + t.Fatalf("current_participants participant_type = %q, want bot: %#v", got, out.CurrentParticipants[0]) } - if got := out.CurrentRoster[0].Name; got != "Meeting Bot" { - t.Fatalf("current_roster name = %q, want actor name", got) + if got := out.CurrentParticipants[0].Name; got != "Meeting Bot" { + t.Fatalf("current_participants name = %q, want actor name", got) } - if got := out.CurrentRoster[0].Label; got != "Meeting Bot [bot,participant]" { - t.Fatalf("current_roster label = %q, want enriched bot label", got) + if got := out.CurrentParticipants[0].Label; got != "Meeting Bot [bot,participant]" { + t.Fatalf("current_participants label = %q, want enriched bot label", got) } } -func TestBuildMeetingEventsOutput_DoesNotOverwriteRosterName(t *testing.T) { +func TestBuildMeetingEventsOutput_DoesNotOverwriteParticipantName(t *testing.T) { event := participantJoinedEvent() payload := common.GetMap(event, "payload") items := common.GetSlice(payload, "participant_joined_items") @@ -1360,14 +1360,14 @@ func TestBuildMeetingEventsOutput_DoesNotOverwriteRosterName(t *testing.T) { } out := buildMeetingEventsOutput(map[string]interface{}{}, []interface{}{event}, []interface{}{ - map[string]interface{}{"id": "ou_user", "user_name": "Roster Name", "user_type": 1, "role": "3"}, + map[string]interface{}{"id": "ou_user", "user_name": "Participant Name", "user_type": 1, "role": "3"}, }, meetingEventsIdentity{}) - if got := out.CurrentRoster[0].Name; got != "Roster Name" { - t.Fatalf("current_roster name = %q, want roster name", got) + if got := out.CurrentParticipants[0].Name; got != "Participant Name" { + t.Fatalf("current_participants name = %q, want participant name", got) } - if got := out.CurrentRoster[0].Label; got != "Roster Name [human,participant]" { - t.Fatalf("current_roster label = %q, want roster label", got) + if got := out.CurrentParticipants[0].Label; got != "Participant Name [human,participant]" { + t.Fatalf("current_participants label = %q, want participant label", got) } } diff --git a/skills/lark-vc-agent/SKILL.md b/skills/lark-vc-agent/SKILL.md index b7d609679..984e01cbe 100644 --- a/skills/lark-vc-agent/SKILL.md +++ b/skills/lark-vc-agent/SKILL.md @@ -72,7 +72,7 @@ metadata: - 再根据 `note_id`、`minute_token` 和用户意图,按 [`lark-vc`](../lark-vc/SKILL.md) 的产物决策读取正文、逐字稿或妙记。 - 想看参会人快照:用 `vc meeting get --with-participants`(见 [`lark-vc`](../lark-vc/SKILL.md)) 5. **默认必须使用** **`--page-all`**,除非用户明确要求“只查一页”,或确实需要控制返回体大小。 -6. 命令默认输出结构化事件契约:`meeting`、`identity`、`current_roster`、`events`、`warnings`、`has_more`、`page_token`;参会人含 `participant_type`、`role`、`is_self` 和可读 `label`,事件细节保留在 `payload`。 +6. 命令默认输出结构化事件契约:`meeting`、`identity`、`current_participants`、`events`、`warnings`、`has_more`、`page_token`;参会人含 `participant_type`、`role`、`is_self` 和可读 `label`,事件细节保留在 `payload`。 7. 输出格式默认优先 `--format pretty`(时间线更易读,并带当前身份与当前名单标签);需要稳定字段做结构化处理时用 `--format json`;需要流式消费事件时用 `--format ndjson`。 8. **必须识别分页信号**:只要响应里出现 `has_more=true`、pretty 里的 `more available`,或返回了非空 `page_token`,就不能把当前结果当作完整事件流;默认应继续分页,或明确告诉用户当前只是部分结果。 9. 保留响应里的 `page_token`,下次增量拉取直接续,不要从头再拉。 diff --git a/skills/lark-vc-agent/references/lark-vc-agent-meeting-events.md b/skills/lark-vc-agent/references/lark-vc-agent-meeting-events.md index 371975663..15d2b5527 100644 --- a/skills/lark-vc-agent/references/lark-vc-agent-meeting-events.md +++ b/skills/lark-vc-agent/references/lark-vc-agent-meeting-events.md @@ -110,7 +110,7 @@ lark-cli vc +meeting-events --as user --meeting-id --page-all --format pret ### 5. 输出格式差异 -- `--format json`:结构化契约,顶层包含 `meeting`、`identity`、`current_roster`、`events`、`has_more`、`page_token`。参会人身份统一含 `participant_type`、`role`、`is_self`、`label`;每条事件保留 `payload` 便于追溯细节。 +- `--format json`:结构化契约,顶层包含 `meeting`、`identity`、`current_participants`、`events`、`has_more`、`page_token`。参会人身份统一含 `participant_type`、`role`、`is_self`、`label`;每条事件保留 `payload` 便于追溯细节。 - `--format pretty`:默认推荐格式,输出当前身份、当前名单和逐条时间线,适合快速理解“发生了什么”。 - `--format ndjson`:输出事件行,并带 metadata 行,适合流式消费。 @@ -160,7 +160,7 @@ lark-cli vc +meeting-events --as user --meeting-id --page-all --format pret |------|------| | `meeting` | 会议身份与时间状态,包含 `id/topic/meeting_no/start_time/end_time/status` | | `identity` | 当前读取身份,包含 `id/name/participant_type/role/is_self/label` | -| `current_roster` | 服务端当前名单;当 roster 缺少姓名或类型为 `unknown` 时,CLI 会用同 ID 的事件 actor 信息补全,不做完整历史 replay | +| `current_participants` | 服务端当前参会人名单;当参会人缺少姓名或类型为 `unknown` 时,CLI 会用同 ID 的事件 actor 信息补全,不做完整历史 replay | | `events` | 结构化事件列表;每条事件含 `actors` 和事件细节 `payload` | | `warnings` | 非阻断告警列表,例如当前名单补充信息不可用;事件列表本身仍可使用 | | `has_more` | 是否还有下一页 |