@vibecheck-ai/cli 20.1.0 → 23.0.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.
@@ -110,7 +110,7 @@ var require_path = __commonJS({
110
110
  Object.defineProperty(exports2, "__esModule", { value: true });
111
111
  exports2.convertPosixPathToPattern = exports2.convertWindowsPathToPattern = exports2.convertPathToPattern = exports2.escapePosixPath = exports2.escapeWindowsPath = exports2.escape = exports2.removeLeadingDotSegment = exports2.makeAbsolute = exports2.unixify = void 0;
112
112
  var os2 = require("os");
113
- var path3 = require("path");
113
+ var path6 = require("path");
114
114
  var IS_WINDOWS_PLATFORM = os2.platform() === "win32";
115
115
  var LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2;
116
116
  var POSIX_UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()*?[\]{|}]|^!|[!+@](?=\()|\\(?![!()*+?@[\]{|}]))/g;
@@ -123,7 +123,7 @@ var require_path = __commonJS({
123
123
  __name(unixify, "unixify");
124
124
  exports2.unixify = unixify;
125
125
  function makeAbsolute(cwd, filepath) {
126
- return path3.resolve(cwd, filepath);
126
+ return path6.resolve(cwd, filepath);
127
127
  }
128
128
  __name(makeAbsolute, "makeAbsolute");
129
129
  exports2.makeAbsolute = makeAbsolute;
@@ -1440,7 +1440,7 @@ var require_braces = __commonJS({
1440
1440
  var require_constants2 = __commonJS({
1441
1441
  "../../node_modules/.pnpm/picomatch@2.3.1/node_modules/picomatch/lib/constants.js"(exports2, module2) {
1442
1442
  "use strict";
1443
- var path3 = require("path");
1443
+ var path6 = require("path");
1444
1444
  var WIN_SLASH = "\\\\/";
1445
1445
  var WIN_NO_SLASH = `[^${WIN_SLASH}]`;
1446
1446
  var DOT_LITERAL = "\\.";
@@ -1610,7 +1610,7 @@ var require_constants2 = __commonJS({
1610
1610
  /* | */
1611
1611
  CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279,
1612
1612
  /* \uFEFF */
1613
- SEP: path3.sep,
1613
+ SEP: path6.sep,
1614
1614
  /**
1615
1615
  * Create EXTGLOB_CHARS
1616
1616
  */
@@ -1637,7 +1637,7 @@ var require_constants2 = __commonJS({
1637
1637
  var require_utils2 = __commonJS({
1638
1638
  "../../node_modules/.pnpm/picomatch@2.3.1/node_modules/picomatch/lib/utils.js"(exports2) {
1639
1639
  "use strict";
1640
- var path3 = require("path");
1640
+ var path6 = require("path");
1641
1641
  var win32 = process.platform === "win32";
1642
1642
  var {
1643
1643
  REGEX_BACKSLASH,
@@ -1666,7 +1666,7 @@ var require_utils2 = __commonJS({
1666
1666
  if (options && typeof options.windows === "boolean") {
1667
1667
  return options.windows;
1668
1668
  }
1669
- return win32 === true || path3.sep === "\\";
1669
+ return win32 === true || path6.sep === "\\";
1670
1670
  };
1671
1671
  exports2.escapeLast = (input, char, lastIdx) => {
1672
1672
  const idx = input.lastIndexOf(char, lastIdx);
@@ -2801,7 +2801,7 @@ var require_parse2 = __commonJS({
2801
2801
  var require_picomatch = __commonJS({
2802
2802
  "../../node_modules/.pnpm/picomatch@2.3.1/node_modules/picomatch/lib/picomatch.js"(exports2, module2) {
2803
2803
  "use strict";
2804
- var path3 = require("path");
2804
+ var path6 = require("path");
2805
2805
  var scan = require_scan();
2806
2806
  var parse = require_parse2();
2807
2807
  var utils = require_utils2();
@@ -2886,7 +2886,7 @@ var require_picomatch = __commonJS({
2886
2886
  };
2887
2887
  picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {
2888
2888
  const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
2889
- return regex.test(path3.basename(input));
2889
+ return regex.test(path6.basename(input));
2890
2890
  };
2891
2891
  picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);
2892
2892
  picomatch.parse = (pattern, options) => {
@@ -3113,7 +3113,7 @@ var require_pattern = __commonJS({
3113
3113
  "use strict";
3114
3114
  Object.defineProperty(exports2, "__esModule", { value: true });
3115
3115
  exports2.isAbsolute = exports2.partitionAbsoluteAndRelative = exports2.removeDuplicateSlashes = exports2.matchAny = exports2.convertPatternsToRe = exports2.makeRe = exports2.getPatternParts = exports2.expandBraceExpansion = exports2.expandPatternsWithBraceExpansion = exports2.isAffectDepthOfReadingPattern = exports2.endsWithSlashGlobStar = exports2.hasGlobStar = exports2.getBaseDirectory = exports2.isPatternRelatedToParentDirectory = exports2.getPatternsOutsideCurrentDirectory = exports2.getPatternsInsideCurrentDirectory = exports2.getPositivePatterns = exports2.getNegativePatterns = exports2.isPositivePattern = exports2.isNegativePattern = exports2.convertToNegativePattern = exports2.convertToPositivePattern = exports2.isDynamicPattern = exports2.isStaticPattern = void 0;
3116
- var path3 = require("path");
3116
+ var path6 = require("path");
3117
3117
  var globParent = require_glob_parent();
3118
3118
  var micromatch = require_micromatch();
3119
3119
  var GLOBSTAR = "**";
@@ -3223,7 +3223,7 @@ var require_pattern = __commonJS({
3223
3223
  __name(endsWithSlashGlobStar, "endsWithSlashGlobStar");
3224
3224
  exports2.endsWithSlashGlobStar = endsWithSlashGlobStar;
3225
3225
  function isAffectDepthOfReadingPattern(pattern) {
3226
- const basename = path3.basename(pattern);
3226
+ const basename = path6.basename(pattern);
3227
3227
  return endsWithSlashGlobStar(pattern) || isStaticPattern(basename);
3228
3228
  }
3229
3229
  __name(isAffectDepthOfReadingPattern, "isAffectDepthOfReadingPattern");
@@ -3290,7 +3290,7 @@ var require_pattern = __commonJS({
3290
3290
  __name(partitionAbsoluteAndRelative, "partitionAbsoluteAndRelative");
3291
3291
  exports2.partitionAbsoluteAndRelative = partitionAbsoluteAndRelative;
3292
3292
  function isAbsolute(pattern) {
3293
- return path3.isAbsolute(pattern);
3293
+ return path6.isAbsolute(pattern);
3294
3294
  }
3295
3295
  __name(isAbsolute, "isAbsolute");
3296
3296
  exports2.isAbsolute = isAbsolute;
@@ -3479,10 +3479,10 @@ var require_utils3 = __commonJS({
3479
3479
  exports2.array = array;
3480
3480
  var errno = require_errno();
3481
3481
  exports2.errno = errno;
3482
- var fs3 = require_fs();
3483
- exports2.fs = fs3;
3484
- var path3 = require_path();
3485
- exports2.path = path3;
3482
+ var fs6 = require_fs();
3483
+ exports2.fs = fs6;
3484
+ var path6 = require_path();
3485
+ exports2.path = path6;
3486
3486
  var pattern = require_pattern();
3487
3487
  exports2.pattern = pattern;
3488
3488
  var stream = require_stream();
@@ -3602,8 +3602,8 @@ var require_async = __commonJS({
3602
3602
  "use strict";
3603
3603
  Object.defineProperty(exports2, "__esModule", { value: true });
3604
3604
  exports2.read = void 0;
3605
- function read(path3, settings, callback) {
3606
- settings.fs.lstat(path3, (lstatError, lstat) => {
3605
+ function read(path6, settings, callback) {
3606
+ settings.fs.lstat(path6, (lstatError, lstat) => {
3607
3607
  if (lstatError !== null) {
3608
3608
  callFailureCallback(callback, lstatError);
3609
3609
  return;
@@ -3612,7 +3612,7 @@ var require_async = __commonJS({
3612
3612
  callSuccessCallback(callback, lstat);
3613
3613
  return;
3614
3614
  }
3615
- settings.fs.stat(path3, (statError, stat3) => {
3615
+ settings.fs.stat(path6, (statError, stat4) => {
3616
3616
  if (statError !== null) {
3617
3617
  if (settings.throwErrorOnBrokenSymbolicLink) {
3618
3618
  callFailureCallback(callback, statError);
@@ -3622,9 +3622,9 @@ var require_async = __commonJS({
3622
3622
  return;
3623
3623
  }
3624
3624
  if (settings.markSymbolicLink) {
3625
- stat3.isSymbolicLink = () => true;
3625
+ stat4.isSymbolicLink = () => true;
3626
3626
  }
3627
- callSuccessCallback(callback, stat3);
3627
+ callSuccessCallback(callback, stat4);
3628
3628
  });
3629
3629
  });
3630
3630
  }
@@ -3647,17 +3647,17 @@ var require_sync = __commonJS({
3647
3647
  "use strict";
3648
3648
  Object.defineProperty(exports2, "__esModule", { value: true });
3649
3649
  exports2.read = void 0;
3650
- function read(path3, settings) {
3651
- const lstat = settings.fs.lstatSync(path3);
3650
+ function read(path6, settings) {
3651
+ const lstat = settings.fs.lstatSync(path6);
3652
3652
  if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) {
3653
3653
  return lstat;
3654
3654
  }
3655
3655
  try {
3656
- const stat3 = settings.fs.statSync(path3);
3656
+ const stat4 = settings.fs.statSync(path6);
3657
3657
  if (settings.markSymbolicLink) {
3658
- stat3.isSymbolicLink = () => true;
3658
+ stat4.isSymbolicLink = () => true;
3659
3659
  }
3660
- return stat3;
3660
+ return stat4;
3661
3661
  } catch (error) {
3662
3662
  if (!settings.throwErrorOnBrokenSymbolicLink) {
3663
3663
  return lstat;
@@ -3676,12 +3676,12 @@ var require_fs2 = __commonJS({
3676
3676
  "use strict";
3677
3677
  Object.defineProperty(exports2, "__esModule", { value: true });
3678
3678
  exports2.createFileSystemAdapter = exports2.FILE_SYSTEM_ADAPTER = void 0;
3679
- var fs3 = require("fs");
3679
+ var fs6 = require("fs");
3680
3680
  exports2.FILE_SYSTEM_ADAPTER = {
3681
- lstat: fs3.lstat,
3682
- stat: fs3.stat,
3683
- lstatSync: fs3.lstatSync,
3684
- statSync: fs3.statSync
3681
+ lstat: fs6.lstat,
3682
+ stat: fs6.stat,
3683
+ lstatSync: fs6.lstatSync,
3684
+ statSync: fs6.statSync
3685
3685
  };
3686
3686
  function createFileSystemAdapter(fsMethods) {
3687
3687
  if (fsMethods === void 0) {
@@ -3699,7 +3699,7 @@ var require_settings = __commonJS({
3699
3699
  "../../node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/settings.js"(exports2) {
3700
3700
  "use strict";
3701
3701
  Object.defineProperty(exports2, "__esModule", { value: true });
3702
- var fs3 = require_fs2();
3702
+ var fs6 = require_fs2();
3703
3703
  var Settings = class {
3704
3704
  static {
3705
3705
  __name(this, "Settings");
@@ -3707,7 +3707,7 @@ var require_settings = __commonJS({
3707
3707
  constructor(_options = {}) {
3708
3708
  this._options = _options;
3709
3709
  this.followSymbolicLink = this._getValue(this._options.followSymbolicLink, true);
3710
- this.fs = fs3.createFileSystemAdapter(this._options.fs);
3710
+ this.fs = fs6.createFileSystemAdapter(this._options.fs);
3711
3711
  this.markSymbolicLink = this._getValue(this._options.markSymbolicLink, false);
3712
3712
  this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true);
3713
3713
  }
@@ -3729,21 +3729,21 @@ var require_out = __commonJS({
3729
3729
  var sync = require_sync();
3730
3730
  var settings_1 = require_settings();
3731
3731
  exports2.Settings = settings_1.default;
3732
- function stat3(path3, optionsOrSettingsOrCallback, callback) {
3732
+ function stat4(path6, optionsOrSettingsOrCallback, callback) {
3733
3733
  if (typeof optionsOrSettingsOrCallback === "function") {
3734
- async.read(path3, getSettings(), optionsOrSettingsOrCallback);
3734
+ async.read(path6, getSettings(), optionsOrSettingsOrCallback);
3735
3735
  return;
3736
3736
  }
3737
- async.read(path3, getSettings(optionsOrSettingsOrCallback), callback);
3737
+ async.read(path6, getSettings(optionsOrSettingsOrCallback), callback);
3738
3738
  }
3739
- __name(stat3, "stat");
3740
- exports2.stat = stat3;
3741
- function statSync(path3, optionsOrSettings) {
3739
+ __name(stat4, "stat");
3740
+ exports2.stat = stat4;
3741
+ function statSync2(path6, optionsOrSettings) {
3742
3742
  const settings = getSettings(optionsOrSettings);
3743
- return sync.read(path3, settings);
3743
+ return sync.read(path6, settings);
3744
3744
  }
3745
- __name(statSync, "statSync");
3746
- exports2.statSync = statSync;
3745
+ __name(statSync2, "statSync");
3746
+ exports2.statSync = statSync2;
3747
3747
  function getSettings(settingsOrOptions = {}) {
3748
3748
  if (settingsOrOptions instanceof settings_1.default) {
3749
3749
  return settingsOrOptions;
@@ -3873,8 +3873,8 @@ var require_utils4 = __commonJS({
3873
3873
  "use strict";
3874
3874
  Object.defineProperty(exports2, "__esModule", { value: true });
3875
3875
  exports2.fs = void 0;
3876
- var fs3 = require_fs3();
3877
- exports2.fs = fs3;
3876
+ var fs6 = require_fs3();
3877
+ exports2.fs = fs6;
3878
3878
  }
3879
3879
  });
3880
3880
 
@@ -3970,16 +3970,16 @@ var require_async2 = __commonJS({
3970
3970
  return;
3971
3971
  }
3972
3972
  const tasks = names.map((name) => {
3973
- const path3 = common.joinPathSegments(directory, name, settings.pathSegmentSeparator);
3973
+ const path6 = common.joinPathSegments(directory, name, settings.pathSegmentSeparator);
3974
3974
  return (done) => {
3975
- fsStat.stat(path3, settings.fsStatSettings, (error, stats) => {
3975
+ fsStat.stat(path6, settings.fsStatSettings, (error, stats) => {
3976
3976
  if (error !== null) {
3977
3977
  done(error);
3978
3978
  return;
3979
3979
  }
3980
3980
  const entry = {
3981
3981
  name,
3982
- path: path3,
3982
+ path: path6,
3983
3983
  dirent: utils.fs.createDirentFromStats(name, stats)
3984
3984
  };
3985
3985
  if (settings.stats) {
@@ -4079,14 +4079,14 @@ var require_fs4 = __commonJS({
4079
4079
  "use strict";
4080
4080
  Object.defineProperty(exports2, "__esModule", { value: true });
4081
4081
  exports2.createFileSystemAdapter = exports2.FILE_SYSTEM_ADAPTER = void 0;
4082
- var fs3 = require("fs");
4082
+ var fs6 = require("fs");
4083
4083
  exports2.FILE_SYSTEM_ADAPTER = {
4084
- lstat: fs3.lstat,
4085
- stat: fs3.stat,
4086
- lstatSync: fs3.lstatSync,
4087
- statSync: fs3.statSync,
4088
- readdir: fs3.readdir,
4089
- readdirSync: fs3.readdirSync
4084
+ lstat: fs6.lstat,
4085
+ stat: fs6.stat,
4086
+ lstatSync: fs6.lstatSync,
4087
+ statSync: fs6.statSync,
4088
+ readdir: fs6.readdir,
4089
+ readdirSync: fs6.readdirSync
4090
4090
  };
4091
4091
  function createFileSystemAdapter(fsMethods) {
4092
4092
  if (fsMethods === void 0) {
@@ -4104,9 +4104,9 @@ var require_settings2 = __commonJS({
4104
4104
  "../../node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/settings.js"(exports2) {
4105
4105
  "use strict";
4106
4106
  Object.defineProperty(exports2, "__esModule", { value: true });
4107
- var path3 = require("path");
4107
+ var path6 = require("path");
4108
4108
  var fsStat = require_out();
4109
- var fs3 = require_fs4();
4109
+ var fs6 = require_fs4();
4110
4110
  var Settings = class {
4111
4111
  static {
4112
4112
  __name(this, "Settings");
@@ -4114,8 +4114,8 @@ var require_settings2 = __commonJS({
4114
4114
  constructor(_options = {}) {
4115
4115
  this._options = _options;
4116
4116
  this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false);
4117
- this.fs = fs3.createFileSystemAdapter(this._options.fs);
4118
- this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path3.sep);
4117
+ this.fs = fs6.createFileSystemAdapter(this._options.fs);
4118
+ this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path6.sep);
4119
4119
  this.stats = this._getValue(this._options.stats, false);
4120
4120
  this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true);
4121
4121
  this.fsStatSettings = new fsStat.Settings({
@@ -4142,18 +4142,18 @@ var require_out2 = __commonJS({
4142
4142
  var sync = require_sync2();
4143
4143
  var settings_1 = require_settings2();
4144
4144
  exports2.Settings = settings_1.default;
4145
- function scandir(path3, optionsOrSettingsOrCallback, callback) {
4145
+ function scandir(path6, optionsOrSettingsOrCallback, callback) {
4146
4146
  if (typeof optionsOrSettingsOrCallback === "function") {
4147
- async.read(path3, getSettings(), optionsOrSettingsOrCallback);
4147
+ async.read(path6, getSettings(), optionsOrSettingsOrCallback);
4148
4148
  return;
4149
4149
  }
4150
- async.read(path3, getSettings(optionsOrSettingsOrCallback), callback);
4150
+ async.read(path6, getSettings(optionsOrSettingsOrCallback), callback);
4151
4151
  }
4152
4152
  __name(scandir, "scandir");
4153
4153
  exports2.scandir = scandir;
4154
- function scandirSync(path3, optionsOrSettings) {
4154
+ function scandirSync(path6, optionsOrSettings) {
4155
4155
  const settings = getSettings(optionsOrSettings);
4156
- return sync.read(path3, settings);
4156
+ return sync.read(path6, settings);
4157
4157
  }
4158
4158
  __name(scandirSync, "scandirSync");
4159
4159
  exports2.scandirSync = scandirSync;
@@ -4454,13 +4454,13 @@ var require_queue = __commonJS({
4454
4454
  queue.drained = drained;
4455
4455
  return queue;
4456
4456
  function push(value) {
4457
- var p = new Promise(function(resolve, reject) {
4457
+ var p = new Promise(function(resolve2, reject) {
4458
4458
  pushCb(value, function(err, result) {
4459
4459
  if (err) {
4460
4460
  reject(err);
4461
4461
  return;
4462
4462
  }
4463
- resolve(result);
4463
+ resolve2(result);
4464
4464
  });
4465
4465
  });
4466
4466
  p.catch(noop);
@@ -4468,13 +4468,13 @@ var require_queue = __commonJS({
4468
4468
  }
4469
4469
  __name(push, "push");
4470
4470
  function unshift(value) {
4471
- var p = new Promise(function(resolve, reject) {
4471
+ var p = new Promise(function(resolve2, reject) {
4472
4472
  unshiftCb(value, function(err, result) {
4473
4473
  if (err) {
4474
4474
  reject(err);
4475
4475
  return;
4476
4476
  }
4477
- resolve(result);
4477
+ resolve2(result);
4478
4478
  });
4479
4479
  });
4480
4480
  p.catch(noop);
@@ -4482,15 +4482,15 @@ var require_queue = __commonJS({
4482
4482
  }
4483
4483
  __name(unshift, "unshift");
4484
4484
  function drained() {
4485
- var p = new Promise(function(resolve) {
4485
+ var p = new Promise(function(resolve2) {
4486
4486
  process.nextTick(function() {
4487
4487
  if (queue.idle()) {
4488
- resolve();
4488
+ resolve2();
4489
4489
  } else {
4490
4490
  var previousDrain = queue.drain;
4491
4491
  queue.drain = function() {
4492
4492
  if (typeof previousDrain === "function") previousDrain();
4493
- resolve();
4493
+ resolve2();
4494
4494
  queue.drain = previousDrain;
4495
4495
  };
4496
4496
  }
@@ -4850,7 +4850,7 @@ var require_settings3 = __commonJS({
4850
4850
  "../../node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/settings.js"(exports2) {
4851
4851
  "use strict";
4852
4852
  Object.defineProperty(exports2, "__esModule", { value: true });
4853
- var path3 = require("path");
4853
+ var path6 = require("path");
4854
4854
  var fsScandir = require_out2();
4855
4855
  var Settings = class {
4856
4856
  static {
@@ -4863,7 +4863,7 @@ var require_settings3 = __commonJS({
4863
4863
  this.deepFilter = this._getValue(this._options.deepFilter, null);
4864
4864
  this.entryFilter = this._getValue(this._options.entryFilter, null);
4865
4865
  this.errorFilter = this._getValue(this._options.errorFilter, null);
4866
- this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path3.sep);
4866
+ this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path6.sep);
4867
4867
  this.fsScandirSettings = new fsScandir.Settings({
4868
4868
  followSymbolicLinks: this._options.followSymbolicLinks,
4869
4869
  fs: this._options.fs,
@@ -4929,7 +4929,7 @@ var require_reader2 = __commonJS({
4929
4929
  "../../node_modules/.pnpm/fast-glob@3.3.3/node_modules/fast-glob/out/readers/reader.js"(exports2) {
4930
4930
  "use strict";
4931
4931
  Object.defineProperty(exports2, "__esModule", { value: true });
4932
- var path3 = require("path");
4932
+ var path6 = require("path");
4933
4933
  var fsStat = require_out();
4934
4934
  var utils = require_utils3();
4935
4935
  var Reader = class {
@@ -4945,7 +4945,7 @@ var require_reader2 = __commonJS({
4945
4945
  });
4946
4946
  }
4947
4947
  _getFullEntryPath(filepath) {
4948
- return path3.resolve(this._settings.cwd, filepath);
4948
+ return path6.resolve(this._settings.cwd, filepath);
4949
4949
  }
4950
4950
  _makeEntry(stats, pattern) {
4951
4951
  const entry = {
@@ -5015,9 +5015,9 @@ var require_stream3 = __commonJS({
5015
5015
  });
5016
5016
  }
5017
5017
  _getStat(filepath) {
5018
- return new Promise((resolve, reject) => {
5018
+ return new Promise((resolve2, reject) => {
5019
5019
  this._stat(filepath, this._fsStatSettings, (error, stats) => {
5020
- return error === null ? resolve(stats) : reject(error);
5020
+ return error === null ? resolve2(stats) : reject(error);
5021
5021
  });
5022
5022
  });
5023
5023
  }
@@ -5044,10 +5044,10 @@ var require_async5 = __commonJS({
5044
5044
  this._readerStream = new stream_1.default(this._settings);
5045
5045
  }
5046
5046
  dynamic(root, options) {
5047
- return new Promise((resolve, reject) => {
5047
+ return new Promise((resolve2, reject) => {
5048
5048
  this._walkAsync(root, options, (error, entries) => {
5049
5049
  if (error === null) {
5050
- resolve(entries);
5050
+ resolve2(entries);
5051
5051
  } else {
5052
5052
  reject(error);
5053
5053
  }
@@ -5057,10 +5057,10 @@ var require_async5 = __commonJS({
5057
5057
  async static(patterns, options) {
5058
5058
  const entries = [];
5059
5059
  const stream = this._readerStream.static(patterns, options);
5060
- return new Promise((resolve, reject) => {
5060
+ return new Promise((resolve2, reject) => {
5061
5061
  stream.once("error", reject);
5062
5062
  stream.on("data", (entry) => entries.push(entry));
5063
- stream.once("end", () => resolve(entries));
5063
+ stream.once("end", () => resolve2(entries));
5064
5064
  });
5065
5065
  }
5066
5066
  };
@@ -5385,7 +5385,7 @@ var require_provider = __commonJS({
5385
5385
  "../../node_modules/.pnpm/fast-glob@3.3.3/node_modules/fast-glob/out/providers/provider.js"(exports2) {
5386
5386
  "use strict";
5387
5387
  Object.defineProperty(exports2, "__esModule", { value: true });
5388
- var path3 = require("path");
5388
+ var path6 = require("path");
5389
5389
  var deep_1 = require_deep();
5390
5390
  var entry_1 = require_entry();
5391
5391
  var error_1 = require_error();
@@ -5402,7 +5402,7 @@ var require_provider = __commonJS({
5402
5402
  this.entryTransformer = new entry_2.default(this._settings);
5403
5403
  }
5404
5404
  _getRootDirectory(task) {
5405
- return path3.resolve(this._settings.cwd, task.base);
5405
+ return path6.resolve(this._settings.cwd, task.base);
5406
5406
  }
5407
5407
  _getReaderOptions(task) {
5408
5408
  const basePath = task.base === "." ? "" : task.base;
@@ -5595,16 +5595,16 @@ var require_settings4 = __commonJS({
5595
5595
  "use strict";
5596
5596
  Object.defineProperty(exports2, "__esModule", { value: true });
5597
5597
  exports2.DEFAULT_FILE_SYSTEM_ADAPTER = void 0;
5598
- var fs3 = require("fs");
5598
+ var fs6 = require("fs");
5599
5599
  var os2 = require("os");
5600
5600
  var CPU_COUNT = Math.max(os2.cpus().length, 1);
5601
5601
  exports2.DEFAULT_FILE_SYSTEM_ADAPTER = {
5602
- lstat: fs3.lstat,
5603
- lstatSync: fs3.lstatSync,
5604
- stat: fs3.stat,
5605
- statSync: fs3.statSync,
5606
- readdir: fs3.readdir,
5607
- readdirSync: fs3.readdirSync
5602
+ lstat: fs6.lstat,
5603
+ lstatSync: fs6.lstatSync,
5604
+ stat: fs6.stat,
5605
+ statSync: fs6.statSync,
5606
+ readdir: fs6.readdir,
5607
+ readdirSync: fs6.readdirSync
5608
5608
  };
5609
5609
  var Settings = class {
5610
5610
  static {
@@ -5777,10 +5777,10 @@ __export(FileRunner_exports, {
5777
5777
  });
5778
5778
  module.exports = __toCommonJS(FileRunner_exports);
5779
5779
  var import_events = require("events");
5780
- var fs2 = __toESM(require("fs"));
5781
- var fsp = __toESM(require("fs/promises"));
5780
+ var fs5 = __toESM(require("fs"));
5781
+ var fsp4 = __toESM(require("fs/promises"));
5782
5782
  var os = __toESM(require("os"));
5783
- var path2 = __toESM(require("path"));
5783
+ var path5 = __toESM(require("path"));
5784
5784
 
5785
5785
  // ../discovery/dist/index.js
5786
5786
  var import_fast_glob = __toESM(require_out4(), 1);
@@ -5994,6 +5994,564 @@ __name(discoverFilesInDirs, "discoverFilesInDirs");
5994
5994
 
5995
5995
  // src/runner/FileRunner.ts
5996
5996
  var import_engines = require("@vibecheck/engines");
5997
+
5998
+ // src/cache/ScanCache.ts
5999
+ var fs2 = __toESM(require("fs"));
6000
+ var fsp = __toESM(require("fs/promises"));
6001
+ var path2 = __toESM(require("path"));
6002
+ var CACHE_VERSION = 1;
6003
+ var CACHE_FILENAME = "scan-cache.json";
6004
+ var CACHE_TTL_MS2 = 7 * 24 * 60 * 60 * 1e3;
6005
+ var MAX_CACHE_SIZE_BYTES = 10 * 1024 * 1024;
6006
+ var PRUNE_INTERVAL_MS = 24 * 60 * 60 * 1e3;
6007
+ var ENGINE_VERSION = "3.0.0";
6008
+ var ScanCache = class {
6009
+ static {
6010
+ __name(this, "ScanCache");
6011
+ }
6012
+ _cachePath;
6013
+ _entries = /* @__PURE__ */ new Map();
6014
+ _metadata;
6015
+ _dirty = false;
6016
+ _hits = 0;
6017
+ _misses = 0;
6018
+ constructor(workspaceRoot) {
6019
+ const cacheDir = path2.join(workspaceRoot, ".vibecheck");
6020
+ this._cachePath = path2.join(cacheDir, CACHE_FILENAME);
6021
+ this._metadata = {
6022
+ version: CACHE_VERSION,
6023
+ createdAt: Date.now(),
6024
+ lastPruned: Date.now(),
6025
+ totalEntries: 0,
6026
+ totalSizeBytes: 0
6027
+ };
6028
+ }
6029
+ /**
6030
+ * Load cache from disk. Non-blocking — returns immediately if file doesn't exist.
6031
+ */
6032
+ async load() {
6033
+ try {
6034
+ if (!fs2.existsSync(this._cachePath)) return;
6035
+ const raw = await fsp.readFile(this._cachePath, "utf-8");
6036
+ const data = JSON.parse(raw);
6037
+ if (data.metadata.version !== CACHE_VERSION) {
6038
+ this._entries.clear();
6039
+ this._dirty = true;
6040
+ return;
6041
+ }
6042
+ this._metadata = data.metadata;
6043
+ this._entries = new Map(Object.entries(data.entries));
6044
+ if (Date.now() - this._metadata.lastPruned > PRUNE_INTERVAL_MS) {
6045
+ this._prune();
6046
+ }
6047
+ } catch (err) {
6048
+ this._entries.clear();
6049
+ this._dirty = true;
6050
+ }
6051
+ }
6052
+ /**
6053
+ * Get cached result for a file. Returns null if not cached or invalid.
6054
+ */
6055
+ get(relativePath, contentHash, confidenceThreshold) {
6056
+ const entry = this._entries.get(relativePath);
6057
+ if (!entry) {
6058
+ this._misses++;
6059
+ return null;
6060
+ }
6061
+ if (entry.contentHash !== contentHash) {
6062
+ this._entries.delete(relativePath);
6063
+ this._dirty = true;
6064
+ this._misses++;
6065
+ return null;
6066
+ }
6067
+ if (entry.engineVersion !== ENGINE_VERSION) {
6068
+ this._entries.delete(relativePath);
6069
+ this._dirty = true;
6070
+ this._misses++;
6071
+ return null;
6072
+ }
6073
+ if (entry.confidenceThreshold !== confidenceThreshold) {
6074
+ this._entries.delete(relativePath);
6075
+ this._dirty = true;
6076
+ this._misses++;
6077
+ return null;
6078
+ }
6079
+ if (Date.now() - entry.cachedAt > CACHE_TTL_MS2) {
6080
+ this._entries.delete(relativePath);
6081
+ this._dirty = true;
6082
+ this._misses++;
6083
+ return null;
6084
+ }
6085
+ this._hits++;
6086
+ return entry;
6087
+ }
6088
+ /**
6089
+ * Store scan result in cache.
6090
+ */
6091
+ set(relativePath, contentHash, findings, confidenceThreshold, fileSizeBytes, scanDurationMs) {
6092
+ const entry = {
6093
+ file: relativePath,
6094
+ contentHash,
6095
+ findings,
6096
+ cachedAt: Date.now(),
6097
+ engineVersion: ENGINE_VERSION,
6098
+ confidenceThreshold,
6099
+ fileSizeBytes,
6100
+ scanDurationMs
6101
+ };
6102
+ this._entries.set(relativePath, entry);
6103
+ this._dirty = true;
6104
+ }
6105
+ /**
6106
+ * Invalidate a specific file (e.g., when user edits it).
6107
+ */
6108
+ invalidate(relativePath) {
6109
+ if (this._entries.delete(relativePath)) {
6110
+ this._dirty = true;
6111
+ }
6112
+ }
6113
+ /**
6114
+ * Clear entire cache.
6115
+ */
6116
+ clear() {
6117
+ this._entries.clear();
6118
+ this._dirty = true;
6119
+ this._hits = 0;
6120
+ this._misses = 0;
6121
+ }
6122
+ /**
6123
+ * Persist cache to disk. Only writes if dirty.
6124
+ */
6125
+ async save() {
6126
+ if (!this._dirty) return;
6127
+ try {
6128
+ const cacheDir = path2.dirname(this._cachePath);
6129
+ if (!fs2.existsSync(cacheDir)) {
6130
+ await fsp.mkdir(cacheDir, { recursive: true });
6131
+ }
6132
+ this._metadata.totalEntries = this._entries.size;
6133
+ this._metadata.lastPruned = Date.now();
6134
+ const data = {
6135
+ metadata: this._metadata,
6136
+ entries: Object.fromEntries(this._entries)
6137
+ };
6138
+ const json = JSON.stringify(data, null, 2);
6139
+ this._metadata.totalSizeBytes = Buffer.byteLength(json, "utf-8");
6140
+ if (this._metadata.totalSizeBytes > MAX_CACHE_SIZE_BYTES) {
6141
+ this._prune();
6142
+ const prunedData = {
6143
+ metadata: this._metadata,
6144
+ entries: Object.fromEntries(this._entries)
6145
+ };
6146
+ await fsp.writeFile(this._cachePath, JSON.stringify(prunedData, null, 2), "utf-8");
6147
+ } else {
6148
+ await fsp.writeFile(this._cachePath, json, "utf-8");
6149
+ }
6150
+ this._dirty = false;
6151
+ } catch (err) {
6152
+ process.stderr.write(`[vibecheck] Cache write failed: ${err.message}
6153
+ `);
6154
+ }
6155
+ }
6156
+ /**
6157
+ * Get cache statistics.
6158
+ */
6159
+ getStats() {
6160
+ const total = this._hits + this._misses;
6161
+ const hitRate = total > 0 ? this._hits / total : 0;
6162
+ let oldestAge = 0;
6163
+ let newestAge = Infinity;
6164
+ const now = Date.now();
6165
+ for (const entry of this._entries.values()) {
6166
+ const age = now - entry.cachedAt;
6167
+ if (age > oldestAge) oldestAge = age;
6168
+ if (age < newestAge) newestAge = age;
6169
+ }
6170
+ return {
6171
+ hits: this._hits,
6172
+ misses: this._misses,
6173
+ hitRate,
6174
+ totalEntries: this._entries.size,
6175
+ cacheSizeBytes: this._metadata.totalSizeBytes,
6176
+ oldestEntryAge: oldestAge,
6177
+ newestEntryAge: newestAge === Infinity ? 0 : newestAge
6178
+ };
6179
+ }
6180
+ /**
6181
+ * Prune old entries to keep cache size under limit.
6182
+ * Removes oldest entries first (LRU-style).
6183
+ */
6184
+ _prune() {
6185
+ const now = Date.now();
6186
+ const entries = [...this._entries.entries()];
6187
+ for (const [key, entry] of entries) {
6188
+ if (now - entry.cachedAt > CACHE_TTL_MS2) {
6189
+ this._entries.delete(key);
6190
+ }
6191
+ }
6192
+ const remaining = [...this._entries.entries()];
6193
+ remaining.sort((a, b) => a[1].cachedAt - b[1].cachedAt);
6194
+ const avgEntrySize = 2048;
6195
+ const maxEntries = Math.floor(MAX_CACHE_SIZE_BYTES / avgEntrySize);
6196
+ if (remaining.length > maxEntries) {
6197
+ const toRemove = remaining.length - maxEntries;
6198
+ for (let i = 0; i < toRemove; i++) {
6199
+ this._entries.delete(remaining[i][0]);
6200
+ }
6201
+ }
6202
+ this._metadata.lastPruned = now;
6203
+ this._dirty = true;
6204
+ }
6205
+ };
6206
+
6207
+ // src/cache/ChangeDetector.ts
6208
+ var fs3 = __toESM(require("fs"));
6209
+ var fsp2 = __toESM(require("fs/promises"));
6210
+ var path3 = __toESM(require("path"));
6211
+ var import_child_process = require("child_process");
6212
+ var import_util = require("util");
6213
+ var execFileAsync = (0, import_util.promisify)(import_child_process.execFile);
6214
+ var ChangeDetector = class {
6215
+ static {
6216
+ __name(this, "ChangeDetector");
6217
+ }
6218
+ _workspaceRoot;
6219
+ constructor(workspaceRoot) {
6220
+ this._workspaceRoot = workspaceRoot;
6221
+ }
6222
+ /**
6223
+ * Detect changed files using best available strategy.
6224
+ */
6225
+ async detect(options) {
6226
+ const { allFiles, lastScanTime, forceFull } = options;
6227
+ if (forceFull) {
6228
+ return {
6229
+ changedFiles: new Set(allFiles),
6230
+ allFiles,
6231
+ strategy: "full"
6232
+ };
6233
+ }
6234
+ if (!lastScanTime) {
6235
+ return {
6236
+ changedFiles: new Set(allFiles),
6237
+ allFiles,
6238
+ strategy: "full"
6239
+ };
6240
+ }
6241
+ const gitResult = await this._detectViaGit(allFiles, lastScanTime);
6242
+ if (gitResult) return gitResult;
6243
+ const mtimeResult = await this._detectViaMtime(allFiles, lastScanTime);
6244
+ return mtimeResult;
6245
+ }
6246
+ /**
6247
+ * Git-based change detection.
6248
+ * Returns files changed since last scan timestamp.
6249
+ */
6250
+ async _detectViaGit(allFiles, lastScanTime) {
6251
+ try {
6252
+ const { stdout: gitRoot } = await execFileAsync("git", ["rev-parse", "--show-toplevel"], {
6253
+ cwd: this._workspaceRoot,
6254
+ timeout: 2e3
6255
+ });
6256
+ if (!gitRoot.trim()) return null;
6257
+ const sinceDate = new Date(lastScanTime).toISOString();
6258
+ const { stdout: diffOutput } = await execFileAsync(
6259
+ "git",
6260
+ ["diff", "--name-only", `--since=${sinceDate}`, "HEAD"],
6261
+ {
6262
+ cwd: this._workspaceRoot,
6263
+ timeout: 5e3
6264
+ }
6265
+ );
6266
+ const { stdout: statusOutput } = await execFileAsync(
6267
+ "git",
6268
+ ["status", "--porcelain", "--untracked-files=all"],
6269
+ {
6270
+ cwd: this._workspaceRoot,
6271
+ timeout: 5e3
6272
+ }
6273
+ );
6274
+ const changedPaths = /* @__PURE__ */ new Set();
6275
+ for (const line of diffOutput.split("\n")) {
6276
+ const trimmed = line.trim();
6277
+ if (trimmed) {
6278
+ const absPath = path3.resolve(this._workspaceRoot, trimmed);
6279
+ changedPaths.add(absPath);
6280
+ }
6281
+ }
6282
+ for (const line of statusOutput.split("\n")) {
6283
+ const trimmed = line.trim();
6284
+ if (!trimmed) continue;
6285
+ const filename = trimmed.slice(3);
6286
+ if (filename) {
6287
+ const absPath = path3.resolve(this._workspaceRoot, filename);
6288
+ changedPaths.add(absPath);
6289
+ }
6290
+ }
6291
+ const allFilesSet = new Set(allFiles);
6292
+ const changedFiles = new Set(
6293
+ [...changedPaths].filter((f) => allFilesSet.has(f))
6294
+ );
6295
+ if (changedFiles.size === 0) {
6296
+ const newFiles = allFiles.filter((f) => {
6297
+ try {
6298
+ const stat4 = fs3.statSync(f);
6299
+ return stat4.mtimeMs > lastScanTime;
6300
+ } catch {
6301
+ return false;
6302
+ }
6303
+ });
6304
+ for (const f of newFiles) changedFiles.add(f);
6305
+ }
6306
+ return {
6307
+ changedFiles,
6308
+ allFiles,
6309
+ strategy: "git-diff",
6310
+ lastScanTime
6311
+ };
6312
+ } catch (err) {
6313
+ return null;
6314
+ }
6315
+ }
6316
+ /**
6317
+ * Mtime-based change detection (fallback).
6318
+ * Returns files modified after last scan timestamp.
6319
+ */
6320
+ async _detectViaMtime(allFiles, lastScanTime) {
6321
+ const changedFiles = /* @__PURE__ */ new Set();
6322
+ await Promise.all(
6323
+ allFiles.map(async (file) => {
6324
+ try {
6325
+ const stat4 = await fsp2.stat(file);
6326
+ if (stat4.mtimeMs > lastScanTime) {
6327
+ changedFiles.add(file);
6328
+ }
6329
+ } catch {
6330
+ }
6331
+ })
6332
+ );
6333
+ return {
6334
+ changedFiles,
6335
+ allFiles,
6336
+ strategy: "mtime",
6337
+ lastScanTime
6338
+ };
6339
+ }
6340
+ /**
6341
+ * Get list of files changed in git working directory (staged + unstaged).
6342
+ * Used for `vibecheck scan staged` and watch mode.
6343
+ */
6344
+ async getGitChangedFiles() {
6345
+ try {
6346
+ const { stdout } = await execFileAsync(
6347
+ "git",
6348
+ ["status", "--porcelain", "--untracked-files=all"],
6349
+ {
6350
+ cwd: this._workspaceRoot,
6351
+ timeout: 5e3
6352
+ }
6353
+ );
6354
+ const files = [];
6355
+ for (const line of stdout.split("\n")) {
6356
+ const trimmed = line.trim();
6357
+ if (!trimmed) continue;
6358
+ const filename = trimmed.slice(3);
6359
+ if (filename) {
6360
+ const absPath = path3.resolve(this._workspaceRoot, filename);
6361
+ files.push(absPath);
6362
+ }
6363
+ }
6364
+ return files;
6365
+ } catch {
6366
+ return [];
6367
+ }
6368
+ }
6369
+ /**
6370
+ * Get list of staged files only.
6371
+ */
6372
+ async getGitStagedFiles() {
6373
+ try {
6374
+ const { stdout } = await execFileAsync(
6375
+ "git",
6376
+ ["diff", "--cached", "--name-only"],
6377
+ {
6378
+ cwd: this._workspaceRoot,
6379
+ timeout: 5e3
6380
+ }
6381
+ );
6382
+ const files = [];
6383
+ for (const line of stdout.split("\n")) {
6384
+ const trimmed = line.trim();
6385
+ if (trimmed) {
6386
+ const absPath = path3.resolve(this._workspaceRoot, trimmed);
6387
+ files.push(absPath);
6388
+ }
6389
+ }
6390
+ return files;
6391
+ } catch {
6392
+ return [];
6393
+ }
6394
+ }
6395
+ };
6396
+ async function saveLastScanTime(workspaceRoot) {
6397
+ const timestampFile = path3.join(workspaceRoot, ".vibecheck", "last-scan.txt");
6398
+ const cacheDir = path3.dirname(timestampFile);
6399
+ try {
6400
+ if (!fs3.existsSync(cacheDir)) {
6401
+ await fsp2.mkdir(cacheDir, { recursive: true });
6402
+ }
6403
+ await fsp2.writeFile(timestampFile, Date.now().toString(), "utf-8");
6404
+ } catch {
6405
+ }
6406
+ }
6407
+ __name(saveLastScanTime, "saveLastScanTime");
6408
+ async function loadLastScanTime(workspaceRoot) {
6409
+ const timestampFile = path3.join(workspaceRoot, ".vibecheck", "last-scan.txt");
6410
+ try {
6411
+ if (!fs3.existsSync(timestampFile)) return void 0;
6412
+ const content = await fsp2.readFile(timestampFile, "utf-8");
6413
+ const timestamp = parseInt(content.trim(), 10);
6414
+ return isNaN(timestamp) ? void 0 : timestamp;
6415
+ } catch {
6416
+ return void 0;
6417
+ }
6418
+ }
6419
+ __name(loadLastScanTime, "loadLastScanTime");
6420
+
6421
+ // src/cache/PerformanceMetrics.ts
6422
+ var fs4 = __toESM(require("fs"));
6423
+ var fsp3 = __toESM(require("fs/promises"));
6424
+ var path4 = __toESM(require("path"));
6425
+ var PerformanceTracker = class {
6426
+ static {
6427
+ __name(this, "PerformanceTracker");
6428
+ }
6429
+ _startTime = 0;
6430
+ _discoveryStartTime = 0;
6431
+ _discoveryEndTime = 0;
6432
+ _scanStartTime = 0;
6433
+ _scanEndTime = 0;
6434
+ _workspaceRoot;
6435
+ _historyPath;
6436
+ constructor(workspaceRoot) {
6437
+ this._workspaceRoot = workspaceRoot;
6438
+ this._historyPath = path4.join(workspaceRoot, ".vibecheck", "perf-history.json");
6439
+ }
6440
+ /**
6441
+ * Mark CLI startup complete.
6442
+ */
6443
+ markStartup() {
6444
+ this._startTime = performance.now();
6445
+ }
6446
+ /**
6447
+ * Mark discovery phase start.
6448
+ */
6449
+ markDiscoveryStart() {
6450
+ this._discoveryStartTime = performance.now();
6451
+ }
6452
+ /**
6453
+ * Mark discovery phase end.
6454
+ */
6455
+ markDiscoveryEnd() {
6456
+ this._discoveryEndTime = performance.now();
6457
+ }
6458
+ /**
6459
+ * Mark scan phase start.
6460
+ */
6461
+ markScanStart() {
6462
+ this._scanStartTime = performance.now();
6463
+ }
6464
+ /**
6465
+ * Mark scan phase end.
6466
+ */
6467
+ markScanEnd() {
6468
+ this._scanEndTime = performance.now();
6469
+ }
6470
+ /**
6471
+ * Create performance snapshot from current metrics.
6472
+ */
6473
+ createSnapshot(filesScanned, cacheHits, cacheMisses, engineLatencies) {
6474
+ const now = performance.now();
6475
+ const startupMs = this._discoveryStartTime - this._startTime;
6476
+ const discoveryMs = this._discoveryEndTime - this._discoveryStartTime;
6477
+ const totalScanMs = this._scanEndTime - this._scanStartTime;
6478
+ const throughput = totalScanMs > 0 ? filesScanned / totalScanMs * 1e3 : 0;
6479
+ const cacheTotal = cacheHits + cacheMisses;
6480
+ const cacheHitRate = cacheTotal > 0 ? cacheHits / cacheTotal : 0;
6481
+ const memoryUsageMB = process.memoryUsage().heapUsed / 1024 / 1024;
6482
+ return {
6483
+ timestamp: Date.now(),
6484
+ startupMs: Math.round(startupMs),
6485
+ discoveryMs: Math.round(discoveryMs),
6486
+ totalScanMs: Math.round(totalScanMs),
6487
+ filesScanned,
6488
+ throughput: Math.round(throughput * 100) / 100,
6489
+ cacheHitRate: Math.round(cacheHitRate * 100) / 100,
6490
+ cacheHits,
6491
+ cacheMisses,
6492
+ engineLatencies,
6493
+ memoryUsageMB: Math.round(memoryUsageMB * 100) / 100
6494
+ };
6495
+ }
6496
+ /**
6497
+ * Save snapshot to performance history.
6498
+ */
6499
+ async saveSnapshot(snapshot) {
6500
+ try {
6501
+ const cacheDir = path4.dirname(this._historyPath);
6502
+ if (!fs4.existsSync(cacheDir)) {
6503
+ await fsp3.mkdir(cacheDir, { recursive: true });
6504
+ }
6505
+ let history;
6506
+ if (fs4.existsSync(this._historyPath)) {
6507
+ const raw = await fsp3.readFile(this._historyPath, "utf-8");
6508
+ history = JSON.parse(raw);
6509
+ } else {
6510
+ history = { snapshots: [], maxSnapshots: 10 };
6511
+ }
6512
+ history.snapshots.push(snapshot);
6513
+ if (history.snapshots.length > history.maxSnapshots) {
6514
+ history.snapshots = history.snapshots.slice(-history.maxSnapshots);
6515
+ }
6516
+ await fsp3.writeFile(this._historyPath, JSON.stringify(history, null, 2), "utf-8");
6517
+ } catch {
6518
+ }
6519
+ }
6520
+ /**
6521
+ * Load performance history from disk.
6522
+ */
6523
+ async loadHistory() {
6524
+ try {
6525
+ if (!fs4.existsSync(this._historyPath)) return null;
6526
+ const raw = await fsp3.readFile(this._historyPath, "utf-8");
6527
+ return JSON.parse(raw);
6528
+ } catch {
6529
+ return null;
6530
+ }
6531
+ }
6532
+ /**
6533
+ * Get performance trend (last N runs).
6534
+ */
6535
+ async getTrend(metric, count = 5) {
6536
+ const history = await this.loadHistory();
6537
+ if (!history) return [];
6538
+ return history.snapshots.slice(-count).map((s) => s[metric]).filter((v) => typeof v === "number");
6539
+ }
6540
+ /**
6541
+ * Detect performance regression.
6542
+ * Returns true if latest run is significantly slower than average.
6543
+ */
6544
+ async detectRegression(threshold = 0.2) {
6545
+ const trend = await this.getTrend("totalScanMs", 5);
6546
+ if (trend.length < 3) return false;
6547
+ const latest = trend[trend.length - 1];
6548
+ const previous = trend.slice(0, -1);
6549
+ const avg = previous.reduce((sum, v) => sum + v, 0) / previous.length;
6550
+ return latest > avg * (1 + threshold);
6551
+ }
6552
+ };
6553
+
6554
+ // src/runner/FileRunner.ts
5997
6555
  var import_engines2 = require("@vibecheck/engines");
5998
6556
  var DEFAULT_ENGINE_THRESHOLDS = {
5999
6557
  env_var: 0.72,
@@ -6023,16 +6581,16 @@ var IgnoreFilter = class _IgnoreFilter {
6023
6581
  _cache = /* @__PURE__ */ new Map();
6024
6582
  static _CACHE_MAX = 4096;
6025
6583
  constructor(workspaceRoot, ignoreFile, respectGitignore = true) {
6026
- const vcIgnorePath = ignoreFile ?? path2.join(workspaceRoot, ".vibecheckignore");
6584
+ const vcIgnorePath = ignoreFile ?? path5.join(workspaceRoot, ".vibecheckignore");
6027
6585
  this._loadFile(vcIgnorePath);
6028
6586
  if (respectGitignore) {
6029
- this._loadFile(path2.join(workspaceRoot, ".gitignore"));
6587
+ this._loadFile(path5.join(workspaceRoot, ".gitignore"));
6030
6588
  }
6031
6589
  }
6032
6590
  _loadFile(filePath) {
6033
6591
  try {
6034
- if (!fs2.existsSync(filePath)) return;
6035
- const content = fs2.readFileSync(filePath, "utf-8");
6592
+ if (!fs5.existsSync(filePath)) return;
6593
+ const content = fs5.readFileSync(filePath, "utf-8");
6036
6594
  for (const raw of content.split("\n")) {
6037
6595
  const line = raw.replace(/#.*$/, "").trim();
6038
6596
  if (!line) continue;
@@ -6124,11 +6682,11 @@ async function discoverFiles2(targets, workspaceRoot, filter, signal) {
6124
6682
  for (const target of targets) {
6125
6683
  if (signal?.aborted) break;
6126
6684
  try {
6127
- const stat3 = await fsp.stat(target);
6128
- if (stat3.isDirectory()) {
6685
+ const stat4 = await fsp4.stat(target);
6686
+ if (stat4.isDirectory()) {
6129
6687
  dirsToScan.push(target);
6130
- } else if (stat3.isFile() && CHECKED_EXTS.has(path2.extname(target).toLowerCase())) {
6131
- const rel = path2.relative(workspaceRoot, target).replace(/\\/g, "/");
6688
+ } else if (stat4.isFile() && CHECKED_EXTS.has(path5.extname(target).toLowerCase())) {
6689
+ const rel = path5.relative(workspaceRoot, target).replace(/\\/g, "/");
6132
6690
  if (!filter.isIgnored(rel)) explicitFiles.push(target);
6133
6691
  }
6134
6692
  } catch (err) {
@@ -6145,7 +6703,7 @@ async function discoverFiles2(targets, workspaceRoot, filter, signal) {
6145
6703
  rootDir: workspaceRoot
6146
6704
  });
6147
6705
  return result.files.filter((f) => {
6148
- const rel = path2.relative(workspaceRoot, f).replace(/\\/g, "/");
6706
+ const rel = path5.relative(workspaceRoot, f).replace(/\\/g, "/");
6149
6707
  return !filter.isIgnored(rel);
6150
6708
  });
6151
6709
  }
@@ -6173,14 +6731,14 @@ async function discoverFiles2(targets, workspaceRoot, filter, signal) {
6173
6731
  discoveredFiles.sort();
6174
6732
  }
6175
6733
  const filtered = discoveredFiles.filter((f) => {
6176
- const rel = path2.relative(workspaceRoot, f).replace(/\\/g, "/");
6734
+ const rel = path5.relative(workspaceRoot, f).replace(/\\/g, "/");
6177
6735
  return !filter.isIgnored(rel);
6178
6736
  });
6179
6737
  return [.../* @__PURE__ */ new Set([...explicitFiles, ...filtered])];
6180
6738
  }
6181
6739
  __name(discoverFiles2, "discoverFiles");
6182
6740
  function makeDelta(filePath, text) {
6183
- const ext = path2.extname(filePath).toLowerCase();
6741
+ const ext = path5.extname(filePath).toLowerCase();
6184
6742
  const lines = text.split("\n");
6185
6743
  return {
6186
6744
  documentUri: filePath,
@@ -6309,7 +6867,11 @@ async function runOnFiles(targets, options) {
6309
6867
  files: explicitFiles,
6310
6868
  allowlist = {},
6311
6869
  engineToggles = null,
6312
- suppressRules = []
6870
+ suppressRules = [],
6871
+ enableCache = true,
6872
+ enableIncremental = true,
6873
+ clearCache = false,
6874
+ trackPerformance = false
6313
6875
  } = options;
6314
6876
  const suppressRulesSet = new Set(suppressRules.map((r) => r.toUpperCase()));
6315
6877
  const getThreshold = /* @__PURE__ */ __name((engineId) => engineConfidenceThresholds[engineId] ?? DEFAULT_ENGINE_THRESHOLDS[engineId] ?? confidenceThreshold, "getThreshold");
@@ -6332,6 +6894,15 @@ async function runOnFiles(targets, options) {
6332
6894
  signal.addEventListener("abort", () => ac.abort(), { once: true });
6333
6895
  }
6334
6896
  }
6897
+ const scanCache = enableCache ? new ScanCache(workspaceRoot) : null;
6898
+ const changeDetector = enableIncremental ? new ChangeDetector(workspaceRoot) : null;
6899
+ const perfTracker = trackPerformance ? new PerformanceTracker(workspaceRoot) : null;
6900
+ if (scanCache && clearCache) {
6901
+ await scanCache.clear();
6902
+ }
6903
+ if (perfTracker) {
6904
+ perfTracker.markStartup();
6905
+ }
6335
6906
  const internalSignal = ac.signal;
6336
6907
  (0, import_events.setMaxListeners)(64, internalSignal);
6337
6908
  const emitProgress = /* @__PURE__ */ __name((patch) => {
@@ -6345,13 +6916,31 @@ async function runOnFiles(targets, options) {
6345
6916
  ...patch
6346
6917
  });
6347
6918
  }, "emitProgress");
6919
+ if (perfTracker) {
6920
+ perfTracker.markDiscoveryStart();
6921
+ }
6348
6922
  emitProgress({ phase: "discovery" });
6349
6923
  const filter = new IgnoreFilter(workspaceRoot, ignoreFile, respectGitignore);
6350
- const files = explicitFiles ? explicitFiles.filter((f) => {
6351
- const ext = path2.extname(f).toLowerCase();
6352
- const rel = path2.relative(workspaceRoot, f).replace(/\\/g, "/");
6924
+ let files = explicitFiles ? explicitFiles.filter((f) => {
6925
+ const ext = path5.extname(f).toLowerCase();
6926
+ const rel = path5.relative(workspaceRoot, f).replace(/\\/g, "/");
6353
6927
  return CHECKED_EXTS.has(ext) && !filter.isIgnored(rel);
6354
6928
  }) : await discoverFiles2(targets, workspaceRoot, filter, internalSignal);
6929
+ if (perfTracker) {
6930
+ perfTracker.markDiscoveryEnd();
6931
+ }
6932
+ if (changeDetector && files.length > 0) {
6933
+ const lastScanTime = await loadLastScanTime(workspaceRoot);
6934
+ const changeResult = await changeDetector.detect({
6935
+ workspaceRoot,
6936
+ allFiles: files,
6937
+ lastScanTime,
6938
+ forceFull: false
6939
+ });
6940
+ if (changeResult.strategy !== "full") {
6941
+ files = files.filter((f) => changeResult.changedFiles.has(f));
6942
+ }
6943
+ }
6355
6944
  if (internalSignal.aborted) {
6356
6945
  return { files: [], summary: buildSummary([], 0, performance.now() - startTime) };
6357
6946
  }
@@ -6362,6 +6951,9 @@ async function runOnFiles(targets, options) {
6362
6951
  summary: buildSummary([], 0, performance.now() - startTime)
6363
6952
  };
6364
6953
  }
6954
+ if (perfTracker) {
6955
+ perfTracker.markScanStart();
6956
+ }
6365
6957
  emitProgress({ phase: "activating", filesDiscovered: files.length });
6366
6958
  const allowlistEnvVars = allowlist.envVars;
6367
6959
  const truthpack = await (0, import_engines.loadTruthpack)(workspaceRoot);
@@ -6375,7 +6967,7 @@ async function runOnFiles(targets, options) {
6375
6967
  return loader;
6376
6968
  })();
6377
6969
  const ghostRouteIndex = truthpack ? (0, import_engines.truthpackToRouteIndex)(truthpack.routes, workspaceRoot) : void 0;
6378
- const sdkMapsDir = path2.join(__dirname, "..", "engines", "sdk-maps");
6970
+ const sdkMapsDir = path5.join(__dirname, "..", "engines", "sdk-maps");
6379
6971
  const registry = (0, import_engines.createDefaultRegistry)();
6380
6972
  registry.register(
6381
6973
  new import_engines.EnvVarEngine(envIndex, {
@@ -6396,7 +6988,7 @@ async function runOnFiles(targets, options) {
6396
6988
  );
6397
6989
  const phantomConfig = {
6398
6990
  confidenceThreshold: getThreshold("phantom_dep"),
6399
- registryCachePath: path2.join(workspaceRoot, ".vibecheck", "registry-cache.json")
6991
+ registryCachePath: path5.join(workspaceRoot, ".vibecheck", "registry-cache.json")
6400
6992
  };
6401
6993
  registry.register(new import_engines.PhantomDepEngine(workspaceRoot, phantomConfig), {
6402
6994
  timeoutMs: options.engineTimeouts?.["phantom-dep"] ?? 100,
@@ -6443,6 +7035,9 @@ async function runOnFiles(targets, options) {
6443
7035
  }
6444
7036
  let scannedCount = 0;
6445
7037
  let findingsCount = 0;
7038
+ let cacheHits = 0;
7039
+ let cacheMisses = 0;
7040
+ const engineLatencyMap = /* @__PURE__ */ new Map();
6446
7041
  const fileResults = await mapPool(
6447
7042
  files,
6448
7043
  concurrency,
@@ -6450,29 +7045,56 @@ async function runOnFiles(targets, options) {
6450
7045
  if (internalSignal.aborted) {
6451
7046
  return makeSkippedResult(file, workspaceRoot, "Scan aborted");
6452
7047
  }
6453
- let stat3;
7048
+ let stat4;
6454
7049
  try {
6455
- stat3 = await fsp.stat(file);
7050
+ stat4 = await fsp4.stat(file);
6456
7051
  } catch (err) {
6457
7052
  return makeSkippedResult(file, workspaceRoot, `Stat error: ${err.message}`);
6458
7053
  }
6459
- if (stat3.size > MAX_FILE_SIZE) {
6460
- return makeSkippedResult(file, workspaceRoot, `File too large (${Math.round(stat3.size / 1024)}KB > 1MB limit)`);
7054
+ if (stat4.size > MAX_FILE_SIZE) {
7055
+ return makeSkippedResult(file, workspaceRoot, `File too large (${Math.round(stat4.size / 1024)}KB > 1MB limit)`);
6461
7056
  }
6462
- if (stat3.size === 0) {
7057
+ if (stat4.size === 0) {
6463
7058
  return makeSkippedResult(file, workspaceRoot, "Empty file");
6464
7059
  }
6465
7060
  let text;
6466
7061
  try {
6467
- text = await fsp.readFile(file, "utf-8");
7062
+ text = await fsp4.readFile(file, "utf-8");
6468
7063
  } catch (err) {
6469
7064
  return makeSkippedResult(file, workspaceRoot, `Read error: ${err.message}`);
6470
7065
  }
6471
7066
  if (text.trim().length === 0) {
6472
7067
  return makeSkippedResult(file, workspaceRoot, "Empty file");
6473
7068
  }
7069
+ if (scanCache) {
7070
+ const cached = await scanCache.get(file, text, confidenceThreshold);
7071
+ if (cached) {
7072
+ cacheHits++;
7073
+ scannedCount++;
7074
+ findingsCount += cached.findings.length;
7075
+ emitProgress({
7076
+ phase: "scanning",
7077
+ filesDiscovered: files.length,
7078
+ filesScanned: scannedCount,
7079
+ filesTotal: files.length,
7080
+ findingsSoFar: findingsCount,
7081
+ currentFile: path5.relative(workspaceRoot, file).replace(/\\/g, "/")
7082
+ });
7083
+ const rel2 = path5.relative(workspaceRoot, file).replace(/\\/g, "/");
7084
+ return {
7085
+ file,
7086
+ relativePath: rel2,
7087
+ findings: cached.findings,
7088
+ engineMetrics: [],
7089
+ scanDurationMs: 0,
7090
+ fileSizeBytes: stat4.size,
7091
+ skipped: false
7092
+ };
7093
+ }
7094
+ cacheMisses++;
7095
+ }
6474
7096
  const delta = makeDelta(file, text);
6475
- const fileExt = path2.extname(file).toLowerCase();
7097
+ const fileExt = path5.extname(file).toLowerCase();
6476
7098
  const fileStart = performance.now();
6477
7099
  const applicableSlots = registry.getActive().filter((s) => {
6478
7100
  const exts = s.engine.supportedExtensions ?? s.extensions;
@@ -6505,22 +7127,33 @@ async function runOnFiles(targets, options) {
6505
7127
  }
6506
7128
  scannedCount++;
6507
7129
  findingsCount += deduped.length;
7130
+ const scanDurationMs = Math.round(performance.now() - fileStart);
7131
+ if (scanCache) {
7132
+ await scanCache.set(file, text, deduped, confidenceThreshold, stat4.size, scanDurationMs);
7133
+ }
7134
+ for (const metric of metrics) {
7135
+ if (metric.status === "ok") {
7136
+ const latencies = engineLatencyMap.get(metric.engineId) ?? [];
7137
+ latencies.push(metric.durationMs);
7138
+ engineLatencyMap.set(metric.engineId, latencies);
7139
+ }
7140
+ }
6508
7141
  emitProgress({
6509
7142
  phase: "scanning",
6510
7143
  filesDiscovered: files.length,
6511
7144
  filesScanned: scannedCount,
6512
7145
  filesTotal: files.length,
6513
7146
  findingsSoFar: findingsCount,
6514
- currentFile: path2.relative(workspaceRoot, file).replace(/\\/g, "/")
7147
+ currentFile: path5.relative(workspaceRoot, file).replace(/\\/g, "/")
6515
7148
  });
6516
- const rel = path2.relative(workspaceRoot, file).replace(/\\/g, "/");
7149
+ const rel = path5.relative(workspaceRoot, file).replace(/\\/g, "/");
6517
7150
  return {
6518
7151
  file,
6519
7152
  relativePath: rel,
6520
7153
  findings: deduped,
6521
7154
  engineMetrics: metrics,
6522
- scanDurationMs: Math.round(performance.now() - fileStart),
6523
- fileSizeBytes: stat3.size,
7155
+ scanDurationMs,
7156
+ fileSizeBytes: stat4.size,
6524
7157
  skipped: false
6525
7158
  };
6526
7159
  },
@@ -6530,6 +7163,27 @@ async function runOnFiles(targets, options) {
6530
7163
  registry.dispose();
6531
7164
  const totalMs = performance.now() - startTime;
6532
7165
  const summary = buildSummary(fileResults, files.length, totalMs);
7166
+ if (perfTracker) {
7167
+ perfTracker.markScanEnd();
7168
+ const engineLatencies = {};
7169
+ for (const [engineId, latencies] of engineLatencyMap.entries()) {
7170
+ if (latencies.length > 0) {
7171
+ const sorted = [...latencies].sort((a, b) => a - b);
7172
+ const p95Idx = Math.ceil(sorted.length * 0.95) - 1;
7173
+ engineLatencies[engineId] = sorted[Math.max(0, p95Idx)] ?? 0;
7174
+ }
7175
+ }
7176
+ const snapshot = perfTracker.createSnapshot(
7177
+ summary.filesScanned,
7178
+ cacheHits,
7179
+ cacheMisses,
7180
+ engineLatencies
7181
+ );
7182
+ await perfTracker.saveSnapshot(snapshot);
7183
+ }
7184
+ if (changeDetector) {
7185
+ await saveLastScanTime(workspaceRoot);
7186
+ }
6533
7187
  emitProgress({
6534
7188
  phase: "complete",
6535
7189
  filesDiscovered: files.length,
@@ -6576,7 +7230,7 @@ __name(filterInlineSuppressions, "filterInlineSuppressions");
6576
7230
  function makeSkippedResult(file, workspaceRoot, reason) {
6577
7231
  return {
6578
7232
  file,
6579
- relativePath: path2.relative(workspaceRoot, file).replace(/\\/g, "/"),
7233
+ relativePath: path5.relative(workspaceRoot, file).replace(/\\/g, "/"),
6580
7234
  findings: [],
6581
7235
  engineMetrics: [],
6582
7236
  scanDurationMs: 0,