digital-workers 2.1.1 → 2.3.0

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 (197) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +136 -180
  3. package/dist/actions.d.ts.map +1 -1
  4. package/dist/actions.js +34 -21
  5. package/dist/actions.js.map +1 -1
  6. package/dist/agent-comms.d.ts +438 -0
  7. package/dist/agent-comms.d.ts.map +1 -0
  8. package/dist/agent-comms.js +677 -0
  9. package/dist/agent-comms.js.map +1 -0
  10. package/dist/approve.d.ts +40 -8
  11. package/dist/approve.d.ts.map +1 -1
  12. package/dist/approve.js +86 -20
  13. package/dist/approve.js.map +1 -1
  14. package/dist/ask.d.ts +38 -7
  15. package/dist/ask.d.ts.map +1 -1
  16. package/dist/ask.js +85 -25
  17. package/dist/ask.js.map +1 -1
  18. package/dist/browse.d.ts +223 -0
  19. package/dist/browse.d.ts.map +1 -0
  20. package/dist/browse.js +392 -0
  21. package/dist/browse.js.map +1 -0
  22. package/dist/capability-tiers.d.ts +230 -0
  23. package/dist/capability-tiers.d.ts.map +1 -0
  24. package/dist/capability-tiers.js +388 -0
  25. package/dist/capability-tiers.js.map +1 -0
  26. package/dist/cascade-context.d.ts +523 -0
  27. package/dist/cascade-context.d.ts.map +1 -0
  28. package/dist/cascade-context.js +494 -0
  29. package/dist/cascade-context.js.map +1 -0
  30. package/dist/client.d.ts +162 -0
  31. package/dist/client.d.ts.map +1 -0
  32. package/dist/client.js +64 -0
  33. package/dist/client.js.map +1 -0
  34. package/dist/decide.d.ts +42 -6
  35. package/dist/decide.d.ts.map +1 -1
  36. package/dist/decide.js +54 -11
  37. package/dist/decide.js.map +1 -1
  38. package/dist/do.d.ts +36 -7
  39. package/dist/do.d.ts.map +1 -1
  40. package/dist/do.js +82 -39
  41. package/dist/do.js.map +1 -1
  42. package/dist/error-escalation.d.ts +416 -0
  43. package/dist/error-escalation.d.ts.map +1 -0
  44. package/dist/error-escalation.js +656 -0
  45. package/dist/error-escalation.js.map +1 -0
  46. package/dist/generate.d.ts +48 -7
  47. package/dist/generate.d.ts.map +1 -1
  48. package/dist/generate.js +49 -8
  49. package/dist/generate.js.map +1 -1
  50. package/dist/goals.d.ts +10 -9
  51. package/dist/goals.d.ts.map +1 -1
  52. package/dist/goals.js +30 -24
  53. package/dist/goals.js.map +1 -1
  54. package/dist/image.d.ts +189 -0
  55. package/dist/image.d.ts.map +1 -0
  56. package/dist/image.js +528 -0
  57. package/dist/image.js.map +1 -0
  58. package/dist/index.d.ts +59 -2
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +92 -2
  61. package/dist/index.js.map +1 -1
  62. package/dist/is.d.ts +45 -10
  63. package/dist/is.d.ts.map +1 -1
  64. package/dist/is.js +56 -21
  65. package/dist/is.js.map +1 -1
  66. package/dist/kpis.d.ts +24 -15
  67. package/dist/kpis.d.ts.map +1 -1
  68. package/dist/kpis.js +16 -14
  69. package/dist/kpis.js.map +1 -1
  70. package/dist/load-balancing.d.ts +395 -0
  71. package/dist/load-balancing.d.ts.map +1 -0
  72. package/dist/load-balancing.js +991 -0
  73. package/dist/load-balancing.js.map +1 -0
  74. package/dist/logger.d.ts +76 -0
  75. package/dist/logger.d.ts.map +1 -0
  76. package/dist/logger.js +39 -0
  77. package/dist/logger.js.map +1 -0
  78. package/dist/notify.d.ts +38 -9
  79. package/dist/notify.d.ts.map +1 -1
  80. package/dist/notify.js +72 -17
  81. package/dist/notify.js.map +1 -1
  82. package/dist/role.d.ts +5 -4
  83. package/dist/role.d.ts.map +1 -1
  84. package/dist/role.js +13 -10
  85. package/dist/role.js.map +1 -1
  86. package/dist/runtime.d.ts +310 -0
  87. package/dist/runtime.d.ts.map +1 -0
  88. package/dist/runtime.js +510 -0
  89. package/dist/runtime.js.map +1 -0
  90. package/dist/team.d.ts +11 -6
  91. package/dist/team.d.ts.map +1 -1
  92. package/dist/team.js +22 -15
  93. package/dist/team.js.map +1 -1
  94. package/dist/transports/email.d.ts +318 -0
  95. package/dist/transports/email.d.ts.map +1 -0
  96. package/dist/transports/email.js +779 -0
  97. package/dist/transports/email.js.map +1 -0
  98. package/dist/transports/slack.d.ts +515 -0
  99. package/dist/transports/slack.d.ts.map +1 -0
  100. package/dist/transports/slack.js +844 -0
  101. package/dist/transports/slack.js.map +1 -0
  102. package/dist/transports.d.ts.map +1 -1
  103. package/dist/transports.js +44 -25
  104. package/dist/transports.js.map +1 -1
  105. package/dist/types.d.ts +149 -19
  106. package/dist/types.d.ts.map +1 -1
  107. package/dist/types.js +6 -0
  108. package/dist/types.js.map +1 -1
  109. package/dist/utils/id.d.ts +19 -0
  110. package/dist/utils/id.d.ts.map +1 -0
  111. package/dist/utils/id.js +21 -0
  112. package/dist/utils/id.js.map +1 -0
  113. package/dist/video.d.ts +203 -0
  114. package/dist/video.d.ts.map +1 -0
  115. package/dist/video.js +528 -0
  116. package/dist/video.js.map +1 -0
  117. package/dist/worker.d.ts +343 -0
  118. package/dist/worker.d.ts.map +1 -0
  119. package/dist/worker.js +698 -0
  120. package/dist/worker.js.map +1 -0
  121. package/package.json +24 -5
  122. package/src/actions.ts +48 -38
  123. package/src/agent-comms.ts +1200 -0
  124. package/src/approve.ts +91 -20
  125. package/src/ask.ts +99 -25
  126. package/src/browse.ts +627 -0
  127. package/src/capability-tiers.ts +545 -0
  128. package/src/cascade-context.ts +648 -0
  129. package/src/client.ts +221 -0
  130. package/src/decide.ts +81 -35
  131. package/src/do.ts +98 -52
  132. package/src/error-escalation.ts +1123 -0
  133. package/src/generate.ts +52 -18
  134. package/src/goals.ts +36 -27
  135. package/src/image.ts +816 -0
  136. package/src/index.ts +410 -2
  137. package/src/is.ts +59 -25
  138. package/src/kpis.ts +41 -36
  139. package/src/load-balancing.ts +1467 -0
  140. package/src/logger.ts +93 -0
  141. package/src/notify.ts +78 -17
  142. package/src/role.ts +30 -20
  143. package/src/runtime.ts +796 -0
  144. package/src/team.ts +24 -19
  145. package/src/transports/email.ts +1160 -0
  146. package/src/transports/slack.ts +1320 -0
  147. package/src/transports.ts +58 -43
  148. package/src/types.ts +182 -46
  149. package/src/utils/id.ts +21 -0
  150. package/src/video.ts +906 -0
  151. package/src/worker.ts +1007 -0
  152. package/test/agent-comms.test.ts +1397 -0
  153. package/test/approve.test.ts +305 -0
  154. package/test/ask.test.ts +274 -0
  155. package/test/browse.test.ts +361 -0
  156. package/test/capability-tiers.test.ts +631 -0
  157. package/test/cascade-context.test.ts +692 -0
  158. package/test/decide.test.ts +252 -0
  159. package/test/do.test.ts +144 -0
  160. package/test/error-escalation.test.ts +1205 -0
  161. package/test/error-logging.test.ts +357 -0
  162. package/test/generate.test.ts +319 -0
  163. package/test/image.test.ts +398 -0
  164. package/test/is.test.ts +287 -0
  165. package/test/load-balancing-safety.test.ts +404 -0
  166. package/test/load-balancing-thread-safety.test.ts +464 -0
  167. package/test/load-balancing.test.ts +1145 -0
  168. package/test/notify.test.ts +434 -0
  169. package/test/primitives.test.ts +320 -0
  170. package/test/runtime-integration.test.ts +892 -0
  171. package/test/transports/crypto.test.ts +230 -0
  172. package/test/transports/email.test.ts +866 -0
  173. package/test/transports/id-generation.test.ts +91 -0
  174. package/test/transports/slack.test.ts +760 -0
  175. package/test/type-safety.test.ts +834 -0
  176. package/test/types.test.ts +95 -2
  177. package/test/video.test.ts +530 -0
  178. package/test/worker.test.ts +1433 -0
  179. package/tsconfig.json +4 -1
  180. package/vitest.config.ts +42 -0
  181. package/wrangler.jsonc +36 -0
  182. package/.turbo/turbo-build.log +0 -5
  183. package/src/actions.js +0 -436
  184. package/src/approve.js +0 -234
  185. package/src/ask.js +0 -226
  186. package/src/decide.js +0 -244
  187. package/src/do.js +0 -227
  188. package/src/generate.js +0 -298
  189. package/src/goals.js +0 -205
  190. package/src/index.js +0 -68
  191. package/src/is.js +0 -317
  192. package/src/kpis.js +0 -270
  193. package/src/notify.js +0 -219
  194. package/src/role.js +0 -110
  195. package/src/team.js +0 -130
  196. package/src/transports.js +0 -357
  197. package/src/types.js +0 -71
@@ -0,0 +1,230 @@
1
+ /**
2
+ * Tests for Slack Signature Verification Crypto Functions
3
+ *
4
+ * This module tests the HMAC-SHA256 signature verification used by Slack webhooks.
5
+ * The implementation should work in both Node.js and Cloudflare Workers environments
6
+ * using the Web Crypto API.
7
+ *
8
+ * Bead issue: aip-621l
9
+ */
10
+
11
+ import { describe, it, expect } from 'vitest'
12
+ import { verifySlackSignature, computeHmacSha256Hex } from '../../src/transports/slack.js'
13
+
14
+ // Test constants matching Slack's signing secret format
15
+ const TEST_SIGNING_SECRET = 'a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'
16
+ const TEST_TIMESTAMP = '1531420618'
17
+ const TEST_BODY = 'token=xyzz0WbapA4vBCDEFasx0q6G&team_id=T1DC2JH3J&team_domain=testteamnow'
18
+
19
+ // Pre-computed signature for the test data above
20
+ // This is the expected signature when signing "v0:1531420618:token=xyzz0WbapA4vBCDEFasx0q6G&team_id=T1DC2JH3J&team_domain=testteamnow"
21
+ // with the signing secret "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
22
+ // Note: We'll compute the actual expected value when implementing
23
+
24
+ describe('Slack Signature Verification', () => {
25
+ describe('computeHmacSha256Hex', () => {
26
+ it('should compute HMAC-SHA256 and return hex string', async () => {
27
+ const baseString = `v0:${TEST_TIMESTAMP}:${TEST_BODY}`
28
+ const result = await computeHmacSha256Hex(baseString, TEST_SIGNING_SECRET)
29
+
30
+ // Result should be a 64-character hex string (256 bits = 32 bytes = 64 hex chars)
31
+ expect(result).toMatch(/^[a-f0-9]{64}$/)
32
+ })
33
+
34
+ it('should produce consistent results for same input', async () => {
35
+ const data = 'test data'
36
+ const secret = 'test secret'
37
+
38
+ const result1 = await computeHmacSha256Hex(data, secret)
39
+ const result2 = await computeHmacSha256Hex(data, secret)
40
+
41
+ expect(result1).toBe(result2)
42
+ })
43
+
44
+ it('should produce different results for different data', async () => {
45
+ const secret = 'test secret'
46
+
47
+ const result1 = await computeHmacSha256Hex('data1', secret)
48
+ const result2 = await computeHmacSha256Hex('data2', secret)
49
+
50
+ expect(result1).not.toBe(result2)
51
+ })
52
+
53
+ it('should produce different results for different secrets', async () => {
54
+ const data = 'test data'
55
+
56
+ const result1 = await computeHmacSha256Hex(data, 'secret1')
57
+ const result2 = await computeHmacSha256Hex(data, 'secret2')
58
+
59
+ expect(result1).not.toBe(result2)
60
+ })
61
+
62
+ it('should handle empty data', async () => {
63
+ const result = await computeHmacSha256Hex('', 'secret')
64
+
65
+ expect(result).toMatch(/^[a-f0-9]{64}$/)
66
+ })
67
+
68
+ it('should handle unicode data', async () => {
69
+ const result = await computeHmacSha256Hex('Hello, World! Emoji test: *smile*', 'secret')
70
+
71
+ expect(result).toMatch(/^[a-f0-9]{64}$/)
72
+ })
73
+ })
74
+
75
+ describe('verifySlackSignature', () => {
76
+ it('should verify a valid signature', async () => {
77
+ // First compute what the signature should be
78
+ const baseString = `v0:${TEST_TIMESTAMP}:${TEST_BODY}`
79
+ const hmac = await computeHmacSha256Hex(baseString, TEST_SIGNING_SECRET)
80
+ const validSignature = `v0=${hmac}`
81
+
82
+ const isValid = await verifySlackSignature(
83
+ validSignature,
84
+ TEST_TIMESTAMP,
85
+ TEST_BODY,
86
+ TEST_SIGNING_SECRET
87
+ )
88
+
89
+ expect(isValid).toBe(true)
90
+ })
91
+
92
+ it('should reject an invalid signature', async () => {
93
+ const invalidSignature = 'v0=0000000000000000000000000000000000000000000000000000000000000000'
94
+
95
+ const isValid = await verifySlackSignature(
96
+ invalidSignature,
97
+ TEST_TIMESTAMP,
98
+ TEST_BODY,
99
+ TEST_SIGNING_SECRET
100
+ )
101
+
102
+ expect(isValid).toBe(false)
103
+ })
104
+
105
+ it('should reject a malformed signature (missing v0= prefix)', async () => {
106
+ const malformedSignature = 'abc123def456'
107
+
108
+ const isValid = await verifySlackSignature(
109
+ malformedSignature,
110
+ TEST_TIMESTAMP,
111
+ TEST_BODY,
112
+ TEST_SIGNING_SECRET
113
+ )
114
+
115
+ expect(isValid).toBe(false)
116
+ })
117
+
118
+ it('should reject signature with wrong secret', async () => {
119
+ // Compute signature with correct secret
120
+ const baseString = `v0:${TEST_TIMESTAMP}:${TEST_BODY}`
121
+ const hmac = await computeHmacSha256Hex(baseString, TEST_SIGNING_SECRET)
122
+ const signature = `v0=${hmac}`
123
+
124
+ // Verify with wrong secret
125
+ const isValid = await verifySlackSignature(
126
+ signature,
127
+ TEST_TIMESTAMP,
128
+ TEST_BODY,
129
+ 'wrong-secret-key'
130
+ )
131
+
132
+ expect(isValid).toBe(false)
133
+ })
134
+
135
+ it('should reject signature with tampered body', async () => {
136
+ // Compute signature with original body
137
+ const baseString = `v0:${TEST_TIMESTAMP}:${TEST_BODY}`
138
+ const hmac = await computeHmacSha256Hex(baseString, TEST_SIGNING_SECRET)
139
+ const signature = `v0=${hmac}`
140
+
141
+ // Verify with tampered body
142
+ const isValid = await verifySlackSignature(
143
+ signature,
144
+ TEST_TIMESTAMP,
145
+ TEST_BODY + 'tampered',
146
+ TEST_SIGNING_SECRET
147
+ )
148
+
149
+ expect(isValid).toBe(false)
150
+ })
151
+
152
+ it('should reject signature with wrong timestamp', async () => {
153
+ // Compute signature with original timestamp
154
+ const baseString = `v0:${TEST_TIMESTAMP}:${TEST_BODY}`
155
+ const hmac = await computeHmacSha256Hex(baseString, TEST_SIGNING_SECRET)
156
+ const signature = `v0=${hmac}`
157
+
158
+ // Verify with different timestamp
159
+ const isValid = await verifySlackSignature(
160
+ signature,
161
+ '1234567890',
162
+ TEST_BODY,
163
+ TEST_SIGNING_SECRET
164
+ )
165
+
166
+ expect(isValid).toBe(false)
167
+ })
168
+
169
+ it('should use constant-time comparison to prevent timing attacks', async () => {
170
+ // This test verifies the function handles different-length signatures safely
171
+ const baseString = `v0:${TEST_TIMESTAMP}:${TEST_BODY}`
172
+ const hmac = await computeHmacSha256Hex(baseString, TEST_SIGNING_SECRET)
173
+ const validSignature = `v0=${hmac}`
174
+
175
+ // Short signature
176
+ const isValidShort = await verifySlackSignature(
177
+ 'v0=abc',
178
+ TEST_TIMESTAMP,
179
+ TEST_BODY,
180
+ TEST_SIGNING_SECRET
181
+ )
182
+ expect(isValidShort).toBe(false)
183
+
184
+ // Long signature
185
+ const isValidLong = await verifySlackSignature(
186
+ validSignature + 'extra',
187
+ TEST_TIMESTAMP,
188
+ TEST_BODY,
189
+ TEST_SIGNING_SECRET
190
+ )
191
+ expect(isValidLong).toBe(false)
192
+
193
+ // Correct length but wrong content
194
+ const wrongSig = 'v0=' + '0'.repeat(64)
195
+ const isValidWrong = await verifySlackSignature(
196
+ wrongSig,
197
+ TEST_TIMESTAMP,
198
+ TEST_BODY,
199
+ TEST_SIGNING_SECRET
200
+ )
201
+ expect(isValidWrong).toBe(false)
202
+ })
203
+ })
204
+
205
+ describe('Web Crypto API compatibility', () => {
206
+ it('should work in environments with crypto.subtle', async () => {
207
+ // This test verifies that the global crypto.subtle is being used
208
+ expect(globalThis.crypto).toBeDefined()
209
+ expect(globalThis.crypto.subtle).toBeDefined()
210
+
211
+ // The actual crypto operations should work
212
+ const result = await computeHmacSha256Hex('test', 'secret')
213
+ expect(result).toMatch(/^[a-f0-9]{64}$/)
214
+ })
215
+
216
+ it('should produce results compatible with known HMAC-SHA256 test vectors', async () => {
217
+ // RFC 4231 test vector (truncated to check format)
218
+ // Key: "key"
219
+ // Data: "The quick brown fox jumps over the lazy dog"
220
+ // Expected HMAC-SHA256: f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
221
+ const testKey = 'key'
222
+ const testData = 'The quick brown fox jumps over the lazy dog'
223
+ const expectedHmac = 'f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8'
224
+
225
+ const result = await computeHmacSha256Hex(testData, testKey)
226
+
227
+ expect(result).toBe(expectedHmac)
228
+ })
229
+ })
230
+ })