@openclaw/google-meet 2026.7.2-beta.7 → 2026.8.1-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,38 +1,72 @@
1
- import { n as hasCreateSpaceConfigInput, r as resolveCreateSpaceConfig } from "./create-af1MDlus.js";
2
- import { a as buildGoogleMeetCalendarDayWindow, i as resolveGoogleMeetGatewayOperationTimeoutMs, o as findGoogleMeetCalendarEvent, s as listGoogleMeetCalendarEvents } from "./config-BcaS1BDr.js";
3
- import { _ as endGoogleMeetActiveConference, g as createGoogleMeetSpace, h as fetchGoogleMeetAttendance, m as fetchGoogleMeetArtifacts, p as buildGoogleMeetPreflightReport, v as fetchGoogleMeetSpace, y as fetchLatestGoogleMeetConferenceRecord } from "./chrome-create-DMKruRFW.js";
4
- import { buildGoogleMeetAuthUrl, createGoogleMeetOAuthState, createGoogleMeetPkce, exchangeGoogleMeetAuthCode, resolveGoogleMeetAccessToken, waitForGoogleMeetAuthCode } from "./oauth-DOfMKlGp.js";
5
- import { callGatewayFromCli } from "openclaw/plugin-sdk/gateway-runtime";
1
+ import { a as resolveGoogleMeetTokenFromParams, c as buildGoogleMeetPreflightReport, d as fetchGoogleMeetSpace, f as fetchLatestGoogleMeetConferenceRecord, i as resolveArtifactQueryFromParams, l as createGoogleMeetSpace, m as listGoogleMeetCalendarEvents, n as fetchResolvedGoogleMeetAttendance, o as resolveMeetingFromParams, p as buildGoogleMeetCalendarDayWindow, s as resolveSpaceFromParams, t as fetchResolvedGoogleMeetArtifacts, u as endGoogleMeetActiveConference } from "./plugin-helpers-C9-Y0Ago.js";
2
+ import { i as resolveGoogleMeetGatewayOperationTimeoutMs } from "./config-wBK8loBb.js";
3
+ import { buildGoogleMeetAuthUrl, exchangeGoogleMeetAuthCode, resolveGoogleMeetAccessToken, waitForGoogleMeetAuthCode } from "./oauth-9sUJ68Mw.js";
4
+ import { n as hasCreateSpaceConfigInput, r as resolveCreateSpaceConfig } from "./create-BEDHM6uL.js";
6
5
  import { clampTimerTimeoutMs, parseStrictNonNegativeInteger, parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
7
- import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
6
+ import { callGatewayFromCli, isGatewayClientRequestError, isGatewayTransportError } from "openclaw/plugin-sdk/gateway-runtime";
7
+ import { generateHexPkceVerifierChallenge } from "openclaw/plugin-sdk/provider-auth";
8
+ import { generateOAuthState } from "openclaw/plugin-sdk/provider-auth-runtime";
9
+ import fsp, { stat } from "node:fs/promises";
8
10
  import path from "node:path";
9
- import { mkdir, writeFile } from "node:fs/promises";
10
11
  import JSZip from "jszip";
12
+ import { replaceFileAtomic, writeExternalFileWithinRoot } from "openclaw/plugin-sdk/security-runtime";
11
13
  import { createInterface } from "node:readline/promises";
12
14
  import { format } from "node:util";
13
- import prettyMilliseconds from "pretty-ms";
15
+ import { formatDurationCompact } from "openclaw/plugin-sdk/time-runtime";
16
+ //#region extensions/google-meet/src/cli-command-context.ts
17
+ function addGoogleMeetOAuthOptions(command) {
18
+ return command.option("--access-token <token>", "Access token override").option("--refresh-token <token>", "Refresh token override").option("--client-id <id>", "OAuth client id override").option("--client-secret <secret>", "OAuth client secret override").option("--expires-at <ms>", "Cached access token expiry as unix epoch milliseconds");
19
+ }
20
+ function addGoogleMeetMeetingOption(command) {
21
+ return command.option("--meeting <value>", "Meet URL, meeting code, or spaces/{id}");
22
+ }
23
+ function addGoogleMeetCalendarOptions(command) {
24
+ return command.option("--today", "Find a Meet link on today's calendar").option("--event <query>", "Find a matching calendar event with a Meet link").option("--calendar <id>", "Calendar id for --today or --event", "primary");
25
+ }
26
+ function addGoogleMeetArtifactOptions(command) {
27
+ return addGoogleMeetOAuthOptions(addGoogleMeetCalendarOptions(addGoogleMeetMeetingOption(command).option("--conference-record <name>", "Conference record name or id"))).option("--page-size <n>", "Max resources per Meet API page").option("--all-conference-records", "Fetch every conference record for --meeting");
28
+ }
29
+ //#endregion
14
30
  //#region extensions/google-meet/src/cli-shared.ts
15
- const testing = {
16
- parsePositiveNumber,
17
- resolveGoogleMeetGatewayOperationTimeoutMs,
18
- resolveGoogleMeetGatewayTimeoutMs,
19
- resolveGoogleMeetOAuthCallbackTimeoutMs
20
- };
21
31
  const GOOGLE_MEET_GATEWAY_DEFAULT_TIMEOUT_MS = 5e3;
22
32
  const PLAIN_DECIMAL_NUMBER_RE = /^\d+(?:\.\d+)?$/;
33
+ function parseGoogleMeetMode(value) {
34
+ if (value === void 0 || value === "agent" || value === "bidi" || value === "transcribe" || value === "realtime") return value;
35
+ throw new Error(`mode must be agent, bidi, transcribe, or realtime; received ${value}`);
36
+ }
37
+ function parseGoogleMeetTransport(value) {
38
+ if (value === void 0 || value === "chrome" || value === "chrome-node" || value === "twilio") return value;
39
+ throw new Error(`transport must be chrome, chrome-node, or twilio; received ${value}`);
40
+ }
41
+ function parseGoogleMeetBrowserTransport(value) {
42
+ const transport = parseGoogleMeetTransport(value);
43
+ if (transport === "twilio") throw new Error(`transport must be chrome or chrome-node; received ${value}`);
44
+ return transport;
45
+ }
23
46
  function writeStdoutJson(value) {
24
47
  process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
25
48
  }
26
49
  function isGatewayUnavailableForLocalFallback(err, method) {
27
- const message = formatErrorMessage(err);
28
- return message.includes("ECONNREFUSED") || message.includes("ECONNRESET") || message.includes("EHOSTUNREACH") || message.includes("ENOTFOUND") || message.includes("gateway not connected") || message.includes(`unknown method: ${method}`);
50
+ if (isGatewayTransportError(err)) return err.kind === "closed" && err.code === void 0;
51
+ return isGatewayClientRequestError(err) && err.message.includes(`unknown method: ${method}`);
29
52
  }
30
53
  function writeStdoutLine(...values) {
31
54
  process.stdout.write(`${format(...values)}\n`);
32
55
  }
33
56
  async function writeCliOutput(options, text) {
34
57
  if (options.output?.trim()) {
35
- await writeFile(options.output, text.endsWith("\n") ? text : `${text}\n`, "utf8");
58
+ const dirMode = (await stat(path.dirname(options.output))).mode & 4095;
59
+ await replaceFileAtomic({
60
+ filePath: options.output,
61
+ content: text.endsWith("\n") ? text : `${text}\n`,
62
+ dirMode,
63
+ mode: 438 & ~process.umask(),
64
+ preserveExistingMode: true,
65
+ tempPrefix: ".google-meet-output",
66
+ syncTempFile: true,
67
+ syncParentDir: true,
68
+ throwOnCleanupError: true
69
+ });
36
70
  writeStdoutLine("wrote: %s", options.output);
37
71
  return;
38
72
  }
@@ -105,7 +139,10 @@ async function callGoogleMeetGateway(params) {
105
139
  }
106
140
  function formatDuration(value) {
107
141
  if (value === void 0) return "n/a";
108
- return prettyMilliseconds(Math.max(0, Math.round(value / 1e3) * 1e3), { unitCount: 2 });
142
+ return formatDurationCompact(Math.max(0, Math.round(value / 1e3) * 1e3), {
143
+ showYears: true,
144
+ spaced: true
145
+ }) ?? "0ms";
109
146
  }
110
147
  function writeDoctorStatus(status) {
111
148
  if (!status.found) {
@@ -199,7 +236,6 @@ function writeRecoverCurrentTabResult(result) {
199
236
  toolPolicy: "safe-read-only"
200
237
  },
201
238
  chrome: {
202
- audioBackend: "blackhole-2ch",
203
239
  launched: true,
204
240
  nodeId: result.nodeId,
205
241
  health: result.browser
@@ -543,10 +579,25 @@ function googleMeetExportFileNames() {
543
579
  function defaultExportDirectory() {
544
580
  return `google-meet-export-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
545
581
  }
582
+ async function publishMeetExportFile(outputPath, content) {
583
+ const absolutePath = path.resolve(outputPath);
584
+ await writeExternalFileWithinRoot({
585
+ rootDir: path.dirname(absolutePath),
586
+ path: path.basename(absolutePath),
587
+ write: async (tempPath) => {
588
+ await fsp.writeFile(tempPath, content);
589
+ }
590
+ });
591
+ }
546
592
  async function writeMeetExportBundle(params) {
547
593
  const outputDir = params.outputDir?.trim() || defaultExportDirectory();
548
- await mkdir(outputDir, { recursive: true });
549
- const zipFile = params.zip ? `${outputDir.replace(/\/$/, "")}.zip` : void 0;
594
+ await fsp.mkdir(outputDir, { recursive: true });
595
+ let zipOutputDir = outputDir;
596
+ if (params.zip) {
597
+ const resolvedOutputDir = path.resolve(outputDir);
598
+ if (resolvedOutputDir !== path.parse(resolvedOutputDir).root) zipOutputDir = outputDir.replace(path.sep === "\\" ? /[\\/]+$/ : /\/+$/, "");
599
+ }
600
+ const zipFile = params.zip ? `${zipOutputDir.replace(/\/$/, "")}.zip` : void 0;
550
601
  const fileNames = googleMeetExportFileNames();
551
602
  const files = [
552
603
  {
@@ -582,7 +633,7 @@ async function writeMeetExportBundle(params) {
582
633
  }), null, 2)}\n`
583
634
  }
584
635
  ];
585
- for (const file of files) await writeFile(path.join(outputDir, file.name), file.content, "utf8");
636
+ for (const file of files) await publishMeetExportFile(path.join(outputDir, file.name), file.content);
586
637
  const result = {
587
638
  outputDir,
588
639
  files: files.map((file) => path.join(outputDir, file.name))
@@ -590,38 +641,31 @@ async function writeMeetExportBundle(params) {
590
641
  if (zipFile) {
591
642
  const zip = new JSZip();
592
643
  for (const file of files) zip.file(file.name, file.content);
593
- await writeFile(zipFile, await zip.generateAsync({ type: "nodebuffer" }));
644
+ await publishMeetExportFile(zipFile, await zip.generateAsync({ type: "nodebuffer" }));
594
645
  result.zipFile = zipFile;
595
646
  }
596
647
  return result;
597
648
  }
598
649
  //#endregion
599
650
  //#region extensions/google-meet/src/cli-artifact-commands.ts
651
+ async function resolveCliArtifactQuery(context, options) {
652
+ const { lateAfterMinutes, earlyBeforeMinutes, ...raw } = context.resolveCliArtifactParams(options);
653
+ return {
654
+ ...await resolveArtifactQueryFromParams(context.config, raw),
655
+ lateAfterMinutes,
656
+ earlyBeforeMinutes
657
+ };
658
+ }
600
659
  function registerGoogleMeetArtifactCommands(context) {
601
660
  const params = context;
602
- const { root, resolveArtifactTokenOptions, resolveMeetingForToken } = context;
603
- root.command("artifacts").description("List Meet conference records and available participant/artifact metadata").option("--meeting <value>", "Meet URL, meeting code, or spaces/{id}").option("--conference-record <name>", "Conference record name or id").option("--today", "Find a Meet link on today's calendar").option("--event <query>", "Find a matching calendar event with a Meet link").option("--calendar <id>", "Calendar id for --today or --event", "primary").option("--access-token <token>", "Access token override").option("--refresh-token <token>", "Refresh token override").option("--client-id <id>", "OAuth client id override").option("--client-secret <secret>", "OAuth client secret override").option("--expires-at <ms>", "Cached access token expiry as unix epoch milliseconds").option("--page-size <n>", "Max resources per Meet API page").option("--all-conference-records", "Fetch every conference record for --meeting").option("--no-transcript-entries", "Skip structured transcript entry lookup").option("--include-doc-bodies", "Export linked transcript and smart-note Google Docs text").option("--format <format>", "Output format: summary or markdown", "summary").option("--output <path>", "Write output to a file instead of stdout").option("--json", "Print JSON output", false).action(async (options) => {
604
- const resolved = resolveArtifactTokenOptions(params.config, options);
605
- const token = await resolveGoogleMeetAccessToken(resolved);
606
- const meeting = resolved.conferenceRecord ? resolved.meeting : (await resolveMeetingForToken({
607
- config: params.config,
608
- options,
609
- accessToken: token.accessToken,
610
- configuredMeeting: resolved.meeting
611
- })).meeting;
612
- const result = await fetchGoogleMeetArtifacts({
613
- accessToken: token.accessToken,
614
- meeting,
615
- conferenceRecord: resolved.conferenceRecord,
616
- pageSize: resolved.pageSize,
617
- includeTranscriptEntries: resolved.includeTranscriptEntries,
618
- allConferenceRecords: resolved.allConferenceRecords,
619
- includeDocumentBodies: resolved.includeDocumentBodies
620
- });
661
+ const { root } = context;
662
+ addGoogleMeetArtifactOptions(root.command("artifacts").description("List Meet conference records and available participant/artifact metadata")).option("--no-transcript-entries", "Skip structured transcript entry lookup").option("--include-doc-bodies", "Export linked transcript and smart-note Google Docs text").option("--format <format>", "Output format: summary or markdown", "summary").option("--output <path>", "Write output to a file instead of stdout").option("--json", "Print JSON output", false).action(async (options) => {
663
+ const resolved = await resolveCliArtifactQuery(params, options);
664
+ const result = await fetchResolvedGoogleMeetArtifacts(resolved);
621
665
  if (options.json) {
622
666
  await writeCliOutput(options, JSON.stringify({
623
667
  ...result,
624
- tokenSource: token.refreshed ? "refresh-token" : "cached-access-token"
668
+ tokenSource: resolved.token.refreshed ? "refresh-token" : "cached-access-token"
625
669
  }, null, 2));
626
670
  return;
627
671
  }
@@ -631,31 +675,15 @@ function registerGoogleMeetArtifactCommands(context) {
631
675
  }
632
676
  if (options.format && options.format !== "summary") throw new Error("Unsupported format. Expected summary or markdown.");
633
677
  writeArtifactsSummary(result);
634
- writeStdoutLine("token source: %s", token.refreshed ? "refresh-token" : "cached-access-token");
678
+ writeStdoutLine("token source: %s", resolved.token.refreshed ? "refresh-token" : "cached-access-token");
635
679
  });
636
- root.command("attendance").description("List Meet participants and participant sessions").option("--meeting <value>", "Meet URL, meeting code, or spaces/{id}").option("--conference-record <name>", "Conference record name or id").option("--today", "Find a Meet link on today's calendar").option("--event <query>", "Find a matching calendar event with a Meet link").option("--calendar <id>", "Calendar id for --today or --event", "primary").option("--access-token <token>", "Access token override").option("--refresh-token <token>", "Refresh token override").option("--client-id <id>", "OAuth client id override").option("--client-secret <secret>", "OAuth client secret override").option("--expires-at <ms>", "Cached access token expiry as unix epoch milliseconds").option("--page-size <n>", "Max resources per Meet API page").option("--all-conference-records", "Fetch every conference record for --meeting").option("--no-merge-duplicates", "Keep duplicate participant resources as separate rows").option("--late-after-minutes <n>", "Mark participants late after this many minutes", "5").option("--early-before-minutes <n>", "Mark early leavers before this many minutes", "5").option("--format <format>", "Output format: summary, markdown, or csv", "summary").option("--output <path>", "Write output to a file instead of stdout").option("--json", "Print JSON output", false).action(async (options) => {
637
- const resolved = resolveArtifactTokenOptions(params.config, options);
638
- const token = await resolveGoogleMeetAccessToken(resolved);
639
- const meeting = resolved.conferenceRecord ? resolved.meeting : (await resolveMeetingForToken({
640
- config: params.config,
641
- options,
642
- accessToken: token.accessToken,
643
- configuredMeeting: resolved.meeting
644
- })).meeting;
645
- const result = await fetchGoogleMeetAttendance({
646
- accessToken: token.accessToken,
647
- meeting,
648
- conferenceRecord: resolved.conferenceRecord,
649
- pageSize: resolved.pageSize,
650
- allConferenceRecords: resolved.allConferenceRecords,
651
- mergeDuplicateParticipants: resolved.mergeDuplicateParticipants,
652
- lateAfterMinutes: resolved.lateAfterMinutes,
653
- earlyBeforeMinutes: resolved.earlyBeforeMinutes
654
- });
680
+ addGoogleMeetArtifactOptions(root.command("attendance").description("List Meet participants and participant sessions")).option("--no-merge-duplicates", "Keep duplicate participant resources as separate rows").option("--late-after-minutes <n>", "Mark participants late after this many minutes", "5").option("--early-before-minutes <n>", "Mark early leavers before this many minutes", "5").option("--format <format>", "Output format: summary, markdown, or csv", "summary").option("--output <path>", "Write output to a file instead of stdout").option("--json", "Print JSON output", false).action(async (options) => {
681
+ const resolved = await resolveCliArtifactQuery(params, options);
682
+ const result = await fetchResolvedGoogleMeetAttendance(resolved);
655
683
  if (options.json) {
656
684
  await writeCliOutput(options, JSON.stringify({
657
685
  ...result,
658
- tokenSource: token.refreshed ? "refresh-token" : "cached-access-token"
686
+ tokenSource: resolved.token.refreshed ? "refresh-token" : "cached-access-token"
659
687
  }, null, 2));
660
688
  return;
661
689
  }
@@ -669,42 +697,17 @@ function registerGoogleMeetArtifactCommands(context) {
669
697
  }
670
698
  if (options.format && options.format !== "summary") throw new Error("Unsupported format. Expected summary, markdown, or csv.");
671
699
  writeAttendanceSummary(result);
672
- writeStdoutLine("token source: %s", token.refreshed ? "refresh-token" : "cached-access-token");
700
+ writeStdoutLine("token source: %s", resolved.token.refreshed ? "refresh-token" : "cached-access-token");
673
701
  });
674
- root.command("export").description("Write Meet artifacts, attendance, transcript, and raw JSON into a folder").option("--meeting <value>", "Meet URL, meeting code, or spaces/{id}").option("--conference-record <name>", "Conference record name or id").option("--today", "Find a Meet link on today's calendar").option("--event <query>", "Find a matching calendar event with a Meet link").option("--calendar <id>", "Calendar id for --today or --event", "primary").option("--access-token <token>", "Access token override").option("--refresh-token <token>", "Refresh token override").option("--client-id <id>", "OAuth client id override").option("--client-secret <secret>", "OAuth client secret override").option("--expires-at <ms>", "Cached access token expiry as unix epoch milliseconds").option("--page-size <n>", "Max resources per Meet API page").option("--all-conference-records", "Fetch every conference record for --meeting").option("--no-transcript-entries", "Skip structured transcript entry lookup").option("--include-doc-bodies", "Export linked transcript and smart-note Google Docs text").option("--no-merge-duplicates", "Keep duplicate participant resources as separate rows").option("--late-after-minutes <n>", "Mark participants late after this many minutes", "5").option("--early-before-minutes <n>", "Mark early leavers before this many minutes", "5").option("--output <dir>", "Output directory").option("--zip", "Also write a portable .zip archive").option("--dry-run", "Fetch export data and print the manifest without writing files", false).option("--json", "Print JSON output", false).action(async (options) => {
675
- const resolved = resolveArtifactTokenOptions(params.config, options);
676
- const token = await resolveGoogleMeetAccessToken(resolved);
677
- const meetingResult = resolved.conferenceRecord ? { meeting: resolved.meeting } : await resolveMeetingForToken({
678
- config: params.config,
679
- options,
680
- accessToken: token.accessToken,
681
- configuredMeeting: resolved.meeting
682
- });
683
- const artifacts = await fetchGoogleMeetArtifacts({
684
- accessToken: token.accessToken,
685
- meeting: meetingResult.meeting,
686
- conferenceRecord: resolved.conferenceRecord,
687
- pageSize: resolved.pageSize,
688
- includeTranscriptEntries: resolved.includeTranscriptEntries,
689
- allConferenceRecords: resolved.allConferenceRecords,
690
- includeDocumentBodies: resolved.includeDocumentBodies
691
- });
692
- const attendance = await fetchGoogleMeetAttendance({
693
- accessToken: token.accessToken,
694
- meeting: meetingResult.meeting,
695
- conferenceRecord: resolved.conferenceRecord,
696
- pageSize: resolved.pageSize,
697
- allConferenceRecords: resolved.allConferenceRecords,
698
- mergeDuplicateParticipants: resolved.mergeDuplicateParticipants,
699
- lateAfterMinutes: resolved.lateAfterMinutes,
700
- earlyBeforeMinutes: resolved.earlyBeforeMinutes
701
- });
702
- const resolvedMeeting = meetingResult.meeting ?? resolved.meeting;
702
+ addGoogleMeetArtifactOptions(root.command("export").description("Write Meet artifacts, attendance, transcript, and raw JSON into a folder")).option("--no-transcript-entries", "Skip structured transcript entry lookup").option("--include-doc-bodies", "Export linked transcript and smart-note Google Docs text").option("--no-merge-duplicates", "Keep duplicate participant resources as separate rows").option("--late-after-minutes <n>", "Mark participants late after this many minutes", "5").option("--early-before-minutes <n>", "Mark early leavers before this many minutes", "5").option("--output <dir>", "Output directory").option("--zip", "Also write a portable .zip archive").option("--dry-run", "Fetch export data and print the manifest without writing files", false).option("--json", "Print JSON output", false).action(async (options) => {
703
+ const resolved = await resolveCliArtifactQuery(params, options);
704
+ const artifacts = await fetchResolvedGoogleMeetArtifacts(resolved);
705
+ const attendance = await fetchResolvedGoogleMeetAttendance(resolved);
703
706
  const request = {
704
- ...resolvedMeeting ? { meeting: resolvedMeeting } : {},
707
+ ...resolved.meeting ? { meeting: resolved.meeting } : {},
705
708
  ...resolved.conferenceRecord ? { conferenceRecord: resolved.conferenceRecord } : {},
706
- ...meetingResult.calendarEvent?.event.id ? { calendarEventId: meetingResult.calendarEvent.event.id } : {},
707
- ...meetingResult.calendarEvent?.event.summary ? { calendarEventSummary: meetingResult.calendarEvent.event.summary } : {},
709
+ ...resolved.calendarEvent?.event.id ? { calendarEventId: resolved.calendarEvent.event.id } : {},
710
+ ...resolved.calendarEvent?.event.summary ? { calendarEventSummary: resolved.calendarEvent.event.summary } : {},
708
711
  ...options.calendar ? { calendarId: options.calendar } : {},
709
712
  ...resolved.pageSize !== void 0 ? { pageSize: resolved.pageSize } : {},
710
713
  includeTranscriptEntries: resolved.includeTranscriptEntries,
@@ -722,11 +725,11 @@ function registerGoogleMeetArtifactCommands(context) {
722
725
  attendance,
723
726
  files: googleMeetExportFileNames(),
724
727
  request,
725
- tokenSource: token.refreshed ? "refresh-token" : "cached-access-token",
726
- ...meetingResult.calendarEvent ? { calendarEvent: meetingResult.calendarEvent } : {}
728
+ tokenSource: resolved.token.refreshed ? "refresh-token" : "cached-access-token",
729
+ ...resolved.calendarEvent ? { calendarEvent: resolved.calendarEvent } : {}
727
730
  }),
728
- ...meetingResult.calendarEvent ? { calendarEvent: meetingResult.calendarEvent } : {},
729
- tokenSource: token.refreshed ? "refresh-token" : "cached-access-token"
731
+ ...resolved.calendarEvent ? { calendarEvent: resolved.calendarEvent } : {},
732
+ tokenSource: resolved.token.refreshed ? "refresh-token" : "cached-access-token"
730
733
  });
731
734
  return;
732
735
  }
@@ -736,13 +739,13 @@ function registerGoogleMeetArtifactCommands(context) {
736
739
  attendance,
737
740
  zip: Boolean(options.zip),
738
741
  request,
739
- tokenSource: token.refreshed ? "refresh-token" : "cached-access-token",
740
- ...meetingResult.calendarEvent ? { calendarEvent: meetingResult.calendarEvent } : {}
742
+ tokenSource: resolved.token.refreshed ? "refresh-token" : "cached-access-token",
743
+ ...resolved.calendarEvent ? { calendarEvent: resolved.calendarEvent } : {}
741
744
  });
742
745
  const payload = {
743
746
  ...bundle,
744
- ...meetingResult.calendarEvent ? { calendarEvent: meetingResult.calendarEvent } : {},
745
- tokenSource: token.refreshed ? "refresh-token" : "cached-access-token"
747
+ ...resolved.calendarEvent ? { calendarEvent: resolved.calendarEvent } : {},
748
+ tokenSource: resolved.token.refreshed ? "refresh-token" : "cached-access-token"
746
749
  };
747
750
  if (options.json) {
748
751
  writeStdoutJson(payload);
@@ -904,8 +907,8 @@ function registerGoogleMeetProbeCommands(context) {
904
907
  root.command("join").argument("[url]", "Explicit https://meet.google.com/... URL").option("--transport <transport>", "Transport: chrome, chrome-node, or twilio").option("--mode <mode>", "Mode: agent, bidi, or transcribe").option("--message <text>", "Realtime speech to trigger after join").option("--dial-in-number <phone>", "Meet dial-in number for Twilio transport").option("--pin <pin>", "Meet phone PIN; # is appended if omitted").option("--dtmf-sequence <sequence>", "Explicit Twilio DTMF sequence").action(async (url, options) => {
905
908
  const payload = {
906
909
  url: resolveMeetingInput(params.config, url),
907
- transport: options.transport,
908
- mode: options.mode,
910
+ transport: parseGoogleMeetTransport(options.transport),
911
+ mode: parseGoogleMeetMode(options.mode),
909
912
  message: options.message,
910
913
  dialInNumber: options.dialInNumber,
911
914
  pin: options.pin,
@@ -927,8 +930,8 @@ function registerGoogleMeetProbeCommands(context) {
927
930
  root.command("test-speech").argument("[url]", "Explicit https://meet.google.com/... URL").option("--transport <transport>", "Transport: chrome, chrome-node, or twilio").option("--mode <mode>", "Mode: agent, bidi, or transcribe").option("--message <text>", "Realtime speech to trigger", "Say exactly: Google Meet speech test complete.").action(async (url, options) => {
928
931
  const payload = {
929
932
  url: resolveMeetingInput(params.config, url),
930
- transport: options.transport,
931
- mode: options.mode,
933
+ transport: parseGoogleMeetTransport(options.transport),
934
+ mode: parseGoogleMeetMode(options.mode),
932
935
  message: options.message
933
936
  };
934
937
  const delegated = await callGoogleMeetGateway({
@@ -946,7 +949,7 @@ function registerGoogleMeetProbeCommands(context) {
946
949
  root.command("test-listen").argument("[url]", "Explicit https://meet.google.com/... URL").option("--transport <transport>", "Transport: chrome or chrome-node").option("--timeout-ms <ms>", "How long to wait for fresh captions/transcript movement").action(async (url, options) => {
947
950
  const payload = {
948
951
  url: resolveMeetingInput(params.config, url),
949
- transport: options.transport,
952
+ transport: parseGoogleMeetBrowserTransport(options.transport),
950
953
  timeoutMs: parsePositiveNumber(options.timeoutMs, "timeout-ms")
951
954
  };
952
955
  const delegated = await callGoogleMeetGateway({
@@ -1006,7 +1009,7 @@ function registerGoogleMeetLifecycleCommands(context) {
1006
1009
  root.command("recover-tab").description("Focus and inspect an existing Google Meet tab").argument("[url]", "Optional Meet URL to match").option("--transport <transport>", "Transport to inspect: chrome or chrome-node").option("--json", "Print JSON output", false).action(async (url, options) => {
1007
1010
  const result = await (await params.ensureRuntime()).recoverCurrentTab({
1008
1011
  url,
1009
- transport: options.transport
1012
+ transport: parseGoogleMeetBrowserTransport(options.transport)
1010
1013
  });
1011
1014
  if (options.json) {
1012
1015
  writeStdoutJson(result);
@@ -1016,14 +1019,16 @@ function registerGoogleMeetLifecycleCommands(context) {
1016
1019
  });
1017
1020
  root.command("setup").description("Show Google Meet transport setup status").option("--transport <transport>", "Transport to check: chrome, chrome-node, or twilio").option("--mode <mode>", "Mode to check: agent, bidi, or transcribe").option("--json", "Print JSON output", false).action(async (options) => {
1018
1021
  const status = await (await params.ensureRuntime()).setupStatus({
1019
- transport: options.transport,
1020
- mode: options.mode
1022
+ transport: parseGoogleMeetTransport(options.transport),
1023
+ mode: parseGoogleMeetMode(options.mode)
1021
1024
  });
1022
1025
  if (options.json) {
1023
1026
  writeStdoutJson(status);
1027
+ if (!status.ok) process.exitCode = 1;
1024
1028
  return;
1025
1029
  }
1026
1030
  writeSetupStatus(status);
1031
+ if (!status.ok) process.exitCode = 1;
1027
1032
  });
1028
1033
  root.command("leave").argument("<session-id>", "Meet session ID").action(async (sessionId) => {
1029
1034
  const delegated = await callGoogleMeetGateway({
@@ -1065,10 +1070,24 @@ function registerGoogleMeetLifecycleCommands(context) {
1065
1070
  }
1066
1071
  //#endregion
1067
1072
  //#region extensions/google-meet/src/cli-space-commands.ts
1073
+ function writeGoogleMeetCreateOutput(payload, json) {
1074
+ if (json) {
1075
+ writeStdoutJson(payload);
1076
+ return;
1077
+ }
1078
+ writeStdoutLine("meeting uri: %s", payload.meetingUri);
1079
+ if (payload.space?.name) writeStdoutLine("space: %s", payload.space.name);
1080
+ if (payload.space?.meetingCode) writeStdoutLine("meeting code: %s", payload.space.meetingCode);
1081
+ if (payload.source) writeStdoutLine("source: %s", payload.source);
1082
+ if (payload.browser?.nodeId) writeStdoutLine("node: %s", payload.browser.nodeId);
1083
+ if (payload.tokenSource) writeStdoutLine("token source: %s", payload.tokenSource);
1084
+ const joinedSessionId = payload.joined ? payload.join?.session?.id : void 0;
1085
+ writeStdoutLine(joinedSessionId ? "joined: %s" : "joined: no (run `openclaw googlemeet join %s`)", joinedSessionId ?? payload.meetingUri);
1086
+ }
1068
1087
  function registerGoogleMeetCreateCommands(context) {
1069
1088
  const params = context;
1070
- const { root, callGateway, operationTimeoutMs, hasCreateOAuth, resolveMeetingInput, resolveOAuthTokenOptions } = context;
1071
- root.command("create").description("Create a new Google Meet space and print its meeting URL").option("--access-token <token>", "Access token override").option("--refresh-token <token>", "Refresh token override").option("--client-id <id>", "OAuth client id override").option("--client-secret <secret>", "OAuth client secret override").option("--expires-at <ms>", "Cached access token expiry as unix epoch milliseconds").option("--access-type <type>", "Google Meet SpaceConfig accessType for API create: OPEN, TRUSTED, or RESTRICTED").option("--entry-point-access <type>", "Google Meet SpaceConfig entryPointAccess for API create: ALL or CREATOR_APP_ONLY").option("--no-join", "Only create the meeting URL; do not join it").option("--transport <transport>", "Join transport: chrome, chrome-node, or twilio").option("--mode <mode>", "Join mode: agent, bidi, or transcribe").option("--message <text>", "Realtime speech to trigger after join").option("--dial-in-number <phone>", "Meet dial-in number for Twilio transport").option("--pin <pin>", "Meet phone PIN; # is appended if omitted").option("--dtmf-sequence <sequence>", "Explicit Twilio DTMF sequence").option("--json", "Print JSON output", false).action(async (options) => {
1089
+ const { root, callGateway, operationTimeoutMs, hasCreateOAuth, resolveMeetingInput, resolveCliParams } = context;
1090
+ addGoogleMeetOAuthOptions(root.command("create").description("Create a new Google Meet space and print its meeting URL")).option("--access-type <type>", "Google Meet SpaceConfig accessType for API create: OPEN, TRUSTED, or RESTRICTED").option("--entry-point-access <type>", "Google Meet SpaceConfig entryPointAccess for API create: ALL or CREATOR_APP_ONLY").option("--no-join", "Only create the meeting URL; do not join it").option("--transport <transport>", "Join transport: chrome, chrome-node, or twilio").option("--mode <mode>", "Join mode: agent, bidi, or transcribe").option("--message <text>", "Realtime speech to trigger after join").option("--dial-in-number <phone>", "Meet dial-in number for Twilio transport").option("--pin <pin>", "Meet phone PIN; # is appended if omitted").option("--dtmf-sequence <sequence>", "Explicit Twilio DTMF sequence").option("--json", "Print JSON output", false).action(async (options) => {
1072
1091
  if (options.join !== false) {
1073
1092
  const delegated = await callGoogleMeetGateway({
1074
1093
  callGateway,
@@ -1078,18 +1097,7 @@ function registerGoogleMeetCreateCommands(context) {
1078
1097
  });
1079
1098
  if (delegated.ok) {
1080
1099
  const payload = delegated.payload;
1081
- if (options.json) {
1082
- writeStdoutJson(payload);
1083
- return;
1084
- }
1085
- writeStdoutLine("meeting uri: %s", payload.meetingUri);
1086
- if (payload.space?.name) writeStdoutLine("space: %s", payload.space.name);
1087
- if (payload.space?.meetingCode) writeStdoutLine("meeting code: %s", payload.space.meetingCode);
1088
- if (payload.source) writeStdoutLine("source: %s", payload.source);
1089
- if (payload.browser?.nodeId) writeStdoutLine("node: %s", payload.browser.nodeId);
1090
- if (payload.tokenSource) writeStdoutLine("token source: %s", payload.tokenSource);
1091
- if (payload.joined && payload.join?.session?.id) writeStdoutLine("joined: %s", payload.join.session.id);
1092
- else writeStdoutLine("joined: no (run `openclaw googlemeet join %s`)", payload.meetingUri);
1100
+ writeGoogleMeetCreateOutput(payload, options.json);
1093
1101
  return;
1094
1102
  }
1095
1103
  }
@@ -1099,14 +1107,14 @@ function registerGoogleMeetCreateCommands(context) {
1099
1107
  const result = await rt.createViaBrowser();
1100
1108
  const join = options.join !== false ? await rt.join({
1101
1109
  url: result.meetingUri,
1102
- transport: options.transport,
1103
- mode: options.mode,
1110
+ transport: parseGoogleMeetTransport(options.transport),
1111
+ mode: parseGoogleMeetMode(options.mode),
1104
1112
  message: options.message,
1105
1113
  dialInNumber: options.dialInNumber,
1106
1114
  pin: options.pin,
1107
1115
  dtmfSequence: options.dtmfSequence
1108
1116
  }) : void 0;
1109
- const payload = {
1117
+ writeGoogleMeetCreateOutput({
1110
1118
  source: result.source,
1111
1119
  meetingUri: result.meetingUri,
1112
1120
  joined: Boolean(join),
@@ -1117,50 +1125,32 @@ function registerGoogleMeetCreateCommands(context) {
1117
1125
  browserUrl: result.browserUrl,
1118
1126
  browserTitle: result.browserTitle
1119
1127
  }
1120
- };
1121
- if (options.json) {
1122
- writeStdoutJson(payload);
1123
- return;
1124
- }
1125
- writeStdoutLine("meeting uri: %s", result.meetingUri);
1126
- writeStdoutLine("source: browser");
1127
- writeStdoutLine("node: %s", result.nodeId);
1128
- if (join) writeStdoutLine("joined: %s", join.session.id);
1129
- else writeStdoutLine("joined: no (run `openclaw googlemeet join %s`)", result.meetingUri);
1128
+ }, options.json);
1130
1129
  return;
1131
1130
  }
1132
- const token = await resolveGoogleMeetAccessToken(resolveOAuthTokenOptions(params.config, options));
1131
+ const token = await resolveGoogleMeetTokenFromParams(params.config, resolveCliParams(options));
1133
1132
  const result = await createGoogleMeetSpace({
1134
1133
  accessToken: token.accessToken,
1135
1134
  config: resolveCreateSpaceConfig(options)
1136
1135
  });
1137
1136
  const join = options.join !== false ? await (await params.ensureRuntime()).join({
1138
1137
  url: result.meetingUri,
1139
- transport: options.transport,
1140
- mode: options.mode,
1138
+ transport: parseGoogleMeetTransport(options.transport),
1139
+ mode: parseGoogleMeetMode(options.mode),
1141
1140
  message: options.message,
1142
1141
  dialInNumber: options.dialInNumber,
1143
1142
  pin: options.pin,
1144
1143
  dtmfSequence: options.dtmfSequence
1145
1144
  }) : void 0;
1146
- if (options.json) {
1147
- writeStdoutJson({
1148
- ...result,
1149
- tokenSource: token.refreshed ? "refresh-token" : "cached-access-token",
1150
- joined: Boolean(join),
1151
- ...join ? { join } : {}
1152
- });
1153
- return;
1154
- }
1155
- writeStdoutLine("meeting uri: %s", result.meetingUri);
1156
- writeStdoutLine("space: %s", result.space.name);
1157
- if (result.space.meetingCode) writeStdoutLine("meeting code: %s", result.space.meetingCode);
1158
- writeStdoutLine("token source: %s", token.refreshed ? "refresh-token" : "cached-access-token");
1159
- if (join) writeStdoutLine("joined: %s", join.session.id);
1160
- else writeStdoutLine("joined: no (run `openclaw googlemeet join %s`)", result.meetingUri);
1145
+ writeGoogleMeetCreateOutput({
1146
+ ...result,
1147
+ tokenSource: token.refreshed ? "refresh-token" : "cached-access-token",
1148
+ joined: Boolean(join),
1149
+ ...join ? { join } : {}
1150
+ }, options.json);
1161
1151
  });
1162
- root.command("end-active-conference").description("End the active conference for a Google Meet space").argument("[meeting]", "Meet URL, meeting code, or spaces/{id}").option("--access-token <token>", "Access token override").option("--refresh-token <token>", "Refresh token override").option("--client-id <id>", "OAuth client id override").option("--client-secret <secret>", "OAuth client secret override").option("--expires-at <ms>", "Cached access token expiry as unix epoch milliseconds").option("--json", "Print JSON output", false).action(async (meeting, options) => {
1163
- const token = await resolveGoogleMeetAccessToken(resolveOAuthTokenOptions(params.config, options));
1152
+ addGoogleMeetOAuthOptions(root.command("end-active-conference").description("End the active conference for a Google Meet space").argument("[meeting]", "Meet URL, meeting code, or spaces/{id}")).option("--json", "Print JSON output", false).action(async (meeting, options) => {
1153
+ const token = await resolveGoogleMeetTokenFromParams(params.config, resolveCliParams(options));
1164
1154
  const result = await endGoogleMeetActiveConference({
1165
1155
  accessToken: token.accessToken,
1166
1156
  meeting: resolveMeetingInput(params.config, meeting ?? options.meeting)
@@ -1179,34 +1169,32 @@ function registerGoogleMeetCreateCommands(context) {
1179
1169
  }
1180
1170
  function registerGoogleMeetApiCommands(context) {
1181
1171
  const params = context;
1182
- const { root, resolveMeetingForToken, resolveOAuthTokenOptions, resolveTokenOptions } = context;
1183
- root.command("resolve-space").description("Resolve a Meet URL, meeting code, or spaces/{id} to its canonical space").option("--meeting <value>", "Meet URL, meeting code, or spaces/{id}").option("--access-token <token>", "Access token override").option("--refresh-token <token>", "Refresh token override").option("--client-id <id>", "OAuth client id override").option("--client-secret <secret>", "OAuth client secret override").option("--expires-at <ms>", "Cached access token expiry as unix epoch milliseconds").option("--json", "Print JSON output", false).action(async (options) => {
1184
- const resolved = resolveTokenOptions(params.config, options);
1185
- const token = await resolveGoogleMeetAccessToken(resolved);
1186
- const space = await fetchGoogleMeetSpace({
1187
- accessToken: token.accessToken,
1188
- meeting: resolved.meeting
1172
+ const { root, resolveCliParams, resolveMeetingInput } = context;
1173
+ addGoogleMeetOAuthOptions(addGoogleMeetMeetingOption(root.command("resolve-space").description("Resolve a Meet URL, meeting code, or spaces/{id} to its canonical space"))).option("--json", "Print JSON output", false).action(async (options) => {
1174
+ const meeting = resolveMeetingInput(params.config, options.meeting);
1175
+ const { space, token } = await resolveSpaceFromParams(params.config, {
1176
+ ...resolveCliParams(options),
1177
+ meeting
1189
1178
  });
1190
1179
  if (options.json) {
1191
1180
  writeStdoutJson(space);
1192
1181
  return;
1193
1182
  }
1194
- writeStdoutLine("input: %s", resolved.meeting);
1183
+ writeStdoutLine("input: %s", meeting);
1195
1184
  writeStdoutLine("space: %s", space.name);
1196
1185
  if (space.meetingCode) writeStdoutLine("meeting code: %s", space.meetingCode);
1197
1186
  if (space.meetingUri) writeStdoutLine("meeting uri: %s", space.meetingUri);
1198
1187
  writeStdoutLine("active conference: %s", space.activeConference ? "yes" : "no");
1199
1188
  writeStdoutLine("token source: %s", token.refreshed ? "refresh-token" : "cached-access-token");
1200
1189
  });
1201
- root.command("preflight").description("Validate OAuth + meeting resolution prerequisites for Meet media work").option("--meeting <value>", "Meet URL, meeting code, or spaces/{id}").option("--access-token <token>", "Access token override").option("--refresh-token <token>", "Refresh token override").option("--client-id <id>", "OAuth client id override").option("--client-secret <secret>", "OAuth client secret override").option("--expires-at <ms>", "Cached access token expiry as unix epoch milliseconds").option("--json", "Print JSON output", false).action(async (options) => {
1202
- const resolved = resolveTokenOptions(params.config, options);
1203
- const token = await resolveGoogleMeetAccessToken(resolved);
1204
- const space = await fetchGoogleMeetSpace({
1205
- accessToken: token.accessToken,
1206
- meeting: resolved.meeting
1190
+ addGoogleMeetOAuthOptions(addGoogleMeetMeetingOption(root.command("preflight").description("Validate OAuth + meeting resolution prerequisites for Meet media work"))).option("--json", "Print JSON output", false).action(async (options) => {
1191
+ const meeting = resolveMeetingInput(params.config, options.meeting);
1192
+ const { space, token } = await resolveSpaceFromParams(params.config, {
1193
+ ...resolveCliParams(options),
1194
+ meeting
1207
1195
  });
1208
1196
  const report = buildGoogleMeetPreflightReport({
1209
- input: resolved.meeting,
1197
+ input: meeting,
1210
1198
  space,
1211
1199
  previewAcknowledged: params.config.preview.enrollmentAcknowledged,
1212
1200
  tokenSource: token.refreshed ? "refresh-token" : "cached-access-token"
@@ -1229,13 +1217,18 @@ function registerGoogleMeetApiCommands(context) {
1229
1217
  writeStdoutLine("blockers:");
1230
1218
  for (const blocker of report.blockers) writeStdoutLine("- %s", blocker);
1231
1219
  });
1232
- root.command("latest").description("Find the latest Meet conference record for a meeting").option("--meeting <value>", "Meet URL, meeting code, or spaces/{id}").option("--today", "Find a Meet link on today's calendar").option("--event <query>", "Find a matching calendar event with a Meet link").option("--calendar <id>", "Calendar id for --today or --event", "primary").option("--access-token <token>", "Access token override").option("--refresh-token <token>", "Refresh token override").option("--client-id <id>", "OAuth client id override").option("--client-secret <secret>", "OAuth client secret override").option("--expires-at <ms>", "Cached access token expiry as unix epoch milliseconds").option("--json", "Print JSON output", false).action(async (options) => {
1233
- const token = await resolveGoogleMeetAccessToken(resolveOAuthTokenOptions(params.config, options));
1234
- const resolved = await resolveMeetingForToken({
1220
+ addGoogleMeetOAuthOptions(addGoogleMeetCalendarOptions(addGoogleMeetMeetingOption(root.command("latest").description("Find the latest Meet conference record for a meeting")))).option("--json", "Print JSON output", false).action(async (options) => {
1221
+ const raw = resolveCliParams(options);
1222
+ const token = await resolveGoogleMeetTokenFromParams(params.config, raw);
1223
+ if (!options.today && !options.event?.trim()) {
1224
+ const meeting = options.meeting?.trim() || params.config.defaults.meeting;
1225
+ if (!meeting) throw new Error("Meeting input is required. Pass --meeting, --today, --event, or configure defaults.meeting.");
1226
+ raw.meeting = meeting;
1227
+ }
1228
+ const resolved = await resolveMeetingFromParams({
1235
1229
  config: params.config,
1236
- options,
1237
- accessToken: token.accessToken,
1238
- configuredMeeting: options.meeting?.trim()
1230
+ raw,
1231
+ accessToken: token.accessToken
1239
1232
  });
1240
1233
  const result = await fetchLatestGoogleMeetConferenceRecord({
1241
1234
  accessToken: token.accessToken,
@@ -1257,7 +1250,7 @@ function registerGoogleMeetApiCommands(context) {
1257
1250
  writeStdoutLine("token source: %s", token.refreshed ? "refresh-token" : "cached-access-token");
1258
1251
  });
1259
1252
  root.command("calendar-events").description("Preview Calendar events with Google Meet links").option("--today", "Find Meet links on today's calendar").option("--event <query>", "Find matching calendar events with Meet links").option("--calendar <id>", "Calendar id for lookup", "primary").option("--access-token <token>", "Access token override").option("--refresh-token <token>", "Refresh token override").option("--client-id <id>", "OAuth client id override").option("--client-secret <secret>", "OAuth client secret override").option("--expires-at <ms>", "Cached access token expiry as unix epoch milliseconds").option("--json", "Print JSON output", false).action(async (options) => {
1260
- const token = await resolveGoogleMeetAccessToken(resolveOAuthTokenOptions(params.config, options));
1253
+ const token = await resolveGoogleMeetTokenFromParams(params.config, resolveCliParams(options));
1261
1254
  const window = options.today ? buildGoogleMeetCalendarDayWindow() : {};
1262
1255
  const result = await listGoogleMeetCalendarEvents({
1263
1256
  accessToken: token.accessToken,
@@ -1284,67 +1277,30 @@ function resolveMeetingInput(config, value) {
1284
1277
  if (!meeting) throw new Error("Meeting input is required. Pass a URL/meeting code or configure defaults.meeting.");
1285
1278
  return meeting;
1286
1279
  }
1287
- function resolveOAuthTokenOptions(config, options) {
1288
- return {
1289
- clientId: options.clientId?.trim() || config.oauth.clientId,
1290
- clientSecret: options.clientSecret?.trim() || config.oauth.clientSecret,
1291
- refreshToken: options.refreshToken?.trim() || config.oauth.refreshToken,
1292
- accessToken: options.accessToken?.trim() || config.oauth.accessToken,
1293
- expiresAt: parseOptionalNumber(options.expiresAt) ?? config.oauth.expiresAt
1294
- };
1295
- }
1296
- function resolveTokenOptions(config, options) {
1297
- return {
1298
- meeting: resolveMeetingInput(config, options.meeting),
1299
- ...resolveOAuthTokenOptions(config, options)
1300
- };
1301
- }
1302
1280
  function hasCalendarLookupOptions(options) {
1303
1281
  return Boolean(options.today || options.event?.trim());
1304
1282
  }
1305
- async function resolveCalendarMeetingInput(params) {
1306
- if (!hasCalendarLookupOptions(params.options)) return {};
1307
- const window = params.options.today ? buildGoogleMeetCalendarDayWindow() : {};
1308
- const calendarEvent = await findGoogleMeetCalendarEvent({
1309
- accessToken: params.accessToken,
1310
- calendarId: params.options.calendar,
1311
- eventQuery: params.options.event,
1312
- ...window
1313
- });
1283
+ function resolveCliParams(options) {
1284
+ const { calendar, expiresAt, ...raw } = options;
1314
1285
  return {
1315
- meeting: calendarEvent.meetingUri,
1316
- calendarEvent
1286
+ ...raw,
1287
+ calendarId: calendar,
1288
+ expiresAt: parseOptionalNumber(expiresAt)
1317
1289
  };
1318
1290
  }
1319
- async function resolveMeetingForToken(params) {
1320
- const calendarMeeting = await resolveCalendarMeetingInput({
1321
- accessToken: params.accessToken,
1322
- options: params.options
1323
- });
1324
- const meeting = calendarMeeting.meeting ?? params.configuredMeeting ?? params.config.defaults.meeting;
1325
- if (!meeting) throw new Error("Meeting input is required. Pass --meeting, --today, --event, or configure defaults.meeting.");
1326
- return calendarMeeting.calendarEvent ? {
1327
- meeting,
1328
- calendarEvent: calendarMeeting.calendarEvent
1329
- } : { meeting };
1330
- }
1331
- function resolveArtifactTokenOptions(config, options) {
1291
+ function resolveCliArtifactParams(config, options) {
1332
1292
  const meeting = options.meeting?.trim() || config.defaults.meeting;
1333
1293
  const conferenceRecord = options.conferenceRecord?.trim();
1334
1294
  if (!meeting && !conferenceRecord && !hasCalendarLookupOptions(options)) throw new Error("Meeting input or conference record is required. Pass --meeting, --today, --event, --conference-record, or configure defaults.meeting.");
1335
1295
  return {
1296
+ ...resolveCliParams(options),
1336
1297
  meeting,
1337
1298
  conferenceRecord,
1338
- clientId: options.clientId?.trim() || config.oauth.clientId,
1339
- clientSecret: options.clientSecret?.trim() || config.oauth.clientSecret,
1340
- refreshToken: options.refreshToken?.trim() || config.oauth.refreshToken,
1341
- accessToken: options.accessToken?.trim() || config.oauth.accessToken,
1342
- expiresAt: parseOptionalNumber(options.expiresAt) ?? config.oauth.expiresAt,
1343
1299
  pageSize: parsePositiveIntegerOption(options.pageSize, "page-size"),
1344
- includeTranscriptEntries: options.transcriptEntries !== false,
1345
- allConferenceRecords: Boolean(options.allConferenceRecords),
1346
- includeDocumentBodies: Boolean(options.includeDocBodies),
1347
- mergeDuplicateParticipants: options.mergeDuplicates !== false,
1300
+ includeTranscriptEntries: options.transcriptEntries,
1301
+ includeAllConferenceRecords: options.allConferenceRecords,
1302
+ includeDocumentBodies: options.includeDocBodies,
1303
+ mergeDuplicateParticipants: options.mergeDuplicates,
1348
1304
  lateAfterMinutes: parseOptionalNumber(options.lateAfterMinutes),
1349
1305
  earlyBeforeMinutes: parseOptionalNumber(options.earlyBeforeMinutes)
1350
1306
  };
@@ -1360,8 +1316,8 @@ function registerGoogleMeetCli(params) {
1360
1316
  const clientId = options.clientId?.trim() || params.config.oauth.clientId;
1361
1317
  const clientSecret = options.clientSecret?.trim() || params.config.oauth.clientSecret;
1362
1318
  if (!clientId) throw new Error("Missing Google Meet OAuth client id. Configure oauth.clientId or pass --client-id.");
1363
- const { verifier, challenge } = createGoogleMeetPkce();
1364
- const state = createGoogleMeetOAuthState();
1319
+ const { verifier, challenge } = generateHexPkceVerifierChallenge();
1320
+ const state = generateOAuthState();
1365
1321
  const authUrl = buildGoogleMeetAuthUrl({
1366
1322
  clientId,
1367
1323
  challenge,
@@ -1402,10 +1358,8 @@ function registerGoogleMeetCli(params) {
1402
1358
  callGateway,
1403
1359
  operationTimeoutMs,
1404
1360
  resolveMeetingInput,
1405
- resolveOAuthTokenOptions,
1406
- resolveTokenOptions,
1407
- resolveMeetingForToken,
1408
- resolveArtifactTokenOptions,
1361
+ resolveCliParams,
1362
+ resolveCliArtifactParams: (options) => resolveCliArtifactParams(params.config, options),
1409
1363
  hasCreateOAuth
1410
1364
  };
1411
1365
  registerGoogleMeetCreateCommands(context);
@@ -1417,4 +1371,4 @@ function registerGoogleMeetCli(params) {
1417
1371
  registerGoogleMeetLifecycleCommands(context);
1418
1372
  }
1419
1373
  //#endregion
1420
- export { buildGoogleMeetExportManifest, googleMeetExportFileNames, registerGoogleMeetCli, testing, writeMeetExportBundle };
1374
+ export { buildGoogleMeetExportManifest, googleMeetExportFileNames, registerGoogleMeetCli, writeMeetExportBundle };