@openclaw/google-meet 2026.9.6 → 2026.9.7
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.
- package/assets/icon.png +0 -0
- package/dist/.setup/{chrome-create-BZRBHJp9.mjs → chrome-create-wuAK5Pnq.mjs} +14 -19
- package/dist/.setup/{cli-CbxqjjTC.mjs → cli-DVDq0TFu.mjs} +27 -695
- package/dist/.setup/cli-export-D4IM6KLJ.mjs +632 -0
- package/dist/.setup/config-BXGAMntj.mjs +240 -0
- package/dist/.setup/{create-CG9Pgwsb.mjs → create-UrHOmnWb.mjs} +4 -17
- package/dist/.setup/{google-meet-platform-adapter-DQZ74Kd5.mjs → google-meet-platform-adapter-gosgbMIM.mjs} +337 -228
- package/dist/.setup/{google-meet-platform-constants-Bs5iAg3E.mjs → google-meet-platform-constants-CnRfrYX7.mjs} +1 -4
- package/dist/.setup/{node-host-BUrsParx.mjs → node-host-Tr7Mx3da.mjs} +3 -3
- package/dist/.setup/{node-invoke-policy-hwXq9MfV.mjs → node-invoke-policy-Dd3krTYV.mjs} +2 -2
- package/dist/.setup/{oauth-22Ey-zCb.mjs → oauth-BoyruWcS.mjs} +2 -2
- package/dist/.setup/{plugin-helpers--7X3icub.mjs → plugin-helpers-CdQ_YNA7.mjs} +147 -236
- package/dist/.setup/{plugin-registration-B3LXKV4R.mjs → plugin-registration-aCEuCerg.mjs} +34 -10
- package/dist/.setup/{runtime-BuIZ5e3V.mjs → runtime-BdiF53A2.mjs} +85 -41
- package/dist/doctor-contract-api.js +3 -6
- package/dist/index.js +48 -12
- package/node_modules/typebox/build/compile/code.mjs +1 -2
- package/node_modules/typebox/build/compile/validator.mjs +5 -1
- package/node_modules/typebox/build/format/iri.mjs +16 -9
- package/node_modules/typebox/build/guard/emit.mjs +2 -2
- package/node_modules/typebox/build/guard/guard.d.mts +7 -5
- package/node_modules/typebox/build/guard/guard.mjs +14 -9
- package/node_modules/typebox/build/guard/index.mjs +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.d.mts +6 -0
- package/node_modules/typebox/build/guard/unicode/unicode.mjs +35 -0
- package/node_modules/typebox/build/guard/{string.mjs → unicode/unicode_segment.mjs} +16 -19
- package/node_modules/typebox/build/schema/build.mjs +2 -3
- package/node_modules/typebox/build/schema/engine/_pathing.d.mts +1 -0
- package/node_modules/typebox/build/schema/engine/_pathing.mjs +11 -0
- package/node_modules/typebox/build/schema/engine/_refine.mjs +13 -5
- package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependencies.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/format.mjs +9 -2
- package/node_modules/typebox/build/schema/engine/patternProperties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/properties.mjs +3 -2
- package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/ref.d.mts +1 -1
- package/node_modules/typebox/build/schema/engine/ref.mjs +2 -2
- package/node_modules/typebox/build/schema/engine/schema.mjs +24 -24
- package/node_modules/typebox/build/schema/parse.mjs +3 -0
- package/node_modules/typebox/build/schema/pointer/pointer.d.mts +1 -6
- package/node_modules/typebox/build/schema/pointer/pointer.mjs +47 -64
- package/node_modules/typebox/build/system/settings/internal.d.mts +2 -0
- package/node_modules/typebox/build/system/settings/internal.mjs +20 -0
- package/node_modules/typebox/build/system/settings/settings.d.mts +11 -0
- package/node_modules/typebox/build/system/settings/settings.mjs +14 -0
- package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
- package/node_modules/typebox/build/type/extends/inference.mjs +15 -2
- package/node_modules/typebox/build/type/extends/tuple.d.mts +2 -1
- package/node_modules/typebox/build/type/extends/tuple.mjs +21 -1
- package/node_modules/typebox/build/value/parse/parse.mjs +10 -4
- package/node_modules/typebox/package.json +1 -1
- package/node_modules/typebox/readme.md +3 -1
- package/package.json +5 -5
- package/dist/.setup/config-C-6enWkx.mjs +0 -328
- package/dist/.setup/google-api-errors-BDYXfKRa.mjs +0 -17
- /package/node_modules/typebox/build/guard/{string.d.mts → unicode/unicode_segment.d.mts} +0 -0
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import { i as resolveGoogleMeetGatewayOperationTimeoutMs } from "./config-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { a as resolveArtifactQueryFromParams, c as resolveSpaceFromParams, d as endGoogleMeetActiveConference, f as fetchGoogleMeetSpace, h as listGoogleMeetCalendarEvents, l as buildGoogleMeetPreflightReport, m as buildGoogleMeetCalendarDayWindow, n as fetchResolvedGoogleMeetArtifacts, o as resolveGoogleMeetTokenFromParams, p as fetchLatestGoogleMeetConferenceRecord, r as fetchResolvedGoogleMeetAttendance, s as resolveMeetingFromParams, t as buildGoogleMeetExportRequest, u as createGoogleMeetSpace } from "./plugin-helpers-CdQ_YNA7.mjs";
|
|
2
|
+
import { i as resolveGoogleMeetGatewayOperationTimeoutMs } from "./config-BXGAMntj.mjs";
|
|
3
|
+
import { C as writeSetupStatus, S as writeRecoverCurrentTabResult, T as writeStdoutLine, _ as promptInput, a as renderAttendanceCsv, b as writeDoctorStatus, c as writeCalendarEventsSummary, d as parseGoogleMeetBrowserTransport, f as parseGoogleMeetMode, g as parsePositiveNumber, h as parsePositiveIntegerOption, i as renderArtifactsSummary, l as writeLatestConferenceRecordSummary, m as parseOptionalNumber, n as exportGoogleMeetBundle, o as renderAttendanceMarkdown, p as parseGoogleMeetTransport, r as renderArtifactsMarkdown, s as renderAttendanceSummary, u as callGoogleMeetGateway, v as resolveGoogleMeetOAuthCallbackTimeoutMs, w as writeStdoutJson, x as writeLeaveResult, y as writeCliOutput } from "./cli-export-D4IM6KLJ.mjs";
|
|
4
|
+
import { buildGoogleMeetAuthUrl, exchangeGoogleMeetAuthCode, resolveGoogleMeetAccessToken, waitForGoogleMeetAuthCode } from "./oauth-BoyruWcS.mjs";
|
|
5
|
+
import { n as hasCreateSpaceConfigInput, r as resolveCreateSpaceConfig } from "./create-UrHOmnWb.mjs";
|
|
6
|
+
import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
7
|
+
import { callGatewayFromCli } from "openclaw/plugin-sdk/gateway-runtime";
|
|
7
8
|
import { generateHexPkceVerifierChallenge } from "openclaw/plugin-sdk/provider-auth";
|
|
8
9
|
import { generateOAuthState } from "openclaw/plugin-sdk/provider-auth-runtime";
|
|
9
|
-
import fsp, { stat } from "node:fs/promises";
|
|
10
|
-
import path from "node:path";
|
|
11
|
-
import JSZip from "jszip";
|
|
12
|
-
import { replaceFileAtomic, writeExternalFileWithinRoot } from "openclaw/plugin-sdk/security-runtime";
|
|
13
|
-
import { createInterface } from "node:readline/promises";
|
|
14
|
-
import { format } from "node:util";
|
|
15
|
-
import { formatDurationCompact } from "openclaw/plugin-sdk/time-runtime";
|
|
16
10
|
//#region extensions/google-meet/src/cli-command-context.ts
|
|
17
11
|
function addGoogleMeetOAuthOptions(command) {
|
|
18
12
|
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");
|
|
@@ -27,631 +21,6 @@ function addGoogleMeetArtifactOptions(command) {
|
|
|
27
21
|
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
22
|
}
|
|
29
23
|
//#endregion
|
|
30
|
-
//#region extensions/google-meet/src/cli-shared.ts
|
|
31
|
-
const GOOGLE_MEET_GATEWAY_DEFAULT_TIMEOUT_MS = 5e3;
|
|
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
|
-
}
|
|
46
|
-
function writeStdoutJson(value) {
|
|
47
|
-
process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
|
|
48
|
-
}
|
|
49
|
-
function isGatewayUnavailableForLocalFallback(err, method) {
|
|
50
|
-
if (isGatewayTransportError(err)) return err.kind === "closed" && err.code === void 0;
|
|
51
|
-
return isGatewayClientRequestError(err) && err.message.includes(`unknown method: ${method}`);
|
|
52
|
-
}
|
|
53
|
-
function writeStdoutLine(...values) {
|
|
54
|
-
process.stdout.write(`${format(...values)}\n`);
|
|
55
|
-
}
|
|
56
|
-
async function writeCliOutput(options, text) {
|
|
57
|
-
if (options.output?.trim()) {
|
|
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
|
-
});
|
|
70
|
-
writeStdoutLine("wrote: %s", options.output);
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
process.stdout.write(text.endsWith("\n") ? text : `${text}\n`);
|
|
74
|
-
}
|
|
75
|
-
async function promptInput(message) {
|
|
76
|
-
const rl = createInterface({
|
|
77
|
-
input: process.stdin,
|
|
78
|
-
output: process.stderr
|
|
79
|
-
});
|
|
80
|
-
try {
|
|
81
|
-
return await rl.question(message);
|
|
82
|
-
} finally {
|
|
83
|
-
rl.close();
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
function parseOptionalNumber(value) {
|
|
87
|
-
if (!value?.trim()) return;
|
|
88
|
-
const trimmed = value.trim();
|
|
89
|
-
const parsed = PLAIN_DECIMAL_NUMBER_RE.test(trimmed) ? Number(trimmed) : NaN;
|
|
90
|
-
if (!Number.isFinite(parsed)) throw new Error(`Expected a numeric value, received ${value}`);
|
|
91
|
-
return parsed;
|
|
92
|
-
}
|
|
93
|
-
function writeSetupStatus(status) {
|
|
94
|
-
writeStdoutLine("Google Meet setup: %s", status.ok ? "OK" : "needs attention");
|
|
95
|
-
for (const check of status.checks) writeStdoutLine("[%s] %s: %s", check.ok ? "ok" : "fail", check.id, check.message);
|
|
96
|
-
}
|
|
97
|
-
function formatBoolean(value) {
|
|
98
|
-
return typeof value === "boolean" ? value ? "yes" : "no" : "unknown";
|
|
99
|
-
}
|
|
100
|
-
function formatOptional(value) {
|
|
101
|
-
return typeof value === "string" && value.trim() ? value : "n/a";
|
|
102
|
-
}
|
|
103
|
-
function parsePositiveNumber(value, label) {
|
|
104
|
-
if (value === void 0) return;
|
|
105
|
-
const trimmed = value.trim();
|
|
106
|
-
const parsed = PLAIN_DECIMAL_NUMBER_RE.test(trimmed) ? Number(trimmed) : NaN;
|
|
107
|
-
if (!Number.isFinite(parsed) || parsed <= 0) throw new Error(`${label} must be a positive number`);
|
|
108
|
-
return parsed;
|
|
109
|
-
}
|
|
110
|
-
function resolveGoogleMeetGatewayTimeoutMs(timeoutMs) {
|
|
111
|
-
return typeof timeoutMs === "number" && Number.isFinite(timeoutMs) ? clampTimerTimeoutMs(Math.ceil(timeoutMs)) ?? 1 : GOOGLE_MEET_GATEWAY_DEFAULT_TIMEOUT_MS;
|
|
112
|
-
}
|
|
113
|
-
function resolveGoogleMeetOAuthCallbackTimeoutMs(timeoutSec) {
|
|
114
|
-
return clampTimerTimeoutMs((parsePositiveNumber(timeoutSec, "timeout-sec") ?? 300) * 1e3) ?? 3e5;
|
|
115
|
-
}
|
|
116
|
-
function parsePositiveIntegerOption(value, label) {
|
|
117
|
-
if (value === void 0) return;
|
|
118
|
-
const parsed = parseStrictPositiveInteger(value);
|
|
119
|
-
if (parsed === void 0) throw new Error(`${label} must be a positive integer`);
|
|
120
|
-
return parsed;
|
|
121
|
-
}
|
|
122
|
-
async function callGoogleMeetGateway(params) {
|
|
123
|
-
try {
|
|
124
|
-
const timeoutMs = resolveGoogleMeetGatewayTimeoutMs(params.timeoutMs);
|
|
125
|
-
return {
|
|
126
|
-
ok: true,
|
|
127
|
-
payload: await params.callGateway(params.method, {
|
|
128
|
-
json: true,
|
|
129
|
-
timeout: String(timeoutMs)
|
|
130
|
-
}, params.payload, { progress: false })
|
|
131
|
-
};
|
|
132
|
-
} catch (err) {
|
|
133
|
-
if (isGatewayUnavailableForLocalFallback(err, params.method)) return {
|
|
134
|
-
ok: false,
|
|
135
|
-
error: err
|
|
136
|
-
};
|
|
137
|
-
throw err;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
function formatDuration(value) {
|
|
141
|
-
if (value === void 0) return "n/a";
|
|
142
|
-
const roundedMs = Math.max(0, Math.round(value / 1e3) * 1e3);
|
|
143
|
-
return formatDurationCompact(roundedMs, {
|
|
144
|
-
showYears: true,
|
|
145
|
-
spaced: true
|
|
146
|
-
}) ?? "0ms";
|
|
147
|
-
}
|
|
148
|
-
function writeDoctorStatus(status) {
|
|
149
|
-
if (!status.found) {
|
|
150
|
-
writeStdoutLine("Google Meet session: not found");
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
const sessions = status.session ? [status.session] : status.sessions ?? [];
|
|
154
|
-
if (sessions.length === 0) {
|
|
155
|
-
writeStdoutLine("Google Meet sessions: none");
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
writeStdoutLine("Google Meet sessions: %d", sessions.length);
|
|
159
|
-
for (const session of sessions) {
|
|
160
|
-
const health = session.chrome?.health;
|
|
161
|
-
writeStdoutLine("");
|
|
162
|
-
writeStdoutLine("session: %s", session.id);
|
|
163
|
-
writeStdoutLine("url: %s", session.url);
|
|
164
|
-
writeStdoutLine("state: %s", session.state);
|
|
165
|
-
writeStdoutLine("transport: %s", session.transport);
|
|
166
|
-
writeStdoutLine("mode: %s", session.mode);
|
|
167
|
-
if (session.twilio) {
|
|
168
|
-
writeStdoutLine("twilio dial-in: %s", session.twilio.dialInNumber);
|
|
169
|
-
writeStdoutLine("voice call id: %s", formatOptional(session.twilio.voiceCallId));
|
|
170
|
-
writeStdoutLine("dtmf sent: %s", formatBoolean(session.twilio.dtmfSent));
|
|
171
|
-
writeStdoutLine("intro sent: %s", formatBoolean(session.twilio.introSent));
|
|
172
|
-
}
|
|
173
|
-
if (!session.chrome) continue;
|
|
174
|
-
writeStdoutLine("node: %s", session.chrome?.nodeId ?? "local/none");
|
|
175
|
-
writeStdoutLine("audio bridge: %s", session.chrome?.audioBridge?.type ?? "none");
|
|
176
|
-
const bridgeProvider = session.chrome?.audioBridge?.provider ?? session.realtime.transcriptionProvider ?? session.realtime.provider ?? "n/a";
|
|
177
|
-
writeStdoutLine(session.mode === "agent" ? "transcription provider: %s" : "provider: %s", bridgeProvider);
|
|
178
|
-
if (session.realtime.enabled) writeStdoutLine("talk-back mode: %s", session.realtime.strategy ?? session.mode);
|
|
179
|
-
writeStdoutLine("in call: %s", formatBoolean(health?.inCall));
|
|
180
|
-
writeStdoutLine("lobby waiting: %s", formatBoolean(health?.lobbyWaiting));
|
|
181
|
-
writeStdoutLine("captioning: %s", formatBoolean(health?.captioning));
|
|
182
|
-
writeStdoutLine("transcript lines: %s", health?.transcriptLines ?? 0);
|
|
183
|
-
writeStdoutLine("last caption: %s", formatOptional(health?.lastCaptionAt));
|
|
184
|
-
writeStdoutLine("manual action: %s", formatBoolean(Boolean(health?.manualAction)));
|
|
185
|
-
if (health?.manualAction) {
|
|
186
|
-
writeStdoutLine("manual reason: %s", formatOptional(health.manualAction.reason));
|
|
187
|
-
writeStdoutLine("manual message: %s", formatOptional(health.manualAction.message));
|
|
188
|
-
}
|
|
189
|
-
writeStdoutLine("speech ready: %s", formatBoolean(health?.speechReady));
|
|
190
|
-
if (health?.speechReady === false) {
|
|
191
|
-
writeStdoutLine("speech blocked reason: %s", formatOptional(health.speechBlockedReason));
|
|
192
|
-
writeStdoutLine("speech blocked message: %s", formatOptional(health.speechBlockedMessage));
|
|
193
|
-
}
|
|
194
|
-
writeStdoutLine("provider connected: %s", formatBoolean(health?.providerConnected));
|
|
195
|
-
writeStdoutLine("realtime ready: %s", formatBoolean(health?.realtimeReady));
|
|
196
|
-
writeStdoutLine("audio input active: %s", formatBoolean(health?.audioInputActive));
|
|
197
|
-
writeStdoutLine("audio output active: %s", formatBoolean(health?.audioOutputActive));
|
|
198
|
-
writeStdoutLine("meet output routed: %s", formatBoolean(health?.audioOutputRouted));
|
|
199
|
-
if (health?.audioOutputDeviceLabel || health?.audioOutputRouteError) {
|
|
200
|
-
writeStdoutLine("meet output device: %s", formatOptional(health.audioOutputDeviceLabel));
|
|
201
|
-
writeStdoutLine("meet output route error: %s", formatOptional(health.audioOutputRouteError));
|
|
202
|
-
}
|
|
203
|
-
writeStdoutLine("last input: %s (%s bytes)", formatOptional(health?.lastInputAt), health?.lastInputBytes ?? 0);
|
|
204
|
-
writeStdoutLine("last output: %s (%s bytes)", formatOptional(health?.lastOutputAt), health?.lastOutputBytes ?? 0);
|
|
205
|
-
writeStdoutLine("bridge closed: %s", formatBoolean(health?.bridgeClosed));
|
|
206
|
-
writeStdoutLine("browser url: %s", formatOptional(health?.browserUrl));
|
|
207
|
-
if (health?.lastCaptionText) writeStdoutLine("last caption text: %s%s", health.lastCaptionSpeaker ? `${health.lastCaptionSpeaker}: ` : "", health.lastCaptionText);
|
|
208
|
-
writeStdoutLine("realtime transcript lines: %s", health?.realtimeTranscriptLines ?? 0);
|
|
209
|
-
if (health?.lastRealtimeTranscriptText) writeStdoutLine("last realtime transcript: %s%s", health.lastRealtimeTranscriptRole ? `${health.lastRealtimeTranscriptRole}: ` : "", health.lastRealtimeTranscriptText);
|
|
210
|
-
if (health?.lastRealtimeEventType) {
|
|
211
|
-
const detail = health.lastRealtimeEventDetail ? ` ${health.lastRealtimeEventDetail}` : "";
|
|
212
|
-
writeStdoutLine("last realtime event: %s%s", health.lastRealtimeEventType, detail);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
function writeRecoverCurrentTabResult(result) {
|
|
217
|
-
writeStdoutLine("Google Meet current tab: %s", result.found ? "found" : "not found");
|
|
218
|
-
writeStdoutLine("transport: %s", result.transport);
|
|
219
|
-
writeStdoutLine("node: %s", result.nodeId ?? "local/none");
|
|
220
|
-
if (result.targetId) writeStdoutLine("target: %s", result.targetId);
|
|
221
|
-
if (result.tab?.url) writeStdoutLine("tab url: %s", result.tab.url);
|
|
222
|
-
writeStdoutLine("message: %s", result.message);
|
|
223
|
-
if (result.browser) writeDoctorStatus({
|
|
224
|
-
found: true,
|
|
225
|
-
session: {
|
|
226
|
-
id: "current-tab",
|
|
227
|
-
url: result.browser.browserUrl ?? result.tab?.url ?? "unknown",
|
|
228
|
-
transport: result.transport,
|
|
229
|
-
mode: "transcribe",
|
|
230
|
-
agentId: "main",
|
|
231
|
-
state: "active",
|
|
232
|
-
createdAt: "",
|
|
233
|
-
updatedAt: "",
|
|
234
|
-
participantIdentity: result.transport === "chrome-node" ? "signed-in Google Chrome profile on a paired node" : "signed-in Google Chrome profile",
|
|
235
|
-
realtime: {
|
|
236
|
-
enabled: false,
|
|
237
|
-
toolPolicy: "safe-read-only"
|
|
238
|
-
},
|
|
239
|
-
chrome: {
|
|
240
|
-
launched: true,
|
|
241
|
-
nodeId: result.nodeId,
|
|
242
|
-
health: result.browser
|
|
243
|
-
},
|
|
244
|
-
notes: []
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
function writeLeaveResult(sessionId, result) {
|
|
249
|
-
if (result.browserLeft === false) {
|
|
250
|
-
writeStdoutLine("left %s, but the browser participant may still be in the call; check session notes", sessionId);
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
writeStdoutLine("left %s", sessionId);
|
|
254
|
-
}
|
|
255
|
-
//#endregion
|
|
256
|
-
//#region extensions/google-meet/src/cli-export.ts
|
|
257
|
-
function renderArtifactsSummary(result) {
|
|
258
|
-
const lines = [];
|
|
259
|
-
if (result.input) lines.push(`input: ${result.input}`);
|
|
260
|
-
if (result.space) lines.push(`space: ${result.space.name}`);
|
|
261
|
-
lines.push(`conference records: ${result.conferenceRecords.length}`);
|
|
262
|
-
for (const entry of result.artifacts) {
|
|
263
|
-
lines.push("");
|
|
264
|
-
lines.push(`record: ${entry.conferenceRecord.name}`);
|
|
265
|
-
lines.push(`started: ${formatOptional(entry.conferenceRecord.startTime)}`);
|
|
266
|
-
lines.push(`ended: ${formatOptional(entry.conferenceRecord.endTime)}`);
|
|
267
|
-
lines.push(`participants: ${entry.participants.length}`);
|
|
268
|
-
lines.push(`recordings: ${entry.recordings.length}`);
|
|
269
|
-
lines.push(`transcripts: ${entry.transcripts.length}`);
|
|
270
|
-
lines.push(`transcript entries: ${entry.transcriptEntries.reduce((count, transcript) => count + transcript.entries.length, 0)}`);
|
|
271
|
-
lines.push(`smart notes: ${entry.smartNotes.length}`);
|
|
272
|
-
if (entry.smartNotesError) lines.push(`smart notes warning: ${entry.smartNotesError}`);
|
|
273
|
-
for (const recording of entry.recordings) lines.push(`- recording: ${recording.name}`);
|
|
274
|
-
for (const transcript of entry.transcripts) {
|
|
275
|
-
lines.push(`- transcript: ${transcript.name}`);
|
|
276
|
-
if (transcript.documentTextError) lines.push(`- transcript document body warning: ${transcript.documentTextError}`);
|
|
277
|
-
}
|
|
278
|
-
for (const transcriptEntries of entry.transcriptEntries) if (transcriptEntries.entriesError) lines.push(`- transcript entries warning: ${transcriptEntries.transcript}: ${transcriptEntries.entriesError}`);
|
|
279
|
-
for (const smartNote of entry.smartNotes) {
|
|
280
|
-
lines.push(`- smart note: ${smartNote.name}`);
|
|
281
|
-
if (smartNote.documentTextError) lines.push(`- smart note document body warning: ${smartNote.documentTextError}`);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
return `${lines.join("\n")}\n`;
|
|
285
|
-
}
|
|
286
|
-
function renderAttendanceSummary(result) {
|
|
287
|
-
const lines = [];
|
|
288
|
-
if (result.input) lines.push(`input: ${result.input}`);
|
|
289
|
-
if (result.space) lines.push(`space: ${result.space.name}`);
|
|
290
|
-
lines.push(`conference records: ${result.conferenceRecords.length}`);
|
|
291
|
-
lines.push(`attendance rows: ${result.attendance.length}`);
|
|
292
|
-
for (const row of result.attendance) {
|
|
293
|
-
const identity = row.displayName || row.user || row.participant;
|
|
294
|
-
lines.push("");
|
|
295
|
-
lines.push(`participant: ${identity}`);
|
|
296
|
-
lines.push(`record: ${row.conferenceRecord}`);
|
|
297
|
-
lines.push(`resource: ${row.participant}`);
|
|
298
|
-
lines.push(`participants merged: ${row.participants?.length ?? 1}`);
|
|
299
|
-
lines.push(`first joined: ${formatOptional(row.firstJoinTime ?? row.earliestStartTime)}`);
|
|
300
|
-
lines.push(`last left: ${formatOptional(row.lastLeaveTime ?? row.latestEndTime)}`);
|
|
301
|
-
lines.push(`duration: ${formatDuration(row.durationMs)}`);
|
|
302
|
-
lines.push(`late: ${row.late ? formatDuration(row.lateByMs) : "no"}`);
|
|
303
|
-
lines.push(`early leave: ${row.earlyLeave ? formatDuration(row.earlyLeaveByMs) : "no"}`);
|
|
304
|
-
lines.push(`sessions: ${row.sessions.length}`);
|
|
305
|
-
for (const session of row.sessions) lines.push(`- ${session.name}: ${formatOptional(session.startTime)} -> ${formatOptional(session.endTime)}`);
|
|
306
|
-
}
|
|
307
|
-
return `${lines.join("\n")}\n`;
|
|
308
|
-
}
|
|
309
|
-
function writeLatestConferenceRecordSummary(result) {
|
|
310
|
-
writeStdoutLine("input: %s", result.input);
|
|
311
|
-
writeStdoutLine("space: %s", result.space.name);
|
|
312
|
-
if (!result.conferenceRecord) {
|
|
313
|
-
writeStdoutLine("conference record: none");
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
writeStdoutLine("conference record: %s", result.conferenceRecord.name);
|
|
317
|
-
writeStdoutLine("started: %s", formatOptional(result.conferenceRecord.startTime));
|
|
318
|
-
writeStdoutLine("ended: %s", formatOptional(result.conferenceRecord.endTime));
|
|
319
|
-
}
|
|
320
|
-
function writeCalendarEventsSummary(result) {
|
|
321
|
-
writeStdoutLine("calendar: %s", result.calendarId);
|
|
322
|
-
writeStdoutLine("meet events: %d", result.events.length);
|
|
323
|
-
for (const entry of result.events) {
|
|
324
|
-
writeStdoutLine("");
|
|
325
|
-
writeStdoutLine("%s%s", entry.selected ? "* " : "- ", entry.event.summary ?? "untitled");
|
|
326
|
-
writeStdoutLine("meeting uri: %s", entry.meetingUri);
|
|
327
|
-
writeStdoutLine("starts: %s", formatOptional(entry.event.start?.dateTime ?? entry.event.start?.date));
|
|
328
|
-
writeStdoutLine("ends: %s", formatOptional(entry.event.end?.dateTime ?? entry.event.end?.date));
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
function pushMarkdownLine(lines, text = "") {
|
|
332
|
-
lines.push(text);
|
|
333
|
-
}
|
|
334
|
-
function formatMarkdownOptional(value) {
|
|
335
|
-
return typeof value === "string" && value.trim() ? value : "n/a";
|
|
336
|
-
}
|
|
337
|
-
function formatMarkdownIdentity(row) {
|
|
338
|
-
return row.displayName || row.user || row.participant;
|
|
339
|
-
}
|
|
340
|
-
function participantDisplayName(entry, name) {
|
|
341
|
-
const participant = entry.participants.find((candidate) => candidate.name === name);
|
|
342
|
-
if (!participant) return name;
|
|
343
|
-
return participant.signedinUser?.displayName ?? participant.anonymousUser?.displayName ?? participant.phoneUser?.displayName ?? participant.signedinUser?.user ?? name;
|
|
344
|
-
}
|
|
345
|
-
function renderArtifactsMarkdown(result) {
|
|
346
|
-
const lines = ["# Google Meet Artifacts"];
|
|
347
|
-
if (result.input) pushMarkdownLine(lines, `Input: ${result.input}`);
|
|
348
|
-
if (result.space) pushMarkdownLine(lines, `Space: ${result.space.name}`);
|
|
349
|
-
pushMarkdownLine(lines);
|
|
350
|
-
pushMarkdownLine(lines, `Conference records: ${result.conferenceRecords.length}`);
|
|
351
|
-
for (const entry of result.artifacts) {
|
|
352
|
-
pushMarkdownLine(lines);
|
|
353
|
-
pushMarkdownLine(lines, `## ${entry.conferenceRecord.name}`);
|
|
354
|
-
pushMarkdownLine(lines, `Started: ${formatMarkdownOptional(entry.conferenceRecord.startTime)}`);
|
|
355
|
-
pushMarkdownLine(lines, `Ended: ${formatMarkdownOptional(entry.conferenceRecord.endTime)}`);
|
|
356
|
-
pushMarkdownLine(lines);
|
|
357
|
-
pushMarkdownLine(lines, `Participants: ${entry.participants.length}`);
|
|
358
|
-
pushMarkdownLine(lines, `Recordings: ${entry.recordings.length}`);
|
|
359
|
-
pushMarkdownLine(lines, `Transcripts: ${entry.transcripts.length}`);
|
|
360
|
-
pushMarkdownLine(lines, `Transcript entries: ${entry.transcriptEntries.reduce((count, transcript) => count + transcript.entries.length, 0)}`);
|
|
361
|
-
pushMarkdownLine(lines, `Smart notes: ${entry.smartNotes.length}`);
|
|
362
|
-
const warnings = collectGoogleMeetArtifactWarnings({
|
|
363
|
-
conferenceRecords: [entry.conferenceRecord],
|
|
364
|
-
artifacts: [entry]
|
|
365
|
-
});
|
|
366
|
-
if (warnings.length > 0) {
|
|
367
|
-
pushMarkdownLine(lines);
|
|
368
|
-
pushMarkdownLine(lines, "### Warnings");
|
|
369
|
-
for (const warning of warnings) pushMarkdownLine(lines, `- ${warning.resource ? `${warning.resource}: ` : ""}${warning.message}`);
|
|
370
|
-
}
|
|
371
|
-
if (entry.recordings.length > 0) {
|
|
372
|
-
pushMarkdownLine(lines);
|
|
373
|
-
pushMarkdownLine(lines, "### Recordings");
|
|
374
|
-
for (const recording of entry.recordings) pushMarkdownLine(lines, `- ${recording.name}`);
|
|
375
|
-
}
|
|
376
|
-
if (entry.transcripts.length > 0) {
|
|
377
|
-
pushMarkdownLine(lines);
|
|
378
|
-
pushMarkdownLine(lines, "### Transcripts");
|
|
379
|
-
for (const transcript of entry.transcripts) {
|
|
380
|
-
pushMarkdownLine(lines, `- ${transcript.name}`);
|
|
381
|
-
if (transcript.documentTextError) pushMarkdownLine(lines, ` - Document body warning: ${transcript.documentTextError}`);
|
|
382
|
-
else if (transcript.documentText) pushMarkdownLine(lines, ` - Document body: ${transcript.documentText.length} chars`);
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
for (const transcriptEntries of entry.transcriptEntries) {
|
|
386
|
-
pushMarkdownLine(lines);
|
|
387
|
-
pushMarkdownLine(lines, `### Transcript Entries: ${transcriptEntries.transcript}`);
|
|
388
|
-
if (transcriptEntries.entriesError) {
|
|
389
|
-
pushMarkdownLine(lines, `Warning: ${transcriptEntries.entriesError}`);
|
|
390
|
-
continue;
|
|
391
|
-
}
|
|
392
|
-
if (transcriptEntries.entries.length === 0) {
|
|
393
|
-
pushMarkdownLine(lines, "_No transcript entries._");
|
|
394
|
-
continue;
|
|
395
|
-
}
|
|
396
|
-
for (const transcriptEntry of transcriptEntries.entries) {
|
|
397
|
-
const times = transcriptEntry.startTime || transcriptEntry.endTime ? ` (${formatMarkdownOptional(transcriptEntry.startTime)} -> ${formatMarkdownOptional(transcriptEntry.endTime)})` : "";
|
|
398
|
-
pushMarkdownLine(lines, `- ${transcriptEntry.participant ? `${participantDisplayName(entry, transcriptEntry.participant)}: ` : ""}${transcriptEntry.text ?? ""}${times}`);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
if (entry.smartNotes.length > 0) {
|
|
402
|
-
pushMarkdownLine(lines);
|
|
403
|
-
pushMarkdownLine(lines, "### Smart Notes");
|
|
404
|
-
for (const smartNote of entry.smartNotes) {
|
|
405
|
-
pushMarkdownLine(lines, `- ${smartNote.name}`);
|
|
406
|
-
if (smartNote.documentTextError) pushMarkdownLine(lines, ` - Document body warning: ${smartNote.documentTextError}`);
|
|
407
|
-
else if (smartNote.documentText) pushMarkdownLine(lines, ` - Document body: ${smartNote.documentText.length} chars`);
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
return `${lines.join("\n")}\n`;
|
|
412
|
-
}
|
|
413
|
-
function renderAttendanceMarkdown(result) {
|
|
414
|
-
const lines = ["# Google Meet Attendance"];
|
|
415
|
-
if (result.input) pushMarkdownLine(lines, `Input: ${result.input}`);
|
|
416
|
-
if (result.space) pushMarkdownLine(lines, `Space: ${result.space.name}`);
|
|
417
|
-
pushMarkdownLine(lines);
|
|
418
|
-
pushMarkdownLine(lines, `Conference records: ${result.conferenceRecords.length}`);
|
|
419
|
-
pushMarkdownLine(lines, `Attendance rows: ${result.attendance.length}`);
|
|
420
|
-
for (const row of result.attendance) {
|
|
421
|
-
pushMarkdownLine(lines);
|
|
422
|
-
pushMarkdownLine(lines, `## ${formatMarkdownIdentity(row)}`);
|
|
423
|
-
pushMarkdownLine(lines, `Record: ${row.conferenceRecord}`);
|
|
424
|
-
pushMarkdownLine(lines, `Resource: ${row.participant}`);
|
|
425
|
-
pushMarkdownLine(lines, `Participants merged: ${row.participants?.length ?? 1}`);
|
|
426
|
-
pushMarkdownLine(lines, `First joined: ${formatMarkdownOptional(row.firstJoinTime ?? row.earliestStartTime)}`);
|
|
427
|
-
pushMarkdownLine(lines, `Last left: ${formatMarkdownOptional(row.lastLeaveTime ?? row.latestEndTime)}`);
|
|
428
|
-
pushMarkdownLine(lines, `Duration: ${formatDuration(row.durationMs)}`);
|
|
429
|
-
pushMarkdownLine(lines, `Late: ${row.late ? formatDuration(row.lateByMs) : "no"}`);
|
|
430
|
-
pushMarkdownLine(lines, `Early leave: ${row.earlyLeave ? formatDuration(row.earlyLeaveByMs) : "no"}`);
|
|
431
|
-
pushMarkdownLine(lines, `Sessions: ${row.sessions.length}`);
|
|
432
|
-
for (const session of row.sessions) pushMarkdownLine(lines, `- ${session.name}: ${formatMarkdownOptional(session.startTime)} -> ${formatMarkdownOptional(session.endTime)}`);
|
|
433
|
-
}
|
|
434
|
-
return `${lines.join("\n")}\n`;
|
|
435
|
-
}
|
|
436
|
-
function neutralizeSpreadsheetFormulaCell(text) {
|
|
437
|
-
return /^[ \t\r\n]*[=+\-@\uFF0B\uFF0D\uFF1D\uFF20]/u.test(text) || /^[\t\r\n]/.test(text) ? `'${text}` : text;
|
|
438
|
-
}
|
|
439
|
-
function csvCell(value) {
|
|
440
|
-
const safeText = neutralizeSpreadsheetFormulaCell(value === void 0 || value === null ? "" : typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : JSON.stringify(value));
|
|
441
|
-
return /[",\r\n]/.test(safeText) ? `"${safeText.replaceAll("\"", "\"\"")}"` : safeText;
|
|
442
|
-
}
|
|
443
|
-
function renderAttendanceCsv(result) {
|
|
444
|
-
const rows = [[
|
|
445
|
-
"conferenceRecord",
|
|
446
|
-
"displayName",
|
|
447
|
-
"user",
|
|
448
|
-
"participants",
|
|
449
|
-
"firstJoined",
|
|
450
|
-
"lastLeft",
|
|
451
|
-
"durationMs",
|
|
452
|
-
"sessions",
|
|
453
|
-
"late",
|
|
454
|
-
"lateByMs",
|
|
455
|
-
"earlyLeave",
|
|
456
|
-
"earlyLeaveByMs"
|
|
457
|
-
]];
|
|
458
|
-
for (const row of result.attendance) rows.push([
|
|
459
|
-
row.conferenceRecord,
|
|
460
|
-
row.displayName ?? "",
|
|
461
|
-
row.user ?? "",
|
|
462
|
-
(row.participants ?? [row.participant]).join(";"),
|
|
463
|
-
row.firstJoinTime ?? row.earliestStartTime ?? "",
|
|
464
|
-
row.lastLeaveTime ?? row.latestEndTime ?? "",
|
|
465
|
-
row.durationMs ?? "",
|
|
466
|
-
row.sessions.length,
|
|
467
|
-
row.late ?? "",
|
|
468
|
-
row.lateByMs ?? "",
|
|
469
|
-
row.earlyLeave ?? "",
|
|
470
|
-
row.earlyLeaveByMs ?? ""
|
|
471
|
-
]);
|
|
472
|
-
return `${rows.map((row) => row.map(csvCell).join(",")).join("\n")}\n`;
|
|
473
|
-
}
|
|
474
|
-
function renderTranscriptMarkdown(result) {
|
|
475
|
-
const lines = ["# Google Meet Transcript"];
|
|
476
|
-
if (result.input) pushMarkdownLine(lines, `Input: ${result.input}`);
|
|
477
|
-
for (const entry of result.artifacts) {
|
|
478
|
-
pushMarkdownLine(lines);
|
|
479
|
-
pushMarkdownLine(lines, `## ${entry.conferenceRecord.name}`);
|
|
480
|
-
if (entry.transcriptEntries.length === 0) {
|
|
481
|
-
pushMarkdownLine(lines, "_No transcript entries._");
|
|
482
|
-
continue;
|
|
483
|
-
}
|
|
484
|
-
for (const transcriptEntries of entry.transcriptEntries) {
|
|
485
|
-
pushMarkdownLine(lines);
|
|
486
|
-
pushMarkdownLine(lines, `### ${transcriptEntries.transcript}`);
|
|
487
|
-
if (transcriptEntries.entriesError) {
|
|
488
|
-
pushMarkdownLine(lines, `Warning: ${transcriptEntries.entriesError}`);
|
|
489
|
-
continue;
|
|
490
|
-
}
|
|
491
|
-
for (const transcriptEntry of transcriptEntries.entries) pushMarkdownLine(lines, `- ${transcriptEntry.participant ? participantDisplayName(entry, transcriptEntry.participant) : "unknown"}${transcriptEntry.startTime ? ` [${transcriptEntry.startTime}]` : ""}: ${transcriptEntry.text ?? ""}`);
|
|
492
|
-
}
|
|
493
|
-
const docsTranscripts = entry.transcripts.filter((transcript) => transcript.documentText);
|
|
494
|
-
if (docsTranscripts.length > 0) {
|
|
495
|
-
pushMarkdownLine(lines);
|
|
496
|
-
pushMarkdownLine(lines, "### Transcript Document Bodies");
|
|
497
|
-
for (const transcript of docsTranscripts) {
|
|
498
|
-
pushMarkdownLine(lines);
|
|
499
|
-
pushMarkdownLine(lines, `#### ${transcript.name}`);
|
|
500
|
-
pushMarkdownLine(lines, transcript.documentText?.trim() || "_Empty document body._");
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
const smartNotes = entry.smartNotes.filter((smartNote) => smartNote.documentText);
|
|
504
|
-
if (smartNotes.length > 0) {
|
|
505
|
-
pushMarkdownLine(lines);
|
|
506
|
-
pushMarkdownLine(lines, "### Smart Note Document Bodies");
|
|
507
|
-
for (const smartNote of smartNotes) {
|
|
508
|
-
pushMarkdownLine(lines);
|
|
509
|
-
pushMarkdownLine(lines, `#### ${smartNote.name}`);
|
|
510
|
-
pushMarkdownLine(lines, smartNote.documentText?.trim() || "_Empty document body._");
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
return `${lines.join("\n")}\n`;
|
|
515
|
-
}
|
|
516
|
-
function collectGoogleMeetArtifactWarnings(result) {
|
|
517
|
-
const warnings = [];
|
|
518
|
-
for (const entry of result.artifacts) {
|
|
519
|
-
const conferenceRecord = entry.conferenceRecord.name;
|
|
520
|
-
if (entry.smartNotesError) warnings.push({
|
|
521
|
-
type: "smart_notes",
|
|
522
|
-
conferenceRecord,
|
|
523
|
-
message: entry.smartNotesError
|
|
524
|
-
});
|
|
525
|
-
for (const transcriptEntries of entry.transcriptEntries) if (transcriptEntries.entriesError) warnings.push({
|
|
526
|
-
type: "transcript_entries",
|
|
527
|
-
conferenceRecord,
|
|
528
|
-
resource: transcriptEntries.transcript,
|
|
529
|
-
message: transcriptEntries.entriesError
|
|
530
|
-
});
|
|
531
|
-
for (const transcript of entry.transcripts) if (transcript.documentTextError) warnings.push({
|
|
532
|
-
type: "transcript_document_body",
|
|
533
|
-
conferenceRecord,
|
|
534
|
-
resource: transcript.name,
|
|
535
|
-
message: transcript.documentTextError
|
|
536
|
-
});
|
|
537
|
-
for (const smartNote of entry.smartNotes) if (smartNote.documentTextError) warnings.push({
|
|
538
|
-
type: "smart_note_document_body",
|
|
539
|
-
conferenceRecord,
|
|
540
|
-
resource: smartNote.name,
|
|
541
|
-
message: smartNote.documentTextError
|
|
542
|
-
});
|
|
543
|
-
}
|
|
544
|
-
return warnings;
|
|
545
|
-
}
|
|
546
|
-
function buildGoogleMeetExportManifest(params) {
|
|
547
|
-
const transcriptEntryCount = params.artifacts.artifacts.reduce((count, entry) => count + entry.transcriptEntries.reduce((entryCount, transcript) => entryCount + transcript.entries.length, 0), 0);
|
|
548
|
-
const warnings = collectGoogleMeetArtifactWarnings(params.artifacts);
|
|
549
|
-
return {
|
|
550
|
-
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
551
|
-
...params.request ? { request: params.request } : {},
|
|
552
|
-
...params.tokenSource ? { tokenSource: params.tokenSource } : {},
|
|
553
|
-
...params.calendarEvent ? { calendarEvent: params.calendarEvent } : {},
|
|
554
|
-
inputs: {
|
|
555
|
-
...params.artifacts.input ? { artifacts: params.artifacts.input } : {},
|
|
556
|
-
...params.attendance.input ? { attendance: params.attendance.input } : {}
|
|
557
|
-
},
|
|
558
|
-
counts: {
|
|
559
|
-
conferenceRecords: params.artifacts.conferenceRecords.length,
|
|
560
|
-
artifacts: params.artifacts.artifacts.length,
|
|
561
|
-
attendanceRows: params.attendance.attendance.length,
|
|
562
|
-
recordings: params.artifacts.artifacts.reduce((count, entry) => count + entry.recordings.length, 0),
|
|
563
|
-
transcripts: params.artifacts.artifacts.reduce((count, entry) => count + entry.transcripts.length, 0),
|
|
564
|
-
transcriptEntries: transcriptEntryCount,
|
|
565
|
-
smartNotes: params.artifacts.artifacts.reduce((count, entry) => count + entry.smartNotes.length, 0),
|
|
566
|
-
warnings: warnings.length
|
|
567
|
-
},
|
|
568
|
-
conferenceRecords: params.artifacts.conferenceRecords.map((record) => record.name),
|
|
569
|
-
files: params.files,
|
|
570
|
-
...params.zipFile ? { zipFile: params.zipFile } : {},
|
|
571
|
-
warnings
|
|
572
|
-
};
|
|
573
|
-
}
|
|
574
|
-
function googleMeetExportFileNames() {
|
|
575
|
-
return [
|
|
576
|
-
"summary.md",
|
|
577
|
-
"attendance.csv",
|
|
578
|
-
"transcript.md",
|
|
579
|
-
"artifacts.json",
|
|
580
|
-
"attendance.json",
|
|
581
|
-
"manifest.json"
|
|
582
|
-
];
|
|
583
|
-
}
|
|
584
|
-
function defaultExportDirectory() {
|
|
585
|
-
return `google-meet-export-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
|
|
586
|
-
}
|
|
587
|
-
async function publishMeetExportFile(outputPath, content) {
|
|
588
|
-
const absolutePath = path.resolve(outputPath);
|
|
589
|
-
await writeExternalFileWithinRoot({
|
|
590
|
-
rootDir: path.dirname(absolutePath),
|
|
591
|
-
path: path.basename(absolutePath),
|
|
592
|
-
write: async (tempPath) => {
|
|
593
|
-
await fsp.writeFile(tempPath, content);
|
|
594
|
-
}
|
|
595
|
-
});
|
|
596
|
-
}
|
|
597
|
-
async function writeMeetExportBundle(params) {
|
|
598
|
-
const outputDir = params.outputDir?.trim() || defaultExportDirectory();
|
|
599
|
-
await fsp.mkdir(outputDir, { recursive: true });
|
|
600
|
-
let zipOutputDir = outputDir;
|
|
601
|
-
if (params.zip) {
|
|
602
|
-
const resolvedOutputDir = path.resolve(outputDir);
|
|
603
|
-
if (resolvedOutputDir !== path.parse(resolvedOutputDir).root) zipOutputDir = outputDir.replace(path.sep === "\\" ? /[\\/]+$/ : /\/+$/, "");
|
|
604
|
-
}
|
|
605
|
-
const zipFile = params.zip ? `${zipOutputDir.replace(/\/$/, "")}.zip` : void 0;
|
|
606
|
-
const fileNames = googleMeetExportFileNames();
|
|
607
|
-
const files = [
|
|
608
|
-
{
|
|
609
|
-
name: "summary.md",
|
|
610
|
-
content: `${renderArtifactsMarkdown(params.artifacts)}\n${renderAttendanceMarkdown(params.attendance)}`
|
|
611
|
-
},
|
|
612
|
-
{
|
|
613
|
-
name: "attendance.csv",
|
|
614
|
-
content: renderAttendanceCsv(params.attendance)
|
|
615
|
-
},
|
|
616
|
-
{
|
|
617
|
-
name: "transcript.md",
|
|
618
|
-
content: renderTranscriptMarkdown(params.artifacts)
|
|
619
|
-
},
|
|
620
|
-
{
|
|
621
|
-
name: "artifacts.json",
|
|
622
|
-
content: `${JSON.stringify(params.artifacts, null, 2)}\n`
|
|
623
|
-
},
|
|
624
|
-
{
|
|
625
|
-
name: "attendance.json",
|
|
626
|
-
content: `${JSON.stringify(params.attendance, null, 2)}\n`
|
|
627
|
-
},
|
|
628
|
-
{
|
|
629
|
-
name: "manifest.json",
|
|
630
|
-
content: `${JSON.stringify(buildGoogleMeetExportManifest({
|
|
631
|
-
artifacts: params.artifacts,
|
|
632
|
-
attendance: params.attendance,
|
|
633
|
-
files: fileNames,
|
|
634
|
-
...params.request ? { request: params.request } : {},
|
|
635
|
-
...params.tokenSource ? { tokenSource: params.tokenSource } : {},
|
|
636
|
-
...params.calendarEvent ? { calendarEvent: params.calendarEvent } : {},
|
|
637
|
-
...zipFile ? { zipFile } : {}
|
|
638
|
-
}), null, 2)}\n`
|
|
639
|
-
}
|
|
640
|
-
];
|
|
641
|
-
for (const file of files) await publishMeetExportFile(path.join(outputDir, file.name), file.content);
|
|
642
|
-
const result = {
|
|
643
|
-
outputDir,
|
|
644
|
-
files: files.map((file) => path.join(outputDir, file.name))
|
|
645
|
-
};
|
|
646
|
-
if (zipFile) {
|
|
647
|
-
const zip = new JSZip();
|
|
648
|
-
for (const file of files) zip.file(file.name, file.content);
|
|
649
|
-
await publishMeetExportFile(zipFile, await zip.generateAsync({ type: "nodebuffer" }));
|
|
650
|
-
result.zipFile = zipFile;
|
|
651
|
-
}
|
|
652
|
-
return result;
|
|
653
|
-
}
|
|
654
|
-
//#endregion
|
|
655
24
|
//#region extensions/google-meet/src/cli-artifact-commands.ts
|
|
656
25
|
async function resolveCliArtifactQuery(context, options) {
|
|
657
26
|
const { lateAfterMinutes, earlyBeforeMinutes, ...raw } = context.resolveCliArtifactParams(options);
|
|
@@ -700,57 +69,23 @@ function registerGoogleMeetArtifactCommands(context) {
|
|
|
700
69
|
const resolved = await resolveCliArtifactQuery(params, options);
|
|
701
70
|
const artifacts = await fetchResolvedGoogleMeetArtifacts(resolved);
|
|
702
71
|
const attendance = await fetchResolvedGoogleMeetAttendance(resolved);
|
|
703
|
-
const
|
|
704
|
-
...resolved.meeting ? { meeting: resolved.meeting } : {},
|
|
705
|
-
...resolved.conferenceRecord ? { conferenceRecord: resolved.conferenceRecord } : {},
|
|
706
|
-
...resolved.calendarEvent?.event.id ? { calendarEventId: resolved.calendarEvent.event.id } : {},
|
|
707
|
-
...resolved.calendarEvent?.event.summary ? { calendarEventSummary: resolved.calendarEvent.event.summary } : {},
|
|
708
|
-
...options.calendar ? { calendarId: options.calendar } : {},
|
|
709
|
-
...resolved.pageSize !== void 0 ? { pageSize: resolved.pageSize } : {},
|
|
710
|
-
includeTranscriptEntries: resolved.includeTranscriptEntries,
|
|
711
|
-
includeDocumentBodies: resolved.includeDocumentBodies,
|
|
712
|
-
allConferenceRecords: resolved.allConferenceRecords,
|
|
713
|
-
mergeDuplicateParticipants: resolved.mergeDuplicateParticipants,
|
|
714
|
-
...resolved.lateAfterMinutes !== void 0 ? { lateAfterMinutes: resolved.lateAfterMinutes } : {},
|
|
715
|
-
...resolved.earlyBeforeMinutes !== void 0 ? { earlyBeforeMinutes: resolved.earlyBeforeMinutes } : {}
|
|
716
|
-
};
|
|
717
|
-
if (options.dryRun) {
|
|
718
|
-
writeStdoutJson({
|
|
719
|
-
dryRun: true,
|
|
720
|
-
manifest: buildGoogleMeetExportManifest({
|
|
721
|
-
artifacts,
|
|
722
|
-
attendance,
|
|
723
|
-
files: googleMeetExportFileNames(),
|
|
724
|
-
request,
|
|
725
|
-
tokenSource: resolveTokenSource(resolved.token.refreshed),
|
|
726
|
-
...resolved.calendarEvent ? { calendarEvent: resolved.calendarEvent } : {}
|
|
727
|
-
}),
|
|
728
|
-
...resolved.calendarEvent ? { calendarEvent: resolved.calendarEvent } : {},
|
|
729
|
-
tokenSource: resolveTokenSource(resolved.token.refreshed)
|
|
730
|
-
});
|
|
731
|
-
return;
|
|
732
|
-
}
|
|
733
|
-
const bundle = await writeMeetExportBundle({
|
|
72
|
+
const payload = await exportGoogleMeetBundle({
|
|
734
73
|
outputDir: options.output,
|
|
735
74
|
artifacts,
|
|
736
75
|
attendance,
|
|
737
76
|
zip: Boolean(options.zip),
|
|
738
|
-
|
|
77
|
+
dryRun: options.dryRun,
|
|
78
|
+
request: buildGoogleMeetExportRequest(resolved, options.calendar),
|
|
739
79
|
tokenSource: resolveTokenSource(resolved.token.refreshed),
|
|
740
|
-
|
|
80
|
+
calendarEvent: resolved.calendarEvent
|
|
741
81
|
});
|
|
742
|
-
|
|
743
|
-
...bundle,
|
|
744
|
-
...resolved.calendarEvent ? { calendarEvent: resolved.calendarEvent } : {},
|
|
745
|
-
tokenSource: resolveTokenSource(resolved.token.refreshed)
|
|
746
|
-
};
|
|
747
|
-
if (options.json) {
|
|
82
|
+
if (options.json || "dryRun" in payload) {
|
|
748
83
|
writeStdoutJson(payload);
|
|
749
84
|
return;
|
|
750
85
|
}
|
|
751
|
-
writeStdoutLine("export: %s",
|
|
752
|
-
for (const file of
|
|
753
|
-
if (
|
|
86
|
+
writeStdoutLine("export: %s", payload.outputDir);
|
|
87
|
+
for (const file of payload.files) writeStdoutLine("- %s", file);
|
|
88
|
+
if (payload.zipFile) writeStdoutLine("zip: %s", payload.zipFile);
|
|
754
89
|
});
|
|
755
90
|
}
|
|
756
91
|
//#endregion
|
|
@@ -879,16 +214,9 @@ function registerGoogleMeetDoctorCommand(context) {
|
|
|
879
214
|
method: "googlemeet.status",
|
|
880
215
|
payload: { sessionId }
|
|
881
216
|
});
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
writeStdoutJson(status);
|
|
886
|
-
return;
|
|
887
|
-
}
|
|
888
|
-
writeDoctorStatus(status);
|
|
889
|
-
return;
|
|
890
|
-
}
|
|
891
|
-
const status = await (await params.ensureRuntime()).status(sessionId);
|
|
217
|
+
let status;
|
|
218
|
+
if (delegated.ok) status = delegated.payload;
|
|
219
|
+
else status = await (await params.ensureRuntime()).status(sessionId);
|
|
892
220
|
if (options.json) {
|
|
893
221
|
writeStdoutJson(status);
|
|
894
222
|
return;
|
|
@@ -922,7 +250,8 @@ function registerGoogleMeetProbeCommands(context) {
|
|
|
922
250
|
writeStdoutJson(result.session ?? delegated.payload);
|
|
923
251
|
return;
|
|
924
252
|
}
|
|
925
|
-
|
|
253
|
+
const result = await (await params.ensureRuntime()).join(payload);
|
|
254
|
+
writeStdoutJson(result.session);
|
|
926
255
|
});
|
|
927
256
|
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
257
|
const payload = {
|
|
@@ -941,7 +270,8 @@ function registerGoogleMeetProbeCommands(context) {
|
|
|
941
270
|
writeStdoutJson(delegated.payload);
|
|
942
271
|
return;
|
|
943
272
|
}
|
|
944
|
-
|
|
273
|
+
const rt = await params.ensureRuntime();
|
|
274
|
+
writeStdoutJson(await rt.testSpeech(payload));
|
|
945
275
|
});
|
|
946
276
|
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
277
|
const payload = {
|
|
@@ -959,7 +289,8 @@ function registerGoogleMeetProbeCommands(context) {
|
|
|
959
289
|
writeStdoutJson(delegated.payload);
|
|
960
290
|
return;
|
|
961
291
|
}
|
|
962
|
-
|
|
292
|
+
const rt = await params.ensureRuntime();
|
|
293
|
+
writeStdoutJson(await rt.testListen(payload));
|
|
963
294
|
});
|
|
964
295
|
}
|
|
965
296
|
function registerGoogleMeetSessionCommands(context) {
|
|
@@ -975,7 +306,8 @@ function registerGoogleMeetSessionCommands(context) {
|
|
|
975
306
|
writeStdoutJson(delegated.payload);
|
|
976
307
|
return;
|
|
977
308
|
}
|
|
978
|
-
|
|
309
|
+
const rt = await params.ensureRuntime();
|
|
310
|
+
writeStdoutJson(await rt.status(sessionId));
|
|
979
311
|
});
|
|
980
312
|
root.command("transcript").description("Print the bounded caption transcript for a Meet session").argument("<session-id>", "Meet session ID").option("--since <index>", "Resume from the previous response's nextIndex").option("--json", "Print JSON output", false).action(async (sessionId, options) => {
|
|
981
313
|
const sinceIndex = parseStrictNonNegativeInteger(options.since);
|
|
@@ -1356,4 +688,4 @@ function registerGoogleMeetCli(params) {
|
|
|
1356
688
|
registerGoogleMeetLifecycleCommands(context);
|
|
1357
689
|
}
|
|
1358
690
|
//#endregion
|
|
1359
|
-
export {
|
|
691
|
+
export { registerGoogleMeetCli };
|