@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,237 +0,0 @@
1
- import type * as Lark from "@larksuiteoapi/node-sdk";
2
- import type { FasedAgentPluginApi } from "fased/plugin-sdk";
3
- import { listEnabledFeishuAccounts } from "./accounts.js";
4
- import { createFeishuToolClient, resolveAnyEnabledFeishuToolsConfig } from "./tool-account.js";
5
- import { FeishuWikiSchema, type FeishuWikiParams } from "./wiki-schema.js";
6
-
7
- // ============ Helpers ============
8
-
9
- function json(data: unknown) {
10
- return {
11
- content: [{ type: "text" as const, text: JSON.stringify(data, null, 2) }],
12
- details: data,
13
- };
14
- }
15
-
16
- type ObjType = "doc" | "sheet" | "mindnote" | "bitable" | "file" | "docx" | "slides";
17
-
18
- // ============ Actions ============
19
-
20
- const WIKI_ACCESS_HINT =
21
- "To grant wiki access: Open wiki space → Settings → Members → Add the bot. " +
22
- "See: https://open.feishu.cn/document/server-docs/docs/wiki-v2/wiki-qa#a40ad4ca";
23
-
24
- async function listSpaces(client: Lark.Client) {
25
- const res = await client.wiki.space.list({});
26
- if (res.code !== 0) {
27
- throw new Error(res.msg);
28
- }
29
-
30
- const spaces =
31
- res.data?.items?.map((s) => ({
32
- space_id: s.space_id,
33
- name: s.name,
34
- description: s.description,
35
- visibility: s.visibility,
36
- })) ?? [];
37
-
38
- return {
39
- spaces,
40
- ...(spaces.length === 0 && { hint: WIKI_ACCESS_HINT }),
41
- };
42
- }
43
-
44
- async function listNodes(client: Lark.Client, spaceId: string, parentNodeToken?: string) {
45
- const res = await client.wiki.spaceNode.list({
46
- path: { space_id: spaceId },
47
- params: { parent_node_token: parentNodeToken },
48
- });
49
- if (res.code !== 0) {
50
- throw new Error(res.msg);
51
- }
52
-
53
- return {
54
- nodes:
55
- res.data?.items?.map((n) => ({
56
- node_token: n.node_token,
57
- obj_token: n.obj_token,
58
- obj_type: n.obj_type,
59
- title: n.title,
60
- has_child: n.has_child,
61
- })) ?? [],
62
- };
63
- }
64
-
65
- async function getNode(client: Lark.Client, token: string) {
66
- const res = await client.wiki.space.getNode({
67
- params: { token },
68
- });
69
- if (res.code !== 0) {
70
- throw new Error(res.msg);
71
- }
72
-
73
- const node = res.data?.node;
74
- return {
75
- node_token: node?.node_token,
76
- space_id: node?.space_id,
77
- obj_token: node?.obj_token,
78
- obj_type: node?.obj_type,
79
- title: node?.title,
80
- parent_node_token: node?.parent_node_token,
81
- has_child: node?.has_child,
82
- creator: node?.creator,
83
- create_time: node?.node_create_time,
84
- };
85
- }
86
-
87
- async function createNode(
88
- client: Lark.Client,
89
- spaceId: string,
90
- title: string,
91
- objType?: string,
92
- parentNodeToken?: string,
93
- ) {
94
- const res = await client.wiki.spaceNode.create({
95
- path: { space_id: spaceId },
96
- data: {
97
- obj_type: (objType as ObjType) || "docx",
98
- node_type: "origin" as const,
99
- title,
100
- parent_node_token: parentNodeToken,
101
- },
102
- });
103
- if (res.code !== 0) {
104
- throw new Error(res.msg);
105
- }
106
-
107
- const node = res.data?.node;
108
- return {
109
- node_token: node?.node_token,
110
- obj_token: node?.obj_token,
111
- obj_type: node?.obj_type,
112
- title: node?.title,
113
- };
114
- }
115
-
116
- async function moveNode(
117
- client: Lark.Client,
118
- spaceId: string,
119
- nodeToken: string,
120
- targetSpaceId?: string,
121
- targetParentToken?: string,
122
- ) {
123
- const res = await client.wiki.spaceNode.move({
124
- path: { space_id: spaceId, node_token: nodeToken },
125
- data: {
126
- target_space_id: targetSpaceId || spaceId,
127
- target_parent_token: targetParentToken,
128
- },
129
- });
130
- if (res.code !== 0) {
131
- throw new Error(res.msg);
132
- }
133
-
134
- return {
135
- success: true,
136
- node_token: res.data?.node?.node_token,
137
- };
138
- }
139
-
140
- async function renameNode(client: Lark.Client, spaceId: string, nodeToken: string, title: string) {
141
- const res = await client.wiki.spaceNode.updateTitle({
142
- path: { space_id: spaceId, node_token: nodeToken },
143
- data: { title },
144
- });
145
- if (res.code !== 0) {
146
- throw new Error(res.msg);
147
- }
148
-
149
- return {
150
- success: true,
151
- node_token: nodeToken,
152
- title,
153
- };
154
- }
155
-
156
- // ============ Tool Registration ============
157
-
158
- export function registerFeishuWikiTools(api: FasedAgentPluginApi) {
159
- if (!api.config) {
160
- api.logger.debug?.("feishu_wiki: No config available, skipping wiki tools");
161
- return;
162
- }
163
-
164
- const accounts = listEnabledFeishuAccounts(api.config);
165
- if (accounts.length === 0) {
166
- api.logger.debug?.("feishu_wiki: No Feishu accounts configured, skipping wiki tools");
167
- return;
168
- }
169
-
170
- const toolsCfg = resolveAnyEnabledFeishuToolsConfig(accounts);
171
- if (!toolsCfg.wiki) {
172
- api.logger.debug?.("feishu_wiki: wiki tool disabled in config");
173
- return;
174
- }
175
-
176
- type FeishuWikiExecuteParams = FeishuWikiParams & { accountId?: string };
177
-
178
- api.registerTool(
179
- (ctx) => {
180
- const defaultAccountId = ctx.agentAccountId;
181
- return {
182
- name: "feishu_wiki",
183
- label: "Feishu Wiki",
184
- description:
185
- "Feishu knowledge base operations. Actions: spaces, nodes, get, create, move, rename",
186
- parameters: FeishuWikiSchema,
187
- async execute(_toolCallId, params) {
188
- const p = params as FeishuWikiExecuteParams;
189
- try {
190
- const client = createFeishuToolClient({
191
- api,
192
- executeParams: p,
193
- defaultAccountId,
194
- });
195
- switch (p.action) {
196
- case "spaces":
197
- return json(await listSpaces(client));
198
- case "nodes":
199
- return json(await listNodes(client, p.space_id, p.parent_node_token));
200
- case "get":
201
- return json(await getNode(client, p.token));
202
- case "search":
203
- return json({
204
- error:
205
- "Search is not available. Use feishu_wiki with action: 'nodes' to browse or action: 'get' to lookup by token.",
206
- });
207
- case "create":
208
- return json(
209
- await createNode(client, p.space_id, p.title, p.obj_type, p.parent_node_token),
210
- );
211
- case "move":
212
- return json(
213
- await moveNode(
214
- client,
215
- p.space_id,
216
- p.node_token,
217
- p.target_space_id,
218
- p.target_parent_token,
219
- ),
220
- );
221
- case "rename":
222
- return json(await renameNode(client, p.space_id, p.node_token, p.title));
223
- default:
224
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- exhaustive check fallback
225
- return json({ error: `Unknown action: ${(p as any).action}` });
226
- }
227
- } catch (err) {
228
- return json({ error: err instanceof Error ? err.message : String(err) });
229
- }
230
- },
231
- };
232
- },
233
- { name: "feishu_wiki" },
234
- );
235
-
236
- api.logger.debug?.(`feishu_wiki: Registered feishu_wiki tool`);
237
- }
@@ -1,9 +0,0 @@
1
- {
2
- "id": "googlechat",
3
- "channels": ["googlechat"],
4
- "configSchema": {
5
- "type": "object",
6
- "additionalProperties": false,
7
- "properties": {}
8
- }
9
- }
@@ -1,19 +0,0 @@
1
- import type { FasedAgentPluginApi } from "fased/plugin-sdk";
2
- import { emptyPluginConfigSchema } from "fased/plugin-sdk";
3
- import { googlechatDock, googlechatPlugin } from "./src/channel.js";
4
- import { handleGoogleChatWebhookRequest } from "./src/monitor.js";
5
- import { setGoogleChatRuntime } from "./src/runtime.js";
6
-
7
- const plugin = {
8
- id: "googlechat",
9
- name: "Google Chat",
10
- description: "FasedAgent Google Chat channel plugin",
11
- configSchema: emptyPluginConfigSchema(),
12
- register(api: FasedAgentPluginApi) {
13
- setGoogleChatRuntime(api.runtime);
14
- api.registerChannel({ plugin: googlechatPlugin, dock: googlechatDock });
15
- api.registerHttpHandler(handleGoogleChatWebhookRequest);
16
- },
17
- };
18
-
19
- export default plugin;
@@ -1,37 +0,0 @@
1
- {
2
- "name": "@fased/googlechat",
3
- "version": "0.1.36",
4
- "private": true,
5
- "description": "FasedAgent Google Chat channel plugin",
6
- "type": "module",
7
- "dependencies": {
8
- "google-auth-library": "^10.6.1"
9
- },
10
- "peerDependencies": {
11
- "@fased/fased": "^0.1.36"
12
- },
13
- "fased": {
14
- "extensions": [
15
- "./index.ts"
16
- ],
17
- "channel": {
18
- "id": "googlechat",
19
- "label": "Google Chat",
20
- "selectionLabel": "Google Chat (Chat API)",
21
- "detailLabel": "Google Chat",
22
- "docsPath": "/channels/googlechat",
23
- "docsLabel": "googlechat",
24
- "blurb": "Google Workspace Chat app via HTTP webhooks.",
25
- "aliases": [
26
- "gchat",
27
- "google-chat"
28
- ],
29
- "order": 55
30
- },
31
- "install": {
32
- "npmSpec": "@fased/googlechat",
33
- "localPath": "extensions/googlechat",
34
- "defaultChoice": "local"
35
- }
36
- }
37
- }
@@ -1,147 +0,0 @@
1
- import type { FasedAgentConfig } from "fased/plugin-sdk";
2
- import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "fased/plugin-sdk/account-id";
3
- import type { GoogleChatAccountConfig } from "./types.config.js";
4
-
5
- export type GoogleChatCredentialSource = "file" | "inline" | "env" | "none";
6
-
7
- export type ResolvedGoogleChatAccount = {
8
- accountId: string;
9
- name?: string;
10
- enabled: boolean;
11
- config: GoogleChatAccountConfig;
12
- credentialSource: GoogleChatCredentialSource;
13
- credentials?: Record<string, unknown>;
14
- credentialsFile?: string;
15
- };
16
-
17
- const ENV_SERVICE_ACCOUNT = "GOOGLE_CHAT_SERVICE_ACCOUNT";
18
- const ENV_SERVICE_ACCOUNT_FILE = "GOOGLE_CHAT_SERVICE_ACCOUNT_FILE";
19
-
20
- function listConfiguredAccountIds(cfg: FasedAgentConfig): string[] {
21
- const accounts = cfg.channels?.["googlechat"]?.accounts;
22
- if (!accounts || typeof accounts !== "object") {
23
- return [];
24
- }
25
- return Object.keys(accounts).filter(Boolean);
26
- }
27
-
28
- export function listGoogleChatAccountIds(cfg: FasedAgentConfig): string[] {
29
- const ids = listConfiguredAccountIds(cfg);
30
- if (ids.length === 0) {
31
- return [DEFAULT_ACCOUNT_ID];
32
- }
33
- return ids.toSorted((a, b) => a.localeCompare(b));
34
- }
35
-
36
- export function resolveDefaultGoogleChatAccountId(cfg: FasedAgentConfig): string {
37
- const channel = cfg.channels?.["googlechat"];
38
- if (channel?.defaultAccount?.trim()) {
39
- return channel.defaultAccount.trim();
40
- }
41
- const ids = listGoogleChatAccountIds(cfg);
42
- if (ids.includes(DEFAULT_ACCOUNT_ID)) {
43
- return DEFAULT_ACCOUNT_ID;
44
- }
45
- return ids[0] ?? DEFAULT_ACCOUNT_ID;
46
- }
47
-
48
- function resolveAccountConfig(
49
- cfg: FasedAgentConfig,
50
- accountId: string,
51
- ): GoogleChatAccountConfig | undefined {
52
- const accounts = cfg.channels?.["googlechat"]?.accounts;
53
- if (!accounts || typeof accounts !== "object") {
54
- return undefined;
55
- }
56
- return accounts[accountId];
57
- }
58
-
59
- function mergeGoogleChatAccountConfig(
60
- cfg: FasedAgentConfig,
61
- accountId: string,
62
- ): GoogleChatAccountConfig {
63
- const raw = cfg.channels?.["googlechat"] ?? {};
64
- const { accounts: _ignored, defaultAccount: _ignored2, ...base } = raw;
65
- const account = resolveAccountConfig(cfg, accountId) ?? {};
66
- return { ...base, ...account } as GoogleChatAccountConfig;
67
- }
68
-
69
- function parseServiceAccount(value: unknown): Record<string, unknown> | null {
70
- if (value && typeof value === "object") {
71
- return value as Record<string, unknown>;
72
- }
73
- if (typeof value !== "string") {
74
- return null;
75
- }
76
- const trimmed = value.trim();
77
- if (!trimmed) {
78
- return null;
79
- }
80
- try {
81
- return JSON.parse(trimmed) as Record<string, unknown>;
82
- } catch {
83
- return null;
84
- }
85
- }
86
-
87
- function resolveCredentialsFromConfig(params: {
88
- accountId: string;
89
- account: GoogleChatAccountConfig;
90
- }): {
91
- credentials?: Record<string, unknown>;
92
- credentialsFile?: string;
93
- source: GoogleChatCredentialSource;
94
- } {
95
- const { account, accountId } = params;
96
- const inline = parseServiceAccount(account.serviceAccount);
97
- if (inline) {
98
- return { credentials: inline, source: "inline" };
99
- }
100
-
101
- const file = account.serviceAccountFile?.trim();
102
- if (file) {
103
- return { credentialsFile: file, source: "file" };
104
- }
105
-
106
- if (accountId === DEFAULT_ACCOUNT_ID) {
107
- const envJson = process.env[ENV_SERVICE_ACCOUNT];
108
- const envInline = parseServiceAccount(envJson);
109
- if (envInline) {
110
- return { credentials: envInline, source: "env" };
111
- }
112
- const envFile = process.env[ENV_SERVICE_ACCOUNT_FILE]?.trim();
113
- if (envFile) {
114
- return { credentialsFile: envFile, source: "env" };
115
- }
116
- }
117
-
118
- return { source: "none" };
119
- }
120
-
121
- export function resolveGoogleChatAccount(params: {
122
- cfg: FasedAgentConfig;
123
- accountId?: string | null;
124
- }): ResolvedGoogleChatAccount {
125
- const accountId = normalizeAccountId(params.accountId);
126
- const baseEnabled = params.cfg.channels?.["googlechat"]?.enabled !== false;
127
- const merged = mergeGoogleChatAccountConfig(params.cfg, accountId);
128
- const accountEnabled = merged.enabled !== false;
129
- const enabled = baseEnabled && accountEnabled;
130
- const credentials = resolveCredentialsFromConfig({ accountId, account: merged });
131
-
132
- return {
133
- accountId,
134
- name: merged.name?.trim() || undefined,
135
- enabled,
136
- config: merged,
137
- credentialSource: credentials.source,
138
- credentials: credentials.credentials,
139
- credentialsFile: credentials.credentialsFile,
140
- };
141
- }
142
-
143
- export function listEnabledGoogleChatAccounts(cfg: FasedAgentConfig): ResolvedGoogleChatAccount[] {
144
- return listGoogleChatAccountIds(cfg)
145
- .map((accountId) => resolveGoogleChatAccount({ cfg, accountId }))
146
- .filter((account) => account.enabled);
147
- }
@@ -1,176 +0,0 @@
1
- import type {
2
- ChannelMessageActionAdapter,
3
- ChannelMessageActionName,
4
- FasedAgentConfig,
5
- } from "fased/plugin-sdk";
6
- import {
7
- createActionGate,
8
- extractToolSend,
9
- jsonResult,
10
- readNumberParam,
11
- readReactionParams,
12
- readStringParam,
13
- } from "fased/plugin-sdk";
14
- import { listEnabledGoogleChatAccounts, resolveGoogleChatAccount } from "./accounts.js";
15
- import {
16
- createGoogleChatReaction,
17
- deleteGoogleChatReaction,
18
- listGoogleChatReactions,
19
- sendGoogleChatMessage,
20
- uploadGoogleChatAttachment,
21
- } from "./api.js";
22
- import { getGoogleChatRuntime } from "./runtime.js";
23
- import { resolveGoogleChatOutboundSpace } from "./targets.js";
24
-
25
- const providerId = "googlechat";
26
-
27
- function listEnabledAccounts(cfg: FasedAgentConfig) {
28
- return listEnabledGoogleChatAccounts(cfg).filter(
29
- (account) => account.enabled && account.credentialSource !== "none",
30
- );
31
- }
32
-
33
- function isReactionsEnabled(
34
- accounts: ReturnType<typeof listEnabledAccounts>,
35
- cfg: FasedAgentConfig,
36
- ) {
37
- for (const account of accounts) {
38
- const gate = createActionGate(
39
- (account.config.actions ??
40
- (cfg.channels?.["googlechat"] as { actions?: unknown })?.actions) as Record<
41
- string,
42
- boolean | undefined
43
- >,
44
- );
45
- if (gate("reactions")) {
46
- return true;
47
- }
48
- }
49
- return false;
50
- }
51
-
52
- function resolveAppUserNames(account: { config: { botUser?: string | null } }) {
53
- return new Set(["users/app", account.config.botUser?.trim()].filter(Boolean) as string[]);
54
- }
55
-
56
- export const googlechatMessageActions: ChannelMessageActionAdapter = {
57
- listActions: ({ cfg }) => {
58
- const accounts = listEnabledAccounts(cfg);
59
- if (accounts.length === 0) {
60
- return [];
61
- }
62
- const actions = new Set<ChannelMessageActionName>([]);
63
- actions.add("send");
64
- if (isReactionsEnabled(accounts, cfg)) {
65
- actions.add("react");
66
- actions.add("reactions");
67
- }
68
- return Array.from(actions);
69
- },
70
- extractToolSend: ({ args }) => {
71
- return extractToolSend(args, "sendMessage");
72
- },
73
- handleAction: async ({ action, params, cfg, accountId }) => {
74
- const account = resolveGoogleChatAccount({
75
- cfg: cfg,
76
- accountId,
77
- });
78
- if (account.credentialSource === "none") {
79
- throw new Error("Google Chat credentials are missing.");
80
- }
81
-
82
- if (action === "send") {
83
- const to = readStringParam(params, "to", { required: true });
84
- const content = readStringParam(params, "message", {
85
- required: true,
86
- allowEmpty: true,
87
- });
88
- const mediaUrl = readStringParam(params, "media", { trim: false });
89
- const threadId = readStringParam(params, "threadId") ?? readStringParam(params, "replyTo");
90
- const space = await resolveGoogleChatOutboundSpace({ account, target: to });
91
-
92
- if (mediaUrl) {
93
- const core = getGoogleChatRuntime();
94
- const maxBytes = (account.config.mediaMaxMb ?? 20) * 1024 * 1024;
95
- const loaded = await core.channel.media.fetchRemoteMedia({ url: mediaUrl, maxBytes });
96
- const upload = await uploadGoogleChatAttachment({
97
- account,
98
- space,
99
- filename: loaded.fileName ?? "attachment",
100
- buffer: loaded.buffer,
101
- contentType: loaded.contentType,
102
- });
103
- await sendGoogleChatMessage({
104
- account,
105
- space,
106
- text: content,
107
- thread: threadId ?? undefined,
108
- attachments: upload.attachmentUploadToken
109
- ? [
110
- {
111
- attachmentUploadToken: upload.attachmentUploadToken,
112
- contentName: loaded.fileName,
113
- },
114
- ]
115
- : undefined,
116
- });
117
- return jsonResult({ ok: true, to: space });
118
- }
119
-
120
- await sendGoogleChatMessage({
121
- account,
122
- space,
123
- text: content,
124
- thread: threadId ?? undefined,
125
- });
126
- return jsonResult({ ok: true, to: space });
127
- }
128
-
129
- if (action === "react") {
130
- const messageName = readStringParam(params, "messageId", { required: true });
131
- const { emoji, remove, isEmpty } = readReactionParams(params, {
132
- removeErrorMessage: "Emoji is required to remove a Google Chat reaction.",
133
- });
134
- if (remove || isEmpty) {
135
- const reactions = await listGoogleChatReactions({ account, messageName });
136
- const appUsers = resolveAppUserNames(account);
137
- const toRemove = reactions.filter((reaction) => {
138
- const userName = reaction.user?.name?.trim();
139
- if (appUsers.size > 0 && !appUsers.has(userName ?? "")) {
140
- return false;
141
- }
142
- if (emoji) {
143
- return reaction.emoji?.unicode === emoji;
144
- }
145
- return true;
146
- });
147
- for (const reaction of toRemove) {
148
- if (!reaction.name) {
149
- continue;
150
- }
151
- await deleteGoogleChatReaction({ account, reactionName: reaction.name });
152
- }
153
- return jsonResult({ ok: true, removed: toRemove.length });
154
- }
155
- const reaction = await createGoogleChatReaction({
156
- account,
157
- messageName,
158
- emoji,
159
- });
160
- return jsonResult({ ok: true, reaction });
161
- }
162
-
163
- if (action === "reactions") {
164
- const messageName = readStringParam(params, "messageId", { required: true });
165
- const limit = readNumberParam(params, "limit", { integer: true });
166
- const reactions = await listGoogleChatReactions({
167
- account,
168
- messageName,
169
- limit: limit ?? undefined,
170
- });
171
- return jsonResult({ ok: true, reactions });
172
- }
173
-
174
- throw new Error(`Action ${action} is not supported for provider ${providerId}.`);
175
- },
176
- };