@clef-sh/core 0.1.17 → 0.1.19

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 (56) hide show
  1. package/dist/artifact/guards.d.ts +40 -0
  2. package/dist/artifact/guards.d.ts.map +1 -0
  3. package/dist/artifact/packer.d.ts.map +1 -1
  4. package/dist/artifact/types.d.ts +11 -2
  5. package/dist/artifact/types.d.ts.map +1 -1
  6. package/dist/compliance/generator.d.ts.map +1 -1
  7. package/dist/compliance/run.d.ts +19 -0
  8. package/dist/compliance/run.d.ts.map +1 -1
  9. package/dist/git/integration.d.ts +8 -5
  10. package/dist/git/integration.d.ts.map +1 -1
  11. package/dist/hsm/bundled.d.ts +10 -0
  12. package/dist/hsm/bundled.d.ts.map +1 -0
  13. package/dist/hsm/index.d.ts +4 -0
  14. package/dist/hsm/index.d.ts.map +1 -0
  15. package/dist/hsm/keyservice.d.ts +36 -0
  16. package/dist/hsm/keyservice.d.ts.map +1 -0
  17. package/dist/hsm/resolver.d.ts +22 -0
  18. package/dist/hsm/resolver.d.ts.map +1 -0
  19. package/dist/import/index.d.ts +7 -0
  20. package/dist/import/index.d.ts.map +1 -1
  21. package/dist/index.d.mts +14 -4
  22. package/dist/index.d.ts +14 -4
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +1129 -385
  25. package/dist/index.js.map +4 -4
  26. package/dist/index.mjs +1107 -381
  27. package/dist/index.mjs.map +4 -4
  28. package/dist/lint/runner.d.ts +7 -0
  29. package/dist/lint/runner.d.ts.map +1 -1
  30. package/dist/manifest/parser.d.ts.map +1 -1
  31. package/dist/merge/metadata-driver.d.ts +17 -0
  32. package/dist/merge/metadata-driver.d.ts.map +1 -0
  33. package/dist/migration/backend.d.ts.map +1 -1
  34. package/dist/pack/backends/json-envelope.d.ts +33 -0
  35. package/dist/pack/backends/json-envelope.d.ts.map +1 -0
  36. package/dist/pack/registry.d.ts +27 -0
  37. package/dist/pack/registry.d.ts.map +1 -0
  38. package/dist/pack/types.d.ts +78 -0
  39. package/dist/pack/types.d.ts.map +1 -0
  40. package/dist/pending/metadata.d.ts +40 -15
  41. package/dist/pending/metadata.d.ts.map +1 -1
  42. package/dist/policy/evaluator.d.ts +19 -9
  43. package/dist/policy/evaluator.d.ts.map +1 -1
  44. package/dist/policy/types.d.ts +40 -9
  45. package/dist/policy/types.d.ts.map +1 -1
  46. package/dist/scanner/index.d.ts +9 -1
  47. package/dist/scanner/index.d.ts.map +1 -1
  48. package/dist/scanner/patterns.d.ts +12 -0
  49. package/dist/scanner/patterns.d.ts.map +1 -1
  50. package/dist/sops/client.d.ts +11 -1
  51. package/dist/sops/client.d.ts.map +1 -1
  52. package/dist/sops/hsm-arn.d.ts +51 -0
  53. package/dist/sops/hsm-arn.d.ts.map +1 -0
  54. package/dist/types/index.d.ts +18 -2
  55. package/dist/types/index.d.ts.map +1 -1
  56. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -301,13 +301,13 @@ var require_lib = __commonJS({
301
301
  "node_modules/write-file-atomic/lib/index.js"(exports2, module2) {
302
302
  "use strict";
303
303
  module2.exports = writeFile;
304
- module2.exports.sync = writeFileSync6;
304
+ module2.exports.sync = writeFileSync7;
305
305
  module2.exports._getTmpname = getTmpname;
306
306
  module2.exports._cleanupOnExit = cleanupOnExit;
307
- var fs18 = require("fs");
307
+ var fs21 = require("fs");
308
308
  var crypto5 = require("node:crypto");
309
309
  var { onExit } = require_cjs();
310
- var path26 = require("path");
310
+ var path28 = require("path");
311
311
  var { promisify } = require("util");
312
312
  var activeFiles = {};
313
313
  var threadId = (function getId() {
@@ -325,7 +325,7 @@ var require_lib = __commonJS({
325
325
  function cleanupOnExit(tmpfile) {
326
326
  return () => {
327
327
  try {
328
- fs18.unlinkSync(typeof tmpfile === "function" ? tmpfile() : tmpfile);
328
+ fs21.unlinkSync(typeof tmpfile === "function" ? tmpfile() : tmpfile);
329
329
  } catch {
330
330
  }
331
331
  };
@@ -360,13 +360,13 @@ var require_lib = __commonJS({
360
360
  let fd;
361
361
  let tmpfile;
362
362
  const removeOnExitHandler = onExit(cleanupOnExit(() => tmpfile));
363
- const absoluteName = path26.resolve(filename);
363
+ const absoluteName = path28.resolve(filename);
364
364
  try {
365
365
  await serializeActiveFile(absoluteName);
366
- const truename = await promisify(fs18.realpath)(filename).catch(() => filename);
366
+ const truename = await promisify(fs21.realpath)(filename).catch(() => filename);
367
367
  tmpfile = getTmpname(truename);
368
368
  if (!options.mode || !options.chown) {
369
- const stats = await promisify(fs18.stat)(truename).catch(() => {
369
+ const stats = await promisify(fs21.stat)(truename).catch(() => {
370
370
  });
371
371
  if (stats) {
372
372
  if (options.mode == null) {
@@ -377,45 +377,45 @@ var require_lib = __commonJS({
377
377
  }
378
378
  }
379
379
  }
380
- fd = await promisify(fs18.open)(tmpfile, "w", options.mode);
380
+ fd = await promisify(fs21.open)(tmpfile, "w", options.mode);
381
381
  if (options.tmpfileCreated) {
382
382
  await options.tmpfileCreated(tmpfile);
383
383
  }
384
384
  if (ArrayBuffer.isView(data)) {
385
- await promisify(fs18.write)(fd, data, 0, data.length, 0);
385
+ await promisify(fs21.write)(fd, data, 0, data.length, 0);
386
386
  } else if (data != null) {
387
- await promisify(fs18.write)(fd, String(data), 0, String(options.encoding || "utf8"));
387
+ await promisify(fs21.write)(fd, String(data), 0, String(options.encoding || "utf8"));
388
388
  }
389
389
  if (options.fsync !== false) {
390
- await promisify(fs18.fsync)(fd);
390
+ await promisify(fs21.fsync)(fd);
391
391
  }
392
- await promisify(fs18.close)(fd);
392
+ await promisify(fs21.close)(fd);
393
393
  fd = null;
394
394
  if (options.chown) {
395
- await promisify(fs18.chown)(tmpfile, options.chown.uid, options.chown.gid).catch((err) => {
395
+ await promisify(fs21.chown)(tmpfile, options.chown.uid, options.chown.gid).catch((err) => {
396
396
  if (!isChownErrOk(err)) {
397
397
  throw err;
398
398
  }
399
399
  });
400
400
  }
401
401
  if (options.mode) {
402
- await promisify(fs18.chmod)(tmpfile, options.mode).catch((err) => {
402
+ await promisify(fs21.chmod)(tmpfile, options.mode).catch((err) => {
403
403
  if (!isChownErrOk(err)) {
404
404
  throw err;
405
405
  }
406
406
  });
407
407
  }
408
- await promisify(fs18.rename)(tmpfile, truename);
408
+ await promisify(fs21.rename)(tmpfile, truename);
409
409
  } finally {
410
410
  if (fd) {
411
- await promisify(fs18.close)(fd).catch(
411
+ await promisify(fs21.close)(fd).catch(
412
412
  /* istanbul ignore next */
413
413
  () => {
414
414
  }
415
415
  );
416
416
  }
417
417
  removeOnExitHandler();
418
- await promisify(fs18.unlink)(tmpfile).catch(() => {
418
+ await promisify(fs21.unlink)(tmpfile).catch(() => {
419
419
  });
420
420
  activeFiles[absoluteName].shift();
421
421
  if (activeFiles[absoluteName].length > 0) {
@@ -441,20 +441,20 @@ var require_lib = __commonJS({
441
441
  }
442
442
  return promise;
443
443
  }
444
- function writeFileSync6(filename, data, options) {
444
+ function writeFileSync7(filename, data, options) {
445
445
  if (typeof options === "string") {
446
446
  options = { encoding: options };
447
447
  } else if (!options) {
448
448
  options = {};
449
449
  }
450
450
  try {
451
- filename = fs18.realpathSync(filename);
451
+ filename = fs21.realpathSync(filename);
452
452
  } catch (ex) {
453
453
  }
454
454
  const tmpfile = getTmpname(filename);
455
455
  if (!options.mode || !options.chown) {
456
456
  try {
457
- const stats = fs18.statSync(filename);
457
+ const stats = fs21.statSync(filename);
458
458
  options = Object.assign({}, options);
459
459
  if (!options.mode) {
460
460
  options.mode = stats.mode;
@@ -470,23 +470,23 @@ var require_lib = __commonJS({
470
470
  const removeOnExitHandler = onExit(cleanup);
471
471
  let threw = true;
472
472
  try {
473
- fd = fs18.openSync(tmpfile, "w", options.mode || 438);
473
+ fd = fs21.openSync(tmpfile, "w", options.mode || 438);
474
474
  if (options.tmpfileCreated) {
475
475
  options.tmpfileCreated(tmpfile);
476
476
  }
477
477
  if (ArrayBuffer.isView(data)) {
478
- fs18.writeSync(fd, data, 0, data.length, 0);
478
+ fs21.writeSync(fd, data, 0, data.length, 0);
479
479
  } else if (data != null) {
480
- fs18.writeSync(fd, String(data), 0, String(options.encoding || "utf8"));
480
+ fs21.writeSync(fd, String(data), 0, String(options.encoding || "utf8"));
481
481
  }
482
482
  if (options.fsync !== false) {
483
- fs18.fsyncSync(fd);
483
+ fs21.fsyncSync(fd);
484
484
  }
485
- fs18.closeSync(fd);
485
+ fs21.closeSync(fd);
486
486
  fd = null;
487
487
  if (options.chown) {
488
488
  try {
489
- fs18.chownSync(tmpfile, options.chown.uid, options.chown.gid);
489
+ fs21.chownSync(tmpfile, options.chown.uid, options.chown.gid);
490
490
  } catch (err) {
491
491
  if (!isChownErrOk(err)) {
492
492
  throw err;
@@ -495,19 +495,19 @@ var require_lib = __commonJS({
495
495
  }
496
496
  if (options.mode) {
497
497
  try {
498
- fs18.chmodSync(tmpfile, options.mode);
498
+ fs21.chmodSync(tmpfile, options.mode);
499
499
  } catch (err) {
500
500
  if (!isChownErrOk(err)) {
501
501
  throw err;
502
502
  }
503
503
  }
504
504
  }
505
- fs18.renameSync(tmpfile, filename);
505
+ fs21.renameSync(tmpfile, filename);
506
506
  threw = false;
507
507
  } finally {
508
508
  if (fd) {
509
509
  try {
510
- fs18.closeSync(fd);
510
+ fs21.closeSync(fd);
511
511
  } catch (ex) {
512
512
  }
513
513
  }
@@ -546,54 +546,54 @@ var require_polyfills = __commonJS({
546
546
  }
547
547
  var chdir;
548
548
  module2.exports = patch;
549
- function patch(fs18) {
549
+ function patch(fs21) {
550
550
  if (constants.hasOwnProperty("O_SYMLINK") && process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) {
551
- patchLchmod(fs18);
552
- }
553
- if (!fs18.lutimes) {
554
- patchLutimes(fs18);
555
- }
556
- fs18.chown = chownFix(fs18.chown);
557
- fs18.fchown = chownFix(fs18.fchown);
558
- fs18.lchown = chownFix(fs18.lchown);
559
- fs18.chmod = chmodFix(fs18.chmod);
560
- fs18.fchmod = chmodFix(fs18.fchmod);
561
- fs18.lchmod = chmodFix(fs18.lchmod);
562
- fs18.chownSync = chownFixSync(fs18.chownSync);
563
- fs18.fchownSync = chownFixSync(fs18.fchownSync);
564
- fs18.lchownSync = chownFixSync(fs18.lchownSync);
565
- fs18.chmodSync = chmodFixSync(fs18.chmodSync);
566
- fs18.fchmodSync = chmodFixSync(fs18.fchmodSync);
567
- fs18.lchmodSync = chmodFixSync(fs18.lchmodSync);
568
- fs18.stat = statFix(fs18.stat);
569
- fs18.fstat = statFix(fs18.fstat);
570
- fs18.lstat = statFix(fs18.lstat);
571
- fs18.statSync = statFixSync(fs18.statSync);
572
- fs18.fstatSync = statFixSync(fs18.fstatSync);
573
- fs18.lstatSync = statFixSync(fs18.lstatSync);
574
- if (fs18.chmod && !fs18.lchmod) {
575
- fs18.lchmod = function(path26, mode, cb) {
551
+ patchLchmod(fs21);
552
+ }
553
+ if (!fs21.lutimes) {
554
+ patchLutimes(fs21);
555
+ }
556
+ fs21.chown = chownFix(fs21.chown);
557
+ fs21.fchown = chownFix(fs21.fchown);
558
+ fs21.lchown = chownFix(fs21.lchown);
559
+ fs21.chmod = chmodFix(fs21.chmod);
560
+ fs21.fchmod = chmodFix(fs21.fchmod);
561
+ fs21.lchmod = chmodFix(fs21.lchmod);
562
+ fs21.chownSync = chownFixSync(fs21.chownSync);
563
+ fs21.fchownSync = chownFixSync(fs21.fchownSync);
564
+ fs21.lchownSync = chownFixSync(fs21.lchownSync);
565
+ fs21.chmodSync = chmodFixSync(fs21.chmodSync);
566
+ fs21.fchmodSync = chmodFixSync(fs21.fchmodSync);
567
+ fs21.lchmodSync = chmodFixSync(fs21.lchmodSync);
568
+ fs21.stat = statFix(fs21.stat);
569
+ fs21.fstat = statFix(fs21.fstat);
570
+ fs21.lstat = statFix(fs21.lstat);
571
+ fs21.statSync = statFixSync(fs21.statSync);
572
+ fs21.fstatSync = statFixSync(fs21.fstatSync);
573
+ fs21.lstatSync = statFixSync(fs21.lstatSync);
574
+ if (fs21.chmod && !fs21.lchmod) {
575
+ fs21.lchmod = function(path28, mode, cb) {
576
576
  if (cb) process.nextTick(cb);
577
577
  };
578
- fs18.lchmodSync = function() {
578
+ fs21.lchmodSync = function() {
579
579
  };
580
580
  }
581
- if (fs18.chown && !fs18.lchown) {
582
- fs18.lchown = function(path26, uid, gid, cb) {
581
+ if (fs21.chown && !fs21.lchown) {
582
+ fs21.lchown = function(path28, uid, gid, cb) {
583
583
  if (cb) process.nextTick(cb);
584
584
  };
585
- fs18.lchownSync = function() {
585
+ fs21.lchownSync = function() {
586
586
  };
587
587
  }
588
588
  if (platform === "win32") {
589
- fs18.rename = typeof fs18.rename !== "function" ? fs18.rename : (function(fs$rename) {
589
+ fs21.rename = typeof fs21.rename !== "function" ? fs21.rename : (function(fs$rename) {
590
590
  function rename(from, to, cb) {
591
591
  var start = Date.now();
592
592
  var backoff = 0;
593
593
  fs$rename(from, to, function CB(er) {
594
594
  if (er && (er.code === "EACCES" || er.code === "EPERM" || er.code === "EBUSY") && Date.now() - start < 6e4) {
595
595
  setTimeout(function() {
596
- fs18.stat(to, function(stater, st) {
596
+ fs21.stat(to, function(stater, st) {
597
597
  if (stater && stater.code === "ENOENT")
598
598
  fs$rename(from, to, CB);
599
599
  else
@@ -609,9 +609,9 @@ var require_polyfills = __commonJS({
609
609
  }
610
610
  if (Object.setPrototypeOf) Object.setPrototypeOf(rename, fs$rename);
611
611
  return rename;
612
- })(fs18.rename);
612
+ })(fs21.rename);
613
613
  }
614
- fs18.read = typeof fs18.read !== "function" ? fs18.read : (function(fs$read) {
614
+ fs21.read = typeof fs21.read !== "function" ? fs21.read : (function(fs$read) {
615
615
  function read(fd, buffer, offset, length, position, callback_) {
616
616
  var callback;
617
617
  if (callback_ && typeof callback_ === "function") {
@@ -619,22 +619,22 @@ var require_polyfills = __commonJS({
619
619
  callback = function(er, _, __) {
620
620
  if (er && er.code === "EAGAIN" && eagCounter < 10) {
621
621
  eagCounter++;
622
- return fs$read.call(fs18, fd, buffer, offset, length, position, callback);
622
+ return fs$read.call(fs21, fd, buffer, offset, length, position, callback);
623
623
  }
624
624
  callback_.apply(this, arguments);
625
625
  };
626
626
  }
627
- return fs$read.call(fs18, fd, buffer, offset, length, position, callback);
627
+ return fs$read.call(fs21, fd, buffer, offset, length, position, callback);
628
628
  }
629
629
  if (Object.setPrototypeOf) Object.setPrototypeOf(read, fs$read);
630
630
  return read;
631
- })(fs18.read);
632
- fs18.readSync = typeof fs18.readSync !== "function" ? fs18.readSync : /* @__PURE__ */ (function(fs$readSync) {
631
+ })(fs21.read);
632
+ fs21.readSync = typeof fs21.readSync !== "function" ? fs21.readSync : /* @__PURE__ */ (function(fs$readSync) {
633
633
  return function(fd, buffer, offset, length, position) {
634
634
  var eagCounter = 0;
635
635
  while (true) {
636
636
  try {
637
- return fs$readSync.call(fs18, fd, buffer, offset, length, position);
637
+ return fs$readSync.call(fs21, fd, buffer, offset, length, position);
638
638
  } catch (er) {
639
639
  if (er.code === "EAGAIN" && eagCounter < 10) {
640
640
  eagCounter++;
@@ -644,11 +644,11 @@ var require_polyfills = __commonJS({
644
644
  }
645
645
  }
646
646
  };
647
- })(fs18.readSync);
648
- function patchLchmod(fs19) {
649
- fs19.lchmod = function(path26, mode, callback) {
650
- fs19.open(
651
- path26,
647
+ })(fs21.readSync);
648
+ function patchLchmod(fs22) {
649
+ fs22.lchmod = function(path28, mode, callback) {
650
+ fs22.open(
651
+ path28,
652
652
  constants.O_WRONLY | constants.O_SYMLINK,
653
653
  mode,
654
654
  function(err, fd) {
@@ -656,80 +656,80 @@ var require_polyfills = __commonJS({
656
656
  if (callback) callback(err);
657
657
  return;
658
658
  }
659
- fs19.fchmod(fd, mode, function(err2) {
660
- fs19.close(fd, function(err22) {
659
+ fs22.fchmod(fd, mode, function(err2) {
660
+ fs22.close(fd, function(err22) {
661
661
  if (callback) callback(err2 || err22);
662
662
  });
663
663
  });
664
664
  }
665
665
  );
666
666
  };
667
- fs19.lchmodSync = function(path26, mode) {
668
- var fd = fs19.openSync(path26, constants.O_WRONLY | constants.O_SYMLINK, mode);
667
+ fs22.lchmodSync = function(path28, mode) {
668
+ var fd = fs22.openSync(path28, constants.O_WRONLY | constants.O_SYMLINK, mode);
669
669
  var threw = true;
670
670
  var ret;
671
671
  try {
672
- ret = fs19.fchmodSync(fd, mode);
672
+ ret = fs22.fchmodSync(fd, mode);
673
673
  threw = false;
674
674
  } finally {
675
675
  if (threw) {
676
676
  try {
677
- fs19.closeSync(fd);
677
+ fs22.closeSync(fd);
678
678
  } catch (er) {
679
679
  }
680
680
  } else {
681
- fs19.closeSync(fd);
681
+ fs22.closeSync(fd);
682
682
  }
683
683
  }
684
684
  return ret;
685
685
  };
686
686
  }
687
- function patchLutimes(fs19) {
688
- if (constants.hasOwnProperty("O_SYMLINK") && fs19.futimes) {
689
- fs19.lutimes = function(path26, at, mt, cb) {
690
- fs19.open(path26, constants.O_SYMLINK, function(er, fd) {
687
+ function patchLutimes(fs22) {
688
+ if (constants.hasOwnProperty("O_SYMLINK") && fs22.futimes) {
689
+ fs22.lutimes = function(path28, at, mt, cb) {
690
+ fs22.open(path28, constants.O_SYMLINK, function(er, fd) {
691
691
  if (er) {
692
692
  if (cb) cb(er);
693
693
  return;
694
694
  }
695
- fs19.futimes(fd, at, mt, function(er2) {
696
- fs19.close(fd, function(er22) {
695
+ fs22.futimes(fd, at, mt, function(er2) {
696
+ fs22.close(fd, function(er22) {
697
697
  if (cb) cb(er2 || er22);
698
698
  });
699
699
  });
700
700
  });
701
701
  };
702
- fs19.lutimesSync = function(path26, at, mt) {
703
- var fd = fs19.openSync(path26, constants.O_SYMLINK);
702
+ fs22.lutimesSync = function(path28, at, mt) {
703
+ var fd = fs22.openSync(path28, constants.O_SYMLINK);
704
704
  var ret;
705
705
  var threw = true;
706
706
  try {
707
- ret = fs19.futimesSync(fd, at, mt);
707
+ ret = fs22.futimesSync(fd, at, mt);
708
708
  threw = false;
709
709
  } finally {
710
710
  if (threw) {
711
711
  try {
712
- fs19.closeSync(fd);
712
+ fs22.closeSync(fd);
713
713
  } catch (er) {
714
714
  }
715
715
  } else {
716
- fs19.closeSync(fd);
716
+ fs22.closeSync(fd);
717
717
  }
718
718
  }
719
719
  return ret;
720
720
  };
721
- } else if (fs19.futimes) {
722
- fs19.lutimes = function(_a, _b, _c, cb) {
721
+ } else if (fs22.futimes) {
722
+ fs22.lutimes = function(_a, _b, _c, cb) {
723
723
  if (cb) process.nextTick(cb);
724
724
  };
725
- fs19.lutimesSync = function() {
725
+ fs22.lutimesSync = function() {
726
726
  };
727
727
  }
728
728
  }
729
729
  function chmodFix(orig) {
730
730
  if (!orig) return orig;
731
731
  return function(target, mode, cb) {
732
- return orig.call(fs18, target, mode, function(er) {
732
+ return orig.call(fs21, target, mode, function(er) {
733
733
  if (chownErOk(er)) er = null;
734
734
  if (cb) cb.apply(this, arguments);
735
735
  });
@@ -739,7 +739,7 @@ var require_polyfills = __commonJS({
739
739
  if (!orig) return orig;
740
740
  return function(target, mode) {
741
741
  try {
742
- return orig.call(fs18, target, mode);
742
+ return orig.call(fs21, target, mode);
743
743
  } catch (er) {
744
744
  if (!chownErOk(er)) throw er;
745
745
  }
@@ -748,7 +748,7 @@ var require_polyfills = __commonJS({
748
748
  function chownFix(orig) {
749
749
  if (!orig) return orig;
750
750
  return function(target, uid, gid, cb) {
751
- return orig.call(fs18, target, uid, gid, function(er) {
751
+ return orig.call(fs21, target, uid, gid, function(er) {
752
752
  if (chownErOk(er)) er = null;
753
753
  if (cb) cb.apply(this, arguments);
754
754
  });
@@ -758,7 +758,7 @@ var require_polyfills = __commonJS({
758
758
  if (!orig) return orig;
759
759
  return function(target, uid, gid) {
760
760
  try {
761
- return orig.call(fs18, target, uid, gid);
761
+ return orig.call(fs21, target, uid, gid);
762
762
  } catch (er) {
763
763
  if (!chownErOk(er)) throw er;
764
764
  }
@@ -778,13 +778,13 @@ var require_polyfills = __commonJS({
778
778
  }
779
779
  if (cb) cb.apply(this, arguments);
780
780
  }
781
- return options ? orig.call(fs18, target, options, callback) : orig.call(fs18, target, callback);
781
+ return options ? orig.call(fs21, target, options, callback) : orig.call(fs21, target, callback);
782
782
  };
783
783
  }
784
784
  function statFixSync(orig) {
785
785
  if (!orig) return orig;
786
786
  return function(target, options) {
787
- var stats = options ? orig.call(fs18, target, options) : orig.call(fs18, target);
787
+ var stats = options ? orig.call(fs21, target, options) : orig.call(fs21, target);
788
788
  if (stats) {
789
789
  if (stats.uid < 0) stats.uid += 4294967296;
790
790
  if (stats.gid < 0) stats.gid += 4294967296;
@@ -813,16 +813,16 @@ var require_legacy_streams = __commonJS({
813
813
  "../../node_modules/graceful-fs/legacy-streams.js"(exports2, module2) {
814
814
  var Stream = require("stream").Stream;
815
815
  module2.exports = legacy;
816
- function legacy(fs18) {
816
+ function legacy(fs21) {
817
817
  return {
818
818
  ReadStream,
819
819
  WriteStream
820
820
  };
821
- function ReadStream(path26, options) {
822
- if (!(this instanceof ReadStream)) return new ReadStream(path26, options);
821
+ function ReadStream(path28, options) {
822
+ if (!(this instanceof ReadStream)) return new ReadStream(path28, options);
823
823
  Stream.call(this);
824
824
  var self = this;
825
- this.path = path26;
825
+ this.path = path28;
826
826
  this.fd = null;
827
827
  this.readable = true;
828
828
  this.paused = false;
@@ -856,7 +856,7 @@ var require_legacy_streams = __commonJS({
856
856
  });
857
857
  return;
858
858
  }
859
- fs18.open(this.path, this.flags, this.mode, function(err, fd) {
859
+ fs21.open(this.path, this.flags, this.mode, function(err, fd) {
860
860
  if (err) {
861
861
  self.emit("error", err);
862
862
  self.readable = false;
@@ -867,10 +867,10 @@ var require_legacy_streams = __commonJS({
867
867
  self._read();
868
868
  });
869
869
  }
870
- function WriteStream(path26, options) {
871
- if (!(this instanceof WriteStream)) return new WriteStream(path26, options);
870
+ function WriteStream(path28, options) {
871
+ if (!(this instanceof WriteStream)) return new WriteStream(path28, options);
872
872
  Stream.call(this);
873
- this.path = path26;
873
+ this.path = path28;
874
874
  this.fd = null;
875
875
  this.writable = true;
876
876
  this.flags = "w";
@@ -895,7 +895,7 @@ var require_legacy_streams = __commonJS({
895
895
  this.busy = false;
896
896
  this._queue = [];
897
897
  if (this.fd === null) {
898
- this._open = fs18.open;
898
+ this._open = fs21.open;
899
899
  this._queue.push([this._open, this.path, this.flags, this.mode, void 0]);
900
900
  this.flush();
901
901
  }
@@ -930,7 +930,7 @@ var require_clone = __commonJS({
930
930
  // ../../node_modules/graceful-fs/graceful-fs.js
931
931
  var require_graceful_fs = __commonJS({
932
932
  "../../node_modules/graceful-fs/graceful-fs.js"(exports2, module2) {
933
- var fs18 = require("fs");
933
+ var fs21 = require("fs");
934
934
  var polyfills = require_polyfills();
935
935
  var legacy = require_legacy_streams();
936
936
  var clone = require_clone();
@@ -962,12 +962,12 @@ var require_graceful_fs = __commonJS({
962
962
  m = "GFS4: " + m.split(/\n/).join("\nGFS4: ");
963
963
  console.error(m);
964
964
  };
965
- if (!fs18[gracefulQueue]) {
965
+ if (!fs21[gracefulQueue]) {
966
966
  queue = global[gracefulQueue] || [];
967
- publishQueue(fs18, queue);
968
- fs18.close = (function(fs$close) {
967
+ publishQueue(fs21, queue);
968
+ fs21.close = (function(fs$close) {
969
969
  function close(fd, cb) {
970
- return fs$close.call(fs18, fd, function(err) {
970
+ return fs$close.call(fs21, fd, function(err) {
971
971
  if (!err) {
972
972
  resetQueue();
973
973
  }
@@ -979,48 +979,48 @@ var require_graceful_fs = __commonJS({
979
979
  value: fs$close
980
980
  });
981
981
  return close;
982
- })(fs18.close);
983
- fs18.closeSync = (function(fs$closeSync) {
982
+ })(fs21.close);
983
+ fs21.closeSync = (function(fs$closeSync) {
984
984
  function closeSync2(fd) {
985
- fs$closeSync.apply(fs18, arguments);
985
+ fs$closeSync.apply(fs21, arguments);
986
986
  resetQueue();
987
987
  }
988
988
  Object.defineProperty(closeSync2, previousSymbol, {
989
989
  value: fs$closeSync
990
990
  });
991
991
  return closeSync2;
992
- })(fs18.closeSync);
992
+ })(fs21.closeSync);
993
993
  if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || "")) {
994
994
  process.on("exit", function() {
995
- debug(fs18[gracefulQueue]);
996
- require("assert").equal(fs18[gracefulQueue].length, 0);
995
+ debug(fs21[gracefulQueue]);
996
+ require("assert").equal(fs21[gracefulQueue].length, 0);
997
997
  });
998
998
  }
999
999
  }
1000
1000
  var queue;
1001
1001
  if (!global[gracefulQueue]) {
1002
- publishQueue(global, fs18[gracefulQueue]);
1003
- }
1004
- module2.exports = patch(clone(fs18));
1005
- if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs18.__patched) {
1006
- module2.exports = patch(fs18);
1007
- fs18.__patched = true;
1008
- }
1009
- function patch(fs19) {
1010
- polyfills(fs19);
1011
- fs19.gracefulify = patch;
1012
- fs19.createReadStream = createReadStream;
1013
- fs19.createWriteStream = createWriteStream;
1014
- var fs$readFile = fs19.readFile;
1015
- fs19.readFile = readFile;
1016
- function readFile(path26, options, cb) {
1002
+ publishQueue(global, fs21[gracefulQueue]);
1003
+ }
1004
+ module2.exports = patch(clone(fs21));
1005
+ if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs21.__patched) {
1006
+ module2.exports = patch(fs21);
1007
+ fs21.__patched = true;
1008
+ }
1009
+ function patch(fs22) {
1010
+ polyfills(fs22);
1011
+ fs22.gracefulify = patch;
1012
+ fs22.createReadStream = createReadStream;
1013
+ fs22.createWriteStream = createWriteStream;
1014
+ var fs$readFile = fs22.readFile;
1015
+ fs22.readFile = readFile;
1016
+ function readFile(path28, options, cb) {
1017
1017
  if (typeof options === "function")
1018
1018
  cb = options, options = null;
1019
- return go$readFile(path26, options, cb);
1020
- function go$readFile(path27, options2, cb2, startTime) {
1021
- return fs$readFile(path27, options2, function(err) {
1019
+ return go$readFile(path28, options, cb);
1020
+ function go$readFile(path29, options2, cb2, startTime) {
1021
+ return fs$readFile(path29, options2, function(err) {
1022
1022
  if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
1023
- enqueue([go$readFile, [path27, options2, cb2], err, startTime || Date.now(), Date.now()]);
1023
+ enqueue([go$readFile, [path29, options2, cb2], err, startTime || Date.now(), Date.now()]);
1024
1024
  else {
1025
1025
  if (typeof cb2 === "function")
1026
1026
  cb2.apply(this, arguments);
@@ -1028,16 +1028,16 @@ var require_graceful_fs = __commonJS({
1028
1028
  });
1029
1029
  }
1030
1030
  }
1031
- var fs$writeFile = fs19.writeFile;
1032
- fs19.writeFile = writeFile;
1033
- function writeFile(path26, data, options, cb) {
1031
+ var fs$writeFile = fs22.writeFile;
1032
+ fs22.writeFile = writeFile;
1033
+ function writeFile(path28, data, options, cb) {
1034
1034
  if (typeof options === "function")
1035
1035
  cb = options, options = null;
1036
- return go$writeFile(path26, data, options, cb);
1037
- function go$writeFile(path27, data2, options2, cb2, startTime) {
1038
- return fs$writeFile(path27, data2, options2, function(err) {
1036
+ return go$writeFile(path28, data, options, cb);
1037
+ function go$writeFile(path29, data2, options2, cb2, startTime) {
1038
+ return fs$writeFile(path29, data2, options2, function(err) {
1039
1039
  if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
1040
- enqueue([go$writeFile, [path27, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
1040
+ enqueue([go$writeFile, [path29, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
1041
1041
  else {
1042
1042
  if (typeof cb2 === "function")
1043
1043
  cb2.apply(this, arguments);
@@ -1045,17 +1045,17 @@ var require_graceful_fs = __commonJS({
1045
1045
  });
1046
1046
  }
1047
1047
  }
1048
- var fs$appendFile = fs19.appendFile;
1048
+ var fs$appendFile = fs22.appendFile;
1049
1049
  if (fs$appendFile)
1050
- fs19.appendFile = appendFile;
1051
- function appendFile(path26, data, options, cb) {
1050
+ fs22.appendFile = appendFile;
1051
+ function appendFile(path28, data, options, cb) {
1052
1052
  if (typeof options === "function")
1053
1053
  cb = options, options = null;
1054
- return go$appendFile(path26, data, options, cb);
1055
- function go$appendFile(path27, data2, options2, cb2, startTime) {
1056
- return fs$appendFile(path27, data2, options2, function(err) {
1054
+ return go$appendFile(path28, data, options, cb);
1055
+ function go$appendFile(path29, data2, options2, cb2, startTime) {
1056
+ return fs$appendFile(path29, data2, options2, function(err) {
1057
1057
  if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
1058
- enqueue([go$appendFile, [path27, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
1058
+ enqueue([go$appendFile, [path29, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
1059
1059
  else {
1060
1060
  if (typeof cb2 === "function")
1061
1061
  cb2.apply(this, arguments);
@@ -1063,9 +1063,9 @@ var require_graceful_fs = __commonJS({
1063
1063
  });
1064
1064
  }
1065
1065
  }
1066
- var fs$copyFile = fs19.copyFile;
1066
+ var fs$copyFile = fs22.copyFile;
1067
1067
  if (fs$copyFile)
1068
- fs19.copyFile = copyFile;
1068
+ fs22.copyFile = copyFile;
1069
1069
  function copyFile(src, dest, flags, cb) {
1070
1070
  if (typeof flags === "function") {
1071
1071
  cb = flags;
@@ -1083,34 +1083,34 @@ var require_graceful_fs = __commonJS({
1083
1083
  });
1084
1084
  }
1085
1085
  }
1086
- var fs$readdir = fs19.readdir;
1087
- fs19.readdir = readdir;
1086
+ var fs$readdir = fs22.readdir;
1087
+ fs22.readdir = readdir;
1088
1088
  var noReaddirOptionVersions = /^v[0-5]\./;
1089
- function readdir(path26, options, cb) {
1089
+ function readdir(path28, options, cb) {
1090
1090
  if (typeof options === "function")
1091
1091
  cb = options, options = null;
1092
- var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir2(path27, options2, cb2, startTime) {
1093
- return fs$readdir(path27, fs$readdirCallback(
1094
- path27,
1092
+ var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir2(path29, options2, cb2, startTime) {
1093
+ return fs$readdir(path29, fs$readdirCallback(
1094
+ path29,
1095
1095
  options2,
1096
1096
  cb2,
1097
1097
  startTime
1098
1098
  ));
1099
- } : function go$readdir2(path27, options2, cb2, startTime) {
1100
- return fs$readdir(path27, options2, fs$readdirCallback(
1101
- path27,
1099
+ } : function go$readdir2(path29, options2, cb2, startTime) {
1100
+ return fs$readdir(path29, options2, fs$readdirCallback(
1101
+ path29,
1102
1102
  options2,
1103
1103
  cb2,
1104
1104
  startTime
1105
1105
  ));
1106
1106
  };
1107
- return go$readdir(path26, options, cb);
1108
- function fs$readdirCallback(path27, options2, cb2, startTime) {
1107
+ return go$readdir(path28, options, cb);
1108
+ function fs$readdirCallback(path29, options2, cb2, startTime) {
1109
1109
  return function(err, files) {
1110
1110
  if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
1111
1111
  enqueue([
1112
1112
  go$readdir,
1113
- [path27, options2, cb2],
1113
+ [path29, options2, cb2],
1114
1114
  err,
1115
1115
  startTime || Date.now(),
1116
1116
  Date.now()
@@ -1125,21 +1125,21 @@ var require_graceful_fs = __commonJS({
1125
1125
  }
1126
1126
  }
1127
1127
  if (process.version.substr(0, 4) === "v0.8") {
1128
- var legStreams = legacy(fs19);
1128
+ var legStreams = legacy(fs22);
1129
1129
  ReadStream = legStreams.ReadStream;
1130
1130
  WriteStream = legStreams.WriteStream;
1131
1131
  }
1132
- var fs$ReadStream = fs19.ReadStream;
1132
+ var fs$ReadStream = fs22.ReadStream;
1133
1133
  if (fs$ReadStream) {
1134
1134
  ReadStream.prototype = Object.create(fs$ReadStream.prototype);
1135
1135
  ReadStream.prototype.open = ReadStream$open;
1136
1136
  }
1137
- var fs$WriteStream = fs19.WriteStream;
1137
+ var fs$WriteStream = fs22.WriteStream;
1138
1138
  if (fs$WriteStream) {
1139
1139
  WriteStream.prototype = Object.create(fs$WriteStream.prototype);
1140
1140
  WriteStream.prototype.open = WriteStream$open;
1141
1141
  }
1142
- Object.defineProperty(fs19, "ReadStream", {
1142
+ Object.defineProperty(fs22, "ReadStream", {
1143
1143
  get: function() {
1144
1144
  return ReadStream;
1145
1145
  },
@@ -1149,7 +1149,7 @@ var require_graceful_fs = __commonJS({
1149
1149
  enumerable: true,
1150
1150
  configurable: true
1151
1151
  });
1152
- Object.defineProperty(fs19, "WriteStream", {
1152
+ Object.defineProperty(fs22, "WriteStream", {
1153
1153
  get: function() {
1154
1154
  return WriteStream;
1155
1155
  },
@@ -1160,7 +1160,7 @@ var require_graceful_fs = __commonJS({
1160
1160
  configurable: true
1161
1161
  });
1162
1162
  var FileReadStream = ReadStream;
1163
- Object.defineProperty(fs19, "FileReadStream", {
1163
+ Object.defineProperty(fs22, "FileReadStream", {
1164
1164
  get: function() {
1165
1165
  return FileReadStream;
1166
1166
  },
@@ -1171,7 +1171,7 @@ var require_graceful_fs = __commonJS({
1171
1171
  configurable: true
1172
1172
  });
1173
1173
  var FileWriteStream = WriteStream;
1174
- Object.defineProperty(fs19, "FileWriteStream", {
1174
+ Object.defineProperty(fs22, "FileWriteStream", {
1175
1175
  get: function() {
1176
1176
  return FileWriteStream;
1177
1177
  },
@@ -1181,7 +1181,7 @@ var require_graceful_fs = __commonJS({
1181
1181
  enumerable: true,
1182
1182
  configurable: true
1183
1183
  });
1184
- function ReadStream(path26, options) {
1184
+ function ReadStream(path28, options) {
1185
1185
  if (this instanceof ReadStream)
1186
1186
  return fs$ReadStream.apply(this, arguments), this;
1187
1187
  else
@@ -1201,7 +1201,7 @@ var require_graceful_fs = __commonJS({
1201
1201
  }
1202
1202
  });
1203
1203
  }
1204
- function WriteStream(path26, options) {
1204
+ function WriteStream(path28, options) {
1205
1205
  if (this instanceof WriteStream)
1206
1206
  return fs$WriteStream.apply(this, arguments), this;
1207
1207
  else
@@ -1219,22 +1219,22 @@ var require_graceful_fs = __commonJS({
1219
1219
  }
1220
1220
  });
1221
1221
  }
1222
- function createReadStream(path26, options) {
1223
- return new fs19.ReadStream(path26, options);
1222
+ function createReadStream(path28, options) {
1223
+ return new fs22.ReadStream(path28, options);
1224
1224
  }
1225
- function createWriteStream(path26, options) {
1226
- return new fs19.WriteStream(path26, options);
1225
+ function createWriteStream(path28, options) {
1226
+ return new fs22.WriteStream(path28, options);
1227
1227
  }
1228
- var fs$open = fs19.open;
1229
- fs19.open = open;
1230
- function open(path26, flags, mode, cb) {
1228
+ var fs$open = fs22.open;
1229
+ fs22.open = open;
1230
+ function open(path28, flags, mode, cb) {
1231
1231
  if (typeof mode === "function")
1232
1232
  cb = mode, mode = null;
1233
- return go$open(path26, flags, mode, cb);
1234
- function go$open(path27, flags2, mode2, cb2, startTime) {
1235
- return fs$open(path27, flags2, mode2, function(err, fd) {
1233
+ return go$open(path28, flags, mode, cb);
1234
+ function go$open(path29, flags2, mode2, cb2, startTime) {
1235
+ return fs$open(path29, flags2, mode2, function(err, fd) {
1236
1236
  if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
1237
- enqueue([go$open, [path27, flags2, mode2, cb2], err, startTime || Date.now(), Date.now()]);
1237
+ enqueue([go$open, [path29, flags2, mode2, cb2], err, startTime || Date.now(), Date.now()]);
1238
1238
  else {
1239
1239
  if (typeof cb2 === "function")
1240
1240
  cb2.apply(this, arguments);
@@ -1242,20 +1242,20 @@ var require_graceful_fs = __commonJS({
1242
1242
  });
1243
1243
  }
1244
1244
  }
1245
- return fs19;
1245
+ return fs22;
1246
1246
  }
1247
1247
  function enqueue(elem) {
1248
1248
  debug("ENQUEUE", elem[0].name, elem[1]);
1249
- fs18[gracefulQueue].push(elem);
1249
+ fs21[gracefulQueue].push(elem);
1250
1250
  retry();
1251
1251
  }
1252
1252
  var retryTimer;
1253
1253
  function resetQueue() {
1254
1254
  var now = Date.now();
1255
- for (var i = 0; i < fs18[gracefulQueue].length; ++i) {
1256
- if (fs18[gracefulQueue][i].length > 2) {
1257
- fs18[gracefulQueue][i][3] = now;
1258
- fs18[gracefulQueue][i][4] = now;
1255
+ for (var i = 0; i < fs21[gracefulQueue].length; ++i) {
1256
+ if (fs21[gracefulQueue][i].length > 2) {
1257
+ fs21[gracefulQueue][i][3] = now;
1258
+ fs21[gracefulQueue][i][4] = now;
1259
1259
  }
1260
1260
  }
1261
1261
  retry();
@@ -1263,9 +1263,9 @@ var require_graceful_fs = __commonJS({
1263
1263
  function retry() {
1264
1264
  clearTimeout(retryTimer);
1265
1265
  retryTimer = void 0;
1266
- if (fs18[gracefulQueue].length === 0)
1266
+ if (fs21[gracefulQueue].length === 0)
1267
1267
  return;
1268
- var elem = fs18[gracefulQueue].shift();
1268
+ var elem = fs21[gracefulQueue].shift();
1269
1269
  var fn = elem[0];
1270
1270
  var args = elem[1];
1271
1271
  var err = elem[2];
@@ -1287,7 +1287,7 @@ var require_graceful_fs = __commonJS({
1287
1287
  debug("RETRY", fn.name, args);
1288
1288
  fn.apply(null, args.concat([startTime]));
1289
1289
  } else {
1290
- fs18[gracefulQueue].push(elem);
1290
+ fs21[gracefulQueue].push(elem);
1291
1291
  }
1292
1292
  }
1293
1293
  if (retryTimer === void 0) {
@@ -1722,10 +1722,10 @@ var require_mtime_precision = __commonJS({
1722
1722
  "../../node_modules/proper-lockfile/lib/mtime-precision.js"(exports2, module2) {
1723
1723
  "use strict";
1724
1724
  var cacheSymbol = /* @__PURE__ */ Symbol();
1725
- function probe(file, fs18, callback) {
1726
- const cachedPrecision = fs18[cacheSymbol];
1725
+ function probe(file, fs21, callback) {
1726
+ const cachedPrecision = fs21[cacheSymbol];
1727
1727
  if (cachedPrecision) {
1728
- return fs18.stat(file, (err, stat) => {
1728
+ return fs21.stat(file, (err, stat) => {
1729
1729
  if (err) {
1730
1730
  return callback(err);
1731
1731
  }
@@ -1733,16 +1733,16 @@ var require_mtime_precision = __commonJS({
1733
1733
  });
1734
1734
  }
1735
1735
  const mtime = new Date(Math.ceil(Date.now() / 1e3) * 1e3 + 5);
1736
- fs18.utimes(file, mtime, mtime, (err) => {
1736
+ fs21.utimes(file, mtime, mtime, (err) => {
1737
1737
  if (err) {
1738
1738
  return callback(err);
1739
1739
  }
1740
- fs18.stat(file, (err2, stat) => {
1740
+ fs21.stat(file, (err2, stat) => {
1741
1741
  if (err2) {
1742
1742
  return callback(err2);
1743
1743
  }
1744
1744
  const precision = stat.mtime.getTime() % 1e3 === 0 ? "s" : "ms";
1745
- Object.defineProperty(fs18, cacheSymbol, { value: precision });
1745
+ Object.defineProperty(fs21, cacheSymbol, { value: precision });
1746
1746
  callback(null, stat.mtime, precision);
1747
1747
  });
1748
1748
  });
@@ -1763,8 +1763,8 @@ var require_mtime_precision = __commonJS({
1763
1763
  var require_lockfile = __commonJS({
1764
1764
  "../../node_modules/proper-lockfile/lib/lockfile.js"(exports2, module2) {
1765
1765
  "use strict";
1766
- var path26 = require("path");
1767
- var fs18 = require_graceful_fs();
1766
+ var path28 = require("path");
1767
+ var fs21 = require_graceful_fs();
1768
1768
  var retry = require_retry2();
1769
1769
  var onExit = require_signal_exit();
1770
1770
  var mtimePrecision = require_mtime_precision();
@@ -1774,7 +1774,7 @@ var require_lockfile = __commonJS({
1774
1774
  }
1775
1775
  function resolveCanonicalPath(file, options, callback) {
1776
1776
  if (!options.realpath) {
1777
- return callback(null, path26.resolve(file));
1777
+ return callback(null, path28.resolve(file));
1778
1778
  }
1779
1779
  options.fs.realpath(file, callback);
1780
1780
  }
@@ -1895,7 +1895,7 @@ var require_lockfile = __commonJS({
1895
1895
  update: null,
1896
1896
  realpath: true,
1897
1897
  retries: 0,
1898
- fs: fs18,
1898
+ fs: fs21,
1899
1899
  onCompromised: (err) => {
1900
1900
  throw err;
1901
1901
  },
@@ -1939,7 +1939,7 @@ var require_lockfile = __commonJS({
1939
1939
  }
1940
1940
  function unlock(file, options, callback) {
1941
1941
  options = {
1942
- fs: fs18,
1942
+ fs: fs21,
1943
1943
  realpath: true,
1944
1944
  ...options
1945
1945
  };
@@ -1961,7 +1961,7 @@ var require_lockfile = __commonJS({
1961
1961
  options = {
1962
1962
  stale: 1e4,
1963
1963
  realpath: true,
1964
- fs: fs18,
1964
+ fs: fs21,
1965
1965
  ...options
1966
1966
  };
1967
1967
  options.stale = Math.max(options.stale || 0, 2e3);
@@ -2000,16 +2000,16 @@ var require_lockfile = __commonJS({
2000
2000
  var require_adapter = __commonJS({
2001
2001
  "../../node_modules/proper-lockfile/lib/adapter.js"(exports2, module2) {
2002
2002
  "use strict";
2003
- var fs18 = require_graceful_fs();
2004
- function createSyncFs(fs19) {
2003
+ var fs21 = require_graceful_fs();
2004
+ function createSyncFs(fs22) {
2005
2005
  const methods = ["mkdir", "realpath", "stat", "rmdir", "utimes"];
2006
- const newFs = { ...fs19 };
2006
+ const newFs = { ...fs22 };
2007
2007
  methods.forEach((method) => {
2008
2008
  newFs[method] = (...args) => {
2009
2009
  const callback = args.pop();
2010
2010
  let ret;
2011
2011
  try {
2012
- ret = fs19[`${method}Sync`](...args);
2012
+ ret = fs22[`${method}Sync`](...args);
2013
2013
  } catch (err) {
2014
2014
  return callback(err);
2015
2015
  }
@@ -2047,7 +2047,7 @@ var require_adapter = __commonJS({
2047
2047
  }
2048
2048
  function toSyncOptions(options) {
2049
2049
  options = { ...options };
2050
- options.fs = createSyncFs(options.fs || fs18);
2050
+ options.fs = createSyncFs(options.fs || fs21);
2051
2051
  if (typeof options.retries === "number" && options.retries > 0 || options.retries && typeof options.retries.retries === "number" && options.retries.retries > 0) {
2052
2052
  throw Object.assign(new Error("Cannot use retries with the sync api"), { code: "ESYNC" });
2053
2053
  }
@@ -2702,7 +2702,7 @@ var require_age_encryption = __commonJS({
2702
2702
  };
2703
2703
  }
2704
2704
  // @__NO_SIDE_EFFECTS__
2705
- function join19(separator = "") {
2705
+ function join20(separator = "") {
2706
2706
  astr("join", separator);
2707
2707
  return {
2708
2708
  encode: (from) => {
@@ -2832,9 +2832,9 @@ var require_age_encryption = __commonJS({
2832
2832
  decode(s) {
2833
2833
  return decodeBase64Builtin(s, false);
2834
2834
  }
2835
- } : /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */ join19(""));
2836
- var base64nopad = /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ join19(""));
2837
- var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join19(""));
2835
+ } : /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */ join20(""));
2836
+ var base64nopad = /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ join20(""));
2837
+ var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join20(""));
2838
2838
  var POLYMOD_GENERATORS = [996825010, 642813549, 513874426, 1027748829, 705979059];
2839
2839
  function bech32Polymod(pre) {
2840
2840
  const b = pre >> 25;
@@ -9030,11 +9030,14 @@ __export(index_exports, {
9030
9030
  GitIntegration: () => GitIntegration,
9031
9031
  GitOperationError: () => GitOperationError,
9032
9032
  ImportRunner: () => ImportRunner,
9033
+ InvalidArtifactError: () => InvalidArtifactError,
9034
+ JsonEnvelopeBackend: () => JsonEnvelopeBackend,
9033
9035
  LintRunner: () => LintRunner,
9034
9036
  ManifestParser: () => ManifestParser,
9035
9037
  ManifestValidationError: () => ManifestValidationError,
9036
9038
  MatrixManager: () => MatrixManager,
9037
9039
  MemoryPackOutput: () => MemoryPackOutput,
9040
+ PackBackendRegistry: () => PackBackendRegistry,
9038
9041
  PolicyEvaluator: () => PolicyEvaluator,
9039
9042
  PolicyParser: () => PolicyParser,
9040
9043
  PolicyValidationError: () => PolicyValidationError,
@@ -9063,6 +9066,7 @@ __export(index_exports, {
9063
9066
  TransactionPreflightError: () => TransactionPreflightError,
9064
9067
  TransactionRollbackError: () => TransactionRollbackError,
9065
9068
  VALID_KMS_PROVIDERS: () => VALID_KMS_PROVIDERS,
9069
+ assertPackedArtifact: () => assertPackedArtifact,
9066
9070
  assertSops: () => assertSops,
9067
9071
  buildSigningPayload: () => buildSigningPayload,
9068
9072
  checkAll: () => checkAll,
@@ -9078,8 +9082,11 @@ __export(index_exports, {
9078
9082
  generateRandomValue: () => generateRandomValue,
9079
9083
  generateSigningKeyPair: () => generateSigningKeyPair,
9080
9084
  getPendingKeys: () => getPendingKeys,
9085
+ getRotations: () => getRotations,
9086
+ isClefHsmArn: () => isClefHsmArn,
9081
9087
  isHighEntropy: () => isHighEntropy,
9082
9088
  isKmsEnvelope: () => isKmsEnvelope,
9089
+ isPackedArtifact: () => isPackedArtifact,
9083
9090
  isPending: () => isPending,
9084
9091
  keyPreview: () => keyPreview,
9085
9092
  loadIgnoreRules: () => loadIgnoreRules,
@@ -9089,19 +9096,26 @@ __export(index_exports, {
9089
9096
  markPendingWithRetry: () => markPendingWithRetry,
9090
9097
  markResolved: () => markResolved,
9091
9098
  matchPatterns: () => matchPatterns,
9099
+ mergeMetadataContents: () => mergeMetadataContents,
9100
+ mergeMetadataFiles: () => mergeMetadataFiles,
9092
9101
  metadataPath: () => metadataPath,
9093
9102
  parse: () => parse9,
9094
9103
  parseDotenv: () => parseDotenv,
9095
9104
  parseIgnoreContent: () => parseIgnoreContent,
9096
9105
  parseJson: () => parseJson,
9097
9106
  parseYaml: () => parseYaml,
9107
+ pkcs11UriToSyntheticArn: () => pkcs11UriToSyntheticArn,
9098
9108
  readManifestYaml: () => readManifestYaml,
9109
+ recordRotation: () => recordRotation,
9099
9110
  redactValue: () => redactValue,
9100
9111
  removeAccessRequest: () => removeRequest,
9112
+ removeRotation: () => removeRotation,
9101
9113
  requestsFilePath: () => requestsFilePath,
9114
+ resetKeyserviceResolution: () => resetKeyserviceResolution,
9102
9115
  resetSopsResolution: () => resetSopsResolution,
9103
9116
  resolveBackendConfig: () => resolveBackendConfig,
9104
9117
  resolveIdentitySecrets: () => resolveIdentitySecrets,
9118
+ resolveKeyservicePath: () => resolveKeyservicePath,
9105
9119
  resolveRecipientsForEnvironment: () => resolveRecipientsForEnvironment,
9106
9120
  resolveSopsPath: () => resolveSopsPath,
9107
9121
  runCompliance: () => runCompliance,
@@ -9112,8 +9126,12 @@ __export(index_exports, {
9112
9126
  shouldIgnoreMatch: () => shouldIgnoreMatch,
9113
9127
  signEd25519: () => signEd25519,
9114
9128
  signKms: () => signKms,
9129
+ spawnKeyservice: () => spawnKeyservice,
9130
+ syntheticArnToPkcs11Uri: () => syntheticArnToPkcs11Uri,
9131
+ tryBundledKeyservice: () => tryBundledKeyservice,
9115
9132
  upsertRequest: () => upsertRequest,
9116
9133
  validateAgePublicKey: () => validateAgePublicKey,
9134
+ validatePackedArtifact: () => validatePackedArtifact,
9117
9135
  validateResetScope: () => validateResetScope,
9118
9136
  verifySignature: () => verifySignature,
9119
9137
  writeManifestYaml: () => writeManifestYaml,
@@ -9131,7 +9149,8 @@ function resolveBackendConfig(manifest, environment) {
9131
9149
  aws_kms_arn: manifest.sops.aws_kms_arn,
9132
9150
  gcp_kms_resource_id: manifest.sops.gcp_kms_resource_id,
9133
9151
  azure_kv_url: manifest.sops.azure_kv_url,
9134
- pgp_fingerprint: manifest.sops.pgp_fingerprint
9152
+ pgp_fingerprint: manifest.sops.pgp_fingerprint,
9153
+ pkcs11_uri: manifest.sops.pkcs11_uri
9135
9154
  };
9136
9155
  }
9137
9156
  function resolveRecipientsForEnvironment(manifest, environment) {
@@ -9278,7 +9297,8 @@ function keyPreview(key) {
9278
9297
 
9279
9298
  // src/manifest/parser.ts
9280
9299
  var CLEF_MANIFEST_FILENAME = "clef.yaml";
9281
- var VALID_BACKENDS = ["age", "awskms", "gcpkms", "azurekv", "pgp"];
9300
+ var VALID_BACKENDS = ["age", "awskms", "gcpkms", "azurekv", "pgp", "hsm"];
9301
+ var PKCS11_URI_PATTERN = /^pkcs11:[a-zA-Z][a-zA-Z0-9_-]*=[^;]+/;
9282
9302
  var VALID_TOP_LEVEL_KEYS = [
9283
9303
  "version",
9284
9304
  "environments",
@@ -9437,12 +9457,27 @@ var ManifestParser = class {
9437
9457
  "environments"
9438
9458
  );
9439
9459
  }
9460
+ if (backend === "hsm") {
9461
+ if (typeof sopsOverride.pkcs11_uri !== "string") {
9462
+ throw new ManifestValidationError(
9463
+ `Environment '${envObj.name}' uses 'hsm' backend but is missing 'pkcs11_uri'.`,
9464
+ "environments"
9465
+ );
9466
+ }
9467
+ if (!PKCS11_URI_PATTERN.test(sopsOverride.pkcs11_uri)) {
9468
+ throw new ManifestValidationError(
9469
+ `Environment '${envObj.name}' has an invalid 'pkcs11_uri' '${sopsOverride.pkcs11_uri}'. Must start with 'pkcs11:' and contain at least one attribute (e.g. 'pkcs11:slot=0;label=clef-dek-wrapper').`,
9470
+ "environments"
9471
+ );
9472
+ }
9473
+ }
9440
9474
  result.sops = {
9441
9475
  backend,
9442
9476
  ...typeof sopsOverride.aws_kms_arn === "string" ? { aws_kms_arn: sopsOverride.aws_kms_arn } : {},
9443
9477
  ...typeof sopsOverride.gcp_kms_resource_id === "string" ? { gcp_kms_resource_id: sopsOverride.gcp_kms_resource_id } : {},
9444
9478
  ...typeof sopsOverride.azure_kv_url === "string" ? { azure_kv_url: sopsOverride.azure_kv_url } : {},
9445
- ...typeof sopsOverride.pgp_fingerprint === "string" ? { pgp_fingerprint: sopsOverride.pgp_fingerprint } : {}
9479
+ ...typeof sopsOverride.pgp_fingerprint === "string" ? { pgp_fingerprint: sopsOverride.pgp_fingerprint } : {},
9480
+ ...typeof sopsOverride.pkcs11_uri === "string" ? { pkcs11_uri: sopsOverride.pkcs11_uri } : {}
9446
9481
  };
9447
9482
  }
9448
9483
  if (envObj.recipients !== void 0) {
@@ -9574,7 +9609,7 @@ var ManifestParser = class {
9574
9609
  const sopsObj = obj.sops;
9575
9610
  if (!sopsObj.default_backend || typeof sopsObj.default_backend !== "string") {
9576
9611
  throw new ManifestValidationError(
9577
- "Field 'sops.default_backend' is required and must be one of: age, awskms, gcpkms, azurekv, pgp.",
9612
+ `Field 'sops.default_backend' is required and must be one of: ${VALID_BACKENDS.join(", ")}.`,
9578
9613
  "sops.default_backend"
9579
9614
  );
9580
9615
  }
@@ -9601,13 +9636,32 @@ var ManifestParser = class {
9601
9636
  })
9602
9637
  }
9603
9638
  } : {};
9639
+ if (sopsObj.pkcs11_uri !== void 0 && typeof sopsObj.pkcs11_uri !== "string") {
9640
+ throw new ManifestValidationError(
9641
+ "Field 'sops.pkcs11_uri' must be a string.",
9642
+ "sops.pkcs11_uri"
9643
+ );
9644
+ }
9645
+ if (typeof sopsObj.pkcs11_uri === "string" && !PKCS11_URI_PATTERN.test(sopsObj.pkcs11_uri)) {
9646
+ throw new ManifestValidationError(
9647
+ `Field 'sops.pkcs11_uri' has invalid format '${sopsObj.pkcs11_uri}'. Must start with 'pkcs11:' and contain at least one attribute (e.g. 'pkcs11:slot=0;label=clef-dek-wrapper').`,
9648
+ "sops.pkcs11_uri"
9649
+ );
9650
+ }
9651
+ if (sopsObj.default_backend === "hsm" && typeof sopsObj.pkcs11_uri !== "string") {
9652
+ throw new ManifestValidationError(
9653
+ "Field 'sops.pkcs11_uri' is required when sops.default_backend is 'hsm'.",
9654
+ "sops.pkcs11_uri"
9655
+ );
9656
+ }
9604
9657
  const sopsConfig = {
9605
9658
  default_backend: sopsObj.default_backend,
9606
9659
  ...parsedAge,
9607
9660
  ...typeof sopsObj.aws_kms_arn === "string" ? { aws_kms_arn: sopsObj.aws_kms_arn } : {},
9608
9661
  ...typeof sopsObj.gcp_kms_resource_id === "string" ? { gcp_kms_resource_id: sopsObj.gcp_kms_resource_id } : {},
9609
9662
  ...typeof sopsObj.azure_kv_url === "string" ? { azure_kv_url: sopsObj.azure_kv_url } : {},
9610
- ...typeof sopsObj.pgp_fingerprint === "string" ? { pgp_fingerprint: sopsObj.pgp_fingerprint } : {}
9663
+ ...typeof sopsObj.pgp_fingerprint === "string" ? { pgp_fingerprint: sopsObj.pgp_fingerprint } : {},
9664
+ ...typeof sopsObj.pkcs11_uri === "string" ? { pkcs11_uri: sopsObj.pkcs11_uri } : {}
9611
9665
  };
9612
9666
  for (const env of environments) {
9613
9667
  if (env.recipients && env.recipients.length > 0) {
@@ -9866,6 +9920,20 @@ var PATTERNS = [
9866
9920
  },
9867
9921
  { name: "Database URL", regex: /(?:postgres|mysql|mongodb|redis):\/\/[^:]+:[^@]+@/ }
9868
9922
  ];
9923
+ var PUBLIC_PREFIX_PATTERNS = [
9924
+ // reCAPTCHA v2, v3, and Enterprise site keys are exactly 40 chars and
9925
+ // begin with 6L[c-f]. Site keys are designed to be embedded in HTML.
9926
+ // https://developers.google.com/recaptcha/docs/faq
9927
+ { name: "reCAPTCHA site key", regex: /^6L[c-f][0-9A-Za-z_-]{37}$/ },
9928
+ // Stripe publishable keys (client-side, distinct from sk_live_/sk_test_).
9929
+ { name: "Stripe publishable key", regex: /^pk_(?:live|test)_[0-9a-zA-Z]{24,}$/ }
9930
+ ];
9931
+ function matchPublicPrefix(value) {
9932
+ for (const def of PUBLIC_PREFIX_PATTERNS) {
9933
+ if (def.regex.test(value)) return { name: def.name };
9934
+ }
9935
+ return null;
9936
+ }
9869
9937
  function shannonEntropy(str) {
9870
9938
  if (str.length === 0) return 0;
9871
9939
  const freq = /* @__PURE__ */ new Map();
@@ -10054,7 +10122,8 @@ var ScanRunner = class {
10054
10122
  }
10055
10123
  }
10056
10124
  if (options.severity !== "high") {
10057
- const entropyHit = this.detectEntropy(line, lineNum, relPath);
10125
+ const allowPublic = options.publicAllowlist !== false;
10126
+ const entropyHit = this.detectEntropy(line, lineNum, relPath, allowPublic);
10058
10127
  if (entropyHit && !shouldIgnoreMatch(entropyHit, ignoreRules)) {
10059
10128
  matches.push(entropyHit);
10060
10129
  }
@@ -10095,13 +10164,14 @@ var ScanRunner = class {
10095
10164
  return false;
10096
10165
  }
10097
10166
  }
10098
- detectEntropy(line, lineNum, filePath) {
10167
+ detectEntropy(line, lineNum, filePath, allowPublic) {
10099
10168
  const valuePattern = /(?:=|:\s*)["']?([A-Za-z0-9+/=_-]{20,})["']?/;
10100
10169
  const match = valuePattern.exec(line);
10101
10170
  if (!match) return null;
10102
10171
  const value = match[1];
10103
10172
  const entropy = shannonEntropy(value);
10104
10173
  if (!isHighEntropy(value)) return null;
10174
+ if (allowPublic && matchPublicPrefix(value)) return null;
10105
10175
  const varMatch = /(\w+)\s*(?:=|:)/.exec(line);
10106
10176
  const varName = varMatch ? varMatch[1] : "";
10107
10177
  const preview = varName ? `${varName}=\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022` : redactValue(value);
@@ -10183,41 +10253,50 @@ function metadataPath(encryptedFilePath) {
10183
10253
  return path4.join(dir, `${base}.clef-meta.yaml`);
10184
10254
  }
10185
10255
  var HEADER_COMMENT = "# Managed by Clef. Do not edit manually.\n";
10256
+ function emptyMetadata() {
10257
+ return { version: 1, pending: [], rotations: [] };
10258
+ }
10186
10259
  async function loadMetadata(filePath) {
10187
10260
  const metaPath = metadataPath(filePath);
10188
10261
  try {
10189
- if (!fs5.existsSync(metaPath)) {
10190
- return { version: 1, pending: [] };
10191
- }
10262
+ if (!fs5.existsSync(metaPath)) return emptyMetadata();
10192
10263
  const content = fs5.readFileSync(metaPath, "utf-8");
10193
10264
  const parsed = YAML3.parse(content);
10194
- if (!parsed || !Array.isArray(parsed.pending)) {
10195
- return { version: 1, pending: [] };
10196
- }
10197
- return {
10198
- version: 1,
10199
- pending: parsed.pending.map((p) => ({
10200
- key: p.key,
10201
- since: new Date(p.since),
10202
- setBy: p.setBy
10203
- }))
10204
- };
10265
+ if (!parsed || typeof parsed !== "object") return emptyMetadata();
10266
+ const pendingRaw = Array.isArray(parsed.pending) ? parsed.pending : [];
10267
+ const pending = pendingRaw.filter(
10268
+ (p) => !!p && typeof p === "object" && typeof p.key === "string" && typeof p.since === "string" && typeof p.setBy === "string"
10269
+ ).map((p) => ({ key: p.key, since: new Date(p.since), setBy: p.setBy }));
10270
+ const rotationsRaw = Array.isArray(parsed.rotations) ? parsed.rotations : [];
10271
+ const rotations = rotationsRaw.filter(
10272
+ (r) => !!r && typeof r === "object" && typeof r.key === "string" && typeof r.last_rotated_at === "string" && typeof r.rotated_by === "string" && typeof r.rotation_count === "number"
10273
+ ).map((r) => ({
10274
+ key: r.key,
10275
+ lastRotatedAt: new Date(r.last_rotated_at),
10276
+ rotatedBy: r.rotated_by,
10277
+ rotationCount: r.rotation_count
10278
+ }));
10279
+ return { version: 1, pending, rotations };
10205
10280
  } catch {
10206
- return { version: 1, pending: [] };
10281
+ return emptyMetadata();
10207
10282
  }
10208
10283
  }
10209
10284
  async function saveMetadata(filePath, metadata) {
10210
10285
  const metaPath = metadataPath(filePath);
10211
10286
  const dir = path4.dirname(metaPath);
10212
- if (!fs5.existsSync(dir)) {
10213
- fs5.mkdirSync(dir, { recursive: true });
10214
- }
10287
+ if (!fs5.existsSync(dir)) fs5.mkdirSync(dir, { recursive: true });
10215
10288
  const data = {
10216
10289
  version: metadata.version,
10217
10290
  pending: metadata.pending.map((p) => ({
10218
10291
  key: p.key,
10219
10292
  since: p.since.toISOString(),
10220
10293
  setBy: p.setBy
10294
+ })),
10295
+ rotations: metadata.rotations.map((r) => ({
10296
+ key: r.key,
10297
+ last_rotated_at: r.lastRotatedAt.toISOString(),
10298
+ rotated_by: r.rotatedBy,
10299
+ rotation_count: r.rotationCount
10221
10300
  }))
10222
10301
  };
10223
10302
  fs5.writeFileSync(metaPath, HEADER_COMMENT + YAML3.stringify(data), "utf-8");
@@ -10248,6 +10327,38 @@ async function isPending(filePath, key) {
10248
10327
  const metadata = await loadMetadata(filePath);
10249
10328
  return metadata.pending.some((p) => p.key === key);
10250
10329
  }
10330
+ async function recordRotation(filePath, keys, rotatedBy, now = /* @__PURE__ */ new Date()) {
10331
+ const metadata = await loadMetadata(filePath);
10332
+ for (const key of keys) {
10333
+ const existing = metadata.rotations.findIndex((r) => r.key === key);
10334
+ if (existing >= 0) {
10335
+ metadata.rotations[existing] = {
10336
+ key,
10337
+ lastRotatedAt: now,
10338
+ rotatedBy,
10339
+ rotationCount: metadata.rotations[existing].rotationCount + 1
10340
+ };
10341
+ } else {
10342
+ metadata.rotations.push({
10343
+ key,
10344
+ lastRotatedAt: now,
10345
+ rotatedBy,
10346
+ rotationCount: 1
10347
+ });
10348
+ }
10349
+ }
10350
+ metadata.pending = metadata.pending.filter((p) => !keys.includes(p.key));
10351
+ await saveMetadata(filePath, metadata);
10352
+ }
10353
+ async function removeRotation(filePath, keys) {
10354
+ const metadata = await loadMetadata(filePath);
10355
+ metadata.rotations = metadata.rotations.filter((r) => !keys.includes(r.key));
10356
+ await saveMetadata(filePath, metadata);
10357
+ }
10358
+ async function getRotations(filePath) {
10359
+ const metadata = await loadMetadata(filePath);
10360
+ return metadata.rotations;
10361
+ }
10251
10362
  function generateRandomValue() {
10252
10363
  return crypto2.randomBytes(32).toString("hex");
10253
10364
  }
@@ -11049,61 +11160,83 @@ var GitIntegration = class {
11049
11160
  * @throws {@link GitOperationError} On failure.
11050
11161
  */
11051
11162
  async installMergeDriver(repoRoot) {
11052
- const configResult = await this.runner.run(
11053
- "git",
11054
- ["config", "merge.sops.name", "SOPS-aware merge driver"],
11055
- { cwd: repoRoot }
11056
- );
11057
- if (configResult.exitCode !== 0) {
11058
- throw new GitOperationError(
11059
- `Failed to configure merge driver name: ${configResult.stderr.trim()}`,
11060
- "Ensure you are inside a git repository."
11163
+ const drivers = [
11164
+ { config: "merge.sops", friendly: "SOPS-aware merge driver" },
11165
+ { config: "merge.clef-metadata", friendly: "Clef metadata merge driver" }
11166
+ ];
11167
+ for (const driver of drivers) {
11168
+ const nameResult = await this.runner.run(
11169
+ "git",
11170
+ ["config", `${driver.config}.name`, driver.friendly],
11171
+ { cwd: repoRoot }
11061
11172
  );
11062
- }
11063
- const driverResult = await this.runner.run(
11064
- "git",
11065
- ["config", "merge.sops.driver", "clef merge-driver %O %A %B"],
11066
- { cwd: repoRoot }
11067
- );
11068
- if (driverResult.exitCode !== 0) {
11069
- throw new GitOperationError(
11070
- `Failed to configure merge driver command: ${driverResult.stderr.trim()}`,
11071
- "Ensure you are inside a git repository."
11173
+ if (nameResult.exitCode !== 0) {
11174
+ throw new GitOperationError(
11175
+ `Failed to configure merge driver name: ${nameResult.stderr.trim()}`,
11176
+ "Ensure you are inside a git repository."
11177
+ );
11178
+ }
11179
+ const driverResult = await this.runner.run(
11180
+ "git",
11181
+ ["config", `${driver.config}.driver`, "clef merge-driver %O %A %B"],
11182
+ { cwd: repoRoot }
11072
11183
  );
11184
+ if (driverResult.exitCode !== 0) {
11185
+ throw new GitOperationError(
11186
+ `Failed to configure merge driver command: ${driverResult.stderr.trim()}`,
11187
+ "Ensure you are inside a git repository."
11188
+ );
11189
+ }
11073
11190
  }
11074
11191
  await this.ensureGitattributes(repoRoot);
11075
11192
  }
11076
11193
  /**
11077
- * Check whether the SOPS merge driver is configured in both
11078
- * `.git/config` and `.gitattributes`.
11079
- *
11080
- * @param repoRoot - Absolute path to the repository root.
11081
- * @returns An object indicating which parts are configured.
11194
+ * Check whether both Clef merge drivers are configured in `.git/config`
11195
+ * and `.gitattributes`. Reports separately on the SOPS driver
11196
+ * (`merge=sops` for `.enc.*`) and the metadata driver
11197
+ * (`merge=clef-metadata` for `.clef-meta.yaml`) so `clef doctor` can
11198
+ * prompt the user to run `clef hooks` when only the SOPS driver is
11199
+ * installed (older install, pre-metadata-merge).
11082
11200
  */
11083
11201
  async checkMergeDriver(repoRoot) {
11084
- const configResult = await this.runner.run("git", ["config", "--get", "merge.sops.driver"], {
11202
+ const sopsConfig = await this.runner.run("git", ["config", "--get", "merge.sops.driver"], {
11085
11203
  cwd: repoRoot
11086
11204
  });
11087
- const gitConfig = configResult.exitCode === 0 && configResult.stdout.trim().length > 0;
11205
+ const gitConfig = sopsConfig.exitCode === 0 && sopsConfig.stdout.trim().length > 0;
11206
+ const metaConfig = await this.runner.run(
11207
+ "git",
11208
+ ["config", "--get", "merge.clef-metadata.driver"],
11209
+ { cwd: repoRoot }
11210
+ );
11211
+ const metadataGitConfig = metaConfig.exitCode === 0 && metaConfig.stdout.trim().length > 0;
11088
11212
  const attrFilePath = path8.join(repoRoot, ".gitattributes");
11089
11213
  const attrContent = fs9.existsSync(attrFilePath) ? fs9.readFileSync(attrFilePath, "utf-8") : "";
11090
11214
  const gitattributes = attrContent.includes("merge=sops");
11091
- return { gitConfig, gitattributes };
11215
+ const metadataGitattributes = attrContent.includes("merge=clef-metadata");
11216
+ return { gitConfig, gitattributes, metadataGitConfig, metadataGitattributes };
11092
11217
  }
11093
11218
  async ensureGitattributes(repoRoot) {
11094
11219
  const attrPath = path8.join(repoRoot, ".gitattributes");
11095
- const mergeRule = "*.enc.yaml merge=sops\n*.enc.json merge=sops";
11096
11220
  const existing = fs9.existsSync(attrPath) ? fs9.readFileSync(attrPath, "utf-8") : "";
11097
- if (existing.includes("merge=sops")) {
11098
- return;
11099
- }
11100
- const newContent = existing.trimEnd() ? `${existing.trimEnd()}
11221
+ let newContent = existing;
11222
+ if (!existing.includes("merge=sops")) {
11223
+ const block = `# Clef: SOPS-aware merge driver for encrypted files
11224
+ *.enc.yaml merge=sops
11225
+ *.enc.json merge=sops
11226
+ `;
11227
+ newContent = newContent.trimEnd() ? `${newContent.trimEnd()}
11101
11228
 
11102
- # Clef: SOPS-aware merge driver for encrypted files
11103
- ${mergeRule}
11104
- ` : `# Clef: SOPS-aware merge driver for encrypted files
11105
- ${mergeRule}
11229
+ ${block}` : block;
11230
+ }
11231
+ if (!newContent.includes("merge=clef-metadata")) {
11232
+ const block = `# Clef: rotation-aware merge driver for metadata sidecars
11233
+ *.clef-meta.yaml merge=clef-metadata
11106
11234
  `;
11235
+ newContent = newContent.trimEnd() ? `${newContent.trimEnd()}
11236
+
11237
+ ${block}` : block;
11238
+ }
11239
+ if (newContent === existing) return;
11107
11240
  try {
11108
11241
  fs9.writeFileSync(attrPath, newContent, "utf-8");
11109
11242
  } catch (err) {
@@ -11493,6 +11626,39 @@ ${privateKey}
11493
11626
  `;
11494
11627
  }
11495
11628
 
11629
+ // src/sops/hsm-arn.ts
11630
+ var CLEF_HSM_ARN_RE = /^arn:aws[\w-]*:kms:[^:]+:\d+:alias\/clef-hsm\/(v\d+)\/([A-Za-z0-9_-]+)$/;
11631
+ var ARN_PREFIX = "arn:aws:kms:us-east-1:000000000000:alias/clef-hsm/v1/";
11632
+ var SUPPORTED_VERSION = "v1";
11633
+ function pkcs11UriToSyntheticArn(uri) {
11634
+ if (!uri.startsWith("pkcs11:")) {
11635
+ throw new Error(`Expected a pkcs11 URI starting with 'pkcs11:', got '${uri}'.`);
11636
+ }
11637
+ const payload = Buffer.from(uri, "utf8").toString("base64url");
11638
+ const arn = ARN_PREFIX + payload;
11639
+ if (!CLEF_HSM_ARN_RE.test(arn)) {
11640
+ throw new Error(`Synthesized ARN failed self-validation: '${arn}'.`);
11641
+ }
11642
+ return arn;
11643
+ }
11644
+ function syntheticArnToPkcs11Uri(arn) {
11645
+ const match = CLEF_HSM_ARN_RE.exec(arn);
11646
+ if (!match) return null;
11647
+ const [, version, payload] = match;
11648
+ if (version !== SUPPORTED_VERSION) return null;
11649
+ let decoded;
11650
+ try {
11651
+ decoded = Buffer.from(payload, "base64url").toString("utf8");
11652
+ } catch {
11653
+ return null;
11654
+ }
11655
+ if (!decoded.startsWith("pkcs11:")) return null;
11656
+ return decoded;
11657
+ }
11658
+ function isClefHsmArn(arn) {
11659
+ return CLEF_HSM_ARN_RE.test(arn);
11660
+ }
11661
+
11496
11662
  // src/sops/client.ts
11497
11663
  function formatFromPath(filePath) {
11498
11664
  return filePath.endsWith(".json") ? "json" : "yaml";
@@ -11524,14 +11690,25 @@ var SopsClient = class {
11524
11690
  * to the subprocess environment.
11525
11691
  * @param sopsPath - Optional explicit path to the sops binary. When omitted,
11526
11692
  * resolved automatically via {@link resolveSopsPath}.
11693
+ * @param keyserviceAddr - Optional address of an external SOPS KeyService
11694
+ * sidecar (e.g. `tcp://127.0.0.1:12345`). When set, every SOPS invocation
11695
+ * includes `--enable-local-keyservice=false --keyservice <addr>` so KMS
11696
+ * wrap/unwrap is routed to the sidecar (used for the HSM backend, where
11697
+ * the sidecar is `clef-keyservice` talking PKCS#11 to the HSM).
11698
+ *
11699
+ * The flags are inserted **after** the SOPS subcommand — placing them
11700
+ * before is silently ignored by SOPS (a footgun discovered the first
11701
+ * time we shipped this).
11527
11702
  */
11528
- constructor(runner, ageKeyFile, ageKey, sopsPath) {
11703
+ constructor(runner, ageKeyFile, ageKey, sopsPath, keyserviceAddr) {
11529
11704
  this.runner = runner;
11530
11705
  this.ageKeyFile = ageKeyFile;
11531
11706
  this.ageKey = ageKey;
11532
11707
  this.sopsCommand = sopsPath ?? resolveSopsPath().path;
11708
+ this.keyserviceArgs = keyserviceAddr ? Object.freeze(["--enable-local-keyservice=false", "--keyservice", keyserviceAddr]) : Object.freeze([]);
11533
11709
  }
11534
11710
  sopsCommand;
11711
+ keyserviceArgs;
11535
11712
  buildSopsEnv() {
11536
11713
  const env = {};
11537
11714
  if (this.ageKey) {
@@ -11556,7 +11733,7 @@ var SopsClient = class {
11556
11733
  const env = this.buildSopsEnv();
11557
11734
  const result = await this.runner.run(
11558
11735
  this.sopsCommand,
11559
- ["decrypt", "--output-type", fmt, filePath],
11736
+ ["decrypt", ...this.keyserviceArgs, "--output-type", fmt, filePath],
11560
11737
  {
11561
11738
  ...env ? { env } : {}
11562
11739
  }
@@ -11623,6 +11800,7 @@ var SopsClient = class {
11623
11800
  "--config",
11624
11801
  configPath,
11625
11802
  "encrypt",
11803
+ ...this.keyserviceArgs,
11626
11804
  ...args,
11627
11805
  "--input-type",
11628
11806
  fmt,
@@ -11679,7 +11857,7 @@ var SopsClient = class {
11679
11857
  const env = this.buildSopsEnv();
11680
11858
  const result = await this.runner.run(
11681
11859
  this.sopsCommand,
11682
- ["rotate", "-i", "--add-age", key, filePath],
11860
+ ["rotate", ...this.keyserviceArgs, "-i", "--add-age", key, filePath],
11683
11861
  {
11684
11862
  ...env ? { env } : {}
11685
11863
  }
@@ -11703,7 +11881,7 @@ var SopsClient = class {
11703
11881
  const env = this.buildSopsEnv();
11704
11882
  const result = await this.runner.run(
11705
11883
  this.sopsCommand,
11706
- ["rotate", "-i", "--rm-age", key, filePath],
11884
+ ["rotate", ...this.keyserviceArgs, "-i", "--rm-age", key, filePath],
11707
11885
  {
11708
11886
  ...env ? { env } : {}
11709
11887
  }
@@ -11818,7 +11996,14 @@ var SopsClient = class {
11818
11996
  }
11819
11997
  detectBackend(sops) {
11820
11998
  if (sops.age && Array.isArray(sops.age) && sops.age.length > 0) return "age";
11821
- if (sops.kms && Array.isArray(sops.kms) && sops.kms.length > 0) return "awskms";
11999
+ if (sops.kms && Array.isArray(sops.kms) && sops.kms.length > 0) {
12000
+ const kmsEntries = sops.kms;
12001
+ const firstArn = kmsEntries[0]?.arn;
12002
+ if (typeof firstArn === "string" && isClefHsmArn(firstArn)) {
12003
+ return "hsm";
12004
+ }
12005
+ return "awskms";
12006
+ }
11822
12007
  if (sops.gcp_kms && Array.isArray(sops.gcp_kms) && sops.gcp_kms.length > 0)
11823
12008
  return "gcpkms";
11824
12009
  if (sops.azure_kv && Array.isArray(sops.azure_kv) && sops.azure_kv.length > 0)
@@ -11836,6 +12021,13 @@ var SopsClient = class {
11836
12021
  const entries = sops.kms;
11837
12022
  return entries?.map((e) => String(e.arn ?? "")) ?? [];
11838
12023
  }
12024
+ case "hsm": {
12025
+ const entries = sops.kms;
12026
+ return entries?.map((e) => {
12027
+ const raw = String(e.arn ?? "");
12028
+ return syntheticArnToPkcs11Uri(raw) ?? raw;
12029
+ }) ?? [];
12030
+ }
11839
12031
  case "gcpkms": {
11840
12032
  const entries = sops.gcp_kms;
11841
12033
  return entries?.map((e) => String(e.resource_id ?? "")) ?? [];
@@ -11861,7 +12053,8 @@ var SopsClient = class {
11861
12053
  aws_kms_arn: manifest.sops.aws_kms_arn,
11862
12054
  gcp_kms_resource_id: manifest.sops.gcp_kms_resource_id,
11863
12055
  azure_kv_url: manifest.sops.azure_kv_url,
11864
- pgp_fingerprint: manifest.sops.pgp_fingerprint
12056
+ pgp_fingerprint: manifest.sops.pgp_fingerprint,
12057
+ pkcs11_uri: manifest.sops.pkcs11_uri
11865
12058
  };
11866
12059
  switch (config.backend) {
11867
12060
  case "age": {
@@ -11893,13 +12086,172 @@ var SopsClient = class {
11893
12086
  args.push("--pgp", config.pgp_fingerprint);
11894
12087
  }
11895
12088
  break;
12089
+ case "hsm":
12090
+ if (config.pkcs11_uri) {
12091
+ args.push("--kms", pkcs11UriToSyntheticArn(config.pkcs11_uri));
12092
+ }
12093
+ break;
11896
12094
  }
11897
12095
  return args;
11898
12096
  }
11899
12097
  };
11900
12098
 
11901
- // src/lint/runner.ts
12099
+ // src/hsm/bundled.ts
12100
+ var fs14 = __toESM(require("fs"));
11902
12101
  var path12 = __toESM(require("path"));
12102
+ function tryBundledKeyservice() {
12103
+ const platform = process.platform;
12104
+ const arch = process.arch;
12105
+ const archName = arch === "x64" ? "x64" : arch === "arm64" ? "arm64" : null;
12106
+ if (!archName) return null;
12107
+ const platformName = platform === "darwin" ? "darwin" : platform === "linux" ? "linux" : null;
12108
+ if (!platformName) return null;
12109
+ const packageName = `@clef-sh/keyservice-${platformName}-${archName}`;
12110
+ const binName = "clef-keyservice";
12111
+ try {
12112
+ const packageMain = require.resolve(`${packageName}/package.json`);
12113
+ const packageDir = path12.dirname(packageMain);
12114
+ const binPath = path12.join(packageDir, "bin", binName);
12115
+ return fs14.existsSync(binPath) ? binPath : null;
12116
+ } catch {
12117
+ return null;
12118
+ }
12119
+ }
12120
+
12121
+ // src/hsm/resolver.ts
12122
+ var fs15 = __toESM(require("fs"));
12123
+ var path13 = __toESM(require("path"));
12124
+ function validateKeyservicePath(candidate) {
12125
+ if (!path13.isAbsolute(candidate)) {
12126
+ throw new Error(`CLEF_KEYSERVICE_PATH must be an absolute path, got '${candidate}'.`);
12127
+ }
12128
+ const segments = candidate.split(/[/\\]/);
12129
+ if (segments.includes("..")) {
12130
+ throw new Error(
12131
+ `CLEF_KEYSERVICE_PATH contains '..' path segments ('${candidate}'). Use an absolute path without directory traversal.`
12132
+ );
12133
+ }
12134
+ }
12135
+ var cached2;
12136
+ function resolveKeyservicePath() {
12137
+ if (cached2) return cached2;
12138
+ const envPath = process.env.CLEF_KEYSERVICE_PATH?.trim();
12139
+ if (envPath) {
12140
+ validateKeyservicePath(envPath);
12141
+ if (!fs15.existsSync(envPath)) {
12142
+ throw new Error(`CLEF_KEYSERVICE_PATH points to '${envPath}' but the file does not exist.`);
12143
+ }
12144
+ cached2 = { path: envPath, source: "env" };
12145
+ return cached2;
12146
+ }
12147
+ const bundledPath = tryBundledKeyservice();
12148
+ if (bundledPath) {
12149
+ cached2 = { path: bundledPath, source: "bundled" };
12150
+ return cached2;
12151
+ }
12152
+ cached2 = { path: "clef-keyservice", source: "system" };
12153
+ return cached2;
12154
+ }
12155
+ function resetKeyserviceResolution() {
12156
+ cached2 = void 0;
12157
+ }
12158
+
12159
+ // src/hsm/keyservice.ts
12160
+ var import_child_process = require("child_process");
12161
+ var readline = __toESM(require("readline"));
12162
+ var PORT_REGEX = /^PORT=(\d+)$/;
12163
+ var STARTUP_TIMEOUT_MS = 5e3;
12164
+ var SHUTDOWN_TIMEOUT_MS = 3e3;
12165
+ async function spawnKeyservice(options) {
12166
+ if (!options.pin && !options.pinFile) {
12167
+ throw new Error(
12168
+ "Keyservice requires a PIN. Set CLEF_PKCS11_PIN, CLEF_PKCS11_PIN_FILE, or .clef/config.yaml pkcs11_pin_file."
12169
+ );
12170
+ }
12171
+ const args = ["--addr", "127.0.0.1:0", "--pkcs11-module", options.modulePath];
12172
+ const childEnv = {
12173
+ ...process.env,
12174
+ ...options.extraEnv ?? {},
12175
+ ...options.pin ? { CLEF_PKCS11_PIN: options.pin } : {},
12176
+ ...options.pinFile ? { CLEF_PKCS11_PIN_FILE: options.pinFile } : {}
12177
+ };
12178
+ const child = (0, import_child_process.spawn)(options.binaryPath, args, {
12179
+ stdio: ["ignore", "pipe", "pipe"],
12180
+ env: childEnv
12181
+ });
12182
+ const port = await readPort(child);
12183
+ return {
12184
+ addr: `tcp://127.0.0.1:${port}`,
12185
+ kill: () => killGracefully(child)
12186
+ };
12187
+ }
12188
+ function readPort(child) {
12189
+ return new Promise((resolve, reject) => {
12190
+ let settled = false;
12191
+ if (!child.stdout) {
12192
+ reject(new Error("Keyservice child has no stdout pipe."));
12193
+ return;
12194
+ }
12195
+ const rl = readline.createInterface({ input: child.stdout });
12196
+ const settle = () => {
12197
+ clearTimeout(timer);
12198
+ rl.close();
12199
+ };
12200
+ const timer = setTimeout(() => {
12201
+ if (!settled) {
12202
+ settled = true;
12203
+ settle();
12204
+ child.kill("SIGKILL");
12205
+ reject(
12206
+ new Error(
12207
+ `clef-keyservice did not report a port within ${STARTUP_TIMEOUT_MS}ms. Check that the PKCS#11 module path is valid and the PIN is correct.`
12208
+ )
12209
+ );
12210
+ }
12211
+ }, STARTUP_TIMEOUT_MS);
12212
+ rl.on("line", (line) => {
12213
+ const match = PORT_REGEX.exec(line);
12214
+ if (match && !settled) {
12215
+ settled = true;
12216
+ settle();
12217
+ resolve(parseInt(match[1], 10));
12218
+ }
12219
+ });
12220
+ child.on("error", (err) => {
12221
+ if (!settled) {
12222
+ settled = true;
12223
+ settle();
12224
+ reject(new Error(`Failed to start clef-keyservice: ${err.message}`));
12225
+ }
12226
+ });
12227
+ child.on("exit", (code) => {
12228
+ if (!settled) {
12229
+ settled = true;
12230
+ settle();
12231
+ reject(new Error(`clef-keyservice exited with code ${code} before reporting a port.`));
12232
+ }
12233
+ });
12234
+ });
12235
+ }
12236
+ function killGracefully(child) {
12237
+ return new Promise((resolve) => {
12238
+ if (child.exitCode !== null) {
12239
+ resolve();
12240
+ return;
12241
+ }
12242
+ const timer = setTimeout(() => {
12243
+ child.kill("SIGKILL");
12244
+ }, SHUTDOWN_TIMEOUT_MS);
12245
+ child.on("exit", () => {
12246
+ clearTimeout(timer);
12247
+ resolve();
12248
+ });
12249
+ child.kill("SIGTERM");
12250
+ });
12251
+ }
12252
+
12253
+ // src/lint/runner.ts
12254
+ var path14 = __toESM(require("path"));
11903
12255
  var LintRunner = class {
11904
12256
  constructor(matrixManager, schemaValidator, sopsClient) {
11905
12257
  this.matrixManager = matrixManager;
@@ -11999,7 +12351,7 @@ var LintRunner = class {
11999
12351
  }
12000
12352
  const ns = manifest.namespaces.find((n) => n.name === cell.namespace);
12001
12353
  if (ns?.schema) {
12002
- const schemaPath = path12.join(repoRoot, ns.schema);
12354
+ const schemaPath = path14.join(repoRoot, ns.schema);
12003
12355
  try {
12004
12356
  const schema = this.schemaValidator.loadSchema(schemaPath);
12005
12357
  const result = this.schemaValidator.validate(decrypted.values, schema);
@@ -12100,8 +12452,50 @@ var LintRunner = class {
12100
12452
  );
12101
12453
  issues.push(...siIssues);
12102
12454
  }
12455
+ const metadataIssues = await this.lintMetadataConsistency(existingCells);
12456
+ issues.push(...metadataIssues);
12103
12457
  return { issues, fileCount: fileCount + missingCells.length, pendingCount };
12104
12458
  }
12459
+ /**
12460
+ * Cross-reference `.clef-meta.yaml` against the cipher's plaintext key
12461
+ * names for each existing cell. Reports orphan rotation records and
12462
+ * dual-state (pending + rotation) inconsistencies. Uses
12463
+ * {@link readSopsKeyNames} (plaintext YAML parse) — no decryption.
12464
+ */
12465
+ async lintMetadataConsistency(cells) {
12466
+ const issues = [];
12467
+ for (const cell of cells) {
12468
+ const keysInCipher = readSopsKeyNames(cell.filePath);
12469
+ if (keysInCipher === null) continue;
12470
+ const cipherKeys = new Set(keysInCipher);
12471
+ const metadata = await loadMetadata(cell.filePath);
12472
+ for (const record of metadata.rotations) {
12473
+ if (!cipherKeys.has(record.key)) {
12474
+ issues.push({
12475
+ severity: "warning",
12476
+ category: "metadata",
12477
+ file: cell.filePath,
12478
+ key: record.key,
12479
+ message: `Rotation record exists for key '${record.key}' but the key is not in this cell. Remove the orphan entry from .clef-meta.yaml or re-add the key via clef set.`
12480
+ });
12481
+ }
12482
+ }
12483
+ const pendingKeys = new Set(metadata.pending.map((p) => p.key));
12484
+ for (const record of metadata.rotations) {
12485
+ if (pendingKeys.has(record.key)) {
12486
+ issues.push({
12487
+ severity: "error",
12488
+ category: "metadata",
12489
+ file: cell.filePath,
12490
+ key: record.key,
12491
+ message: `Key '${record.key}' appears in both 'pending' and 'rotations' sections of .clef-meta.yaml. One of them is stale \u2014 likely a manual edit or a failed transaction. Re-run clef set to reconcile.`,
12492
+ fixCommand: `clef set ${cell.namespace}/${cell.environment} ${record.key}`
12493
+ });
12494
+ }
12495
+ }
12496
+ }
12497
+ return issues;
12498
+ }
12105
12499
  /**
12106
12500
  * Lint service identity configurations for drift issues.
12107
12501
  */
@@ -12244,14 +12638,14 @@ Use 'clef exec' to inject secrets directly into a process, or 'clef export --for
12244
12638
  };
12245
12639
 
12246
12640
  // src/import/index.ts
12247
- var path14 = __toESM(require("path"));
12641
+ var path16 = __toESM(require("path"));
12248
12642
 
12249
12643
  // src/import/parsers.ts
12250
- var path13 = __toESM(require("path"));
12644
+ var path15 = __toESM(require("path"));
12251
12645
  var YAML8 = __toESM(require("yaml"));
12252
12646
  function detectFormat(filePath, content) {
12253
- const base = path13.basename(filePath);
12254
- const ext = path13.extname(filePath).toLowerCase();
12647
+ const base = path15.basename(filePath);
12648
+ const ext = path15.extname(filePath).toLowerCase();
12255
12649
  if (base === ".env" || base.startsWith(".env.")) {
12256
12650
  return "dotenv";
12257
12651
  }
@@ -12417,7 +12811,7 @@ var ImportRunner = class {
12417
12811
  */
12418
12812
  async import(target, sourcePath, content, manifest, repoRoot, options) {
12419
12813
  const [ns, env] = target.split("/");
12420
- const filePath = path14.join(
12814
+ const filePath = path16.join(
12421
12815
  repoRoot,
12422
12816
  manifest.file_pattern.replace("{namespace}", ns).replace("{environment}", env)
12423
12817
  );
@@ -12454,22 +12848,33 @@ var ImportRunner = class {
12454
12848
  }
12455
12849
  const decrypted = await this.sopsClient.decrypt(filePath);
12456
12850
  const newValues = { ...decrypted.values };
12851
+ const rotatedKeys = [];
12457
12852
  for (const [key, value] of candidates) {
12458
- if (key in decrypted.values && !options.overwrite) {
12853
+ const existed = key in decrypted.values;
12854
+ if (existed && !options.overwrite) {
12459
12855
  skipped.push(key);
12460
12856
  continue;
12461
12857
  }
12858
+ const valueChanged = !existed || decrypted.values[key] !== value;
12462
12859
  newValues[key] = value;
12463
12860
  imported.push(key);
12861
+ if (valueChanged) rotatedKeys.push(key);
12464
12862
  }
12465
12863
  if (imported.length === 0) {
12466
12864
  return { imported, skipped, failed, warnings, dryRun: false };
12467
12865
  }
12866
+ const relCellPath = path16.relative(repoRoot, filePath);
12867
+ const relMetaPath = relCellPath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml");
12468
12868
  await this.tx.run(repoRoot, {
12469
12869
  description: `clef import ${target}: ${imported.length} key(s)`,
12470
- paths: [path14.relative(repoRoot, filePath)],
12870
+ // Include the metadata path so rotation records created in the mutate
12871
+ // callback are staged and rolled back atomically with the ciphertext.
12872
+ paths: [relCellPath, relMetaPath],
12471
12873
  mutate: async () => {
12472
12874
  await this.sopsClient.encrypt(filePath, newValues, manifest, env);
12875
+ if (options.rotatedBy && rotatedKeys.length > 0) {
12876
+ await recordRotation(filePath, rotatedKeys, options.rotatedBy);
12877
+ }
12473
12878
  }
12474
12879
  });
12475
12880
  return { imported, skipped, failed, warnings, dryRun: false };
@@ -12477,7 +12882,7 @@ var ImportRunner = class {
12477
12882
  };
12478
12883
 
12479
12884
  // src/recipients/index.ts
12480
- var path15 = __toESM(require("path"));
12885
+ var path17 = __toESM(require("path"));
12481
12886
  function parseRecipientEntry(entry) {
12482
12887
  if (typeof entry === "string") {
12483
12888
  return { key: entry };
@@ -12602,7 +13007,7 @@ var RecipientManager = class {
12602
13007
  const reEncryptedFiles = [];
12603
13008
  await this.tx.run(repoRoot, {
12604
13009
  description: environment ? `clef recipients add ${keyPreview(normalizedKey)} -e ${environment}` : `clef recipients add ${keyPreview(normalizedKey)}`,
12605
- paths: [...cells.map((c) => path15.relative(repoRoot, c.filePath)), CLEF_MANIFEST_FILENAME],
13010
+ paths: [...cells.map((c) => path17.relative(repoRoot, c.filePath)), CLEF_MANIFEST_FILENAME],
12606
13011
  mutate: async () => {
12607
13012
  const doc = readManifestYaml(repoRoot);
12608
13013
  const recipients = environment ? ensureEnvironmentRecipientsArray(doc, environment) : ensureRecipientsArray(doc);
@@ -12661,7 +13066,7 @@ var RecipientManager = class {
12661
13066
  const reEncryptedFiles = [];
12662
13067
  await this.tx.run(repoRoot, {
12663
13068
  description: environment ? `clef recipients remove ${keyPreview(trimmedKey)} -e ${environment}` : `clef recipients remove ${keyPreview(trimmedKey)}`,
12664
- paths: [...cells.map((c) => path15.relative(repoRoot, c.filePath)), CLEF_MANIFEST_FILENAME],
13069
+ paths: [...cells.map((c) => path17.relative(repoRoot, c.filePath)), CLEF_MANIFEST_FILENAME],
12665
13070
  mutate: async () => {
12666
13071
  const doc = readManifestYaml(repoRoot);
12667
13072
  const recipients = environment ? ensureEnvironmentRecipientsArray(doc, environment) : ensureRecipientsArray(doc);
@@ -12690,19 +13095,19 @@ var RecipientManager = class {
12690
13095
  };
12691
13096
 
12692
13097
  // src/recipients/requests.ts
12693
- var fs14 = __toESM(require("fs"));
12694
- var path16 = __toESM(require("path"));
13098
+ var fs16 = __toESM(require("fs"));
13099
+ var path18 = __toESM(require("path"));
12695
13100
  var YAML9 = __toESM(require("yaml"));
12696
13101
  var REQUESTS_FILENAME = ".clef-requests.yaml";
12697
13102
  var HEADER_COMMENT2 = "# Pending recipient access requests. Approve with: clef recipients approve <label>\n";
12698
13103
  function requestsFilePath(repoRoot) {
12699
- return path16.join(repoRoot, REQUESTS_FILENAME);
13104
+ return path18.join(repoRoot, REQUESTS_FILENAME);
12700
13105
  }
12701
13106
  function loadRequests(repoRoot) {
12702
13107
  const filePath = requestsFilePath(repoRoot);
12703
13108
  try {
12704
- if (!fs14.existsSync(filePath)) return [];
12705
- const content = fs14.readFileSync(filePath, "utf-8");
13109
+ if (!fs16.existsSync(filePath)) return [];
13110
+ const content = fs16.readFileSync(filePath, "utf-8");
12706
13111
  const parsed = YAML9.parse(content);
12707
13112
  if (!parsed || !Array.isArray(parsed.requests)) return [];
12708
13113
  return parsed.requests.map((r) => ({
@@ -12719,7 +13124,7 @@ function saveRequests(repoRoot, requests) {
12719
13124
  const filePath = requestsFilePath(repoRoot);
12720
13125
  if (requests.length === 0) {
12721
13126
  try {
12722
- fs14.unlinkSync(filePath);
13127
+ fs16.unlinkSync(filePath);
12723
13128
  } catch {
12724
13129
  }
12725
13130
  return;
@@ -12735,7 +13140,7 @@ function saveRequests(repoRoot, requests) {
12735
13140
  return raw;
12736
13141
  })
12737
13142
  };
12738
- fs14.writeFileSync(filePath, HEADER_COMMENT2 + YAML9.stringify(data), "utf-8");
13143
+ fs16.writeFileSync(filePath, HEADER_COMMENT2 + YAML9.stringify(data), "utf-8");
12739
13144
  }
12740
13145
  function upsertRequest(repoRoot, key, label, environment) {
12741
13146
  const requests = loadRequests(repoRoot);
@@ -12771,7 +13176,7 @@ function findInList(requests, identifier) {
12771
13176
  }
12772
13177
 
12773
13178
  // src/drift/detector.ts
12774
- var path17 = __toESM(require("path"));
13179
+ var path19 = __toESM(require("path"));
12775
13180
  var DriftDetector = class {
12776
13181
  parser = new ManifestParser();
12777
13182
  matrix = new MatrixManager();
@@ -12784,8 +13189,8 @@ var DriftDetector = class {
12784
13189
  * @returns Drift result with any issues found.
12785
13190
  */
12786
13191
  detect(localRoot, remoteRoot, namespaceFilter) {
12787
- const localManifest = this.parser.parse(path17.join(localRoot, CLEF_MANIFEST_FILENAME));
12788
- const remoteManifest = this.parser.parse(path17.join(remoteRoot, CLEF_MANIFEST_FILENAME));
13192
+ const localManifest = this.parser.parse(path19.join(localRoot, CLEF_MANIFEST_FILENAME));
13193
+ const remoteManifest = this.parser.parse(path19.join(remoteRoot, CLEF_MANIFEST_FILENAME));
12789
13194
  const localCells = this.matrix.resolveMatrix(localManifest, localRoot);
12790
13195
  const remoteCells = this.matrix.resolveMatrix(remoteManifest, remoteRoot);
12791
13196
  const localEnvNames = localManifest.environments.map((e) => e.name);
@@ -12849,7 +13254,7 @@ var DriftDetector = class {
12849
13254
  };
12850
13255
 
12851
13256
  // src/report/generator.ts
12852
- var path18 = __toESM(require("path"));
13257
+ var path20 = __toESM(require("path"));
12853
13258
 
12854
13259
  // src/report/sanitizer.ts
12855
13260
  var ReportSanitizer = class {
@@ -13005,7 +13410,7 @@ var ReportGenerator = class {
13005
13410
  let manifest = null;
13006
13411
  try {
13007
13412
  const parser = new ManifestParser();
13008
- manifest = parser.parse(path18.join(repoRoot, "clef.yaml"));
13413
+ manifest = parser.parse(path20.join(repoRoot, "clef.yaml"));
13009
13414
  } catch {
13010
13415
  const emptyManifest = {
13011
13416
  manifestVersion: 0,
@@ -13482,8 +13887,118 @@ var SopsMergeDriver = class {
13482
13887
  }
13483
13888
  };
13484
13889
 
13890
+ // src/merge/metadata-driver.ts
13891
+ var fs17 = __toESM(require("fs"));
13892
+ var YAML10 = __toESM(require("yaml"));
13893
+ var HEADER_COMMENT3 = "# Managed by Clef. Do not edit manually.\n";
13894
+ function parseMetadata(content) {
13895
+ try {
13896
+ const parsed = YAML10.parse(content);
13897
+ if (!parsed || typeof parsed !== "object") return emptyMetadata2();
13898
+ const pendingRaw = Array.isArray(parsed.pending) ? parsed.pending : [];
13899
+ const pending = pendingRaw.filter(
13900
+ (p) => !!p && typeof p === "object" && typeof p.key === "string" && typeof p.since === "string" && typeof p.setBy === "string"
13901
+ ).map((p) => ({ key: p.key, since: new Date(p.since), setBy: p.setBy }));
13902
+ const rotationsRaw = Array.isArray(parsed.rotations) ? parsed.rotations : [];
13903
+ const rotations = rotationsRaw.filter(
13904
+ (r) => !!r && typeof r === "object" && typeof r.key === "string" && typeof r.last_rotated_at === "string" && typeof r.rotated_by === "string" && typeof r.rotation_count === "number"
13905
+ ).map((r) => ({
13906
+ key: r.key,
13907
+ lastRotatedAt: new Date(r.last_rotated_at),
13908
+ rotatedBy: r.rotated_by,
13909
+ rotationCount: r.rotation_count
13910
+ }));
13911
+ return { version: 1, pending, rotations };
13912
+ } catch {
13913
+ return emptyMetadata2();
13914
+ }
13915
+ }
13916
+ function emptyMetadata2() {
13917
+ return { version: 1, pending: [], rotations: [] };
13918
+ }
13919
+ function serializeMetadata(m) {
13920
+ const data = {
13921
+ version: m.version,
13922
+ pending: m.pending.map((p) => ({
13923
+ key: p.key,
13924
+ since: p.since.toISOString(),
13925
+ setBy: p.setBy
13926
+ })),
13927
+ rotations: m.rotations.map((r) => ({
13928
+ key: r.key,
13929
+ last_rotated_at: r.lastRotatedAt.toISOString(),
13930
+ rotated_by: r.rotatedBy,
13931
+ rotation_count: r.rotationCount
13932
+ }))
13933
+ };
13934
+ return HEADER_COMMENT3 + YAML10.stringify(data);
13935
+ }
13936
+ function mergeRotations(ours, theirs) {
13937
+ const byKey = /* @__PURE__ */ new Map();
13938
+ const ourByKey = new Map(ours.map((r) => [r.key, r]));
13939
+ const theirByKey = new Map(theirs.map((r) => [r.key, r]));
13940
+ const allKeys = /* @__PURE__ */ new Set([...ourByKey.keys(), ...theirByKey.keys()]);
13941
+ for (const key of allKeys) {
13942
+ const o = ourByKey.get(key);
13943
+ const t = theirByKey.get(key);
13944
+ if (o && t) {
13945
+ const oTime = o.lastRotatedAt.getTime();
13946
+ const tTime = t.lastRotatedAt.getTime();
13947
+ const winner = tTime > oTime ? t : o;
13948
+ byKey.set(key, {
13949
+ key,
13950
+ lastRotatedAt: winner.lastRotatedAt,
13951
+ rotatedBy: winner.rotatedBy,
13952
+ rotationCount: Math.max(o.rotationCount, t.rotationCount) + 1
13953
+ });
13954
+ } else if (o) {
13955
+ byKey.set(key, o);
13956
+ } else if (t) {
13957
+ byKey.set(key, t);
13958
+ }
13959
+ }
13960
+ return Array.from(byKey.values());
13961
+ }
13962
+ function mergePending(oursPending, theirsPending, oursRotations, theirsRotations) {
13963
+ const ourByKey = new Map(oursPending.map((p) => [p.key, p]));
13964
+ const theirByKey = new Map(theirsPending.map((p) => [p.key, p]));
13965
+ const rotatedKeys = /* @__PURE__ */ new Set([
13966
+ ...oursRotations.map((r) => r.key),
13967
+ ...theirsRotations.map((r) => r.key)
13968
+ ]);
13969
+ const allKeys = /* @__PURE__ */ new Set([...ourByKey.keys(), ...theirByKey.keys()]);
13970
+ const out = [];
13971
+ for (const key of allKeys) {
13972
+ if (rotatedKeys.has(key)) continue;
13973
+ const o = ourByKey.get(key);
13974
+ const t = theirByKey.get(key);
13975
+ if (o && t) {
13976
+ const winner = t.since.getTime() > o.since.getTime() ? t : o;
13977
+ out.push({ key, since: winner.since, setBy: winner.setBy });
13978
+ } else if (o) {
13979
+ out.push(o);
13980
+ } else if (t) {
13981
+ out.push(t);
13982
+ }
13983
+ }
13984
+ return out;
13985
+ }
13986
+ function mergeMetadataContents(oursContent, theirsContent) {
13987
+ const ours = parseMetadata(oursContent);
13988
+ const theirs = parseMetadata(theirsContent);
13989
+ const rotations = mergeRotations(ours.rotations, theirs.rotations);
13990
+ const pending = mergePending(ours.pending, theirs.pending, ours.rotations, theirs.rotations);
13991
+ return serializeMetadata({ version: 1, pending, rotations });
13992
+ }
13993
+ function mergeMetadataFiles(_basePath, oursPath, theirsPath) {
13994
+ const oursContent = fs17.existsSync(oursPath) ? fs17.readFileSync(oursPath, "utf-8") : "";
13995
+ const theirsContent = fs17.existsSync(theirsPath) ? fs17.readFileSync(theirsPath, "utf-8") : "";
13996
+ const merged = mergeMetadataContents(oursContent, theirsContent);
13997
+ fs17.writeFileSync(oursPath, merged, "utf-8");
13998
+ }
13999
+
13485
14000
  // src/service-identity/manager.ts
13486
- var path19 = __toESM(require("path"));
14001
+ var path21 = __toESM(require("path"));
13487
14002
  var ServiceIdentityManager = class {
13488
14003
  constructor(encryption, matrixManager, tx) {
13489
14004
  this.encryption = encryption;
@@ -13495,7 +14010,7 @@ var ServiceIdentityManager = class {
13495
14010
  * to seed TransactionManager.run's `paths` argument.
13496
14011
  */
13497
14012
  txPaths(repoRoot, cells) {
13498
- return [...cells.map((c) => path19.relative(repoRoot, c.filePath)), CLEF_MANIFEST_FILENAME];
14013
+ return [...cells.map((c) => path21.relative(repoRoot, c.filePath)), CLEF_MANIFEST_FILENAME];
13499
14014
  }
13500
14015
  /**
13501
14016
  * Create a new service identity with per-environment age key pairs or KMS envelope config.
@@ -14017,8 +14532,8 @@ var ServiceIdentityManager = class {
14017
14532
  };
14018
14533
 
14019
14534
  // src/structure/manager.ts
14020
- var fs15 = __toESM(require("fs"));
14021
- var path20 = __toESM(require("path"));
14535
+ var fs18 = __toESM(require("fs"));
14536
+ var path22 = __toESM(require("path"));
14022
14537
  var StructureManager = class {
14023
14538
  constructor(matrixManager, encryption, tx) {
14024
14539
  this.matrixManager = matrixManager;
@@ -14039,15 +14554,15 @@ var StructureManager = class {
14039
14554
  this.assertValidIdentifier("namespace", name);
14040
14555
  const newCellPaths = manifest.environments.map((env) => ({
14041
14556
  environment: env.name,
14042
- filePath: path20.join(
14557
+ filePath: path22.join(
14043
14558
  repoRoot,
14044
14559
  manifest.file_pattern.replace("{namespace}", name).replace("{environment}", env.name)
14045
14560
  )
14046
14561
  }));
14047
14562
  for (const cell of newCellPaths) {
14048
- if (fs15.existsSync(cell.filePath)) {
14563
+ if (fs18.existsSync(cell.filePath)) {
14049
14564
  throw new Error(
14050
- `Cannot add namespace '${name}': file '${path20.relative(repoRoot, cell.filePath)}' already exists.`
14565
+ `Cannot add namespace '${name}': file '${path22.relative(repoRoot, cell.filePath)}' already exists.`
14051
14566
  );
14052
14567
  }
14053
14568
  }
@@ -14066,7 +14581,7 @@ var StructureManager = class {
14066
14581
  await this.tx.run(repoRoot, {
14067
14582
  description: `clef namespace add ${name}`,
14068
14583
  paths: [
14069
- ...newCellPaths.map((c) => path20.relative(repoRoot, c.filePath)),
14584
+ ...newCellPaths.map((c) => path22.relative(repoRoot, c.filePath)),
14070
14585
  CLEF_MANIFEST_FILENAME
14071
14586
  ],
14072
14587
  mutate: async () => {
@@ -14111,15 +14626,15 @@ var StructureManager = class {
14111
14626
  this.assertValidIdentifier("environment", name);
14112
14627
  const newCellPaths = manifest.namespaces.map((ns) => ({
14113
14628
  namespace: ns.name,
14114
- filePath: path20.join(
14629
+ filePath: path22.join(
14115
14630
  repoRoot,
14116
14631
  manifest.file_pattern.replace("{namespace}", ns.name).replace("{environment}", name)
14117
14632
  )
14118
14633
  }));
14119
14634
  for (const cell of newCellPaths) {
14120
- if (fs15.existsSync(cell.filePath)) {
14635
+ if (fs18.existsSync(cell.filePath)) {
14121
14636
  throw new Error(
14122
- `Cannot add environment '${name}': file '${path20.relative(repoRoot, cell.filePath)}' already exists.`
14637
+ `Cannot add environment '${name}': file '${path22.relative(repoRoot, cell.filePath)}' already exists.`
14123
14638
  );
14124
14639
  }
14125
14640
  }
@@ -14138,7 +14653,7 @@ var StructureManager = class {
14138
14653
  await this.tx.run(repoRoot, {
14139
14654
  description: `clef env add ${name}`,
14140
14655
  paths: [
14141
- ...newCellPaths.map((c) => path20.relative(repoRoot, c.filePath)),
14656
+ ...newCellPaths.map((c) => path22.relative(repoRoot, c.filePath)),
14142
14657
  CLEF_MANIFEST_FILENAME
14143
14658
  ],
14144
14659
  mutate: async () => {
@@ -14201,7 +14716,7 @@ var StructureManager = class {
14201
14716
  paths: this.deletePaths(repoRoot, cellsToDelete),
14202
14717
  mutate: async () => {
14203
14718
  for (const cell of cellsToDelete) {
14204
- fs15.unlinkSync(cell.filePath);
14719
+ fs18.unlinkSync(cell.filePath);
14205
14720
  this.unlinkMetaSibling(cell.filePath);
14206
14721
  }
14207
14722
  const doc = readManifestYaml(repoRoot);
@@ -14251,7 +14766,7 @@ var StructureManager = class {
14251
14766
  paths: this.deletePaths(repoRoot, cellsToDelete),
14252
14767
  mutate: async () => {
14253
14768
  for (const cell of cellsToDelete) {
14254
- fs15.unlinkSync(cell.filePath);
14769
+ fs18.unlinkSync(cell.filePath);
14255
14770
  this.unlinkMetaSibling(cell.filePath);
14256
14771
  }
14257
14772
  const doc = readManifestYaml(repoRoot);
@@ -14293,9 +14808,9 @@ var StructureManager = class {
14293
14808
  const renamePairs = isRename ? this.collectRenamePairs(manifest, repoRoot, name, opts.rename, "namespace") : [];
14294
14809
  if (isRename) {
14295
14810
  for (const pair of renamePairs) {
14296
- if (fs15.existsSync(pair.to)) {
14811
+ if (fs18.existsSync(pair.to)) {
14297
14812
  throw new Error(
14298
- `Rename target '${path20.relative(repoRoot, pair.to)}' already exists. Move or remove it first.`
14813
+ `Rename target '${path22.relative(repoRoot, pair.to)}' already exists. Move or remove it first.`
14299
14814
  );
14300
14815
  }
14301
14816
  }
@@ -14336,9 +14851,9 @@ var StructureManager = class {
14336
14851
  const renamePairs = isRename ? this.collectRenamePairs(manifest, repoRoot, name, opts.rename, "environment") : [];
14337
14852
  if (isRename) {
14338
14853
  for (const pair of renamePairs) {
14339
- if (fs15.existsSync(pair.to)) {
14854
+ if (fs18.existsSync(pair.to)) {
14340
14855
  throw new Error(
14341
- `Rename target '${path20.relative(repoRoot, pair.to)}' already exists. Move or remove it first.`
14856
+ `Rename target '${path22.relative(repoRoot, pair.to)}' already exists. Move or remove it first.`
14342
14857
  );
14343
14858
  }
14344
14859
  }
@@ -14373,7 +14888,7 @@ var StructureManager = class {
14373
14888
  const newCellPath = this.swapAxisInCellPath(repoRoot, manifest, cell, axis, newName);
14374
14889
  pairs.push({ from: cell.filePath, to: newCellPath });
14375
14890
  const oldMeta = cell.filePath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml");
14376
- if (fs15.existsSync(oldMeta)) {
14891
+ if (fs18.existsSync(oldMeta)) {
14377
14892
  const newMeta = newCellPath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml");
14378
14893
  pairs.push({ from: oldMeta, to: newMeta });
14379
14894
  }
@@ -14388,7 +14903,7 @@ var StructureManager = class {
14388
14903
  swapAxisInCellPath(repoRoot, manifest, cell, axis, newName) {
14389
14904
  const ns = axis === "namespace" ? newName : cell.namespace;
14390
14905
  const env = axis === "environment" ? newName : cell.environment;
14391
- return path20.join(
14906
+ return path22.join(
14392
14907
  repoRoot,
14393
14908
  manifest.file_pattern.replace("{namespace}", ns).replace("{environment}", env)
14394
14909
  );
@@ -14400,8 +14915,8 @@ var StructureManager = class {
14400
14915
  txPaths(repoRoot, renamePairs) {
14401
14916
  const paths = /* @__PURE__ */ new Set();
14402
14917
  for (const pair of renamePairs) {
14403
- paths.add(path20.relative(repoRoot, pair.from));
14404
- paths.add(path20.relative(repoRoot, pair.to));
14918
+ paths.add(path22.relative(repoRoot, pair.from));
14919
+ paths.add(path22.relative(repoRoot, pair.to));
14405
14920
  }
14406
14921
  paths.add(CLEF_MANIFEST_FILENAME);
14407
14922
  return [...paths];
@@ -14412,11 +14927,11 @@ var StructureManager = class {
14412
14927
  */
14413
14928
  applyRenames(pairs) {
14414
14929
  for (const pair of pairs) {
14415
- const targetDir = path20.dirname(pair.to);
14416
- if (!fs15.existsSync(targetDir)) {
14417
- fs15.mkdirSync(targetDir, { recursive: true });
14930
+ const targetDir = path22.dirname(pair.to);
14931
+ if (!fs18.existsSync(targetDir)) {
14932
+ fs18.mkdirSync(targetDir, { recursive: true });
14418
14933
  }
14419
- fs15.renameSync(pair.from, pair.to);
14934
+ fs18.renameSync(pair.from, pair.to);
14420
14935
  }
14421
14936
  }
14422
14937
  /**
@@ -14427,10 +14942,10 @@ var StructureManager = class {
14427
14942
  deletePaths(repoRoot, cells) {
14428
14943
  const paths = /* @__PURE__ */ new Set();
14429
14944
  for (const cell of cells) {
14430
- paths.add(path20.relative(repoRoot, cell.filePath));
14945
+ paths.add(path22.relative(repoRoot, cell.filePath));
14431
14946
  const meta = cell.filePath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml");
14432
- if (fs15.existsSync(meta)) {
14433
- paths.add(path20.relative(repoRoot, meta));
14947
+ if (fs18.existsSync(meta)) {
14948
+ paths.add(path22.relative(repoRoot, meta));
14434
14949
  }
14435
14950
  }
14436
14951
  paths.add(CLEF_MANIFEST_FILENAME);
@@ -14443,8 +14958,8 @@ var StructureManager = class {
14443
14958
  */
14444
14959
  unlinkMetaSibling(cellPath) {
14445
14960
  const meta = cellPath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml");
14446
- if (fs15.existsSync(meta)) {
14447
- fs15.unlinkSync(meta);
14961
+ if (fs18.existsSync(meta)) {
14962
+ fs18.unlinkSync(meta);
14448
14963
  }
14449
14964
  }
14450
14965
  /**
@@ -14589,20 +15104,20 @@ async function resolveIdentitySecrets(identityName, environment, manifest, repoR
14589
15104
  var crypto4 = __toESM(require("crypto"));
14590
15105
 
14591
15106
  // src/artifact/output.ts
14592
- var fs16 = __toESM(require("fs"));
14593
- var path21 = __toESM(require("path"));
15107
+ var fs19 = __toESM(require("fs"));
15108
+ var path23 = __toESM(require("path"));
14594
15109
  var FilePackOutput = class {
14595
15110
  constructor(outputPath) {
14596
15111
  this.outputPath = outputPath;
14597
15112
  }
14598
15113
  async write(_artifact, json) {
14599
- const outputDir = path21.dirname(this.outputPath);
14600
- if (!fs16.existsSync(outputDir)) {
14601
- fs16.mkdirSync(outputDir, { recursive: true });
15114
+ const outputDir = path23.dirname(this.outputPath);
15115
+ if (!fs19.existsSync(outputDir)) {
15116
+ fs19.mkdirSync(outputDir, { recursive: true });
14602
15117
  }
14603
15118
  const tmpOutput = `${this.outputPath}.tmp.${process.pid}`;
14604
- fs16.writeFileSync(tmpOutput, json, "utf-8");
14605
- fs16.renameSync(tmpOutput, this.outputPath);
15119
+ fs19.writeFileSync(tmpOutput, json, "utf-8");
15120
+ fs19.renameSync(tmpOutput, this.outputPath);
14606
15121
  }
14607
15122
  };
14608
15123
  var MemoryPackOutput = class {
@@ -14809,28 +15324,187 @@ var ArtifactPacker = class {
14809
15324
  const json = JSON.stringify(artifact, null, 2);
14810
15325
  const output = config.output ?? new FilePackOutput(config.outputPath ?? "artifact.json");
14811
15326
  await output.write(artifact, json);
15327
+ const keys = Object.keys(resolved.values);
14812
15328
  return {
14813
15329
  outputPath: config.outputPath ?? "",
14814
15330
  namespaceCount: resolved.identity.namespaces.length,
14815
- keyCount: Object.keys(resolved.values).length,
15331
+ keyCount: keys.length,
15332
+ keys,
14816
15333
  artifactSize: Buffer.byteLength(json, "utf-8"),
14817
15334
  revision: artifact.revision
14818
15335
  };
14819
15336
  }
14820
15337
  };
14821
15338
 
15339
+ // src/artifact/guards.ts
15340
+ var InvalidArtifactError = class extends ClefError {
15341
+ constructor(message) {
15342
+ super(
15343
+ message,
15344
+ "Ensure the artifact was produced by a compatible clef version and was not tampered with."
15345
+ );
15346
+ this.name = "InvalidArtifactError";
15347
+ }
15348
+ };
15349
+ var VALID_SIGNATURE_ALGORITHMS = ["Ed25519", "ECDSA_SHA256"];
15350
+ function isKmsEnvelope2(x) {
15351
+ if (typeof x !== "object" || x === null) return false;
15352
+ const o = x;
15353
+ return typeof o.provider === "string" && typeof o.keyId === "string" && typeof o.wrappedKey === "string" && typeof o.algorithm === "string" && typeof o.iv === "string" && typeof o.authTag === "string";
15354
+ }
15355
+ function validatePackedArtifact(x) {
15356
+ if (typeof x !== "object" || x === null) {
15357
+ return { valid: false, reason: "expected object" };
15358
+ }
15359
+ const o = x;
15360
+ if (o.version !== 1) {
15361
+ return { valid: false, reason: `unsupported version: ${String(o.version)}` };
15362
+ }
15363
+ if (typeof o.identity !== "string") {
15364
+ return { valid: false, reason: "missing or invalid 'identity' (expected string)" };
15365
+ }
15366
+ if (typeof o.environment !== "string") {
15367
+ return { valid: false, reason: "missing or invalid 'environment' (expected string)" };
15368
+ }
15369
+ if (typeof o.packedAt !== "string") {
15370
+ return { valid: false, reason: "missing or invalid 'packedAt' (expected string)" };
15371
+ }
15372
+ if (typeof o.revision !== "string") {
15373
+ return { valid: false, reason: "missing or invalid 'revision' (expected string)" };
15374
+ }
15375
+ if (typeof o.ciphertextHash !== "string") {
15376
+ return { valid: false, reason: "missing or invalid 'ciphertextHash' (expected string)" };
15377
+ }
15378
+ if (typeof o.ciphertext !== "string") {
15379
+ return { valid: false, reason: "missing or invalid 'ciphertext' (expected string)" };
15380
+ }
15381
+ if (o.envelope !== void 0 && !isKmsEnvelope2(o.envelope)) {
15382
+ return { valid: false, reason: "invalid 'envelope' (expected KmsEnvelope shape)" };
15383
+ }
15384
+ if (o.expiresAt !== void 0 && typeof o.expiresAt !== "string") {
15385
+ return { valid: false, reason: "invalid 'expiresAt' (expected string)" };
15386
+ }
15387
+ if (o.revokedAt !== void 0 && typeof o.revokedAt !== "string") {
15388
+ return { valid: false, reason: "invalid 'revokedAt' (expected string)" };
15389
+ }
15390
+ if (o.signature !== void 0 && typeof o.signature !== "string") {
15391
+ return { valid: false, reason: "invalid 'signature' (expected string)" };
15392
+ }
15393
+ if (o.signatureAlgorithm !== void 0 && !VALID_SIGNATURE_ALGORITHMS.includes(o.signatureAlgorithm)) {
15394
+ return {
15395
+ valid: false,
15396
+ reason: `invalid 'signatureAlgorithm': expected one of ${VALID_SIGNATURE_ALGORITHMS.join(", ")}`
15397
+ };
15398
+ }
15399
+ return { valid: true, value: o };
15400
+ }
15401
+ function isPackedArtifact(x) {
15402
+ return validatePackedArtifact(x).valid;
15403
+ }
15404
+ function assertPackedArtifact(x, context) {
15405
+ const result = validatePackedArtifact(x);
15406
+ if (!result.valid) {
15407
+ const prefix = context ? `${context}: ` : "";
15408
+ throw new InvalidArtifactError(`${prefix}${result.reason}`);
15409
+ }
15410
+ }
15411
+
15412
+ // src/pack/registry.ts
15413
+ var PackBackendRegistry = class {
15414
+ factories = /* @__PURE__ */ new Map();
15415
+ /**
15416
+ * Register a backend factory under the given id. Throws if a backend
15417
+ * with the same id is already registered — collisions surface as a clear
15418
+ * error rather than a silent overwrite.
15419
+ */
15420
+ register(id, factory) {
15421
+ if (this.factories.has(id)) {
15422
+ throw new Error(`Pack backend "${id}" is already registered.`);
15423
+ }
15424
+ this.factories.set(id, factory);
15425
+ }
15426
+ /** Whether a backend with the given id has been registered. */
15427
+ has(id) {
15428
+ return this.factories.has(id);
15429
+ }
15430
+ /** Registered backend ids, in registration order. */
15431
+ list() {
15432
+ return [...this.factories.keys()];
15433
+ }
15434
+ /**
15435
+ * Resolve a backend by id. Throws if unknown. Factories may be async so
15436
+ * a plugin package can defer construction (e.g. loading a heavy SDK only
15437
+ * when the backend is actually used).
15438
+ */
15439
+ async resolve(id) {
15440
+ const factory = this.factories.get(id);
15441
+ if (!factory) {
15442
+ const available = this.list().join(", ") || "(none)";
15443
+ throw new Error(`Unknown pack backend "${id}". Available backends: ${available}`);
15444
+ }
15445
+ return await factory();
15446
+ }
15447
+ };
15448
+
15449
+ // src/pack/backends/json-envelope.ts
15450
+ var JsonEnvelopeBackend = class {
15451
+ id = "json-envelope";
15452
+ description = "Write the Clef JSON artifact envelope to a local file (default).";
15453
+ validateOptions(raw) {
15454
+ const opts = raw;
15455
+ if (opts.signingKey && opts.signingKmsKeyId) {
15456
+ throw new Error(
15457
+ "Cannot specify both signingKey (Ed25519) and signingKmsKeyId (KMS). Choose one."
15458
+ );
15459
+ }
15460
+ if (!opts.outputPath && !opts.output) {
15461
+ throw new Error("json-envelope backend requires an 'outputPath' or 'output' option.");
15462
+ }
15463
+ }
15464
+ async pack(req) {
15465
+ const opts = req.backendOptions;
15466
+ const packer = new ArtifactPacker(
15467
+ req.services.encryption,
15468
+ new MatrixManager(),
15469
+ req.services.kms
15470
+ );
15471
+ const output = opts.output ?? (opts.outputPath ? new FilePackOutput(opts.outputPath) : void 0);
15472
+ const result = await packer.pack(
15473
+ {
15474
+ identity: req.identity,
15475
+ environment: req.environment,
15476
+ outputPath: opts.outputPath,
15477
+ output,
15478
+ ttl: req.ttl,
15479
+ signingKey: opts.signingKey,
15480
+ signingKmsKeyId: opts.signingKmsKeyId
15481
+ },
15482
+ req.manifest,
15483
+ req.repoRoot
15484
+ );
15485
+ return {
15486
+ ...result,
15487
+ backend: this.id,
15488
+ details: {
15489
+ outputPath: opts.outputPath ?? null
15490
+ }
15491
+ };
15492
+ }
15493
+ };
15494
+
14822
15495
  // src/kms/types.ts
14823
15496
  var VALID_KMS_PROVIDERS = ["aws", "gcp", "azure"];
14824
15497
 
14825
15498
  // src/migration/backend.ts
14826
- var path22 = __toESM(require("path"));
14827
- var YAML10 = __toESM(require("yaml"));
15499
+ var path24 = __toESM(require("path"));
15500
+ var YAML11 = __toESM(require("yaml"));
14828
15501
  var BACKEND_KEY_FIELDS = {
14829
15502
  age: void 0,
14830
15503
  awskms: "aws_kms_arn",
14831
15504
  gcpkms: "gcp_kms_resource_id",
14832
15505
  azurekv: "azure_kv_url",
14833
- pgp: "pgp_fingerprint"
15506
+ pgp: "pgp_fingerprint",
15507
+ hsm: "pkcs11_uri"
14834
15508
  };
14835
15509
  var ALL_KEY_FIELDS = Object.values(BACKEND_KEY_FIELDS).filter(
14836
15510
  (v) => v !== void 0
@@ -14940,14 +15614,14 @@ var BackendMigrator = class {
14940
15614
  await this.tx.run(repoRoot, {
14941
15615
  description: environment ? `clef migrate-backend ${target.backend}: ${environment}` : `clef migrate-backend ${target.backend}`,
14942
15616
  paths: [
14943
- ...toMigrate.map((c) => path22.relative(repoRoot, c.filePath)),
15617
+ ...toMigrate.map((c) => path24.relative(repoRoot, c.filePath)),
14944
15618
  CLEF_MANIFEST_FILENAME
14945
15619
  ],
14946
15620
  mutate: async () => {
14947
15621
  const doc = readManifestYaml(repoRoot);
14948
15622
  this.updateManifestDoc(doc, target, environment);
14949
15623
  writeManifestYaml(repoRoot, doc);
14950
- const updatedManifest = YAML10.parse(YAML10.stringify(doc));
15624
+ const updatedManifest = YAML11.parse(YAML11.stringify(doc));
14951
15625
  for (const cell of toMigrate) {
14952
15626
  onProgress?.({
14953
15627
  type: "migrate",
@@ -15038,7 +15712,7 @@ var BackendMigrator = class {
15038
15712
  };
15039
15713
 
15040
15714
  // src/reset/manager.ts
15041
- var path23 = __toESM(require("path"));
15715
+ var path25 = __toESM(require("path"));
15042
15716
  var ResetManager = class {
15043
15717
  constructor(matrixManager, encryption, schemaValidator, tx) {
15044
15718
  this.matrixManager = matrixManager;
@@ -15063,11 +15737,11 @@ var ResetManager = class {
15063
15737
  txPaths.push(CLEF_MANIFEST_FILENAME);
15064
15738
  }
15065
15739
  for (const cell of targetCells) {
15066
- txPaths.push(path23.relative(repoRoot, cell.filePath));
15740
+ txPaths.push(path25.relative(repoRoot, cell.filePath));
15067
15741
  const cellKeys = keyPlan.get(cell.namespace) ?? [];
15068
15742
  if (cellKeys.length > 0) {
15069
15743
  txPaths.push(
15070
- path23.relative(repoRoot, cell.filePath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml"))
15744
+ path25.relative(repoRoot, cell.filePath.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml"))
15071
15745
  );
15072
15746
  }
15073
15747
  }
@@ -15155,7 +15829,7 @@ var ResetManager = class {
15155
15829
  for (const namespace of namespaces) {
15156
15830
  const nsDef = manifest.namespaces.find((n) => n.name === namespace);
15157
15831
  if (nsDef?.schema) {
15158
- const schema = this.schemaValidator.loadSchema(path23.join(repoRoot, nsDef.schema));
15832
+ const schema = this.schemaValidator.loadSchema(path25.join(repoRoot, nsDef.schema));
15159
15833
  plan.set(namespace, Object.keys(schema.keys));
15160
15834
  continue;
15161
15835
  }
@@ -15234,7 +15908,7 @@ function withBackendOverride(manifest, envNames, backend, key) {
15234
15908
  }
15235
15909
 
15236
15910
  // src/sync/manager.ts
15237
- var path24 = __toESM(require("path"));
15911
+ var path26 = __toESM(require("path"));
15238
15912
  var SyncManager = class {
15239
15913
  constructor(matrixManager, encryption, tx) {
15240
15914
  this.matrixManager = matrixManager;
@@ -15303,7 +15977,7 @@ var SyncManager = class {
15303
15977
  }
15304
15978
  const txPaths = [];
15305
15979
  for (const cell of syncPlan.cells) {
15306
- const rel = path24.relative(repoRoot, cell.filePath);
15980
+ const rel = path26.relative(repoRoot, cell.filePath);
15307
15981
  txPaths.push(rel);
15308
15982
  txPaths.push(rel.replace(/\.enc\.(yaml|json)$/, ".clef-meta.yaml"));
15309
15983
  }
@@ -15342,8 +16016,8 @@ var SyncManager = class {
15342
16016
  };
15343
16017
 
15344
16018
  // src/policy/parser.ts
15345
- var fs17 = __toESM(require("fs"));
15346
- var YAML11 = __toESM(require("yaml"));
16019
+ var fs20 = __toESM(require("fs"));
16020
+ var YAML12 = __toESM(require("yaml"));
15347
16021
 
15348
16022
  // src/policy/types.ts
15349
16023
  var DEFAULT_POLICY = Object.freeze({
@@ -15364,7 +16038,7 @@ var PolicyParser = class {
15364
16038
  parse(filePath) {
15365
16039
  let raw;
15366
16040
  try {
15367
- raw = fs17.readFileSync(filePath, "utf-8");
16041
+ raw = fs20.readFileSync(filePath, "utf-8");
15368
16042
  } catch {
15369
16043
  throw new PolicyValidationError(`Could not read policy file at '${filePath}'.`);
15370
16044
  }
@@ -15379,7 +16053,7 @@ var PolicyParser = class {
15379
16053
  parseContent(content) {
15380
16054
  let parsed;
15381
16055
  try {
15382
- parsed = YAML11.parse(content);
16056
+ parsed = YAML12.parse(content);
15383
16057
  } catch {
15384
16058
  throw new PolicyValidationError(
15385
16059
  "Policy file contains invalid YAML. Check for syntax errors."
@@ -15392,7 +16066,7 @@ var PolicyParser = class {
15392
16066
  * not exist. Any other read or validation error throws.
15393
16067
  */
15394
16068
  load(filePath) {
15395
- if (!fs17.existsSync(filePath)) return DEFAULT_POLICY;
16069
+ if (!fs20.existsSync(filePath)) return DEFAULT_POLICY;
15396
16070
  return this.parse(filePath);
15397
16071
  }
15398
16072
  validate(raw) {
@@ -15460,31 +16134,64 @@ var PolicyEvaluator = class {
15460
16134
  this.policy = policy;
15461
16135
  }
15462
16136
  /**
15463
- * Evaluate a single encrypted file's rotation state.
16137
+ * Evaluate a single encrypted file's per-key rotation state.
15464
16138
  *
15465
16139
  * @param filePath Repo-relative or absolute path to the encrypted file.
15466
- * @param environment Environment name from the matrix; selects per-env
15467
- * overrides if present in the policy.
15468
- * @param metadata Result of `SopsClient.getMetadata()` for the file.
15469
- * @param now Reference time (defaults to `new Date()`). Inject for
15470
- * deterministic tests and reproducible audits.
16140
+ * @param environment Environment name; selects per-env overrides.
16141
+ * @param metadata SOPS metadata for the file (carries last_modified,
16142
+ * backend, recipients). The evaluator does not read
16143
+ * `last_modified` for the policy gate it is echoed
16144
+ * into the output for audit consumers only.
16145
+ * @param keys Plaintext key names present in the cipher, enumerated
16146
+ * from the unencrypted YAML top-level keys (no decrypt
16147
+ * required since SOPS stores key names in plaintext).
16148
+ * @param rotations Rotation records from `.clef-meta.yaml`. Records for
16149
+ * keys not in `keys` are ignored (those are orphans;
16150
+ * lint surfaces them as a warning).
16151
+ * @param now Reference time. Inject for deterministic tests.
15471
16152
  */
15472
- evaluateFile(filePath, environment, metadata, now = /* @__PURE__ */ new Date()) {
16153
+ evaluateFile(filePath, environment, metadata, keys, rotations, now = /* @__PURE__ */ new Date()) {
15473
16154
  const maxAgeDays = this.resolveMaxAgeDays(environment);
15474
- const rotationDue = new Date(metadata.lastModified.getTime() + maxAgeDays * MS_PER_DAY);
15475
- const rotationOverdue = now.getTime() > rotationDue.getTime();
15476
- const daysOverdue = rotationOverdue ? Math.floor((now.getTime() - rotationDue.getTime()) / MS_PER_DAY) : 0;
16155
+ const byKey = new Map(rotations.map((r) => [r.key, r]));
16156
+ const keyStatuses = keys.map(
16157
+ (key) => this.evaluateKey(key, byKey.get(key), maxAgeDays, now)
16158
+ );
15477
16159
  return {
15478
16160
  path: filePath,
15479
16161
  environment,
15480
16162
  backend: metadata.backend,
15481
16163
  recipients: metadata.recipients,
15482
16164
  last_modified: metadata.lastModified.toISOString(),
15483
- // Treat a missing `lastModifiedPresent` as `true` — the field is
15484
- // optional on SopsMetadata and only `parseMetadataFromFile` knows
15485
- // authoritatively whether the underlying file carried `sops.lastmodified`.
15486
- // Hand-constructed metadata is assumed trustworthy.
15487
16165
  last_modified_known: metadata.lastModifiedPresent !== false,
16166
+ keys: keyStatuses,
16167
+ // Cell-level compliance is the AND of per-key verdicts. An empty
16168
+ // `keys` array (cell with no secrets) is vacuously compliant.
16169
+ compliant: keyStatuses.every((k) => k.compliant)
16170
+ };
16171
+ }
16172
+ evaluateKey(key, record, maxAgeDays, now) {
16173
+ if (!record) {
16174
+ return {
16175
+ key,
16176
+ last_rotated_at: null,
16177
+ last_rotated_known: false,
16178
+ rotated_by: null,
16179
+ rotation_count: 0,
16180
+ rotation_due: null,
16181
+ rotation_overdue: false,
16182
+ days_overdue: 0,
16183
+ compliant: false
16184
+ };
16185
+ }
16186
+ const rotationDue = new Date(record.lastRotatedAt.getTime() + maxAgeDays * MS_PER_DAY);
16187
+ const rotationOverdue = now.getTime() > rotationDue.getTime();
16188
+ const daysOverdue = rotationOverdue ? Math.floor((now.getTime() - rotationDue.getTime()) / MS_PER_DAY) : 0;
16189
+ return {
16190
+ key,
16191
+ last_rotated_at: record.lastRotatedAt.toISOString(),
16192
+ last_rotated_known: true,
16193
+ rotated_by: record.rotatedBy,
16194
+ rotation_count: record.rotationCount,
15488
16195
  rotation_due: rotationDue.toISOString(),
15489
16196
  rotation_overdue: rotationOverdue,
15490
16197
  days_overdue: daysOverdue,
@@ -15540,10 +16247,11 @@ var ComplianceGenerator = class {
15540
16247
  return `sha256:${(0, import_crypto2.createHash)("sha256").update(canonicalJson(policy)).digest("hex")}`;
15541
16248
  }
15542
16249
  buildSummary(scan, lint, files) {
16250
+ const rotationOverdue = files.filter((f) => !f.compliant).length;
15543
16251
  return {
15544
16252
  total_files: files.length,
15545
16253
  compliant: files.filter((f) => f.compliant).length,
15546
- rotation_overdue: files.filter((f) => f.rotation_overdue).length,
16254
+ rotation_overdue: rotationOverdue,
15547
16255
  scan_violations: scan.matches.length,
15548
16256
  lint_errors: lint.issues.filter((i) => i.severity === "error").length
15549
16257
  };
@@ -15551,13 +16259,13 @@ var ComplianceGenerator = class {
15551
16259
  };
15552
16260
 
15553
16261
  // src/compliance/run.ts
15554
- var path25 = __toESM(require("path"));
16262
+ var path27 = __toESM(require("path"));
15555
16263
  var UNKNOWN = "unknown";
15556
16264
  async function runCompliance(opts) {
15557
16265
  const start = Date.now();
15558
16266
  const repoRoot = opts.repoRoot ?? process.cwd();
15559
- const manifestPath = opts.manifestPath ?? path25.join(repoRoot, "clef.yaml");
15560
- const policyPath = opts.policyPath ?? path25.join(repoRoot, CLEF_POLICY_FILENAME);
16267
+ const manifestPath = opts.manifestPath ?? path27.join(repoRoot, "clef.yaml");
16268
+ const policyPath = opts.policyPath ?? path27.join(repoRoot, CLEF_POLICY_FILENAME);
15561
16269
  const include = {
15562
16270
  scan: opts.include?.scan ?? true,
15563
16271
  lint: opts.include?.lint ?? true,
@@ -15566,7 +16274,7 @@ async function runCompliance(opts) {
15566
16274
  const now = opts.now ?? /* @__PURE__ */ new Date();
15567
16275
  const manifest = new ManifestParser().parse(manifestPath);
15568
16276
  const policy = opts.policy ?? new PolicyParser().load(policyPath);
15569
- const sopsClient = new SopsClient(opts.runner);
16277
+ const sopsClient = new SopsClient(opts.runner, opts.ageKeyFile, opts.ageKey, opts.sopsPath);
15570
16278
  const matrixManager = new MatrixManager();
15571
16279
  const schemaValidator = new SchemaValidator();
15572
16280
  const [sha, repo, files, scanResult, lintResult] = await Promise.all([
@@ -15584,12 +16292,13 @@ async function runCompliance(opts) {
15584
16292
  include.scan ? new ScanRunner(opts.runner).scan(repoRoot, manifest) : Promise.resolve(emptyScan()),
15585
16293
  include.lint ? new LintRunner(matrixManager, schemaValidator, sopsClient).run(manifest, repoRoot) : Promise.resolve(emptyLint())
15586
16294
  ]);
16295
+ const adjustedLint = downgradeDecryptIssues(lintResult);
15587
16296
  const document = new ComplianceGenerator().generate({
15588
16297
  sha,
15589
16298
  repo,
15590
16299
  policy,
15591
16300
  scanResult,
15592
- lintResult,
16301
+ lintResult: adjustedLint,
15593
16302
  files,
15594
16303
  now
15595
16304
  });
@@ -15602,8 +16311,10 @@ async function evaluateMatrix(args) {
15602
16311
  return Promise.all(
15603
16312
  cells.map(async (cell) => {
15604
16313
  const metadata = await args.sopsClient.getMetadata(cell.filePath);
15605
- const relPath = path25.relative(args.repoRoot, cell.filePath).replace(/\\/g, "/");
15606
- return evaluator.evaluateFile(relPath, cell.environment, metadata, args.now);
16314
+ const relPath = path27.relative(args.repoRoot, cell.filePath).replace(/\\/g, "/");
16315
+ const keys = readSopsKeyNames(cell.filePath) ?? [];
16316
+ const rotations = await getRotations(cell.filePath);
16317
+ return evaluator.evaluateFile(relPath, cell.environment, metadata, keys, rotations, args.now);
15607
16318
  })
15608
16319
  );
15609
16320
  }
@@ -15624,6 +16335,21 @@ function emptyScan() {
15624
16335
  function emptyLint() {
15625
16336
  return { issues: [], fileCount: 0, pendingCount: 0 };
15626
16337
  }
16338
+ function downgradeDecryptIssues(result) {
16339
+ return {
16340
+ ...result,
16341
+ issues: result.issues.map((issue) => {
16342
+ if (issue.category === "sops" && issue.message.startsWith("Failed to decrypt")) {
16343
+ return {
16344
+ ...issue,
16345
+ severity: "info",
16346
+ message: `File not decryptable in this environment (compliance runs without keys). Original check: ${issue.message}`
16347
+ };
16348
+ }
16349
+ return issue;
16350
+ })
16351
+ };
16352
+ }
15627
16353
  async function detectSha(runner, repoRoot) {
15628
16354
  const env = process.env;
15629
16355
  const fromEnv = env.GITHUB_SHA ?? env.CI_COMMIT_SHA ?? env.BITBUCKET_COMMIT ?? env.CIRCLE_SHA1 ?? env.BUILD_VCS_NUMBER;
@@ -15664,11 +16390,14 @@ async function detectRepo(runner, repoRoot) {
15664
16390
  GitIntegration,
15665
16391
  GitOperationError,
15666
16392
  ImportRunner,
16393
+ InvalidArtifactError,
16394
+ JsonEnvelopeBackend,
15667
16395
  LintRunner,
15668
16396
  ManifestParser,
15669
16397
  ManifestValidationError,
15670
16398
  MatrixManager,
15671
16399
  MemoryPackOutput,
16400
+ PackBackendRegistry,
15672
16401
  PolicyEvaluator,
15673
16402
  PolicyParser,
15674
16403
  PolicyValidationError,
@@ -15697,6 +16426,7 @@ async function detectRepo(runner, repoRoot) {
15697
16426
  TransactionPreflightError,
15698
16427
  TransactionRollbackError,
15699
16428
  VALID_KMS_PROVIDERS,
16429
+ assertPackedArtifact,
15700
16430
  assertSops,
15701
16431
  buildSigningPayload,
15702
16432
  checkAll,
@@ -15712,8 +16442,11 @@ async function detectRepo(runner, repoRoot) {
15712
16442
  generateRandomValue,
15713
16443
  generateSigningKeyPair,
15714
16444
  getPendingKeys,
16445
+ getRotations,
16446
+ isClefHsmArn,
15715
16447
  isHighEntropy,
15716
16448
  isKmsEnvelope,
16449
+ isPackedArtifact,
15717
16450
  isPending,
15718
16451
  keyPreview,
15719
16452
  loadIgnoreRules,
@@ -15723,19 +16456,26 @@ async function detectRepo(runner, repoRoot) {
15723
16456
  markPendingWithRetry,
15724
16457
  markResolved,
15725
16458
  matchPatterns,
16459
+ mergeMetadataContents,
16460
+ mergeMetadataFiles,
15726
16461
  metadataPath,
15727
16462
  parse,
15728
16463
  parseDotenv,
15729
16464
  parseIgnoreContent,
15730
16465
  parseJson,
15731
16466
  parseYaml,
16467
+ pkcs11UriToSyntheticArn,
15732
16468
  readManifestYaml,
16469
+ recordRotation,
15733
16470
  redactValue,
15734
16471
  removeAccessRequest,
16472
+ removeRotation,
15735
16473
  requestsFilePath,
16474
+ resetKeyserviceResolution,
15736
16475
  resetSopsResolution,
15737
16476
  resolveBackendConfig,
15738
16477
  resolveIdentitySecrets,
16478
+ resolveKeyservicePath,
15739
16479
  resolveRecipientsForEnvironment,
15740
16480
  resolveSopsPath,
15741
16481
  runCompliance,
@@ -15746,8 +16486,12 @@ async function detectRepo(runner, repoRoot) {
15746
16486
  shouldIgnoreMatch,
15747
16487
  signEd25519,
15748
16488
  signKms,
16489
+ spawnKeyservice,
16490
+ syntheticArnToPkcs11Uri,
16491
+ tryBundledKeyservice,
15749
16492
  upsertRequest,
15750
16493
  validateAgePublicKey,
16494
+ validatePackedArtifact,
15751
16495
  validateResetScope,
15752
16496
  verifySignature,
15753
16497
  writeManifestYaml,