Skip to content

fix: normalize vc meeting events contract - #1544

Open
Ren1104 wants to merge 9 commits into
mainfrom
features/F-vc-meeting-events-contract
Open

fix: normalize vc meeting events contract#1544
Ren1104 wants to merge 9 commits into
mainfrom
features/F-vc-meeting-events-contract

Conversation

@Ren1104

@Ren1104 Ren1104 commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • normalize vc +meeting-events bot-facing compact output with bot identity, self markers, server current roster, normalized time/status fields, pretty labels, and raw escape hatch
  • update focused tests and lark-vc-agent guidance for the bot-only contract

Validation

  • gofmt on changed Go files
  • go build ./shortcuts/vc via controlled compile runner
  • collector-backed commit/push completed for features/F-vc-meeting-events-contract

Gate4 acceptance will continue with MR checks, remote UT/semantic, FT, and QA lanes under the same verification identity.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added +meeting-events --view with compact (default) and raw output modes.
    • compact output now includes normalized meeting, bot identity, current_roster, and event fields.
  • Changed Behavior

    • +meeting-events now supports bot authentication only (--as bot).
    • --view raw is available only with --format json, preserving the legacy event envelope (without bot/roster metadata).
  • Bug Fixes / Improvements

    • NDJSON output now adds a metadata row; time strings are normalized.
  • Documentation

    • Updated skill/reference guidance for bot-only event reads, pagination behavior, and meeting-visibility rules.

Source-Branch: features/F-vc-meeting-events-contract
Source-Commit: 5efaf65
Source-Subject: feat: surface search API notices (#1413)
Repo: larksuite-cli
Synced-By: bytedance
Timestamp: 20260623_090053Z
@github-actions github-actions Bot added domain/vc PR touches the vc domain size/L Large or sensitive change across domains or core paths labels Jun 23, 2026
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

+meeting-events is restricted to bot-only auth, gains a --view compact|raw flag, and its Execute path now branches: raw emits the legacy event envelope; compact fetches bot identity and current roster, normalizes all output into typed structs, and renders via NDJSON or pretty. Tests and agent skill docs are updated throughout.

Changes

vc +meeting-events: bot-only auth + compact/raw view

Layer / File(s) Summary
Auth change, view type, and normalized output contracts
shortcuts/vc/vc_meeting_events.go
VCMeetingEvents.AuthTypes narrows to ["bot"]; meetingEventsView enum (compact/raw) and all normalized output structs (normalizedMeetingEventsOutput, normalizedMeeting, normalizedIdentity, normalizedMeetingEvent) are declared; encoding/json and validate imports added.
View flag registration and validation
shortcuts/vc/vc_meeting_events.go
--view flag is registered on the shortcut; meetingEventsOutputView defaults to compact, validates allowed values, and rejects raw when format is not JSON.
Branched Execute flow: raw vs compact paths
shortcuts/vc/vc_meeting_events.go
Execute branches on view: raw emits events as-is with an NDJSON metadata count row and returns; compact calls bot-info and fetchMeetingEventsCurrentRoster, then buildNormalizedMeetingEvents, and dispatches to NDJSON or pretty renderers.
Normalization and rendering helpers
shortcuts/vc/vc_meeting_events.go
Helpers normalize bot identity, meeting/event/roster structures (status from time bounds, actor extraction, is_self tagging), time strings, deep-clone raw payloads, construct NDJSON rows, and render compact pretty output.
Test suite updates and new test cases
shortcuts/vc/vc_meeting_events_test.go
Default view=compact added to test runtime; bot-info and roster HTTP stubs introduced; fixture event payloads extended with classification fields; all existing tests migrated from --as user to --as bot with updated JSON/pretty assertions; new tests cover raw JSON skip, NDJSON metadata row, and raw+pretty validation rejection.
Agent skill docs: bot-only identity and compact view
skills/lark-vc-agent/SKILL.md, skills/lark-vc-agent/references/lark-vc-agent-meeting-events.md, skills/lark-vc-agent/references/lark-vc-agent-meeting-list-active.md
Identity routing rules updated to mandate --as bot for all +meeting-events calls; all example commands updated to --view compact; reference docs revised with bot-presence constraints, 9-digit meeting number guidance, output mode descriptions, and troubleshooting updates.

Sequence Diagram(s)

sequenceDiagram
    participant Agent
    participant Execute as +meeting-events Execute
    participant BotAPI as /open-apis/bot/v3/info
    participant MeetingAPI as /open-apis/vc/v1/meetings/{id}
    participant EventsAPI as VC Events API

    Agent->>Execute: --as bot --view compact
    Execute->>EventsAPI: fetch raw events (page_token, time range)
    EventsAPI-->>Execute: raw event list + has_more/page_token

    alt view=raw
        Execute-->>Agent: raw JSON + NDJSON metadata count row
    else view=compact
        Execute->>BotAPI: GET bot identity
        BotAPI-->>Execute: bot open_id, name
        Execute->>MeetingAPI: GET participants / current_roster
        MeetingAPI-->>Execute: roster list
        Execute->>Execute: buildNormalizedMeetingEvents (normalize meeting/bot/roster/events)
        alt format=ndjson
            Execute-->>Agent: NDJSON rows + metadata row
        else format=pretty
            Execute-->>Agent: compact pretty text (bot label + roster + timeline)
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • larksuite/cli#824: Initial implementation of vc +meeting-events shortcut in the same files (vc_meeting_events.go and its tests); this PR is a direct follow-up extending that feature.
  • larksuite/cli#1483: Modifies the same +meeting-events shortcut around authentication and meeting-id handling, which this PR further constrains to bot-only and extends with the --view branching.

Suggested reviewers

  • zhaoleibd
  • hugang-lark

Poem

🐇 Hoppity-hop, the bot takes the stage,
No more user auth on this VC page!
--view compact lines up the roster neat,
--view raw preserves the old heartbeat.
Each actor tagged, each roster known —
The bunny normalized it, all on its own! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: normalize vc meeting events contract' directly and concisely describes the main change: normalizing the contract for vc meeting events to be bot-only with improved output formatting.
Description check ✅ Passed The description includes a summary section, lists main changes, and documents validation steps. However, it deviates from the template by using a 'Validation' section instead of 'Test Plan', and omits a proper 'Changes' section with bullet points and the 'Related Issues' section.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch features/F-vc-meeting-events-contract

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@f61d6b4cd31514e1bf2f3951642a2d9a484c370d

🧩 Skill update

npx skills add larksuite/cli#features/F-vc-meeting-events-contract -y -g

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@shortcuts/vc/vc_meeting_events_test.go`:
- Around line 637-648: The test for VCMeetingEvents.Validate at line 637 needs
to add typed Problem metadata assertions per test guidelines. After the existing
Param field assertion using errors.As for *errs.ValidationError, also call
errs.ProblemOf(err) on the validation error and assert the typed metadata fields
(at least Category and Subtype) to ensure comprehensive error-path testing while
maintaining the Param check via errors.As since ProblemOf does not expose it.

In `@shortcuts/vc/vc_meeting_events.go`:
- Around line 121-124: The error handling in the botInfo declaration is
incorrectly wrapping the network failure from runtime.BotInfo() as a validation
error using errs.NewValidationError with errs.SubtypeInvalidArgument. Replace
this with the appropriate network error type, use .WithCause(err) to preserve
the full error chain instead of flattening it with %v formatting, and remove the
.WithParam("--as") call since the flag itself was valid and the actual failure
was the remote fetch.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 45162c13-5801-4152-ad24-35ea3ac02dff

📥 Commits

Reviewing files that changed from the base of the PR and between 736b131 and 1cdb506.

📒 Files selected for processing (5)
  • shortcuts/vc/vc_meeting_events.go
  • shortcuts/vc/vc_meeting_events_test.go
  • skills/lark-vc-agent/SKILL.md
  • skills/lark-vc-agent/references/lark-vc-agent-meeting-events.md
  • skills/lark-vc-agent/references/lark-vc-agent-meeting-list-active.md

Comment thread shortcuts/vc/vc_meeting_events_test.go Outdated
Comment on lines +637 to +648
err := VCMeetingEvents.Validate(context.Background(), runtime)
if err == nil {
t.Fatal("expected validation error for raw pretty")
}
var ve *errs.ValidationError
if !errors.As(err, &ve) {
t.Fatalf("expected *errs.ValidationError, got %T: %v", err, err)
}
if ve.Param != "--view" {
t.Errorf("Param = %q, want %q", ve.Param, "--view")
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add typed Problem assertions for this error-path test.

At Line 637, this test only checks *errs.ValidationError and Param. Per test guidelines, also assert typed metadata from errs.ProblemOf(err) (at least Category/Subtype), while keeping Param assertion via errors.As since ProblemOf does not expose Param.

Suggested assertion update
 err := VCMeetingEvents.Validate(context.Background(), runtime)
 if err == nil {
 	t.Fatal("expected validation error for raw pretty")
 }
+prob, ok := errs.ProblemOf(err)
+if !ok {
+	t.Fatalf("expected typed problem, got %T: %v", err, err)
+}
+if prob.Category != errs.CategoryValidation {
+	t.Errorf("Category = %q, want %q", prob.Category, errs.CategoryValidation)
+}
+if prob.Subtype != errs.SubtypeInvalidArgument {
+	t.Errorf("Subtype = %q, want %q", prob.Subtype, errs.SubtypeInvalidArgument)
+}
 var ve *errs.ValidationError
 if !errors.As(err, &ve) {
 	t.Fatalf("expected *errs.ValidationError, got %T: %v", err, err)
 }
 if ve.Param != "--view" {
 	t.Errorf("Param = %q, want %q", ve.Param, "--view")
 }

As per coding guidelines, error-path tests should assert typed metadata via errs.ProblemOf, and based on learnings Param should be checked via errors.As(*errs.ValidationError).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
err := VCMeetingEvents.Validate(context.Background(), runtime)
if err == nil {
t.Fatal("expected validation error for raw pretty")
}
var ve *errs.ValidationError
if !errors.As(err, &ve) {
t.Fatalf("expected *errs.ValidationError, got %T: %v", err, err)
}
if ve.Param != "--view" {
t.Errorf("Param = %q, want %q", ve.Param, "--view")
}
}
err := VCMeetingEvents.Validate(context.Background(), runtime)
if err == nil {
t.Fatal("expected validation error for raw pretty")
}
prob, ok := errs.ProblemOf(err)
if !ok {
t.Fatalf("expected typed problem, got %T: %v", err, err)
}
if prob.Category != errs.CategoryValidation {
t.Errorf("Category = %q, want %q", prob.Category, errs.CategoryValidation)
}
if prob.Subtype != errs.SubtypeInvalidArgument {
t.Errorf("Subtype = %q, want %q", prob.Subtype, errs.SubtypeInvalidArgument)
}
var ve *errs.ValidationError
if !errors.As(err, &ve) {
t.Fatalf("expected *errs.ValidationError, got %T: %v", err, err)
}
if ve.Param != "--view" {
t.Errorf("Param = %q, want %q", ve.Param, "--view")
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/vc/vc_meeting_events_test.go` around lines 637 - 648, The test for
VCMeetingEvents.Validate at line 637 needs to add typed Problem metadata
assertions per test guidelines. After the existing Param field assertion using
errors.As for *errs.ValidationError, also call errs.ProblemOf(err) on the
validation error and assert the typed metadata fields (at least Category and
Subtype) to ensure comprehensive error-path testing while maintaining the Param
check via errors.As since ProblemOf does not expose it.

Sources: Coding guidelines, Learnings

Comment thread shortcuts/vc/vc_meeting_events.go Outdated
Comment on lines 121 to 124
botInfo, err := runtime.BotInfo()
if err != nil {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "fetch bot identity for compact meeting-events output: %v", err).WithParam("--as")
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Locate BotInfo() and its error origin
rg -nP --type=go -C6 'func \([^)]*\) BotInfo\(\)' shortcuts/common/
rg -nP --type=go -C4 'botInfoFunc\s*=' shortcuts/common/

Repository: larksuite/cli

Length of output: 3083


🏁 Script executed:

# Find and examine the fetchBotInfo function to see what error it returns
rg -nP --type=go -A15 'func \([^)]*\) fetchBotInfo\(\)' shortcuts/common/

Repository: larksuite/cli

Length of output: 1281


🏁 Script executed:

# Also check the actual code at the target file and lines
sed -n '115,130p' shortcuts/vc/vc_meeting_events.go

Repository: larksuite/cli

Length of output: 789


Wrap bot-identity fetch failure as a network error, not a validation error.

runtime.BotInfo() performs a network call to /bot/v3/info and returns raw errors (from fetchBotInfo(), which uses bare fmt.Errorf). Wrapping any failure as errs.NewValidationError(errs.SubtypeInvalidArgument, ...) mislabels transport/auth failures as argument problems. Three issues:

  • A raw lower-layer error gets incorrectly classified as a validation error instead of a network failure.
  • %v flattens the error, so .WithCause is missing and errors.Is/errors.Unwrap no longer work.
  • .WithParam("--as") names a flag that didn't fail; the user's --as bot input was valid — the remote fetch failed.

Fix by wrapping as a network error and preserving the underlying cause:

 	botInfo, err := runtime.BotInfo()
 	if err != nil {
-		return errs.NewValidationError(errs.SubtypeInvalidArgument, "fetch bot identity for compact meeting-events output: %v", err).WithParam("--as")
+		return errs.NewNetworkError(errs.SubtypeNetworkTransport, "fetch bot identity for compact meeting-events output").
+		    WithCause(err).
+		    WithHint("retry, or verify the bot token/permissions for /bot/v3/info")
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
botInfo, err := runtime.BotInfo()
if err != nil {
return errs.NewValidationError(errs.SubtypeInvalidArgument, "fetch bot identity for compact meeting-events output: %v", err).WithParam("--as")
}
botInfo, err := runtime.BotInfo()
if err != nil {
return errs.NewNetworkError(errs.SubtypeNetworkTransport, "fetch bot identity for compact meeting-events output").
WithCause(err).
WithHint("retry, or verify the bot token/permissions for /bot/v3/info")
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/vc/vc_meeting_events.go` around lines 121 - 124, The error handling
in the botInfo declaration is incorrectly wrapping the network failure from
runtime.BotInfo() as a validation error using errs.NewValidationError with
errs.SubtypeInvalidArgument. Replace this with the appropriate network error
type, use .WithCause(err) to preserve the full error chain instead of flattening
it with %v formatting, and remove the .WithParam("--as") call since the flag
itself was valid and the actual failure was the remote fetch.

Source: Coding guidelines

Ren1104 added 4 commits June 23, 2026 17:12
Source-Branch: features/F-vc-meeting-events-contract
Source-Commit: 1cdb506
Source-Subject: fix: normalize vc meeting events contract
Repo: larksuite-cli
Synced-By: bytedance
Timestamp: 20260623_091211Z
Source-Branch: features/F-vc-meeting-events-contract
Source-Commit: f57b62c
Source-Subject: fix: stabilize meeting events validation examples
Repo: larksuite-cli
Synced-By: bytedance
Timestamp: 20260623_091922Z
Source-Branch: features/F-vc-meeting-events-contract
Source-Commit: d29e99a
Source-Subject: fix: keep meeting events examples deterministic
Repo: larksuite-cli
Synced-By: bytedance
Timestamp: 20260623_092620Z
Source-Branch: features/F-vc-meeting-events-contract
Source-Commit: 79cbc83
Source-Subject: fix: align meeting events pagination test
Repo: larksuite-cli
Synced-By: bytedance
Timestamp: 20260623_093249Z
@codecov

codecov Bot commented Jun 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.13765% with 54 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.08%. Comparing base (736b131) to head (f61d6b4).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
shortcuts/vc/vc_meeting_events.go 78.13% 34 Missing and 20 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1544      +/-   ##
==========================================
+ Coverage   73.97%   74.08%   +0.11%     
==========================================
  Files         787      787              
  Lines       76293    76591     +298     
==========================================
+ Hits        56436    56741     +305     
+ Misses      15625    15582      -43     
- Partials     4232     4268      +36     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown

PR Quality Summary

CI did not complete successfully. Use the failed check links below to decide whether this PR needs a code change or a rerun.

Failed checks

  • deterministic-gate — failure — details
  • results — failure — details

deterministic-gate

  • example_dry_runskills/lark-vc-agent/SKILL.md:128 — example dry-run exited with code 2: { "ok": false, "identity": "user", "error": { "type": "validation", "subtype": "invalid_argument", "message": "--meeting-id must be a positive integer, got \"meeting_test123\"", "param": "--meeting-id" } } — Action: update the example so it can run locally with --dry-run, or mark placeholders explicitly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain/vc PR touches the vc domain size/L Large or sensitive change across domains or core paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant