@phuetz/code-buddy 0.1.12 → 0.1.14

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 (321) hide show
  1. package/README.md +228 -13
  2. package/dist/agent/architect-mode.d.ts +11 -0
  3. package/dist/agent/architect-mode.js +133 -25
  4. package/dist/agent/architect-mode.js.map +1 -1
  5. package/dist/agent/codebuddy-agent.d.ts +24 -0
  6. package/dist/agent/codebuddy-agent.js +118 -16
  7. package/dist/agent/codebuddy-agent.js.map +1 -1
  8. package/dist/agent/execution/agent-executor.d.ts +9 -0
  9. package/dist/agent/execution/agent-executor.js +62 -1
  10. package/dist/agent/execution/agent-executor.js.map +1 -1
  11. package/dist/agent/message-queue.d.ts +77 -0
  12. package/dist/agent/message-queue.js +116 -0
  13. package/dist/agent/message-queue.js.map +1 -0
  14. package/dist/agent/middleware/auto-observation.d.ts +37 -0
  15. package/dist/agent/middleware/auto-observation.js +231 -0
  16. package/dist/agent/middleware/auto-observation.js.map +1 -0
  17. package/dist/agent/middleware/index.d.ts +2 -0
  18. package/dist/agent/middleware/index.js +1 -0
  19. package/dist/agent/middleware/index.js.map +1 -1
  20. package/dist/agent/tool-handler.js +3 -2
  21. package/dist/agent/tool-handler.js.map +1 -1
  22. package/dist/agent/turn-diff-tracker.js +3 -0
  23. package/dist/agent/turn-diff-tracker.js.map +1 -1
  24. package/dist/agent/types.d.ts +7 -2
  25. package/dist/analytics/budget-alerts.d.ts +81 -0
  26. package/dist/analytics/budget-alerts.js +126 -0
  27. package/dist/analytics/budget-alerts.js.map +1 -0
  28. package/dist/analytics/cost-predictor.d.ts +79 -0
  29. package/dist/analytics/cost-predictor.js +150 -0
  30. package/dist/analytics/cost-predictor.js.map +1 -0
  31. package/dist/analytics/index.d.ts +2 -0
  32. package/dist/analytics/index.js +2 -0
  33. package/dist/analytics/index.js.map +1 -1
  34. package/dist/auth/profile-manager.d.ts +205 -0
  35. package/dist/auth/profile-manager.js +484 -0
  36. package/dist/auth/profile-manager.js.map +1 -0
  37. package/dist/browser-automation/browser-manager.d.ts +79 -1
  38. package/dist/browser-automation/browser-manager.js +265 -2
  39. package/dist/browser-automation/browser-manager.js.map +1 -1
  40. package/dist/browser-automation/profile-manager.d.ts +32 -0
  41. package/dist/browser-automation/profile-manager.js +83 -0
  42. package/dist/browser-automation/profile-manager.js.map +1 -0
  43. package/dist/browser-automation/route-interceptor.d.ts +29 -0
  44. package/dist/browser-automation/route-interceptor.js +103 -0
  45. package/dist/browser-automation/route-interceptor.js.map +1 -0
  46. package/dist/browser-automation/screenshot-annotator.d.ts +23 -0
  47. package/dist/browser-automation/screenshot-annotator.js +86 -0
  48. package/dist/browser-automation/screenshot-annotator.js.map +1 -0
  49. package/dist/browser-automation/types.d.ts +47 -0
  50. package/dist/cache/llm-response-cache.js +3 -0
  51. package/dist/cache/llm-response-cache.js.map +1 -1
  52. package/dist/canvas/canvas-server.js +4 -3
  53. package/dist/canvas/canvas-server.js.map +1 -1
  54. package/dist/channels/discord/client.d.ts +2 -1
  55. package/dist/channels/discord/client.js +28 -16
  56. package/dist/channels/discord/client.js.map +1 -1
  57. package/dist/channels/dm-pairing.js +6 -3
  58. package/dist/channels/dm-pairing.js.map +1 -1
  59. package/dist/channels/google-chat/index.d.ts +210 -0
  60. package/dist/channels/google-chat/index.js +505 -0
  61. package/dist/channels/google-chat/index.js.map +1 -0
  62. package/dist/channels/group-security.d.ts +182 -0
  63. package/dist/channels/group-security.js +407 -0
  64. package/dist/channels/group-security.js.map +1 -0
  65. package/dist/channels/index.d.ts +17 -1
  66. package/dist/channels/index.js +16 -0
  67. package/dist/channels/index.js.map +1 -1
  68. package/dist/channels/matrix/index.d.ts +181 -0
  69. package/dist/channels/matrix/index.js +643 -0
  70. package/dist/channels/matrix/index.js.map +1 -0
  71. package/dist/channels/offline-queue.d.ts +92 -0
  72. package/dist/channels/offline-queue.js +112 -0
  73. package/dist/channels/offline-queue.js.map +1 -0
  74. package/dist/channels/reconnection-manager.d.ts +117 -0
  75. package/dist/channels/reconnection-manager.js +171 -0
  76. package/dist/channels/reconnection-manager.js.map +1 -0
  77. package/dist/channels/signal/index.d.ts +184 -0
  78. package/dist/channels/signal/index.js +488 -0
  79. package/dist/channels/signal/index.js.map +1 -0
  80. package/dist/channels/slack/client.d.ts +2 -1
  81. package/dist/channels/slack/client.js +30 -15
  82. package/dist/channels/slack/client.js.map +1 -1
  83. package/dist/channels/teams/index.d.ts +196 -0
  84. package/dist/channels/teams/index.js +477 -0
  85. package/dist/channels/teams/index.js.map +1 -0
  86. package/dist/channels/telegram/client.d.ts +3 -1
  87. package/dist/channels/telegram/client.js +29 -2
  88. package/dist/channels/telegram/client.js.map +1 -1
  89. package/dist/channels/webchat/index.d.ts +103 -0
  90. package/dist/channels/webchat/index.js +697 -0
  91. package/dist/channels/webchat/index.js.map +1 -0
  92. package/dist/channels/whatsapp/index.d.ts +105 -0
  93. package/dist/channels/whatsapp/index.js +533 -0
  94. package/dist/channels/whatsapp/index.js.map +1 -0
  95. package/dist/codebuddy/client.js +11 -5
  96. package/dist/codebuddy/client.js.map +1 -1
  97. package/dist/codebuddy/tool-definitions/advanced-tools.d.ts +1 -0
  98. package/dist/codebuddy/tool-definitions/advanced-tools.js +103 -3
  99. package/dist/codebuddy/tool-definitions/advanced-tools.js.map +1 -1
  100. package/dist/codebuddy/tool-definitions/index.d.ts +1 -1
  101. package/dist/codebuddy/tool-definitions/index.js +1 -1
  102. package/dist/codebuddy/tool-definitions/index.js.map +1 -1
  103. package/dist/codebuddy/tools.js +3 -1
  104. package/dist/codebuddy/tools.js.map +1 -1
  105. package/dist/commands/cli/config-command.d.ts +8 -0
  106. package/dist/commands/cli/config-command.js +90 -0
  107. package/dist/commands/cli/config-command.js.map +1 -0
  108. package/dist/commands/cli/openclaw-commands.d.ts +12 -0
  109. package/dist/commands/cli/openclaw-commands.js +446 -0
  110. package/dist/commands/cli/openclaw-commands.js.map +1 -0
  111. package/dist/commands/cli/utility-commands.js +30 -0
  112. package/dist/commands/cli/utility-commands.js.map +1 -1
  113. package/dist/commands/client-dispatcher.js +22 -2
  114. package/dist/commands/client-dispatcher.js.map +1 -1
  115. package/dist/commands/enhanced-command-handler.js +21 -2
  116. package/dist/commands/enhanced-command-handler.js.map +1 -1
  117. package/dist/commands/handlers/extra-handlers.d.ts +30 -0
  118. package/dist/commands/handlers/extra-handlers.js +547 -0
  119. package/dist/commands/handlers/extra-handlers.js.map +1 -0
  120. package/dist/commands/handlers/index.d.ts +1 -0
  121. package/dist/commands/handlers/index.js +2 -0
  122. package/dist/commands/handlers/index.js.map +1 -1
  123. package/dist/commands/slash/builtin-commands.js +41 -34
  124. package/dist/commands/slash/builtin-commands.js.map +1 -1
  125. package/dist/config/env-schema.d.ts +58 -0
  126. package/dist/config/env-schema.js +789 -0
  127. package/dist/config/env-schema.js.map +1 -0
  128. package/dist/config/feature-flags.js +2 -1
  129. package/dist/config/feature-flags.js.map +1 -1
  130. package/dist/context/bootstrap-loader.d.ts +48 -0
  131. package/dist/context/bootstrap-loader.js +123 -0
  132. package/dist/context/bootstrap-loader.js.map +1 -0
  133. package/dist/context/codebase-rag/chunker.js +2 -2
  134. package/dist/context/codebase-rag/chunker.js.map +1 -1
  135. package/dist/copilot/copilot-proxy.d.ts +15 -1
  136. package/dist/copilot/copilot-proxy.js +92 -23
  137. package/dist/copilot/copilot-proxy.js.map +1 -1
  138. package/dist/daemon/health-monitor.js +11 -7
  139. package/dist/daemon/health-monitor.js.map +1 -1
  140. package/dist/daemon/heartbeat.d.ts +112 -0
  141. package/dist/daemon/heartbeat.js +339 -0
  142. package/dist/daemon/heartbeat.js.map +1 -0
  143. package/dist/desktop-automation/smart-snapshot.d.ts +11 -0
  144. package/dist/desktop-automation/smart-snapshot.js +38 -0
  145. package/dist/desktop-automation/smart-snapshot.js.map +1 -1
  146. package/dist/extensions/extension-loader.js +4 -0
  147. package/dist/extensions/extension-loader.js.map +1 -1
  148. package/dist/identity/identity-manager.d.ts +95 -0
  149. package/dist/identity/identity-manager.js +242 -0
  150. package/dist/identity/identity-manager.js.map +1 -0
  151. package/dist/index.js +147 -17
  152. package/dist/index.js.map +1 -1
  153. package/dist/input/text-to-speech.js +4 -2
  154. package/dist/input/text-to-speech.js.map +1 -1
  155. package/dist/input/voice-control.js +5 -3
  156. package/dist/input/voice-control.js.map +1 -1
  157. package/dist/integrations/github-integration.js +1 -1
  158. package/dist/integrations/github-integration.js.map +1 -1
  159. package/dist/orchestration/orchestrator.js +3 -0
  160. package/dist/orchestration/orchestrator.js.map +1 -1
  161. package/dist/persistence/conversation-branches.js +2 -1
  162. package/dist/persistence/conversation-branches.js.map +1 -1
  163. package/dist/persistence/session-store.d.ts +1 -1
  164. package/dist/persistence/session-store.js +1 -1
  165. package/dist/persistence/session-store.js.map +1 -1
  166. package/dist/plugins/plugin-system.js +5 -2
  167. package/dist/plugins/plugin-system.js.map +1 -1
  168. package/dist/providers/gemini-provider.js +6 -4
  169. package/dist/providers/gemini-provider.js.map +1 -1
  170. package/dist/providers/local-llm-provider.js +8 -0
  171. package/dist/providers/local-llm-provider.js.map +1 -1
  172. package/dist/sandbox/auto-sandbox.d.ts +59 -0
  173. package/dist/sandbox/auto-sandbox.js +145 -0
  174. package/dist/sandbox/auto-sandbox.js.map +1 -0
  175. package/dist/scheduler/cron-scheduler.js +2 -0
  176. package/dist/scheduler/cron-scheduler.js.map +1 -1
  177. package/dist/scheduler/scheduler.js +11 -2
  178. package/dist/scheduler/scheduler.js.map +1 -1
  179. package/dist/security/audit-logger.d.ts +127 -0
  180. package/dist/security/audit-logger.js +194 -0
  181. package/dist/security/audit-logger.js.map +1 -0
  182. package/dist/security/bash-allowlist/allowlist-store.js +3 -2
  183. package/dist/security/bash-allowlist/allowlist-store.js.map +1 -1
  184. package/dist/security/bash-parser.js +0 -2
  185. package/dist/security/bash-parser.js.map +1 -1
  186. package/dist/security/code-validator.d.ts +51 -0
  187. package/dist/security/code-validator.js +185 -0
  188. package/dist/security/code-validator.js.map +1 -0
  189. package/dist/security/dangerous-patterns.d.ts +68 -0
  190. package/dist/security/dangerous-patterns.js +218 -0
  191. package/dist/security/dangerous-patterns.js.map +1 -0
  192. package/dist/security/remote-approval.d.ts +65 -0
  193. package/dist/security/remote-approval.js +138 -0
  194. package/dist/security/remote-approval.js.map +1 -0
  195. package/dist/security/security-audit.d.ts +7 -0
  196. package/dist/security/security-audit.js +23 -0
  197. package/dist/security/security-audit.js.map +1 -1
  198. package/dist/security/syntax-validator.d.ts +17 -0
  199. package/dist/security/syntax-validator.js +292 -0
  200. package/dist/security/syntax-validator.js.map +1 -0
  201. package/dist/server/index.js +277 -2
  202. package/dist/server/index.js.map +1 -1
  203. package/dist/server/middleware/logging.js +9 -1
  204. package/dist/server/middleware/logging.js.map +1 -1
  205. package/dist/server/routes/memory.js +4 -1
  206. package/dist/server/routes/memory.js.map +1 -1
  207. package/dist/server/routes/metrics.js +1 -1
  208. package/dist/server/routes/metrics.js.map +1 -1
  209. package/dist/server/routes/sessions.js +5 -4
  210. package/dist/server/routes/sessions.js.map +1 -1
  211. package/dist/server/websocket/handler.js +8 -2
  212. package/dist/server/websocket/handler.js.map +1 -1
  213. package/dist/services/prompt-builder.js +16 -0
  214. package/dist/services/prompt-builder.js.map +1 -1
  215. package/dist/skills/hub.d.ts +231 -0
  216. package/dist/skills/hub.js +694 -0
  217. package/dist/skills/hub.js.map +1 -0
  218. package/dist/skills/skill-loader.js +1 -1
  219. package/dist/skills/skill-loader.js.map +1 -1
  220. package/dist/skills/skill-manager.js +2 -1
  221. package/dist/skills/skill-manager.js.map +1 -1
  222. package/dist/skills/skill-registry.js +4 -0
  223. package/dist/skills/skill-registry.js.map +1 -1
  224. package/dist/talk-mode/providers/audioreader-tts.js +1 -0
  225. package/dist/talk-mode/providers/audioreader-tts.js.map +1 -1
  226. package/dist/tools/apply-patch.d.ts +1 -0
  227. package/dist/tools/apply-patch.js +66 -12
  228. package/dist/tools/apply-patch.js.map +1 -1
  229. package/dist/tools/bash/bash-tool.d.ts +123 -0
  230. package/dist/tools/bash/bash-tool.js +549 -0
  231. package/dist/tools/bash/bash-tool.js.map +1 -0
  232. package/dist/tools/bash/command-validator.d.ts +49 -0
  233. package/dist/tools/bash/command-validator.js +223 -0
  234. package/dist/tools/bash/command-validator.js.map +1 -0
  235. package/dist/tools/bash/index.d.ts +7 -0
  236. package/dist/tools/bash/index.js +8 -0
  237. package/dist/tools/bash/index.js.map +1 -0
  238. package/dist/tools/bash/security-patterns.d.ts +44 -0
  239. package/dist/tools/bash/security-patterns.js +234 -0
  240. package/dist/tools/bash/security-patterns.js.map +1 -0
  241. package/dist/tools/bash/streaming-executor.d.ts +23 -0
  242. package/dist/tools/bash/streaming-executor.js +134 -0
  243. package/dist/tools/bash/streaming-executor.js.map +1 -0
  244. package/dist/tools/bash.js +5 -3
  245. package/dist/tools/bash.js.map +1 -1
  246. package/dist/tools/code-formatter.js +41 -27
  247. package/dist/tools/code-formatter.js.map +1 -1
  248. package/dist/tools/code-review.js +1 -1
  249. package/dist/tools/code-review.js.map +1 -1
  250. package/dist/tools/computer-control-tool.js +21 -0
  251. package/dist/tools/computer-control-tool.js.map +1 -1
  252. package/dist/tools/document-tool.js +3 -2
  253. package/dist/tools/document-tool.js.map +1 -1
  254. package/dist/tools/git-tool.d.ts +45 -0
  255. package/dist/tools/git-tool.js +224 -2
  256. package/dist/tools/git-tool.js.map +1 -1
  257. package/dist/tools/index.d.ts +1 -1
  258. package/dist/tools/index.js +1 -1
  259. package/dist/tools/index.js.map +1 -1
  260. package/dist/tools/morph-editor.js +1 -0
  261. package/dist/tools/morph-editor.js.map +1 -1
  262. package/dist/tools/multi-edit.js +31 -3
  263. package/dist/tools/multi-edit.js.map +1 -1
  264. package/dist/tools/notebook-tool.js +8 -2
  265. package/dist/tools/notebook-tool.js.map +1 -1
  266. package/dist/tools/process-tool.d.ts +69 -0
  267. package/dist/tools/process-tool.js +222 -0
  268. package/dist/tools/process-tool.js.map +1 -0
  269. package/dist/tools/registry/git-tools.d.ts +32 -0
  270. package/dist/tools/registry/git-tools.js +211 -0
  271. package/dist/tools/registry/git-tools.js.map +1 -0
  272. package/dist/tools/registry/index.d.ts +2 -0
  273. package/dist/tools/registry/index.js +8 -0
  274. package/dist/tools/registry/index.js.map +1 -1
  275. package/dist/tools/registry/misc-tools.d.ts +32 -4
  276. package/dist/tools/registry/misc-tools.js +230 -90
  277. package/dist/tools/registry/misc-tools.js.map +1 -1
  278. package/dist/tools/registry/process-tools.d.ts +20 -0
  279. package/dist/tools/registry/process-tools.js +141 -0
  280. package/dist/tools/registry/process-tools.js.map +1 -0
  281. package/dist/tools/registry/types.d.ts +2 -0
  282. package/dist/tools/search.js +4 -2
  283. package/dist/tools/search.js.map +1 -1
  284. package/dist/tools/video-tool.js +30 -14
  285. package/dist/tools/video-tool.js.map +1 -1
  286. package/dist/tools/web-search.js +4 -1
  287. package/dist/tools/web-search.js.map +1 -1
  288. package/dist/ui/components/ChatInterface.js +9 -0
  289. package/dist/ui/components/ChatInterface.js.map +1 -1
  290. package/dist/utils/autonomy-manager.js +3 -2
  291. package/dist/utils/autonomy-manager.js.map +1 -1
  292. package/dist/utils/config-validation/schema.d.ts +15 -15
  293. package/dist/utils/confirmation-service.d.ts +16 -0
  294. package/dist/utils/confirmation-service.js +37 -3
  295. package/dist/utils/confirmation-service.js.map +1 -1
  296. package/dist/utils/custom-instructions.js +2 -1
  297. package/dist/utils/custom-instructions.js.map +1 -1
  298. package/dist/utils/diff-generator.js +3 -1
  299. package/dist/utils/diff-generator.js.map +1 -1
  300. package/dist/utils/graceful-shutdown.js +9 -9
  301. package/dist/utils/graceful-shutdown.js.map +1 -1
  302. package/dist/utils/head-tail-truncation.d.ts +18 -0
  303. package/dist/utils/head-tail-truncation.js +127 -0
  304. package/dist/utils/head-tail-truncation.js.map +1 -1
  305. package/dist/utils/history-manager.js +3 -2
  306. package/dist/utils/history-manager.js.map +1 -1
  307. package/dist/utils/logger.d.ts +2 -0
  308. package/dist/utils/logger.js +18 -3
  309. package/dist/utils/logger.js.map +1 -1
  310. package/dist/utils/performance.js +16 -15
  311. package/dist/utils/performance.js.map +1 -1
  312. package/dist/utils/stream-helpers.js +4 -2
  313. package/dist/utils/stream-helpers.js.map +1 -1
  314. package/dist/utils/update-notifier.js +2 -1
  315. package/dist/utils/update-notifier.js.map +1 -1
  316. package/dist/workflows/pipeline.d.ts +54 -1
  317. package/dist/workflows/pipeline.js +128 -7
  318. package/dist/workflows/pipeline.js.map +1 -1
  319. package/dist/workflows/step-manager.js +2 -1
  320. package/dist/workflows/step-manager.js.map +1 -1
  321. package/package.json +6 -3
@@ -0,0 +1,477 @@
1
+ /**
2
+ * Microsoft Teams Channel Adapter
3
+ *
4
+ * Microsoft Teams integration via the Bot Framework REST API.
5
+ * Uses the Bot Framework v4 protocol for authentication and messaging.
6
+ *
7
+ * Requires:
8
+ * - An Azure Bot resource with a Microsoft App ID and Password
9
+ * - The bot registered in the Teams Developer Portal
10
+ *
11
+ * The adapter receives activities via webhook (HTTP POST to /api/messages)
12
+ * and sends messages via the Bot Framework connector service.
13
+ *
14
+ * Reference: https://learn.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-connector-api-reference
15
+ */
16
+ import { BaseChannel, getSessionKey, checkDMPairing } from '../index.js';
17
+ import { logger } from '../../utils/logger.js';
18
+ // ============================================================================
19
+ // Channel Implementation
20
+ // ============================================================================
21
+ const BOT_FRAMEWORK_TOKEN_URL = 'https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token';
22
+ const BOT_FRAMEWORK_SCOPE = 'https://api.botframework.com/.default';
23
+ const OPENID_METADATA_URL = 'https://login.botframework.com/v1/.well-known/openidconfiguration';
24
+ /**
25
+ * Microsoft Teams channel using Bot Framework REST API
26
+ */
27
+ export class TeamsChannel extends BaseChannel {
28
+ accessToken = null;
29
+ tokenExpiry = 0;
30
+ conversationRefs = new Map();
31
+ serviceUrls = new Set();
32
+ constructor(config) {
33
+ super('teams', config);
34
+ if (!config.appId) {
35
+ throw new Error('Teams App ID is required');
36
+ }
37
+ if (!config.appPassword) {
38
+ throw new Error('Teams App Password is required');
39
+ }
40
+ }
41
+ get teamsConfig() {
42
+ return this.config;
43
+ }
44
+ // ==========================================================================
45
+ // Authentication
46
+ // ==========================================================================
47
+ /**
48
+ * Get a Bot Framework access token
49
+ */
50
+ async getAccessToken() {
51
+ // Return cached token if still valid (with 60s buffer)
52
+ if (this.accessToken && Date.now() < this.tokenExpiry - 60000) {
53
+ return this.accessToken;
54
+ }
55
+ const authority = this.teamsConfig.oauthAuthority ?? BOT_FRAMEWORK_TOKEN_URL;
56
+ const response = await fetch(authority, {
57
+ method: 'POST',
58
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
59
+ body: new URLSearchParams({
60
+ grant_type: 'client_credentials',
61
+ client_id: this.teamsConfig.appId,
62
+ client_secret: this.teamsConfig.appPassword,
63
+ scope: BOT_FRAMEWORK_SCOPE,
64
+ }),
65
+ });
66
+ if (!response.ok) {
67
+ const text = await response.text();
68
+ throw new Error(`Bot Framework token exchange failed: ${response.status} ${text}`);
69
+ }
70
+ const data = (await response.json());
71
+ this.accessToken = data.access_token;
72
+ this.tokenExpiry = Date.now() + data.expires_in * 1000;
73
+ return data.access_token;
74
+ }
75
+ /**
76
+ * Make an authenticated request to the Bot Connector API
77
+ */
78
+ async apiRequest(method, serviceUrl, endpoint, body) {
79
+ const token = await this.getAccessToken();
80
+ const baseUrl = serviceUrl.replace(/\/$/, '');
81
+ const url = `${baseUrl}${endpoint}`;
82
+ const response = await fetch(url, {
83
+ method,
84
+ headers: {
85
+ Authorization: `Bearer ${token}`,
86
+ 'Content-Type': 'application/json',
87
+ },
88
+ body: body ? JSON.stringify(body) : undefined,
89
+ });
90
+ if (!response.ok) {
91
+ const text = await response.text();
92
+ throw new Error(`Bot Framework API error: ${response.status} ${text}`);
93
+ }
94
+ const contentType = response.headers.get('content-type') ?? '';
95
+ if (contentType.includes('application/json')) {
96
+ return (await response.json());
97
+ }
98
+ const text = await response.text();
99
+ if (!text)
100
+ return {};
101
+ try {
102
+ return JSON.parse(text);
103
+ }
104
+ catch {
105
+ return text;
106
+ }
107
+ }
108
+ // ==========================================================================
109
+ // Lifecycle
110
+ // ==========================================================================
111
+ /**
112
+ * Connect to Teams by validating the app credentials.
113
+ * The actual message receiving happens via webhooks.
114
+ */
115
+ async connect() {
116
+ try {
117
+ // Validate credentials by fetching a token
118
+ await this.getAccessToken();
119
+ this.status.connected = true;
120
+ this.status.authenticated = true;
121
+ this.status.info = {
122
+ appId: this.teamsConfig.appId,
123
+ tenantId: this.teamsConfig.tenantId ?? 'botframework.com',
124
+ };
125
+ logger.debug('Teams connected', { appId: this.teamsConfig.appId });
126
+ this.emit('connected', 'teams');
127
+ }
128
+ catch (error) {
129
+ this.status.error = error instanceof Error ? error.message : String(error);
130
+ this.emit('error', 'teams', error instanceof Error ? error : new Error(String(error)));
131
+ throw error;
132
+ }
133
+ }
134
+ /**
135
+ * Disconnect from Teams
136
+ */
137
+ async disconnect() {
138
+ this.accessToken = null;
139
+ this.tokenExpiry = 0;
140
+ this.conversationRefs.clear();
141
+ this.serviceUrls.clear();
142
+ this.status.connected = false;
143
+ this.status.authenticated = false;
144
+ this.emit('disconnected', 'teams');
145
+ }
146
+ /**
147
+ * Send a message to a Teams conversation
148
+ */
149
+ async send(message) {
150
+ if (!this.status.connected) {
151
+ return { success: false, error: 'Teams not connected', timestamp: new Date() };
152
+ }
153
+ try {
154
+ // Look up conversation reference to find the serviceUrl
155
+ const ref = this.conversationRefs.get(message.channelId);
156
+ if (!ref) {
157
+ return {
158
+ success: false,
159
+ error: `No conversation reference found for ${message.channelId}. The bot must receive a message first.`,
160
+ timestamp: new Date(),
161
+ };
162
+ }
163
+ const activity = {
164
+ type: 'message',
165
+ text: message.content,
166
+ textFormat: message.parseMode === 'html' ? 'xml' : 'markdown',
167
+ };
168
+ // Reply threading
169
+ if (message.replyTo) {
170
+ activity.replyToId = message.replyTo;
171
+ }
172
+ // Attachments
173
+ if (message.attachments && message.attachments.length > 0) {
174
+ activity.attachments = message.attachments
175
+ .filter((a) => a.url)
176
+ .map((a) => ({
177
+ contentType: a.mimeType ?? 'application/octet-stream',
178
+ contentUrl: a.url,
179
+ name: a.fileName,
180
+ }));
181
+ }
182
+ // Buttons via hero card
183
+ if (message.buttons && message.buttons.length > 0) {
184
+ const heroCard = this.buildHeroCard(message.content, message.buttons);
185
+ activity.attachments = [
186
+ {
187
+ contentType: 'application/vnd.microsoft.card.hero',
188
+ content: heroCard,
189
+ },
190
+ ];
191
+ // When using a card, text goes in the card
192
+ delete activity.text;
193
+ }
194
+ const result = await this.apiRequest('POST', ref.serviceUrl, `/v3/conversations/${encodeURIComponent(ref.conversation.id)}/activities`, activity);
195
+ return {
196
+ success: true,
197
+ messageId: result.id,
198
+ timestamp: new Date(),
199
+ };
200
+ }
201
+ catch (error) {
202
+ logger.debug('Teams send error', {
203
+ error: error instanceof Error ? error.message : String(error),
204
+ });
205
+ return {
206
+ success: false,
207
+ error: error instanceof Error ? error.message : String(error),
208
+ timestamp: new Date(),
209
+ };
210
+ }
211
+ }
212
+ // ==========================================================================
213
+ // Webhook / Activity Handling
214
+ // ==========================================================================
215
+ /**
216
+ * Handle an incoming Bot Framework activity.
217
+ * Call this from your HTTP server when you receive a POST to /api/messages.
218
+ *
219
+ * @param activity - The parsed request body (Bot Framework Activity)
220
+ * @param authHeader - The Authorization header from the request (for validation)
221
+ */
222
+ async handleActivity(activity, authHeader) {
223
+ // Basic validation: ensure it's from Teams
224
+ if (activity.channelId && activity.channelId !== 'msteams' && activity.channelId !== 'emulator') {
225
+ logger.debug('Teams: ignoring activity from non-Teams channel', {
226
+ channelId: activity.channelId,
227
+ });
228
+ }
229
+ // Store conversation reference for proactive messaging
230
+ if (activity.from && activity.conversation && activity.serviceUrl && activity.recipient) {
231
+ this.storeConversationReference(activity);
232
+ }
233
+ switch (activity.type) {
234
+ case 'message':
235
+ await this.handleMessageActivity(activity);
236
+ break;
237
+ case 'conversationUpdate':
238
+ this.handleConversationUpdate(activity);
239
+ break;
240
+ case 'invoke':
241
+ await this.handleInvoke(activity);
242
+ break;
243
+ case 'event':
244
+ logger.debug('Teams: event activity', { name: activity.name });
245
+ break;
246
+ case 'messageReaction':
247
+ // Could emit reaction event
248
+ break;
249
+ default:
250
+ logger.debug('Teams: unhandled activity type', { type: activity.type });
251
+ }
252
+ }
253
+ /**
254
+ * Handle a message activity
255
+ */
256
+ async handleMessageActivity(activity) {
257
+ if (!activity.from || !activity.conversation)
258
+ return;
259
+ // Check user allowlist
260
+ if (!this.isUserAllowed(activity.from.id))
261
+ return;
262
+ // Check channel allowlist
263
+ if (!this.isChannelAllowed(activity.conversation.id))
264
+ return;
265
+ // Strip bot @mention from the text
266
+ let text = activity.text ?? '';
267
+ if (activity.entities) {
268
+ for (const entity of activity.entities) {
269
+ if (entity.type === 'mention' && entity.mentioned?.id === activity.recipient?.id) {
270
+ text = text.replace(entity.text ?? '', '').trim();
271
+ }
272
+ }
273
+ }
274
+ // Build attachments
275
+ const attachments = (activity.attachments ?? [])
276
+ .filter((a) => a.contentUrl)
277
+ .map((a) => ({
278
+ type: this.mimeToContentType(a.contentType),
279
+ url: a.contentUrl,
280
+ fileName: a.name,
281
+ mimeType: a.contentType,
282
+ }));
283
+ const isGroup = activity.conversation.isGroup ??
284
+ (activity.conversation.conversationType === 'groupChat' ||
285
+ activity.conversation.conversationType === 'channel');
286
+ const inbound = {
287
+ id: activity.id ?? `teams-${Date.now()}`,
288
+ channel: {
289
+ id: activity.conversation.id,
290
+ type: 'teams',
291
+ name: activity.conversation.name ?? activity.conversation.id,
292
+ isDM: !isGroup,
293
+ isGroup,
294
+ },
295
+ sender: {
296
+ id: activity.from.id,
297
+ displayName: activity.from.name,
298
+ isBot: activity.from.role === 'bot',
299
+ },
300
+ content: text,
301
+ contentType: attachments.length > 0 ? attachments[0].type : (text.startsWith('/') ? 'command' : 'text'),
302
+ attachments: attachments.length > 0 ? attachments : undefined,
303
+ replyTo: activity.replyToId,
304
+ timestamp: activity.timestamp ? new Date(activity.timestamp) : new Date(),
305
+ raw: activity,
306
+ };
307
+ const parsed = this.parseCommand(inbound);
308
+ parsed.sessionKey = getSessionKey(parsed);
309
+ // DM pairing check
310
+ const pairingStatus = await checkDMPairing(parsed);
311
+ if (!pairingStatus.approved) {
312
+ const { getDMPairing } = await import('../dm-pairing.js');
313
+ const pairingMessage = getDMPairing().getPairingMessage(pairingStatus);
314
+ if (pairingMessage) {
315
+ await this.send({ channelId: activity.conversation.id, content: pairingMessage });
316
+ }
317
+ return;
318
+ }
319
+ this.status.lastActivity = new Date();
320
+ this.emit('message', parsed);
321
+ if (parsed.isCommand) {
322
+ this.emit('command', parsed);
323
+ }
324
+ }
325
+ /**
326
+ * Handle conversation update (members added/removed)
327
+ */
328
+ handleConversationUpdate(activity) {
329
+ const channelData = activity.channelData ?? {};
330
+ const eventType = channelData.eventType;
331
+ logger.debug('Teams: conversation update', {
332
+ conversationId: activity.conversation?.id,
333
+ eventType,
334
+ });
335
+ }
336
+ /**
337
+ * Handle invoke activity (adaptive card actions, messaging extensions, etc.)
338
+ */
339
+ async handleInvoke(activity) {
340
+ if (!activity.from || !activity.conversation)
341
+ return;
342
+ if (activity.name === 'adaptiveCard/action') {
343
+ const value = activity.value;
344
+ if (value) {
345
+ const inbound = {
346
+ id: activity.id ?? `invoke-${Date.now()}`,
347
+ channel: {
348
+ id: activity.conversation.id,
349
+ type: 'teams',
350
+ name: activity.conversation.name ?? activity.conversation.id,
351
+ },
352
+ sender: {
353
+ id: activity.from.id,
354
+ displayName: activity.from.name,
355
+ },
356
+ content: JSON.stringify(value),
357
+ contentType: 'command',
358
+ isCommand: true,
359
+ commandName: 'card_action',
360
+ commandArgs: Object.entries(value).map(([k, v]) => `${k}=${v}`),
361
+ timestamp: new Date(),
362
+ raw: activity,
363
+ };
364
+ inbound.sessionKey = getSessionKey(inbound);
365
+ this.emit('command', inbound);
366
+ }
367
+ }
368
+ }
369
+ // ==========================================================================
370
+ // Proactive Messaging
371
+ // ==========================================================================
372
+ /**
373
+ * Store a conversation reference for later proactive messaging
374
+ */
375
+ storeConversationReference(activity) {
376
+ if (!activity.conversation || !activity.from || !activity.recipient || !activity.serviceUrl)
377
+ return;
378
+ const ref = {
379
+ activityId: activity.id,
380
+ user: activity.from,
381
+ bot: activity.recipient,
382
+ conversation: activity.conversation,
383
+ channelId: activity.channelId ?? 'msteams',
384
+ serviceUrl: activity.serviceUrl,
385
+ };
386
+ this.conversationRefs.set(activity.conversation.id, ref);
387
+ this.serviceUrls.add(activity.serviceUrl);
388
+ }
389
+ /**
390
+ * Get a stored conversation reference
391
+ */
392
+ getConversationReference(conversationId) {
393
+ return this.conversationRefs.get(conversationId);
394
+ }
395
+ /**
396
+ * Send a proactive message to a conversation.
397
+ * The bot must have previously received a message from that conversation.
398
+ */
399
+ async sendProactive(conversationId, text) {
400
+ return this.send({ channelId: conversationId, content: text });
401
+ }
402
+ /**
403
+ * Send typing indicator to a conversation
404
+ */
405
+ async sendTyping(conversationId) {
406
+ const ref = this.conversationRefs.get(conversationId);
407
+ if (!ref)
408
+ return;
409
+ try {
410
+ await this.apiRequest('POST', ref.serviceUrl, `/v3/conversations/${encodeURIComponent(conversationId)}/activities`, { type: 'typing' });
411
+ }
412
+ catch {
413
+ // Typing indicators are non-critical
414
+ }
415
+ }
416
+ /**
417
+ * Update a previously sent message
418
+ */
419
+ async updateMessage(conversationId, activityId, text) {
420
+ const ref = this.conversationRefs.get(conversationId);
421
+ if (!ref)
422
+ throw new Error(`No conversation reference for ${conversationId}`);
423
+ await this.apiRequest('PUT', ref.serviceUrl, `/v3/conversations/${encodeURIComponent(conversationId)}/activities/${encodeURIComponent(activityId)}`, {
424
+ type: 'message',
425
+ text,
426
+ id: activityId,
427
+ });
428
+ }
429
+ /**
430
+ * Delete a previously sent message
431
+ */
432
+ async deleteMessage(conversationId, activityId) {
433
+ const ref = this.conversationRefs.get(conversationId);
434
+ if (!ref)
435
+ throw new Error(`No conversation reference for ${conversationId}`);
436
+ await this.apiRequest('DELETE', ref.serviceUrl, `/v3/conversations/${encodeURIComponent(conversationId)}/activities/${encodeURIComponent(activityId)}`);
437
+ }
438
+ // ==========================================================================
439
+ // Helpers
440
+ // ==========================================================================
441
+ /**
442
+ * Build a hero card with buttons
443
+ */
444
+ buildHeroCard(text, buttons) {
445
+ return {
446
+ title: '',
447
+ text,
448
+ buttons: buttons.map((btn) => {
449
+ if (btn.type === 'url' && btn.url) {
450
+ return { type: 'openUrl', title: btn.text, value: btn.url };
451
+ }
452
+ return {
453
+ type: 'messageBack',
454
+ title: btn.text,
455
+ text: btn.data ?? btn.text,
456
+ value: btn.data ?? btn.text,
457
+ };
458
+ }),
459
+ };
460
+ }
461
+ /**
462
+ * Map MIME type to ContentType
463
+ */
464
+ mimeToContentType(mime) {
465
+ if (!mime)
466
+ return 'file';
467
+ if (mime.startsWith('image/'))
468
+ return 'image';
469
+ if (mime.startsWith('audio/'))
470
+ return 'audio';
471
+ if (mime.startsWith('video/'))
472
+ return 'video';
473
+ return 'file';
474
+ }
475
+ }
476
+ export default TeamsChannel;
477
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/channels/teams/index.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,8 @@ export declare class TelegramChannel extends BaseChannel {
15
15
  private pollingTimeout;
16
16
  private lastUpdateId;
17
17
  private botInfo;
18
+ private reconnectionManager;
19
+ private consecutiveErrors;
18
20
  constructor(config: TelegramConfig);
19
21
  private get telegramConfig();
20
22
  private get apiUrl();
@@ -51,7 +53,7 @@ export declare class TelegramChannel extends BaseChannel {
51
53
  */
52
54
  private startPolling;
53
55
  /**
54
- * Poll for updates
56
+ * Poll for updates with reconnection support
55
57
  */
56
58
  private poll;
57
59
  /**
@@ -5,6 +5,8 @@
5
5
  * Supports both polling and webhook modes.
6
6
  */
7
7
  import { BaseChannel, getSessionKey, checkDMPairing } from '../index.js';
8
+ import { ReconnectionManager } from '../reconnection-manager.js';
9
+ import { logger } from '../../utils/logger.js';
8
10
  const TELEGRAM_API_BASE = 'https://api.telegram.org';
9
11
  /**
10
12
  * Telegram channel implementation
@@ -14,11 +16,18 @@ export class TelegramChannel extends BaseChannel {
14
16
  pollingTimeout = null;
15
17
  lastUpdateId = 0;
16
18
  botInfo = null;
19
+ reconnectionManager;
20
+ consecutiveErrors = 0;
17
21
  constructor(config) {
18
22
  super('telegram', config);
19
23
  if (!config.token) {
20
24
  throw new Error('Telegram bot token is required');
21
25
  }
26
+ this.reconnectionManager = new ReconnectionManager('telegram', {
27
+ maxRetries: 10,
28
+ initialDelayMs: 2000,
29
+ maxDelayMs: 60000,
30
+ });
22
31
  }
23
32
  get telegramConfig() {
24
33
  return this.config;
@@ -81,7 +90,9 @@ export class TelegramChannel extends BaseChannel {
81
90
  * Disconnect from Telegram
82
91
  */
83
92
  async disconnect() {
93
+ this.reconnectionManager.cancel();
84
94
  this.pollingActive = false;
95
+ this.consecutiveErrors = 0;
85
96
  if (this.pollingTimeout) {
86
97
  clearTimeout(this.pollingTimeout);
87
98
  this.pollingTimeout = null;
@@ -238,7 +249,7 @@ export class TelegramChannel extends BaseChannel {
238
249
  this.poll();
239
250
  }
240
251
  /**
241
- * Poll for updates
252
+ * Poll for updates with reconnection support
242
253
  */
243
254
  async poll() {
244
255
  if (!this.pollingActive)
@@ -249,14 +260,30 @@ export class TelegramChannel extends BaseChannel {
249
260
  timeout: this.telegramConfig.pollingTimeout ?? 30,
250
261
  allowed_updates: ['message', 'edited_message', 'callback_query'],
251
262
  });
263
+ // Reset consecutive error count on success
264
+ this.consecutiveErrors = 0;
265
+ this.reconnectionManager.onConnected();
252
266
  for (const update of updates) {
253
267
  this.lastUpdateId = update.update_id;
254
268
  await this.handleUpdate(update);
255
269
  }
256
270
  }
257
271
  catch (error) {
272
+ this.consecutiveErrors++;
258
273
  this.emit('error', 'telegram', error);
259
- // Backoff on error
274
+ if (this.consecutiveErrors >= 5) {
275
+ // Too many consecutive errors -- use reconnection manager
276
+ logger.debug('Telegram: too many consecutive polling errors, attempting reconnect');
277
+ this.pollingActive = false;
278
+ this.status.connected = false;
279
+ this.reconnectionManager.scheduleReconnect(async () => {
280
+ this.consecutiveErrors = 0;
281
+ await this.connect();
282
+ this.reconnectionManager.onConnected();
283
+ });
284
+ return;
285
+ }
286
+ // Simple backoff for transient errors
260
287
  await new Promise((resolve) => setTimeout(resolve, 5000));
261
288
  if (!this.pollingActive)
262
289
  return;