@clef-sh/cli 0.1.6-beta.32 → 0.1.7-beta.45

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.
package/dist/index.cjs CHANGED
@@ -966,8 +966,8 @@ var require_command = __commonJS({
966
966
  "../../node_modules/commander/lib/command.js"(exports2) {
967
967
  var EventEmitter = require("node:events").EventEmitter;
968
968
  var childProcess = require("node:child_process");
969
- var path43 = require("node:path");
970
- var fs26 = require("node:fs");
969
+ var path44 = require("node:path");
970
+ var fs27 = require("node:fs");
971
971
  var process2 = require("node:process");
972
972
  var { Argument: Argument2, humanReadableArgName } = require_argument();
973
973
  var { CommanderError: CommanderError2 } = require_error();
@@ -1899,11 +1899,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
1899
1899
  let launchWithNode = false;
1900
1900
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1901
1901
  function findFile(baseDir, baseName) {
1902
- const localBin = path43.resolve(baseDir, baseName);
1903
- if (fs26.existsSync(localBin)) return localBin;
1904
- if (sourceExt.includes(path43.extname(baseName))) return void 0;
1902
+ const localBin = path44.resolve(baseDir, baseName);
1903
+ if (fs27.existsSync(localBin)) return localBin;
1904
+ if (sourceExt.includes(path44.extname(baseName))) return void 0;
1905
1905
  const foundExt = sourceExt.find(
1906
- (ext) => fs26.existsSync(`${localBin}${ext}`)
1906
+ (ext) => fs27.existsSync(`${localBin}${ext}`)
1907
1907
  );
1908
1908
  if (foundExt) return `${localBin}${foundExt}`;
1909
1909
  return void 0;
@@ -1915,21 +1915,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
1915
1915
  if (this._scriptPath) {
1916
1916
  let resolvedScriptPath;
1917
1917
  try {
1918
- resolvedScriptPath = fs26.realpathSync(this._scriptPath);
1918
+ resolvedScriptPath = fs27.realpathSync(this._scriptPath);
1919
1919
  } catch (err) {
1920
1920
  resolvedScriptPath = this._scriptPath;
1921
1921
  }
1922
- executableDir = path43.resolve(
1923
- path43.dirname(resolvedScriptPath),
1922
+ executableDir = path44.resolve(
1923
+ path44.dirname(resolvedScriptPath),
1924
1924
  executableDir
1925
1925
  );
1926
1926
  }
1927
1927
  if (executableDir) {
1928
1928
  let localFile = findFile(executableDir, executableFile);
1929
1929
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
1930
- const legacyName = path43.basename(
1930
+ const legacyName = path44.basename(
1931
1931
  this._scriptPath,
1932
- path43.extname(this._scriptPath)
1932
+ path44.extname(this._scriptPath)
1933
1933
  );
1934
1934
  if (legacyName !== this._name) {
1935
1935
  localFile = findFile(
@@ -1940,7 +1940,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1940
1940
  }
1941
1941
  executableFile = localFile || executableFile;
1942
1942
  }
1943
- launchWithNode = sourceExt.includes(path43.extname(executableFile));
1943
+ launchWithNode = sourceExt.includes(path44.extname(executableFile));
1944
1944
  let proc;
1945
1945
  if (process2.platform !== "win32") {
1946
1946
  if (launchWithNode) {
@@ -2780,7 +2780,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2780
2780
  * @return {Command}
2781
2781
  */
2782
2782
  nameFromFilename(filename) {
2783
- this._name = path43.basename(filename, path43.extname(filename));
2783
+ this._name = path44.basename(filename, path44.extname(filename));
2784
2784
  return this;
2785
2785
  }
2786
2786
  /**
@@ -2794,9 +2794,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
2794
2794
  * @param {string} [path]
2795
2795
  * @return {(string|null|Command)}
2796
2796
  */
2797
- executableDir(path44) {
2798
- if (path44 === void 0) return this._executableDir;
2799
- this._executableDir = path44;
2797
+ executableDir(path45) {
2798
+ if (path45 === void 0) return this._executableDir;
2799
+ this._executableDir = path45;
2800
2800
  return this;
2801
2801
  }
2802
2802
  /**
@@ -3103,17 +3103,17 @@ var require_visit = __commonJS({
3103
3103
  visit.BREAK = BREAK;
3104
3104
  visit.SKIP = SKIP;
3105
3105
  visit.REMOVE = REMOVE;
3106
- function visit_(key, node, visitor, path43) {
3107
- const ctrl = callVisitor(key, node, visitor, path43);
3106
+ function visit_(key, node, visitor, path44) {
3107
+ const ctrl = callVisitor(key, node, visitor, path44);
3108
3108
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3109
- replaceNode(key, path43, ctrl);
3110
- return visit_(key, ctrl, visitor, path43);
3109
+ replaceNode(key, path44, ctrl);
3110
+ return visit_(key, ctrl, visitor, path44);
3111
3111
  }
3112
3112
  if (typeof ctrl !== "symbol") {
3113
3113
  if (identity.isCollection(node)) {
3114
- path43 = Object.freeze(path43.concat(node));
3114
+ path44 = Object.freeze(path44.concat(node));
3115
3115
  for (let i = 0; i < node.items.length; ++i) {
3116
- const ci = visit_(i, node.items[i], visitor, path43);
3116
+ const ci = visit_(i, node.items[i], visitor, path44);
3117
3117
  if (typeof ci === "number")
3118
3118
  i = ci - 1;
3119
3119
  else if (ci === BREAK)
@@ -3124,13 +3124,13 @@ var require_visit = __commonJS({
3124
3124
  }
3125
3125
  }
3126
3126
  } else if (identity.isPair(node)) {
3127
- path43 = Object.freeze(path43.concat(node));
3128
- const ck = visit_("key", node.key, visitor, path43);
3127
+ path44 = Object.freeze(path44.concat(node));
3128
+ const ck = visit_("key", node.key, visitor, path44);
3129
3129
  if (ck === BREAK)
3130
3130
  return BREAK;
3131
3131
  else if (ck === REMOVE)
3132
3132
  node.key = null;
3133
- const cv = visit_("value", node.value, visitor, path43);
3133
+ const cv = visit_("value", node.value, visitor, path44);
3134
3134
  if (cv === BREAK)
3135
3135
  return BREAK;
3136
3136
  else if (cv === REMOVE)
@@ -3151,17 +3151,17 @@ var require_visit = __commonJS({
3151
3151
  visitAsync.BREAK = BREAK;
3152
3152
  visitAsync.SKIP = SKIP;
3153
3153
  visitAsync.REMOVE = REMOVE;
3154
- async function visitAsync_(key, node, visitor, path43) {
3155
- const ctrl = await callVisitor(key, node, visitor, path43);
3154
+ async function visitAsync_(key, node, visitor, path44) {
3155
+ const ctrl = await callVisitor(key, node, visitor, path44);
3156
3156
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3157
- replaceNode(key, path43, ctrl);
3158
- return visitAsync_(key, ctrl, visitor, path43);
3157
+ replaceNode(key, path44, ctrl);
3158
+ return visitAsync_(key, ctrl, visitor, path44);
3159
3159
  }
3160
3160
  if (typeof ctrl !== "symbol") {
3161
3161
  if (identity.isCollection(node)) {
3162
- path43 = Object.freeze(path43.concat(node));
3162
+ path44 = Object.freeze(path44.concat(node));
3163
3163
  for (let i = 0; i < node.items.length; ++i) {
3164
- const ci = await visitAsync_(i, node.items[i], visitor, path43);
3164
+ const ci = await visitAsync_(i, node.items[i], visitor, path44);
3165
3165
  if (typeof ci === "number")
3166
3166
  i = ci - 1;
3167
3167
  else if (ci === BREAK)
@@ -3172,13 +3172,13 @@ var require_visit = __commonJS({
3172
3172
  }
3173
3173
  }
3174
3174
  } else if (identity.isPair(node)) {
3175
- path43 = Object.freeze(path43.concat(node));
3176
- const ck = await visitAsync_("key", node.key, visitor, path43);
3175
+ path44 = Object.freeze(path44.concat(node));
3176
+ const ck = await visitAsync_("key", node.key, visitor, path44);
3177
3177
  if (ck === BREAK)
3178
3178
  return BREAK;
3179
3179
  else if (ck === REMOVE)
3180
3180
  node.key = null;
3181
- const cv = await visitAsync_("value", node.value, visitor, path43);
3181
+ const cv = await visitAsync_("value", node.value, visitor, path44);
3182
3182
  if (cv === BREAK)
3183
3183
  return BREAK;
3184
3184
  else if (cv === REMOVE)
@@ -3205,23 +3205,23 @@ var require_visit = __commonJS({
3205
3205
  }
3206
3206
  return visitor;
3207
3207
  }
3208
- function callVisitor(key, node, visitor, path43) {
3208
+ function callVisitor(key, node, visitor, path44) {
3209
3209
  if (typeof visitor === "function")
3210
- return visitor(key, node, path43);
3210
+ return visitor(key, node, path44);
3211
3211
  if (identity.isMap(node))
3212
- return visitor.Map?.(key, node, path43);
3212
+ return visitor.Map?.(key, node, path44);
3213
3213
  if (identity.isSeq(node))
3214
- return visitor.Seq?.(key, node, path43);
3214
+ return visitor.Seq?.(key, node, path44);
3215
3215
  if (identity.isPair(node))
3216
- return visitor.Pair?.(key, node, path43);
3216
+ return visitor.Pair?.(key, node, path44);
3217
3217
  if (identity.isScalar(node))
3218
- return visitor.Scalar?.(key, node, path43);
3218
+ return visitor.Scalar?.(key, node, path44);
3219
3219
  if (identity.isAlias(node))
3220
- return visitor.Alias?.(key, node, path43);
3220
+ return visitor.Alias?.(key, node, path44);
3221
3221
  return void 0;
3222
3222
  }
3223
- function replaceNode(key, path43, node) {
3224
- const parent = path43[path43.length - 1];
3223
+ function replaceNode(key, path44, node) {
3224
+ const parent = path44[path44.length - 1];
3225
3225
  if (identity.isCollection(parent)) {
3226
3226
  parent.items[key] = node;
3227
3227
  } else if (identity.isPair(parent)) {
@@ -3829,10 +3829,10 @@ var require_Collection = __commonJS({
3829
3829
  var createNode = require_createNode();
3830
3830
  var identity = require_identity();
3831
3831
  var Node = require_Node();
3832
- function collectionFromPath(schema, path43, value) {
3832
+ function collectionFromPath(schema, path44, value) {
3833
3833
  let v = value;
3834
- for (let i = path43.length - 1; i >= 0; --i) {
3835
- const k = path43[i];
3834
+ for (let i = path44.length - 1; i >= 0; --i) {
3835
+ const k = path44[i];
3836
3836
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
3837
3837
  const a = [];
3838
3838
  a[k] = v;
@@ -3851,7 +3851,7 @@ var require_Collection = __commonJS({
3851
3851
  sourceObjects: /* @__PURE__ */ new Map()
3852
3852
  });
3853
3853
  }
3854
- var isEmptyPath = (path43) => path43 == null || typeof path43 === "object" && !!path43[Symbol.iterator]().next().done;
3854
+ var isEmptyPath = (path44) => path44 == null || typeof path44 === "object" && !!path44[Symbol.iterator]().next().done;
3855
3855
  var Collection = class extends Node.NodeBase {
3856
3856
  constructor(type, schema) {
3857
3857
  super(type);
@@ -3881,11 +3881,11 @@ var require_Collection = __commonJS({
3881
3881
  * be a Pair instance or a `{ key, value }` object, which may not have a key
3882
3882
  * that already exists in the map.
3883
3883
  */
3884
- addIn(path43, value) {
3885
- if (isEmptyPath(path43))
3884
+ addIn(path44, value) {
3885
+ if (isEmptyPath(path44))
3886
3886
  this.add(value);
3887
3887
  else {
3888
- const [key, ...rest] = path43;
3888
+ const [key, ...rest] = path44;
3889
3889
  const node = this.get(key, true);
3890
3890
  if (identity.isCollection(node))
3891
3891
  node.addIn(rest, value);
@@ -3899,8 +3899,8 @@ var require_Collection = __commonJS({
3899
3899
  * Removes a value from the collection.
3900
3900
  * @returns `true` if the item was found and removed.
3901
3901
  */
3902
- deleteIn(path43) {
3903
- const [key, ...rest] = path43;
3902
+ deleteIn(path44) {
3903
+ const [key, ...rest] = path44;
3904
3904
  if (rest.length === 0)
3905
3905
  return this.delete(key);
3906
3906
  const node = this.get(key, true);
@@ -3914,8 +3914,8 @@ var require_Collection = __commonJS({
3914
3914
  * scalar values from their surrounding node; to disable set `keepScalar` to
3915
3915
  * `true` (collections are always returned intact).
3916
3916
  */
3917
- getIn(path43, keepScalar) {
3918
- const [key, ...rest] = path43;
3917
+ getIn(path44, keepScalar) {
3918
+ const [key, ...rest] = path44;
3919
3919
  const node = this.get(key, true);
3920
3920
  if (rest.length === 0)
3921
3921
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -3933,8 +3933,8 @@ var require_Collection = __commonJS({
3933
3933
  /**
3934
3934
  * Checks if the collection includes a value with the key `key`.
3935
3935
  */
3936
- hasIn(path43) {
3937
- const [key, ...rest] = path43;
3936
+ hasIn(path44) {
3937
+ const [key, ...rest] = path44;
3938
3938
  if (rest.length === 0)
3939
3939
  return this.has(key);
3940
3940
  const node = this.get(key, true);
@@ -3944,8 +3944,8 @@ var require_Collection = __commonJS({
3944
3944
  * Sets a value in this collection. For `!!set`, `value` needs to be a
3945
3945
  * boolean to add/remove the item from the set.
3946
3946
  */
3947
- setIn(path43, value) {
3948
- const [key, ...rest] = path43;
3947
+ setIn(path44, value) {
3948
+ const [key, ...rest] = path44;
3949
3949
  if (rest.length === 0) {
3950
3950
  this.set(key, value);
3951
3951
  } else {
@@ -6449,9 +6449,9 @@ var require_Document = __commonJS({
6449
6449
  this.contents.add(value);
6450
6450
  }
6451
6451
  /** Adds a value to the document. */
6452
- addIn(path43, value) {
6452
+ addIn(path44, value) {
6453
6453
  if (assertCollection(this.contents))
6454
- this.contents.addIn(path43, value);
6454
+ this.contents.addIn(path44, value);
6455
6455
  }
6456
6456
  /**
6457
6457
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -6526,14 +6526,14 @@ var require_Document = __commonJS({
6526
6526
  * Removes a value from the document.
6527
6527
  * @returns `true` if the item was found and removed.
6528
6528
  */
6529
- deleteIn(path43) {
6530
- if (Collection.isEmptyPath(path43)) {
6529
+ deleteIn(path44) {
6530
+ if (Collection.isEmptyPath(path44)) {
6531
6531
  if (this.contents == null)
6532
6532
  return false;
6533
6533
  this.contents = null;
6534
6534
  return true;
6535
6535
  }
6536
- return assertCollection(this.contents) ? this.contents.deleteIn(path43) : false;
6536
+ return assertCollection(this.contents) ? this.contents.deleteIn(path44) : false;
6537
6537
  }
6538
6538
  /**
6539
6539
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -6548,10 +6548,10 @@ var require_Document = __commonJS({
6548
6548
  * scalar values from their surrounding node; to disable set `keepScalar` to
6549
6549
  * `true` (collections are always returned intact).
6550
6550
  */
6551
- getIn(path43, keepScalar) {
6552
- if (Collection.isEmptyPath(path43))
6551
+ getIn(path44, keepScalar) {
6552
+ if (Collection.isEmptyPath(path44))
6553
6553
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
6554
- return identity.isCollection(this.contents) ? this.contents.getIn(path43, keepScalar) : void 0;
6554
+ return identity.isCollection(this.contents) ? this.contents.getIn(path44, keepScalar) : void 0;
6555
6555
  }
6556
6556
  /**
6557
6557
  * Checks if the document includes a value with the key `key`.
@@ -6562,10 +6562,10 @@ var require_Document = __commonJS({
6562
6562
  /**
6563
6563
  * Checks if the document includes a value at `path`.
6564
6564
  */
6565
- hasIn(path43) {
6566
- if (Collection.isEmptyPath(path43))
6565
+ hasIn(path44) {
6566
+ if (Collection.isEmptyPath(path44))
6567
6567
  return this.contents !== void 0;
6568
- return identity.isCollection(this.contents) ? this.contents.hasIn(path43) : false;
6568
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path44) : false;
6569
6569
  }
6570
6570
  /**
6571
6571
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -6582,13 +6582,13 @@ var require_Document = __commonJS({
6582
6582
  * Sets a value in this document. For `!!set`, `value` needs to be a
6583
6583
  * boolean to add/remove the item from the set.
6584
6584
  */
6585
- setIn(path43, value) {
6586
- if (Collection.isEmptyPath(path43)) {
6585
+ setIn(path44, value) {
6586
+ if (Collection.isEmptyPath(path44)) {
6587
6587
  this.contents = value;
6588
6588
  } else if (this.contents == null) {
6589
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path43), value);
6589
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path44), value);
6590
6590
  } else if (assertCollection(this.contents)) {
6591
- this.contents.setIn(path43, value);
6591
+ this.contents.setIn(path44, value);
6592
6592
  }
6593
6593
  }
6594
6594
  /**
@@ -8540,9 +8540,9 @@ var require_cst_visit = __commonJS({
8540
8540
  visit.BREAK = BREAK;
8541
8541
  visit.SKIP = SKIP;
8542
8542
  visit.REMOVE = REMOVE;
8543
- visit.itemAtPath = (cst, path43) => {
8543
+ visit.itemAtPath = (cst, path44) => {
8544
8544
  let item = cst;
8545
- for (const [field, index] of path43) {
8545
+ for (const [field, index] of path44) {
8546
8546
  const tok = item?.[field];
8547
8547
  if (tok && "items" in tok) {
8548
8548
  item = tok.items[index];
@@ -8551,23 +8551,23 @@ var require_cst_visit = __commonJS({
8551
8551
  }
8552
8552
  return item;
8553
8553
  };
8554
- visit.parentCollection = (cst, path43) => {
8555
- const parent = visit.itemAtPath(cst, path43.slice(0, -1));
8556
- const field = path43[path43.length - 1][0];
8554
+ visit.parentCollection = (cst, path44) => {
8555
+ const parent = visit.itemAtPath(cst, path44.slice(0, -1));
8556
+ const field = path44[path44.length - 1][0];
8557
8557
  const coll = parent?.[field];
8558
8558
  if (coll && "items" in coll)
8559
8559
  return coll;
8560
8560
  throw new Error("Parent collection not found");
8561
8561
  };
8562
- function _visit(path43, item, visitor) {
8563
- let ctrl = visitor(item, path43);
8562
+ function _visit(path44, item, visitor) {
8563
+ let ctrl = visitor(item, path44);
8564
8564
  if (typeof ctrl === "symbol")
8565
8565
  return ctrl;
8566
8566
  for (const field of ["key", "value"]) {
8567
8567
  const token = item[field];
8568
8568
  if (token && "items" in token) {
8569
8569
  for (let i = 0; i < token.items.length; ++i) {
8570
- const ci = _visit(Object.freeze(path43.concat([[field, i]])), token.items[i], visitor);
8570
+ const ci = _visit(Object.freeze(path44.concat([[field, i]])), token.items[i], visitor);
8571
8571
  if (typeof ci === "number")
8572
8572
  i = ci - 1;
8573
8573
  else if (ci === BREAK)
@@ -8578,10 +8578,10 @@ var require_cst_visit = __commonJS({
8578
8578
  }
8579
8579
  }
8580
8580
  if (typeof ctrl === "function" && field === "key")
8581
- ctrl = ctrl(item, path43);
8581
+ ctrl = ctrl(item, path44);
8582
8582
  }
8583
8583
  }
8584
- return typeof ctrl === "function" ? ctrl(item, path43) : ctrl;
8584
+ return typeof ctrl === "function" ? ctrl(item, path44) : ctrl;
8585
8585
  }
8586
8586
  exports2.visit = visit;
8587
8587
  }
@@ -9866,14 +9866,14 @@ var require_parser = __commonJS({
9866
9866
  case "scalar":
9867
9867
  case "single-quoted-scalar":
9868
9868
  case "double-quoted-scalar": {
9869
- const fs26 = this.flowScalar(this.type);
9869
+ const fs27 = this.flowScalar(this.type);
9870
9870
  if (atNextItem || it.value) {
9871
- map.items.push({ start, key: fs26, sep: [] });
9871
+ map.items.push({ start, key: fs27, sep: [] });
9872
9872
  this.onKeyLine = true;
9873
9873
  } else if (it.sep) {
9874
- this.stack.push(fs26);
9874
+ this.stack.push(fs27);
9875
9875
  } else {
9876
- Object.assign(it, { key: fs26, sep: [] });
9876
+ Object.assign(it, { key: fs27, sep: [] });
9877
9877
  this.onKeyLine = true;
9878
9878
  }
9879
9879
  return;
@@ -10001,13 +10001,13 @@ var require_parser = __commonJS({
10001
10001
  case "scalar":
10002
10002
  case "single-quoted-scalar":
10003
10003
  case "double-quoted-scalar": {
10004
- const fs26 = this.flowScalar(this.type);
10004
+ const fs27 = this.flowScalar(this.type);
10005
10005
  if (!it || it.value)
10006
- fc.items.push({ start: [], key: fs26, sep: [] });
10006
+ fc.items.push({ start: [], key: fs27, sep: [] });
10007
10007
  else if (it.sep)
10008
- this.stack.push(fs26);
10008
+ this.stack.push(fs27);
10009
10009
  else
10010
- Object.assign(it, { key: fs26, sep: [] });
10010
+ Object.assign(it, { key: fs27, sep: [] });
10011
10011
  return;
10012
10012
  }
10013
10013
  case "flow-map-end":
@@ -10215,7 +10215,7 @@ var require_public_api = __commonJS({
10215
10215
  }
10216
10216
  return doc;
10217
10217
  }
10218
- function parse15(src, reviver, options) {
10218
+ function parse16(src, reviver, options) {
10219
10219
  let _reviver = void 0;
10220
10220
  if (typeof reviver === "function") {
10221
10221
  _reviver = reviver;
@@ -10256,7 +10256,7 @@ var require_public_api = __commonJS({
10256
10256
  return value.toString(options);
10257
10257
  return new Document.Document(value, _replacer, options).toString(options);
10258
10258
  }
10259
- exports2.parse = parse15;
10259
+ exports2.parse = parse16;
10260
10260
  exports2.parseAllDocuments = parseAllDocuments;
10261
10261
  exports2.parseDocument = parseDocument;
10262
10262
  exports2.stringify = stringify7;
@@ -11452,12 +11452,13 @@ var init_metadata = __esm({
11452
11452
  });
11453
11453
 
11454
11454
  // ../core/src/matrix/manager.ts
11455
- var fs5, path4, MatrixManager;
11455
+ var fs5, path4, YAML3, MatrixManager;
11456
11456
  var init_manager = __esm({
11457
11457
  "../core/src/matrix/manager.ts"() {
11458
11458
  "use strict";
11459
11459
  fs5 = __toESM(require("fs"));
11460
11460
  path4 = __toESM(require("path"));
11461
+ YAML3 = __toESM(require_dist());
11461
11462
  init_metadata();
11462
11463
  MatrixManager = class {
11463
11464
  /**
@@ -11513,9 +11514,15 @@ var init_manager = __esm({
11513
11514
  * @param repoRoot - Absolute path to the repository root.
11514
11515
  * @param sopsClient - SOPS client used to decrypt each cell.
11515
11516
  */
11516
- async getMatrixStatus(manifest, repoRoot, sopsClient) {
11517
+ async getMatrixStatus(manifest, repoRoot, _sopsClient) {
11517
11518
  const cells = this.resolveMatrix(manifest, repoRoot);
11518
11519
  const statuses = [];
11520
+ const cellKeys = /* @__PURE__ */ new Map();
11521
+ for (const cell of cells) {
11522
+ if (cell.exists) {
11523
+ cellKeys.set(cell.filePath, this.readKeyNames(cell.filePath));
11524
+ }
11525
+ }
11519
11526
  for (const cell of cells) {
11520
11527
  if (!cell.exists) {
11521
11528
  statuses.push({
@@ -11538,48 +11545,56 @@ var init_manager = __esm({
11538
11545
  pendingCount = pending.length;
11539
11546
  } catch {
11540
11547
  }
11541
- try {
11542
- const decrypted = await sopsClient.decrypt(cell.filePath);
11543
- const keyCount = Object.keys(decrypted.values).length;
11544
- const lastModified = decrypted.metadata.lastModified;
11545
- const issues = [];
11546
- const siblingCells = cells.filter(
11547
- (c) => c.namespace === cell.namespace && c.environment !== cell.environment && c.exists
11548
- );
11549
- for (const sibling of siblingCells) {
11550
- try {
11551
- const siblingDecrypted = await sopsClient.decrypt(sibling.filePath);
11552
- const siblingKeys = Object.keys(siblingDecrypted.values);
11553
- const currentKeys = Object.keys(decrypted.values);
11554
- const missingKeys = siblingKeys.filter((k) => !currentKeys.includes(k));
11555
- for (const mk of missingKeys) {
11556
- issues.push({
11557
- type: "missing_keys",
11558
- message: `Key '${mk}' exists in ${sibling.environment} but is missing here.`,
11559
- key: mk
11560
- });
11561
- }
11562
- } catch {
11563
- }
11548
+ const keys = cellKeys.get(cell.filePath) ?? [];
11549
+ const keyCount = keys.length;
11550
+ const lastModified = this.readLastModified(cell.filePath);
11551
+ const issues = [];
11552
+ const siblingCells = cells.filter(
11553
+ (c) => c.namespace === cell.namespace && c.environment !== cell.environment && c.exists
11554
+ );
11555
+ for (const sibling of siblingCells) {
11556
+ const siblingKeys = cellKeys.get(sibling.filePath) ?? [];
11557
+ const missingKeys = siblingKeys.filter((k) => !keys.includes(k));
11558
+ for (const mk of missingKeys) {
11559
+ issues.push({
11560
+ type: "missing_keys",
11561
+ message: `Key '${mk}' exists in ${sibling.environment} but is missing here.`,
11562
+ key: mk
11563
+ });
11564
11564
  }
11565
- statuses.push({ cell, keyCount, pendingCount, lastModified, issues });
11566
- } catch {
11567
- statuses.push({
11568
- cell,
11569
- keyCount: 0,
11570
- pendingCount: 0,
11571
- lastModified: null,
11572
- issues: [
11573
- {
11574
- type: "sops_error",
11575
- message: `Could not decrypt '${cell.filePath}'. Check your key configuration.`
11576
- }
11577
- ]
11578
- });
11579
11565
  }
11566
+ statuses.push({ cell, keyCount, pendingCount, lastModified, issues });
11580
11567
  }
11581
11568
  return statuses;
11582
11569
  }
11570
+ /**
11571
+ * Read top-level key names from a SOPS file without decryption.
11572
+ * SOPS stores key names in plaintext — only values are encrypted.
11573
+ */
11574
+ readKeyNames(filePath) {
11575
+ try {
11576
+ const raw = fs5.readFileSync(filePath, "utf-8");
11577
+ const parsed = YAML3.parse(raw);
11578
+ if (!parsed || typeof parsed !== "object") return [];
11579
+ return Object.keys(parsed).filter((k) => k !== "sops");
11580
+ } catch {
11581
+ return [];
11582
+ }
11583
+ }
11584
+ /**
11585
+ * Read the lastModified timestamp from SOPS metadata without decryption.
11586
+ */
11587
+ readLastModified(filePath) {
11588
+ try {
11589
+ const raw = fs5.readFileSync(filePath, "utf-8");
11590
+ const parsed = YAML3.parse(raw);
11591
+ const sops = parsed?.sops;
11592
+ if (sops?.lastmodified) return new Date(String(sops.lastmodified));
11593
+ return null;
11594
+ } catch {
11595
+ return null;
11596
+ }
11597
+ }
11583
11598
  /**
11584
11599
  * Check whether an environment has the `protected` flag set in the manifest.
11585
11600
  *
@@ -11595,12 +11610,12 @@ var init_manager = __esm({
11595
11610
  });
11596
11611
 
11597
11612
  // ../core/src/schema/validator.ts
11598
- var fs6, YAML3, SchemaValidator;
11613
+ var fs6, YAML4, SchemaValidator;
11599
11614
  var init_validator2 = __esm({
11600
11615
  "../core/src/schema/validator.ts"() {
11601
11616
  "use strict";
11602
11617
  fs6 = __toESM(require("fs"));
11603
- YAML3 = __toESM(require_dist());
11618
+ YAML4 = __toESM(require_dist());
11604
11619
  init_types();
11605
11620
  SchemaValidator = class {
11606
11621
  /**
@@ -11619,7 +11634,7 @@ var init_validator2 = __esm({
11619
11634
  }
11620
11635
  let parsed;
11621
11636
  try {
11622
- parsed = YAML3.parse(raw);
11637
+ parsed = YAML4.parse(raw);
11623
11638
  } catch {
11624
11639
  throw new SchemaLoadError(`Schema file '${filePath}' contains invalid YAML.`, filePath);
11625
11640
  }
@@ -12951,7 +12966,7 @@ var require_age_encryption = __commonJS({
12951
12966
  };
12952
12967
  }
12953
12968
  // @__NO_SIDE_EFFECTS__
12954
- function join38(separator = "") {
12969
+ function join39(separator = "") {
12955
12970
  astr("join", separator);
12956
12971
  return {
12957
12972
  encode: (from) => {
@@ -13081,9 +13096,9 @@ var require_age_encryption = __commonJS({
13081
13096
  decode(s) {
13082
13097
  return decodeBase64Builtin(s, false);
13083
13098
  }
13084
- } : /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */ join38(""));
13085
- var base64nopad = /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ join38(""));
13086
- var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join38(""));
13099
+ } : /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */ join39(""));
13100
+ var base64nopad = /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ join39(""));
13101
+ var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join39(""));
13087
13102
  var POLYMOD_GENERATORS = [996825010, 642813549, 513874426, 1027748829, 705979059];
13088
13103
  function bech32Polymod(pre) {
13089
13104
  const b = pre >> 25;
@@ -19299,14 +19314,14 @@ function openWindowsInputPipe(content) {
19299
19314
  });
19300
19315
  });
19301
19316
  }
19302
- var fs10, net, import_crypto, YAML4, SopsClient;
19317
+ var fs10, net, import_crypto, YAML5, SopsClient;
19303
19318
  var init_client = __esm({
19304
19319
  "../core/src/sops/client.ts"() {
19305
19320
  "use strict";
19306
19321
  fs10 = __toESM(require("fs"));
19307
19322
  net = __toESM(require("net"));
19308
19323
  import_crypto = require("crypto");
19309
- YAML4 = __toESM(require_dist());
19324
+ YAML5 = __toESM(require_dist());
19310
19325
  init_types();
19311
19326
  init_checker();
19312
19327
  init_keygen();
@@ -19371,7 +19386,7 @@ var init_client = __esm({
19371
19386
  }
19372
19387
  let parsed;
19373
19388
  try {
19374
- parsed = YAML4.parse(result.stdout) ?? {};
19389
+ parsed = YAML5.parse(result.stdout) ?? {};
19375
19390
  } catch {
19376
19391
  throw new SopsDecryptionError(
19377
19392
  `Decrypted content of '${filePath}' is not valid YAML.`,
@@ -19398,7 +19413,7 @@ var init_client = __esm({
19398
19413
  async encrypt(filePath, values, manifest, environment) {
19399
19414
  await assertSops(this.runner, this.sopsCommand);
19400
19415
  const fmt = formatFromPath(filePath);
19401
- const content = fmt === "json" ? JSON.stringify(values, null, 2) : YAML4.stringify(values);
19416
+ const content = fmt === "json" ? JSON.stringify(values, null, 2) : YAML5.stringify(values);
19402
19417
  const args = this.buildEncryptArgs(filePath, manifest, environment);
19403
19418
  const env = this.buildSopsEnv();
19404
19419
  let inputArg;
@@ -19598,7 +19613,7 @@ var init_client = __esm({
19598
19613
  }
19599
19614
  let parsed;
19600
19615
  try {
19601
- parsed = YAML4.parse(content);
19616
+ parsed = YAML5.parse(content);
19602
19617
  } catch {
19603
19618
  throw new SopsDecryptionError(
19604
19619
  `File '${filePath}' is not valid YAML. Cannot extract SOPS metadata.`,
@@ -19907,7 +19922,7 @@ var init_runner = __esm({
19907
19922
  /**
19908
19923
  * Lint service identity configurations for drift issues.
19909
19924
  */
19910
- async lintServiceIdentities(identities, manifest, _repoRoot, existingCells) {
19925
+ async lintServiceIdentities(identities, manifest, repoRoot, existingCells) {
19911
19926
  const issues = [];
19912
19927
  const declaredEnvNames = new Set(manifest.environments.map((e) => e.name));
19913
19928
  const declaredNsNames = new Set(manifest.namespaces.map((ns) => ns.name));
@@ -20065,7 +20080,7 @@ function detectFormat(filePath, content) {
20065
20080
  } catch {
20066
20081
  }
20067
20082
  try {
20068
- const parsed = YAML5.parse(content);
20083
+ const parsed = YAML6.parse(content);
20069
20084
  if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
20070
20085
  return "yaml";
20071
20086
  }
@@ -20146,7 +20161,7 @@ function parseJson(content) {
20146
20161
  function parseYaml(content) {
20147
20162
  let parsed;
20148
20163
  try {
20149
- parsed = YAML5.parse(content);
20164
+ parsed = YAML6.parse(content);
20150
20165
  } catch (err) {
20151
20166
  throw new Error(`Invalid YAML: ${err.message}`);
20152
20167
  }
@@ -20180,7 +20195,7 @@ function parseYaml(content) {
20180
20195
  }
20181
20196
  return { pairs, format: "yaml", skipped, warnings };
20182
20197
  }
20183
- function parse6(content, format, filePath) {
20198
+ function parse7(content, format, filePath) {
20184
20199
  const resolved = format === "auto" ? detectFormat(filePath ?? "", content) : format;
20185
20200
  switch (resolved) {
20186
20201
  case "dotenv":
@@ -20191,12 +20206,12 @@ function parse6(content, format, filePath) {
20191
20206
  return parseYaml(content);
20192
20207
  }
20193
20208
  }
20194
- var path11, YAML5;
20209
+ var path11, YAML6;
20195
20210
  var init_parsers = __esm({
20196
20211
  "../core/src/import/parsers.ts"() {
20197
20212
  "use strict";
20198
20213
  path11 = __toESM(require("path"));
20199
- YAML5 = __toESM(require_dist());
20214
+ YAML6 = __toESM(require_dist());
20200
20215
  }
20201
20216
  });
20202
20217
 
@@ -20227,7 +20242,7 @@ var init_import = __esm({
20227
20242
  repoRoot,
20228
20243
  manifest.file_pattern.replace("{namespace}", ns).replace("{environment}", env)
20229
20244
  );
20230
- const parsed = parse6(content, options.format ?? "auto", sourcePath ?? "");
20245
+ const parsed = parse7(content, options.format ?? "auto", sourcePath ?? "");
20231
20246
  let candidates = Object.entries(parsed.pairs);
20232
20247
  if (options.prefix) {
20233
20248
  const prefix = options.prefix;
@@ -20306,11 +20321,11 @@ function toRecipient(entry) {
20306
20321
  function readManifestYaml(repoRoot) {
20307
20322
  const manifestPath = path13.join(repoRoot, CLEF_MANIFEST_FILENAME);
20308
20323
  const raw = fs11.readFileSync(manifestPath, "utf-8");
20309
- return YAML6.parse(raw);
20324
+ return YAML7.parse(raw);
20310
20325
  }
20311
20326
  function writeManifestYaml(repoRoot, doc) {
20312
20327
  const manifestPath = path13.join(repoRoot, CLEF_MANIFEST_FILENAME);
20313
- fs11.writeFileSync(manifestPath, YAML6.stringify(doc), "utf-8");
20328
+ fs11.writeFileSync(manifestPath, YAML7.stringify(doc), "utf-8");
20314
20329
  }
20315
20330
  function getRecipientsArray(doc) {
20316
20331
  const sops = doc.sops;
@@ -20358,13 +20373,13 @@ function ensureEnvironmentRecipientsArray(doc, envName) {
20358
20373
  }
20359
20374
  return env.recipients;
20360
20375
  }
20361
- var fs11, path13, YAML6, RecipientManager;
20376
+ var fs11, path13, YAML7, RecipientManager;
20362
20377
  var init_recipients = __esm({
20363
20378
  "../core/src/recipients/index.ts"() {
20364
20379
  "use strict";
20365
20380
  fs11 = __toESM(require("fs"));
20366
20381
  path13 = __toESM(require("path"));
20367
- YAML6 = __toESM(require_dist());
20382
+ YAML7 = __toESM(require_dist());
20368
20383
  init_validator();
20369
20384
  init_parser();
20370
20385
  RecipientManager = class {
@@ -20562,7 +20577,7 @@ function loadRequests(repoRoot) {
20562
20577
  try {
20563
20578
  if (!fs12.existsSync(filePath)) return [];
20564
20579
  const content = fs12.readFileSync(filePath, "utf-8");
20565
- const parsed = YAML7.parse(content);
20580
+ const parsed = YAML8.parse(content);
20566
20581
  if (!parsed || !Array.isArray(parsed.requests)) return [];
20567
20582
  return parsed.requests.map((r) => ({
20568
20583
  key: r.key,
@@ -20594,7 +20609,7 @@ function saveRequests(repoRoot, requests) {
20594
20609
  return raw;
20595
20610
  })
20596
20611
  };
20597
- fs12.writeFileSync(filePath, HEADER_COMMENT2 + YAML7.stringify(data), "utf-8");
20612
+ fs12.writeFileSync(filePath, HEADER_COMMENT2 + YAML8.stringify(data), "utf-8");
20598
20613
  }
20599
20614
  function upsertRequest(repoRoot, key, label, environment) {
20600
20615
  const requests = loadRequests(repoRoot);
@@ -20628,26 +20643,26 @@ function findInList(requests, identifier) {
20628
20643
  const byKey = requests.find((r) => r.key === identifier);
20629
20644
  return byKey ?? null;
20630
20645
  }
20631
- var fs12, path14, YAML7, REQUESTS_FILENAME, HEADER_COMMENT2;
20646
+ var fs12, path14, YAML8, REQUESTS_FILENAME, HEADER_COMMENT2;
20632
20647
  var init_requests = __esm({
20633
20648
  "../core/src/recipients/requests.ts"() {
20634
20649
  "use strict";
20635
20650
  fs12 = __toESM(require("fs"));
20636
20651
  path14 = __toESM(require("path"));
20637
- YAML7 = __toESM(require_dist());
20652
+ YAML8 = __toESM(require_dist());
20638
20653
  REQUESTS_FILENAME = ".clef-requests.yaml";
20639
20654
  HEADER_COMMENT2 = "# Pending recipient access requests. Approve with: clef recipients approve <label>\n";
20640
20655
  }
20641
20656
  });
20642
20657
 
20643
20658
  // ../core/src/drift/detector.ts
20644
- var fs13, path15, YAML8, DriftDetector;
20659
+ var fs13, path15, YAML9, DriftDetector;
20645
20660
  var init_detector = __esm({
20646
20661
  "../core/src/drift/detector.ts"() {
20647
20662
  "use strict";
20648
20663
  fs13 = __toESM(require("fs"));
20649
20664
  path15 = __toESM(require("path"));
20650
- YAML8 = __toESM(require_dist());
20665
+ YAML9 = __toESM(require_dist());
20651
20666
  init_parser();
20652
20667
  init_manager();
20653
20668
  DriftDetector = class {
@@ -20736,7 +20751,7 @@ var init_detector = __esm({
20736
20751
  try {
20737
20752
  if (!fs13.existsSync(filePath)) return null;
20738
20753
  const raw = fs13.readFileSync(filePath, "utf-8");
20739
- const parsed = YAML8.parse(raw);
20754
+ const parsed = YAML9.parse(raw);
20740
20755
  if (parsed === null || parsed === void 0 || typeof parsed !== "object") return null;
20741
20756
  return Object.keys(parsed).filter((k) => k !== "sops");
20742
20757
  } catch {
@@ -20887,13 +20902,13 @@ var init_sanitizer = __esm({
20887
20902
  });
20888
20903
 
20889
20904
  // ../core/src/report/generator.ts
20890
- var fs14, path16, YAML9, ReportGenerator;
20905
+ var fs14, path16, YAML10, ReportGenerator;
20891
20906
  var init_generator = __esm({
20892
20907
  "../core/src/report/generator.ts"() {
20893
20908
  "use strict";
20894
20909
  fs14 = __toESM(require("fs"));
20895
20910
  path16 = __toESM(require("path"));
20896
- YAML9 = __toESM(require_dist());
20911
+ YAML10 = __toESM(require_dist());
20897
20912
  init_types();
20898
20913
  init_parser();
20899
20914
  init_runner();
@@ -21072,7 +21087,7 @@ var init_generator = __esm({
21072
21087
  try {
21073
21088
  if (!fs14.existsSync(filePath)) return 0;
21074
21089
  const raw = fs14.readFileSync(filePath, "utf-8");
21075
- const parsed = YAML9.parse(raw);
21090
+ const parsed = YAML10.parse(raw);
21076
21091
  if (parsed === null || parsed === void 0 || typeof parsed !== "object") return 0;
21077
21092
  return Object.keys(parsed).filter((k) => k !== "sops").length;
21078
21093
  } catch {
@@ -21444,14 +21459,14 @@ var init_driver = __esm({
21444
21459
  });
21445
21460
 
21446
21461
  // ../core/src/service-identity/manager.ts
21447
- var fs15, os, path17, YAML10, PartialRotationError, ServiceIdentityManager;
21462
+ var fs15, os, path17, YAML11, PartialRotationError, ServiceIdentityManager;
21448
21463
  var init_manager2 = __esm({
21449
21464
  "../core/src/service-identity/manager.ts"() {
21450
21465
  "use strict";
21451
21466
  fs15 = __toESM(require("fs"));
21452
21467
  os = __toESM(require("os"));
21453
21468
  path17 = __toESM(require("path"));
21454
- YAML10 = __toESM(require_dist());
21469
+ YAML11 = __toESM(require_dist());
21455
21470
  init_types();
21456
21471
  init_keygen();
21457
21472
  init_parser();
@@ -21507,7 +21522,7 @@ var init_manager2 = __esm({
21507
21522
  await this.registerRecipients(definition, manifest, repoRoot);
21508
21523
  const manifestPath = path17.join(repoRoot, CLEF_MANIFEST_FILENAME);
21509
21524
  const raw = fs15.readFileSync(manifestPath, "utf-8");
21510
- const doc = YAML10.parse(raw);
21525
+ const doc = YAML11.parse(raw);
21511
21526
  if (!Array.isArray(doc.service_identities)) {
21512
21527
  doc.service_identities = [];
21513
21528
  }
@@ -21519,7 +21534,7 @@ var init_manager2 = __esm({
21519
21534
  });
21520
21535
  const tmpCreate = path17.join(os.tmpdir(), `clef-manifest-${process.pid}-${Date.now()}.tmp`);
21521
21536
  try {
21522
- fs15.writeFileSync(tmpCreate, YAML10.stringify(doc), "utf-8");
21537
+ fs15.writeFileSync(tmpCreate, YAML11.stringify(doc), "utf-8");
21523
21538
  fs15.renameSync(tmpCreate, manifestPath);
21524
21539
  } finally {
21525
21540
  try {
@@ -21541,6 +21556,95 @@ var init_manager2 = __esm({
21541
21556
  get(manifest, name) {
21542
21557
  return manifest.service_identities?.find((si) => si.name === name);
21543
21558
  }
21559
+ /**
21560
+ * Delete a service identity: remove its recipients from scoped SOPS files
21561
+ * and remove it from the manifest.
21562
+ */
21563
+ async delete(name, manifest, repoRoot) {
21564
+ const identity = this.get(manifest, name);
21565
+ if (!identity) {
21566
+ throw new Error(`Service identity '${name}' not found.`);
21567
+ }
21568
+ const cells = this.matrixManager.resolveMatrix(manifest, repoRoot).filter((c) => c.exists);
21569
+ for (const cell of cells) {
21570
+ if (!identity.namespaces.includes(cell.namespace)) continue;
21571
+ const envConfig = identity.environments[cell.environment];
21572
+ if (!envConfig?.recipient) continue;
21573
+ if (isKmsEnvelope(envConfig)) continue;
21574
+ try {
21575
+ await this.encryption.removeRecipient(cell.filePath, envConfig.recipient);
21576
+ } catch {
21577
+ }
21578
+ }
21579
+ const manifestPath = path17.join(repoRoot, CLEF_MANIFEST_FILENAME);
21580
+ const raw = fs15.readFileSync(manifestPath, "utf-8");
21581
+ const doc = YAML11.parse(raw);
21582
+ const identities = doc.service_identities;
21583
+ if (Array.isArray(identities)) {
21584
+ doc.service_identities = identities.filter(
21585
+ (si) => si.name !== name
21586
+ );
21587
+ }
21588
+ const tmp = path17.join(os.tmpdir(), `clef-manifest-${process.pid}-${Date.now()}.tmp`);
21589
+ try {
21590
+ fs15.writeFileSync(tmp, YAML11.stringify(doc), "utf-8");
21591
+ fs15.renameSync(tmp, manifestPath);
21592
+ } finally {
21593
+ try {
21594
+ fs15.unlinkSync(tmp);
21595
+ } catch {
21596
+ }
21597
+ }
21598
+ }
21599
+ /**
21600
+ * Update environment backends on an existing service identity.
21601
+ * Switches age → KMS (removes old recipient) or updates KMS config.
21602
+ * Returns new private keys for any environments switched from KMS → age.
21603
+ */
21604
+ async updateEnvironments(name, kmsEnvConfigs, manifest, repoRoot) {
21605
+ const identity = this.get(manifest, name);
21606
+ if (!identity) {
21607
+ throw new Error(`Service identity '${name}' not found.`);
21608
+ }
21609
+ const manifestPath = path17.join(repoRoot, CLEF_MANIFEST_FILENAME);
21610
+ const raw = fs15.readFileSync(manifestPath, "utf-8");
21611
+ const doc = YAML11.parse(raw);
21612
+ const identities = doc.service_identities;
21613
+ const siDoc = identities.find((si) => si.name === name);
21614
+ const envs = siDoc.environments;
21615
+ const cells = this.matrixManager.resolveMatrix(manifest, repoRoot).filter((c) => c.exists);
21616
+ const privateKeys = {};
21617
+ for (const [envName, kmsConfig] of Object.entries(kmsEnvConfigs)) {
21618
+ const oldConfig = identity.environments[envName];
21619
+ if (!oldConfig) {
21620
+ throw new Error(`Environment '${envName}' not found on identity '${name}'.`);
21621
+ }
21622
+ if (oldConfig.recipient) {
21623
+ const scopedCells = cells.filter(
21624
+ (c) => identity.namespaces.includes(c.namespace) && c.environment === envName
21625
+ );
21626
+ for (const cell of scopedCells) {
21627
+ try {
21628
+ await this.encryption.removeRecipient(cell.filePath, oldConfig.recipient);
21629
+ } catch {
21630
+ }
21631
+ }
21632
+ }
21633
+ envs[envName] = { kms: kmsConfig };
21634
+ identity.environments[envName] = { kms: kmsConfig };
21635
+ }
21636
+ const tmp = path17.join(os.tmpdir(), `clef-manifest-${process.pid}-${Date.now()}.tmp`);
21637
+ try {
21638
+ fs15.writeFileSync(tmp, YAML11.stringify(doc), "utf-8");
21639
+ fs15.renameSync(tmp, manifestPath);
21640
+ } finally {
21641
+ try {
21642
+ fs15.unlinkSync(tmp);
21643
+ } catch {
21644
+ }
21645
+ }
21646
+ return { privateKeys };
21647
+ }
21544
21648
  /**
21545
21649
  * Register a service identity's public keys as SOPS recipients on scoped matrix files.
21546
21650
  */
@@ -21573,7 +21677,7 @@ var init_manager2 = __esm({
21573
21677
  }
21574
21678
  const manifestPath = path17.join(repoRoot, CLEF_MANIFEST_FILENAME);
21575
21679
  const raw = fs15.readFileSync(manifestPath, "utf-8");
21576
- const doc = YAML10.parse(raw);
21680
+ const doc = YAML11.parse(raw);
21577
21681
  const identities = doc.service_identities;
21578
21682
  const siDoc = identities.find((si) => si.name === name);
21579
21683
  const envs = siDoc.environments;
@@ -21628,7 +21732,7 @@ var init_manager2 = __esm({
21628
21732
  }
21629
21733
  const tmpRotate = path17.join(os.tmpdir(), `clef-manifest-${process.pid}-${Date.now()}.tmp`);
21630
21734
  try {
21631
- fs15.writeFileSync(tmpRotate, YAML10.stringify(doc), "utf-8");
21735
+ fs15.writeFileSync(tmpRotate, YAML11.stringify(doc), "utf-8");
21632
21736
  fs15.renameSync(tmpRotate, manifestPath);
21633
21737
  } finally {
21634
21738
  try {
@@ -21801,7 +21905,8 @@ var init_packer = __esm({
21801
21905
  try {
21802
21906
  const e = new Encrypter();
21803
21907
  e.addRecipient(ephemeralPublicKey);
21804
- ciphertext = await e.encrypt(plaintext);
21908
+ const encrypted = await e.encrypt(plaintext);
21909
+ ciphertext = Buffer.from(encrypted).toString("base64");
21805
21910
  } catch {
21806
21911
  throw new Error("Failed to age-encrypt artifact with ephemeral key.");
21807
21912
  }
@@ -21830,7 +21935,8 @@ var init_packer = __esm({
21830
21935
  const { Encrypter } = await Promise.resolve().then(() => __toESM(require_age_encryption()));
21831
21936
  const e = new Encrypter();
21832
21937
  e.addRecipient(resolved.recipient);
21833
- ciphertext = await e.encrypt(plaintext);
21938
+ const encrypted = await e.encrypt(plaintext);
21939
+ ciphertext = Buffer.from(encrypted).toString("base64");
21834
21940
  } catch {
21835
21941
  throw new Error("Failed to age-encrypt artifact. Check recipient key.");
21836
21942
  }
@@ -21932,7 +22038,7 @@ __export(src_exports, {
21932
22038
  markResolved: () => markResolved,
21933
22039
  matchPatterns: () => matchPatterns,
21934
22040
  metadataPath: () => metadataPath,
21935
- parse: () => parse6,
22041
+ parse: () => parse7,
21936
22042
  parseDotenv: () => parseDotenv,
21937
22043
  parseIgnoreContent: () => parseIgnoreContent,
21938
22044
  parseJson: () => parseJson,
@@ -22070,7 +22176,7 @@ var require_ms = __commonJS({
22070
22176
  options = options || {};
22071
22177
  var type = typeof val;
22072
22178
  if (type === "string" && val.length > 0) {
22073
- return parse15(val);
22179
+ return parse16(val);
22074
22180
  } else if (type === "number" && isFinite(val)) {
22075
22181
  return options.long ? fmtLong(val) : fmtShort(val);
22076
22182
  }
@@ -22078,7 +22184,7 @@ var require_ms = __commonJS({
22078
22184
  "val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
22079
22185
  );
22080
22186
  };
22081
- function parse15(str2) {
22187
+ function parse16(str2) {
22082
22188
  str2 = String(str2);
22083
22189
  if (str2.length > 100) {
22084
22190
  return;
@@ -23517,7 +23623,7 @@ var require_bytes = __commonJS({
23517
23623
  "use strict";
23518
23624
  module2.exports = bytes;
23519
23625
  module2.exports.format = format;
23520
- module2.exports.parse = parse15;
23626
+ module2.exports.parse = parse16;
23521
23627
  var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g;
23522
23628
  var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/;
23523
23629
  var map = {
@@ -23531,7 +23637,7 @@ var require_bytes = __commonJS({
23531
23637
  var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb|pb)$/i;
23532
23638
  function bytes(value, options) {
23533
23639
  if (typeof value === "string") {
23534
- return parse15(value);
23640
+ return parse16(value);
23535
23641
  }
23536
23642
  if (typeof value === "number") {
23537
23643
  return format(value, options);
@@ -23575,7 +23681,7 @@ var require_bytes = __commonJS({
23575
23681
  }
23576
23682
  return str2 + unitSeparator + unit;
23577
23683
  }
23578
- function parse15(val) {
23684
+ function parse16(val) {
23579
23685
  if (typeof val === "number" && !isNaN(val)) {
23580
23686
  return val;
23581
23687
  }
@@ -27780,7 +27886,7 @@ var require_content_type = __commonJS({
27780
27886
  var QUOTE_REGEXP = /([\\"])/g;
27781
27887
  var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
27782
27888
  exports2.format = format;
27783
- exports2.parse = parse15;
27889
+ exports2.parse = parse16;
27784
27890
  function format(obj) {
27785
27891
  if (!obj || typeof obj !== "object") {
27786
27892
  throw new TypeError("argument obj is required");
@@ -27804,7 +27910,7 @@ var require_content_type = __commonJS({
27804
27910
  }
27805
27911
  return string;
27806
27912
  }
27807
- function parse15(string) {
27913
+ function parse16(string) {
27808
27914
  if (!string) {
27809
27915
  throw new TypeError("argument string is required");
27810
27916
  }
@@ -37329,11 +37435,11 @@ var require_mime_types = __commonJS({
37329
37435
  }
37330
37436
  return exts[0];
37331
37437
  }
37332
- function lookup(path43) {
37333
- if (!path43 || typeof path43 !== "string") {
37438
+ function lookup(path44) {
37439
+ if (!path44 || typeof path44 !== "string") {
37334
37440
  return false;
37335
37441
  }
37336
- var extension2 = extname2("x." + path43).toLowerCase().slice(1);
37442
+ var extension2 = extname2("x." + path44).toLowerCase().slice(1);
37337
37443
  if (!extension2) {
37338
37444
  return false;
37339
37445
  }
@@ -37386,7 +37492,7 @@ var require_media_typer = __commonJS({
37386
37492
  var TYPE_NAME_REGEXP = /^[A-Za-z0-9][A-Za-z0-9!#$&^_-]{0,126}$/;
37387
37493
  var TYPE_REGEXP = /^ *([A-Za-z0-9][A-Za-z0-9!#$&^_-]{0,126})\/([A-Za-z0-9][A-Za-z0-9!#$&^_.+-]{0,126}) *$/;
37388
37494
  exports2.format = format;
37389
- exports2.parse = parse15;
37495
+ exports2.parse = parse16;
37390
37496
  exports2.test = test;
37391
37497
  function format(obj) {
37392
37498
  if (!obj || typeof obj !== "object") {
@@ -37419,7 +37525,7 @@ var require_media_typer = __commonJS({
37419
37525
  }
37420
37526
  return TYPE_REGEXP.test(string.toLowerCase());
37421
37527
  }
37422
- function parse15(string) {
37528
+ function parse16(string) {
37423
37529
  if (!string) {
37424
37530
  throw new TypeError("argument string is required");
37425
37531
  }
@@ -37605,7 +37711,7 @@ var require_read = __commonJS({
37605
37711
  var hasBody = require_type_is().hasBody;
37606
37712
  var { getCharset } = require_utils();
37607
37713
  module2.exports = read;
37608
- function read(req, res, next, parse15, debug, options) {
37714
+ function read(req, res, next, parse16, debug, options) {
37609
37715
  if (onFinished.isFinished(req)) {
37610
37716
  debug("body already parsed");
37611
37717
  next();
@@ -37693,7 +37799,7 @@ var require_read = __commonJS({
37693
37799
  try {
37694
37800
  debug("parse body");
37695
37801
  str2 = typeof body !== "string" && encoding !== null ? iconv.decode(body, encoding) : body;
37696
- req.body = parse15(str2, encoding);
37802
+ req.body = parse16(str2, encoding);
37697
37803
  } catch (err) {
37698
37804
  next(createError(400, err, {
37699
37805
  body: str2,
@@ -37766,7 +37872,7 @@ var require_json = __commonJS({
37766
37872
  const normalizedOptions = normalizeOptions(options, "application/json");
37767
37873
  var reviver = options?.reviver;
37768
37874
  var strict = options?.strict !== false;
37769
- function parse15(body) {
37875
+ function parse16(body) {
37770
37876
  if (body.length === 0) {
37771
37877
  return {};
37772
37878
  }
@@ -37793,7 +37899,7 @@ var require_json = __commonJS({
37793
37899
  isValidCharset: (charset) => charset.slice(0, 4) === "utf-"
37794
37900
  };
37795
37901
  return function jsonParser(req, res, next) {
37796
- read(req, res, next, parse15, debug, readOptions);
37902
+ read(req, res, next, parse16, debug, readOptions);
37797
37903
  };
37798
37904
  }
37799
37905
  function createStrictSyntaxError(str2, char) {
@@ -40371,11 +40477,11 @@ var require_lib2 = __commonJS({
40371
40477
  "../../node_modules/qs/lib/index.js"(exports2, module2) {
40372
40478
  "use strict";
40373
40479
  var stringify7 = require_stringify2();
40374
- var parse15 = require_parse();
40480
+ var parse16 = require_parse();
40375
40481
  var formats = require_formats();
40376
40482
  module2.exports = {
40377
40483
  formats,
40378
- parse: parse15,
40484
+ parse: parse16,
40379
40485
  stringify: stringify7
40380
40486
  };
40381
40487
  }
@@ -40397,7 +40503,7 @@ var require_urlencoded = __commonJS({
40397
40503
  throw new TypeError("option defaultCharset must be either utf-8 or iso-8859-1");
40398
40504
  }
40399
40505
  var queryparse = createQueryParser(options);
40400
- function parse15(body, encoding) {
40506
+ function parse16(body, encoding) {
40401
40507
  return body.length ? queryparse(body, encoding) : {};
40402
40508
  }
40403
40509
  const readOptions = {
@@ -40406,7 +40512,7 @@ var require_urlencoded = __commonJS({
40406
40512
  isValidCharset: (charset) => charset === "utf-8" || charset === "iso-8859-1"
40407
40513
  };
40408
40514
  return function urlencodedParser(req, res, next) {
40409
- read(req, res, next, parse15, debug, readOptions);
40515
+ read(req, res, next, parse16, debug, readOptions);
40410
40516
  };
40411
40517
  }
40412
40518
  function createQueryParser(options) {
@@ -40590,7 +40696,7 @@ var require_parseurl = __commonJS({
40590
40696
  "../../node_modules/parseurl/index.js"(exports2, module2) {
40591
40697
  "use strict";
40592
40698
  var url = require("url");
40593
- var parse15 = url.parse;
40699
+ var parse16 = url.parse;
40594
40700
  var Url = url.Url;
40595
40701
  module2.exports = parseurl;
40596
40702
  module2.exports.original = originalurl;
@@ -40622,7 +40728,7 @@ var require_parseurl = __commonJS({
40622
40728
  }
40623
40729
  function fastparse(str2) {
40624
40730
  if (typeof str2 !== "string" || str2.charCodeAt(0) !== 47) {
40625
- return parse15(str2);
40731
+ return parse16(str2);
40626
40732
  }
40627
40733
  var pathname = str2;
40628
40734
  var query = null;
@@ -40650,7 +40756,7 @@ var require_parseurl = __commonJS({
40650
40756
  /* # */
40651
40757
  case 160:
40652
40758
  case 65279:
40653
- return parse15(str2);
40759
+ return parse16(str2);
40654
40760
  }
40655
40761
  }
40656
40762
  var url2 = Url !== void 0 ? new Url() : {};
@@ -40801,13 +40907,13 @@ var require_view = __commonJS({
40801
40907
  "../../node_modules/express/lib/view.js"(exports2, module2) {
40802
40908
  "use strict";
40803
40909
  var debug = require_src()("express:view");
40804
- var path43 = require("node:path");
40805
- var fs26 = require("node:fs");
40806
- var dirname7 = path43.dirname;
40807
- var basename5 = path43.basename;
40808
- var extname2 = path43.extname;
40809
- var join38 = path43.join;
40810
- var resolve6 = path43.resolve;
40910
+ var path44 = require("node:path");
40911
+ var fs27 = require("node:fs");
40912
+ var dirname7 = path44.dirname;
40913
+ var basename5 = path44.basename;
40914
+ var extname2 = path44.extname;
40915
+ var join39 = path44.join;
40916
+ var resolve6 = path44.resolve;
40811
40917
  module2.exports = View;
40812
40918
  function View(name, options) {
40813
40919
  var opts = options || {};
@@ -40836,17 +40942,17 @@ var require_view = __commonJS({
40836
40942
  this.path = this.lookup(fileName);
40837
40943
  }
40838
40944
  View.prototype.lookup = function lookup(name) {
40839
- var path44;
40945
+ var path45;
40840
40946
  var roots = [].concat(this.root);
40841
40947
  debug('lookup "%s"', name);
40842
- for (var i = 0; i < roots.length && !path44; i++) {
40948
+ for (var i = 0; i < roots.length && !path45; i++) {
40843
40949
  var root = roots[i];
40844
40950
  var loc = resolve6(root, name);
40845
40951
  var dir = dirname7(loc);
40846
40952
  var file = basename5(loc);
40847
- path44 = this.resolve(dir, file);
40953
+ path45 = this.resolve(dir, file);
40848
40954
  }
40849
- return path44;
40955
+ return path45;
40850
40956
  };
40851
40957
  View.prototype.render = function render(options, callback) {
40852
40958
  var sync = true;
@@ -40868,21 +40974,21 @@ var require_view = __commonJS({
40868
40974
  };
40869
40975
  View.prototype.resolve = function resolve7(dir, file) {
40870
40976
  var ext = this.ext;
40871
- var path44 = join38(dir, file);
40872
- var stat = tryStat(path44);
40977
+ var path45 = join39(dir, file);
40978
+ var stat = tryStat(path45);
40873
40979
  if (stat && stat.isFile()) {
40874
- return path44;
40980
+ return path45;
40875
40981
  }
40876
- path44 = join38(dir, basename5(file, ext), "index" + ext);
40877
- stat = tryStat(path44);
40982
+ path45 = join39(dir, basename5(file, ext), "index" + ext);
40983
+ stat = tryStat(path45);
40878
40984
  if (stat && stat.isFile()) {
40879
- return path44;
40985
+ return path45;
40880
40986
  }
40881
40987
  };
40882
- function tryStat(path44) {
40883
- debug('stat "%s"', path44);
40988
+ function tryStat(path45) {
40989
+ debug('stat "%s"', path45);
40884
40990
  try {
40885
- return fs26.statSync(path44);
40991
+ return fs27.statSync(path45);
40886
40992
  } catch (e) {
40887
40993
  return void 0;
40888
40994
  }
@@ -50388,11 +50494,11 @@ var require_mime_types2 = __commonJS({
50388
50494
  }
50389
50495
  return exts[0];
50390
50496
  }
50391
- function lookup(path43) {
50392
- if (!path43 || typeof path43 !== "string") {
50497
+ function lookup(path44) {
50498
+ if (!path44 || typeof path44 !== "string") {
50393
50499
  return false;
50394
50500
  }
50395
- var extension2 = extname2("x." + path43).toLowerCase().slice(1);
50501
+ var extension2 = extname2("x." + path44).toLowerCase().slice(1);
50396
50502
  if (!extension2) {
50397
50503
  return false;
50398
50504
  }
@@ -50446,7 +50552,7 @@ var require_forwarded = __commonJS({
50446
50552
  if (!req) {
50447
50553
  throw new TypeError("argument req is required");
50448
50554
  }
50449
- var proxyAddrs = parse15(req.headers["x-forwarded-for"] || "");
50555
+ var proxyAddrs = parse16(req.headers["x-forwarded-for"] || "");
50450
50556
  var socketAddr = getSocketAddr(req);
50451
50557
  var addrs = [socketAddr].concat(proxyAddrs);
50452
50558
  return addrs;
@@ -50454,7 +50560,7 @@ var require_forwarded = __commonJS({
50454
50560
  function getSocketAddr(req) {
50455
50561
  return req.socket ? req.socket.remoteAddress : req.connection.remoteAddress;
50456
50562
  }
50457
- function parse15(header) {
50563
+ function parse16(header) {
50458
50564
  var end = header.length;
50459
50565
  var list = [];
50460
50566
  var start = header.length;
@@ -51483,7 +51589,7 @@ var require_dist2 = __commonJS({
51483
51589
  "use strict";
51484
51590
  Object.defineProperty(exports2, "__esModule", { value: true });
51485
51591
  exports2.PathError = exports2.TokenData = void 0;
51486
- exports2.parse = parse15;
51592
+ exports2.parse = parse16;
51487
51593
  exports2.compile = compile;
51488
51594
  exports2.match = match;
51489
51595
  exports2.pathToRegexp = pathToRegexp;
@@ -51529,7 +51635,7 @@ var require_dist2 = __commonJS({
51529
51635
  }
51530
51636
  };
51531
51637
  exports2.PathError = PathError;
51532
- function parse15(str2, options = {}) {
51638
+ function parse16(str2, options = {}) {
51533
51639
  const { encodePath = NOOP_VALUE } = options;
51534
51640
  const chars = [...str2];
51535
51641
  const tokens = [];
@@ -51585,15 +51691,15 @@ var require_dist2 = __commonJS({
51585
51691
  if (token.type === endType)
51586
51692
  break;
51587
51693
  if (token.type === "char" || token.type === "escape") {
51588
- let path43 = token.value;
51694
+ let path44 = token.value;
51589
51695
  let cur = tokens[pos];
51590
51696
  while (cur.type === "char" || cur.type === "escape") {
51591
- path43 += cur.value;
51697
+ path44 += cur.value;
51592
51698
  cur = tokens[++pos];
51593
51699
  }
51594
51700
  output.push({
51595
51701
  type: "text",
51596
- value: encodePath(path43)
51702
+ value: encodePath(path44)
51597
51703
  });
51598
51704
  continue;
51599
51705
  }
@@ -51617,16 +51723,16 @@ var require_dist2 = __commonJS({
51617
51723
  }
51618
51724
  return new TokenData(consumeUntil("end"), str2);
51619
51725
  }
51620
- function compile(path43, options = {}) {
51726
+ function compile(path44, options = {}) {
51621
51727
  const { encode = encodeURIComponent, delimiter = DEFAULT_DELIMITER } = options;
51622
- const data = typeof path43 === "object" ? path43 : parse15(path43, options);
51728
+ const data = typeof path44 === "object" ? path44 : parse16(path44, options);
51623
51729
  const fn = tokensToFunction(data.tokens, delimiter, encode);
51624
- return function path44(params = {}) {
51625
- const [path45, ...missing] = fn(params);
51730
+ return function path45(params = {}) {
51731
+ const [path46, ...missing] = fn(params);
51626
51732
  if (missing.length) {
51627
51733
  throw new TypeError(`Missing parameters: ${missing.join(", ")}`);
51628
51734
  }
51629
- return path45;
51735
+ return path46;
51630
51736
  };
51631
51737
  }
51632
51738
  function tokensToFunction(tokens, delimiter, encode) {
@@ -51682,9 +51788,9 @@ var require_dist2 = __commonJS({
51682
51788
  return [encodeValue(value)];
51683
51789
  };
51684
51790
  }
51685
- function match(path43, options = {}) {
51791
+ function match(path44, options = {}) {
51686
51792
  const { decode = decodeURIComponent, delimiter = DEFAULT_DELIMITER } = options;
51687
- const { regexp, keys } = pathToRegexp(path43, options);
51793
+ const { regexp, keys } = pathToRegexp(path44, options);
51688
51794
  const decoders = keys.map((key) => {
51689
51795
  if (decode === false)
51690
51796
  return NOOP_VALUE;
@@ -51696,7 +51802,7 @@ var require_dist2 = __commonJS({
51696
51802
  const m = regexp.exec(input);
51697
51803
  if (!m)
51698
51804
  return false;
51699
- const path44 = m[0];
51805
+ const path45 = m[0];
51700
51806
  const params = /* @__PURE__ */ Object.create(null);
51701
51807
  for (let i = 1; i < m.length; i++) {
51702
51808
  if (m[i] === void 0)
@@ -51705,16 +51811,16 @@ var require_dist2 = __commonJS({
51705
51811
  const decoder = decoders[i - 1];
51706
51812
  params[key.name] = decoder(m[i]);
51707
51813
  }
51708
- return { path: path44, params };
51814
+ return { path: path45, params };
51709
51815
  };
51710
51816
  }
51711
- function pathToRegexp(path43, options = {}) {
51817
+ function pathToRegexp(path44, options = {}) {
51712
51818
  const { delimiter = DEFAULT_DELIMITER, end = true, sensitive = false, trailing = true } = options;
51713
51819
  const keys = [];
51714
51820
  const flags = sensitive ? "" : "i";
51715
51821
  const sources = [];
51716
- for (const input of pathsToArray(path43, [])) {
51717
- const data = typeof input === "object" ? input : parse15(input, options);
51822
+ for (const input of pathsToArray(path44, [])) {
51823
+ const data = typeof input === "object" ? input : parse16(input, options);
51718
51824
  for (const tokens of flatten(data.tokens, 0, [])) {
51719
51825
  sources.push(toRegExpSource(tokens, delimiter, keys, data.originalPath));
51720
51826
  }
@@ -51843,18 +51949,18 @@ var require_layer = __commonJS({
51843
51949
  var TRAILING_SLASH_REGEXP = /\/+$/;
51844
51950
  var MATCHING_GROUP_REGEXP = /\((?:\?<(.*?)>)?(?!\?)/g;
51845
51951
  module2.exports = Layer;
51846
- function Layer(path43, options, fn) {
51952
+ function Layer(path44, options, fn) {
51847
51953
  if (!(this instanceof Layer)) {
51848
- return new Layer(path43, options, fn);
51954
+ return new Layer(path44, options, fn);
51849
51955
  }
51850
- debug("new %o", path43);
51956
+ debug("new %o", path44);
51851
51957
  const opts = options || {};
51852
51958
  this.handle = fn;
51853
51959
  this.keys = [];
51854
51960
  this.name = fn.name || "<anonymous>";
51855
51961
  this.params = void 0;
51856
51962
  this.path = void 0;
51857
- this.slash = path43 === "/" && opts.end === false;
51963
+ this.slash = path44 === "/" && opts.end === false;
51858
51964
  function matcher(_path) {
51859
51965
  if (_path instanceof RegExp) {
51860
51966
  const keys = [];
@@ -51893,7 +51999,7 @@ var require_layer = __commonJS({
51893
51999
  decode: decodeParam
51894
52000
  });
51895
52001
  }
51896
- this.matchers = Array.isArray(path43) ? path43.map(matcher) : [matcher(path43)];
52002
+ this.matchers = Array.isArray(path44) ? path44.map(matcher) : [matcher(path44)];
51897
52003
  }
51898
52004
  Layer.prototype.handleError = function handleError(error, req, res, next) {
51899
52005
  const fn = this.handle;
@@ -51933,9 +52039,9 @@ var require_layer = __commonJS({
51933
52039
  next(err);
51934
52040
  }
51935
52041
  };
51936
- Layer.prototype.match = function match(path43) {
52042
+ Layer.prototype.match = function match(path44) {
51937
52043
  let match2;
51938
- if (path43 != null) {
52044
+ if (path44 != null) {
51939
52045
  if (this.slash) {
51940
52046
  this.params = {};
51941
52047
  this.path = "";
@@ -51943,7 +52049,7 @@ var require_layer = __commonJS({
51943
52049
  }
51944
52050
  let i = 0;
51945
52051
  while (!match2 && i < this.matchers.length) {
51946
- match2 = this.matchers[i](path43);
52052
+ match2 = this.matchers[i](path44);
51947
52053
  i++;
51948
52054
  }
51949
52055
  }
@@ -51971,13 +52077,13 @@ var require_layer = __commonJS({
51971
52077
  throw err;
51972
52078
  }
51973
52079
  }
51974
- function loosen(path43) {
51975
- if (path43 instanceof RegExp || path43 === "/") {
51976
- return path43;
52080
+ function loosen(path44) {
52081
+ if (path44 instanceof RegExp || path44 === "/") {
52082
+ return path44;
51977
52083
  }
51978
- return Array.isArray(path43) ? path43.map(function(p) {
52084
+ return Array.isArray(path44) ? path44.map(function(p) {
51979
52085
  return loosen(p);
51980
- }) : String(path43).replace(TRAILING_SLASH_REGEXP, "");
52086
+ }) : String(path44).replace(TRAILING_SLASH_REGEXP, "");
51981
52087
  }
51982
52088
  }
51983
52089
  });
@@ -51993,9 +52099,9 @@ var require_route = __commonJS({
51993
52099
  var flatten = Array.prototype.flat;
51994
52100
  var methods = METHODS.map((method) => method.toLowerCase());
51995
52101
  module2.exports = Route;
51996
- function Route(path43) {
51997
- debug("new %o", path43);
51998
- this.path = path43;
52102
+ function Route(path44) {
52103
+ debug("new %o", path44);
52104
+ this.path = path44;
51999
52105
  this.stack = [];
52000
52106
  this.methods = /* @__PURE__ */ Object.create(null);
52001
52107
  }
@@ -52203,8 +52309,8 @@ var require_router = __commonJS({
52203
52309
  if (++sync > 100) {
52204
52310
  return setImmediate(next, err);
52205
52311
  }
52206
- const path43 = getPathname(req);
52207
- if (path43 == null) {
52312
+ const path44 = getPathname(req);
52313
+ if (path44 == null) {
52208
52314
  return done(layerError);
52209
52315
  }
52210
52316
  let layer;
@@ -52212,7 +52318,7 @@ var require_router = __commonJS({
52212
52318
  let route;
52213
52319
  while (match !== true && idx < stack.length) {
52214
52320
  layer = stack[idx++];
52215
- match = matchLayer(layer, path43);
52321
+ match = matchLayer(layer, path44);
52216
52322
  route = layer.route;
52217
52323
  if (typeof match !== "boolean") {
52218
52324
  layerError = layerError || match;
@@ -52250,18 +52356,18 @@ var require_router = __commonJS({
52250
52356
  } else if (route) {
52251
52357
  layer.handleRequest(req, res, next);
52252
52358
  } else {
52253
- trimPrefix(layer, layerError, layerPath, path43);
52359
+ trimPrefix(layer, layerError, layerPath, path44);
52254
52360
  }
52255
52361
  sync = 0;
52256
52362
  });
52257
52363
  }
52258
- function trimPrefix(layer, layerError, layerPath, path43) {
52364
+ function trimPrefix(layer, layerError, layerPath, path44) {
52259
52365
  if (layerPath.length !== 0) {
52260
- if (layerPath !== path43.substring(0, layerPath.length)) {
52366
+ if (layerPath !== path44.substring(0, layerPath.length)) {
52261
52367
  next(layerError);
52262
52368
  return;
52263
52369
  }
52264
- const c = path43[layerPath.length];
52370
+ const c = path44[layerPath.length];
52265
52371
  if (c && c !== "/") {
52266
52372
  next(layerError);
52267
52373
  return;
@@ -52285,7 +52391,7 @@ var require_router = __commonJS({
52285
52391
  };
52286
52392
  Router.prototype.use = function use(handler) {
52287
52393
  let offset = 0;
52288
- let path43 = "/";
52394
+ let path44 = "/";
52289
52395
  if (typeof handler !== "function") {
52290
52396
  let arg = handler;
52291
52397
  while (Array.isArray(arg) && arg.length !== 0) {
@@ -52293,7 +52399,7 @@ var require_router = __commonJS({
52293
52399
  }
52294
52400
  if (typeof arg !== "function") {
52295
52401
  offset = 1;
52296
- path43 = handler;
52402
+ path44 = handler;
52297
52403
  }
52298
52404
  }
52299
52405
  const callbacks = flatten.call(slice.call(arguments, offset), Infinity);
@@ -52305,8 +52411,8 @@ var require_router = __commonJS({
52305
52411
  if (typeof fn !== "function") {
52306
52412
  throw new TypeError("argument handler must be a function");
52307
52413
  }
52308
- debug("use %o %s", path43, fn.name || "<anonymous>");
52309
- const layer = new Layer(path43, {
52414
+ debug("use %o %s", path44, fn.name || "<anonymous>");
52415
+ const layer = new Layer(path44, {
52310
52416
  sensitive: this.caseSensitive,
52311
52417
  strict: false,
52312
52418
  end: false
@@ -52316,9 +52422,9 @@ var require_router = __commonJS({
52316
52422
  }
52317
52423
  return this;
52318
52424
  };
52319
- Router.prototype.route = function route(path43) {
52320
- const route2 = new Route(path43);
52321
- const layer = new Layer(path43, {
52425
+ Router.prototype.route = function route(path44) {
52426
+ const route2 = new Route(path44);
52427
+ const layer = new Layer(path44, {
52322
52428
  sensitive: this.caseSensitive,
52323
52429
  strict: this.strict,
52324
52430
  end: true
@@ -52331,8 +52437,8 @@ var require_router = __commonJS({
52331
52437
  return route2;
52332
52438
  };
52333
52439
  methods.concat("all").forEach(function(method) {
52334
- Router.prototype[method] = function(path43) {
52335
- const route = this.route(path43);
52440
+ Router.prototype[method] = function(path44) {
52441
+ const route = this.route(path44);
52336
52442
  route[method].apply(route, slice.call(arguments, 1));
52337
52443
  return this;
52338
52444
  };
@@ -52361,9 +52467,9 @@ var require_router = __commonJS({
52361
52467
  const fqdnIndex = url.substring(0, pathLength).indexOf("://");
52362
52468
  return fqdnIndex !== -1 ? url.substring(0, url.indexOf("/", 3 + fqdnIndex)) : void 0;
52363
52469
  }
52364
- function matchLayer(layer, path43) {
52470
+ function matchLayer(layer, path44) {
52365
52471
  try {
52366
- return layer.match(path43);
52472
+ return layer.match(path44);
52367
52473
  } catch (err) {
52368
52474
  return err;
52369
52475
  }
@@ -52591,7 +52697,7 @@ var require_application = __commonJS({
52591
52697
  };
52592
52698
  app.use = function use(fn) {
52593
52699
  var offset = 0;
52594
- var path43 = "/";
52700
+ var path44 = "/";
52595
52701
  if (typeof fn !== "function") {
52596
52702
  var arg = fn;
52597
52703
  while (Array.isArray(arg) && arg.length !== 0) {
@@ -52599,7 +52705,7 @@ var require_application = __commonJS({
52599
52705
  }
52600
52706
  if (typeof arg !== "function") {
52601
52707
  offset = 1;
52602
- path43 = fn;
52708
+ path44 = fn;
52603
52709
  }
52604
52710
  }
52605
52711
  var fns = flatten.call(slice.call(arguments, offset), Infinity);
@@ -52609,12 +52715,12 @@ var require_application = __commonJS({
52609
52715
  var router = this.router;
52610
52716
  fns.forEach(function(fn2) {
52611
52717
  if (!fn2 || !fn2.handle || !fn2.set) {
52612
- return router.use(path43, fn2);
52718
+ return router.use(path44, fn2);
52613
52719
  }
52614
- debug(".use app under %s", path43);
52615
- fn2.mountpath = path43;
52720
+ debug(".use app under %s", path44);
52721
+ fn2.mountpath = path44;
52616
52722
  fn2.parent = this;
52617
- router.use(path43, function mounted_app(req, res, next) {
52723
+ router.use(path44, function mounted_app(req, res, next) {
52618
52724
  var orig = req.app;
52619
52725
  fn2.handle(req, res, function(err) {
52620
52726
  Object.setPrototypeOf(req, orig.request);
@@ -52626,8 +52732,8 @@ var require_application = __commonJS({
52626
52732
  }, this);
52627
52733
  return this;
52628
52734
  };
52629
- app.route = function route(path43) {
52630
- return this.router.route(path43);
52735
+ app.route = function route(path44) {
52736
+ return this.router.route(path44);
52631
52737
  };
52632
52738
  app.engine = function engine(ext, fn) {
52633
52739
  if (typeof fn !== "function") {
@@ -52670,7 +52776,7 @@ var require_application = __commonJS({
52670
52776
  }
52671
52777
  return this;
52672
52778
  };
52673
- app.path = function path43() {
52779
+ app.path = function path44() {
52674
52780
  return this.parent ? this.parent.path() + this.mountpath : "";
52675
52781
  };
52676
52782
  app.enabled = function enabled(setting) {
@@ -52686,17 +52792,17 @@ var require_application = __commonJS({
52686
52792
  return this.set(setting, false);
52687
52793
  };
52688
52794
  methods.forEach(function(method) {
52689
- app[method] = function(path43) {
52795
+ app[method] = function(path44) {
52690
52796
  if (method === "get" && arguments.length === 1) {
52691
- return this.set(path43);
52797
+ return this.set(path44);
52692
52798
  }
52693
- var route = this.route(path43);
52799
+ var route = this.route(path44);
52694
52800
  route[method].apply(route, slice.call(arguments, 1));
52695
52801
  return this;
52696
52802
  };
52697
52803
  });
52698
- app.all = function all(path43) {
52699
- var route = this.route(path43);
52804
+ app.all = function all(path44) {
52805
+ var route = this.route(path44);
52700
52806
  var args = slice.call(arguments, 1);
52701
52807
  for (var i = 0; i < methods.length; i++) {
52702
52808
  route[methods[i]].apply(route, args);
@@ -62730,11 +62836,11 @@ var require_mime_types3 = __commonJS({
62730
62836
  }
62731
62837
  return exts[0];
62732
62838
  }
62733
- function lookup(path43) {
62734
- if (!path43 || typeof path43 !== "string") {
62839
+ function lookup(path44) {
62840
+ if (!path44 || typeof path44 !== "string") {
62735
62841
  return false;
62736
62842
  }
62737
- var extension2 = extname2("x." + path43).toLowerCase().slice(1);
62843
+ var extension2 = extname2("x." + path44).toLowerCase().slice(1);
62738
62844
  if (!extension2) {
62739
62845
  return false;
62740
62846
  }
@@ -63023,7 +63129,7 @@ var require_request = __commonJS({
63023
63129
  var http = require("node:http");
63024
63130
  var fresh = require_fresh();
63025
63131
  var parseRange = require_range_parser();
63026
- var parse15 = require_parseurl();
63132
+ var parse16 = require_parseurl();
63027
63133
  var proxyaddr = require_proxy_addr();
63028
63134
  var req = Object.create(http.IncomingMessage.prototype);
63029
63135
  module2.exports = req;
@@ -63068,7 +63174,7 @@ var require_request = __commonJS({
63068
63174
  if (!queryparse) {
63069
63175
  return /* @__PURE__ */ Object.create(null);
63070
63176
  }
63071
- var querystring = parse15(this).query;
63177
+ var querystring = parse16(this).query;
63072
63178
  return queryparse(querystring);
63073
63179
  });
63074
63180
  req.is = function is(types) {
@@ -63111,8 +63217,8 @@ var require_request = __commonJS({
63111
63217
  var subdomains2 = !isIP(hostname) ? hostname.split(".").reverse() : [hostname];
63112
63218
  return subdomains2.slice(offset);
63113
63219
  });
63114
- defineGetter(req, "path", function path43() {
63115
- return parse15(this).pathname;
63220
+ defineGetter(req, "path", function path44() {
63221
+ return parse16(this).pathname;
63116
63222
  });
63117
63223
  defineGetter(req, "host", function host() {
63118
63224
  var trust = this.app.get("trust proxy fn");
@@ -63166,7 +63272,7 @@ var require_content_disposition = __commonJS({
63166
63272
  "../../node_modules/content-disposition/index.js"(exports2, module2) {
63167
63273
  "use strict";
63168
63274
  module2.exports = contentDisposition;
63169
- module2.exports.parse = parse15;
63275
+ module2.exports.parse = parse16;
63170
63276
  var basename5 = require("path").basename;
63171
63277
  var ENCODE_URL_ATTR_CHAR_REGEXP = /[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g;
63172
63278
  var HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/;
@@ -63257,7 +63363,7 @@ var require_content_disposition = __commonJS({
63257
63363
  function getlatin1(val) {
63258
63364
  return String(val).replace(NON_LATIN1_REGEXP, "?");
63259
63365
  }
63260
- function parse15(string) {
63366
+ function parse16(string) {
63261
63367
  if (!string || typeof string !== "string") {
63262
63368
  throw new TypeError("argument string is required");
63263
63369
  }
@@ -63346,7 +63452,7 @@ var require_cookie_signature = __commonJS({
63346
63452
  var require_cookie = __commonJS({
63347
63453
  "../../node_modules/cookie/index.js"(exports2) {
63348
63454
  "use strict";
63349
- exports2.parse = parse15;
63455
+ exports2.parse = parse16;
63350
63456
  exports2.serialize = serialize;
63351
63457
  var __toString = Object.prototype.toString;
63352
63458
  var __hasOwnProperty = Object.prototype.hasOwnProperty;
@@ -63354,7 +63460,7 @@ var require_cookie = __commonJS({
63354
63460
  var cookieValueRegExp = /^("?)[\u0021\u0023-\u002B\u002D-\u003A\u003C-\u005B\u005D-\u007E]*\1$/;
63355
63461
  var domainValueRegExp = /^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i;
63356
63462
  var pathValueRegExp = /^[\u0020-\u003A\u003D-\u007E]*$/;
63357
- function parse15(str2, opt) {
63463
+ function parse16(str2, opt) {
63358
63464
  if (typeof str2 !== "string") {
63359
63465
  throw new TypeError("argument str must be a string");
63360
63466
  }
@@ -72964,11 +73070,11 @@ var require_mime_types4 = __commonJS({
72964
73070
  }
72965
73071
  return exts[0];
72966
73072
  }
72967
- function lookup(path43) {
72968
- if (!path43 || typeof path43 !== "string") {
73073
+ function lookup(path44) {
73074
+ if (!path44 || typeof path44 !== "string") {
72969
73075
  return false;
72970
73076
  }
72971
- var extension2 = extname2("x." + path43).toLowerCase().slice(1);
73077
+ var extension2 = extname2("x." + path44).toLowerCase().slice(1);
72972
73078
  if (!extension2) {
72973
73079
  return false;
72974
73080
  }
@@ -73023,32 +73129,32 @@ var require_send = __commonJS({
73023
73129
  var escapeHtml = require_escape_html();
73024
73130
  var etag = require_etag();
73025
73131
  var fresh = require_fresh();
73026
- var fs26 = require("fs");
73132
+ var fs27 = require("fs");
73027
73133
  var mime = require_mime_types4();
73028
73134
  var ms = require_ms();
73029
73135
  var onFinished = require_on_finished();
73030
73136
  var parseRange = require_range_parser();
73031
- var path43 = require("path");
73137
+ var path44 = require("path");
73032
73138
  var statuses = require_statuses();
73033
73139
  var Stream = require("stream");
73034
73140
  var util = require("util");
73035
- var extname2 = path43.extname;
73036
- var join38 = path43.join;
73037
- var normalize = path43.normalize;
73038
- var resolve6 = path43.resolve;
73039
- var sep = path43.sep;
73141
+ var extname2 = path44.extname;
73142
+ var join39 = path44.join;
73143
+ var normalize = path44.normalize;
73144
+ var resolve6 = path44.resolve;
73145
+ var sep = path44.sep;
73040
73146
  var BYTES_RANGE_REGEXP = /^ *bytes=/;
73041
73147
  var MAX_MAXAGE = 60 * 60 * 24 * 365 * 1e3;
73042
73148
  var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;
73043
73149
  module2.exports = send;
73044
- function send(req, path44, options) {
73045
- return new SendStream(req, path44, options);
73150
+ function send(req, path45, options) {
73151
+ return new SendStream(req, path45, options);
73046
73152
  }
73047
- function SendStream(req, path44, options) {
73153
+ function SendStream(req, path45, options) {
73048
73154
  Stream.call(this);
73049
73155
  var opts = options || {};
73050
73156
  this.options = opts;
73051
- this.path = path44;
73157
+ this.path = path45;
73052
73158
  this.req = req;
73053
73159
  this._acceptRanges = opts.acceptRanges !== void 0 ? Boolean(opts.acceptRanges) : true;
73054
73160
  this._cacheControl = opts.cacheControl !== void 0 ? Boolean(opts.cacheControl) : true;
@@ -73162,10 +73268,10 @@ var require_send = __commonJS({
73162
73268
  var lastModified = this.res.getHeader("Last-Modified");
73163
73269
  return parseHttpDate(lastModified) <= parseHttpDate(ifRange);
73164
73270
  };
73165
- SendStream.prototype.redirect = function redirect(path44) {
73271
+ SendStream.prototype.redirect = function redirect(path45) {
73166
73272
  var res = this.res;
73167
73273
  if (hasListeners(this, "directory")) {
73168
- this.emit("directory", res, path44);
73274
+ this.emit("directory", res, path45);
73169
73275
  return;
73170
73276
  }
73171
73277
  if (this.hasTrailingSlash()) {
@@ -73185,38 +73291,38 @@ var require_send = __commonJS({
73185
73291
  SendStream.prototype.pipe = function pipe(res) {
73186
73292
  var root = this._root;
73187
73293
  this.res = res;
73188
- var path44 = decode(this.path);
73189
- if (path44 === -1) {
73294
+ var path45 = decode(this.path);
73295
+ if (path45 === -1) {
73190
73296
  this.error(400);
73191
73297
  return res;
73192
73298
  }
73193
- if (~path44.indexOf("\0")) {
73299
+ if (~path45.indexOf("\0")) {
73194
73300
  this.error(400);
73195
73301
  return res;
73196
73302
  }
73197
73303
  var parts;
73198
73304
  if (root !== null) {
73199
- if (path44) {
73200
- path44 = normalize("." + sep + path44);
73305
+ if (path45) {
73306
+ path45 = normalize("." + sep + path45);
73201
73307
  }
73202
- if (UP_PATH_REGEXP.test(path44)) {
73203
- debug('malicious path "%s"', path44);
73308
+ if (UP_PATH_REGEXP.test(path45)) {
73309
+ debug('malicious path "%s"', path45);
73204
73310
  this.error(403);
73205
73311
  return res;
73206
73312
  }
73207
- parts = path44.split(sep);
73208
- path44 = normalize(join38(root, path44));
73313
+ parts = path45.split(sep);
73314
+ path45 = normalize(join39(root, path45));
73209
73315
  } else {
73210
- if (UP_PATH_REGEXP.test(path44)) {
73211
- debug('malicious path "%s"', path44);
73316
+ if (UP_PATH_REGEXP.test(path45)) {
73317
+ debug('malicious path "%s"', path45);
73212
73318
  this.error(403);
73213
73319
  return res;
73214
73320
  }
73215
- parts = normalize(path44).split(sep);
73216
- path44 = resolve6(path44);
73321
+ parts = normalize(path45).split(sep);
73322
+ path45 = resolve6(path45);
73217
73323
  }
73218
73324
  if (containsDotFile(parts)) {
73219
- debug('%s dotfile "%s"', this._dotfiles, path44);
73325
+ debug('%s dotfile "%s"', this._dotfiles, path45);
73220
73326
  switch (this._dotfiles) {
73221
73327
  case "allow":
73222
73328
  break;
@@ -73230,13 +73336,13 @@ var require_send = __commonJS({
73230
73336
  }
73231
73337
  }
73232
73338
  if (this._index.length && this.hasTrailingSlash()) {
73233
- this.sendIndex(path44);
73339
+ this.sendIndex(path45);
73234
73340
  return res;
73235
73341
  }
73236
- this.sendFile(path44);
73342
+ this.sendFile(path45);
73237
73343
  return res;
73238
73344
  };
73239
- SendStream.prototype.send = function send2(path44, stat) {
73345
+ SendStream.prototype.send = function send2(path45, stat) {
73240
73346
  var len = stat.size;
73241
73347
  var options = this.options;
73242
73348
  var opts = {};
@@ -73248,9 +73354,9 @@ var require_send = __commonJS({
73248
73354
  this.headersAlreadySent();
73249
73355
  return;
73250
73356
  }
73251
- debug('pipe "%s"', path44);
73252
- this.setHeader(path44, stat);
73253
- this.type(path44);
73357
+ debug('pipe "%s"', path45);
73358
+ this.setHeader(path45, stat);
73359
+ this.type(path45);
73254
73360
  if (this.isConditionalGET()) {
73255
73361
  if (this.isPreconditionFailure()) {
73256
73362
  this.error(412);
@@ -73299,30 +73405,30 @@ var require_send = __commonJS({
73299
73405
  res.end();
73300
73406
  return;
73301
73407
  }
73302
- this.stream(path44, opts);
73408
+ this.stream(path45, opts);
73303
73409
  };
73304
- SendStream.prototype.sendFile = function sendFile(path44) {
73410
+ SendStream.prototype.sendFile = function sendFile(path45) {
73305
73411
  var i = 0;
73306
73412
  var self = this;
73307
- debug('stat "%s"', path44);
73308
- fs26.stat(path44, function onstat(err, stat) {
73309
- var pathEndsWithSep = path44[path44.length - 1] === sep;
73310
- if (err && err.code === "ENOENT" && !extname2(path44) && !pathEndsWithSep) {
73413
+ debug('stat "%s"', path45);
73414
+ fs27.stat(path45, function onstat(err, stat) {
73415
+ var pathEndsWithSep = path45[path45.length - 1] === sep;
73416
+ if (err && err.code === "ENOENT" && !extname2(path45) && !pathEndsWithSep) {
73311
73417
  return next(err);
73312
73418
  }
73313
73419
  if (err) return self.onStatError(err);
73314
- if (stat.isDirectory()) return self.redirect(path44);
73420
+ if (stat.isDirectory()) return self.redirect(path45);
73315
73421
  if (pathEndsWithSep) return self.error(404);
73316
- self.emit("file", path44, stat);
73317
- self.send(path44, stat);
73422
+ self.emit("file", path45, stat);
73423
+ self.send(path45, stat);
73318
73424
  });
73319
73425
  function next(err) {
73320
73426
  if (self._extensions.length <= i) {
73321
73427
  return err ? self.onStatError(err) : self.error(404);
73322
73428
  }
73323
- var p = path44 + "." + self._extensions[i++];
73429
+ var p = path45 + "." + self._extensions[i++];
73324
73430
  debug('stat "%s"', p);
73325
- fs26.stat(p, function(err2, stat) {
73431
+ fs27.stat(p, function(err2, stat) {
73326
73432
  if (err2) return next(err2);
73327
73433
  if (stat.isDirectory()) return next();
73328
73434
  self.emit("file", p, stat);
@@ -73330,7 +73436,7 @@ var require_send = __commonJS({
73330
73436
  });
73331
73437
  }
73332
73438
  };
73333
- SendStream.prototype.sendIndex = function sendIndex(path44) {
73439
+ SendStream.prototype.sendIndex = function sendIndex(path45) {
73334
73440
  var i = -1;
73335
73441
  var self = this;
73336
73442
  function next(err) {
@@ -73338,9 +73444,9 @@ var require_send = __commonJS({
73338
73444
  if (err) return self.onStatError(err);
73339
73445
  return self.error(404);
73340
73446
  }
73341
- var p = join38(path44, self._index[i]);
73447
+ var p = join39(path45, self._index[i]);
73342
73448
  debug('stat "%s"', p);
73343
- fs26.stat(p, function(err2, stat) {
73449
+ fs27.stat(p, function(err2, stat) {
73344
73450
  if (err2) return next(err2);
73345
73451
  if (stat.isDirectory()) return next();
73346
73452
  self.emit("file", p, stat);
@@ -73349,10 +73455,10 @@ var require_send = __commonJS({
73349
73455
  }
73350
73456
  next();
73351
73457
  };
73352
- SendStream.prototype.stream = function stream(path44, options) {
73458
+ SendStream.prototype.stream = function stream(path45, options) {
73353
73459
  var self = this;
73354
73460
  var res = this.res;
73355
- var stream2 = fs26.createReadStream(path44, options);
73461
+ var stream2 = fs27.createReadStream(path45, options);
73356
73462
  this.emit("stream", stream2);
73357
73463
  stream2.pipe(res);
73358
73464
  function cleanup() {
@@ -73367,17 +73473,17 @@ var require_send = __commonJS({
73367
73473
  self.emit("end");
73368
73474
  });
73369
73475
  };
73370
- SendStream.prototype.type = function type(path44) {
73476
+ SendStream.prototype.type = function type(path45) {
73371
73477
  var res = this.res;
73372
73478
  if (res.getHeader("Content-Type")) return;
73373
- var ext = extname2(path44);
73479
+ var ext = extname2(path45);
73374
73480
  var type2 = mime.contentType(ext) || "application/octet-stream";
73375
73481
  debug("content-type %s", type2);
73376
73482
  res.setHeader("Content-Type", type2);
73377
73483
  };
73378
- SendStream.prototype.setHeader = function setHeader(path44, stat) {
73484
+ SendStream.prototype.setHeader = function setHeader(path45, stat) {
73379
73485
  var res = this.res;
73380
- this.emit("headers", res, path44, stat);
73486
+ this.emit("headers", res, path45, stat);
73381
73487
  if (this._acceptRanges && !res.getHeader("Accept-Ranges")) {
73382
73488
  debug("accept ranges");
73383
73489
  res.setHeader("Accept-Ranges", "bytes");
@@ -73435,9 +73541,9 @@ var require_send = __commonJS({
73435
73541
  }
73436
73542
  return err instanceof Error ? createError(status, err, { expose: false }) : createError(status, err);
73437
73543
  }
73438
- function decode(path44) {
73544
+ function decode(path45) {
73439
73545
  try {
73440
- return decodeURIComponent(path44);
73546
+ return decodeURIComponent(path45);
73441
73547
  } catch (err) {
73442
73548
  return -1;
73443
73549
  }
@@ -73510,7 +73616,7 @@ var require_vary = __commonJS({
73510
73616
  if (!field) {
73511
73617
  throw new TypeError("field argument is required");
73512
73618
  }
73513
- var fields = !Array.isArray(field) ? parse15(String(field)) : field;
73619
+ var fields = !Array.isArray(field) ? parse16(String(field)) : field;
73514
73620
  for (var j = 0; j < fields.length; j++) {
73515
73621
  if (!FIELD_NAME_REGEXP.test(fields[j])) {
73516
73622
  throw new TypeError("field argument contains an invalid header name");
@@ -73520,7 +73626,7 @@ var require_vary = __commonJS({
73520
73626
  return header;
73521
73627
  }
73522
73628
  var val = header;
73523
- var vals = parse15(header.toLowerCase());
73629
+ var vals = parse16(header.toLowerCase());
73524
73630
  if (fields.indexOf("*") !== -1 || vals.indexOf("*") !== -1) {
73525
73631
  return "*";
73526
73632
  }
@@ -73533,7 +73639,7 @@ var require_vary = __commonJS({
73533
73639
  }
73534
73640
  return val;
73535
73641
  }
73536
- function parse15(header) {
73642
+ function parse16(header) {
73537
73643
  var end = 0;
73538
73644
  var list = [];
73539
73645
  var start = 0;
@@ -73581,7 +73687,7 @@ var require_response = __commonJS({
73581
73687
  var http = require("node:http");
73582
73688
  var onFinished = require_on_finished();
73583
73689
  var mime = require_mime_types2();
73584
- var path43 = require("node:path");
73690
+ var path44 = require("node:path");
73585
73691
  var pathIsAbsolute = require("node:path").isAbsolute;
73586
73692
  var statuses = require_statuses();
73587
73693
  var sign = require_cookie_signature().sign;
@@ -73590,8 +73696,8 @@ var require_response = __commonJS({
73590
73696
  var setCharset = require_utils3().setCharset;
73591
73697
  var cookie = require_cookie();
73592
73698
  var send = require_send();
73593
- var extname2 = path43.extname;
73594
- var resolve6 = path43.resolve;
73699
+ var extname2 = path44.extname;
73700
+ var resolve6 = path44.resolve;
73595
73701
  var vary = require_vary();
73596
73702
  var { Buffer: Buffer2 } = require("node:buffer");
73597
73703
  var res = Object.create(http.ServerResponse.prototype);
@@ -73737,26 +73843,26 @@ var require_response = __commonJS({
73737
73843
  this.type("txt");
73738
73844
  return this.send(body);
73739
73845
  };
73740
- res.sendFile = function sendFile(path44, options, callback) {
73846
+ res.sendFile = function sendFile(path45, options, callback) {
73741
73847
  var done = callback;
73742
73848
  var req = this.req;
73743
73849
  var res2 = this;
73744
73850
  var next = req.next;
73745
73851
  var opts = options || {};
73746
- if (!path44) {
73852
+ if (!path45) {
73747
73853
  throw new TypeError("path argument is required to res.sendFile");
73748
73854
  }
73749
- if (typeof path44 !== "string") {
73855
+ if (typeof path45 !== "string") {
73750
73856
  throw new TypeError("path must be a string to res.sendFile");
73751
73857
  }
73752
73858
  if (typeof options === "function") {
73753
73859
  done = options;
73754
73860
  opts = {};
73755
73861
  }
73756
- if (!opts.root && !pathIsAbsolute(path44)) {
73862
+ if (!opts.root && !pathIsAbsolute(path45)) {
73757
73863
  throw new TypeError("path must be absolute or specify root to res.sendFile");
73758
73864
  }
73759
- var pathname = encodeURI(path44);
73865
+ var pathname = encodeURI(path45);
73760
73866
  opts.etag = this.app.enabled("etag");
73761
73867
  var file = send(req, pathname, opts);
73762
73868
  sendfile(res2, file, opts, function(err) {
@@ -73767,7 +73873,7 @@ var require_response = __commonJS({
73767
73873
  }
73768
73874
  });
73769
73875
  };
73770
- res.download = function download(path44, filename, options, callback) {
73876
+ res.download = function download(path45, filename, options, callback) {
73771
73877
  var done = callback;
73772
73878
  var name = filename;
73773
73879
  var opts = options || null;
@@ -73784,7 +73890,7 @@ var require_response = __commonJS({
73784
73890
  opts = filename;
73785
73891
  }
73786
73892
  var headers = {
73787
- "Content-Disposition": contentDisposition(name || path44)
73893
+ "Content-Disposition": contentDisposition(name || path45)
73788
73894
  };
73789
73895
  if (opts && opts.headers) {
73790
73896
  var keys = Object.keys(opts.headers);
@@ -73797,7 +73903,7 @@ var require_response = __commonJS({
73797
73903
  }
73798
73904
  opts = Object.create(opts);
73799
73905
  opts.headers = headers;
73800
- var fullPath = !opts.root ? resolve6(path44) : path44;
73906
+ var fullPath = !opts.root ? resolve6(path45) : path45;
73801
73907
  return this.sendFile(fullPath, opts, done);
73802
73908
  };
73803
73909
  res.contentType = res.type = function contentType(type) {
@@ -74080,11 +74186,11 @@ var require_serve_static = __commonJS({
74080
74186
  }
74081
74187
  var forwardError = !fallthrough;
74082
74188
  var originalUrl = parseUrl.original(req);
74083
- var path43 = parseUrl(req).pathname;
74084
- if (path43 === "/" && originalUrl.pathname.substr(-1) !== "/") {
74085
- path43 = "";
74189
+ var path44 = parseUrl(req).pathname;
74190
+ if (path44 === "/" && originalUrl.pathname.substr(-1) !== "/") {
74191
+ path44 = "";
74086
74192
  }
74087
- var stream = send(req, path43, opts);
74193
+ var stream = send(req, path44, opts);
74088
74194
  stream.on("directory", onDirectory);
74089
74195
  if (setHeaders) {
74090
74196
  stream.on("headers", setHeaders);
@@ -75037,7 +75143,7 @@ var require_api = __commonJS({
75037
75143
  })();
75038
75144
  Object.defineProperty(exports2, "__esModule", { value: true });
75039
75145
  exports2.createApiRouter = createApiRouter;
75040
- var path43 = __importStar(require("path"));
75146
+ var path44 = __importStar(require("path"));
75041
75147
  var os3 = __importStar(require("os"));
75042
75148
  var child_process_1 = require("child_process");
75043
75149
  var express_1 = require_express2();
@@ -75055,11 +75161,11 @@ var require_api = __commonJS({
75055
75161
  return deps2.runner.run(cmd, args, {
75056
75162
  ...opts,
75057
75163
  cwd: opts?.cwd ?? deps2.repoRoot,
75058
- env: { SOPS_CONFIG: path43.join(deps2.repoRoot, ".sops.yaml"), ...opts?.env }
75164
+ env: { SOPS_CONFIG: path44.join(deps2.repoRoot, ".sops.yaml"), ...opts?.env }
75059
75165
  });
75060
75166
  }
75061
- const fifoDir = (0, child_process_1.execFileSync)("mktemp", ["-d", path43.join(os3.tmpdir(), "clef-fifo-XXXXXX")]).toString().trim();
75062
- const fifoPath = path43.join(fifoDir, "input");
75167
+ const fifoDir = (0, child_process_1.execFileSync)("mktemp", ["-d", path44.join(os3.tmpdir(), "clef-fifo-XXXXXX")]).toString().trim();
75168
+ const fifoPath = path44.join(fifoDir, "input");
75063
75169
  (0, child_process_1.execFileSync)("mkfifo", [fifoPath]);
75064
75170
  const writer = (0, child_process_1.spawn)("dd", [`of=${fifoPath}`, "status=none"], {
75065
75171
  stdio: ["pipe", "ignore", "ignore"]
@@ -75072,7 +75178,7 @@ var require_api = __commonJS({
75072
75178
  return deps2.runner.run(cmd, patchedArgs, {
75073
75179
  ...restOpts,
75074
75180
  cwd: restOpts?.cwd ?? deps2.repoRoot,
75075
- env: { SOPS_CONFIG: path43.join(deps2.repoRoot, ".sops.yaml"), ...restOpts?.env }
75181
+ env: { SOPS_CONFIG: path44.join(deps2.repoRoot, ".sops.yaml"), ...restOpts?.env }
75076
75182
  }).finally(() => {
75077
75183
  try {
75078
75184
  writer.kill();
@@ -75218,7 +75324,7 @@ var require_api = __commonJS({
75218
75324
  const nsDef = manifest.namespaces.find((n) => n.name === ns);
75219
75325
  if (nsDef?.schema) {
75220
75326
  try {
75221
- const schema = schemaValidator.loadSchema(path43.join(deps2.repoRoot, nsDef.schema));
75327
+ const schema = schemaValidator.loadSchema(path44.join(deps2.repoRoot, nsDef.schema));
75222
75328
  const result = schemaValidator.validate({ [key]: String(value) }, schema);
75223
75329
  const violations = [...result.errors, ...result.warnings];
75224
75330
  if (violations.length > 0) {
@@ -75482,8 +75588,8 @@ var require_api = __commonJS({
75482
75588
  res.status(400).json({ error: "Request body must include a 'file' string.", code: "BAD_REQUEST" });
75483
75589
  return;
75484
75590
  }
75485
- const resolved = path43.resolve(deps2.repoRoot, file);
75486
- if (!resolved.startsWith(deps2.repoRoot + path43.sep) && resolved !== deps2.repoRoot) {
75591
+ const resolved = path44.resolve(deps2.repoRoot, file);
75592
+ if (!resolved.startsWith(deps2.repoRoot + path44.sep) && resolved !== deps2.repoRoot) {
75487
75593
  res.status(400).json({
75488
75594
  error: "File path must be within the repository.",
75489
75595
  code: "BAD_REQUEST"
@@ -75633,6 +75739,42 @@ var require_api = __commonJS({
75633
75739
  res.status(500).json({ error: message, code: "RECIPIENTS_REMOVE_ERROR" });
75634
75740
  }
75635
75741
  });
75742
+ router.get("/service-identities", (_req, res) => {
75743
+ try {
75744
+ setNoCacheHeaders(res);
75745
+ const manifest = loadManifest();
75746
+ const identities = manifest.service_identities ?? [];
75747
+ const result = identities.map((si) => {
75748
+ const environments = {};
75749
+ for (const [envName, envConfig] of Object.entries(si.environments)) {
75750
+ const env = manifest.environments.find((e) => e.name === envName);
75751
+ if (envConfig.kms) {
75752
+ environments[envName] = {
75753
+ type: "kms",
75754
+ kms: envConfig.kms,
75755
+ protected: env?.protected ?? false
75756
+ };
75757
+ } else {
75758
+ environments[envName] = {
75759
+ type: "age",
75760
+ publicKey: envConfig.recipient,
75761
+ protected: env?.protected ?? false
75762
+ };
75763
+ }
75764
+ }
75765
+ return {
75766
+ name: si.name,
75767
+ description: si.description,
75768
+ namespaces: si.namespaces,
75769
+ environments
75770
+ };
75771
+ });
75772
+ res.json({ identities: result });
75773
+ } catch (err) {
75774
+ const message = err instanceof Error ? err.message : "Failed to load service identities";
75775
+ res.status(500).json({ error: message, code: "SERVICE_IDENTITY_ERROR" });
75776
+ }
75777
+ });
75636
75778
  function dispose() {
75637
75779
  lastScanResult = null;
75638
75780
  lastScanAt = null;
@@ -75689,7 +75831,7 @@ var require_server = __commonJS({
75689
75831
  };
75690
75832
  Object.defineProperty(exports2, "__esModule", { value: true });
75691
75833
  exports2.startServer = startServer;
75692
- var path43 = __importStar(require("path"));
75834
+ var path44 = __importStar(require("path"));
75693
75835
  var path_1 = require("path");
75694
75836
  var crypto_1 = require("crypto");
75695
75837
  var express_1 = __importDefault(require_express2());
@@ -75785,10 +75927,10 @@ var require_server = __commonJS({
75785
75927
  mountSeaStaticRoutes(app, sea, staticLimiter);
75786
75928
  }
75787
75929
  if (!isSeaBinary) {
75788
- const resolvedClientDir = clientDir ?? path43.resolve(__dirname, "../client");
75930
+ const resolvedClientDir = clientDir ?? path44.resolve(__dirname, "../client");
75789
75931
  app.use(staticLimiter, express_1.default.static(resolvedClientDir));
75790
75932
  app.get("/{*splat}", staticLimiter, (_req, res) => {
75791
- res.sendFile(path43.join(resolvedClientDir, "index.html"));
75933
+ res.sendFile(path44.join(resolvedClientDir, "index.html"));
75792
75934
  });
75793
75935
  }
75794
75936
  const url = `http://127.0.0.1:${port}`;
@@ -75930,32 +76072,32 @@ var require_disk_cache = __commonJS({
75930
76072
  })();
75931
76073
  Object.defineProperty(exports2, "__esModule", { value: true });
75932
76074
  exports2.DiskCache = void 0;
75933
- var fs26 = __importStar(require("fs"));
75934
- var path43 = __importStar(require("path"));
76075
+ var fs27 = __importStar(require("fs"));
76076
+ var path44 = __importStar(require("path"));
75935
76077
  var DiskCache = class {
75936
76078
  artifactPath;
75937
76079
  metaPath;
75938
76080
  constructor(cachePath, identity, environment) {
75939
- const dir = path43.join(cachePath, identity);
75940
- this.artifactPath = path43.join(dir, `${environment}.age.json`);
75941
- this.metaPath = path43.join(dir, `${environment}.meta`);
76081
+ const dir = path44.join(cachePath, identity);
76082
+ this.artifactPath = path44.join(dir, `${environment}.age.json`);
76083
+ this.metaPath = path44.join(dir, `${environment}.meta`);
75942
76084
  }
75943
76085
  /** Write an artifact and optional metadata to disk (atomic via tmp+rename). */
75944
76086
  write(raw, sha) {
75945
- const dir = path43.dirname(this.artifactPath);
75946
- fs26.mkdirSync(dir, { recursive: true });
76087
+ const dir = path44.dirname(this.artifactPath);
76088
+ fs27.mkdirSync(dir, { recursive: true });
75947
76089
  const tmpArtifact = `${this.artifactPath}.tmp.${process.pid}`;
75948
- fs26.writeFileSync(tmpArtifact, raw, "utf-8");
75949
- fs26.renameSync(tmpArtifact, this.artifactPath);
76090
+ fs27.writeFileSync(tmpArtifact, raw, "utf-8");
76091
+ fs27.renameSync(tmpArtifact, this.artifactPath);
75950
76092
  const meta = { sha, fetchedAt: (/* @__PURE__ */ new Date()).toISOString() };
75951
76093
  const tmpMeta = `${this.metaPath}.tmp.${process.pid}`;
75952
- fs26.writeFileSync(tmpMeta, JSON.stringify(meta), "utf-8");
75953
- fs26.renameSync(tmpMeta, this.metaPath);
76094
+ fs27.writeFileSync(tmpMeta, JSON.stringify(meta), "utf-8");
76095
+ fs27.renameSync(tmpMeta, this.metaPath);
75954
76096
  }
75955
76097
  /** Read the cached artifact. Returns null if no cache file exists. */
75956
76098
  read() {
75957
76099
  try {
75958
- return fs26.readFileSync(this.artifactPath, "utf-8");
76100
+ return fs27.readFileSync(this.artifactPath, "utf-8");
75959
76101
  } catch {
75960
76102
  return null;
75961
76103
  }
@@ -75963,7 +76105,7 @@ var require_disk_cache = __commonJS({
75963
76105
  /** Get the SHA from the cached metadata, if available. */
75964
76106
  getCachedSha() {
75965
76107
  try {
75966
- const raw = fs26.readFileSync(this.metaPath, "utf-8");
76108
+ const raw = fs27.readFileSync(this.metaPath, "utf-8");
75967
76109
  const meta = JSON.parse(raw);
75968
76110
  return meta.sha;
75969
76111
  } catch {
@@ -75973,7 +76115,7 @@ var require_disk_cache = __commonJS({
75973
76115
  /** Get the fetchedAt timestamp from metadata, if available. */
75974
76116
  getFetchedAt() {
75975
76117
  try {
75976
- const raw = fs26.readFileSync(this.metaPath, "utf-8");
76118
+ const raw = fs27.readFileSync(this.metaPath, "utf-8");
75977
76119
  const meta = JSON.parse(raw);
75978
76120
  return meta.fetchedAt;
75979
76121
  } catch {
@@ -75983,11 +76125,11 @@ var require_disk_cache = __commonJS({
75983
76125
  /** Remove cached artifact and metadata files. */
75984
76126
  purge() {
75985
76127
  try {
75986
- fs26.unlinkSync(this.artifactPath);
76128
+ fs27.unlinkSync(this.artifactPath);
75987
76129
  } catch {
75988
76130
  }
75989
76131
  try {
75990
- fs26.unlinkSync(this.metaPath);
76132
+ fs27.unlinkSync(this.metaPath);
75991
76133
  } catch {
75992
76134
  }
75993
76135
  }
@@ -76039,7 +76181,7 @@ var require_decrypt = __commonJS({
76039
76181
  })();
76040
76182
  Object.defineProperty(exports2, "__esModule", { value: true });
76041
76183
  exports2.AgeDecryptor = void 0;
76042
- var fs26 = __importStar(require("fs"));
76184
+ var fs27 = __importStar(require("fs"));
76043
76185
  var AgeDecryptor = class {
76044
76186
  /**
76045
76187
  * Decrypt an age-encrypted PEM-armored ciphertext string.
@@ -76052,7 +76194,7 @@ var require_decrypt = __commonJS({
76052
76194
  const { Decrypter } = await Promise.resolve(`${"age-encryption"}`).then((s) => __importStar(require(s)));
76053
76195
  const d = new Decrypter();
76054
76196
  d.addIdentity(privateKey);
76055
- return d.decrypt(ciphertext, "text");
76197
+ return d.decrypt(Buffer.from(ciphertext, "base64"), "text");
76056
76198
  }
76057
76199
  /**
76058
76200
  * Resolve the age private key from either an inline value or a file path.
@@ -76065,7 +76207,7 @@ var require_decrypt = __commonJS({
76065
76207
  if (ageKey)
76066
76208
  return ageKey.trim();
76067
76209
  if (ageKeyFile) {
76068
- const content = fs26.readFileSync(ageKeyFile, "utf-8").trim();
76210
+ const content = fs27.readFileSync(ageKeyFile, "utf-8").trim();
76069
76211
  const lines = content.split("\n").filter((l) => l.startsWith("AGE-SECRET-KEY-"));
76070
76212
  if (lines.length === 0) {
76071
76213
  throw new Error(`No age secret key found in file: ${ageKeyFile}`);
@@ -76875,8 +77017,8 @@ var require_github = __commonJS({
76875
77017
  this.ref = config.ref;
76876
77018
  this.apiUrl = config.apiUrl ?? "https://api.github.com";
76877
77019
  }
76878
- async fetchFile(path43) {
76879
- const url = new URL(`/repos/${this.repo}/contents/${path43}`, this.apiUrl);
77020
+ async fetchFile(path44) {
77021
+ const url = new URL(`/repos/${this.repo}/contents/${path44}`, this.apiUrl);
76880
77022
  if (this.ref)
76881
77023
  url.searchParams.set("ref", this.ref);
76882
77024
  const res = await fetch(url.toString(), {
@@ -76886,7 +77028,7 @@ var require_github = __commonJS({
76886
77028
  }
76887
77029
  });
76888
77030
  if (!res.ok) {
76889
- throw new Error(`GitHub API error: ${res.status} fetching ${path43} from ${this.repo}`);
77031
+ throw new Error(`GitHub API error: ${res.status} fetching ${path44} from ${this.repo}`);
76890
77032
  }
76891
77033
  const data = await res.json();
76892
77034
  const content = Buffer.from(data.content, "base64").toString("utf-8");
@@ -76914,9 +77056,9 @@ var require_gitlab = __commonJS({
76914
77056
  this.ref = config.ref;
76915
77057
  this.apiUrl = config.apiUrl ?? "https://gitlab.com";
76916
77058
  }
76917
- async fetchFile(path43) {
77059
+ async fetchFile(path44) {
76918
77060
  const encodedRepo = encodeURIComponent(this.repo);
76919
- const encodedPath = encodeURIComponent(path43);
77061
+ const encodedPath = encodeURIComponent(path44);
76920
77062
  const url = new URL(`/api/v4/projects/${encodedRepo}/repository/files/${encodedPath}`, this.apiUrl);
76921
77063
  if (this.ref)
76922
77064
  url.searchParams.set("ref", this.ref);
@@ -76926,7 +77068,7 @@ var require_gitlab = __commonJS({
76926
77068
  }
76927
77069
  });
76928
77070
  if (!res.ok) {
76929
- throw new Error(`GitLab API error: ${res.status} fetching ${path43} from ${this.repo}`);
77071
+ throw new Error(`GitLab API error: ${res.status} fetching ${path44} from ${this.repo}`);
76930
77072
  }
76931
77073
  const data = await res.json();
76932
77074
  const content = Buffer.from(data.content, "base64").toString("utf-8");
@@ -76954,8 +77096,8 @@ var require_bitbucket = __commonJS({
76954
77096
  this.ref = config.ref ?? "main";
76955
77097
  this.apiUrl = config.apiUrl ?? "https://api.bitbucket.org";
76956
77098
  }
76957
- async fetchFile(path43) {
76958
- const baseUrl = `${this.apiUrl}/2.0/repositories/${this.repo}/src/${this.ref}/${path43}`;
77099
+ async fetchFile(path44) {
77100
+ const baseUrl = `${this.apiUrl}/2.0/repositories/${this.repo}/src/${this.ref}/${path44}`;
76959
77101
  const metaRes = await fetch(baseUrl, {
76960
77102
  headers: {
76961
77103
  Authorization: `Bearer ${this.token}`,
@@ -76963,7 +77105,7 @@ var require_bitbucket = __commonJS({
76963
77105
  }
76964
77106
  });
76965
77107
  if (!metaRes.ok) {
76966
- throw new Error(`Bitbucket API error: ${metaRes.status} fetching ${path43} from ${this.repo}`);
77108
+ throw new Error(`Bitbucket API error: ${metaRes.status} fetching ${path44} from ${this.repo}`);
76967
77109
  }
76968
77110
  const meta = await metaRes.json();
76969
77111
  const rawRes = await fetch(baseUrl, {
@@ -76972,7 +77114,7 @@ var require_bitbucket = __commonJS({
76972
77114
  }
76973
77115
  });
76974
77116
  if (!rawRes.ok) {
76975
- throw new Error(`Bitbucket API error: ${rawRes.status} fetching raw content of ${path43} from ${this.repo}`);
77117
+ throw new Error(`Bitbucket API error: ${rawRes.status} fetching raw content of ${path44} from ${this.repo}`);
76976
77118
  }
76977
77119
  const content = await rawRes.text();
76978
77120
  return { content, sha: meta.commit.hash };
@@ -77090,14 +77232,14 @@ var require_file = __commonJS({
77090
77232
  })();
77091
77233
  Object.defineProperty(exports2, "__esModule", { value: true });
77092
77234
  exports2.FileArtifactSource = void 0;
77093
- var fs26 = __importStar(require("fs"));
77235
+ var fs27 = __importStar(require("fs"));
77094
77236
  var FileArtifactSource = class {
77095
77237
  path;
77096
77238
  constructor(filePath) {
77097
77239
  this.path = filePath;
77098
77240
  }
77099
77241
  async fetch() {
77100
- const raw = fs26.readFileSync(this.path, "utf-8");
77242
+ const raw = fs27.readFileSync(this.path, "utf-8");
77101
77243
  return { raw };
77102
77244
  }
77103
77245
  describe() {
@@ -77367,7 +77509,7 @@ var NodeSubprocessRunner = class {
77367
77509
  var fs17 = __toESM(require("fs"));
77368
77510
  var path19 = __toESM(require("path"));
77369
77511
  var readline2 = __toESM(require("readline"));
77370
- var YAML11 = __toESM(require_dist());
77512
+ var YAML12 = __toESM(require_dist());
77371
77513
  init_src();
77372
77514
 
77373
77515
  // src/output/formatter.ts
@@ -77511,6 +77653,7 @@ ${label}
77511
77653
  return new Promise((resolve6) => {
77512
77654
  rl.question(color(import_picocolors.default.yellow, `${prompt} [y/N] `), (answer) => {
77513
77655
  rl.close();
77656
+ process.stdin.pause();
77514
77657
  resolve6(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
77515
77658
  });
77516
77659
  });
@@ -77550,6 +77693,7 @@ ${label}
77550
77693
  process.stdin.setRawMode(false);
77551
77694
  }
77552
77695
  process.stdin.removeListener("data", onData);
77696
+ process.stdin.pause();
77553
77697
  process.stderr.write("\n");
77554
77698
  resolve6(value);
77555
77699
  } else if (char === "") {
@@ -77682,25 +77826,57 @@ async function getDarwin(runner2, account) {
77682
77826
  if (result.exitCode === 0) {
77683
77827
  const key = result.stdout.trim();
77684
77828
  if (key.startsWith("AGE-SECRET-KEY-")) return key;
77829
+ if (key) {
77830
+ formatter.warn(
77831
+ "OS keychain entry exists but contains invalid key data\n (expected AGE-SECRET-KEY-... format). The entry may be corrupted.\n Delete the 'clef' entry in Keychain Access and re-run clef init."
77832
+ );
77833
+ }
77685
77834
  }
77686
77835
  return null;
77687
77836
  } catch {
77688
77837
  return null;
77689
77838
  }
77690
77839
  }
77840
+ async function readDarwinRaw(runner2, account) {
77841
+ try {
77842
+ const result = await runner2.run("security", [
77843
+ "find-generic-password",
77844
+ "-a",
77845
+ account,
77846
+ "-s",
77847
+ SERVICE,
77848
+ "-w"
77849
+ ]);
77850
+ return result.exitCode === 0 ? result.stdout.trim() : "";
77851
+ } catch {
77852
+ return "";
77853
+ }
77854
+ }
77691
77855
  async function setDarwin(runner2, privateKey, account) {
77692
77856
  await runner2.run("security", ["delete-generic-password", "-a", account, "-s", SERVICE]).catch(() => {
77693
77857
  });
77694
- const result = await runner2.run("security", [
77695
- "add-generic-password",
77696
- "-a",
77697
- account,
77698
- "-s",
77699
- SERVICE,
77700
- "-w",
77701
- privateKey
77702
- ]);
77703
- return result.exitCode === 0;
77858
+ try {
77859
+ const result = await runner2.run("security", [
77860
+ "add-generic-password",
77861
+ "-a",
77862
+ account,
77863
+ "-s",
77864
+ SERVICE,
77865
+ "-w",
77866
+ privateKey
77867
+ ]);
77868
+ if (result.exitCode !== 0) return false;
77869
+ const stored = await readDarwinRaw(runner2, account);
77870
+ if (stored === privateKey) return true;
77871
+ formatter.warn(
77872
+ "Keychain write succeeded but read-back verification failed \u2014\n the stored value may be truncated or corrupted.\n Falling back to file-based key storage."
77873
+ );
77874
+ await runner2.run("security", ["delete-generic-password", "-a", account, "-s", SERVICE]).catch(() => {
77875
+ });
77876
+ return false;
77877
+ } catch {
77878
+ return false;
77879
+ }
77704
77880
  }
77705
77881
  async function getLinux(runner2, account) {
77706
77882
  try {
@@ -77714,6 +77890,11 @@ async function getLinux(runner2, account) {
77714
77890
  if (result.exitCode === 0) {
77715
77891
  const key = result.stdout.trim();
77716
77892
  if (key.startsWith("AGE-SECRET-KEY-")) return key;
77893
+ if (key) {
77894
+ formatter.warn(
77895
+ "OS keychain entry exists but contains invalid key data\n (expected AGE-SECRET-KEY-... format). The entry may be corrupted."
77896
+ );
77897
+ }
77717
77898
  }
77718
77899
  return null;
77719
77900
  } catch {
@@ -77757,6 +77938,11 @@ ${CRED_HELPER_CS}
77757
77938
  if (result.exitCode === 0) {
77758
77939
  const key = result.stdout.trim();
77759
77940
  if (key.startsWith("AGE-SECRET-KEY-")) return key;
77941
+ if (key) {
77942
+ formatter.warn(
77943
+ "Windows Credential Manager entry exists but contains invalid key data\n (expected AGE-SECRET-KEY-... format). The entry may be corrupted."
77944
+ );
77945
+ }
77760
77946
  }
77761
77947
  return null;
77762
77948
  } catch {
@@ -78023,6 +78209,9 @@ async function handleSecondDevOnboarding(repoRoot, clefConfigPath, deps2, option
78023
78209
  formatter.success("Stored age key in OS keychain");
78024
78210
  config = { age_key_storage: "keychain", age_keychain_label: label };
78025
78211
  } else {
78212
+ formatter.warn(
78213
+ "OS keychain is not available on this system.\n The private key will be written to the filesystem instead.\n See https://docs.clef.sh/guide/key-storage for security implications."
78214
+ );
78026
78215
  let keyPath;
78027
78216
  if (options.nonInteractive || !process.stdin.isTTY) {
78028
78217
  keyPath = process.env.CLEF_AGE_KEY_FILE || defaultAgeKeyPath(label);
@@ -78049,7 +78238,7 @@ async function handleSecondDevOnboarding(repoRoot, clefConfigPath, deps2, option
78049
78238
  if (!fs17.existsSync(clefDir)) {
78050
78239
  fs17.mkdirSync(clefDir, { recursive: true });
78051
78240
  }
78052
- fs17.writeFileSync(clefConfigPath, YAML11.stringify(config), "utf-8");
78241
+ fs17.writeFileSync(clefConfigPath, YAML12.stringify(config), "utf-8");
78053
78242
  formatter.success("Created .clef/config.yaml");
78054
78243
  const gitignorePath = path19.join(clefDir, ".gitignore");
78055
78244
  if (!fs17.existsSync(gitignorePath)) {
@@ -78106,15 +78295,14 @@ async function handleFullSetup(repoRoot, manifestPath, clefConfigPath, deps2, op
78106
78295
  };
78107
78296
  const initParser = new ManifestParser();
78108
78297
  initParser.validate(manifest);
78109
- fs17.writeFileSync(manifestPath, YAML11.stringify(manifest), "utf-8");
78110
- formatter.success("Created clef.yaml");
78111
78298
  let ageKeyFile;
78112
78299
  let ageKey;
78300
+ let publicKey;
78113
78301
  if (backend === "age") {
78114
78302
  const label = generateKeyLabel();
78115
78303
  const identity = await generateAgeIdentity();
78116
78304
  const privateKey = identity.privateKey;
78117
- const publicKey = identity.publicKey;
78305
+ publicKey = identity.publicKey;
78118
78306
  const storedInKeychain = await setKeychainKey(deps2.runner, privateKey, label);
78119
78307
  if (storedInKeychain) {
78120
78308
  formatter.success("Stored age key in OS keychain");
@@ -78158,7 +78346,7 @@ async function handleFullSetup(repoRoot, manifestPath, clefConfigPath, deps2, op
78158
78346
  fs17.mkdirSync(clefDir, { recursive: true });
78159
78347
  }
78160
78348
  const config = ageKeyFile ? { age_key_file: ageKeyFile, age_key_storage: "file", age_keychain_label: label } : { age_key_storage: "keychain", age_keychain_label: label };
78161
- fs17.writeFileSync(clefConfigPath, YAML11.stringify(config), "utf-8");
78349
+ fs17.writeFileSync(clefConfigPath, YAML12.stringify(config), "utf-8");
78162
78350
  formatter.success("Created .clef/config.yaml");
78163
78351
  const gitignorePath = path19.join(clefDir, ".gitignore");
78164
78352
  if (!fs17.existsSync(gitignorePath)) {
@@ -78166,14 +78354,18 @@ async function handleFullSetup(repoRoot, manifestPath, clefConfigPath, deps2, op
78166
78354
  formatter.success("Created .clef/.gitignore");
78167
78355
  }
78168
78356
  formatter.success(`Key label: ${label}`);
78357
+ }
78358
+ const manifestDoc = YAML12.parse(YAML12.stringify(manifest));
78359
+ if (backend === "age" && publicKey) {
78360
+ const sopsDoc = manifestDoc.sops;
78361
+ sopsDoc.age = { recipients: [publicKey] };
78362
+ }
78363
+ fs17.writeFileSync(manifestPath, YAML12.stringify(manifestDoc), "utf-8");
78364
+ formatter.success("Created clef.yaml");
78365
+ {
78169
78366
  const sopsYamlPath = path19.join(repoRoot, ".sops.yaml");
78170
78367
  const sopsConfig = buildSopsYaml(manifest, repoRoot, publicKey);
78171
- fs17.writeFileSync(sopsYamlPath, YAML11.stringify(sopsConfig), "utf-8");
78172
- formatter.success("Created .sops.yaml");
78173
- } else {
78174
- const sopsYamlPath = path19.join(repoRoot, ".sops.yaml");
78175
- const sopsConfig = buildSopsYaml(manifest, repoRoot, void 0);
78176
- fs17.writeFileSync(sopsYamlPath, YAML11.stringify(sopsConfig), "utf-8");
78368
+ fs17.writeFileSync(sopsYamlPath, YAML12.stringify(sopsConfig), "utf-8");
78177
78369
  formatter.success("Created .sops.yaml");
78178
78370
  }
78179
78371
  const sopsClient = new SopsClient(deps2.runner, ageKeyFile, ageKey);
@@ -78263,7 +78455,7 @@ function scaffoldSopsConfig(repoRoot) {
78263
78455
  agePublicKey = resolveAgePublicKeyFromEnvOrFile(repoRoot);
78264
78456
  }
78265
78457
  const sopsConfig = buildSopsYaml(manifest, repoRoot, agePublicKey);
78266
- fs17.writeFileSync(sopsYamlPath, YAML11.stringify(sopsConfig), "utf-8");
78458
+ fs17.writeFileSync(sopsYamlPath, YAML12.stringify(sopsConfig), "utf-8");
78267
78459
  }
78268
78460
  function buildSopsYaml(manifest, _repoRoot, agePublicKey) {
78269
78461
  const creationRules = [];
@@ -78329,7 +78521,7 @@ function resolveAgePublicKeyFromEnvOrFile(repoRoot) {
78329
78521
  const clefConfigPath = path19.join(repoRoot, CLEF_DIR, CLEF_CONFIG_FILENAME);
78330
78522
  if (fs17.existsSync(clefConfigPath)) {
78331
78523
  try {
78332
- const config = YAML11.parse(fs17.readFileSync(clefConfigPath, "utf-8"));
78524
+ const config = YAML12.parse(fs17.readFileSync(clefConfigPath, "utf-8"));
78333
78525
  if (config?.age_key_file) {
78334
78526
  const pubKey = extractAgePublicKey(config.age_key_file);
78335
78527
  if (pubKey) return pubKey;
@@ -78398,6 +78590,7 @@ function promptWithDefault(message, defaultValue) {
78398
78590
  return new Promise((resolve6) => {
78399
78591
  rl.question(prompt, (answer) => {
78400
78592
  rl.close();
78593
+ process.stdin.pause();
78401
78594
  resolve6(answer.trim() || defaultValue);
78402
78595
  });
78403
78596
  });
@@ -78410,7 +78603,7 @@ init_src();
78410
78603
  // src/age-credential.ts
78411
78604
  var fs18 = __toESM(require("fs"));
78412
78605
  var path20 = __toESM(require("path"));
78413
- var YAML12 = __toESM(require_dist());
78606
+ var YAML13 = __toESM(require_dist());
78414
78607
  init_src();
78415
78608
  var CLEF_DIR2 = ".clef";
78416
78609
  var CLEF_CONFIG_FILENAME2 = "config.yaml";
@@ -78420,6 +78613,11 @@ async function resolveAgeCredential(repoRoot, runner2) {
78420
78613
  if (label) {
78421
78614
  const keychainKey = await getKeychainKey(runner2, label);
78422
78615
  if (keychainKey) return { source: "keychain", privateKey: keychainKey };
78616
+ if (config?.age_key_storage !== "file") {
78617
+ formatter.warn(
78618
+ "OS keychain is configured but the age key could not be retrieved.\n Falling back to environment variables / key file.\n Run clef doctor for diagnostics."
78619
+ );
78620
+ }
78423
78621
  }
78424
78622
  if (process.env.CLEF_AGE_KEY) return { source: "env-key" };
78425
78623
  if (process.env.CLEF_AGE_KEY_FILE) return { source: "env-file" };
@@ -78473,7 +78671,10 @@ async function resolveAgePrivateKey(repoRoot, runner2) {
78473
78671
  const content = fs18.readFileSync(filePath, "utf-8");
78474
78672
  const match = content.match(AGE_SECRET_KEY_RE);
78475
78673
  return match ? match[1] : null;
78476
- } catch {
78674
+ } catch (err) {
78675
+ formatter.warn(
78676
+ `Could not read age key file (CLEF_AGE_KEY_FILE=${filePath}): ${err instanceof Error ? err.message : String(err)}`
78677
+ );
78477
78678
  return null;
78478
78679
  }
78479
78680
  }
@@ -78482,7 +78683,10 @@ async function resolveAgePrivateKey(repoRoot, runner2) {
78482
78683
  const content = fs18.readFileSync(credential.path, "utf-8");
78483
78684
  const match = content.match(AGE_SECRET_KEY_RE);
78484
78685
  return match ? match[1] : null;
78485
- } catch {
78686
+ } catch (err) {
78687
+ formatter.warn(
78688
+ `Could not read age key file (${credential.path}): ${err instanceof Error ? err.message : String(err)}`
78689
+ );
78486
78690
  return null;
78487
78691
  }
78488
78692
  }
@@ -78492,17 +78696,53 @@ function readLocalConfig(repoRoot) {
78492
78696
  const clefConfigPath = path20.join(repoRoot, CLEF_DIR2, CLEF_CONFIG_FILENAME2);
78493
78697
  try {
78494
78698
  if (!fs18.existsSync(clefConfigPath)) return null;
78495
- return YAML12.parse(fs18.readFileSync(clefConfigPath, "utf-8"));
78496
- } catch {
78699
+ return YAML13.parse(fs18.readFileSync(clefConfigPath, "utf-8"));
78700
+ } catch (err) {
78701
+ formatter.warn(
78702
+ `Failed to parse ${clefConfigPath}: ${err instanceof Error ? err.message : String(err)}
78703
+ Credential resolution will proceed without local config.`
78704
+ );
78497
78705
  return null;
78498
78706
  }
78499
78707
  }
78500
78708
 
78709
+ // src/clipboard.ts
78710
+ var import_child_process2 = require("child_process");
78711
+ function copyToClipboard(text) {
78712
+ try {
78713
+ switch (process.platform) {
78714
+ case "darwin":
78715
+ (0, import_child_process2.execFileSync)("pbcopy", { input: text, stdio: ["pipe", "ignore", "ignore"] });
78716
+ return true;
78717
+ case "win32":
78718
+ (0, import_child_process2.execFileSync)("clip", { input: text, stdio: ["pipe", "ignore", "ignore"], shell: true });
78719
+ return true;
78720
+ default: {
78721
+ for (const cmd of ["xclip", "xsel"]) {
78722
+ try {
78723
+ const args = cmd === "xclip" ? ["-selection", "clipboard"] : ["--clipboard", "--input"];
78724
+ (0, import_child_process2.execFileSync)(cmd, args, { input: text, stdio: ["pipe", "ignore", "ignore"] });
78725
+ return true;
78726
+ } catch {
78727
+ continue;
78728
+ }
78729
+ }
78730
+ return false;
78731
+ }
78732
+ }
78733
+ } catch {
78734
+ return false;
78735
+ }
78736
+ }
78737
+ function maskedPlaceholder() {
78738
+ return "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
78739
+ }
78740
+
78501
78741
  // src/commands/get.ts
78502
78742
  function registerGetCommand(program3, deps2) {
78503
78743
  program3.command("get <target> <key>").description(
78504
- "Get a single decrypted value.\n\n target: namespace/environment (e.g. payments/production)\n key: the key name to retrieve\n\nExit codes:\n 0 Value found and printed\n 1 Key not found or decryption error"
78505
- ).action(async (target, key) => {
78744
+ "Get a single decrypted value.\n\n target: namespace/environment (e.g. payments/production)\n key: the key name to retrieve\n\nBy default, the value is copied to clipboard and obfuscated on screen.\nUse --raw to print the plaintext value to stdout.\n\nExit codes:\n 0 Value found\n 1 Key not found or decryption error"
78745
+ ).option("--raw", "Print the plaintext value to stdout (for piping/scripting)").action(async (target, key, opts) => {
78506
78746
  try {
78507
78747
  const [namespace, environment] = parseTarget(target);
78508
78748
  const repoRoot = program3.opts().dir || process.cwd();
@@ -78521,7 +78761,17 @@ function registerGetCommand(program3, deps2) {
78521
78761
  process.exit(1);
78522
78762
  return;
78523
78763
  }
78524
- formatter.keyValue(key, decrypted.values[key]);
78764
+ const val = decrypted.values[key];
78765
+ if (opts.raw) {
78766
+ formatter.raw(val);
78767
+ } else {
78768
+ const copied = copyToClipboard(val);
78769
+ if (copied) {
78770
+ formatter.print(` ${key}: ${maskedPlaceholder()} (copied to clipboard)`);
78771
+ } else {
78772
+ formatter.keyValue(key, val);
78773
+ }
78774
+ }
78525
78775
  } catch (err) {
78526
78776
  if (err instanceof SopsMissingError || err instanceof SopsVersionError) {
78527
78777
  formatter.formatDependencyError(err);
@@ -79233,7 +79483,7 @@ async function fetchCheckpoint(config) {
79233
79483
  }
79234
79484
 
79235
79485
  // package.json
79236
- var version = "0.1.6-beta.32";
79486
+ var version = "0.1.7-beta.45";
79237
79487
  var package_default = {
79238
79488
  name: "@clef-sh/cli",
79239
79489
  version,
@@ -79307,6 +79557,10 @@ function registerLintCommand(program3, deps2) {
79307
79557
  const matrixManager = new MatrixManager();
79308
79558
  const schemaValidator = new SchemaValidator();
79309
79559
  const lintRunner = new LintRunner(matrixManager, schemaValidator, sopsClient);
79560
+ const cellCount = manifest.namespaces.length * manifest.environments.length;
79561
+ formatter.print(
79562
+ `${sym("working")} Linting ${cellCount} file(s) across ${manifest.namespaces.length} namespace(s)...`
79563
+ );
79310
79564
  let result;
79311
79565
  if (options.fix) {
79312
79566
  result = await lintRunner.fix(manifest, repoRoot);
@@ -79596,7 +79850,7 @@ async function openBrowser(url, runner2) {
79596
79850
 
79597
79851
  // src/commands/exec.ts
79598
79852
  var path30 = __toESM(require("path"));
79599
- var import_child_process2 = require("child_process");
79853
+ var import_child_process3 = require("child_process");
79600
79854
  init_src();
79601
79855
  function collect(value, previous) {
79602
79856
  return previous.concat([value]);
@@ -79701,7 +79955,7 @@ function spawnChild(command, args, env) {
79701
79955
  return new Promise((resolve6) => {
79702
79956
  let child;
79703
79957
  try {
79704
- child = (0, import_child_process2.spawn)(command, args, {
79958
+ child = (0, import_child_process3.spawn)(command, args, {
79705
79959
  env,
79706
79960
  stdio: "inherit"
79707
79961
  });
@@ -79754,8 +80008,8 @@ var path31 = __toESM(require("path"));
79754
80008
  init_src();
79755
80009
  function registerExportCommand(program3, deps2) {
79756
80010
  program3.command("export <target>").description(
79757
- "Print decrypted secrets as shell export statements to stdout.\n\n target: namespace/environment (e.g. payments/production)\n\nUsage:\n eval $(clef export payments/production --format env)\n\nExit codes:\n 0 Values printed successfully\n 1 Decryption error or invalid arguments"
79758
- ).option("--format <format>", "Output format (only 'env' is supported)", "env").option("--no-export", "Omit the 'export' keyword \u2014 output bare KEY=value pairs").action(async (target, options) => {
80011
+ "Export decrypted secrets as shell export statements.\n\n target: namespace/environment (e.g. payments/production)\n\nBy default, exports are copied to clipboard. Use --raw to print to stdout.\n\nUsage:\n clef export payments/production (copies to clipboard)\n eval $(clef export payments/production --raw) (injects into shell)\n\nExit codes:\n 0 Values exported successfully\n 1 Decryption error or invalid arguments"
80012
+ ).option("--format <format>", "Output format (only 'env' is supported)", "env").option("--no-export", "Omit the 'export' keyword \u2014 output bare KEY=value pairs").option("--raw", "Print to stdout instead of clipboard (for eval/piping)").action(async (target, options) => {
79759
80013
  try {
79760
80014
  if (options.format !== "env") {
79761
80015
  if (options.format === "dotenv" || options.format === "json" || options.format === "yaml") {
@@ -79788,12 +80042,28 @@ Usage: clef export payments/production --format env`
79788
80042
  const decrypted = await sopsClient.decrypt(filePath);
79789
80043
  const consumption = new ConsumptionClient();
79790
80044
  const output = consumption.formatExport(decrypted, "env", !options.export);
79791
- if (process.platform === "linux") {
79792
- formatter.warn(
79793
- "Exported values will be visible in /proc/<pid>/environ to processes with ptrace access. Use clef exec when possible."
79794
- );
80045
+ if (options.raw) {
80046
+ if (process.platform === "linux") {
80047
+ formatter.warn(
80048
+ "Exported values will be visible in /proc/<pid>/environ to processes with ptrace access. Use clef exec when possible."
80049
+ );
80050
+ }
80051
+ formatter.raw(output);
80052
+ } else {
80053
+ const keyCount = Object.keys(decrypted.values).length;
80054
+ const copied = copyToClipboard(output);
80055
+ if (copied) {
80056
+ formatter.success(`${keyCount} secret(s) copied to clipboard as env exports.`);
80057
+ formatter.hint("eval $(clef export " + target + " --raw) to inject into shell");
80058
+ } else {
80059
+ if (process.platform === "linux") {
80060
+ formatter.warn(
80061
+ "Exported values will be visible in /proc/<pid>/environ to processes with ptrace access. Use clef exec when possible."
80062
+ );
80063
+ }
80064
+ formatter.raw(output);
80065
+ }
79795
80066
  }
79796
- formatter.raw(output);
79797
80067
  } catch (err) {
79798
80068
  if (err instanceof SopsMissingError || err instanceof SopsVersionError) {
79799
80069
  formatter.formatDependencyError(err);
@@ -79817,7 +80087,7 @@ function parseTarget7(target) {
79817
80087
  // src/commands/doctor.ts
79818
80088
  var fs20 = __toESM(require("fs"));
79819
80089
  var path32 = __toESM(require("path"));
79820
- var YAML13 = __toESM(require_dist());
80090
+ var YAML14 = __toESM(require_dist());
79821
80091
  init_src();
79822
80092
  function registerDoctorCommand(program3, deps2) {
79823
80093
  program3.command("doctor").description(
@@ -80066,7 +80336,7 @@ function countAgeRecipients(sopsYamlPath) {
80066
80336
  try {
80067
80337
  if (!fs20.existsSync(sopsYamlPath)) return 0;
80068
80338
  const content = fs20.readFileSync(sopsYamlPath, "utf-8");
80069
- const config = YAML13.parse(content);
80339
+ const config = YAML14.parse(content);
80070
80340
  if (!config?.creation_rules || !Array.isArray(config.creation_rules)) {
80071
80341
  return 0;
80072
80342
  }
@@ -80453,6 +80723,7 @@ function waitForEnter(message) {
80453
80723
  });
80454
80724
  rl.question(message, () => {
80455
80725
  rl.close();
80726
+ process.stdin.pause();
80456
80727
  resolve6();
80457
80728
  });
80458
80729
  });
@@ -81002,6 +81273,9 @@ function registerServiceCommand(program3, deps2) {
81002
81273
  `Invalid KMS provider '${provider}'. Must be one of: aws, gcp, azure.`
81003
81274
  );
81004
81275
  }
81276
+ if (kmsEnvConfigs[envName]) {
81277
+ throw new Error(`Duplicate --kms-env for environment '${envName}'.`);
81278
+ }
81005
81279
  kmsEnvConfigs[envName] = {
81006
81280
  provider,
81007
81281
  keyId
@@ -81040,13 +81314,24 @@ function registerServiceCommand(program3, deps2) {
81040
81314
  `
81041
81315
  );
81042
81316
  if (Object.keys(result.privateKeys).length > 0) {
81043
- formatter.warn(
81044
- "Private keys are shown ONCE. Store them securely (e.g. AWS Secrets Manager, Vault).\n"
81045
- );
81046
- for (const [envName, privateKey] of Object.entries(result.privateKeys)) {
81047
- formatter.print(` ${envName}:`);
81048
- formatter.print(` ${privateKey}
81317
+ const entries = Object.entries(result.privateKeys);
81318
+ const block = entries.map(([env, key]) => `${env}: ${key}`).join("\n");
81319
+ const copied = copyToClipboard(block);
81320
+ if (copied) {
81321
+ formatter.warn("Private keys copied to clipboard. Store them securely.\n");
81322
+ for (const [envName] of entries) {
81323
+ formatter.print(` ${envName}: ${maskedPlaceholder()}`);
81324
+ }
81325
+ formatter.print("");
81326
+ } else {
81327
+ formatter.warn(
81328
+ "Private keys are shown ONCE. Store them securely (e.g. AWS Secrets Manager, Vault).\n"
81329
+ );
81330
+ for (const [envName, privateKey] of entries) {
81331
+ formatter.print(` ${envName}:`);
81332
+ formatter.print(` ${privateKey}
81049
81333
  `);
81334
+ }
81050
81335
  }
81051
81336
  for (const k of Object.keys(result.privateKeys)) result.privateKeys[k] = "";
81052
81337
  }
@@ -81181,6 +81466,109 @@ Service Identity: ${identity.name}`);
81181
81466
  process.exit(1);
81182
81467
  }
81183
81468
  });
81469
+ serviceCmd.command("update <name>").description("Update an existing service identity's environment backends.").option(
81470
+ "--kms-env <mapping>",
81471
+ "Switch an environment to KMS envelope encryption: env=provider:keyId (repeatable)",
81472
+ (val, acc) => {
81473
+ acc.push(val);
81474
+ return acc;
81475
+ },
81476
+ []
81477
+ ).action(async (name, opts) => {
81478
+ try {
81479
+ if (opts.kmsEnv.length === 0) {
81480
+ formatter.error("Nothing to update. Provide --kms-env to change environment backends.");
81481
+ process.exit(1);
81482
+ return;
81483
+ }
81484
+ const repoRoot = program3.opts().dir || process.cwd();
81485
+ const parser = new ManifestParser();
81486
+ const manifest = parser.parse(path38.join(repoRoot, "clef.yaml"));
81487
+ const kmsEnvConfigs = {};
81488
+ for (const mapping of opts.kmsEnv) {
81489
+ const eqIdx = mapping.indexOf("=");
81490
+ if (eqIdx === -1) {
81491
+ throw new Error(`Invalid --kms-env format: '${mapping}'. Expected: env=provider:keyId`);
81492
+ }
81493
+ const envName = mapping.slice(0, eqIdx);
81494
+ const rest = mapping.slice(eqIdx + 1);
81495
+ const colonIdx = rest.indexOf(":");
81496
+ if (colonIdx === -1) {
81497
+ throw new Error(`Invalid --kms-env format: '${mapping}'. Expected: env=provider:keyId`);
81498
+ }
81499
+ const provider = rest.slice(0, colonIdx);
81500
+ const keyId = rest.slice(colonIdx + 1);
81501
+ if (!["aws", "gcp", "azure"].includes(provider)) {
81502
+ throw new Error(`Invalid KMS provider '${provider}'. Must be one of: aws, gcp, azure.`);
81503
+ }
81504
+ if (kmsEnvConfigs[envName]) {
81505
+ throw new Error(`Duplicate --kms-env for environment '${envName}'.`);
81506
+ }
81507
+ kmsEnvConfigs[envName] = {
81508
+ provider,
81509
+ keyId
81510
+ };
81511
+ }
81512
+ const matrixManager = new MatrixManager();
81513
+ const sopsClient = await createSopsClient(repoRoot, deps2.runner);
81514
+ const manager = new ServiceIdentityManager(sopsClient, matrixManager);
81515
+ formatter.print(`${sym("working")} Updating service identity '${name}'...`);
81516
+ await manager.updateEnvironments(name, kmsEnvConfigs, manifest, repoRoot);
81517
+ formatter.success(`Service identity '${name}' updated.`);
81518
+ for (const [envName, kmsConfig] of Object.entries(kmsEnvConfigs)) {
81519
+ formatter.print(` ${envName}: switched to KMS envelope (${kmsConfig.provider})`);
81520
+ }
81521
+ formatter.hint(
81522
+ `git add clef.yaml && git commit -m "chore: update service identity '${name}'"`
81523
+ );
81524
+ } catch (err) {
81525
+ if (err instanceof SopsMissingError || err instanceof SopsVersionError) {
81526
+ formatter.formatDependencyError(err);
81527
+ process.exit(1);
81528
+ return;
81529
+ }
81530
+ formatter.error(err.message);
81531
+ process.exit(1);
81532
+ }
81533
+ });
81534
+ serviceCmd.command("delete <name>").description("Delete a service identity and remove its recipients from scoped files.").action(async (name) => {
81535
+ try {
81536
+ const repoRoot = program3.opts().dir || process.cwd();
81537
+ const parser = new ManifestParser();
81538
+ const manifest = parser.parse(path38.join(repoRoot, "clef.yaml"));
81539
+ const identity = manifest.service_identities?.find((si) => si.name === name);
81540
+ if (!identity) {
81541
+ formatter.error(`Service identity '${name}' not found.`);
81542
+ process.exit(1);
81543
+ return;
81544
+ }
81545
+ const confirmed = await formatter.confirm(
81546
+ `Delete service identity '${name}'? This will remove its recipients from all scoped files.`
81547
+ );
81548
+ if (!confirmed) {
81549
+ formatter.error("Aborted.");
81550
+ process.exit(1);
81551
+ return;
81552
+ }
81553
+ const matrixManager = new MatrixManager();
81554
+ const sopsClient = await createSopsClient(repoRoot, deps2.runner);
81555
+ const manager = new ServiceIdentityManager(sopsClient, matrixManager);
81556
+ formatter.print(`${sym("working")} Deleting service identity '${name}'...`);
81557
+ await manager.delete(name, manifest, repoRoot);
81558
+ formatter.success(`Service identity '${name}' deleted.`);
81559
+ formatter.hint(
81560
+ `git add clef.yaml && git commit -m "chore: delete service identity '${name}'"`
81561
+ );
81562
+ } catch (err) {
81563
+ if (err instanceof SopsMissingError || err instanceof SopsVersionError) {
81564
+ formatter.formatDependencyError(err);
81565
+ process.exit(1);
81566
+ return;
81567
+ }
81568
+ formatter.error(err.message);
81569
+ process.exit(1);
81570
+ }
81571
+ });
81184
81572
  serviceCmd.command("rotate <name>").description("Rotate the age key for a service identity.").option("-e, --environment <env>", "Rotate only a specific environment").action(async (name, opts) => {
81185
81573
  try {
81186
81574
  const repoRoot = program3.opts().dir || process.cwd();
@@ -81210,11 +81598,22 @@ Service Identity: ${identity.name}`);
81210
81598
  formatter.print(`${sym("working")} Rotating key for '${name}'...`);
81211
81599
  const newKeys = await manager.rotateKey(name, manifest, repoRoot, opts.environment);
81212
81600
  formatter.success(`Key rotated for '${name}'.`);
81213
- formatter.warn("New private keys are shown ONCE. Store them securely.\n");
81214
- for (const [envName, privateKey] of Object.entries(newKeys)) {
81215
- formatter.print(` ${envName}:`);
81216
- formatter.print(` ${privateKey}
81601
+ const entries = Object.entries(newKeys);
81602
+ const block = entries.map(([env, key]) => `${env}: ${key}`).join("\n");
81603
+ const copied = copyToClipboard(block);
81604
+ if (copied) {
81605
+ formatter.warn("New private keys copied to clipboard. Store them securely.\n");
81606
+ for (const [envName] of entries) {
81607
+ formatter.print(` ${envName}: ${maskedPlaceholder()}`);
81608
+ }
81609
+ formatter.print("");
81610
+ } else {
81611
+ formatter.warn("New private keys are shown ONCE. Store them securely.\n");
81612
+ for (const [envName, privateKey] of entries) {
81613
+ formatter.print(` ${envName}:`);
81614
+ formatter.print(` ${privateKey}
81217
81615
  `);
81616
+ }
81218
81617
  }
81219
81618
  for (const k of Object.keys(newKeys)) newKeys[k] = "";
81220
81619
  formatter.hint(
@@ -81228,11 +81627,25 @@ Service Identity: ${identity.name}`);
81228
81627
  }
81229
81628
  if (err instanceof PartialRotationError) {
81230
81629
  formatter.error(err.message);
81231
- formatter.warn("Partial rotation succeeded. New private keys below \u2014 store them NOW.\n");
81232
- for (const [envName, privateKey] of Object.entries(err.rotatedKeys)) {
81233
- formatter.print(` ${envName}:`);
81234
- formatter.print(` ${privateKey}
81630
+ const partialEntries = Object.entries(err.rotatedKeys);
81631
+ const partialBlock = partialEntries.map(([env, key]) => `${env}: ${key}`).join("\n");
81632
+ const partialCopied = copyToClipboard(partialBlock);
81633
+ if (partialCopied) {
81634
+ formatter.warn(
81635
+ "Partial rotation succeeded. Rotated keys copied to clipboard \u2014 store them NOW.\n"
81636
+ );
81637
+ for (const [envName] of partialEntries) {
81638
+ formatter.print(` ${envName}: ${maskedPlaceholder()}`);
81639
+ }
81640
+ } else {
81641
+ formatter.warn(
81642
+ "Partial rotation succeeded. New private keys below \u2014 store them NOW.\n"
81643
+ );
81644
+ for (const [envName, privateKey] of partialEntries) {
81645
+ formatter.print(` ${envName}:`);
81646
+ formatter.print(` ${privateKey}
81235
81647
  `);
81648
+ }
81236
81649
  }
81237
81650
  for (const k of Object.keys(err.rotatedKeys)) {
81238
81651
  err.rotatedKeys[k] = "";
@@ -81700,6 +82113,189 @@ function formatReportOutput(report) {
81700
82113
  formatter.hint("Run clef lint or clef drift locally for details.");
81701
82114
  }
81702
82115
 
82116
+ // src/commands/install.ts
82117
+ var fs26 = __toESM(require("fs"));
82118
+ var path43 = __toESM(require("path"));
82119
+ var import_yaml = __toESM(require_dist());
82120
+
82121
+ // src/registry/client.ts
82122
+ var DEFAULT_REGISTRY = "https://raw.githubusercontent.com/clef-sh/clef/main/brokers";
82123
+ async function fetchIndex(registryUrl = DEFAULT_REGISTRY) {
82124
+ const url = `${registryUrl}/index.json`;
82125
+ const res = await fetch(url);
82126
+ if (!res.ok) {
82127
+ throw new Error(`Failed to fetch registry index from ${url} (${res.status})`);
82128
+ }
82129
+ return await res.json();
82130
+ }
82131
+ async function fetchBrokerFile(registryUrl, brokerPath, filename) {
82132
+ const url = `${registryUrl}/${brokerPath}/${filename}`;
82133
+ const res = await fetch(url);
82134
+ if (!res.ok) {
82135
+ throw new Error(`Failed to fetch ${filename} from ${url} (${res.status})`);
82136
+ }
82137
+ return res.text();
82138
+ }
82139
+ function findBroker(index, name) {
82140
+ return index.brokers.find((b) => b.name === name);
82141
+ }
82142
+
82143
+ // src/commands/install.ts
82144
+ var TIER_LABELS = {
82145
+ 1: "self-expiring",
82146
+ 2: "stateful",
82147
+ 3: "complex"
82148
+ };
82149
+ function registerInstallCommand(program3, _deps) {
82150
+ program3.command("install <broker>").description(
82151
+ "Install a broker template from the Clef registry.\n\nDownloads broker.yaml, handler.ts, and README.md\ninto brokers/<name>/ in your project.\n\nExit codes:\n 0 Broker installed successfully\n 1 Error (broker not found, network failure, etc.)"
82152
+ ).option("--registry <url>", "Custom registry base URL", DEFAULT_REGISTRY).option("--force", "Overwrite existing broker directory without prompting").action(async (brokerName, options) => {
82153
+ try {
82154
+ const repoRoot = program3.opts().dir || process.cwd();
82155
+ const registryUrl = options.registry;
82156
+ formatter.info(`Fetching ${brokerName} from registry...`);
82157
+ const index = await fetchIndex(registryUrl);
82158
+ const entry = findBroker(index, brokerName);
82159
+ if (!entry) {
82160
+ formatter.error(
82161
+ `Broker "${brokerName}" not found in the registry. Run 'clef search' to list available brokers.`
82162
+ );
82163
+ process.exit(1);
82164
+ return;
82165
+ }
82166
+ const brokerDir = path43.join(repoRoot, "brokers", entry.name);
82167
+ if (fs26.existsSync(brokerDir) && !options.force) {
82168
+ const overwrite = await formatter.confirm(
82169
+ `brokers/${entry.name}/ already exists. Overwrite?`
82170
+ );
82171
+ if (!overwrite) {
82172
+ formatter.info("Installation cancelled.");
82173
+ process.exit(0);
82174
+ return;
82175
+ }
82176
+ }
82177
+ const files = [];
82178
+ for (const filename of ["broker.yaml", "handler.ts", "README.md"]) {
82179
+ try {
82180
+ const content = await fetchBrokerFile(registryUrl, entry.path, filename);
82181
+ files.push({ name: filename, content });
82182
+ } catch {
82183
+ if (filename === "handler.ts") {
82184
+ try {
82185
+ const content = await fetchBrokerFile(registryUrl, entry.path, "handler.js");
82186
+ files.push({ name: "handler.js", content });
82187
+ } catch {
82188
+ formatter.warn(`Could not download handler file for ${brokerName}`);
82189
+ }
82190
+ }
82191
+ }
82192
+ }
82193
+ if (files.length === 0) {
82194
+ formatter.error(`Could not download any files for ${brokerName}`);
82195
+ process.exit(1);
82196
+ return;
82197
+ }
82198
+ if (!fs26.existsSync(brokerDir)) {
82199
+ fs26.mkdirSync(brokerDir, { recursive: true });
82200
+ }
82201
+ for (const file of files) {
82202
+ fs26.writeFileSync(path43.join(brokerDir, file.name), file.content, "utf-8");
82203
+ }
82204
+ const manifestFile = files.find((f) => f.name === "broker.yaml");
82205
+ const manifest = manifestFile ? (0, import_yaml.parse)(manifestFile.content) : {};
82206
+ formatter.print("");
82207
+ formatter.print(` ${sym("success")} ${entry.name}`);
82208
+ formatter.print("");
82209
+ formatter.keyValue(" Name", entry.name);
82210
+ formatter.keyValue(" Provider", entry.provider);
82211
+ formatter.keyValue(" Tier", `${entry.tier} (${TIER_LABELS[entry.tier] ?? "unknown"})`);
82212
+ formatter.keyValue(" Description", entry.description);
82213
+ formatter.print("");
82214
+ formatter.section(" Created");
82215
+ for (const file of files) {
82216
+ formatter.print(` brokers/${entry.name}/${file.name}`);
82217
+ }
82218
+ if (manifest.inputs && manifest.inputs.length > 0) {
82219
+ formatter.section(" Inputs");
82220
+ for (const input of manifest.inputs) {
82221
+ const suffix = input.default !== void 0 ? ` (default: ${input.default})` : " (required)";
82222
+ formatter.print(` ${input.name}${suffix}`);
82223
+ }
82224
+ }
82225
+ if (manifest.output?.keys) {
82226
+ formatter.section(" Output");
82227
+ formatter.keyValue(" Keys", manifest.output.keys.join(", "));
82228
+ if (manifest.output.ttl) {
82229
+ formatter.keyValue(" TTL", `${manifest.output.ttl}s`);
82230
+ }
82231
+ }
82232
+ if (manifest.runtime?.permissions?.length > 0) {
82233
+ formatter.section(" Permissions");
82234
+ for (const perm of manifest.runtime.permissions) {
82235
+ formatter.print(` ${perm}`);
82236
+ }
82237
+ }
82238
+ formatter.print("");
82239
+ formatter.hint(`https://registry.clef.sh/brokers/${entry.name}`);
82240
+ process.exit(0);
82241
+ } catch (err) {
82242
+ formatter.error(err.message);
82243
+ process.exit(1);
82244
+ }
82245
+ });
82246
+ }
82247
+
82248
+ // src/commands/search.ts
82249
+ function registerSearchCommand(program3, _deps) {
82250
+ program3.command("search [query]").description(
82251
+ "Search the Clef broker registry.\n\nWithout arguments, lists all available brokers.\n\nExit codes:\n 0 Results found or listing complete\n 1 Error fetching registry"
82252
+ ).option("--provider <name>", "Filter by cloud provider (aws, gcp, azure, agnostic)").option("--tier <n>", "Filter by tier (1, 2, 3)").option("--registry <url>", "Custom registry base URL", DEFAULT_REGISTRY).action(
82253
+ async (query, options) => {
82254
+ try {
82255
+ const index = await fetchIndex(options.registry);
82256
+ let results = index.brokers;
82257
+ if (query) {
82258
+ const q = query.toLowerCase();
82259
+ results = results.filter(
82260
+ (b) => b.name.toLowerCase().includes(q) || b.description.toLowerCase().includes(q) || b.provider.toLowerCase().includes(q)
82261
+ );
82262
+ }
82263
+ if (options.provider) {
82264
+ results = results.filter((b) => b.provider === options.provider);
82265
+ }
82266
+ if (options.tier) {
82267
+ results = results.filter((b) => b.tier === Number(options.tier));
82268
+ }
82269
+ if (results.length === 0) {
82270
+ formatter.info("No brokers found matching your query.");
82271
+ process.exit(0);
82272
+ return;
82273
+ }
82274
+ const label = query || options.provider || options.tier ? `${results.length} broker${results.length === 1 ? "" : "s"} found` : `${results.length} broker${results.length === 1 ? "" : "s"} available`;
82275
+ formatter.print(`
82276
+ ${label}
82277
+ `);
82278
+ printBrokerTable(results);
82279
+ formatter.print("");
82280
+ process.exit(0);
82281
+ } catch (err) {
82282
+ formatter.error(err.message);
82283
+ process.exit(1);
82284
+ }
82285
+ }
82286
+ );
82287
+ }
82288
+ function printBrokerTable(brokers) {
82289
+ const nameWidth = Math.max(...brokers.map((b) => b.name.length));
82290
+ const providerWidth = Math.max(...brokers.map((b) => b.provider.length));
82291
+ for (const b of brokers) {
82292
+ const name = b.name.padEnd(nameWidth);
82293
+ const provider = b.provider.padEnd(providerWidth);
82294
+ const tier = `Tier ${b.tier}`;
82295
+ formatter.print(` ${name} ${provider} ${tier} ${b.description}`);
82296
+ }
82297
+ }
82298
+
81703
82299
  // src/index.ts
81704
82300
  var VERSION = package_default.version;
81705
82301
  var program2 = new Command();
@@ -81755,6 +82351,8 @@ registerPackCommand(program2, deps);
81755
82351
  registerRevokeCommand(program2, deps);
81756
82352
  registerDriftCommand(program2, deps);
81757
82353
  registerReportCommand(program2, deps);
82354
+ registerInstallCommand(program2, deps);
82355
+ registerSearchCommand(program2, deps);
81758
82356
  program2.parseAsync(process.argv).catch((err) => {
81759
82357
  formatter.error(err.message);
81760
82358
  process.exit(1);