slashvibe-mcp 0.3.21 → 0.3.23

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 (235) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +280 -47
  3. package/auto-update.js +10 -15
  4. package/config.js +36 -31
  5. package/crypto.js +1 -6
  6. package/debug.js +12 -0
  7. package/discord.js +19 -19
  8. package/eslint.config.js +54 -0
  9. package/index.js +217 -207
  10. package/intelligence/index.js +2 -9
  11. package/intelligence/infer.js +10 -16
  12. package/intelligence/patterns.js +23 -18
  13. package/intelligence/proactive.js +16 -15
  14. package/intelligence/serendipity.js +57 -20
  15. package/memory.js +13 -8
  16. package/migrate-v2.js +72 -0
  17. package/notification-emitter.js +2 -2
  18. package/notify.js +39 -14
  19. package/package.json +28 -29
  20. package/post-install.js +141 -0
  21. package/presence.js +2 -2
  22. package/prompts.js +5 -9
  23. package/protocol/index.js +123 -87
  24. package/protocol/telegram-commands.js +36 -37
  25. package/store/api.js +358 -529
  26. package/store/local.js +9 -10
  27. package/store/profiles.js +48 -192
  28. package/store/reservations.js +2 -9
  29. package/store/skills.js +69 -71
  30. package/store/sqlite.js +355 -0
  31. package/test-skills-bootstrap.js +20 -0
  32. package/test-v2-integration.js +385 -0
  33. package/tools/_actions.js +48 -387
  34. package/tools/_connection-queue.js +45 -56
  35. package/tools/_discovery-enhanced.js +52 -57
  36. package/tools/_discovery.js +87 -185
  37. package/tools/{l2-status.js → _experimental/l2-status.js} +68 -70
  38. package/tools/{shipback.js → _experimental/shipback.js} +4 -3
  39. package/tools/_proactive-discovery.js +60 -73
  40. package/tools/_shared/index.js +41 -64
  41. package/tools/admin-inbox.js +10 -15
  42. package/tools/agents.js +1 -1
  43. package/tools/artifact-create.js +13 -23
  44. package/tools/artifact-view.js +4 -4
  45. package/tools/{_deprecated/back.js → back.js} +1 -1
  46. package/tools/bye.js +3 -5
  47. package/tools/consent.js +2 -2
  48. package/tools/context.js +9 -10
  49. package/tools/crossword.js +3 -2
  50. package/tools/discover.js +94 -356
  51. package/tools/dm.js +27 -86
  52. package/tools/doctor.js +12 -41
  53. package/tools/drawing.js +34 -20
  54. package/tools/echo.js +11 -11
  55. package/tools/feed.js +30 -58
  56. package/tools/follow.js +64 -187
  57. package/tools/{_deprecated/forget.js → forget.js} +4 -7
  58. package/tools/game.js +144 -48
  59. package/tools/handoff.js +6 -8
  60. package/tools/help.js +3 -3
  61. package/tools/idea.js +15 -27
  62. package/tools/inbox.js +121 -293
  63. package/tools/init.js +54 -151
  64. package/tools/invite.js +8 -21
  65. package/tools/migrate.js +27 -24
  66. package/tools/multiplayer-game.js +50 -40
  67. package/tools/{_deprecated/mute.js → mute.js} +4 -3
  68. package/tools/notifications.js +58 -48
  69. package/tools/observe.js +12 -15
  70. package/tools/onboarding.js +8 -11
  71. package/tools/open.js +13 -144
  72. package/tools/party-game.js +23 -12
  73. package/tools/patterns.js +2 -1
  74. package/tools/ping.js +5 -7
  75. package/tools/react.js +28 -30
  76. package/tools/{_deprecated/recall.js → recall.js} +5 -10
  77. package/tools/release.js +4 -2
  78. package/tools/{_deprecated/remember.js → remember.js} +4 -6
  79. package/tools/report.js +2 -2
  80. package/tools/request.js +6 -26
  81. package/tools/reserve.js +1 -1
  82. package/tools/session-fork.js +97 -0
  83. package/tools/session-save.js +109 -0
  84. package/tools/settings.js +30 -99
  85. package/tools/ship.js +74 -56
  86. package/tools/{_deprecated/skills-exchange.js → skills-exchange.js} +38 -39
  87. package/tools/social-inbox.js +22 -28
  88. package/tools/social-post.js +24 -27
  89. package/tools/solo-game.js +54 -46
  90. package/tools/start.js +14 -148
  91. package/tools/status.js +21 -68
  92. package/tools/submit.js +4 -2
  93. package/tools/suggest-tags.js +36 -33
  94. package/tools/summarize.js +19 -16
  95. package/tools/tag-suggestions.js +72 -73
  96. package/tools/test.js +1 -1
  97. package/tools/{_deprecated/tictactoe.js → tictactoe.js} +26 -26
  98. package/tools/token.js +4 -4
  99. package/tools/update.js +1 -2
  100. package/tools/watch.js +132 -112
  101. package/tools/who.js +20 -40
  102. package/tools/{_deprecated/wordassociation.js → wordassociation.js} +23 -20
  103. package/tools/workshop-buddy.js +52 -53
  104. package/tools/x-mentions.js +0 -1
  105. package/tools/x-reply.js +0 -1
  106. package/twitter.js +14 -20
  107. package/version.json +8 -10
  108. package/webhook-runner.js +132 -0
  109. package/auth-store.js +0 -148
  110. package/bridges/bridge-monitor.js +0 -388
  111. package/bridges/discord-bot.js +0 -431
  112. package/bridges/farcaster.js +0 -299
  113. package/bridges/telegram.js +0 -261
  114. package/bridges/webhook-health.js +0 -420
  115. package/bridges/webhook-server.js +0 -437
  116. package/bridges/whatsapp.js +0 -441
  117. package/bridges/x-webhook.js +0 -423
  118. package/games/arcade.js +0 -406
  119. package/games/chess.js +0 -451
  120. package/games/colorguess.js +0 -343
  121. package/games/crossword-words.js +0 -171
  122. package/games/crossword.js +0 -461
  123. package/games/drawing.js +0 -347
  124. package/games/gameroulette.js +0 -300
  125. package/games/gamerouter.js +0 -336
  126. package/games/gamestatus.js +0 -337
  127. package/games/guessnumber.js +0 -209
  128. package/games/hangman.js +0 -279
  129. package/games/memory.js +0 -338
  130. package/games/multiplayer-tictactoe.js +0 -389
  131. package/games/pixelart.js +0 -399
  132. package/games/quickduel.js +0 -354
  133. package/games/riddle.js +0 -371
  134. package/games/rockpaperscissors.js +0 -291
  135. package/games/snake.js +0 -406
  136. package/games/storybuilder.js +0 -343
  137. package/games/tictactoe.js +0 -345
  138. package/games/twentyquestions.js +0 -286
  139. package/games/twotruths.js +0 -207
  140. package/games/werewolf.js +0 -508
  141. package/games/wordassociation.js +0 -247
  142. package/games/wordchain.js +0 -135
  143. package/intelligence/interests.js +0 -369
  144. package/setup.js +0 -480
  145. package/smart-inbox.js +0 -276
  146. package/tools/_deprecated/auto-suggest-connections.js +0 -304
  147. package/tools/_deprecated/bootstrap-skills.js +0 -231
  148. package/tools/_deprecated/bridge-dashboard.js +0 -342
  149. package/tools/_deprecated/bridge-health.js +0 -400
  150. package/tools/_deprecated/bridge-live.js +0 -384
  151. package/tools/_deprecated/bridges.js +0 -383
  152. package/tools/_deprecated/colorguess.js +0 -281
  153. package/tools/_deprecated/discover-insights.js +0 -379
  154. package/tools/_deprecated/discover-momentum.js +0 -256
  155. package/tools/_deprecated/discovery-analytics.js +0 -345
  156. package/tools/_deprecated/discovery-auto-suggest.js +0 -275
  157. package/tools/_deprecated/discovery-bootstrap.js +0 -267
  158. package/tools/_deprecated/discovery-daily.js +0 -375
  159. package/tools/_deprecated/discovery-dashboard.js +0 -385
  160. package/tools/_deprecated/discovery-digest.js +0 -314
  161. package/tools/_deprecated/discovery-hub.js +0 -357
  162. package/tools/_deprecated/discovery-insights.js +0 -384
  163. package/tools/_deprecated/discovery-momentum.js +0 -281
  164. package/tools/_deprecated/discovery-monitor.js +0 -319
  165. package/tools/_deprecated/discovery-proactive.js +0 -300
  166. package/tools/_deprecated/draw.js +0 -317
  167. package/tools/_deprecated/farcaster.js +0 -307
  168. package/tools/_deprecated/games-catalog.js +0 -376
  169. package/tools/_deprecated/games.js +0 -313
  170. package/tools/_deprecated/guessnumber.js +0 -194
  171. package/tools/_deprecated/hangman.js +0 -129
  172. package/tools/_deprecated/multiplayer-tictactoe.js +0 -303
  173. package/tools/_deprecated/riddle.js +0 -240
  174. package/tools/_deprecated/run-bootstrap.js +0 -69
  175. package/tools/_deprecated/skills-analytics.js +0 -349
  176. package/tools/_deprecated/skills-bootstrap.js +0 -301
  177. package/tools/_deprecated/skills-dashboard.js +0 -268
  178. package/tools/_deprecated/skills.js +0 -380
  179. package/tools/_deprecated/smart-intro.js +0 -353
  180. package/tools/_deprecated/storybuilder.js +0 -331
  181. package/tools/_deprecated/telegram-bot.js +0 -183
  182. package/tools/_deprecated/telegram-setup.js +0 -214
  183. package/tools/_deprecated/twentyquestions.js +0 -143
  184. package/tools/_shared.js +0 -234
  185. package/tools/_work-context.js +0 -338
  186. package/tools/_work-context.manual-test.js +0 -199
  187. package/tools/_work-context.test.js +0 -260
  188. package/tools/activity.js +0 -220
  189. package/tools/agent-treasury.js +0 -288
  190. package/tools/analytics.js +0 -191
  191. package/tools/approve.js +0 -197
  192. package/tools/arcade.js +0 -173
  193. package/tools/artifacts-price.js +0 -107
  194. package/tools/ask-expert.js +0 -160
  195. package/tools/available.js +0 -120
  196. package/tools/become-expert.js +0 -150
  197. package/tools/broadcast.js +0 -325
  198. package/tools/chat.js +0 -202
  199. package/tools/collaborative-drawing.js +0 -286
  200. package/tools/connection-status.js +0 -178
  201. package/tools/earnings.js +0 -126
  202. package/tools/friends.js +0 -207
  203. package/tools/genesis.js +0 -233
  204. package/tools/gig-browse.js +0 -206
  205. package/tools/gig-complete.js +0 -144
  206. package/tools/health.js +0 -87
  207. package/tools/leaderboard.js +0 -117
  208. package/tools/lib/git-apply.js +0 -206
  209. package/tools/lib/git-bundle.js +0 -407
  210. package/tools/mint.js +0 -377
  211. package/tools/plan.js +0 -225
  212. package/tools/profile.js +0 -219
  213. package/tools/proof-of-work.js +0 -144
  214. package/tools/pulse.js +0 -218
  215. package/tools/reply.js +0 -166
  216. package/tools/reputation.js +0 -175
  217. package/tools/schedule.js +0 -367
  218. package/tools/search-messages.js +0 -123
  219. package/tools/session.js +0 -467
  220. package/tools/session_price.js +0 -128
  221. package/tools/smart-check.js +0 -201
  222. package/tools/social-processor.js +0 -445
  223. package/tools/streak.js +0 -147
  224. package/tools/stuck.js +0 -297
  225. package/tools/subscribe.js +0 -148
  226. package/tools/subscriptions.js +0 -134
  227. package/tools/tip.js +0 -193
  228. package/tools/wallet.js +0 -269
  229. package/tools/webhook-test.js +0 -388
  230. package/tools/withdraw.js +0 -145
  231. package/tools/work-summary.js +0 -96
  232. package/tools/workshop.js +0 -327
  233. /package/tools/{l2-bridge.js → _experimental/l2-bridge.js} +0 -0
  234. /package/tools/{l2.js → _experimental/l2.js} +0 -0
  235. /package/tools/{_deprecated/away.js → away.js} +0 -0
@@ -1,407 +0,0 @@
1
- /**
2
- * Git Bundle Library
3
- *
4
- * Creates and validates git bundles for session sharing.
5
- * Used by broadcast.js to capture code changes during a broadcast.
6
- *
7
- * Key functions:
8
- * - captureSessionStart() - Returns current HEAD commit
9
- * - createBundle(startCommit) - Creates bundle from startCommit to HEAD
10
- * - validateBundle(buffer) - Validates bundle integrity
11
- */
12
-
13
- const { execSync, spawn } = require('child_process');
14
- const fs = require('fs');
15
- const path = require('path');
16
- const os = require('os');
17
-
18
- // Max bundle size (10MB)
19
- const MAX_BUNDLE_SIZE = 10 * 1024 * 1024;
20
-
21
- // Files to exclude from bundles (security)
22
- const EXCLUDED_PATTERNS = [
23
- '.env',
24
- '.env.*',
25
- '*.pem',
26
- '*.key',
27
- '*.p12',
28
- '*.pfx',
29
- '.npmrc',
30
- '.netrc',
31
- 'credentials.json',
32
- 'secrets.json',
33
- '*_rsa',
34
- '*_dsa',
35
- '*_ed25519',
36
- '*_ecdsa',
37
- 'id_rsa*',
38
- 'id_dsa*',
39
- '*.keystore',
40
- ];
41
-
42
- /**
43
- * Check if we're in a git repository
44
- */
45
- function isGitRepo() {
46
- try {
47
- execSync('git rev-parse --is-inside-work-tree', {
48
- stdio: 'pipe',
49
- encoding: 'utf8',
50
- });
51
- return true;
52
- } catch (e) {
53
- return false;
54
- }
55
- }
56
-
57
- /**
58
- * Get current git branch
59
- */
60
- function getCurrentBranch() {
61
- try {
62
- return execSync('git rev-parse --abbrev-ref HEAD', {
63
- stdio: 'pipe',
64
- encoding: 'utf8',
65
- }).trim();
66
- } catch (e) {
67
- return null;
68
- }
69
- }
70
-
71
- /**
72
- * Get current HEAD commit hash
73
- */
74
- function getHeadCommit() {
75
- try {
76
- return execSync('git rev-parse HEAD', {
77
- stdio: 'pipe',
78
- encoding: 'utf8',
79
- }).trim();
80
- } catch (e) {
81
- return null;
82
- }
83
- }
84
-
85
- /**
86
- * Get commit count between two commits
87
- */
88
- function getCommitCount(startCommit, endCommit = 'HEAD') {
89
- try {
90
- const output = execSync(`git rev-list --count ${startCommit}..${endCommit}`, {
91
- stdio: 'pipe',
92
- encoding: 'utf8',
93
- });
94
- return parseInt(output.trim(), 10);
95
- } catch (e) {
96
- return 0;
97
- }
98
- }
99
-
100
- /**
101
- * Get list of files changed between commits
102
- */
103
- function getChangedFiles(startCommit, endCommit = 'HEAD') {
104
- try {
105
- const output = execSync(`git diff --name-only ${startCommit}..${endCommit}`, {
106
- stdio: 'pipe',
107
- encoding: 'utf8',
108
- });
109
- return output.trim().split('\n').filter(Boolean);
110
- } catch (e) {
111
- return [];
112
- }
113
- }
114
-
115
- /**
116
- * Check if any excluded files would be in the bundle
117
- */
118
- function hasExcludedFiles(changedFiles) {
119
- const excluded = [];
120
-
121
- for (const file of changedFiles) {
122
- const basename = path.basename(file);
123
-
124
- for (const pattern of EXCLUDED_PATTERNS) {
125
- // Simple glob matching
126
- if (pattern.startsWith('*')) {
127
- const suffix = pattern.slice(1);
128
- if (basename.endsWith(suffix)) {
129
- excluded.push(file);
130
- break;
131
- }
132
- } else if (pattern.endsWith('*')) {
133
- const prefix = pattern.slice(0, -1);
134
- if (basename.startsWith(prefix)) {
135
- excluded.push(file);
136
- break;
137
- }
138
- } else if (pattern.includes('*')) {
139
- // Pattern like ".env.*"
140
- const [prefix, suffix] = pattern.split('*');
141
- if (basename.startsWith(prefix) && (suffix === '' || basename.endsWith(suffix))) {
142
- excluded.push(file);
143
- break;
144
- }
145
- } else if (basename === pattern || file === pattern) {
146
- excluded.push(file);
147
- break;
148
- }
149
- }
150
- }
151
-
152
- return excluded;
153
- }
154
-
155
- /**
156
- * Capture git state at session start
157
- * @returns {object} - { success, commit, branch, error? }
158
- */
159
- function captureSessionStart() {
160
- if (!isGitRepo()) {
161
- return { success: false, error: 'Not a git repository' };
162
- }
163
-
164
- const commit = getHeadCommit();
165
- const branch = getCurrentBranch();
166
-
167
- if (!commit) {
168
- return { success: false, error: 'Could not get HEAD commit' };
169
- }
170
-
171
- return {
172
- success: true,
173
- commit,
174
- branch,
175
- capturedAt: new Date().toISOString(),
176
- };
177
- }
178
-
179
- /**
180
- * Create a git bundle from startCommit to HEAD
181
- * @param {string} startCommit - Starting commit hash
182
- * @returns {object} - { success, buffer, metadata, error? }
183
- */
184
- function createBundle(startCommit) {
185
- if (!isGitRepo()) {
186
- return { success: false, error: 'Not a git repository' };
187
- }
188
-
189
- if (!startCommit) {
190
- return { success: false, error: 'Start commit required' };
191
- }
192
-
193
- const endCommit = getHeadCommit();
194
- const branch = getCurrentBranch();
195
-
196
- if (!endCommit) {
197
- return { success: false, error: 'Could not get HEAD commit' };
198
- }
199
-
200
- // Check if there are any new commits
201
- const commitCount = getCommitCount(startCommit, endCommit);
202
- if (commitCount === 0) {
203
- return {
204
- success: false,
205
- error: 'No new commits since session start',
206
- metadata: {
207
- startCommit,
208
- endCommit,
209
- branch,
210
- },
211
- };
212
- }
213
-
214
- // Check for excluded files
215
- const changedFiles = getChangedFiles(startCommit, endCommit);
216
- const excludedFiles = hasExcludedFiles(changedFiles);
217
-
218
- if (excludedFiles.length > 0) {
219
- console.log(`[git-bundle] Warning: Excluding sensitive files: ${excludedFiles.join(', ')}`);
220
- }
221
-
222
- // Create temp file for bundle
223
- const tmpDir = os.tmpdir();
224
- const bundlePath = path.join(tmpDir, `vibe-bundle-${Date.now()}.bundle`);
225
-
226
- try {
227
- // Create the bundle
228
- // Format: git bundle create <file> <range>
229
- const bundleRange = `${startCommit}..HEAD`;
230
-
231
- execSync(`git bundle create "${bundlePath}" ${bundleRange}`, {
232
- stdio: 'pipe',
233
- encoding: 'utf8',
234
- });
235
-
236
- // Read the bundle
237
- const buffer = fs.readFileSync(bundlePath);
238
-
239
- // Check size
240
- if (buffer.length > MAX_BUNDLE_SIZE) {
241
- fs.unlinkSync(bundlePath);
242
- return {
243
- success: false,
244
- error: `Bundle too large (${Math.round(buffer.length / 1024 / 1024)}MB > ${MAX_BUNDLE_SIZE / 1024 / 1024}MB limit)`,
245
- };
246
- }
247
-
248
- // Clean up temp file
249
- fs.unlinkSync(bundlePath);
250
-
251
- const metadata = {
252
- initialCommit: startCommit,
253
- finalCommit: endCommit,
254
- branch,
255
- commitCount,
256
- changedFiles: changedFiles.filter((f) => !excludedFiles.includes(f)),
257
- excludedFiles,
258
- size: buffer.length,
259
- createdAt: new Date().toISOString(),
260
- };
261
-
262
- console.log(`[git-bundle] Created bundle: ${commitCount} commits, ${changedFiles.length} files, ${buffer.length} bytes`);
263
-
264
- return {
265
- success: true,
266
- buffer,
267
- metadata,
268
- };
269
- } catch (error) {
270
- // Clean up on error
271
- try {
272
- if (fs.existsSync(bundlePath)) {
273
- fs.unlinkSync(bundlePath);
274
- }
275
- } catch (e) {
276
- // Ignore cleanup errors
277
- }
278
-
279
- console.error('[git-bundle] Failed to create bundle:', error.message);
280
- return { success: false, error: error.message };
281
- }
282
- }
283
-
284
- /**
285
- * Validate a git bundle
286
- * @param {Buffer} buffer - The bundle data
287
- * @returns {object} - { success, info, error? }
288
- */
289
- function validateBundle(buffer) {
290
- if (!buffer || buffer.length === 0) {
291
- return { success: false, error: 'Empty buffer' };
292
- }
293
-
294
- // Check magic bytes (git bundles start with "# v2 git bundle" or "# v3 git bundle")
295
- const header = buffer.slice(0, 20).toString('utf8');
296
- if (!header.startsWith('# v2 git bundle') && !header.startsWith('# v3 git bundle')) {
297
- return { success: false, error: 'Invalid bundle format' };
298
- }
299
-
300
- // Write to temp and verify
301
- const tmpDir = os.tmpdir();
302
- const bundlePath = path.join(tmpDir, `vibe-verify-${Date.now()}.bundle`);
303
-
304
- try {
305
- fs.writeFileSync(bundlePath, buffer);
306
-
307
- // Verify the bundle
308
- const output = execSync(`git bundle verify "${bundlePath}"`, {
309
- stdio: 'pipe',
310
- encoding: 'utf8',
311
- });
312
-
313
- fs.unlinkSync(bundlePath);
314
-
315
- return {
316
- success: true,
317
- info: output.trim(),
318
- size: buffer.length,
319
- };
320
- } catch (error) {
321
- try {
322
- if (fs.existsSync(bundlePath)) {
323
- fs.unlinkSync(bundlePath);
324
- }
325
- } catch (e) {
326
- // Ignore cleanup errors
327
- }
328
-
329
- return { success: false, error: error.message };
330
- }
331
- }
332
-
333
- /**
334
- * Apply a bundle to create a new branch (for forking)
335
- * @param {Buffer} buffer - The bundle data
336
- * @param {string} branchName - Name for the new branch
337
- * @returns {object} - { success, branch, error? }
338
- */
339
- function applyBundle(buffer, branchName = 'forked-session') {
340
- if (!isGitRepo()) {
341
- return { success: false, error: 'Not a git repository' };
342
- }
343
-
344
- const validation = validateBundle(buffer);
345
- if (!validation.success) {
346
- return { success: false, error: `Invalid bundle: ${validation.error}` };
347
- }
348
-
349
- const tmpDir = os.tmpdir();
350
- const bundlePath = path.join(tmpDir, `vibe-apply-${Date.now()}.bundle`);
351
-
352
- try {
353
- fs.writeFileSync(bundlePath, buffer);
354
-
355
- // Get the refs in the bundle
356
- const listOutput = execSync(`git bundle list-heads "${bundlePath}"`, {
357
- stdio: 'pipe',
358
- encoding: 'utf8',
359
- });
360
-
361
- const refs = listOutput.trim().split('\n');
362
- if (refs.length === 0) {
363
- throw new Error('No refs in bundle');
364
- }
365
-
366
- // Get the first commit hash from the bundle
367
- const firstRef = refs[0].split(/\s+/)[0];
368
-
369
- // Unbundle (fetch from bundle)
370
- execSync(`git fetch "${bundlePath}" ${firstRef}:${branchName}`, {
371
- stdio: 'pipe',
372
- });
373
-
374
- fs.unlinkSync(bundlePath);
375
-
376
- console.log(`[git-bundle] Applied bundle to branch: ${branchName}`);
377
-
378
- return {
379
- success: true,
380
- branch: branchName,
381
- refs: refs.map((r) => r.split(/\s+/)),
382
- };
383
- } catch (error) {
384
- try {
385
- if (fs.existsSync(bundlePath)) {
386
- fs.unlinkSync(bundlePath);
387
- }
388
- } catch (e) {
389
- // Ignore cleanup errors
390
- }
391
-
392
- console.error('[git-bundle] Failed to apply bundle:', error.message);
393
- return { success: false, error: error.message };
394
- }
395
- }
396
-
397
- module.exports = {
398
- isGitRepo,
399
- getCurrentBranch,
400
- getHeadCommit,
401
- captureSessionStart,
402
- createBundle,
403
- validateBundle,
404
- applyBundle,
405
- MAX_BUNDLE_SIZE,
406
- EXCLUDED_PATTERNS,
407
- };