@phuetz/code-buddy 0.1.13 → 0.1.15

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 (258) 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 +61 -0
  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/types.d.ts +7 -2
  23. package/dist/analytics/budget-alerts.d.ts +81 -0
  24. package/dist/analytics/budget-alerts.js +126 -0
  25. package/dist/analytics/budget-alerts.js.map +1 -0
  26. package/dist/analytics/cost-predictor.d.ts +79 -0
  27. package/dist/analytics/cost-predictor.js +150 -0
  28. package/dist/analytics/cost-predictor.js.map +1 -0
  29. package/dist/analytics/index.d.ts +2 -0
  30. package/dist/analytics/index.js +2 -0
  31. package/dist/analytics/index.js.map +1 -1
  32. package/dist/auth/profile-manager.d.ts +205 -0
  33. package/dist/auth/profile-manager.js +484 -0
  34. package/dist/auth/profile-manager.js.map +1 -0
  35. package/dist/browser-automation/browser-manager.d.ts +79 -1
  36. package/dist/browser-automation/browser-manager.js +265 -2
  37. package/dist/browser-automation/browser-manager.js.map +1 -1
  38. package/dist/browser-automation/profile-manager.d.ts +32 -0
  39. package/dist/browser-automation/profile-manager.js +83 -0
  40. package/dist/browser-automation/profile-manager.js.map +1 -0
  41. package/dist/browser-automation/route-interceptor.d.ts +29 -0
  42. package/dist/browser-automation/route-interceptor.js +103 -0
  43. package/dist/browser-automation/route-interceptor.js.map +1 -0
  44. package/dist/browser-automation/screenshot-annotator.d.ts +23 -0
  45. package/dist/browser-automation/screenshot-annotator.js +86 -0
  46. package/dist/browser-automation/screenshot-annotator.js.map +1 -0
  47. package/dist/browser-automation/types.d.ts +47 -0
  48. package/dist/channels/discord/client.d.ts +2 -1
  49. package/dist/channels/discord/client.js +28 -16
  50. package/dist/channels/discord/client.js.map +1 -1
  51. package/dist/channels/google-chat/index.d.ts +210 -0
  52. package/dist/channels/google-chat/index.js +505 -0
  53. package/dist/channels/google-chat/index.js.map +1 -0
  54. package/dist/channels/group-security.d.ts +182 -0
  55. package/dist/channels/group-security.js +407 -0
  56. package/dist/channels/group-security.js.map +1 -0
  57. package/dist/channels/index.d.ts +17 -1
  58. package/dist/channels/index.js +16 -0
  59. package/dist/channels/index.js.map +1 -1
  60. package/dist/channels/matrix/index.d.ts +181 -0
  61. package/dist/channels/matrix/index.js +643 -0
  62. package/dist/channels/matrix/index.js.map +1 -0
  63. package/dist/channels/offline-queue.d.ts +92 -0
  64. package/dist/channels/offline-queue.js +112 -0
  65. package/dist/channels/offline-queue.js.map +1 -0
  66. package/dist/channels/reconnection-manager.d.ts +117 -0
  67. package/dist/channels/reconnection-manager.js +179 -0
  68. package/dist/channels/reconnection-manager.js.map +1 -0
  69. package/dist/channels/signal/index.d.ts +184 -0
  70. package/dist/channels/signal/index.js +488 -0
  71. package/dist/channels/signal/index.js.map +1 -0
  72. package/dist/channels/slack/client.d.ts +2 -1
  73. package/dist/channels/slack/client.js +30 -20
  74. package/dist/channels/slack/client.js.map +1 -1
  75. package/dist/channels/teams/index.d.ts +196 -0
  76. package/dist/channels/teams/index.js +477 -0
  77. package/dist/channels/teams/index.js.map +1 -0
  78. package/dist/channels/telegram/client.d.ts +3 -1
  79. package/dist/channels/telegram/client.js +29 -2
  80. package/dist/channels/telegram/client.js.map +1 -1
  81. package/dist/channels/webchat/index.d.ts +103 -0
  82. package/dist/channels/webchat/index.js +697 -0
  83. package/dist/channels/webchat/index.js.map +1 -0
  84. package/dist/channels/whatsapp/index.d.ts +105 -0
  85. package/dist/channels/whatsapp/index.js +533 -0
  86. package/dist/channels/whatsapp/index.js.map +1 -0
  87. package/dist/codebuddy/client.js +6 -3
  88. package/dist/codebuddy/client.js.map +1 -1
  89. package/dist/codebuddy/tool-definitions/advanced-tools.d.ts +1 -0
  90. package/dist/codebuddy/tool-definitions/advanced-tools.js +103 -3
  91. package/dist/codebuddy/tool-definitions/advanced-tools.js.map +1 -1
  92. package/dist/codebuddy/tool-definitions/index.d.ts +1 -1
  93. package/dist/codebuddy/tool-definitions/index.js +1 -1
  94. package/dist/codebuddy/tool-definitions/index.js.map +1 -1
  95. package/dist/codebuddy/tools.js +3 -1
  96. package/dist/codebuddy/tools.js.map +1 -1
  97. package/dist/commands/cli/config-command.d.ts +8 -0
  98. package/dist/commands/cli/config-command.js +90 -0
  99. package/dist/commands/cli/config-command.js.map +1 -0
  100. package/dist/commands/cli/openclaw-commands.d.ts +12 -0
  101. package/dist/commands/cli/openclaw-commands.js +446 -0
  102. package/dist/commands/cli/openclaw-commands.js.map +1 -0
  103. package/dist/commands/cli/utility-commands.js +30 -0
  104. package/dist/commands/cli/utility-commands.js.map +1 -1
  105. package/dist/commands/client-dispatcher.js +22 -2
  106. package/dist/commands/client-dispatcher.js.map +1 -1
  107. package/dist/commands/enhanced-command-handler.js +21 -2
  108. package/dist/commands/enhanced-command-handler.js.map +1 -1
  109. package/dist/commands/handlers/extra-handlers.d.ts +30 -0
  110. package/dist/commands/handlers/extra-handlers.js +547 -0
  111. package/dist/commands/handlers/extra-handlers.js.map +1 -0
  112. package/dist/commands/handlers/index.d.ts +1 -0
  113. package/dist/commands/handlers/index.js +2 -0
  114. package/dist/commands/handlers/index.js.map +1 -1
  115. package/dist/commands/slash/builtin-commands.js +41 -34
  116. package/dist/commands/slash/builtin-commands.js.map +1 -1
  117. package/dist/config/env-schema.d.ts +58 -0
  118. package/dist/config/env-schema.js +789 -0
  119. package/dist/config/env-schema.js.map +1 -0
  120. package/dist/config/feature-flags.js +2 -1
  121. package/dist/config/feature-flags.js.map +1 -1
  122. package/dist/context/bootstrap-loader.d.ts +48 -0
  123. package/dist/context/bootstrap-loader.js +123 -0
  124. package/dist/context/bootstrap-loader.js.map +1 -0
  125. package/dist/copilot/copilot-proxy.d.ts +15 -1
  126. package/dist/copilot/copilot-proxy.js +81 -22
  127. package/dist/copilot/copilot-proxy.js.map +1 -1
  128. package/dist/daemon/heartbeat.d.ts +112 -0
  129. package/dist/daemon/heartbeat.js +339 -0
  130. package/dist/daemon/heartbeat.js.map +1 -0
  131. package/dist/desktop-automation/smart-snapshot.d.ts +11 -0
  132. package/dist/desktop-automation/smart-snapshot.js +28 -0
  133. package/dist/desktop-automation/smart-snapshot.js.map +1 -1
  134. package/dist/identity/identity-manager.d.ts +95 -0
  135. package/dist/identity/identity-manager.js +242 -0
  136. package/dist/identity/identity-manager.js.map +1 -0
  137. package/dist/index.js +147 -17
  138. package/dist/index.js.map +1 -1
  139. package/dist/integrations/github-integration.js +1 -1
  140. package/dist/integrations/github-integration.js.map +1 -1
  141. package/dist/persistence/conversation-branches.js +2 -1
  142. package/dist/persistence/conversation-branches.js.map +1 -1
  143. package/dist/persistence/session-store.d.ts +1 -1
  144. package/dist/persistence/session-store.js +1 -1
  145. package/dist/persistence/session-store.js.map +1 -1
  146. package/dist/sandbox/auto-sandbox.d.ts +59 -0
  147. package/dist/sandbox/auto-sandbox.js +145 -0
  148. package/dist/sandbox/auto-sandbox.js.map +1 -0
  149. package/dist/security/audit-logger.d.ts +127 -0
  150. package/dist/security/audit-logger.js +194 -0
  151. package/dist/security/audit-logger.js.map +1 -0
  152. package/dist/security/bash-allowlist/allowlist-store.js +3 -2
  153. package/dist/security/bash-allowlist/allowlist-store.js.map +1 -1
  154. package/dist/security/bash-parser.js +0 -2
  155. package/dist/security/bash-parser.js.map +1 -1
  156. package/dist/security/code-validator.d.ts +51 -0
  157. package/dist/security/code-validator.js +185 -0
  158. package/dist/security/code-validator.js.map +1 -0
  159. package/dist/security/dangerous-patterns.d.ts +68 -0
  160. package/dist/security/dangerous-patterns.js +218 -0
  161. package/dist/security/dangerous-patterns.js.map +1 -0
  162. package/dist/security/remote-approval.d.ts +65 -0
  163. package/dist/security/remote-approval.js +138 -0
  164. package/dist/security/remote-approval.js.map +1 -0
  165. package/dist/security/security-audit.d.ts +7 -0
  166. package/dist/security/security-audit.js +23 -0
  167. package/dist/security/security-audit.js.map +1 -1
  168. package/dist/security/syntax-validator.d.ts +17 -0
  169. package/dist/security/syntax-validator.js +292 -0
  170. package/dist/security/syntax-validator.js.map +1 -0
  171. package/dist/server/index.js +277 -2
  172. package/dist/server/index.js.map +1 -1
  173. package/dist/services/prompt-builder.js +16 -0
  174. package/dist/services/prompt-builder.js.map +1 -1
  175. package/dist/skills/hub.d.ts +231 -0
  176. package/dist/skills/hub.js +694 -0
  177. package/dist/skills/hub.js.map +1 -0
  178. package/dist/skills/skill-loader.js +1 -1
  179. package/dist/skills/skill-loader.js.map +1 -1
  180. package/dist/skills/skill-manager.js +2 -1
  181. package/dist/skills/skill-manager.js.map +1 -1
  182. package/dist/tools/apply-patch.d.ts +1 -0
  183. package/dist/tools/apply-patch.js +57 -10
  184. package/dist/tools/apply-patch.js.map +1 -1
  185. package/dist/tools/bash/bash-tool.d.ts +123 -0
  186. package/dist/tools/bash/bash-tool.js +549 -0
  187. package/dist/tools/bash/bash-tool.js.map +1 -0
  188. package/dist/tools/bash/command-validator.d.ts +49 -0
  189. package/dist/tools/bash/command-validator.js +223 -0
  190. package/dist/tools/bash/command-validator.js.map +1 -0
  191. package/dist/tools/bash/index.d.ts +7 -0
  192. package/dist/tools/bash/index.js +8 -0
  193. package/dist/tools/bash/index.js.map +1 -0
  194. package/dist/tools/bash/security-patterns.d.ts +44 -0
  195. package/dist/tools/bash/security-patterns.js +234 -0
  196. package/dist/tools/bash/security-patterns.js.map +1 -0
  197. package/dist/tools/bash/streaming-executor.d.ts +23 -0
  198. package/dist/tools/bash/streaming-executor.js +134 -0
  199. package/dist/tools/bash/streaming-executor.js.map +1 -0
  200. package/dist/tools/code-formatter.js +41 -27
  201. package/dist/tools/code-formatter.js.map +1 -1
  202. package/dist/tools/code-review.js +1 -1
  203. package/dist/tools/code-review.js.map +1 -1
  204. package/dist/tools/computer-control-tool.js +21 -0
  205. package/dist/tools/computer-control-tool.js.map +1 -1
  206. package/dist/tools/document-tool.js +3 -2
  207. package/dist/tools/document-tool.js.map +1 -1
  208. package/dist/tools/git-tool.d.ts +45 -0
  209. package/dist/tools/git-tool.js +222 -0
  210. package/dist/tools/git-tool.js.map +1 -1
  211. package/dist/tools/index.d.ts +1 -1
  212. package/dist/tools/index.js +1 -1
  213. package/dist/tools/index.js.map +1 -1
  214. package/dist/tools/multi-edit.js +31 -3
  215. package/dist/tools/multi-edit.js.map +1 -1
  216. package/dist/tools/process-tool.d.ts +69 -0
  217. package/dist/tools/process-tool.js +222 -0
  218. package/dist/tools/process-tool.js.map +1 -0
  219. package/dist/tools/registry/git-tools.d.ts +32 -0
  220. package/dist/tools/registry/git-tools.js +211 -0
  221. package/dist/tools/registry/git-tools.js.map +1 -0
  222. package/dist/tools/registry/index.d.ts +2 -0
  223. package/dist/tools/registry/index.js +8 -0
  224. package/dist/tools/registry/index.js.map +1 -1
  225. package/dist/tools/registry/misc-tools.d.ts +32 -4
  226. package/dist/tools/registry/misc-tools.js +230 -90
  227. package/dist/tools/registry/misc-tools.js.map +1 -1
  228. package/dist/tools/registry/process-tools.d.ts +20 -0
  229. package/dist/tools/registry/process-tools.js +141 -0
  230. package/dist/tools/registry/process-tools.js.map +1 -0
  231. package/dist/tools/registry/types.d.ts +2 -0
  232. package/dist/ui/components/ChatInterface.js +9 -0
  233. package/dist/ui/components/ChatInterface.js.map +1 -1
  234. package/dist/utils/autonomy-manager.js +3 -2
  235. package/dist/utils/autonomy-manager.js.map +1 -1
  236. package/dist/utils/config-validation/schema.d.ts +15 -15
  237. package/dist/utils/confirmation-service.d.ts +16 -0
  238. package/dist/utils/confirmation-service.js +37 -3
  239. package/dist/utils/confirmation-service.js.map +1 -1
  240. package/dist/utils/custom-instructions.js +2 -1
  241. package/dist/utils/custom-instructions.js.map +1 -1
  242. package/dist/utils/graceful-shutdown.js +9 -9
  243. package/dist/utils/graceful-shutdown.js.map +1 -1
  244. package/dist/utils/head-tail-truncation.d.ts +18 -0
  245. package/dist/utils/head-tail-truncation.js +127 -0
  246. package/dist/utils/head-tail-truncation.js.map +1 -1
  247. package/dist/utils/history-manager.js +3 -2
  248. package/dist/utils/history-manager.js.map +1 -1
  249. package/dist/utils/performance.js +16 -15
  250. package/dist/utils/performance.js.map +1 -1
  251. package/dist/utils/update-notifier.js +2 -1
  252. package/dist/utils/update-notifier.js.map +1 -1
  253. package/dist/workflows/pipeline.d.ts +54 -1
  254. package/dist/workflows/pipeline.js +128 -7
  255. package/dist/workflows/pipeline.js.map +1 -1
  256. package/dist/workflows/step-manager.js +2 -1
  257. package/dist/workflows/step-manager.js.map +1 -1
  258. package/package.json +6 -3
@@ -0,0 +1,505 @@
1
+ /**
2
+ * Google Chat Channel Adapter
3
+ *
4
+ * Google Chat integration via Google Workspace Chat API.
5
+ * Uses service account authentication for bot-to-space messaging.
6
+ *
7
+ * Requires:
8
+ * - A Google Cloud project with the Chat API enabled
9
+ * - A service account with Chat Bot scope
10
+ * - The service account JSON key file
11
+ *
12
+ * The adapter operates in two modes:
13
+ * 1. Webhook mode (push): Google Chat sends events to a configured endpoint
14
+ * 2. Pull mode: Polls for space activity via the REST API (limited, mainly for sending)
15
+ *
16
+ * Primary documentation: https://developers.google.com/workspace/chat/api/reference/rest
17
+ */
18
+ import { BaseChannel, getSessionKey, checkDMPairing } from '../index.js';
19
+ import { logger } from '../../utils/logger.js';
20
+ import { readFileSync } from 'fs';
21
+ import crypto from 'crypto';
22
+ // ============================================================================
23
+ // Channel Implementation
24
+ // ============================================================================
25
+ const GOOGLE_CHAT_API = 'https://chat.googleapis.com/v1';
26
+ const GOOGLE_TOKEN_URL = 'https://oauth2.googleapis.com/token';
27
+ const GOOGLE_CHAT_SCOPE = 'https://www.googleapis.com/auth/chat.bot';
28
+ /**
29
+ * Google Chat channel using the Workspace Chat API
30
+ */
31
+ export class GoogleChatChannel extends BaseChannel {
32
+ serviceAccount = null;
33
+ accessToken = null;
34
+ tokenExpiry = 0;
35
+ spaceCache = new Map();
36
+ constructor(config) {
37
+ super('google-chat', config);
38
+ if (!config.serviceAccountPath) {
39
+ throw new Error('Google Chat service account path is required');
40
+ }
41
+ }
42
+ get gchatConfig() {
43
+ return this.config;
44
+ }
45
+ // ==========================================================================
46
+ // Auth (Service Account JWT -> Access Token)
47
+ // ==========================================================================
48
+ /**
49
+ * Load the service account key from disk
50
+ */
51
+ loadServiceAccount() {
52
+ try {
53
+ const raw = readFileSync(this.gchatConfig.serviceAccountPath, 'utf-8');
54
+ return JSON.parse(raw);
55
+ }
56
+ catch (err) {
57
+ throw new Error(`Failed to load Google service account from ${this.gchatConfig.serviceAccountPath}: ${err instanceof Error ? err.message : String(err)}`);
58
+ }
59
+ }
60
+ /**
61
+ * Create a signed JWT for the service account
62
+ */
63
+ createJwt(sa) {
64
+ const now = Math.floor(Date.now() / 1000);
65
+ const expiry = now + 3600; // 1 hour
66
+ const header = { alg: 'RS256', typ: 'JWT' };
67
+ const payload = {
68
+ iss: sa.client_email,
69
+ scope: GOOGLE_CHAT_SCOPE,
70
+ aud: GOOGLE_TOKEN_URL,
71
+ iat: now,
72
+ exp: expiry,
73
+ };
74
+ const encode = (obj) => Buffer.from(JSON.stringify(obj)).toString('base64url');
75
+ const unsigned = `${encode(header)}.${encode(payload)}`;
76
+ const signer = crypto.createSign('RSA-SHA256');
77
+ signer.update(unsigned);
78
+ const signature = signer.sign(sa.private_key, 'base64url');
79
+ return `${unsigned}.${signature}`;
80
+ }
81
+ /**
82
+ * Exchange the signed JWT for a Google OAuth2 access token
83
+ */
84
+ async getAccessToken() {
85
+ // Return cached token if still valid (with 60s buffer)
86
+ if (this.accessToken && Date.now() < this.tokenExpiry - 60000) {
87
+ return this.accessToken;
88
+ }
89
+ if (!this.serviceAccount) {
90
+ this.serviceAccount = this.loadServiceAccount();
91
+ }
92
+ const jwt = this.createJwt(this.serviceAccount);
93
+ const response = await fetch(GOOGLE_TOKEN_URL, {
94
+ method: 'POST',
95
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
96
+ body: new URLSearchParams({
97
+ grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
98
+ assertion: jwt,
99
+ }),
100
+ });
101
+ if (!response.ok) {
102
+ const text = await response.text();
103
+ throw new Error(`Google OAuth token exchange failed: ${response.status} ${text}`);
104
+ }
105
+ const data = (await response.json());
106
+ this.accessToken = data.access_token;
107
+ this.tokenExpiry = Date.now() + data.expires_in * 1000;
108
+ return data.access_token;
109
+ }
110
+ // ==========================================================================
111
+ // API Requests
112
+ // ==========================================================================
113
+ /**
114
+ * Make an authenticated request to the Google Chat API
115
+ */
116
+ async apiRequest(method, endpoint, body) {
117
+ const token = await this.getAccessToken();
118
+ const url = `${GOOGLE_CHAT_API}${endpoint}`;
119
+ const response = await fetch(url, {
120
+ method,
121
+ headers: {
122
+ Authorization: `Bearer ${token}`,
123
+ 'Content-Type': 'application/json',
124
+ },
125
+ body: body ? JSON.stringify(body) : undefined,
126
+ });
127
+ if (!response.ok) {
128
+ const text = await response.text();
129
+ throw new Error(`Google Chat API error: ${response.status} ${text}`);
130
+ }
131
+ const contentType = response.headers.get('content-type') ?? '';
132
+ if (contentType.includes('application/json')) {
133
+ return (await response.json());
134
+ }
135
+ return {};
136
+ }
137
+ // ==========================================================================
138
+ // Lifecycle
139
+ // ==========================================================================
140
+ /**
141
+ * Connect to Google Chat by validating the service account and
142
+ * verifying API access
143
+ */
144
+ async connect() {
145
+ try {
146
+ // Load and validate service account
147
+ this.serviceAccount = this.loadServiceAccount();
148
+ // Get an access token (validates the key)
149
+ await this.getAccessToken();
150
+ // Verify we can list spaces (basic API access check)
151
+ try {
152
+ const resp = await this.apiRequest('GET', '/spaces?pageSize=1');
153
+ if (resp.spaces) {
154
+ for (const space of resp.spaces) {
155
+ this.spaceCache.set(space.name, space);
156
+ }
157
+ }
158
+ }
159
+ catch (err) {
160
+ // Non-fatal: some bots might only work via DMs and not have list permission
161
+ logger.debug('Google Chat: could not list spaces (non-critical)', {
162
+ error: err instanceof Error ? err.message : String(err),
163
+ });
164
+ }
165
+ this.status.connected = true;
166
+ this.status.authenticated = true;
167
+ this.status.info = {
168
+ serviceAccount: this.serviceAccount.client_email,
169
+ projectId: this.serviceAccount.project_id,
170
+ defaultSpace: this.gchatConfig.spaceId,
171
+ };
172
+ logger.debug('Google Chat connected', {
173
+ serviceAccount: this.serviceAccount.client_email,
174
+ });
175
+ this.emit('connected', 'google-chat');
176
+ }
177
+ catch (error) {
178
+ this.status.error = error instanceof Error ? error.message : String(error);
179
+ this.emit('error', 'google-chat', error instanceof Error ? error : new Error(String(error)));
180
+ throw error;
181
+ }
182
+ }
183
+ /**
184
+ * Disconnect from Google Chat
185
+ */
186
+ async disconnect() {
187
+ this.accessToken = null;
188
+ this.tokenExpiry = 0;
189
+ this.serviceAccount = null;
190
+ this.spaceCache.clear();
191
+ this.status.connected = false;
192
+ this.status.authenticated = false;
193
+ this.emit('disconnected', 'google-chat');
194
+ }
195
+ /**
196
+ * Send a message to a Google Chat space
197
+ */
198
+ async send(message) {
199
+ if (!this.status.connected) {
200
+ return { success: false, error: 'Google Chat not connected', timestamp: new Date() };
201
+ }
202
+ try {
203
+ // channelId should be a space name like "spaces/AAAA" or just the space ID
204
+ const spaceName = message.channelId.startsWith('spaces/')
205
+ ? message.channelId
206
+ : `spaces/${message.channelId}`;
207
+ const payload = {
208
+ text: message.content,
209
+ };
210
+ // Thread support
211
+ if (message.threadId) {
212
+ payload.thread = { name: message.threadId };
213
+ // Reply in the same thread
214
+ }
215
+ // Card support for attachments/buttons
216
+ if (message.buttons && message.buttons.length > 0) {
217
+ payload.cardsV2 = [
218
+ {
219
+ cardId: `card-${Date.now()}`,
220
+ card: {
221
+ sections: [
222
+ {
223
+ widgets: [
224
+ {
225
+ buttonList: {
226
+ buttons: message.buttons.map((btn) => {
227
+ if (btn.type === 'url' && btn.url) {
228
+ return {
229
+ text: btn.text,
230
+ onClick: { openLink: { url: btn.url } },
231
+ };
232
+ }
233
+ return {
234
+ text: btn.text,
235
+ onClick: {
236
+ action: {
237
+ actionMethodName: btn.data ?? btn.text,
238
+ },
239
+ },
240
+ };
241
+ }),
242
+ },
243
+ },
244
+ ],
245
+ },
246
+ ],
247
+ },
248
+ },
249
+ ];
250
+ }
251
+ const queryParams = message.threadId
252
+ ? '?messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD'
253
+ : '';
254
+ const result = await this.apiRequest('POST', `/${spaceName}/messages${queryParams}`, payload);
255
+ // Extract message ID from the name (spaces/{spaceId}/messages/{messageId})
256
+ const messageId = result.name?.split('/').pop();
257
+ return {
258
+ success: true,
259
+ messageId,
260
+ timestamp: new Date(),
261
+ };
262
+ }
263
+ catch (error) {
264
+ logger.debug('Google Chat send error', {
265
+ error: error instanceof Error ? error.message : String(error),
266
+ });
267
+ return {
268
+ success: false,
269
+ error: error instanceof Error ? error.message : String(error),
270
+ timestamp: new Date(),
271
+ };
272
+ }
273
+ }
274
+ // ==========================================================================
275
+ // Webhook Handling (Push Mode)
276
+ // ==========================================================================
277
+ /**
278
+ * Handle an incoming Google Chat webhook event.
279
+ * Call this from your HTTP server route handler.
280
+ *
281
+ * @param event - The parsed request body
282
+ * @param bearerToken - The Bearer token from the Authorization header (optional)
283
+ * @returns Response body to send back to Google Chat (can include a synchronous reply)
284
+ */
285
+ async handleWebhook(event, bearerToken) {
286
+ // Verify token if configured
287
+ if (this.gchatConfig.verificationToken) {
288
+ if (event.token !== this.gchatConfig.verificationToken) {
289
+ logger.debug('Google Chat: webhook token mismatch');
290
+ return;
291
+ }
292
+ }
293
+ switch (event.type) {
294
+ case 'MESSAGE':
295
+ return this.handleMessageEvent(event);
296
+ case 'ADDED_TO_SPACE':
297
+ logger.debug('Google Chat: bot added to space', {
298
+ space: event.space?.name,
299
+ user: event.user?.displayName,
300
+ });
301
+ if (event.space) {
302
+ this.spaceCache.set(event.space.name, event.space);
303
+ }
304
+ // Return a greeting
305
+ return { text: 'Hello! I\'m ready to help.' };
306
+ case 'REMOVED_FROM_SPACE':
307
+ logger.debug('Google Chat: bot removed from space', {
308
+ space: event.space?.name,
309
+ });
310
+ if (event.space) {
311
+ this.spaceCache.delete(event.space.name);
312
+ }
313
+ return;
314
+ case 'CARD_CLICKED':
315
+ return this.handleCardClicked(event);
316
+ default:
317
+ logger.debug('Google Chat: unhandled event type', { type: event.type });
318
+ return;
319
+ }
320
+ }
321
+ /**
322
+ * Handle MESSAGE event
323
+ */
324
+ async handleMessageEvent(event) {
325
+ const msg = event.message;
326
+ const user = event.user ?? msg?.sender;
327
+ const space = event.space ?? msg?.space;
328
+ if (!msg || !user || !space)
329
+ return;
330
+ // Ignore bot messages
331
+ if (user.type === 'BOT')
332
+ return;
333
+ const userId = user.name?.replace('users/', '') ?? '';
334
+ if (!this.isUserAllowed(userId))
335
+ return;
336
+ const spaceId = space.name?.replace('spaces/', '') ?? '';
337
+ if (!this.isChannelAllowed(spaceId))
338
+ return;
339
+ // Extract text (argumentText strips the @mention prefix)
340
+ const text = msg.argumentText?.trim() ?? msg.text ?? '';
341
+ // Check for slash commands
342
+ let isCommand = false;
343
+ let commandName;
344
+ let commandArgs;
345
+ if (msg.slashCommand || msg.annotations?.some((a) => a.type === 'SLASH_COMMAND')) {
346
+ const annotation = msg.annotations?.find((a) => a.type === 'SLASH_COMMAND');
347
+ isCommand = true;
348
+ commandName = annotation?.slashCommand?.commandName ?? text.split(/\s+/)[0]?.replace(/^\//, '');
349
+ commandArgs = text.split(/\s+/).slice(1);
350
+ }
351
+ // Build attachments
352
+ const attachments = (msg.attachment ?? []).map((a) => ({
353
+ type: this.mimeToContentType(a.contentType),
354
+ fileName: a.contentName,
355
+ mimeType: a.contentType,
356
+ url: a.downloadUri ?? a.thumbnailUri,
357
+ }));
358
+ const inbound = {
359
+ id: msg.name?.split('/').pop() ?? `gchat-${Date.now()}`,
360
+ channel: {
361
+ id: spaceId,
362
+ type: 'google-chat',
363
+ name: space.displayName ?? spaceId,
364
+ isDM: space.type === 'DM',
365
+ isGroup: space.type === 'ROOM',
366
+ },
367
+ sender: {
368
+ id: userId,
369
+ displayName: user.displayName,
370
+ isBot: false, // Bot messages are filtered above
371
+ },
372
+ content: text,
373
+ contentType: isCommand ? 'command' : (attachments.length > 0 ? attachments[0].type : 'text'),
374
+ attachments: attachments.length > 0 ? attachments : undefined,
375
+ isCommand,
376
+ commandName,
377
+ commandArgs,
378
+ threadId: msg.thread?.name,
379
+ timestamp: msg.createTime ? new Date(msg.createTime) : new Date(),
380
+ raw: event,
381
+ };
382
+ const parsed = this.parseCommand(inbound);
383
+ parsed.sessionKey = getSessionKey(parsed);
384
+ // DM pairing check
385
+ const pairingStatus = await checkDMPairing(parsed);
386
+ if (!pairingStatus.approved) {
387
+ const { getDMPairing } = await import('../dm-pairing.js');
388
+ const pairingMessage = getDMPairing().getPairingMessage(pairingStatus);
389
+ if (pairingMessage) {
390
+ await this.send({ channelId: space.name, content: pairingMessage });
391
+ }
392
+ return;
393
+ }
394
+ this.status.lastActivity = new Date();
395
+ this.emit('message', parsed);
396
+ if (parsed.isCommand) {
397
+ this.emit('command', parsed);
398
+ }
399
+ }
400
+ /**
401
+ * Handle CARD_CLICKED event (button press)
402
+ */
403
+ async handleCardClicked(event) {
404
+ const user = event.user;
405
+ const space = event.space;
406
+ if (!user || !space)
407
+ return;
408
+ const actionName = event.action?.actionMethodName ?? '';
409
+ const params = event.action?.parameters ?? [];
410
+ const userId = user.name?.replace('users/', '') ?? '';
411
+ const spaceId = space.name?.replace('spaces/', '') ?? '';
412
+ const inbound = {
413
+ id: `card-${Date.now()}`,
414
+ channel: {
415
+ id: spaceId,
416
+ type: 'google-chat',
417
+ name: space.displayName ?? spaceId,
418
+ isDM: space.type === 'DM',
419
+ isGroup: space.type === 'ROOM',
420
+ },
421
+ sender: {
422
+ id: userId,
423
+ displayName: user.displayName,
424
+ },
425
+ content: actionName,
426
+ contentType: 'command',
427
+ isCommand: true,
428
+ commandName: 'card_action',
429
+ commandArgs: [actionName, ...params.map((p) => `${p.key}=${p.value}`)],
430
+ timestamp: new Date(),
431
+ raw: event,
432
+ };
433
+ inbound.sessionKey = getSessionKey(inbound);
434
+ this.emit('command', inbound);
435
+ }
436
+ // ==========================================================================
437
+ // Space Management
438
+ // ==========================================================================
439
+ /**
440
+ * List spaces the bot has access to
441
+ */
442
+ async listSpaces() {
443
+ try {
444
+ const result = await this.apiRequest('GET', '/spaces?pageSize=100');
445
+ return result.spaces ?? [];
446
+ }
447
+ catch {
448
+ return [];
449
+ }
450
+ }
451
+ /**
452
+ * Get a specific space
453
+ */
454
+ async getSpace(spaceName) {
455
+ const normalized = spaceName.startsWith('spaces/') ? spaceName : `spaces/${spaceName}`;
456
+ if (this.spaceCache.has(normalized)) {
457
+ return this.spaceCache.get(normalized);
458
+ }
459
+ try {
460
+ const space = await this.apiRequest('GET', `/${normalized}`);
461
+ this.spaceCache.set(space.name, space);
462
+ return space;
463
+ }
464
+ catch {
465
+ return null;
466
+ }
467
+ }
468
+ /**
469
+ * Update a previously sent message
470
+ */
471
+ async updateMessage(messageName, text) {
472
+ const normalized = messageName.startsWith('spaces/')
473
+ ? messageName
474
+ : `spaces/${messageName}`;
475
+ await this.apiRequest('PUT', `/${normalized}?updateMask=text`, { text });
476
+ }
477
+ /**
478
+ * Delete a previously sent message
479
+ */
480
+ async deleteMessage(messageName) {
481
+ const normalized = messageName.startsWith('spaces/')
482
+ ? messageName
483
+ : `spaces/${messageName}`;
484
+ await this.apiRequest('DELETE', `/${normalized}`);
485
+ }
486
+ // ==========================================================================
487
+ // Helpers
488
+ // ==========================================================================
489
+ /**
490
+ * Map MIME type to ContentType
491
+ */
492
+ mimeToContentType(mime) {
493
+ if (!mime)
494
+ return 'file';
495
+ if (mime.startsWith('image/'))
496
+ return 'image';
497
+ if (mime.startsWith('audio/'))
498
+ return 'audio';
499
+ if (mime.startsWith('video/'))
500
+ return 'video';
501
+ return 'file';
502
+ }
503
+ }
504
+ export default GoogleChatChannel;
505
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/channels/google-chat/index.ts"],"names":[],"mappings":"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"}