@kodelyth/googlechat 2026.5.39 → 2026.6.1

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.
@@ -0,0 +1,584 @@
1
+ import { a as resolveDefaultGoogleChatAccountId, i as listGoogleChatAccountIds, n as googlechatSetupAdapter, o as resolveGoogleChatAccount, s as resolveGoogleChatConfigAccessorAccount, t as googlechatSetupWizard } from "./setup-surface-B3Fa7XRx.js";
2
+ import { T as resolveChannelMediaMaxBytes, _ as missingTargetError, a as buildChannelConfigSchema, g as loadOutboundMediaFromUrl, i as PAIRING_APPROVED_MESSAGE, o as chunkTextForOutbound, r as GoogleChatConfigSchema, t as DEFAULT_ACCOUNT_ID, x as readRemoteMediaBuffer } from "./runtime-api-DUH2Cg-0.js";
3
+ import { a as findGoogleChatDirectMessage } from "./api-BkZX4VNX.js";
4
+ import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-8SF6XoKj.js";
5
+ import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-DWX4ikgT.js";
6
+ import { describeAccountSnapshot } from "klaw/plugin-sdk/account-helpers";
7
+ import { formatNormalizedAllowFromEntries } from "klaw/plugin-sdk/allow-from";
8
+ import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter } from "klaw/plugin-sdk/channel-config-helpers";
9
+ import { createChatChannelPlugin } from "klaw/plugin-sdk/channel-core";
10
+ import { buildPassiveProbedChannelStatusSummary } from "klaw/plugin-sdk/extension-shared";
11
+ import { createLazyRuntimeNamedExport } from "klaw/plugin-sdk/lazy-runtime";
12
+ import { createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "klaw/plugin-sdk/status-helpers";
13
+ import { extractToolSend } from "klaw/plugin-sdk/tool-send";
14
+ import { createResolvedApproverActionAuthAdapter, resolveApprovalApprovers } from "klaw/plugin-sdk/approval-auth-runtime";
15
+ import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "klaw/plugin-sdk/string-coerce-runtime";
16
+ import { createAccountStatusSink, runPassiveAccountLifecycle } from "klaw/plugin-sdk/channel-lifecycle";
17
+ import { createMessageReceiptFromOutboundResults, defineChannelMessageAdapter } from "klaw/plugin-sdk/channel-message";
18
+ import { composeAccountWarningCollectors, createAllowlistProviderOpenWarningCollector, createDangerousNameMatchingMutableAllowlistWarningCollector, resolveChannelGroupRequireMention } from "klaw/plugin-sdk/channel-policy";
19
+ import { createChannelDirectoryAdapter, listResolvedDirectoryGroupEntriesFromMapKeys, listResolvedDirectoryUserEntriesFromAllowFrom } from "klaw/plugin-sdk/directory-runtime";
20
+ import { sanitizeForPlainText } from "klaw/plugin-sdk/outbound-runtime";
21
+ //#region extensions/googlechat/src/targets.ts
22
+ function normalizeGoogleChatTarget(raw) {
23
+ const trimmed = raw?.trim();
24
+ if (!trimmed) return;
25
+ const normalized = trimmed.replace(/^(googlechat|google-chat|gchat):/i, "").replace(/^user:(users\/)?/i, "users/").replace(/^space:(spaces\/)?/i, "spaces/");
26
+ if (isGoogleChatUserTarget(normalized)) {
27
+ const suffix = normalized.slice(6);
28
+ return suffix.includes("@") ? `users/${normalizeLowercaseStringOrEmpty(suffix)}` : normalized;
29
+ }
30
+ if (isGoogleChatSpaceTarget(normalized)) return normalized;
31
+ if (normalized.includes("@")) return `users/${normalizeLowercaseStringOrEmpty(normalized)}`;
32
+ return normalized;
33
+ }
34
+ function isGoogleChatUserTarget(value) {
35
+ return normalizeLowercaseStringOrEmpty(value).startsWith("users/");
36
+ }
37
+ function isGoogleChatSpaceTarget(value) {
38
+ return normalizeLowercaseStringOrEmpty(value).startsWith("spaces/");
39
+ }
40
+ function stripMessageSuffix(target) {
41
+ const index = target.indexOf("/messages/");
42
+ if (index === -1) return target;
43
+ return target.slice(0, index);
44
+ }
45
+ async function resolveGoogleChatOutboundSpace(params) {
46
+ const normalized = normalizeGoogleChatTarget(params.target);
47
+ if (!normalized) throw new Error("Missing Google Chat target.");
48
+ const base = stripMessageSuffix(normalized);
49
+ if (isGoogleChatSpaceTarget(base)) return base;
50
+ if (isGoogleChatUserTarget(base)) {
51
+ const dm = await findGoogleChatDirectMessage({
52
+ account: params.account,
53
+ userName: base
54
+ });
55
+ if (!dm?.name) throw new Error(`No Google Chat DM found for ${base}`);
56
+ return dm.name;
57
+ }
58
+ return base;
59
+ }
60
+ //#endregion
61
+ //#region extensions/googlechat/src/approval-auth.ts
62
+ function normalizeGoogleChatApproverId(value) {
63
+ const normalized = normalizeGoogleChatTarget(String(value));
64
+ if (!normalized || !isGoogleChatUserTarget(normalized)) return;
65
+ const suffix = normalizeLowercaseStringOrEmpty(normalized.slice(6));
66
+ if (!suffix || suffix.includes("@")) return;
67
+ return `users/${suffix}`;
68
+ }
69
+ const googleChatApprovalAuth = createResolvedApproverActionAuthAdapter({
70
+ channelLabel: "Google Chat",
71
+ resolveApprovers: ({ cfg, accountId }) => {
72
+ const account = resolveGoogleChatAccount({
73
+ cfg,
74
+ accountId
75
+ }).config;
76
+ return resolveApprovalApprovers({
77
+ allowFrom: account.dm?.allowFrom,
78
+ defaultTo: account.defaultTo,
79
+ normalizeApprover: normalizeGoogleChatApproverId
80
+ });
81
+ },
82
+ normalizeSenderId: (value) => normalizeGoogleChatApproverId(value)
83
+ });
84
+ //#endregion
85
+ //#region extensions/googlechat/src/group-policy.ts
86
+ function resolveGoogleChatGroupRequireMention(params) {
87
+ return resolveChannelGroupRequireMention({
88
+ cfg: params.cfg,
89
+ channel: "googlechat",
90
+ groupId: params.groupId,
91
+ accountId: params.accountId
92
+ });
93
+ }
94
+ //#endregion
95
+ //#region extensions/googlechat/src/channel.adapters.ts
96
+ const loadGoogleChatChannelRuntime$2 = createLazyRuntimeNamedExport(() => import("./channel.runtime-en3RNg9S.js"), "googleChatChannelRuntime");
97
+ function createGoogleChatSendReceipt(params) {
98
+ const messageId = params.messageId?.trim();
99
+ return createMessageReceiptFromOutboundResults({
100
+ results: messageId ? [{
101
+ channel: "googlechat",
102
+ messageId,
103
+ chatId: params.chatId,
104
+ conversationId: params.chatId
105
+ }] : [],
106
+ threadId: params.chatId,
107
+ kind: params.kind
108
+ });
109
+ }
110
+ const formatAllowFromEntry = (entry) => normalizeLowercaseStringOrEmpty(entry.trim().replace(/^(googlechat|google-chat|gchat):/i, "").replace(/^user:/i, "").replace(/^users\//i, ""));
111
+ const collectGoogleChatSecurityWarnings = composeAccountWarningCollectors(createAllowlistProviderOpenWarningCollector({
112
+ providerConfigPresent: (cfg) => cfg.channels?.googlechat !== void 0,
113
+ resolveGroupPolicy: (account) => account.config.groupPolicy,
114
+ buildOpenWarning: {
115
+ surface: "Google Chat spaces",
116
+ openBehavior: "allows any space to trigger (mention-gated)",
117
+ remediation: "Set channels.googlechat.groupPolicy=\"allowlist\" and configure channels.googlechat.groups"
118
+ }
119
+ }), (account) => account.config.dm?.policy === "open" && "- Google Chat DMs are open to anyone. Set channels.googlechat.dm.policy=\"pairing\" or \"allowlist\".");
120
+ const googlechatGroupsAdapter = { resolveRequireMention: resolveGoogleChatGroupRequireMention };
121
+ const googlechatDirectoryAdapter = createChannelDirectoryAdapter({
122
+ listPeers: async (params) => listResolvedDirectoryUserEntriesFromAllowFrom({
123
+ ...params,
124
+ resolveAccount: adaptScopedAccountAccessor(resolveGoogleChatAccount),
125
+ resolveAllowFrom: (account) => account.config.dm?.allowFrom,
126
+ normalizeId: (entry) => normalizeGoogleChatTarget(entry) ?? entry
127
+ }),
128
+ listGroups: async (params) => listResolvedDirectoryGroupEntriesFromMapKeys({
129
+ ...params,
130
+ resolveAccount: adaptScopedAccountAccessor(resolveGoogleChatAccount),
131
+ resolveGroups: (account) => account.config.groups
132
+ })
133
+ });
134
+ const googlechatSecurityAdapter = {
135
+ dm: {
136
+ channelKey: "googlechat",
137
+ resolvePolicy: (account) => account.config.dm?.policy,
138
+ resolveAllowFrom: (account) => account.config.dm?.allowFrom,
139
+ allowFromPathSuffix: "dm.",
140
+ normalizeEntry: (raw) => formatAllowFromEntry(raw)
141
+ },
142
+ collectWarnings: collectGoogleChatSecurityWarnings
143
+ };
144
+ const googlechatThreadingAdapter = { scopedAccountReplyToMode: {
145
+ resolveAccount: (cfg, accountId) => resolveGoogleChatAccount({
146
+ cfg,
147
+ accountId
148
+ }),
149
+ resolveReplyToMode: (account, _chatType) => account.config.replyToMode,
150
+ fallback: "off"
151
+ } };
152
+ const googlechatPairingTextAdapter = {
153
+ idLabel: "googlechatUserId",
154
+ message: PAIRING_APPROVED_MESSAGE,
155
+ normalizeAllowEntry: (entry) => formatAllowFromEntry(entry),
156
+ notify: async ({ cfg, id, message, accountId }) => {
157
+ const account = resolveGoogleChatAccount({
158
+ cfg,
159
+ accountId
160
+ });
161
+ if (account.credentialSource === "none") return;
162
+ const user = normalizeGoogleChatTarget(id) ?? id;
163
+ const space = await resolveGoogleChatOutboundSpace({
164
+ account,
165
+ target: isGoogleChatUserTarget(user) ? user : `users/${user}`
166
+ });
167
+ const { sendGoogleChatMessage } = await loadGoogleChatChannelRuntime$2();
168
+ await sendGoogleChatMessage({
169
+ account,
170
+ space,
171
+ text: message
172
+ });
173
+ }
174
+ };
175
+ const googlechatOutboundAdapter = {
176
+ base: {
177
+ deliveryMode: "direct",
178
+ chunker: chunkTextForOutbound,
179
+ chunkerMode: "markdown",
180
+ textChunkLimit: 4e3,
181
+ sanitizeText: ({ text }) => sanitizeForPlainText(text),
182
+ resolveTarget: ({ to }) => {
183
+ const trimmed = normalizeOptionalString(to) ?? "";
184
+ if (trimmed) {
185
+ const normalized = normalizeGoogleChatTarget(trimmed);
186
+ if (!normalized) return {
187
+ ok: false,
188
+ error: missingTargetError("Google Chat", "<spaces/{space}|users/{user}>")
189
+ };
190
+ return {
191
+ ok: true,
192
+ to: normalized
193
+ };
194
+ }
195
+ return {
196
+ ok: false,
197
+ error: missingTargetError("Google Chat", "<spaces/{space}|users/{user}>")
198
+ };
199
+ }
200
+ },
201
+ attachedResults: {
202
+ channel: "googlechat",
203
+ sendText: async ({ cfg, to, text, accountId, replyToId, threadId }) => {
204
+ const account = resolveGoogleChatAccount({
205
+ cfg,
206
+ accountId
207
+ });
208
+ const space = await resolveGoogleChatOutboundSpace({
209
+ account,
210
+ target: to
211
+ });
212
+ const thread = typeof threadId === "number" ? String(threadId) : threadId ?? replyToId ?? void 0;
213
+ const { sendGoogleChatMessage } = await loadGoogleChatChannelRuntime$2();
214
+ const messageId = (await sendGoogleChatMessage({
215
+ account,
216
+ space,
217
+ text,
218
+ thread
219
+ }))?.messageName ?? "";
220
+ return {
221
+ messageId,
222
+ chatId: space,
223
+ receipt: createGoogleChatSendReceipt({
224
+ messageId,
225
+ chatId: space,
226
+ kind: "text"
227
+ })
228
+ };
229
+ },
230
+ sendMedia: async ({ cfg, to, text, mediaUrl, mediaAccess, mediaLocalRoots, mediaReadFile, accountId, replyToId, threadId }) => {
231
+ if (!mediaUrl) throw new Error("Google Chat mediaUrl is required.");
232
+ const account = resolveGoogleChatAccount({
233
+ cfg,
234
+ accountId
235
+ });
236
+ const space = await resolveGoogleChatOutboundSpace({
237
+ account,
238
+ target: to
239
+ });
240
+ const thread = typeof threadId === "number" ? String(threadId) : threadId ?? replyToId ?? void 0;
241
+ const effectiveMaxBytes = resolveChannelMediaMaxBytes({
242
+ cfg,
243
+ resolveChannelLimitMb: ({ cfg, accountId }) => (cfg.channels?.googlechat)?.accounts?.[accountId]?.mediaMaxMb ?? (cfg.channels?.googlechat)?.mediaMaxMb,
244
+ accountId
245
+ }) ?? (account.config.mediaMaxMb ?? 20) * 1024 * 1024;
246
+ const loaded = /^https?:\/\//i.test(mediaUrl) ? await readRemoteMediaBuffer({
247
+ url: mediaUrl,
248
+ maxBytes: effectiveMaxBytes
249
+ }) : await loadOutboundMediaFromUrl(mediaUrl, {
250
+ maxBytes: effectiveMaxBytes,
251
+ mediaAccess,
252
+ mediaLocalRoots,
253
+ mediaReadFile
254
+ });
255
+ const { sendGoogleChatMessage, uploadGoogleChatAttachment } = await loadGoogleChatChannelRuntime$2();
256
+ const upload = await uploadGoogleChatAttachment({
257
+ account,
258
+ space,
259
+ filename: loaded.fileName ?? "attachment",
260
+ buffer: loaded.buffer,
261
+ contentType: loaded.contentType
262
+ });
263
+ const messageId = (await sendGoogleChatMessage({
264
+ account,
265
+ space,
266
+ text,
267
+ thread,
268
+ attachments: upload.attachmentUploadToken ? [{
269
+ attachmentUploadToken: upload.attachmentUploadToken,
270
+ contentName: loaded.fileName
271
+ }] : void 0
272
+ }))?.messageName ?? "";
273
+ return {
274
+ messageId,
275
+ chatId: space,
276
+ receipt: createGoogleChatSendReceipt({
277
+ messageId,
278
+ chatId: space,
279
+ kind: "media"
280
+ })
281
+ };
282
+ }
283
+ }
284
+ };
285
+ const googlechatMessageAdapter = defineChannelMessageAdapter({
286
+ id: "googlechat",
287
+ durableFinal: { capabilities: {
288
+ text: true,
289
+ media: true,
290
+ thread: true,
291
+ messageSendingHooks: true
292
+ } },
293
+ send: {
294
+ text: googlechatOutboundAdapter.attachedResults.sendText,
295
+ media: googlechatOutboundAdapter.attachedResults.sendMedia
296
+ }
297
+ });
298
+ //#endregion
299
+ //#region extensions/googlechat/src/doctor.ts
300
+ function asObjectRecord(value) {
301
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
302
+ }
303
+ function isGoogleChatMutableAllowEntry(raw) {
304
+ const text = raw.trim();
305
+ if (!text || text === "*") return false;
306
+ const withoutPrefix = text.replace(/^(googlechat|google-chat|gchat):/i, "").trim();
307
+ if (!withoutPrefix) return false;
308
+ return withoutPrefix.replace(/^users\//i, "").includes("@");
309
+ }
310
+ const collectGoogleChatMutableAllowlistWarnings = createDangerousNameMatchingMutableAllowlistWarningCollector({
311
+ channel: "googlechat",
312
+ detector: isGoogleChatMutableAllowEntry,
313
+ collectLists: (scope) => {
314
+ const lists = [{
315
+ pathLabel: `${scope.prefix}.groupAllowFrom`,
316
+ list: scope.account.groupAllowFrom
317
+ }];
318
+ const dm = asObjectRecord(scope.account.dm);
319
+ if (dm) lists.push({
320
+ pathLabel: `${scope.prefix}.dm.allowFrom`,
321
+ list: dm.allowFrom
322
+ });
323
+ const groups = asObjectRecord(scope.account.groups);
324
+ if (groups) for (const [groupKey, groupRaw] of Object.entries(groups)) {
325
+ const group = asObjectRecord(groupRaw);
326
+ if (!group) continue;
327
+ lists.push({
328
+ pathLabel: `${scope.prefix}.groups.${groupKey}.users`,
329
+ list: group.users
330
+ });
331
+ }
332
+ return lists;
333
+ }
334
+ });
335
+ //#endregion
336
+ //#region extensions/googlechat/src/gateway.ts
337
+ const loadGoogleChatChannelRuntime$1 = createLazyRuntimeNamedExport(() => import("./channel.runtime-en3RNg9S.js"), "googleChatChannelRuntime");
338
+ async function startGoogleChatGatewayAccount(ctx) {
339
+ const account = ctx.account;
340
+ const statusSink = createAccountStatusSink({
341
+ accountId: account.accountId,
342
+ setStatus: ctx.setStatus
343
+ });
344
+ ctx.log?.info?.(`[${account.accountId}] starting Google Chat webhook`);
345
+ const { resolveGoogleChatWebhookPath, startGoogleChatMonitor } = await loadGoogleChatChannelRuntime$1();
346
+ statusSink({
347
+ running: true,
348
+ lastStartAt: Date.now(),
349
+ webhookPath: resolveGoogleChatWebhookPath({ account }),
350
+ audienceType: account.config.audienceType,
351
+ audience: account.config.audience
352
+ });
353
+ await runPassiveAccountLifecycle({
354
+ abortSignal: ctx.abortSignal,
355
+ start: async () => await startGoogleChatMonitor({
356
+ account,
357
+ config: ctx.cfg,
358
+ runtime: ctx.runtime,
359
+ abortSignal: ctx.abortSignal,
360
+ webhookPath: account.config.webhookPath,
361
+ webhookUrl: account.config.webhookUrl,
362
+ statusSink
363
+ }),
364
+ stop: async (unregister) => {
365
+ unregister?.();
366
+ },
367
+ onStop: async () => {
368
+ statusSink({
369
+ running: false,
370
+ lastStopAt: Date.now()
371
+ });
372
+ }
373
+ });
374
+ }
375
+ //#endregion
376
+ //#region extensions/googlechat/src/channel.ts
377
+ const loadGoogleChatChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-en3RNg9S.js"), "googleChatChannelRuntime");
378
+ const meta = {
379
+ id: "googlechat",
380
+ label: "Google Chat",
381
+ selectionLabel: "Google Chat (Chat API)",
382
+ docsPath: "/channels/googlechat",
383
+ docsLabel: "googlechat",
384
+ blurb: "Google Workspace Chat app with HTTP webhook.",
385
+ aliases: ["gchat", "google-chat"],
386
+ order: 55,
387
+ detailLabel: "Google Chat",
388
+ systemImage: "message.badge",
389
+ markdownCapable: true
390
+ };
391
+ const googleChatConfigAdapter = createScopedChannelConfigAdapter({
392
+ sectionKey: "googlechat",
393
+ listAccountIds: listGoogleChatAccountIds,
394
+ resolveAccount: adaptScopedAccountAccessor(resolveGoogleChatAccount),
395
+ resolveAccessorAccount: resolveGoogleChatConfigAccessorAccount,
396
+ defaultAccountId: resolveDefaultGoogleChatAccountId,
397
+ clearBaseFields: [
398
+ "serviceAccount",
399
+ "serviceAccountFile",
400
+ "audienceType",
401
+ "audience",
402
+ "webhookPath",
403
+ "webhookUrl",
404
+ "botUser",
405
+ "name"
406
+ ],
407
+ resolveAllowFrom: (account) => account.config.dm?.allowFrom,
408
+ formatAllowFrom: (allowFrom) => formatNormalizedAllowFromEntries({
409
+ allowFrom,
410
+ normalizeEntry: formatAllowFromEntry
411
+ }),
412
+ resolveDefaultTo: (account) => account.config.defaultTo
413
+ });
414
+ const googlechatActions = {
415
+ describeMessageTool: ({ cfg, accountId }) => {
416
+ const accounts = accountId ? [resolveGoogleChatAccount({
417
+ cfg,
418
+ accountId
419
+ })].filter((account) => account.enabled && account.credentialSource !== "none") : listGoogleChatAccountIds(cfg).map((id) => resolveGoogleChatAccount({
420
+ cfg,
421
+ accountId: id
422
+ })).filter((account) => account.enabled && account.credentialSource !== "none");
423
+ if (accounts.length === 0) return null;
424
+ const actions = new Set(["send", "upload-file"]);
425
+ if (accounts.some((account) => account.config.actions?.reactions !== false)) {
426
+ actions.add("react");
427
+ actions.add("reactions");
428
+ }
429
+ return { actions: Array.from(actions) };
430
+ },
431
+ extractToolSend: ({ args }) => extractToolSend(args, "sendMessage"),
432
+ handleAction: async (ctx) => {
433
+ const { googlechatMessageActions } = await import("./actions-YK1wn4ed.js");
434
+ if (!googlechatMessageActions.handleAction) throw new Error("Google Chat actions are not available.");
435
+ return await googlechatMessageActions.handleAction(ctx);
436
+ }
437
+ };
438
+ const googlechatPlugin = createChatChannelPlugin({
439
+ base: {
440
+ id: "googlechat",
441
+ meta: { ...meta },
442
+ setup: googlechatSetupAdapter,
443
+ setupWizard: googlechatSetupWizard,
444
+ capabilities: {
445
+ chatTypes: [
446
+ "direct",
447
+ "group",
448
+ "thread"
449
+ ],
450
+ reactions: true,
451
+ threads: true,
452
+ media: true,
453
+ nativeCommands: false,
454
+ blockStreaming: true
455
+ },
456
+ streaming: { blockStreamingCoalesceDefaults: {
457
+ minChars: 1500,
458
+ idleMs: 1e3
459
+ } },
460
+ reload: { configPrefixes: ["channels.googlechat"] },
461
+ configSchema: buildChannelConfigSchema(GoogleChatConfigSchema),
462
+ config: {
463
+ ...googleChatConfigAdapter,
464
+ isConfigured: (account) => account.credentialSource !== "none",
465
+ describeAccount: (account) => describeAccountSnapshot({
466
+ account,
467
+ configured: account.credentialSource !== "none",
468
+ extra: { credentialSource: account.credentialSource }
469
+ })
470
+ },
471
+ approvalCapability: googleChatApprovalAuth,
472
+ secrets: {
473
+ secretTargetRegistryEntries,
474
+ collectRuntimeConfigAssignments
475
+ },
476
+ groups: googlechatGroupsAdapter,
477
+ messaging: {
478
+ targetPrefixes: [
479
+ "googlechat",
480
+ "google-chat",
481
+ "gchat"
482
+ ],
483
+ normalizeTarget: normalizeGoogleChatTarget,
484
+ targetResolver: {
485
+ looksLikeId: (raw, normalized) => {
486
+ const value = normalized ?? raw.trim();
487
+ return isGoogleChatSpaceTarget(value) || isGoogleChatUserTarget(value);
488
+ },
489
+ hint: "<spaces/{space}|users/{user}>"
490
+ }
491
+ },
492
+ directory: googlechatDirectoryAdapter,
493
+ message: googlechatMessageAdapter,
494
+ resolver: { resolveTargets: async ({ inputs, kind }) => {
495
+ return inputs.map((input) => {
496
+ const normalized = normalizeGoogleChatTarget(input);
497
+ if (!normalized) return {
498
+ input,
499
+ resolved: false,
500
+ note: "empty target"
501
+ };
502
+ if (kind === "user" && isGoogleChatUserTarget(normalized)) return {
503
+ input,
504
+ resolved: true,
505
+ id: normalized
506
+ };
507
+ if (kind === "group" && isGoogleChatSpaceTarget(normalized)) return {
508
+ input,
509
+ resolved: true,
510
+ id: normalized
511
+ };
512
+ return {
513
+ input,
514
+ resolved: false,
515
+ note: "use spaces/{space} or users/{user}"
516
+ };
517
+ });
518
+ } },
519
+ actions: googlechatActions,
520
+ doctor: {
521
+ dmAllowFromMode: "nestedOnly",
522
+ groupModel: "route",
523
+ groupAllowFromFallbackToAllowFrom: false,
524
+ warnOnEmptyGroupSenderAllowlist: false,
525
+ legacyConfigRules,
526
+ normalizeCompatibilityConfig,
527
+ collectMutableAllowlistWarnings: collectGoogleChatMutableAllowlistWarnings
528
+ },
529
+ status: createComputedAccountStatusAdapter({
530
+ defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID),
531
+ collectStatusIssues: (accounts) => accounts.flatMap((entry) => {
532
+ const accountId = entry.accountId ?? DEFAULT_ACCOUNT_ID;
533
+ const enabled = entry.enabled !== false;
534
+ const configured = entry.configured === true;
535
+ if (!enabled || !configured) return [];
536
+ const issues = [];
537
+ if (!entry.audience) issues.push({
538
+ channel: "googlechat",
539
+ accountId,
540
+ kind: "config",
541
+ message: "Google Chat audience is missing (set channels.googlechat.audience).",
542
+ fix: "Set channels.googlechat.audienceType and channels.googlechat.audience."
543
+ });
544
+ if (!entry.audienceType) issues.push({
545
+ channel: "googlechat",
546
+ accountId,
547
+ kind: "config",
548
+ message: "Google Chat audienceType is missing (app-url or project-number).",
549
+ fix: "Set channels.googlechat.audienceType and channels.googlechat.audience."
550
+ });
551
+ return issues;
552
+ }),
553
+ buildChannelSummary: ({ snapshot }) => buildPassiveProbedChannelStatusSummary(snapshot, {
554
+ credentialSource: snapshot.credentialSource ?? "none",
555
+ audienceType: snapshot.audienceType ?? null,
556
+ audience: snapshot.audience ?? null,
557
+ webhookPath: snapshot.webhookPath ?? null,
558
+ webhookUrl: snapshot.webhookUrl ?? null
559
+ }),
560
+ probeAccount: async ({ account }) => (await loadGoogleChatChannelRuntime()).probeGoogleChat(account),
561
+ resolveAccountSnapshot: ({ account }) => ({
562
+ accountId: account.accountId,
563
+ name: account.name,
564
+ enabled: account.enabled,
565
+ configured: account.credentialSource !== "none",
566
+ extra: {
567
+ credentialSource: account.credentialSource,
568
+ audienceType: account.config.audienceType,
569
+ audience: account.config.audience,
570
+ webhookPath: account.config.webhookPath,
571
+ webhookUrl: account.config.webhookUrl,
572
+ dmPolicy: account.config.dm?.policy ?? "pairing"
573
+ }
574
+ })
575
+ }),
576
+ gateway: { startAccount: startGoogleChatGatewayAccount }
577
+ },
578
+ pairing: { text: googlechatPairingTextAdapter },
579
+ security: googlechatSecurityAdapter,
580
+ threading: googlechatThreadingAdapter,
581
+ outbound: googlechatOutboundAdapter
582
+ });
583
+ //#endregion
584
+ export { resolveGoogleChatOutboundSpace as n, googlechatPlugin as t };
@@ -0,0 +1,6 @@
1
+ import { buildChannelConfigSchema } from "klaw/plugin-sdk/channel-config-primitives";
2
+ import { GoogleChatConfigSchema } from "klaw/plugin-sdk/bundled-channel-config-schema";
3
+ //#region extensions/googlechat/src/config-schema.ts
4
+ const GoogleChatChannelConfigSchema = buildChannelConfigSchema(GoogleChatConfigSchema);
5
+ //#endregion
6
+ export { GoogleChatChannelConfigSchema };
@@ -0,0 +1,2 @@
1
+ import { t as googlechatPlugin } from "./channel-DFZdjXD6.js";
2
+ export { googlechatPlugin };