@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,46 +0,0 @@
1
- import { Type, type Static } from "@sinclair/typebox";
2
-
3
- const FileType = Type.Union([
4
- Type.Literal("doc"),
5
- Type.Literal("docx"),
6
- Type.Literal("sheet"),
7
- Type.Literal("bitable"),
8
- Type.Literal("folder"),
9
- Type.Literal("file"),
10
- Type.Literal("mindnote"),
11
- Type.Literal("shortcut"),
12
- ]);
13
-
14
- export const FeishuDriveSchema = Type.Union([
15
- Type.Object({
16
- action: Type.Literal("list"),
17
- folder_token: Type.Optional(
18
- Type.String({ description: "Folder token (optional, omit for root directory)" }),
19
- ),
20
- }),
21
- Type.Object({
22
- action: Type.Literal("info"),
23
- file_token: Type.String({ description: "File or folder token" }),
24
- type: FileType,
25
- }),
26
- Type.Object({
27
- action: Type.Literal("create_folder"),
28
- name: Type.String({ description: "Folder name" }),
29
- folder_token: Type.Optional(
30
- Type.String({ description: "Parent folder token (optional, omit for root)" }),
31
- ),
32
- }),
33
- Type.Object({
34
- action: Type.Literal("move"),
35
- file_token: Type.String({ description: "File token to move" }),
36
- type: FileType,
37
- folder_token: Type.String({ description: "Target folder token" }),
38
- }),
39
- Type.Object({
40
- action: Type.Literal("delete"),
41
- file_token: Type.String({ description: "File token to delete" }),
42
- type: FileType,
43
- }),
44
- ]);
45
-
46
- export type FeishuDriveParams = Static<typeof FeishuDriveSchema>;
@@ -1,232 +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 { FeishuDriveSchema, type FeishuDriveParams } from "./drive-schema.js";
5
- import { createFeishuToolClient, resolveAnyEnabledFeishuToolsConfig } from "./tool-account.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
- // ============ Actions ============
17
-
18
- async function getRootFolderToken(client: Lark.Client): Promise<string> {
19
- // Use generic HTTP client to call the root folder meta API
20
- // as it's not directly exposed in the SDK
21
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- accessing internal SDK property
22
- const domain = (client as any).domain ?? "https://open.feishu.cn";
23
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- accessing internal SDK property
24
- const res = (await (client as any).httpInstance.get(
25
- `${domain}/open-apis/drive/explorer/v2/root_folder/meta`,
26
- )) as { code: number; msg?: string; data?: { token?: string } };
27
- if (res.code !== 0) {
28
- throw new Error(res.msg ?? "Failed to get root folder");
29
- }
30
- const token = res.data?.token;
31
- if (!token) {
32
- throw new Error("Root folder token not found");
33
- }
34
- return token;
35
- }
36
-
37
- async function listFolder(client: Lark.Client, folderToken?: string) {
38
- // Filter out invalid folder_token values (empty, "0", etc.)
39
- const validFolderToken = folderToken && folderToken !== "0" ? folderToken : undefined;
40
- const res = await client.drive.file.list({
41
- params: validFolderToken ? { folder_token: validFolderToken } : {},
42
- });
43
- if (res.code !== 0) {
44
- throw new Error(res.msg);
45
- }
46
-
47
- return {
48
- files:
49
- res.data?.files?.map((f) => ({
50
- token: f.token,
51
- name: f.name,
52
- type: f.type,
53
- url: f.url,
54
- created_time: f.created_time,
55
- modified_time: f.modified_time,
56
- owner_id: f.owner_id,
57
- })) ?? [],
58
- next_page_token: res.data?.next_page_token,
59
- };
60
- }
61
-
62
- async function getFileInfo(client: Lark.Client, fileToken: string, folderToken?: string) {
63
- // Use list with folder_token to find file info
64
- const res = await client.drive.file.list({
65
- params: folderToken ? { folder_token: folderToken } : {},
66
- });
67
- if (res.code !== 0) {
68
- throw new Error(res.msg);
69
- }
70
-
71
- const file = res.data?.files?.find((f) => f.token === fileToken);
72
- if (!file) {
73
- throw new Error(`File not found: ${fileToken}`);
74
- }
75
-
76
- return {
77
- token: file.token,
78
- name: file.name,
79
- type: file.type,
80
- url: file.url,
81
- created_time: file.created_time,
82
- modified_time: file.modified_time,
83
- owner_id: file.owner_id,
84
- };
85
- }
86
-
87
- async function createFolder(client: Lark.Client, name: string, folderToken?: string) {
88
- // Feishu supports using folder_token="0" as the root folder.
89
- // We *try* to resolve the real root token (explorer API), but fall back to "0"
90
- // because some tenants/apps return 400 for that explorer endpoint.
91
- let effectiveToken = folderToken && folderToken !== "0" ? folderToken : "0";
92
- if (effectiveToken === "0") {
93
- try {
94
- effectiveToken = await getRootFolderToken(client);
95
- } catch {
96
- // ignore and keep "0"
97
- }
98
- }
99
-
100
- const res = await client.drive.file.createFolder({
101
- data: {
102
- name,
103
- folder_token: effectiveToken,
104
- },
105
- });
106
- if (res.code !== 0) {
107
- throw new Error(res.msg);
108
- }
109
-
110
- return {
111
- token: res.data?.token,
112
- url: res.data?.url,
113
- };
114
- }
115
-
116
- async function moveFile(client: Lark.Client, fileToken: string, type: string, folderToken: string) {
117
- const res = await client.drive.file.move({
118
- path: { file_token: fileToken },
119
- data: {
120
- type: type as
121
- | "doc"
122
- | "docx"
123
- | "sheet"
124
- | "bitable"
125
- | "folder"
126
- | "file"
127
- | "mindnote"
128
- | "slides",
129
- folder_token: folderToken,
130
- },
131
- });
132
- if (res.code !== 0) {
133
- throw new Error(res.msg);
134
- }
135
-
136
- return {
137
- success: true,
138
- task_id: res.data?.task_id,
139
- };
140
- }
141
-
142
- async function deleteFile(client: Lark.Client, fileToken: string, type: string) {
143
- const res = await client.drive.file.delete({
144
- path: { file_token: fileToken },
145
- params: {
146
- type: type as
147
- | "doc"
148
- | "docx"
149
- | "sheet"
150
- | "bitable"
151
- | "folder"
152
- | "file"
153
- | "mindnote"
154
- | "slides"
155
- | "shortcut",
156
- },
157
- });
158
- if (res.code !== 0) {
159
- throw new Error(res.msg);
160
- }
161
-
162
- return {
163
- success: true,
164
- task_id: res.data?.task_id,
165
- };
166
- }
167
-
168
- // ============ Tool Registration ============
169
-
170
- export function registerFeishuDriveTools(api: FasedAgentPluginApi) {
171
- if (!api.config) {
172
- api.logger.debug?.("feishu_drive: No config available, skipping drive tools");
173
- return;
174
- }
175
-
176
- const accounts = listEnabledFeishuAccounts(api.config);
177
- if (accounts.length === 0) {
178
- api.logger.debug?.("feishu_drive: No Feishu accounts configured, skipping drive tools");
179
- return;
180
- }
181
-
182
- const toolsCfg = resolveAnyEnabledFeishuToolsConfig(accounts);
183
- if (!toolsCfg.drive) {
184
- api.logger.debug?.("feishu_drive: drive tool disabled in config");
185
- return;
186
- }
187
-
188
- type FeishuDriveExecuteParams = FeishuDriveParams & { accountId?: string };
189
-
190
- api.registerTool(
191
- (ctx) => {
192
- const defaultAccountId = ctx.agentAccountId;
193
- return {
194
- name: "feishu_drive",
195
- label: "Feishu Drive",
196
- description:
197
- "Feishu cloud storage operations. Actions: list, info, create_folder, move, delete",
198
- parameters: FeishuDriveSchema,
199
- async execute(_toolCallId, params) {
200
- const p = params as FeishuDriveExecuteParams;
201
- try {
202
- const client = createFeishuToolClient({
203
- api,
204
- executeParams: p,
205
- defaultAccountId,
206
- });
207
- switch (p.action) {
208
- case "list":
209
- return json(await listFolder(client, p.folder_token));
210
- case "info":
211
- return json(await getFileInfo(client, p.file_token));
212
- case "create_folder":
213
- return json(await createFolder(client, p.name, p.folder_token));
214
- case "move":
215
- return json(await moveFile(client, p.file_token, p.type, p.folder_token));
216
- case "delete":
217
- return json(await deleteFile(client, p.file_token, p.type));
218
- default:
219
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- exhaustive check fallback
220
- return json({ error: `Unknown action: ${(p as any).action}` });
221
- }
222
- } catch (err) {
223
- return json({ error: err instanceof Error ? err.message : String(err) });
224
- }
225
- },
226
- };
227
- },
228
- { name: "feishu_drive" },
229
- );
230
-
231
- api.logger.debug?.(`feishu_drive: Registered feishu_drive tool`);
232
- }
@@ -1,131 +0,0 @@
1
- import fs from "node:fs";
2
- import os from "node:os";
3
- import path from "node:path";
4
- import type { FasedAgentConfig, PluginRuntime } from "fased/plugin-sdk";
5
- import type { DynamicAgentCreationConfig } from "./types.js";
6
-
7
- export type MaybeCreateDynamicAgentResult = {
8
- created: boolean;
9
- updatedCfg: FasedAgentConfig;
10
- agentId?: string;
11
- };
12
-
13
- /**
14
- * Check if a dynamic agent should be created for a DM user and create it if needed.
15
- * This creates a unique agent instance with its own workspace for each DM user.
16
- */
17
- export async function maybeCreateDynamicAgent(params: {
18
- cfg: FasedAgentConfig;
19
- runtime: PluginRuntime;
20
- senderOpenId: string;
21
- dynamicCfg: DynamicAgentCreationConfig;
22
- log: (msg: string) => void;
23
- }): Promise<MaybeCreateDynamicAgentResult> {
24
- const { cfg, runtime, senderOpenId, dynamicCfg, log } = params;
25
-
26
- // Check if there's already a binding for this user
27
- const existingBindings = cfg.bindings ?? [];
28
- const hasBinding = existingBindings.some(
29
- (b) =>
30
- b.match?.channel === "feishu" &&
31
- b.match?.peer?.kind === "direct" &&
32
- b.match?.peer?.id === senderOpenId,
33
- );
34
-
35
- if (hasBinding) {
36
- return { created: false, updatedCfg: cfg };
37
- }
38
-
39
- // Check maxAgents limit if configured
40
- if (dynamicCfg.maxAgents !== undefined) {
41
- const feishuAgentCount = (cfg.agents?.list ?? []).filter((a) =>
42
- a.id.startsWith("feishu-"),
43
- ).length;
44
- if (feishuAgentCount >= dynamicCfg.maxAgents) {
45
- log(
46
- `feishu: maxAgents limit (${dynamicCfg.maxAgents}) reached, not creating agent for ${senderOpenId}`,
47
- );
48
- return { created: false, updatedCfg: cfg };
49
- }
50
- }
51
-
52
- // Use full OpenID as agent ID suffix (OpenID format: ou_xxx is already filesystem-safe)
53
- const agentId = `feishu-${senderOpenId}`;
54
-
55
- // Check if agent already exists (but binding was missing)
56
- const existingAgent = (cfg.agents?.list ?? []).find((a) => a.id === agentId);
57
- if (existingAgent) {
58
- // Agent exists but binding doesn't - just add the binding
59
- log(`feishu: agent "${agentId}" exists, adding missing binding for ${senderOpenId}`);
60
-
61
- const updatedCfg: FasedAgentConfig = {
62
- ...cfg,
63
- bindings: [
64
- ...existingBindings,
65
- {
66
- agentId,
67
- match: {
68
- channel: "feishu",
69
- peer: { kind: "direct", id: senderOpenId },
70
- },
71
- },
72
- ],
73
- };
74
-
75
- await runtime.config.writeConfigFile(updatedCfg);
76
- return { created: true, updatedCfg, agentId };
77
- }
78
-
79
- // Resolve path templates with substitutions
80
- const workspaceTemplate = dynamicCfg.workspaceTemplate ?? "~/.fased/workspace-{agentId}";
81
- const agentDirTemplate = dynamicCfg.agentDirTemplate ?? "~/.fased/agents/{agentId}/agent";
82
-
83
- const workspace = resolveUserPath(
84
- workspaceTemplate.replace("{userId}", senderOpenId).replace("{agentId}", agentId),
85
- );
86
- const agentDir = resolveUserPath(
87
- agentDirTemplate.replace("{userId}", senderOpenId).replace("{agentId}", agentId),
88
- );
89
-
90
- log(`feishu: creating dynamic agent "${agentId}" for user ${senderOpenId}`);
91
- log(` workspace: ${workspace}`);
92
- log(` agentDir: ${agentDir}`);
93
-
94
- // Create directories
95
- await fs.promises.mkdir(workspace, { recursive: true });
96
- await fs.promises.mkdir(agentDir, { recursive: true });
97
-
98
- // Update configuration with new agent and binding
99
- const updatedCfg: FasedAgentConfig = {
100
- ...cfg,
101
- agents: {
102
- ...cfg.agents,
103
- list: [...(cfg.agents?.list ?? []), { id: agentId, workspace, agentDir }],
104
- },
105
- bindings: [
106
- ...existingBindings,
107
- {
108
- agentId,
109
- match: {
110
- channel: "feishu",
111
- peer: { kind: "direct", id: senderOpenId },
112
- },
113
- },
114
- ],
115
- };
116
-
117
- // Write updated config using PluginRuntime API
118
- await runtime.config.writeConfigFile(updatedCfg);
119
-
120
- return { created: true, updatedCfg, agentId };
121
- }
122
-
123
- /**
124
- * Resolve a path that may start with ~ to the user's home directory.
125
- */
126
- function resolveUserPath(p: string): string {
127
- if (p.startsWith("~/")) {
128
- return path.join(os.homedir(), p.slice(2));
129
- }
130
- return p;
131
- }
@@ -1,19 +0,0 @@
1
- const CONTROL_CHARS_RE = /[\u0000-\u001f\u007f]/;
2
- const MAX_EXTERNAL_KEY_LENGTH = 512;
3
-
4
- export function normalizeFeishuExternalKey(value: unknown): string | undefined {
5
- if (typeof value !== "string") {
6
- return undefined;
7
- }
8
- const normalized = value.trim();
9
- if (!normalized || normalized.length > MAX_EXTERNAL_KEY_LENGTH) {
10
- return undefined;
11
- }
12
- if (CONTROL_CHARS_RE.test(normalized)) {
13
- return undefined;
14
- }
15
- if (normalized.includes("/") || normalized.includes("\\") || normalized.includes("..")) {
16
- return undefined;
17
- }
18
- return normalized;
19
- }