@vibecheckai/cli 3.7.0 → 3.8.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 (99) hide show
  1. package/README.md +135 -63
  2. package/bin/_deprecations.js +447 -19
  3. package/bin/_router.js +1 -1
  4. package/bin/registry.js +347 -280
  5. package/bin/runners/context/generators/cursor-enhanced.js +2439 -0
  6. package/bin/runners/lib/agent-firewall/enforcement/gateway.js +1059 -0
  7. package/bin/runners/lib/agent-firewall/enforcement/index.js +98 -0
  8. package/bin/runners/lib/agent-firewall/enforcement/mode.js +318 -0
  9. package/bin/runners/lib/agent-firewall/enforcement/orchestrator.js +484 -0
  10. package/bin/runners/lib/agent-firewall/enforcement/proof-artifact.js +418 -0
  11. package/bin/runners/lib/agent-firewall/enforcement/schemas/change-event.schema.json +173 -0
  12. package/bin/runners/lib/agent-firewall/enforcement/schemas/intent.schema.json +181 -0
  13. package/bin/runners/lib/agent-firewall/enforcement/schemas/verdict.schema.json +222 -0
  14. package/bin/runners/lib/agent-firewall/enforcement/verdict-v2.js +333 -0
  15. package/bin/runners/lib/agent-firewall/index.js +200 -0
  16. package/bin/runners/lib/agent-firewall/integration/index.js +20 -0
  17. package/bin/runners/lib/agent-firewall/integration/ship-gate.js +437 -0
  18. package/bin/runners/lib/agent-firewall/intent/alignment-engine.js +622 -0
  19. package/bin/runners/lib/agent-firewall/intent/auto-detect.js +426 -0
  20. package/bin/runners/lib/agent-firewall/intent/index.js +102 -0
  21. package/bin/runners/lib/agent-firewall/intent/schema.js +352 -0
  22. package/bin/runners/lib/agent-firewall/intent/store.js +283 -0
  23. package/bin/runners/lib/agent-firewall/interception/fs-interceptor.js +502 -0
  24. package/bin/runners/lib/agent-firewall/interception/index.js +23 -0
  25. package/bin/runners/lib/agent-firewall/session/collector.js +451 -0
  26. package/bin/runners/lib/agent-firewall/session/index.js +26 -0
  27. package/bin/runners/lib/artifact-envelope.js +540 -0
  28. package/bin/runners/lib/auth-shared.js +977 -0
  29. package/bin/runners/lib/checkpoint.js +941 -0
  30. package/bin/runners/lib/cleanup/engine.js +571 -0
  31. package/bin/runners/lib/cleanup/index.js +53 -0
  32. package/bin/runners/lib/cleanup/output.js +375 -0
  33. package/bin/runners/lib/cleanup/rules.js +1060 -0
  34. package/bin/runners/lib/doctor/diagnosis-receipt.js +454 -0
  35. package/bin/runners/lib/doctor/failure-signatures.js +526 -0
  36. package/bin/runners/lib/doctor/fix-script.js +336 -0
  37. package/bin/runners/lib/doctor/modules/build-tools.js +453 -0
  38. package/bin/runners/lib/doctor/modules/index.js +62 -3
  39. package/bin/runners/lib/doctor/modules/os-quirks.js +706 -0
  40. package/bin/runners/lib/doctor/modules/repo-integrity.js +485 -0
  41. package/bin/runners/lib/doctor/safe-repair.js +384 -0
  42. package/bin/runners/lib/engines/attack-detector.js +1192 -0
  43. package/bin/runners/lib/entitlements-v2.js +2 -2
  44. package/bin/runners/lib/missions/briefing.js +427 -0
  45. package/bin/runners/lib/missions/checkpoint.js +753 -0
  46. package/bin/runners/lib/missions/hardening.js +851 -0
  47. package/bin/runners/lib/missions/plan.js +421 -32
  48. package/bin/runners/lib/missions/safety-gates.js +645 -0
  49. package/bin/runners/lib/missions/schema.js +478 -0
  50. package/bin/runners/lib/packs/bundle.js +675 -0
  51. package/bin/runners/lib/packs/evidence-pack.js +671 -0
  52. package/bin/runners/lib/packs/pack-factory.js +837 -0
  53. package/bin/runners/lib/packs/permissions-pack.js +686 -0
  54. package/bin/runners/lib/packs/proof-graph-pack.js +779 -0
  55. package/bin/runners/lib/safelist/index.js +96 -0
  56. package/bin/runners/lib/safelist/integration.js +334 -0
  57. package/bin/runners/lib/safelist/matcher.js +696 -0
  58. package/bin/runners/lib/safelist/schema.js +948 -0
  59. package/bin/runners/lib/safelist/store.js +438 -0
  60. package/bin/runners/lib/schemas/ship-manifest.schema.json +251 -0
  61. package/bin/runners/lib/ship-gate.js +832 -0
  62. package/bin/runners/lib/ship-manifest.js +1153 -0
  63. package/bin/runners/lib/ship-output.js +1 -1
  64. package/bin/runners/lib/unified-cli-output.js +710 -383
  65. package/bin/runners/lib/upsell.js +3 -3
  66. package/bin/runners/lib/why-tree.js +650 -0
  67. package/bin/runners/runAllowlist.js +33 -4
  68. package/bin/runners/runApprove.js +240 -1122
  69. package/bin/runners/runAudit.js +692 -0
  70. package/bin/runners/runAuth.js +325 -29
  71. package/bin/runners/runCheckpoint.js +442 -494
  72. package/bin/runners/runCleanup.js +343 -0
  73. package/bin/runners/runDoctor.js +269 -19
  74. package/bin/runners/runFix.js +411 -32
  75. package/bin/runners/runForge.js +411 -0
  76. package/bin/runners/runIntent.js +906 -0
  77. package/bin/runners/runKickoff.js +878 -0
  78. package/bin/runners/runLaunch.js +2000 -0
  79. package/bin/runners/runLink.js +785 -0
  80. package/bin/runners/runMcp.js +1741 -837
  81. package/bin/runners/runPacks.js +2089 -0
  82. package/bin/runners/runPolish.js +41 -0
  83. package/bin/runners/runSafelist.js +1190 -0
  84. package/bin/runners/runScan.js +21 -9
  85. package/bin/runners/runShield.js +1282 -0
  86. package/bin/runners/runShip.js +395 -16
  87. package/bin/vibecheck.js +34 -6
  88. package/mcp-server/README.md +117 -158
  89. package/mcp-server/handlers/tool-handler.ts +3 -3
  90. package/mcp-server/index.js +16 -0
  91. package/mcp-server/intent-firewall-interceptor.js +529 -0
  92. package/mcp-server/manifest.json +473 -0
  93. package/mcp-server/package.json +1 -1
  94. package/mcp-server/registry/tool-registry.js +315 -523
  95. package/mcp-server/registry/tools.json +442 -428
  96. package/mcp-server/tier-auth.js +68 -11
  97. package/mcp-server/tools-v3.js +70 -16
  98. package/package.json +1 -1
  99. package/bin/runners/runProof.zip +0 -0
@@ -0,0 +1,485 @@
1
+ /**
2
+ * Repository Integrity Diagnostics Module
3
+ *
4
+ * Checks git state, lock files, caches, and repo health
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const { execSync } = require('child_process');
10
+ const { SEVERITY, CATEGORY, FIX_TYPE } = require('../types');
11
+
12
+ const MODULE_ID = 'repo';
13
+
14
+ function createDiagnostics(projectPath) {
15
+ return [
16
+ {
17
+ id: `${MODULE_ID}.git_status`,
18
+ name: 'Git Repository',
19
+ category: CATEGORY.PROJECT,
20
+ parallel: true,
21
+ check: async () => {
22
+ const gitDir = path.join(projectPath, '.git');
23
+
24
+ if (!fs.existsSync(gitDir)) {
25
+ return {
26
+ severity: SEVERITY.INFO,
27
+ message: 'Not a git repository',
28
+ metadata: { isGitRepo: false },
29
+ fixes: [{
30
+ type: FIX_TYPE.COMMAND,
31
+ description: 'Initialize git repository',
32
+ command: 'git init',
33
+ autoFixable: true,
34
+ }],
35
+ };
36
+ }
37
+
38
+ try {
39
+ // Check git status
40
+ const status = execSync('git status --porcelain', {
41
+ cwd: projectPath,
42
+ encoding: 'utf8',
43
+ timeout: 10000,
44
+ stdio: ['pipe', 'pipe', 'pipe'],
45
+ });
46
+
47
+ const lines = status.trim().split('\n').filter(Boolean);
48
+ const untracked = lines.filter(l => l.startsWith('??')).length;
49
+ const modified = lines.filter(l => l.startsWith(' M') || l.startsWith('M ')).length;
50
+ const staged = lines.filter(l => l.startsWith('A ') || l.startsWith('M ') || l.startsWith('D ')).length;
51
+
52
+ const metadata = { isGitRepo: true, untracked, modified, staged, total: lines.length };
53
+
54
+ if (lines.length === 0) {
55
+ return {
56
+ severity: SEVERITY.PASS,
57
+ message: 'Clean working directory',
58
+ metadata,
59
+ };
60
+ }
61
+
62
+ return {
63
+ severity: SEVERITY.INFO,
64
+ message: `${lines.length} uncommitted changes`,
65
+ detail: `${modified} modified, ${untracked} untracked, ${staged} staged`,
66
+ metadata,
67
+ };
68
+ } catch (err) {
69
+ return {
70
+ severity: SEVERITY.WARNING,
71
+ message: 'Git command failed',
72
+ detail: err.message,
73
+ metadata: { isGitRepo: true },
74
+ };
75
+ }
76
+ },
77
+ },
78
+ {
79
+ id: `${MODULE_ID}.git_hooks`,
80
+ name: 'Git Hooks',
81
+ category: CATEGORY.PROJECT,
82
+ parallel: true,
83
+ check: async () => {
84
+ // Check for Husky
85
+ const huskyDir = path.join(projectPath, '.husky');
86
+ const hasHusky = fs.existsSync(huskyDir);
87
+
88
+ // Check for lefthook
89
+ const leftHookConfig = ['lefthook.yml', 'lefthook.yaml', '.lefthook.yml'];
90
+ const hasLefthook = leftHookConfig.some(f => fs.existsSync(path.join(projectPath, f)));
91
+
92
+ // Check for simple-git-hooks
93
+ const pkgPath = path.join(projectPath, 'package.json');
94
+ let hasSimpleHooks = false;
95
+ if (fs.existsSync(pkgPath)) {
96
+ try {
97
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
98
+ hasSimpleHooks = !!pkg['simple-git-hooks'];
99
+ } catch {}
100
+ }
101
+
102
+ const metadata = { husky: hasHusky, lefthook: hasLefthook, simpleGitHooks: hasSimpleHooks };
103
+
104
+ if (hasHusky) {
105
+ return { severity: SEVERITY.PASS, message: 'Husky configured', metadata };
106
+ }
107
+ if (hasLefthook) {
108
+ return { severity: SEVERITY.PASS, message: 'Lefthook configured', metadata };
109
+ }
110
+ if (hasSimpleHooks) {
111
+ return { severity: SEVERITY.PASS, message: 'simple-git-hooks configured', metadata };
112
+ }
113
+
114
+ return {
115
+ severity: SEVERITY.INFO,
116
+ message: 'No git hooks configured',
117
+ metadata,
118
+ };
119
+ },
120
+ },
121
+ {
122
+ id: `${MODULE_ID}.lock_file`,
123
+ name: 'Lock File',
124
+ category: CATEGORY.PROJECT,
125
+ parallel: true,
126
+ check: async () => {
127
+ const lockFiles = {
128
+ 'pnpm-lock.yaml': 'pnpm',
129
+ 'package-lock.json': 'npm',
130
+ 'yarn.lock': 'yarn',
131
+ 'bun.lockb': 'bun',
132
+ };
133
+
134
+ const found = [];
135
+ for (const [file, manager] of Object.entries(lockFiles)) {
136
+ if (fs.existsSync(path.join(projectPath, file))) {
137
+ found.push({ file, manager });
138
+ }
139
+ }
140
+
141
+ const metadata = { lockFiles: found };
142
+
143
+ if (found.length === 0) {
144
+ return {
145
+ severity: SEVERITY.WARNING,
146
+ message: 'No lock file found',
147
+ detail: 'Lock files ensure reproducible builds',
148
+ metadata,
149
+ fixes: [{
150
+ type: FIX_TYPE.COMMAND,
151
+ description: 'Generate lock file',
152
+ command: 'npm install',
153
+ autoFixable: true,
154
+ }],
155
+ };
156
+ }
157
+
158
+ if (found.length > 1) {
159
+ return {
160
+ severity: SEVERITY.WARNING,
161
+ message: `Multiple lock files: ${found.map(f => f.file).join(', ')}`,
162
+ detail: 'Having multiple lock files can cause confusion and inconsistent installs',
163
+ metadata,
164
+ fixes: [{
165
+ type: FIX_TYPE.MANUAL,
166
+ description: 'Remove extra lock files, keep only one for your chosen package manager',
167
+ autoFixable: false,
168
+ }],
169
+ };
170
+ }
171
+
172
+ const primary = found[0];
173
+ return {
174
+ severity: SEVERITY.PASS,
175
+ message: `${primary.file} (${primary.manager})`,
176
+ metadata,
177
+ };
178
+ },
179
+ },
180
+ {
181
+ id: `${MODULE_ID}.lock_file_sync`,
182
+ name: 'Lock File Sync',
183
+ category: CATEGORY.PROJECT,
184
+ parallel: false,
185
+ dependsOn: [`${MODULE_ID}.lock_file`],
186
+ check: async () => {
187
+ const pkgPath = path.join(projectPath, 'package.json');
188
+ const lockPath = path.join(projectPath, 'package-lock.json');
189
+ const pnpmLockPath = path.join(projectPath, 'pnpm-lock.yaml');
190
+ const yarnLockPath = path.join(projectPath, 'yarn.lock');
191
+
192
+ if (!fs.existsSync(pkgPath)) {
193
+ return { severity: SEVERITY.INFO, message: 'No package.json' };
194
+ }
195
+
196
+ let lockFile = null;
197
+ let command = null;
198
+
199
+ if (fs.existsSync(pnpmLockPath)) {
200
+ lockFile = pnpmLockPath;
201
+ command = 'pnpm install --frozen-lockfile';
202
+ } else if (fs.existsSync(lockPath)) {
203
+ lockFile = lockPath;
204
+ command = 'npm ci';
205
+ } else if (fs.existsSync(yarnLockPath)) {
206
+ lockFile = yarnLockPath;
207
+ command = 'yarn install --frozen-lockfile';
208
+ }
209
+
210
+ if (!lockFile) {
211
+ return { severity: SEVERITY.INFO, message: 'No lock file to check' };
212
+ }
213
+
214
+ // Check modification times
215
+ const pkgStat = fs.statSync(pkgPath);
216
+ const lockStat = fs.statSync(lockFile);
217
+
218
+ const metadata = {
219
+ packageJsonModified: pkgStat.mtime.toISOString(),
220
+ lockFileModified: lockStat.mtime.toISOString(),
221
+ };
222
+
223
+ // If package.json is newer than lock file, might be out of sync
224
+ if (pkgStat.mtime > lockStat.mtime) {
225
+ const hoursDiff = (pkgStat.mtime - lockStat.mtime) / (1000 * 60 * 60);
226
+
227
+ if (hoursDiff > 1) {
228
+ return {
229
+ severity: SEVERITY.WARNING,
230
+ message: 'Lock file may be outdated',
231
+ detail: `package.json modified ${Math.round(hoursDiff)}h after lock file`,
232
+ metadata,
233
+ fixes: [{
234
+ type: FIX_TYPE.COMMAND,
235
+ description: 'Regenerate lock file',
236
+ command: command.replace('--frozen-lockfile', '').replace(' ci', ' install'),
237
+ autoFixable: true,
238
+ }],
239
+ };
240
+ }
241
+ }
242
+
243
+ return {
244
+ severity: SEVERITY.PASS,
245
+ message: 'Lock file appears synchronized',
246
+ metadata,
247
+ };
248
+ },
249
+ },
250
+ {
251
+ id: `${MODULE_ID}.node_modules`,
252
+ name: 'node_modules',
253
+ category: CATEGORY.PROJECT,
254
+ parallel: true,
255
+ check: async () => {
256
+ const nmPath = path.join(projectPath, 'node_modules');
257
+
258
+ if (!fs.existsSync(nmPath)) {
259
+ return {
260
+ severity: SEVERITY.ERROR,
261
+ message: 'node_modules not found',
262
+ detail: 'Dependencies not installed',
263
+ fixes: [{
264
+ type: FIX_TYPE.COMMAND,
265
+ description: 'Install dependencies',
266
+ command: 'npm install',
267
+ autoFixable: true,
268
+ }],
269
+ };
270
+ }
271
+
272
+ // Check if .bin exists
273
+ const binPath = path.join(nmPath, '.bin');
274
+ const hasBin = fs.existsSync(binPath);
275
+
276
+ // Get approximate size (count directories)
277
+ try {
278
+ const entries = fs.readdirSync(nmPath);
279
+ const packageCount = entries.filter(e => !e.startsWith('.')).length;
280
+
281
+ const metadata = { packageCount, hasBin };
282
+
283
+ if (packageCount === 0) {
284
+ return {
285
+ severity: SEVERITY.WARNING,
286
+ message: 'node_modules is empty',
287
+ metadata,
288
+ fixes: [{
289
+ type: FIX_TYPE.COMMAND,
290
+ description: 'Reinstall dependencies',
291
+ command: 'rm -rf node_modules && npm install',
292
+ autoFixable: false,
293
+ dangerous: true,
294
+ }],
295
+ };
296
+ }
297
+
298
+ return {
299
+ severity: SEVERITY.PASS,
300
+ message: `${packageCount} packages`,
301
+ metadata,
302
+ };
303
+ } catch (err) {
304
+ return {
305
+ severity: SEVERITY.WARNING,
306
+ message: 'Could not read node_modules',
307
+ detail: err.message,
308
+ };
309
+ }
310
+ },
311
+ },
312
+ {
313
+ id: `${MODULE_ID}.cache_dirs`,
314
+ name: 'Build Caches',
315
+ category: CATEGORY.PROJECT,
316
+ parallel: true,
317
+ check: async () => {
318
+ const cacheDirs = [
319
+ { name: '.next', desc: 'Next.js cache' },
320
+ { name: '.nuxt', desc: 'Nuxt cache' },
321
+ { name: '.turbo', desc: 'Turborepo cache' },
322
+ { name: '.cache', desc: 'General cache' },
323
+ { name: 'dist', desc: 'Build output' },
324
+ { name: 'build', desc: 'Build output' },
325
+ { name: '.vibecheck', desc: 'Vibecheck cache' },
326
+ { name: 'coverage', desc: 'Test coverage' },
327
+ { name: '.nyc_output', desc: 'NYC coverage' },
328
+ { name: '.eslintcache', desc: 'ESLint cache', isFile: true },
329
+ { name: '.stylelintcache', desc: 'Stylelint cache', isFile: true },
330
+ { name: 'tsconfig.tsbuildinfo', desc: 'TypeScript incremental', isFile: true },
331
+ ];
332
+
333
+ const found = [];
334
+ let totalSizeBytes = 0;
335
+
336
+ for (const cache of cacheDirs) {
337
+ const cachePath = path.join(projectPath, cache.name);
338
+ if (fs.existsSync(cachePath)) {
339
+ try {
340
+ const stat = fs.statSync(cachePath);
341
+ found.push({
342
+ ...cache,
343
+ path: cachePath,
344
+ sizeBytes: stat.isDirectory() ? getDirectorySize(cachePath) : stat.size,
345
+ });
346
+ totalSizeBytes += found[found.length - 1].sizeBytes;
347
+ } catch {
348
+ found.push({ ...cache, path: cachePath, sizeBytes: 0 });
349
+ }
350
+ }
351
+ }
352
+
353
+ const totalSizeMB = (totalSizeBytes / (1024 * 1024)).toFixed(1);
354
+ const metadata = { caches: found, totalSizeBytes, totalSizeMB };
355
+
356
+ if (found.length === 0) {
357
+ return {
358
+ severity: SEVERITY.PASS,
359
+ message: 'No cache directories',
360
+ metadata,
361
+ };
362
+ }
363
+
364
+ // Warn if caches are very large (> 500MB)
365
+ if (totalSizeBytes > 500 * 1024 * 1024) {
366
+ return {
367
+ severity: SEVERITY.WARNING,
368
+ message: `${found.length} caches (${totalSizeMB}MB) — consider clearing`,
369
+ metadata,
370
+ fixes: [{
371
+ type: FIX_TYPE.COMMAND,
372
+ description: 'Clear all caches',
373
+ command: found.map(c => c.isFile ? `rm -f "${c.name}"` : `rm -rf "${c.name}"`).join(' && '),
374
+ autoFixable: false,
375
+ dangerous: true,
376
+ }],
377
+ };
378
+ }
379
+
380
+ return {
381
+ severity: SEVERITY.PASS,
382
+ message: `${found.length} caches (${totalSizeMB}MB)`,
383
+ metadata,
384
+ };
385
+ },
386
+ },
387
+ {
388
+ id: `${MODULE_ID}.gitignore`,
389
+ name: '.gitignore Coverage',
390
+ category: CATEGORY.PROJECT,
391
+ parallel: true,
392
+ check: async () => {
393
+ const gitignorePath = path.join(projectPath, '.gitignore');
394
+
395
+ if (!fs.existsSync(gitignorePath)) {
396
+ return {
397
+ severity: SEVERITY.WARNING,
398
+ message: 'No .gitignore file',
399
+ fixes: [{
400
+ type: FIX_TYPE.COMMAND,
401
+ description: 'Create .gitignore from template',
402
+ command: 'npx gitignore node',
403
+ autoFixable: true,
404
+ }],
405
+ };
406
+ }
407
+
408
+ try {
409
+ const content = fs.readFileSync(gitignorePath, 'utf8');
410
+ const lines = content.split('\n').map(l => l.trim()).filter(l => l && !l.startsWith('#'));
411
+
412
+ const essentialPatterns = [
413
+ { pattern: 'node_modules', desc: 'node_modules directory' },
414
+ { pattern: '.env', desc: 'Environment files' },
415
+ { pattern: 'dist', desc: 'Build output' },
416
+ { pattern: '.next', desc: 'Next.js cache' },
417
+ { pattern: 'coverage', desc: 'Test coverage' },
418
+ ];
419
+
420
+ const missing = [];
421
+ for (const essential of essentialPatterns) {
422
+ const hasPattern = lines.some(l =>
423
+ l === essential.pattern ||
424
+ l.startsWith(essential.pattern + '/') ||
425
+ l === '/' + essential.pattern ||
426
+ l.includes(essential.pattern)
427
+ );
428
+ if (!hasPattern) {
429
+ missing.push(essential);
430
+ }
431
+ }
432
+
433
+ const metadata = { lineCount: lines.length, missing: missing.map(m => m.pattern) };
434
+
435
+ if (missing.length > 0) {
436
+ return {
437
+ severity: SEVERITY.WARNING,
438
+ message: `Missing: ${missing.map(m => m.pattern).join(', ')}`,
439
+ detail: `Consider adding these patterns to .gitignore`,
440
+ metadata,
441
+ fixes: [{
442
+ type: FIX_TYPE.MANUAL,
443
+ description: `Add missing patterns to .gitignore: ${missing.map(m => m.pattern).join(', ')}`,
444
+ autoFixable: false,
445
+ }],
446
+ };
447
+ }
448
+
449
+ return {
450
+ severity: SEVERITY.PASS,
451
+ message: `${lines.length} patterns`,
452
+ metadata,
453
+ };
454
+ } catch (err) {
455
+ return {
456
+ severity: SEVERITY.WARNING,
457
+ message: 'Could not parse .gitignore',
458
+ detail: err.message,
459
+ };
460
+ }
461
+ },
462
+ },
463
+ ];
464
+ }
465
+
466
+ // Helper to get directory size
467
+ function getDirectorySize(dirPath) {
468
+ let size = 0;
469
+ try {
470
+ const entries = fs.readdirSync(dirPath, { withFileTypes: true });
471
+ for (const entry of entries) {
472
+ const entryPath = path.join(dirPath, entry.name);
473
+ if (entry.isDirectory()) {
474
+ size += getDirectorySize(entryPath);
475
+ } else {
476
+ try {
477
+ size += fs.statSync(entryPath).size;
478
+ } catch {}
479
+ }
480
+ }
481
+ } catch {}
482
+ return size;
483
+ }
484
+
485
+ module.exports = { MODULE_ID, createDiagnostics };