Skip to content

v1.0.15

Latest

Choose a tag to compare

@WeMeeting WeMeeting released this 07 Aug 13:47

[v1.0.15] - 2026-08-07

Added

  • New control waiting-room subcommand (cmd/control/waiting_room.go, internal/cmdutil/api_schema.go, internal/utils/enumerate/waiting_room_operate_type.go): Manage waiting room members in an ongoing meeting. Backed by PUT /v1/real-control/meetings/{meeting_id}/waiting-room and wired through WithApiCmd(ApiCmdControlWaitingRoom). Classified as a write operation and listed in the SKILL dangerous-operations table.
    • --meeting-id (required) — Meeting ID.
    • --operate-type (required) — One of enter-meeting (admit into meeting) / back-to-waiting (move back to waiting room) / expel (expel from waiting room). Uses the new reusable cmdutil.EnumValue cobra flag type for client-side validation.
    • --allow-rejoin (optional, --operate-type=expel only) — Whether expelled members are allowed to rejoin. Only sent to the server when the flag is explicitly changed by the user.
    • --users / --sip-users / --pstn-users (at least one required) — Map respectively to regular members' open_id, SIP devices' ms_open_id (instanceid=9), and PSTN devices' ms_open_id (instanceid=0). Total across all three capped at MeetingControlUsersListMax = 20, reusing PackageMeetingControlUsers / PackageMeetingControlSpecialUsers. The kick-target source hard rule from v1.0.8 applies here as well: user identifiers must come from report participants.
    • --operate-type is converted from the CLI string to the downstream API's uint32 enum via the new WaitingRoomOperateTypeValue lookup, backed by the WaitingRoomOperateType enum and its bidirectional name/value map.
  • New report participants-export subcommand (cmd/report/participants_export.go, internal/cmdutil/api_schema.go): Export meeting participants list as an async task. Backed by POST /v1/meetings/export-participants-list and wired through WithApiCmd(ApiCmdReportParticipantsExport).
    • --meeting-id (required) — Meeting ID.
    • --sub-meeting-id (optional) — Sub-meeting ID for recurring meetings.
    • --start / --end (optional) — ISO 8601 window bounds, each converted to a unix timestamp via utils.ISO8601ToTimeStamp before being sent to the server.
    • --file-type (default xlsx) — Export format: xlsx or json; validated client-side.
  • New report job-result subcommand (cmd/report/job_result.go, internal/cmdutil/api_schema.go, internal/utils/enumerate/export_job_status.go): Query the result of an async export task. Backed by GET /v1/export/{job_id} and wired through WithApiCmd(ApiCmdReportJobResult).
    • --job-id (required) — Task ID returned by report participants-export.
    • The response status field is post-processed with the new ExportJobStatusConverter, mapping integer status codes (1=成功 / 2=失败 / 3=处理中) to Chinese display names via the ExportJobStatus int enum.
  • Meeting list enriched with recording basic info (cmd/meeting/record_enrich.go): meeting get, meeting list, meeting list-ended, and meeting search now automatically enrich each meeting object with records_total_count and a records array (recording subject, duration, start time, state, type) by calling the recording APIs after the meeting query completes. The enrichment is best-effort — on any failure the original data is returned unchanged so meeting output is never blocked.
    • meeting get uses the paginated GET /v1/mcp/records/meet-basic-info-list API (capped at maxFullRecordPages = 2 × fullRecordPageSize = 100 = 200 records max) to fetch the full recording snapshot.
    • meeting list / meeting list-ended / meeting search use the batched POST /v1/mcp/records/meet-basic-info API for a lightweight preview.
    • normalizeRecords() inlines state_int / type_int → human-readable state / type string renaming and drops the _int fields, so the output never leaks raw integer codes.
    • Under --compact, the client-side injected records / records_total_count fields are preserved via compactFieldsWithRecords(), which merges recordEnrichmentFields into the remote schema whitelist — the remote schema does not know about these fields since they are injected client-side.
  • New reusable EnumValue cobra flag type (internal/cmdutil/enum.go): A pflag.Value implementation that validates the flag input against a predefined allowlist at parse time, returning a clear InvalidArgsError listing the allowed values when the input is unrecognized. Used by control waiting-room's --operate-type and available for future enum-constrained flags.
  • New DurationSecondsConverter (internal/utils/converter.go): Seconds-based counterpart of the existing HHMMSSConverter (which expects milliseconds). Converts float64 or string second values to HH:MM:SS / MM:SS format. Applied to the duration field in recording objects enriched into meeting output.
  • New ExportJobStatus int enum and ExportJobStatusConverter (internal/utils/enumerate/export_job_status.go, internal/utils/converter.go): Maps export job status IDs to Chinese display names; wired into report job-result output at path status.
  • New WaitingRoomOperateType enum (internal/utils/enumerate/waiting_room_operate_type.go): Defines the three waiting room operations (enter-meeting=1 / back-to-waiting=2 / expel=3) with a bidirectional name↔value map; WaitingRoomOperateTypeName for display and WaitingRoomOperateTypeValue for CLI-to-API conversion.
  • New ApiCmd constants (internal/cmdutil/api_schema.go): ApiCmdReportParticipantsExport, ApiCmdReportJobResult, ApiCmdControlWaitingRoom — so the new commands plug into the --compact and middleware pipeline.

Changed

  • Windows DPAPI keychain now self-heals on unrecoverable master-key failure (internal/core/keychain/keychain_windows.go): When the DPAPI master key becomes permanently unusable (e.g. Windows password force-reset by an administrator, account type switched between local/Microsoft account, Windows Hello/PIN rebuilt, system restored to a pre-credential state), the keychain now detects the condition via the new isDPAPIKeyInvalid() helper — classifying NTE_BAD_KEY_STATE, ERROR_INVALID_DATA, and NTE_BAD_DATA as "permanently dead" — and auto-purges every registry value under the keychain path via purgeStaleRegistryEntries(), then returns ErrNotFound. The upper layer transparently generates a fresh master key on the next login, so the user is simply prompted to re-login instead of being permanently stuck on a "Key not valid for use in specified state" error. Only unambiguous "key permanently unusable" errors trigger self-healing; transient failures (permission denied, EDR interception, DLL not loaded) are surfaced as-is and do not wipe recoverable ciphertext.
  • Windows keychain Remove now cascade-deletes master key on last logout (internal/core/keychain/keychain_windows.go): When removing the last remaining credential (only master_key left in the registry), the master key is now automatically deleted as well. This prevents a leftover undecryptable zombie master key from permanently blocking the next login after a future DPAPI credential change. Regenerating a master key on the next login is cheap (<10ms) and avoids a hard-to-diagnose failure mode. Multi-account scenarios (other business ciphertexts still present) are unaffected — master key is only deleted when it is the sole remaining value.
  • Base64DecodeConverter hardened against non-Base64 and non-UTF-8 input (internal/utils/converter.go): The converter now validates that the decoded output is valid UTF-8 before returning it (prevents garbled output when a field happens to look like Base64 by coincidence). The fallback path switched from URLEncoding (with padding) to RawURLEncoding (no padding), matching the encoding used by some backends. Empty string inputs now short-circuit without a decode attempt.
  • Record state enum descriptions now carry actionable hints (internal/utils/enumerate/record_state.go): RecordStateRecording录制中,不可查看或申请, RecordStateTranscoding转码中,不可查看或申请, RecordStateDone转码完成,可根据录制文件权限进行下一步. These descriptions are surfaced in the meeting recording enrichment output so the user immediately knows whether a recording is actionable.
  • Build script now hardens binary permissions with self-check (build.sh): After compilation, all non-.exe binaries are automatically chmod-ed to 0755, and a mandatory -x check follows — if any binary lacks the executable bit, the build fails with a clear error. This prevents broken releases caused by umask anomalies, post-processing steps, or publishing environments that strip the x bit.
  • npm wrapper tmeet.js now uses a three-layer executable fallback (scripts/tmeet.js): (1) accessSync(X_OK) probe — if the binary is already executable, use it directly (fast path for publish artifacts with baked-in 0755); (2) in-place chmodSync — for conventional environments that permit chmod; (3) copy to os.tmpdir() + chmod — for sandbox/read-only-FS environments where the original path rejects chmod with EROFS/EPERM/EACCES/ENOSYS. A simple size + mtime cache avoids redundant IO on every cold start.
  • WithCompact documentation improved (internal/output/options.go): Now clearly documents that the compact field list is used as-is and that callers with client-side injected fields (e.g. records enrichment) must merge them into the slice beforehand rather than relying on the option to do it.
  • SKILL bumped to 1.0.15 with major structural overhaul (skills/tmeet-skill/SKILL.md, skills/tmeet-skill/references/tmeet-meeting.md, skills/tmeet-skill/references/tmeet-record.md, skills/tmeet-skill/references/tmeet-report.md, skills/tmeet-skill/references/tmeet-control.md, skills/tmeet-skill/references/tmeet-contact.md, skills/tmeet-skill/references/tmeet-tshoot.md):
    • New "命令总览与详情索引" section: A full command tree with clickable Markdown links to every reference doc, replacing the scattered per-module descriptions.
    • New "安全规则" centralized section: Gathers all safety rules from scattered locations into one chapter — dangerous-operation confirmation table (with explicit "wait is hard requirement" anti-pattern table covering self-Q&A, fabricated user instructions, and default-option auto-selection), member-id privacy rule (meeting_id must not be exposed to users), contact-usage gate, kick-target source constraint, multi-result confirmation rule, and missing-parameter prohibition.
    • New "参数规范" section: Consolidates time format, --format, --compact, and pagination rules under a single heading.
    • "查询命令选择准则" relocated and expanded: Now directly below the command tree with an explicit "list vs search" decision table, a recording-query routing pointer to tmeet-record.md, and anti-pattern rules (no keyword-cramming into list, no keyword-as-time confusion, clarify ambiguous input).
    • "核心概念" section removed: The concepts are now covered inline in the respective reference docs.
    • tmeet-report.md updated: Added parameter tables and usage notes for participants-export and job-result, documenting the export→poll-result async workflow.
    • tmeet-control.md updated: Added waiting-room command with parameter table and the three operation-type scenarios.
    • tmeet-meeting.md updated: Documented the 90-day query interval limit for meeting search's --start / --end (server returns 190004 when exceeded; caller must split into ≤90-day windows). Recording enrichment fields (records, records_total_count) documented in meeting output schemas.
    • tmeet-record.md updated: Added "录制查询路由总则" defining the multi-tier routing rules across meeting get/meeting search/meeting list-ended/record list/record search/record transcript-search, plus permission_status permission-judgment guidance.
    • tmeet-contact.md and tmeet-tshoot.md: Refined error-handling guidelines and simplified document structure.

Fixed

  • meeting get recording duration field now uses DurationSecondsConverter (cmd/meeting/get.go): Previously the recording duration field (expressed in seconds by the backend) was mistakenly routed through HHMMSSConverter (which expects milliseconds), producing durations that were 1000× too small. The new DurationSecondsConverter correctly interprets the value as seconds and produces the canonical HH:MM:SS / MM:SS output.