@fased/fased 0.1.36 → 0.1.37

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.
Files changed (244) hide show
  1. package/config/capability-catalog.json +241 -0
  2. package/config/dependency-ownership.json +130 -0
  3. package/config/official-channel-catalog.json +39 -0
  4. package/dist/agents/tools/web-fetch-utils.js +2 -1
  5. package/dist/agents/tools/web-fetch-visibility.js +3 -1
  6. package/dist/brand.js +1 -1
  7. package/dist/browser/pw-session.js +2 -1
  8. package/dist/browser/pw-tools-core.state.js +3 -2
  9. package/dist/browser/runtime-dependency.js +27 -0
  10. package/dist/build-info.json +3 -3
  11. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  12. package/dist/capabilities/catalog.js +228 -0
  13. package/dist/cli/components-cli.js +105 -0
  14. package/dist/cli/hooks-cli.js +1 -1
  15. package/dist/cli/plugins-cli.js +3 -3
  16. package/dist/cli/program/register.subclis.js +9 -0
  17. package/dist/cli/update-cli/update-command.js +1 -1
  18. package/dist/commands/doctor-capabilities.js +26 -0
  19. package/dist/commands/doctor.js +2 -0
  20. package/dist/control-ui/assets/{app-DXYMrRJ9.js → app-JBrTSsNu.js} +1480 -1465
  21. package/dist/control-ui/assets/{index-iGQkJE0l.js → index-H-2DWAnH.js} +3 -3
  22. package/dist/control-ui/index.html +1 -1
  23. package/dist/gateway/method-scopes.js +1 -0
  24. package/dist/gateway/server-methods/plugins-marketplace.js +1 -1
  25. package/dist/gateway/server-methods/services.js +8 -0
  26. package/dist/gateway/server-methods-list.js +1 -0
  27. package/dist/infra/optional-runtime-dependency.js +46 -0
  28. package/dist/media/image-ops.js +6 -1
  29. package/dist/media/input-files.js +11 -2
  30. package/dist/media/mime.js +6 -1
  31. package/dist/memory/sqlite-vec.js +7 -1
  32. package/dist/plugin-sdk/{accounts-VqAX3HJ0.js → accounts-BwkH5bTD.js} +1 -1
  33. package/dist/plugin-sdk/{accounts-COY-15zJ.js → accounts-C5BjfxoO.js} +1 -1
  34. package/dist/plugin-sdk/{accounts-Zgt0NP54.js → accounts-RT6y7n3H.js} +1 -1
  35. package/dist/plugin-sdk/{actions-lB3PCwsz.js → actions-BrU_JMqM.js} +2 -2
  36. package/dist/plugin-sdk/{actions-BI5QViLk.js → actions-CUdVHzeJ.js} +2 -2
  37. package/dist/plugin-sdk/{active-listener-DKZiSaRA.js → active-listener-CE8t5g6l.js} +1 -1
  38. package/dist/plugin-sdk/{active-listener-D6_pdTMC.js → active-listener-Dx1SEGDn.js} +1 -1
  39. package/dist/plugin-sdk/{audio-preflight-Dx8J7XhV.js → audio-preflight-C8SbY4fV.js} +22 -22
  40. package/dist/plugin-sdk/{audio-preflight-CeRstduc.js → audio-preflight-CuABlLDL.js} +22 -22
  41. package/dist/plugin-sdk/{audit-BImNOQvk.js → audit-DxB2Kml5.js} +11 -11
  42. package/dist/plugin-sdk/{audit-CKWkq0Un.js → audit-sSeRDwJb.js} +11 -11
  43. package/dist/plugin-sdk/channel-plugin-common.js +3 -2
  44. package/dist/plugin-sdk/{chunk-skAJZWCT.js → chunk-KCxbJLsV.js} +1 -1
  45. package/dist/plugin-sdk/{chunk-Cjw4712g.js → chunk-M2d7r-Zt.js} +1 -1
  46. package/dist/plugin-sdk/{chunk-items-Df5811D0.js → chunk-items-BGbYyNvO.js} +1 -1
  47. package/dist/plugin-sdk/command-status.js +22 -22
  48. package/dist/plugin-sdk/{commands-registry-5J619bQ2.js → commands-registry-CdT-nl7v.js} +2 -2
  49. package/dist/plugin-sdk/{commands-registry-CoLAT03J.js → commands-registry-DoWdYAJd.js} +2 -2
  50. package/dist/plugin-sdk/{common-CSTxewqY.js → common-Cpw-vuuM.js} +1 -1
  51. package/dist/plugin-sdk/{common-BiF0sTnY.js → common-DJWrErdE.js} +1 -1
  52. package/dist/plugin-sdk/{config-BxVjLTIv.js → config-C0qggNKQ.js} +7 -7
  53. package/dist/plugin-sdk/{config-TFokWwvO.js → config-CgwTaper.js} +45 -2
  54. package/dist/plugin-sdk/{config-DXlISPlx.js → config-DtqAN2L3.js} +45 -2
  55. package/dist/plugin-sdk/{config-DgD5T-Ui.js → config-g1MG9Bet.js} +7 -7
  56. package/dist/plugin-sdk/discord.js +2 -1
  57. package/dist/plugin-sdk/{fetch-guard-DPMynms8.js → fetch-guard-BLdujDnt.js} +1 -1
  58. package/dist/plugin-sdk/{fetch-guard-COLmW2TM.js → fetch-guard-DTKgMN9f.js} +1 -1
  59. package/dist/plugin-sdk/{handle-action-C-UndB8E.js → handle-action-B61D85yo.js} +12 -12
  60. package/dist/plugin-sdk/{handle-action-hhufKxmU.js → handle-action-CjcxGzQD.js} +12 -12
  61. package/dist/plugin-sdk/index.js +22 -22
  62. package/dist/plugin-sdk/{login-DL1oBBfL.js → login-CB_nCjX3.js} +3 -3
  63. package/dist/plugin-sdk/{login-YveoqEvH.js → login-CfRfRNc7.js} +2 -2
  64. package/dist/plugin-sdk/{login-Dnxas1dI.js → login-CzUuDd1v.js} +3 -3
  65. package/dist/plugin-sdk/{login-qr-CVQsGWKq.js → login-qr-D7MEpFza.js} +3 -3
  66. package/dist/plugin-sdk/{login-qr-B343JNXJ.js → login-qr-DgxfBFVN.js} +3 -3
  67. package/dist/plugin-sdk/{manager-BytwRIfK.js → manager-9see0IX5.js} +8 -3
  68. package/dist/plugin-sdk/{manager-BZjd_PCt.js → manager-D2kZ0Cps.js} +8 -3
  69. package/dist/plugin-sdk/{markdown-tables-krKiU4cT.js → markdown-tables-CCSD52rA.js} +1 -1
  70. package/dist/plugin-sdk/{markdown-tables-9rJDQ1X-.js → markdown-tables-DWUNvLrc.js} +1 -1
  71. package/dist/plugin-sdk/{media-D7ZkWU-A.js → media-C7YT4DeU.js} +13 -4
  72. package/dist/plugin-sdk/{media-C6C2c9a4.js → media-Cxw-xLGU.js} +13 -4
  73. package/dist/plugin-sdk/{monitor-CVQNDfhs.js → monitor-9X7wapUN.js} +27 -27
  74. package/dist/plugin-sdk/{monitor-BCxkQBoh.js → monitor-B3IfJzKX.js} +26 -26
  75. package/dist/plugin-sdk/{monitor-BzDW50H6.js → monitor-CTjAST_W.js} +27 -27
  76. package/dist/plugin-sdk/{monitor-BsLMfn3U.js → monitor-tYFfy2u-.js} +26 -26
  77. package/dist/plugin-sdk/{openresponses-http-BB67Z4QM.js → openresponses-http-DEB2fEya.js} +22 -22
  78. package/dist/plugin-sdk/{openresponses-http-NE76GGhj.js → openresponses-http-YgMg1jnp.js} +22 -22
  79. package/dist/plugin-sdk/{ssrf-u0Ul7okY.js → optional-runtime-dependency-szS49voX.js} +46 -2
  80. package/dist/plugin-sdk/{outbound-PGNWU6T-.js → outbound-BCxOxdi-.js} +6 -6
  81. package/dist/plugin-sdk/{outbound-BHWJD9q0.js → outbound-JIwQbpRY.js} +6 -6
  82. package/dist/plugin-sdk/{outbound-attachment-BVzfhqnk.js → outbound-attachment-C-jSFaEB.js} +1 -1
  83. package/dist/plugin-sdk/{outbound-attachment-ClMvNW17.js → outbound-attachment-D6tj5Y5H.js} +1 -1
  84. package/dist/plugin-sdk/{pi-embedded-runner-DQ6UPx6-.js → pi-embedded-runner-CUVk8CIj.js} +72 -60
  85. package/dist/plugin-sdk/{pi-model-discovery-D51L5E9I.js → pi-model-discovery-DadlvsZW.js} +1 -1
  86. package/dist/plugin-sdk/{pi-model-discovery-runtime-DxoFm4Vd.js → pi-model-discovery-runtime-C5ssE6EW.js} +1 -1
  87. package/dist/plugin-sdk/{pi-model-discovery-runtime-DRuh4PNV.js → pi-model-discovery-runtime-DAaOPt64.js} +2 -2
  88. package/dist/plugin-sdk/{pi-model-discovery-runtime-CQOauapl.js → pi-model-discovery-runtime-LB-5lX5L.js} +1 -1
  89. package/dist/plugin-sdk/{pi-model-discovery-runtime-BTWgkx4x.js → pi-model-discovery-runtime-gd77b0UF.js} +2 -2
  90. package/dist/plugin-sdk/{pi-model-discovery-CkH5l9X5.js → pi-model-discovery-yifTIDIn.js} +1 -1
  91. package/dist/plugin-sdk/{pw-ai-DZs6uYRd.js → pw-ai-SNCI9UXT.js} +6 -5
  92. package/dist/plugin-sdk/{pw-ai-Cn-EUPZK.js → pw-ai-sH1Pi-Fh.js} +6 -5
  93. package/dist/plugin-sdk/{registry-B4HvWzob.js → registry-DNkJsNsz.js} +4 -3
  94. package/dist/plugin-sdk/{replies-jDMUBsNO.js → replies-fvzN5wnU.js} +2 -2
  95. package/dist/plugin-sdk/{replies-B_LW9c9f.js → replies-zebgZCHX.js} +2 -2
  96. package/dist/plugin-sdk/{resolve-route-_YZHbS-z.js → resolve-route-CNhTJG_2.js} +1 -1
  97. package/dist/plugin-sdk/{resolve-route-DlHzggnG.js → resolve-route-DO0WR4nB.js} +1 -1
  98. package/dist/plugin-sdk/{resolve-utils-zBhVX3Vx.js → resolve-utils-EFP1DYqG.js} +1 -1
  99. package/dist/plugin-sdk/{retry-policy-DGLs5ebP.js → retry-policy-BLYEgIwP.js} +1 -1
  100. package/dist/plugin-sdk/{retry-policy-DaodShGa.js → retry-policy-sM01QZT2.js} +1 -1
  101. package/dist/plugin-sdk/{runtime-Dd0sswuW.js → runtime-BPyuAmka.js} +4 -3
  102. package/dist/plugin-sdk/{paths-DW-U2r7Y.js → runtime-dependency-B-1u41Ph.js} +27 -3
  103. package/dist/plugin-sdk/{paths-CBCpJ5bu.js → runtime-dependency-Csswyv5r.js} +27 -3
  104. package/dist/plugin-sdk/sat-runtime.js +1 -0
  105. package/dist/plugin-sdk/{send-8remZhsH.js → send-B09HRfHN.js} +6 -6
  106. package/dist/plugin-sdk/{send-DaaAscWj.js → send-BBYcgXA4.js} +5 -5
  107. package/dist/plugin-sdk/{send-DFTB0cnx.js → send-BQXQA81e.js} +6 -6
  108. package/dist/plugin-sdk/{send-CtMVvMJs.js → send-BzFdvD_i.js} +6 -6
  109. package/dist/plugin-sdk/{send-Di9irjS-.js → send-C3u-F_8s.js} +6 -6
  110. package/dist/plugin-sdk/{send-Dl88ZKq2.js → send-D3836_UN.js} +6 -6
  111. package/dist/plugin-sdk/{send-ifgZCHVB.js → send-D7tr-EsH.js} +5 -5
  112. package/dist/plugin-sdk/{send-DvUpYh0d.js → send-DRGzRdI3.js} +6 -6
  113. package/dist/plugin-sdk/{send-D2jlPeKH.js → send-DfkPKz_0.js} +4 -4
  114. package/dist/plugin-sdk/{send-QSt6nbny.js → send-DsxFXrCO.js} +4 -4
  115. package/dist/plugin-sdk/{session-CknrceVU.js → session-DG_bYisw.js} +2 -2
  116. package/dist/plugin-sdk/{session-CyRTcJ8N.js → session-EIStzK0E.js} +2 -2
  117. package/dist/plugin-sdk/{skill-commands-DHxkTA0s.js → skill-commands-CkgGmWBS.js} +2 -2
  118. package/dist/plugin-sdk/{skill-commands-CLXAG5sU.js → skill-commands-hyZA0LE3.js} +2 -2
  119. package/dist/plugin-sdk/{slack-BpJXkwxF.js → slack-C0WZVJPZ.js} +34 -34
  120. package/dist/plugin-sdk/{slack-Br9c6Yzs.js → slack-DtlPw_PN.js} +34 -34
  121. package/dist/plugin-sdk/{slack-actions-8tLGt1Ht.js → slack-actions-BQawWGTJ.js} +11 -11
  122. package/dist/plugin-sdk/{slack-actions-CDSSRo8Y.js → slack-actions-DDMszx56.js} +11 -11
  123. package/dist/plugin-sdk/slack.js +2 -1
  124. package/dist/plugin-sdk/src/brand.d.ts +2 -2
  125. package/dist/plugin-sdk/src/browser/runtime-dependency.d.ts +3 -0
  126. package/dist/plugin-sdk/src/infra/optional-runtime-dependency.d.ts +6 -0
  127. package/dist/plugin-sdk/{ssrf-fG4UHKBw.js → ssrf-Cce6LubA.js} +41 -7
  128. package/dist/plugin-sdk/{status-DoxnzyMC.js → status-CIiBeb9B.js} +72 -60
  129. package/dist/plugin-sdk/{sticker-cache-zmJ39ByC.js → sticker-cache-9houHChV.js} +3 -3
  130. package/dist/plugin-sdk/{sticker-cache-D7WcMYsF.js → sticker-cache-Dwi-XsgB.js} +3 -3
  131. package/dist/plugin-sdk/{tables-CkxblF0u.js → tables-BD7H5ug-.js} +1 -1
  132. package/dist/plugin-sdk/{tables-RBtf8G4P.js → tables-CJE8kB35.js} +1 -1
  133. package/dist/plugin-sdk/{telegram-actions-DAeYXSLk.js → telegram-actions-Bu1edXF2.js} +25 -25
  134. package/dist/plugin-sdk/{telegram-actions-BDeS3ocd.js → telegram-actions-CRXVO8lG.js} +25 -25
  135. package/dist/plugin-sdk/telegram.js +2 -1
  136. package/dist/plugin-sdk/{thread-bindings.lifecycle-DsB94WbE.js → thread-bindings.lifecycle-Djem8FWF.js} +2 -2
  137. package/dist/plugin-sdk/{thread-bindings.lifecycle-DMhV3TsR.js → thread-bindings.lifecycle-gmHv3hc7.js} +2 -2
  138. package/dist/plugin-sdk/{thread-bindings.state-DYWpy7hJ.js → thread-bindings.state-CNT2vxm3.js} +2 -2
  139. package/dist/plugin-sdk/{thread-bindings.state-DG5cBaRn.js → thread-bindings.state-D8kN2X6H.js} +2 -2
  140. package/dist/plugin-sdk/{web-IJ4NoGPJ.js → web-DCrVQr6y.js} +26 -26
  141. package/dist/plugin-sdk/{web-DJwacWQo.js → web-Ds6OWw3C.js} +26 -26
  142. package/dist/plugin-sdk/{whatsapp-actions-DAY8hWpD.js → whatsapp-actions-68Mfs2dJ.js} +12 -12
  143. package/dist/plugin-sdk/{whatsapp-actions-6opfo-oB.js → whatsapp-actions-DRqtzvTO.js} +12 -12
  144. package/dist/plugin-sdk/whatsapp.js +6 -5
  145. package/dist/plugin-sdk/{wsl-B2euLEc2.js → wsl-DcM2PgSS.js} +3 -3
  146. package/dist/plugin-sdk/{wsl-B8eyviuv.js → wsl-PXrdWitE.js} +3 -3
  147. package/dist/plugins/update.js +1 -1
  148. package/dist/tts/tts-core.js +6 -1
  149. package/dist/wizard/onboarding.finalize.js +9 -0
  150. package/extensions/acpx/package.json +1 -1
  151. package/extensions/bluebubbles/package.json +1 -1
  152. package/extensions/copilot-proxy/package.json +1 -1
  153. package/extensions/diagnostics-otel/package.json +1 -1
  154. package/extensions/fased-federation/package.json +1 -1
  155. package/extensions/google-gemini-cli-auth/package.json +1 -1
  156. package/extensions/imessage/package.json +1 -1
  157. package/extensions/irc/package.json +1 -1
  158. package/extensions/line/package.json +1 -1
  159. package/extensions/llm-task/package.json +1 -1
  160. package/extensions/lobster/package.json +1 -1
  161. package/extensions/matrix/CHANGELOG.md +6 -0
  162. package/extensions/matrix/package.json +1 -1
  163. package/extensions/mattermost/package.json +1 -1
  164. package/extensions/memory-core/package.json +2 -2
  165. package/extensions/memory-lancedb/package.json +1 -1
  166. package/extensions/minimax-portal-auth/package.json +1 -1
  167. package/extensions/msteams/CHANGELOG.md +6 -0
  168. package/extensions/msteams/package.json +1 -1
  169. package/extensions/nextcloud-talk/package.json +1 -1
  170. package/extensions/nostr/CHANGELOG.md +6 -0
  171. package/extensions/nostr/package.json +1 -1
  172. package/extensions/open-prose/package.json +1 -1
  173. package/extensions/sat-mining/package.json +1 -1
  174. package/extensions/signal/package.json +1 -1
  175. package/extensions/synology-chat/package.json +1 -1
  176. package/extensions/tlon/package.json +1 -1
  177. package/extensions/twitch/CHANGELOG.md +6 -0
  178. package/extensions/twitch/package.json +1 -1
  179. package/extensions/voice-call/CHANGELOG.md +6 -0
  180. package/extensions/voice-call/package.json +1 -1
  181. package/extensions/zalo/CHANGELOG.md +6 -0
  182. package/extensions/zalo/package.json +1 -1
  183. package/extensions/zalouser/CHANGELOG.md +6 -0
  184. package/extensions/zalouser/package.json +1 -1
  185. package/package.json +22 -15
  186. package/extensions/feishu/fased.plugin.json +0 -10
  187. package/extensions/feishu/index.ts +0 -63
  188. package/extensions/feishu/package.json +0 -33
  189. package/extensions/feishu/skills/feishu-doc/SKILL.md +0 -211
  190. package/extensions/feishu/skills/feishu-doc/references/block-types.md +0 -103
  191. package/extensions/feishu/skills/feishu-drive/SKILL.md +0 -97
  192. package/extensions/feishu/skills/feishu-perm/SKILL.md +0 -119
  193. package/extensions/feishu/skills/feishu-wiki/SKILL.md +0 -111
  194. package/extensions/feishu/src/accounts.ts +0 -159
  195. package/extensions/feishu/src/bitable.ts +0 -713
  196. package/extensions/feishu/src/bot.ts +0 -979
  197. package/extensions/feishu/src/channel.ts +0 -359
  198. package/extensions/feishu/src/client.ts +0 -118
  199. package/extensions/feishu/src/config-schema.ts +0 -226
  200. package/extensions/feishu/src/dedup.ts +0 -54
  201. package/extensions/feishu/src/directory.ts +0 -177
  202. package/extensions/feishu/src/doc-schema.ts +0 -122
  203. package/extensions/feishu/src/docx.ts +0 -998
  204. package/extensions/feishu/src/drive-schema.ts +0 -46
  205. package/extensions/feishu/src/drive.ts +0 -232
  206. package/extensions/feishu/src/dynamic-agent.ts +0 -131
  207. package/extensions/feishu/src/external-keys.ts +0 -19
  208. package/extensions/feishu/src/media.ts +0 -447
  209. package/extensions/feishu/src/mention.ts +0 -133
  210. package/extensions/feishu/src/monitor.ts +0 -434
  211. package/extensions/feishu/src/onboarding.ts +0 -430
  212. package/extensions/feishu/src/outbound.ts +0 -56
  213. package/extensions/feishu/src/perm-schema.ts +0 -52
  214. package/extensions/feishu/src/perm.ts +0 -180
  215. package/extensions/feishu/src/policy.ts +0 -116
  216. package/extensions/feishu/src/probe.ts +0 -44
  217. package/extensions/feishu/src/reactions.ts +0 -160
  218. package/extensions/feishu/src/reply-dispatcher.ts +0 -239
  219. package/extensions/feishu/src/runtime.ts +0 -14
  220. package/extensions/feishu/src/send-result.ts +0 -29
  221. package/extensions/feishu/src/send-target.ts +0 -25
  222. package/extensions/feishu/src/send.ts +0 -313
  223. package/extensions/feishu/src/streaming-card.ts +0 -218
  224. package/extensions/feishu/src/targets.ts +0 -78
  225. package/extensions/feishu/src/tool-account.ts +0 -58
  226. package/extensions/feishu/src/tools-config.ts +0 -21
  227. package/extensions/feishu/src/types.ts +0 -81
  228. package/extensions/feishu/src/typing.ts +0 -80
  229. package/extensions/feishu/src/wiki-schema.ts +0 -55
  230. package/extensions/feishu/src/wiki.ts +0 -237
  231. package/extensions/googlechat/fased.plugin.json +0 -9
  232. package/extensions/googlechat/index.ts +0 -19
  233. package/extensions/googlechat/package.json +0 -37
  234. package/extensions/googlechat/src/accounts.ts +0 -147
  235. package/extensions/googlechat/src/actions.ts +0 -176
  236. package/extensions/googlechat/src/api.ts +0 -282
  237. package/extensions/googlechat/src/auth.ts +0 -137
  238. package/extensions/googlechat/src/channel.ts +0 -591
  239. package/extensions/googlechat/src/monitor.ts +0 -996
  240. package/extensions/googlechat/src/onboarding.ts +0 -344
  241. package/extensions/googlechat/src/runtime.ts +0 -14
  242. package/extensions/googlechat/src/targets.ts +0 -65
  243. package/extensions/googlechat/src/types.config.ts +0 -3
  244. 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,3 +0,0 @@
1
- import type { GoogleChatAccountConfig, GoogleChatConfig } from "fased/plugin-sdk";
2
-
3
- export type { GoogleChatAccountConfig, GoogleChatConfig };
@@ -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
- };