@fased/fased 0.1.36 → 0.1.38
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/config/capability-catalog.json +241 -0
- package/config/dependency-ownership.json +130 -0
- package/config/official-channel-catalog.json +39 -0
- package/dist/agents/tools/web-fetch-utils.js +2 -1
- package/dist/agents/tools/web-fetch-visibility.js +3 -1
- package/dist/brand.js +1 -1
- package/dist/browser/pw-session.js +2 -1
- package/dist/browser/pw-tools-core.state.js +3 -2
- package/dist/browser/runtime-dependency.js +27 -0
- package/dist/build-info.json +3 -3
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/capabilities/catalog.js +228 -0
- package/dist/cli/components-cli.js +105 -0
- package/dist/cli/hooks-cli.js +1 -1
- package/dist/cli/plugins-cli.js +3 -3
- package/dist/cli/program/register.subclis.js +9 -0
- package/dist/cli/update-cli/update-command.js +1 -1
- package/dist/commands/doctor-capabilities.js +26 -0
- package/dist/commands/doctor.js +2 -0
- package/dist/control-ui/assets/{app-DXYMrRJ9.js → app-JBrTSsNu.js} +1480 -1465
- package/dist/control-ui/assets/{index-iGQkJE0l.js → index-H-2DWAnH.js} +3 -3
- package/dist/control-ui/index.html +1 -1
- package/dist/gateway/method-scopes.js +1 -0
- package/dist/gateway/server-methods/plugins-marketplace.js +1 -1
- package/dist/gateway/server-methods/services.js +8 -0
- package/dist/gateway/server-methods-list.js +1 -0
- package/dist/infra/optional-runtime-dependency.js +46 -0
- package/dist/media/image-ops.js +6 -1
- package/dist/media/input-files.js +11 -2
- package/dist/media/mime.js +6 -1
- package/dist/memory/sqlite-vec.js +7 -1
- package/dist/plugin-sdk/{accounts-VqAX3HJ0.js → accounts-BwkH5bTD.js} +1 -1
- package/dist/plugin-sdk/{accounts-Zgt0NP54.js → accounts-RT6y7n3H.js} +1 -1
- package/dist/plugin-sdk/{actions-lB3PCwsz.js → actions-BrU_JMqM.js} +2 -2
- package/dist/plugin-sdk/{actions-BI5QViLk.js → actions-CUdVHzeJ.js} +2 -2
- package/dist/plugin-sdk/{active-listener-DKZiSaRA.js → active-listener-CE8t5g6l.js} +1 -1
- package/dist/plugin-sdk/{active-listener-D6_pdTMC.js → active-listener-Dx1SEGDn.js} +1 -1
- package/dist/plugin-sdk/{audio-preflight-Dx8J7XhV.js → audio-preflight-BPK8t0tI.js} +22 -22
- package/dist/plugin-sdk/{audio-preflight-CeRstduc.js → audio-preflight-kCa_KGRH.js} +22 -22
- package/dist/plugin-sdk/{audit-BImNOQvk.js → audit-DxB2Kml5.js} +11 -11
- package/dist/plugin-sdk/{audit-CKWkq0Un.js → audit-sSeRDwJb.js} +11 -11
- package/dist/plugin-sdk/channel-plugin-common.js +3 -2
- package/dist/plugin-sdk/{chunk-skAJZWCT.js → chunk-KCxbJLsV.js} +1 -1
- package/dist/plugin-sdk/{chunk-Cjw4712g.js → chunk-M2d7r-Zt.js} +1 -1
- package/dist/plugin-sdk/{chunk-items-Df5811D0.js → chunk-items-DGHUeFuI.js} +1 -1
- package/dist/plugin-sdk/command-status.js +22 -22
- package/dist/plugin-sdk/{commands-registry-5J619bQ2.js → commands-registry-CdT-nl7v.js} +2 -2
- package/dist/plugin-sdk/{commands-registry-CoLAT03J.js → commands-registry-DoWdYAJd.js} +2 -2
- package/dist/plugin-sdk/{common-CSTxewqY.js → common-Cpw-vuuM.js} +1 -1
- package/dist/plugin-sdk/{common-BiF0sTnY.js → common-DJWrErdE.js} +1 -1
- package/dist/plugin-sdk/{config-BxVjLTIv.js → config-C0qggNKQ.js} +7 -7
- package/dist/plugin-sdk/{config-TFokWwvO.js → config-CgwTaper.js} +45 -2
- package/dist/plugin-sdk/{config-DXlISPlx.js → config-DtqAN2L3.js} +45 -2
- package/dist/plugin-sdk/discord.js +2 -1
- package/dist/plugin-sdk/{fetch-guard-DPMynms8.js → fetch-guard-BLdujDnt.js} +1 -1
- package/dist/plugin-sdk/{fetch-guard-COLmW2TM.js → fetch-guard-DTKgMN9f.js} +1 -1
- package/dist/plugin-sdk/{handle-action-C-UndB8E.js → handle-action-B61D85yo.js} +12 -12
- package/dist/plugin-sdk/{handle-action-hhufKxmU.js → handle-action-CjcxGzQD.js} +12 -12
- package/dist/plugin-sdk/index.js +22 -22
- package/dist/plugin-sdk/{login-DL1oBBfL.js → login-CB_nCjX3.js} +3 -3
- package/dist/plugin-sdk/{login-Dnxas1dI.js → login-CzUuDd1v.js} +3 -3
- package/dist/plugin-sdk/{login-qr-CVQsGWKq.js → login-qr-D7MEpFza.js} +3 -3
- package/dist/plugin-sdk/{login-qr-B343JNXJ.js → login-qr-DgxfBFVN.js} +3 -3
- package/dist/plugin-sdk/{manager-BytwRIfK.js → manager-9see0IX5.js} +8 -3
- package/dist/plugin-sdk/{manager-BZjd_PCt.js → manager-D2kZ0Cps.js} +8 -3
- package/dist/plugin-sdk/{markdown-tables-krKiU4cT.js → markdown-tables-CCSD52rA.js} +1 -1
- package/dist/plugin-sdk/{markdown-tables-9rJDQ1X-.js → markdown-tables-DWUNvLrc.js} +1 -1
- package/dist/plugin-sdk/{media-D7ZkWU-A.js → media-C7YT4DeU.js} +13 -4
- package/dist/plugin-sdk/{media-C6C2c9a4.js → media-Cxw-xLGU.js} +13 -4
- package/dist/plugin-sdk/{monitor-BsLMfn3U.js → monitor-6lkdOqhQ.js} +26 -26
- package/dist/plugin-sdk/{monitor-BCxkQBoh.js → monitor-C6Ohw9BA.js} +26 -26
- package/dist/plugin-sdk/{monitor-BzDW50H6.js → monitor-o20KTHIi.js} +29 -29
- package/dist/plugin-sdk/{monitor-CVQNDfhs.js → monitor-rOs3mUol.js} +27 -27
- package/dist/plugin-sdk/{openresponses-http-BB67Z4QM.js → openresponses-http-BJONnUdy.js} +22 -22
- package/dist/plugin-sdk/{openresponses-http-NE76GGhj.js → openresponses-http-DkWqYznu.js} +22 -22
- package/dist/plugin-sdk/{ssrf-u0Ul7okY.js → optional-runtime-dependency-szS49voX.js} +46 -2
- package/dist/plugin-sdk/{outbound-PGNWU6T-.js → outbound-BCxOxdi-.js} +6 -6
- package/dist/plugin-sdk/{outbound-BHWJD9q0.js → outbound-JIwQbpRY.js} +6 -6
- package/dist/plugin-sdk/{outbound-attachment-BVzfhqnk.js → outbound-attachment-C-jSFaEB.js} +1 -1
- package/dist/plugin-sdk/{outbound-attachment-ClMvNW17.js → outbound-attachment-D6tj5Y5H.js} +1 -1
- package/dist/plugin-sdk/{pi-embedded-runner-DQ6UPx6-.js → pi-embedded-runner-DqDy0MWN.js} +72 -60
- package/dist/plugin-sdk/{pi-model-discovery-D51L5E9I.js → pi-model-discovery-DadlvsZW.js} +1 -1
- package/dist/plugin-sdk/{pi-model-discovery-runtime-DxoFm4Vd.js → pi-model-discovery-runtime-C5ssE6EW.js} +1 -1
- package/dist/plugin-sdk/{pi-model-discovery-runtime-DRuh4PNV.js → pi-model-discovery-runtime-DAaOPt64.js} +2 -2
- package/dist/plugin-sdk/{pi-model-discovery-runtime-BTWgkx4x.js → pi-model-discovery-runtime-gd77b0UF.js} +2 -2
- package/dist/plugin-sdk/{pi-model-discovery-CkH5l9X5.js → pi-model-discovery-yifTIDIn.js} +1 -1
- package/dist/plugin-sdk/{pw-ai-DZs6uYRd.js → pw-ai-Boor5vYw.js} +6 -5
- package/dist/plugin-sdk/{pw-ai-Cn-EUPZK.js → pw-ai-sH1Pi-Fh.js} +6 -5
- package/dist/plugin-sdk/{registry-B4HvWzob.js → registry-DNkJsNsz.js} +4 -3
- package/dist/plugin-sdk/{replies-jDMUBsNO.js → replies-fvzN5wnU.js} +2 -2
- package/dist/plugin-sdk/{replies-B_LW9c9f.js → replies-zebgZCHX.js} +2 -2
- package/dist/plugin-sdk/{resolve-route-_YZHbS-z.js → resolve-route-CNhTJG_2.js} +1 -1
- package/dist/plugin-sdk/{resolve-route-DlHzggnG.js → resolve-route-DO0WR4nB.js} +1 -1
- package/dist/plugin-sdk/{resolve-utils-zBhVX3Vx.js → resolve-utils-bixHYDBj.js} +1 -1
- package/dist/plugin-sdk/{retry-policy-DGLs5ebP.js → retry-policy-BLYEgIwP.js} +1 -1
- package/dist/plugin-sdk/{retry-policy-DaodShGa.js → retry-policy-sM01QZT2.js} +1 -1
- package/dist/plugin-sdk/{runtime-Dd0sswuW.js → runtime-BPyuAmka.js} +4 -3
- package/dist/plugin-sdk/{paths-CBCpJ5bu.js → runtime-dependency-Csswyv5r.js} +27 -3
- package/dist/plugin-sdk/{paths-DW-U2r7Y.js → runtime-dependency-Deg_sw2k.js} +36 -12
- package/dist/plugin-sdk/sat-runtime.js +1 -0
- package/dist/plugin-sdk/{send-8remZhsH.js → send-B09HRfHN.js} +6 -6
- package/dist/plugin-sdk/{send-DaaAscWj.js → send-BBYcgXA4.js} +5 -5
- package/dist/plugin-sdk/{send-DFTB0cnx.js → send-BQXQA81e.js} +6 -6
- package/dist/plugin-sdk/{send-CtMVvMJs.js → send-BzFdvD_i.js} +6 -6
- package/dist/plugin-sdk/{send-Di9irjS-.js → send-C3u-F_8s.js} +6 -6
- package/dist/plugin-sdk/{send-Dl88ZKq2.js → send-D3836_UN.js} +6 -6
- package/dist/plugin-sdk/{send-ifgZCHVB.js → send-D7tr-EsH.js} +5 -5
- package/dist/plugin-sdk/{send-DvUpYh0d.js → send-DRGzRdI3.js} +6 -6
- package/dist/plugin-sdk/{send-D2jlPeKH.js → send-DfkPKz_0.js} +4 -4
- package/dist/plugin-sdk/{send-QSt6nbny.js → send-DsxFXrCO.js} +4 -4
- package/dist/plugin-sdk/{session-CknrceVU.js → session-DG_bYisw.js} +2 -2
- package/dist/plugin-sdk/{session-CyRTcJ8N.js → session-EIStzK0E.js} +2 -2
- package/dist/plugin-sdk/{skill-commands-DHxkTA0s.js → skill-commands-CkgGmWBS.js} +2 -2
- package/dist/plugin-sdk/{skill-commands-CLXAG5sU.js → skill-commands-hyZA0LE3.js} +2 -2
- package/dist/plugin-sdk/{slack-Br9c6Yzs.js → slack-BErIh0uj.js} +34 -34
- package/dist/plugin-sdk/{slack-BpJXkwxF.js → slack-CGTAN4UD.js} +34 -34
- package/dist/plugin-sdk/{slack-actions-8tLGt1Ht.js → slack-actions-BQawWGTJ.js} +11 -11
- package/dist/plugin-sdk/{slack-actions-CDSSRo8Y.js → slack-actions-DDMszx56.js} +11 -11
- package/dist/plugin-sdk/slack.js +2 -1
- package/dist/plugin-sdk/src/brand.d.ts +2 -2
- package/dist/plugin-sdk/src/browser/runtime-dependency.d.ts +3 -0
- package/dist/plugin-sdk/src/infra/optional-runtime-dependency.d.ts +6 -0
- package/dist/plugin-sdk/{ssrf-fG4UHKBw.js → ssrf-Cce6LubA.js} +41 -7
- package/dist/plugin-sdk/{status-DoxnzyMC.js → status-CCGFb0f2.js} +76 -64
- package/dist/plugin-sdk/{sticker-cache-zmJ39ByC.js → sticker-cache-CKAkkCoU.js} +3 -3
- package/dist/plugin-sdk/{sticker-cache-D7WcMYsF.js → sticker-cache-wxl1Me2i.js} +3 -3
- package/dist/plugin-sdk/{tables-CkxblF0u.js → tables-BD7H5ug-.js} +1 -1
- package/dist/plugin-sdk/{tables-RBtf8G4P.js → tables-CJE8kB35.js} +1 -1
- package/dist/plugin-sdk/{telegram-actions-DAeYXSLk.js → telegram-actions-BRUNEXMr.js} +25 -25
- package/dist/plugin-sdk/{telegram-actions-BDeS3ocd.js → telegram-actions-r86ntIKR.js} +25 -25
- package/dist/plugin-sdk/telegram.js +2 -1
- package/dist/plugin-sdk/{thread-bindings.lifecycle-DsB94WbE.js → thread-bindings.lifecycle-Djem8FWF.js} +2 -2
- package/dist/plugin-sdk/{thread-bindings.lifecycle-DMhV3TsR.js → thread-bindings.lifecycle-gmHv3hc7.js} +2 -2
- package/dist/plugin-sdk/{thread-bindings.state-DYWpy7hJ.js → thread-bindings.state-CNT2vxm3.js} +2 -2
- package/dist/plugin-sdk/{thread-bindings.state-DG5cBaRn.js → thread-bindings.state-D8kN2X6H.js} +2 -2
- package/dist/plugin-sdk/{web-DJwacWQo.js → web-02I0vmdu.js} +26 -26
- package/dist/plugin-sdk/{web-IJ4NoGPJ.js → web-CXz56wyu.js} +26 -26
- package/dist/plugin-sdk/{whatsapp-actions-DAY8hWpD.js → whatsapp-actions-68Mfs2dJ.js} +12 -12
- package/dist/plugin-sdk/{whatsapp-actions-6opfo-oB.js → whatsapp-actions-DRqtzvTO.js} +12 -12
- package/dist/plugin-sdk/whatsapp.js +2 -1
- package/dist/plugin-sdk/{wsl-B2euLEc2.js → wsl-DcM2PgSS.js} +3 -3
- package/dist/plugin-sdk/{wsl-B8eyviuv.js → wsl-PXrdWitE.js} +3 -3
- package/dist/plugins/update.js +1 -1
- package/dist/tts/tts-core.js +6 -1
- package/dist/wizard/onboarding.finalize.js +9 -0
- package/extensions/acpx/package.json +1 -1
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/fased-federation/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +12 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +2 -2
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +12 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +12 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/sat-mining/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/synology-chat/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +12 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +12 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +12 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +12 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +22 -15
- package/extensions/feishu/fased.plugin.json +0 -10
- package/extensions/feishu/index.ts +0 -63
- package/extensions/feishu/package.json +0 -33
- package/extensions/feishu/skills/feishu-doc/SKILL.md +0 -211
- package/extensions/feishu/skills/feishu-doc/references/block-types.md +0 -103
- package/extensions/feishu/skills/feishu-drive/SKILL.md +0 -97
- package/extensions/feishu/skills/feishu-perm/SKILL.md +0 -119
- package/extensions/feishu/skills/feishu-wiki/SKILL.md +0 -111
- package/extensions/feishu/src/accounts.ts +0 -159
- package/extensions/feishu/src/bitable.ts +0 -713
- package/extensions/feishu/src/bot.ts +0 -979
- package/extensions/feishu/src/channel.ts +0 -359
- package/extensions/feishu/src/client.ts +0 -118
- package/extensions/feishu/src/config-schema.ts +0 -226
- package/extensions/feishu/src/dedup.ts +0 -54
- package/extensions/feishu/src/directory.ts +0 -177
- package/extensions/feishu/src/doc-schema.ts +0 -122
- package/extensions/feishu/src/docx.ts +0 -998
- package/extensions/feishu/src/drive-schema.ts +0 -46
- package/extensions/feishu/src/drive.ts +0 -232
- package/extensions/feishu/src/dynamic-agent.ts +0 -131
- package/extensions/feishu/src/external-keys.ts +0 -19
- package/extensions/feishu/src/media.ts +0 -447
- package/extensions/feishu/src/mention.ts +0 -133
- package/extensions/feishu/src/monitor.ts +0 -434
- package/extensions/feishu/src/onboarding.ts +0 -430
- package/extensions/feishu/src/outbound.ts +0 -56
- package/extensions/feishu/src/perm-schema.ts +0 -52
- package/extensions/feishu/src/perm.ts +0 -180
- package/extensions/feishu/src/policy.ts +0 -116
- package/extensions/feishu/src/probe.ts +0 -44
- package/extensions/feishu/src/reactions.ts +0 -160
- package/extensions/feishu/src/reply-dispatcher.ts +0 -239
- package/extensions/feishu/src/runtime.ts +0 -14
- package/extensions/feishu/src/send-result.ts +0 -29
- package/extensions/feishu/src/send-target.ts +0 -25
- package/extensions/feishu/src/send.ts +0 -313
- package/extensions/feishu/src/streaming-card.ts +0 -218
- package/extensions/feishu/src/targets.ts +0 -78
- package/extensions/feishu/src/tool-account.ts +0 -58
- package/extensions/feishu/src/tools-config.ts +0 -21
- package/extensions/feishu/src/types.ts +0 -81
- package/extensions/feishu/src/typing.ts +0 -80
- package/extensions/feishu/src/wiki-schema.ts +0 -55
- package/extensions/feishu/src/wiki.ts +0 -237
- package/extensions/googlechat/fased.plugin.json +0 -9
- package/extensions/googlechat/index.ts +0 -19
- package/extensions/googlechat/package.json +0 -37
- package/extensions/googlechat/src/accounts.ts +0 -147
- package/extensions/googlechat/src/actions.ts +0 -176
- package/extensions/googlechat/src/api.ts +0 -282
- package/extensions/googlechat/src/auth.ts +0 -137
- package/extensions/googlechat/src/channel.ts +0 -591
- package/extensions/googlechat/src/monitor.ts +0 -996
- package/extensions/googlechat/src/onboarding.ts +0 -344
- package/extensions/googlechat/src/runtime.ts +0 -14
- package/extensions/googlechat/src/targets.ts +0 -65
- package/extensions/googlechat/src/types.config.ts +0 -3
- package/extensions/googlechat/src/types.ts +0 -73
|
@@ -1,344 +0,0 @@
|
|
|
1
|
-
import type { FasedAgentConfig, DmPolicy } from "fased/plugin-sdk";
|
|
2
|
-
import {
|
|
3
|
-
addWildcardAllowFrom,
|
|
4
|
-
formatDocsLink,
|
|
5
|
-
mergeAllowFromEntries,
|
|
6
|
-
promptAccountId,
|
|
7
|
-
type ChannelOnboardingAdapter,
|
|
8
|
-
type ChannelOnboardingDmPolicy,
|
|
9
|
-
type WizardPrompter,
|
|
10
|
-
DEFAULT_ACCOUNT_ID,
|
|
11
|
-
normalizeAccountId,
|
|
12
|
-
migrateBaseNameToDefaultAccount,
|
|
13
|
-
} from "fased/plugin-sdk";
|
|
14
|
-
import {
|
|
15
|
-
listGoogleChatAccountIds,
|
|
16
|
-
resolveDefaultGoogleChatAccountId,
|
|
17
|
-
resolveGoogleChatAccount,
|
|
18
|
-
} from "./accounts.js";
|
|
19
|
-
|
|
20
|
-
const channel = "googlechat" as const;
|
|
21
|
-
|
|
22
|
-
const ENV_SERVICE_ACCOUNT = "GOOGLE_CHAT_SERVICE_ACCOUNT";
|
|
23
|
-
const ENV_SERVICE_ACCOUNT_FILE = "GOOGLE_CHAT_SERVICE_ACCOUNT_FILE";
|
|
24
|
-
|
|
25
|
-
function setGoogleChatDmPolicy(cfg: FasedAgentConfig, policy: DmPolicy) {
|
|
26
|
-
const allowFrom =
|
|
27
|
-
policy === "open"
|
|
28
|
-
? addWildcardAllowFrom(cfg.channels?.["googlechat"]?.dm?.allowFrom)
|
|
29
|
-
: undefined;
|
|
30
|
-
return {
|
|
31
|
-
...cfg,
|
|
32
|
-
channels: {
|
|
33
|
-
...cfg.channels,
|
|
34
|
-
googlechat: {
|
|
35
|
-
...cfg.channels?.["googlechat"],
|
|
36
|
-
dm: {
|
|
37
|
-
...cfg.channels?.["googlechat"]?.dm,
|
|
38
|
-
policy,
|
|
39
|
-
...(allowFrom ? { allowFrom } : {}),
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function parseAllowFromInput(raw: string): string[] {
|
|
47
|
-
return raw
|
|
48
|
-
.split(/[\n,;]+/g)
|
|
49
|
-
.map((entry) => entry.trim())
|
|
50
|
-
.filter(Boolean);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async function promptAllowFrom(params: {
|
|
54
|
-
cfg: FasedAgentConfig;
|
|
55
|
-
prompter: WizardPrompter;
|
|
56
|
-
}): Promise<FasedAgentConfig> {
|
|
57
|
-
const current = params.cfg.channels?.["googlechat"]?.dm?.allowFrom ?? [];
|
|
58
|
-
const entry = await params.prompter.text({
|
|
59
|
-
message: "Google Chat allowFrom (users/<id> or raw email; avoid users/<email>)",
|
|
60
|
-
placeholder: "users/123456789, name@example.com",
|
|
61
|
-
initialValue: current[0] ? String(current[0]) : undefined,
|
|
62
|
-
validate: (value) => (String(value ?? "").trim() ? undefined : "Required"),
|
|
63
|
-
});
|
|
64
|
-
const parts = parseAllowFromInput(String(entry));
|
|
65
|
-
const unique = mergeAllowFromEntries(undefined, parts);
|
|
66
|
-
return {
|
|
67
|
-
...params.cfg,
|
|
68
|
-
channels: {
|
|
69
|
-
...params.cfg.channels,
|
|
70
|
-
googlechat: {
|
|
71
|
-
...params.cfg.channels?.["googlechat"],
|
|
72
|
-
enabled: true,
|
|
73
|
-
dm: {
|
|
74
|
-
...params.cfg.channels?.["googlechat"]?.dm,
|
|
75
|
-
policy: "allowlist",
|
|
76
|
-
allowFrom: unique,
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const dmPolicy: ChannelOnboardingDmPolicy = {
|
|
84
|
-
label: "Google Chat",
|
|
85
|
-
channel,
|
|
86
|
-
policyKey: "channels.googlechat.dm.policy",
|
|
87
|
-
allowFromKey: "channels.googlechat.dm.allowFrom",
|
|
88
|
-
getCurrent: (cfg) => cfg.channels?.["googlechat"]?.dm?.policy ?? "pairing",
|
|
89
|
-
setPolicy: (cfg, policy) => setGoogleChatDmPolicy(cfg, policy),
|
|
90
|
-
promptAllowFrom,
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const googleChatUiSetup: ChannelOnboardingAdapter["uiSetup"] = {
|
|
94
|
-
title: "Google Chat",
|
|
95
|
-
detail: "Chat API webhook.",
|
|
96
|
-
notes: [
|
|
97
|
-
"Create a Google Chat app in Google Cloud, enable the Chat API, and create a service account JSON key.",
|
|
98
|
-
"Use the gateway webhook URL or webhook path for inbound Chat events.",
|
|
99
|
-
"Set the audience to the app URL or Google Cloud project number used by the Chat app.",
|
|
100
|
-
],
|
|
101
|
-
fields: [
|
|
102
|
-
{
|
|
103
|
-
label: "Service account file",
|
|
104
|
-
path: ["channels", "googlechat", "serviceAccountFile"],
|
|
105
|
-
placeholder: "/run/secrets/google-chat-service-account.json",
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
label: "Webhook path",
|
|
109
|
-
path: ["channels", "googlechat", "webhookPath"],
|
|
110
|
-
placeholder: "/googlechat",
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
label: "Webhook URL",
|
|
114
|
-
path: ["channels", "googlechat", "webhookUrl"],
|
|
115
|
-
placeholder: "https://agent.example.com/googlechat",
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
label: "Audience type",
|
|
119
|
-
path: ["channels", "googlechat", "audienceType"],
|
|
120
|
-
kind: "select",
|
|
121
|
-
options: [
|
|
122
|
-
{ label: "App URL", value: "app-url" },
|
|
123
|
-
{ label: "Project number", value: "project-number" },
|
|
124
|
-
],
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
label: "Audience",
|
|
128
|
-
path: ["channels", "googlechat", "audience"],
|
|
129
|
-
placeholder: "https://agent.example.com/googlechat or 123456789012",
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
label: "Bot user",
|
|
133
|
-
path: ["channels", "googlechat", "botUser"],
|
|
134
|
-
placeholder: "users/123456789012345678901",
|
|
135
|
-
},
|
|
136
|
-
],
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
function hasGoogleChatWebhookConfig(cfg: FasedAgentConfig, accountId: string): boolean {
|
|
140
|
-
const account = resolveGoogleChatAccount({ cfg, accountId });
|
|
141
|
-
return Boolean(account.config.webhookPath?.trim() || account.config.webhookUrl?.trim());
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function hasGoogleChatAudienceConfig(cfg: FasedAgentConfig, accountId: string): boolean {
|
|
145
|
-
const account = resolveGoogleChatAccount({ cfg, accountId });
|
|
146
|
-
return Boolean(
|
|
147
|
-
(account.config.audienceType === "app-url" ||
|
|
148
|
-
account.config.audienceType === "project-number") &&
|
|
149
|
-
account.config.audience?.trim(),
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
function isGoogleChatConfigured(cfg: FasedAgentConfig, accountId: string): boolean {
|
|
154
|
-
const account = resolveGoogleChatAccount({ cfg, accountId });
|
|
155
|
-
return (
|
|
156
|
-
account.credentialSource !== "none" &&
|
|
157
|
-
hasGoogleChatWebhookConfig(cfg, accountId) &&
|
|
158
|
-
hasGoogleChatAudienceConfig(cfg, accountId)
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
function applyAccountConfig(params: {
|
|
163
|
-
cfg: FasedAgentConfig;
|
|
164
|
-
accountId: string;
|
|
165
|
-
patch: Record<string, unknown>;
|
|
166
|
-
}): FasedAgentConfig {
|
|
167
|
-
const { cfg, accountId, patch } = params;
|
|
168
|
-
if (accountId === DEFAULT_ACCOUNT_ID) {
|
|
169
|
-
return {
|
|
170
|
-
...cfg,
|
|
171
|
-
channels: {
|
|
172
|
-
...cfg.channels,
|
|
173
|
-
googlechat: {
|
|
174
|
-
...cfg.channels?.["googlechat"],
|
|
175
|
-
enabled: true,
|
|
176
|
-
...patch,
|
|
177
|
-
},
|
|
178
|
-
},
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
return {
|
|
182
|
-
...cfg,
|
|
183
|
-
channels: {
|
|
184
|
-
...cfg.channels,
|
|
185
|
-
googlechat: {
|
|
186
|
-
...cfg.channels?.["googlechat"],
|
|
187
|
-
enabled: true,
|
|
188
|
-
accounts: {
|
|
189
|
-
...cfg.channels?.["googlechat"]?.accounts,
|
|
190
|
-
[accountId]: {
|
|
191
|
-
...cfg.channels?.["googlechat"]?.accounts?.[accountId],
|
|
192
|
-
enabled: true,
|
|
193
|
-
...patch,
|
|
194
|
-
},
|
|
195
|
-
},
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
async function promptCredentials(params: {
|
|
202
|
-
cfg: FasedAgentConfig;
|
|
203
|
-
prompter: WizardPrompter;
|
|
204
|
-
accountId: string;
|
|
205
|
-
}): Promise<FasedAgentConfig> {
|
|
206
|
-
const { cfg, prompter, accountId } = params;
|
|
207
|
-
const envReady =
|
|
208
|
-
accountId === DEFAULT_ACCOUNT_ID &&
|
|
209
|
-
(Boolean(process.env[ENV_SERVICE_ACCOUNT]) || Boolean(process.env[ENV_SERVICE_ACCOUNT_FILE]));
|
|
210
|
-
if (envReady) {
|
|
211
|
-
const useEnv = await prompter.confirm({
|
|
212
|
-
message: "Use GOOGLE_CHAT_SERVICE_ACCOUNT env vars?",
|
|
213
|
-
initialValue: true,
|
|
214
|
-
});
|
|
215
|
-
if (useEnv) {
|
|
216
|
-
return applyAccountConfig({ cfg, accountId, patch: {} });
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
const method = await prompter.select({
|
|
221
|
-
message: "Google Chat auth method",
|
|
222
|
-
options: [
|
|
223
|
-
{ value: "file", label: "Service account JSON file" },
|
|
224
|
-
{ value: "inline", label: "Paste service account JSON" },
|
|
225
|
-
],
|
|
226
|
-
initialValue: "file",
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
if (method === "file") {
|
|
230
|
-
const path = await prompter.text({
|
|
231
|
-
message: "Service account JSON path",
|
|
232
|
-
placeholder: "/path/to/service-account.json",
|
|
233
|
-
validate: (value) => (String(value ?? "").trim() ? undefined : "Required"),
|
|
234
|
-
});
|
|
235
|
-
return applyAccountConfig({
|
|
236
|
-
cfg,
|
|
237
|
-
accountId,
|
|
238
|
-
patch: { serviceAccountFile: String(path).trim() },
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const json = await prompter.text({
|
|
243
|
-
message: "Service account JSON (single line)",
|
|
244
|
-
placeholder: '{"type":"service_account", ... }',
|
|
245
|
-
validate: (value) => (String(value ?? "").trim() ? undefined : "Required"),
|
|
246
|
-
});
|
|
247
|
-
return applyAccountConfig({
|
|
248
|
-
cfg,
|
|
249
|
-
accountId,
|
|
250
|
-
patch: { serviceAccount: String(json).trim() },
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
async function promptAudience(params: {
|
|
255
|
-
cfg: FasedAgentConfig;
|
|
256
|
-
prompter: WizardPrompter;
|
|
257
|
-
accountId: string;
|
|
258
|
-
}): Promise<FasedAgentConfig> {
|
|
259
|
-
const account = resolveGoogleChatAccount({
|
|
260
|
-
cfg: params.cfg,
|
|
261
|
-
accountId: params.accountId,
|
|
262
|
-
});
|
|
263
|
-
const currentType = account.config.audienceType ?? "app-url";
|
|
264
|
-
const currentAudience = account.config.audience ?? "";
|
|
265
|
-
const audienceType = await params.prompter.select({
|
|
266
|
-
message: "Webhook audience type",
|
|
267
|
-
options: [
|
|
268
|
-
{ value: "app-url", label: "App URL (recommended)" },
|
|
269
|
-
{ value: "project-number", label: "Project number" },
|
|
270
|
-
],
|
|
271
|
-
initialValue: currentType === "project-number" ? "project-number" : "app-url",
|
|
272
|
-
});
|
|
273
|
-
const audience = await params.prompter.text({
|
|
274
|
-
message: audienceType === "project-number" ? "Project number" : "App URL",
|
|
275
|
-
placeholder: audienceType === "project-number" ? "1234567890" : "https://your.host/googlechat",
|
|
276
|
-
initialValue: currentAudience || undefined,
|
|
277
|
-
validate: (value) => (String(value ?? "").trim() ? undefined : "Required"),
|
|
278
|
-
});
|
|
279
|
-
return applyAccountConfig({
|
|
280
|
-
cfg: params.cfg,
|
|
281
|
-
accountId: params.accountId,
|
|
282
|
-
patch: { audienceType, audience: String(audience).trim() },
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
async function noteGoogleChatSetup(prompter: WizardPrompter) {
|
|
287
|
-
await prompter.note(
|
|
288
|
-
[
|
|
289
|
-
"Google Chat apps use service-account auth and an HTTPS webhook.",
|
|
290
|
-
"Set the Chat API scopes in your service account and configure the Chat app URL.",
|
|
291
|
-
"Webhook verification requires audience type + audience value.",
|
|
292
|
-
`Docs: ${formatDocsLink("/channels/googlechat", "channels/googlechat")}`,
|
|
293
|
-
].join("\n"),
|
|
294
|
-
"Google Chat setup",
|
|
295
|
-
);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
export const googlechatOnboardingAdapter: ChannelOnboardingAdapter = {
|
|
299
|
-
channel,
|
|
300
|
-
uiSetup: googleChatUiSetup,
|
|
301
|
-
dmPolicy,
|
|
302
|
-
getStatus: async ({ cfg }) => {
|
|
303
|
-
const configured = listGoogleChatAccountIds(cfg).some((accountId) =>
|
|
304
|
-
isGoogleChatConfigured(cfg, accountId),
|
|
305
|
-
);
|
|
306
|
-
return {
|
|
307
|
-
channel,
|
|
308
|
-
configured,
|
|
309
|
-
statusLines: [
|
|
310
|
-
`Google Chat: ${
|
|
311
|
-
configured ? "configured" : "needs service account, webhook, and audience"
|
|
312
|
-
}`,
|
|
313
|
-
],
|
|
314
|
-
selectionHint: configured ? "configured" : "needs service account, webhook, and audience",
|
|
315
|
-
};
|
|
316
|
-
},
|
|
317
|
-
configure: async ({ cfg, prompter, accountOverrides, shouldPromptAccountIds }) => {
|
|
318
|
-
const override = accountOverrides["googlechat"]?.trim();
|
|
319
|
-
const defaultAccountId = resolveDefaultGoogleChatAccountId(cfg);
|
|
320
|
-
let accountId = override ? normalizeAccountId(override) : defaultAccountId;
|
|
321
|
-
if (shouldPromptAccountIds && !override) {
|
|
322
|
-
accountId = await promptAccountId({
|
|
323
|
-
cfg,
|
|
324
|
-
prompter,
|
|
325
|
-
label: "Google Chat",
|
|
326
|
-
currentId: accountId,
|
|
327
|
-
listAccountIds: listGoogleChatAccountIds,
|
|
328
|
-
defaultAccountId,
|
|
329
|
-
});
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
let next = cfg;
|
|
333
|
-
await noteGoogleChatSetup(prompter);
|
|
334
|
-
next = await promptCredentials({ cfg: next, prompter, accountId });
|
|
335
|
-
next = await promptAudience({ cfg: next, prompter, accountId });
|
|
336
|
-
|
|
337
|
-
const namedConfig = migrateBaseNameToDefaultAccount({
|
|
338
|
-
cfg: next,
|
|
339
|
-
channelKey: "googlechat",
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
return { cfg: namedConfig, accountId };
|
|
343
|
-
},
|
|
344
|
-
};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { PluginRuntime } from "fased/plugin-sdk";
|
|
2
|
-
|
|
3
|
-
let runtime: PluginRuntime | null = null;
|
|
4
|
-
|
|
5
|
-
export function setGoogleChatRuntime(next: PluginRuntime) {
|
|
6
|
-
runtime = next;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function getGoogleChatRuntime(): PluginRuntime {
|
|
10
|
-
if (!runtime) {
|
|
11
|
-
throw new Error("Google Chat runtime not initialized");
|
|
12
|
-
}
|
|
13
|
-
return runtime;
|
|
14
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import type { ResolvedGoogleChatAccount } from "./accounts.js";
|
|
2
|
-
import { findGoogleChatDirectMessage } from "./api.js";
|
|
3
|
-
|
|
4
|
-
export function normalizeGoogleChatTarget(raw?: string | null): string | undefined {
|
|
5
|
-
const trimmed = raw?.trim();
|
|
6
|
-
if (!trimmed) {
|
|
7
|
-
return undefined;
|
|
8
|
-
}
|
|
9
|
-
const withoutPrefix = trimmed.replace(/^(googlechat|google-chat|gchat):/i, "");
|
|
10
|
-
const normalized = withoutPrefix
|
|
11
|
-
.replace(/^user:(users\/)?/i, "users/")
|
|
12
|
-
.replace(/^space:(spaces\/)?/i, "spaces/");
|
|
13
|
-
if (isGoogleChatUserTarget(normalized)) {
|
|
14
|
-
const suffix = normalized.slice("users/".length);
|
|
15
|
-
return suffix.includes("@") ? `users/${suffix.toLowerCase()}` : normalized;
|
|
16
|
-
}
|
|
17
|
-
if (isGoogleChatSpaceTarget(normalized)) {
|
|
18
|
-
return normalized;
|
|
19
|
-
}
|
|
20
|
-
if (normalized.includes("@")) {
|
|
21
|
-
return `users/${normalized.toLowerCase()}`;
|
|
22
|
-
}
|
|
23
|
-
return normalized;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function isGoogleChatUserTarget(value: string): boolean {
|
|
27
|
-
return value.toLowerCase().startsWith("users/");
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function isGoogleChatSpaceTarget(value: string): boolean {
|
|
31
|
-
return value.toLowerCase().startsWith("spaces/");
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function stripMessageSuffix(target: string): string {
|
|
35
|
-
const index = target.indexOf("/messages/");
|
|
36
|
-
if (index === -1) {
|
|
37
|
-
return target;
|
|
38
|
-
}
|
|
39
|
-
return target.slice(0, index);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export async function resolveGoogleChatOutboundSpace(params: {
|
|
43
|
-
account: ResolvedGoogleChatAccount;
|
|
44
|
-
target: string;
|
|
45
|
-
}): Promise<string> {
|
|
46
|
-
const normalized = normalizeGoogleChatTarget(params.target);
|
|
47
|
-
if (!normalized) {
|
|
48
|
-
throw new Error("Missing Google Chat target.");
|
|
49
|
-
}
|
|
50
|
-
const base = stripMessageSuffix(normalized);
|
|
51
|
-
if (isGoogleChatSpaceTarget(base)) {
|
|
52
|
-
return base;
|
|
53
|
-
}
|
|
54
|
-
if (isGoogleChatUserTarget(base)) {
|
|
55
|
-
const dm = await findGoogleChatDirectMessage({
|
|
56
|
-
account: params.account,
|
|
57
|
-
userName: base,
|
|
58
|
-
});
|
|
59
|
-
if (!dm?.name) {
|
|
60
|
-
throw new Error(`No Google Chat DM found for ${base}`);
|
|
61
|
-
}
|
|
62
|
-
return dm.name;
|
|
63
|
-
}
|
|
64
|
-
return base;
|
|
65
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
export type GoogleChatSpace = {
|
|
2
|
-
name?: string;
|
|
3
|
-
displayName?: string;
|
|
4
|
-
type?: string;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
export type GoogleChatUser = {
|
|
8
|
-
name?: string;
|
|
9
|
-
displayName?: string;
|
|
10
|
-
email?: string;
|
|
11
|
-
type?: string;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export type GoogleChatThread = {
|
|
15
|
-
name?: string;
|
|
16
|
-
threadKey?: string;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export type GoogleChatAttachmentDataRef = {
|
|
20
|
-
resourceName?: string;
|
|
21
|
-
attachmentUploadToken?: string;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export type GoogleChatAttachment = {
|
|
25
|
-
name?: string;
|
|
26
|
-
contentName?: string;
|
|
27
|
-
contentType?: string;
|
|
28
|
-
thumbnailUri?: string;
|
|
29
|
-
downloadUri?: string;
|
|
30
|
-
source?: string;
|
|
31
|
-
attachmentDataRef?: GoogleChatAttachmentDataRef;
|
|
32
|
-
driveDataRef?: Record<string, unknown>;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export type GoogleChatUserMention = {
|
|
36
|
-
user?: GoogleChatUser;
|
|
37
|
-
type?: string;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export type GoogleChatAnnotation = {
|
|
41
|
-
type?: string;
|
|
42
|
-
startIndex?: number;
|
|
43
|
-
length?: number;
|
|
44
|
-
userMention?: GoogleChatUserMention;
|
|
45
|
-
slashCommand?: Record<string, unknown>;
|
|
46
|
-
richLinkMetadata?: Record<string, unknown>;
|
|
47
|
-
customEmojiMetadata?: Record<string, unknown>;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export type GoogleChatMessage = {
|
|
51
|
-
name?: string;
|
|
52
|
-
text?: string;
|
|
53
|
-
argumentText?: string;
|
|
54
|
-
sender?: GoogleChatUser;
|
|
55
|
-
thread?: GoogleChatThread;
|
|
56
|
-
attachment?: GoogleChatAttachment[];
|
|
57
|
-
annotations?: GoogleChatAnnotation[];
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
export type GoogleChatEvent = {
|
|
61
|
-
type?: string;
|
|
62
|
-
eventType?: string;
|
|
63
|
-
eventTime?: string;
|
|
64
|
-
space?: GoogleChatSpace;
|
|
65
|
-
user?: GoogleChatUser;
|
|
66
|
-
message?: GoogleChatMessage;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
export type GoogleChatReaction = {
|
|
70
|
-
name?: string;
|
|
71
|
-
user?: GoogleChatUser;
|
|
72
|
-
emoji?: { unicode?: string };
|
|
73
|
-
};
|