switchroom 0.7.10 → 0.7.13

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.
@@ -1,5 +1,34 @@
1
1
  import { createRequire } from "node:module";
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
2
4
  var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ function __accessProp(key) {
8
+ return this[key];
9
+ }
10
+ var __toESMCache_node;
11
+ var __toESMCache_esm;
12
+ var __toESM = (mod, isNodeMode, target) => {
13
+ var canCache = mod != null && typeof mod === "object";
14
+ if (canCache) {
15
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
16
+ var cached = cache.get(mod);
17
+ if (cached)
18
+ return cached;
19
+ }
20
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
21
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
22
+ for (let key of __getOwnPropNames(mod))
23
+ if (!__hasOwnProp.call(to, key))
24
+ __defProp(to, key, {
25
+ get: __accessProp.bind(mod, key),
26
+ enumerable: true
27
+ });
28
+ if (canCache)
29
+ cache.set(mod, to);
30
+ return to;
31
+ };
3
32
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
4
33
  var __returnValue = (v) => v;
5
34
  function __exportSetter(name, newValue) {
@@ -13,9 +42,1529 @@ var __export = (target, all) => {
13
42
  configurable: true,
14
43
  set: __exportSetter.bind(all, name)
15
44
  });
16
- };
17
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
18
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
45
+ };
46
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
47
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
48
+
49
+ // node_modules/.bun/graceful-fs@4.2.11/node_modules/graceful-fs/polyfills.js
50
+ var require_polyfills = __commonJS((exports, module) => {
51
+ var constants = __require("constants");
52
+ var origCwd = process.cwd;
53
+ var cwd = null;
54
+ var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform;
55
+ process.cwd = function() {
56
+ if (!cwd)
57
+ cwd = origCwd.call(process);
58
+ return cwd;
59
+ };
60
+ try {
61
+ process.cwd();
62
+ } catch (er) {}
63
+ if (typeof process.chdir === "function") {
64
+ chdir = process.chdir;
65
+ process.chdir = function(d) {
66
+ cwd = null;
67
+ chdir.call(process, d);
68
+ };
69
+ if (Object.setPrototypeOf)
70
+ Object.setPrototypeOf(process.chdir, chdir);
71
+ }
72
+ var chdir;
73
+ module.exports = patch;
74
+ function patch(fs) {
75
+ if (constants.hasOwnProperty("O_SYMLINK") && process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) {
76
+ patchLchmod(fs);
77
+ }
78
+ if (!fs.lutimes) {
79
+ patchLutimes(fs);
80
+ }
81
+ fs.chown = chownFix(fs.chown);
82
+ fs.fchown = chownFix(fs.fchown);
83
+ fs.lchown = chownFix(fs.lchown);
84
+ fs.chmod = chmodFix(fs.chmod);
85
+ fs.fchmod = chmodFix(fs.fchmod);
86
+ fs.lchmod = chmodFix(fs.lchmod);
87
+ fs.chownSync = chownFixSync(fs.chownSync);
88
+ fs.fchownSync = chownFixSync(fs.fchownSync);
89
+ fs.lchownSync = chownFixSync(fs.lchownSync);
90
+ fs.chmodSync = chmodFixSync(fs.chmodSync);
91
+ fs.fchmodSync = chmodFixSync(fs.fchmodSync);
92
+ fs.lchmodSync = chmodFixSync(fs.lchmodSync);
93
+ fs.stat = statFix(fs.stat);
94
+ fs.fstat = statFix(fs.fstat);
95
+ fs.lstat = statFix(fs.lstat);
96
+ fs.statSync = statFixSync(fs.statSync);
97
+ fs.fstatSync = statFixSync(fs.fstatSync);
98
+ fs.lstatSync = statFixSync(fs.lstatSync);
99
+ if (fs.chmod && !fs.lchmod) {
100
+ fs.lchmod = function(path, mode, cb) {
101
+ if (cb)
102
+ process.nextTick(cb);
103
+ };
104
+ fs.lchmodSync = function() {};
105
+ }
106
+ if (fs.chown && !fs.lchown) {
107
+ fs.lchown = function(path, uid, gid, cb) {
108
+ if (cb)
109
+ process.nextTick(cb);
110
+ };
111
+ fs.lchownSync = function() {};
112
+ }
113
+ if (platform === "win32") {
114
+ fs.rename = typeof fs.rename !== "function" ? fs.rename : function(fs$rename) {
115
+ function rename(from, to, cb) {
116
+ var start = Date.now();
117
+ var backoff = 0;
118
+ fs$rename(from, to, function CB(er) {
119
+ if (er && (er.code === "EACCES" || er.code === "EPERM" || er.code === "EBUSY") && Date.now() - start < 60000) {
120
+ setTimeout(function() {
121
+ fs.stat(to, function(stater, st) {
122
+ if (stater && stater.code === "ENOENT")
123
+ fs$rename(from, to, CB);
124
+ else
125
+ cb(er);
126
+ });
127
+ }, backoff);
128
+ if (backoff < 100)
129
+ backoff += 10;
130
+ return;
131
+ }
132
+ if (cb)
133
+ cb(er);
134
+ });
135
+ }
136
+ if (Object.setPrototypeOf)
137
+ Object.setPrototypeOf(rename, fs$rename);
138
+ return rename;
139
+ }(fs.rename);
140
+ }
141
+ fs.read = typeof fs.read !== "function" ? fs.read : function(fs$read) {
142
+ function read(fd, buffer, offset, length, position, callback_) {
143
+ var callback;
144
+ if (callback_ && typeof callback_ === "function") {
145
+ var eagCounter = 0;
146
+ callback = function(er, _, __) {
147
+ if (er && er.code === "EAGAIN" && eagCounter < 10) {
148
+ eagCounter++;
149
+ return fs$read.call(fs, fd, buffer, offset, length, position, callback);
150
+ }
151
+ callback_.apply(this, arguments);
152
+ };
153
+ }
154
+ return fs$read.call(fs, fd, buffer, offset, length, position, callback);
155
+ }
156
+ if (Object.setPrototypeOf)
157
+ Object.setPrototypeOf(read, fs$read);
158
+ return read;
159
+ }(fs.read);
160
+ fs.readSync = typeof fs.readSync !== "function" ? fs.readSync : function(fs$readSync) {
161
+ return function(fd, buffer, offset, length, position) {
162
+ var eagCounter = 0;
163
+ while (true) {
164
+ try {
165
+ return fs$readSync.call(fs, fd, buffer, offset, length, position);
166
+ } catch (er) {
167
+ if (er.code === "EAGAIN" && eagCounter < 10) {
168
+ eagCounter++;
169
+ continue;
170
+ }
171
+ throw er;
172
+ }
173
+ }
174
+ };
175
+ }(fs.readSync);
176
+ function patchLchmod(fs2) {
177
+ fs2.lchmod = function(path, mode, callback) {
178
+ fs2.open(path, constants.O_WRONLY | constants.O_SYMLINK, mode, function(err, fd) {
179
+ if (err) {
180
+ if (callback)
181
+ callback(err);
182
+ return;
183
+ }
184
+ fs2.fchmod(fd, mode, function(err2) {
185
+ fs2.close(fd, function(err22) {
186
+ if (callback)
187
+ callback(err2 || err22);
188
+ });
189
+ });
190
+ });
191
+ };
192
+ fs2.lchmodSync = function(path, mode) {
193
+ var fd = fs2.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode);
194
+ var threw = true;
195
+ var ret;
196
+ try {
197
+ ret = fs2.fchmodSync(fd, mode);
198
+ threw = false;
199
+ } finally {
200
+ if (threw) {
201
+ try {
202
+ fs2.closeSync(fd);
203
+ } catch (er) {}
204
+ } else {
205
+ fs2.closeSync(fd);
206
+ }
207
+ }
208
+ return ret;
209
+ };
210
+ }
211
+ function patchLutimes(fs2) {
212
+ if (constants.hasOwnProperty("O_SYMLINK") && fs2.futimes) {
213
+ fs2.lutimes = function(path, at, mt, cb) {
214
+ fs2.open(path, constants.O_SYMLINK, function(er, fd) {
215
+ if (er) {
216
+ if (cb)
217
+ cb(er);
218
+ return;
219
+ }
220
+ fs2.futimes(fd, at, mt, function(er2) {
221
+ fs2.close(fd, function(er22) {
222
+ if (cb)
223
+ cb(er2 || er22);
224
+ });
225
+ });
226
+ });
227
+ };
228
+ fs2.lutimesSync = function(path, at, mt) {
229
+ var fd = fs2.openSync(path, constants.O_SYMLINK);
230
+ var ret;
231
+ var threw = true;
232
+ try {
233
+ ret = fs2.futimesSync(fd, at, mt);
234
+ threw = false;
235
+ } finally {
236
+ if (threw) {
237
+ try {
238
+ fs2.closeSync(fd);
239
+ } catch (er) {}
240
+ } else {
241
+ fs2.closeSync(fd);
242
+ }
243
+ }
244
+ return ret;
245
+ };
246
+ } else if (fs2.futimes) {
247
+ fs2.lutimes = function(_a, _b, _c, cb) {
248
+ if (cb)
249
+ process.nextTick(cb);
250
+ };
251
+ fs2.lutimesSync = function() {};
252
+ }
253
+ }
254
+ function chmodFix(orig) {
255
+ if (!orig)
256
+ return orig;
257
+ return function(target, mode, cb) {
258
+ return orig.call(fs, target, mode, function(er) {
259
+ if (chownErOk(er))
260
+ er = null;
261
+ if (cb)
262
+ cb.apply(this, arguments);
263
+ });
264
+ };
265
+ }
266
+ function chmodFixSync(orig) {
267
+ if (!orig)
268
+ return orig;
269
+ return function(target, mode) {
270
+ try {
271
+ return orig.call(fs, target, mode);
272
+ } catch (er) {
273
+ if (!chownErOk(er))
274
+ throw er;
275
+ }
276
+ };
277
+ }
278
+ function chownFix(orig) {
279
+ if (!orig)
280
+ return orig;
281
+ return function(target, uid, gid, cb) {
282
+ return orig.call(fs, target, uid, gid, function(er) {
283
+ if (chownErOk(er))
284
+ er = null;
285
+ if (cb)
286
+ cb.apply(this, arguments);
287
+ });
288
+ };
289
+ }
290
+ function chownFixSync(orig) {
291
+ if (!orig)
292
+ return orig;
293
+ return function(target, uid, gid) {
294
+ try {
295
+ return orig.call(fs, target, uid, gid);
296
+ } catch (er) {
297
+ if (!chownErOk(er))
298
+ throw er;
299
+ }
300
+ };
301
+ }
302
+ function statFix(orig) {
303
+ if (!orig)
304
+ return orig;
305
+ return function(target, options, cb) {
306
+ if (typeof options === "function") {
307
+ cb = options;
308
+ options = null;
309
+ }
310
+ function callback(er, stats) {
311
+ if (stats) {
312
+ if (stats.uid < 0)
313
+ stats.uid += 4294967296;
314
+ if (stats.gid < 0)
315
+ stats.gid += 4294967296;
316
+ }
317
+ if (cb)
318
+ cb.apply(this, arguments);
319
+ }
320
+ return options ? orig.call(fs, target, options, callback) : orig.call(fs, target, callback);
321
+ };
322
+ }
323
+ function statFixSync(orig) {
324
+ if (!orig)
325
+ return orig;
326
+ return function(target, options) {
327
+ var stats = options ? orig.call(fs, target, options) : orig.call(fs, target);
328
+ if (stats) {
329
+ if (stats.uid < 0)
330
+ stats.uid += 4294967296;
331
+ if (stats.gid < 0)
332
+ stats.gid += 4294967296;
333
+ }
334
+ return stats;
335
+ };
336
+ }
337
+ function chownErOk(er) {
338
+ if (!er)
339
+ return true;
340
+ if (er.code === "ENOSYS")
341
+ return true;
342
+ var nonroot = !process.getuid || process.getuid() !== 0;
343
+ if (nonroot) {
344
+ if (er.code === "EINVAL" || er.code === "EPERM")
345
+ return true;
346
+ }
347
+ return false;
348
+ }
349
+ }
350
+ });
351
+
352
+ // node_modules/.bun/graceful-fs@4.2.11/node_modules/graceful-fs/legacy-streams.js
353
+ var require_legacy_streams = __commonJS((exports, module) => {
354
+ var Stream = __require("stream").Stream;
355
+ module.exports = legacy;
356
+ function legacy(fs) {
357
+ return {
358
+ ReadStream,
359
+ WriteStream
360
+ };
361
+ function ReadStream(path, options) {
362
+ if (!(this instanceof ReadStream))
363
+ return new ReadStream(path, options);
364
+ Stream.call(this);
365
+ var self = this;
366
+ this.path = path;
367
+ this.fd = null;
368
+ this.readable = true;
369
+ this.paused = false;
370
+ this.flags = "r";
371
+ this.mode = 438;
372
+ this.bufferSize = 64 * 1024;
373
+ options = options || {};
374
+ var keys = Object.keys(options);
375
+ for (var index = 0, length = keys.length;index < length; index++) {
376
+ var key = keys[index];
377
+ this[key] = options[key];
378
+ }
379
+ if (this.encoding)
380
+ this.setEncoding(this.encoding);
381
+ if (this.start !== undefined) {
382
+ if (typeof this.start !== "number") {
383
+ throw TypeError("start must be a Number");
384
+ }
385
+ if (this.end === undefined) {
386
+ this.end = Infinity;
387
+ } else if (typeof this.end !== "number") {
388
+ throw TypeError("end must be a Number");
389
+ }
390
+ if (this.start > this.end) {
391
+ throw new Error("start must be <= end");
392
+ }
393
+ this.pos = this.start;
394
+ }
395
+ if (this.fd !== null) {
396
+ process.nextTick(function() {
397
+ self._read();
398
+ });
399
+ return;
400
+ }
401
+ fs.open(this.path, this.flags, this.mode, function(err, fd) {
402
+ if (err) {
403
+ self.emit("error", err);
404
+ self.readable = false;
405
+ return;
406
+ }
407
+ self.fd = fd;
408
+ self.emit("open", fd);
409
+ self._read();
410
+ });
411
+ }
412
+ function WriteStream(path, options) {
413
+ if (!(this instanceof WriteStream))
414
+ return new WriteStream(path, options);
415
+ Stream.call(this);
416
+ this.path = path;
417
+ this.fd = null;
418
+ this.writable = true;
419
+ this.flags = "w";
420
+ this.encoding = "binary";
421
+ this.mode = 438;
422
+ this.bytesWritten = 0;
423
+ options = options || {};
424
+ var keys = Object.keys(options);
425
+ for (var index = 0, length = keys.length;index < length; index++) {
426
+ var key = keys[index];
427
+ this[key] = options[key];
428
+ }
429
+ if (this.start !== undefined) {
430
+ if (typeof this.start !== "number") {
431
+ throw TypeError("start must be a Number");
432
+ }
433
+ if (this.start < 0) {
434
+ throw new Error("start must be >= zero");
435
+ }
436
+ this.pos = this.start;
437
+ }
438
+ this.busy = false;
439
+ this._queue = [];
440
+ if (this.fd === null) {
441
+ this._open = fs.open;
442
+ this._queue.push([this._open, this.path, this.flags, this.mode, undefined]);
443
+ this.flush();
444
+ }
445
+ }
446
+ }
447
+ });
448
+
449
+ // node_modules/.bun/graceful-fs@4.2.11/node_modules/graceful-fs/clone.js
450
+ var require_clone = __commonJS((exports, module) => {
451
+ module.exports = clone;
452
+ var getPrototypeOf = Object.getPrototypeOf || function(obj) {
453
+ return obj.__proto__;
454
+ };
455
+ function clone(obj) {
456
+ if (obj === null || typeof obj !== "object")
457
+ return obj;
458
+ if (obj instanceof Object)
459
+ var copy = { __proto__: getPrototypeOf(obj) };
460
+ else
461
+ var copy = Object.create(null);
462
+ Object.getOwnPropertyNames(obj).forEach(function(key) {
463
+ Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key));
464
+ });
465
+ return copy;
466
+ }
467
+ });
468
+
469
+ // node_modules/.bun/graceful-fs@4.2.11/node_modules/graceful-fs/graceful-fs.js
470
+ var require_graceful_fs = __commonJS((exports, module) => {
471
+ var fs = __require("fs");
472
+ var polyfills = require_polyfills();
473
+ var legacy = require_legacy_streams();
474
+ var clone = require_clone();
475
+ var util = __require("util");
476
+ var gracefulQueue;
477
+ var previousSymbol;
478
+ if (typeof Symbol === "function" && typeof Symbol.for === "function") {
479
+ gracefulQueue = Symbol.for("graceful-fs.queue");
480
+ previousSymbol = Symbol.for("graceful-fs.previous");
481
+ } else {
482
+ gracefulQueue = "___graceful-fs.queue";
483
+ previousSymbol = "___graceful-fs.previous";
484
+ }
485
+ function noop() {}
486
+ function publishQueue(context, queue2) {
487
+ Object.defineProperty(context, gracefulQueue, {
488
+ get: function() {
489
+ return queue2;
490
+ }
491
+ });
492
+ }
493
+ var debug = noop;
494
+ if (util.debuglog)
495
+ debug = util.debuglog("gfs4");
496
+ else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || ""))
497
+ debug = function() {
498
+ var m = util.format.apply(util, arguments);
499
+ m = "GFS4: " + m.split(/\n/).join(`
500
+ GFS4: `);
501
+ console.error(m);
502
+ };
503
+ if (!fs[gracefulQueue]) {
504
+ queue = global[gracefulQueue] || [];
505
+ publishQueue(fs, queue);
506
+ fs.close = function(fs$close) {
507
+ function close(fd, cb) {
508
+ return fs$close.call(fs, fd, function(err) {
509
+ if (!err) {
510
+ resetQueue();
511
+ }
512
+ if (typeof cb === "function")
513
+ cb.apply(this, arguments);
514
+ });
515
+ }
516
+ Object.defineProperty(close, previousSymbol, {
517
+ value: fs$close
518
+ });
519
+ return close;
520
+ }(fs.close);
521
+ fs.closeSync = function(fs$closeSync) {
522
+ function closeSync(fd) {
523
+ fs$closeSync.apply(fs, arguments);
524
+ resetQueue();
525
+ }
526
+ Object.defineProperty(closeSync, previousSymbol, {
527
+ value: fs$closeSync
528
+ });
529
+ return closeSync;
530
+ }(fs.closeSync);
531
+ if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || "")) {
532
+ process.on("exit", function() {
533
+ debug(fs[gracefulQueue]);
534
+ __require("assert").equal(fs[gracefulQueue].length, 0);
535
+ });
536
+ }
537
+ }
538
+ var queue;
539
+ if (!global[gracefulQueue]) {
540
+ publishQueue(global, fs[gracefulQueue]);
541
+ }
542
+ module.exports = patch(clone(fs));
543
+ if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) {
544
+ module.exports = patch(fs);
545
+ fs.__patched = true;
546
+ }
547
+ function patch(fs2) {
548
+ polyfills(fs2);
549
+ fs2.gracefulify = patch;
550
+ fs2.createReadStream = createReadStream;
551
+ fs2.createWriteStream = createWriteStream;
552
+ var fs$readFile = fs2.readFile;
553
+ fs2.readFile = readFile;
554
+ function readFile(path, options, cb) {
555
+ if (typeof options === "function")
556
+ cb = options, options = null;
557
+ return go$readFile(path, options, cb);
558
+ function go$readFile(path2, options2, cb2, startTime) {
559
+ return fs$readFile(path2, options2, function(err) {
560
+ if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
561
+ enqueue([go$readFile, [path2, options2, cb2], err, startTime || Date.now(), Date.now()]);
562
+ else {
563
+ if (typeof cb2 === "function")
564
+ cb2.apply(this, arguments);
565
+ }
566
+ });
567
+ }
568
+ }
569
+ var fs$writeFile = fs2.writeFile;
570
+ fs2.writeFile = writeFile;
571
+ function writeFile(path, data, options, cb) {
572
+ if (typeof options === "function")
573
+ cb = options, options = null;
574
+ return go$writeFile(path, data, options, cb);
575
+ function go$writeFile(path2, data2, options2, cb2, startTime) {
576
+ return fs$writeFile(path2, data2, options2, function(err) {
577
+ if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
578
+ enqueue([go$writeFile, [path2, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
579
+ else {
580
+ if (typeof cb2 === "function")
581
+ cb2.apply(this, arguments);
582
+ }
583
+ });
584
+ }
585
+ }
586
+ var fs$appendFile = fs2.appendFile;
587
+ if (fs$appendFile)
588
+ fs2.appendFile = appendFile;
589
+ function appendFile(path, data, options, cb) {
590
+ if (typeof options === "function")
591
+ cb = options, options = null;
592
+ return go$appendFile(path, data, options, cb);
593
+ function go$appendFile(path2, data2, options2, cb2, startTime) {
594
+ return fs$appendFile(path2, data2, options2, function(err) {
595
+ if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
596
+ enqueue([go$appendFile, [path2, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
597
+ else {
598
+ if (typeof cb2 === "function")
599
+ cb2.apply(this, arguments);
600
+ }
601
+ });
602
+ }
603
+ }
604
+ var fs$copyFile = fs2.copyFile;
605
+ if (fs$copyFile)
606
+ fs2.copyFile = copyFile;
607
+ function copyFile(src, dest, flags, cb) {
608
+ if (typeof flags === "function") {
609
+ cb = flags;
610
+ flags = 0;
611
+ }
612
+ return go$copyFile(src, dest, flags, cb);
613
+ function go$copyFile(src2, dest2, flags2, cb2, startTime) {
614
+ return fs$copyFile(src2, dest2, flags2, function(err) {
615
+ if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
616
+ enqueue([go$copyFile, [src2, dest2, flags2, cb2], err, startTime || Date.now(), Date.now()]);
617
+ else {
618
+ if (typeof cb2 === "function")
619
+ cb2.apply(this, arguments);
620
+ }
621
+ });
622
+ }
623
+ }
624
+ var fs$readdir = fs2.readdir;
625
+ fs2.readdir = readdir;
626
+ var noReaddirOptionVersions = /^v[0-5]\./;
627
+ function readdir(path, options, cb) {
628
+ if (typeof options === "function")
629
+ cb = options, options = null;
630
+ var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir2(path2, options2, cb2, startTime) {
631
+ return fs$readdir(path2, fs$readdirCallback(path2, options2, cb2, startTime));
632
+ } : function go$readdir2(path2, options2, cb2, startTime) {
633
+ return fs$readdir(path2, options2, fs$readdirCallback(path2, options2, cb2, startTime));
634
+ };
635
+ return go$readdir(path, options, cb);
636
+ function fs$readdirCallback(path2, options2, cb2, startTime) {
637
+ return function(err, files) {
638
+ if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
639
+ enqueue([
640
+ go$readdir,
641
+ [path2, options2, cb2],
642
+ err,
643
+ startTime || Date.now(),
644
+ Date.now()
645
+ ]);
646
+ else {
647
+ if (files && files.sort)
648
+ files.sort();
649
+ if (typeof cb2 === "function")
650
+ cb2.call(this, err, files);
651
+ }
652
+ };
653
+ }
654
+ }
655
+ if (process.version.substr(0, 4) === "v0.8") {
656
+ var legStreams = legacy(fs2);
657
+ ReadStream = legStreams.ReadStream;
658
+ WriteStream = legStreams.WriteStream;
659
+ }
660
+ var fs$ReadStream = fs2.ReadStream;
661
+ if (fs$ReadStream) {
662
+ ReadStream.prototype = Object.create(fs$ReadStream.prototype);
663
+ ReadStream.prototype.open = ReadStream$open;
664
+ }
665
+ var fs$WriteStream = fs2.WriteStream;
666
+ if (fs$WriteStream) {
667
+ WriteStream.prototype = Object.create(fs$WriteStream.prototype);
668
+ WriteStream.prototype.open = WriteStream$open;
669
+ }
670
+ Object.defineProperty(fs2, "ReadStream", {
671
+ get: function() {
672
+ return ReadStream;
673
+ },
674
+ set: function(val) {
675
+ ReadStream = val;
676
+ },
677
+ enumerable: true,
678
+ configurable: true
679
+ });
680
+ Object.defineProperty(fs2, "WriteStream", {
681
+ get: function() {
682
+ return WriteStream;
683
+ },
684
+ set: function(val) {
685
+ WriteStream = val;
686
+ },
687
+ enumerable: true,
688
+ configurable: true
689
+ });
690
+ var FileReadStream = ReadStream;
691
+ Object.defineProperty(fs2, "FileReadStream", {
692
+ get: function() {
693
+ return FileReadStream;
694
+ },
695
+ set: function(val) {
696
+ FileReadStream = val;
697
+ },
698
+ enumerable: true,
699
+ configurable: true
700
+ });
701
+ var FileWriteStream = WriteStream;
702
+ Object.defineProperty(fs2, "FileWriteStream", {
703
+ get: function() {
704
+ return FileWriteStream;
705
+ },
706
+ set: function(val) {
707
+ FileWriteStream = val;
708
+ },
709
+ enumerable: true,
710
+ configurable: true
711
+ });
712
+ function ReadStream(path, options) {
713
+ if (this instanceof ReadStream)
714
+ return fs$ReadStream.apply(this, arguments), this;
715
+ else
716
+ return ReadStream.apply(Object.create(ReadStream.prototype), arguments);
717
+ }
718
+ function ReadStream$open() {
719
+ var that = this;
720
+ open(that.path, that.flags, that.mode, function(err, fd) {
721
+ if (err) {
722
+ if (that.autoClose)
723
+ that.destroy();
724
+ that.emit("error", err);
725
+ } else {
726
+ that.fd = fd;
727
+ that.emit("open", fd);
728
+ that.read();
729
+ }
730
+ });
731
+ }
732
+ function WriteStream(path, options) {
733
+ if (this instanceof WriteStream)
734
+ return fs$WriteStream.apply(this, arguments), this;
735
+ else
736
+ return WriteStream.apply(Object.create(WriteStream.prototype), arguments);
737
+ }
738
+ function WriteStream$open() {
739
+ var that = this;
740
+ open(that.path, that.flags, that.mode, function(err, fd) {
741
+ if (err) {
742
+ that.destroy();
743
+ that.emit("error", err);
744
+ } else {
745
+ that.fd = fd;
746
+ that.emit("open", fd);
747
+ }
748
+ });
749
+ }
750
+ function createReadStream(path, options) {
751
+ return new fs2.ReadStream(path, options);
752
+ }
753
+ function createWriteStream(path, options) {
754
+ return new fs2.WriteStream(path, options);
755
+ }
756
+ var fs$open = fs2.open;
757
+ fs2.open = open;
758
+ function open(path, flags, mode, cb) {
759
+ if (typeof mode === "function")
760
+ cb = mode, mode = null;
761
+ return go$open(path, flags, mode, cb);
762
+ function go$open(path2, flags2, mode2, cb2, startTime) {
763
+ return fs$open(path2, flags2, mode2, function(err, fd) {
764
+ if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
765
+ enqueue([go$open, [path2, flags2, mode2, cb2], err, startTime || Date.now(), Date.now()]);
766
+ else {
767
+ if (typeof cb2 === "function")
768
+ cb2.apply(this, arguments);
769
+ }
770
+ });
771
+ }
772
+ }
773
+ return fs2;
774
+ }
775
+ function enqueue(elem) {
776
+ debug("ENQUEUE", elem[0].name, elem[1]);
777
+ fs[gracefulQueue].push(elem);
778
+ retry();
779
+ }
780
+ var retryTimer;
781
+ function resetQueue() {
782
+ var now = Date.now();
783
+ for (var i = 0;i < fs[gracefulQueue].length; ++i) {
784
+ if (fs[gracefulQueue][i].length > 2) {
785
+ fs[gracefulQueue][i][3] = now;
786
+ fs[gracefulQueue][i][4] = now;
787
+ }
788
+ }
789
+ retry();
790
+ }
791
+ function retry() {
792
+ clearTimeout(retryTimer);
793
+ retryTimer = undefined;
794
+ if (fs[gracefulQueue].length === 0)
795
+ return;
796
+ var elem = fs[gracefulQueue].shift();
797
+ var fn = elem[0];
798
+ var args = elem[1];
799
+ var err = elem[2];
800
+ var startTime = elem[3];
801
+ var lastTime = elem[4];
802
+ if (startTime === undefined) {
803
+ debug("RETRY", fn.name, args);
804
+ fn.apply(null, args);
805
+ } else if (Date.now() - startTime >= 60000) {
806
+ debug("TIMEOUT", fn.name, args);
807
+ var cb = args.pop();
808
+ if (typeof cb === "function")
809
+ cb.call(null, err);
810
+ } else {
811
+ var sinceAttempt = Date.now() - lastTime;
812
+ var sinceStart = Math.max(lastTime - startTime, 1);
813
+ var desiredDelay = Math.min(sinceStart * 1.2, 100);
814
+ if (sinceAttempt >= desiredDelay) {
815
+ debug("RETRY", fn.name, args);
816
+ fn.apply(null, args.concat([startTime]));
817
+ } else {
818
+ fs[gracefulQueue].push(elem);
819
+ }
820
+ }
821
+ if (retryTimer === undefined) {
822
+ retryTimer = setTimeout(retry, 0);
823
+ }
824
+ }
825
+ });
826
+
827
+ // node_modules/.bun/retry@0.12.0/node_modules/retry/lib/retry_operation.js
828
+ var require_retry_operation = __commonJS((exports, module) => {
829
+ function RetryOperation(timeouts, options) {
830
+ if (typeof options === "boolean") {
831
+ options = { forever: options };
832
+ }
833
+ this._originalTimeouts = JSON.parse(JSON.stringify(timeouts));
834
+ this._timeouts = timeouts;
835
+ this._options = options || {};
836
+ this._maxRetryTime = options && options.maxRetryTime || Infinity;
837
+ this._fn = null;
838
+ this._errors = [];
839
+ this._attempts = 1;
840
+ this._operationTimeout = null;
841
+ this._operationTimeoutCb = null;
842
+ this._timeout = null;
843
+ this._operationStart = null;
844
+ if (this._options.forever) {
845
+ this._cachedTimeouts = this._timeouts.slice(0);
846
+ }
847
+ }
848
+ module.exports = RetryOperation;
849
+ RetryOperation.prototype.reset = function() {
850
+ this._attempts = 1;
851
+ this._timeouts = this._originalTimeouts;
852
+ };
853
+ RetryOperation.prototype.stop = function() {
854
+ if (this._timeout) {
855
+ clearTimeout(this._timeout);
856
+ }
857
+ this._timeouts = [];
858
+ this._cachedTimeouts = null;
859
+ };
860
+ RetryOperation.prototype.retry = function(err) {
861
+ if (this._timeout) {
862
+ clearTimeout(this._timeout);
863
+ }
864
+ if (!err) {
865
+ return false;
866
+ }
867
+ var currentTime = new Date().getTime();
868
+ if (err && currentTime - this._operationStart >= this._maxRetryTime) {
869
+ this._errors.unshift(new Error("RetryOperation timeout occurred"));
870
+ return false;
871
+ }
872
+ this._errors.push(err);
873
+ var timeout = this._timeouts.shift();
874
+ if (timeout === undefined) {
875
+ if (this._cachedTimeouts) {
876
+ this._errors.splice(this._errors.length - 1, this._errors.length);
877
+ this._timeouts = this._cachedTimeouts.slice(0);
878
+ timeout = this._timeouts.shift();
879
+ } else {
880
+ return false;
881
+ }
882
+ }
883
+ var self = this;
884
+ var timer = setTimeout(function() {
885
+ self._attempts++;
886
+ if (self._operationTimeoutCb) {
887
+ self._timeout = setTimeout(function() {
888
+ self._operationTimeoutCb(self._attempts);
889
+ }, self._operationTimeout);
890
+ if (self._options.unref) {
891
+ self._timeout.unref();
892
+ }
893
+ }
894
+ self._fn(self._attempts);
895
+ }, timeout);
896
+ if (this._options.unref) {
897
+ timer.unref();
898
+ }
899
+ return true;
900
+ };
901
+ RetryOperation.prototype.attempt = function(fn, timeoutOps) {
902
+ this._fn = fn;
903
+ if (timeoutOps) {
904
+ if (timeoutOps.timeout) {
905
+ this._operationTimeout = timeoutOps.timeout;
906
+ }
907
+ if (timeoutOps.cb) {
908
+ this._operationTimeoutCb = timeoutOps.cb;
909
+ }
910
+ }
911
+ var self = this;
912
+ if (this._operationTimeoutCb) {
913
+ this._timeout = setTimeout(function() {
914
+ self._operationTimeoutCb();
915
+ }, self._operationTimeout);
916
+ }
917
+ this._operationStart = new Date().getTime();
918
+ this._fn(this._attempts);
919
+ };
920
+ RetryOperation.prototype.try = function(fn) {
921
+ console.log("Using RetryOperation.try() is deprecated");
922
+ this.attempt(fn);
923
+ };
924
+ RetryOperation.prototype.start = function(fn) {
925
+ console.log("Using RetryOperation.start() is deprecated");
926
+ this.attempt(fn);
927
+ };
928
+ RetryOperation.prototype.start = RetryOperation.prototype.try;
929
+ RetryOperation.prototype.errors = function() {
930
+ return this._errors;
931
+ };
932
+ RetryOperation.prototype.attempts = function() {
933
+ return this._attempts;
934
+ };
935
+ RetryOperation.prototype.mainError = function() {
936
+ if (this._errors.length === 0) {
937
+ return null;
938
+ }
939
+ var counts = {};
940
+ var mainError = null;
941
+ var mainErrorCount = 0;
942
+ for (var i = 0;i < this._errors.length; i++) {
943
+ var error = this._errors[i];
944
+ var message = error.message;
945
+ var count = (counts[message] || 0) + 1;
946
+ counts[message] = count;
947
+ if (count >= mainErrorCount) {
948
+ mainError = error;
949
+ mainErrorCount = count;
950
+ }
951
+ }
952
+ return mainError;
953
+ };
954
+ });
955
+
956
+ // node_modules/.bun/retry@0.12.0/node_modules/retry/lib/retry.js
957
+ var require_retry = __commonJS((exports) => {
958
+ var RetryOperation = require_retry_operation();
959
+ exports.operation = function(options) {
960
+ var timeouts = exports.timeouts(options);
961
+ return new RetryOperation(timeouts, {
962
+ forever: options && options.forever,
963
+ unref: options && options.unref,
964
+ maxRetryTime: options && options.maxRetryTime
965
+ });
966
+ };
967
+ exports.timeouts = function(options) {
968
+ if (options instanceof Array) {
969
+ return [].concat(options);
970
+ }
971
+ var opts = {
972
+ retries: 10,
973
+ factor: 2,
974
+ minTimeout: 1 * 1000,
975
+ maxTimeout: Infinity,
976
+ randomize: false
977
+ };
978
+ for (var key in options) {
979
+ opts[key] = options[key];
980
+ }
981
+ if (opts.minTimeout > opts.maxTimeout) {
982
+ throw new Error("minTimeout is greater than maxTimeout");
983
+ }
984
+ var timeouts = [];
985
+ for (var i = 0;i < opts.retries; i++) {
986
+ timeouts.push(this.createTimeout(i, opts));
987
+ }
988
+ if (options && options.forever && !timeouts.length) {
989
+ timeouts.push(this.createTimeout(i, opts));
990
+ }
991
+ timeouts.sort(function(a, b) {
992
+ return a - b;
993
+ });
994
+ return timeouts;
995
+ };
996
+ exports.createTimeout = function(attempt, opts) {
997
+ var random = opts.randomize ? Math.random() + 1 : 1;
998
+ var timeout = Math.round(random * opts.minTimeout * Math.pow(opts.factor, attempt));
999
+ timeout = Math.min(timeout, opts.maxTimeout);
1000
+ return timeout;
1001
+ };
1002
+ exports.wrap = function(obj, options, methods) {
1003
+ if (options instanceof Array) {
1004
+ methods = options;
1005
+ options = null;
1006
+ }
1007
+ if (!methods) {
1008
+ methods = [];
1009
+ for (var key in obj) {
1010
+ if (typeof obj[key] === "function") {
1011
+ methods.push(key);
1012
+ }
1013
+ }
1014
+ }
1015
+ for (var i = 0;i < methods.length; i++) {
1016
+ var method = methods[i];
1017
+ var original = obj[method];
1018
+ obj[method] = function retryWrapper(original2) {
1019
+ var op = exports.operation(options);
1020
+ var args = Array.prototype.slice.call(arguments, 1);
1021
+ var callback = args.pop();
1022
+ args.push(function(err) {
1023
+ if (op.retry(err)) {
1024
+ return;
1025
+ }
1026
+ if (err) {
1027
+ arguments[0] = op.mainError();
1028
+ }
1029
+ callback.apply(this, arguments);
1030
+ });
1031
+ op.attempt(function() {
1032
+ original2.apply(obj, args);
1033
+ });
1034
+ }.bind(obj, original);
1035
+ obj[method].options = options;
1036
+ }
1037
+ };
1038
+ });
1039
+
1040
+ // node_modules/.bun/signal-exit@3.0.7/node_modules/signal-exit/signals.js
1041
+ var require_signals = __commonJS((exports, module) => {
1042
+ module.exports = [
1043
+ "SIGABRT",
1044
+ "SIGALRM",
1045
+ "SIGHUP",
1046
+ "SIGINT",
1047
+ "SIGTERM"
1048
+ ];
1049
+ if (process.platform !== "win32") {
1050
+ module.exports.push("SIGVTALRM", "SIGXCPU", "SIGXFSZ", "SIGUSR2", "SIGTRAP", "SIGSYS", "SIGQUIT", "SIGIOT");
1051
+ }
1052
+ if (process.platform === "linux") {
1053
+ module.exports.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT", "SIGUNUSED");
1054
+ }
1055
+ });
1056
+
1057
+ // node_modules/.bun/signal-exit@3.0.7/node_modules/signal-exit/index.js
1058
+ var require_signal_exit = __commonJS((exports, module) => {
1059
+ var process2 = global.process;
1060
+ var processOk = function(process3) {
1061
+ return process3 && typeof process3 === "object" && typeof process3.removeListener === "function" && typeof process3.emit === "function" && typeof process3.reallyExit === "function" && typeof process3.listeners === "function" && typeof process3.kill === "function" && typeof process3.pid === "number" && typeof process3.on === "function";
1062
+ };
1063
+ if (!processOk(process2)) {
1064
+ module.exports = function() {
1065
+ return function() {};
1066
+ };
1067
+ } else {
1068
+ assert = __require("assert");
1069
+ signals = require_signals();
1070
+ isWin = /^win/i.test(process2.platform);
1071
+ EE = __require("events");
1072
+ if (typeof EE !== "function") {
1073
+ EE = EE.EventEmitter;
1074
+ }
1075
+ if (process2.__signal_exit_emitter__) {
1076
+ emitter = process2.__signal_exit_emitter__;
1077
+ } else {
1078
+ emitter = process2.__signal_exit_emitter__ = new EE;
1079
+ emitter.count = 0;
1080
+ emitter.emitted = {};
1081
+ }
1082
+ if (!emitter.infinite) {
1083
+ emitter.setMaxListeners(Infinity);
1084
+ emitter.infinite = true;
1085
+ }
1086
+ module.exports = function(cb, opts) {
1087
+ if (!processOk(global.process)) {
1088
+ return function() {};
1089
+ }
1090
+ assert.equal(typeof cb, "function", "a callback must be provided for exit handler");
1091
+ if (loaded === false) {
1092
+ load();
1093
+ }
1094
+ var ev = "exit";
1095
+ if (opts && opts.alwaysLast) {
1096
+ ev = "afterexit";
1097
+ }
1098
+ var remove = function() {
1099
+ emitter.removeListener(ev, cb);
1100
+ if (emitter.listeners("exit").length === 0 && emitter.listeners("afterexit").length === 0) {
1101
+ unload();
1102
+ }
1103
+ };
1104
+ emitter.on(ev, cb);
1105
+ return remove;
1106
+ };
1107
+ unload = function unload2() {
1108
+ if (!loaded || !processOk(global.process)) {
1109
+ return;
1110
+ }
1111
+ loaded = false;
1112
+ signals.forEach(function(sig) {
1113
+ try {
1114
+ process2.removeListener(sig, sigListeners[sig]);
1115
+ } catch (er) {}
1116
+ });
1117
+ process2.emit = originalProcessEmit;
1118
+ process2.reallyExit = originalProcessReallyExit;
1119
+ emitter.count -= 1;
1120
+ };
1121
+ module.exports.unload = unload;
1122
+ emit = function emit2(event, code, signal) {
1123
+ if (emitter.emitted[event]) {
1124
+ return;
1125
+ }
1126
+ emitter.emitted[event] = true;
1127
+ emitter.emit(event, code, signal);
1128
+ };
1129
+ sigListeners = {};
1130
+ signals.forEach(function(sig) {
1131
+ sigListeners[sig] = function listener() {
1132
+ if (!processOk(global.process)) {
1133
+ return;
1134
+ }
1135
+ var listeners = process2.listeners(sig);
1136
+ if (listeners.length === emitter.count) {
1137
+ unload();
1138
+ emit("exit", null, sig);
1139
+ emit("afterexit", null, sig);
1140
+ if (isWin && sig === "SIGHUP") {
1141
+ sig = "SIGINT";
1142
+ }
1143
+ process2.kill(process2.pid, sig);
1144
+ }
1145
+ };
1146
+ });
1147
+ module.exports.signals = function() {
1148
+ return signals;
1149
+ };
1150
+ loaded = false;
1151
+ load = function load2() {
1152
+ if (loaded || !processOk(global.process)) {
1153
+ return;
1154
+ }
1155
+ loaded = true;
1156
+ emitter.count += 1;
1157
+ signals = signals.filter(function(sig) {
1158
+ try {
1159
+ process2.on(sig, sigListeners[sig]);
1160
+ return true;
1161
+ } catch (er) {
1162
+ return false;
1163
+ }
1164
+ });
1165
+ process2.emit = processEmit;
1166
+ process2.reallyExit = processReallyExit;
1167
+ };
1168
+ module.exports.load = load;
1169
+ originalProcessReallyExit = process2.reallyExit;
1170
+ processReallyExit = function processReallyExit2(code) {
1171
+ if (!processOk(global.process)) {
1172
+ return;
1173
+ }
1174
+ process2.exitCode = code || 0;
1175
+ emit("exit", process2.exitCode, null);
1176
+ emit("afterexit", process2.exitCode, null);
1177
+ originalProcessReallyExit.call(process2, process2.exitCode);
1178
+ };
1179
+ originalProcessEmit = process2.emit;
1180
+ processEmit = function processEmit2(ev, arg) {
1181
+ if (ev === "exit" && processOk(global.process)) {
1182
+ if (arg !== undefined) {
1183
+ process2.exitCode = arg;
1184
+ }
1185
+ var ret = originalProcessEmit.apply(this, arguments);
1186
+ emit("exit", process2.exitCode, null);
1187
+ emit("afterexit", process2.exitCode, null);
1188
+ return ret;
1189
+ } else {
1190
+ return originalProcessEmit.apply(this, arguments);
1191
+ }
1192
+ };
1193
+ }
1194
+ var assert;
1195
+ var signals;
1196
+ var isWin;
1197
+ var EE;
1198
+ var emitter;
1199
+ var unload;
1200
+ var emit;
1201
+ var sigListeners;
1202
+ var loaded;
1203
+ var load;
1204
+ var originalProcessReallyExit;
1205
+ var processReallyExit;
1206
+ var originalProcessEmit;
1207
+ var processEmit;
1208
+ });
1209
+
1210
+ // node_modules/.bun/proper-lockfile@4.1.2/node_modules/proper-lockfile/lib/mtime-precision.js
1211
+ var require_mtime_precision = __commonJS((exports, module) => {
1212
+ var cacheSymbol = Symbol();
1213
+ function probe(file, fs, callback) {
1214
+ const cachedPrecision = fs[cacheSymbol];
1215
+ if (cachedPrecision) {
1216
+ return fs.stat(file, (err, stat) => {
1217
+ if (err) {
1218
+ return callback(err);
1219
+ }
1220
+ callback(null, stat.mtime, cachedPrecision);
1221
+ });
1222
+ }
1223
+ const mtime = new Date(Math.ceil(Date.now() / 1000) * 1000 + 5);
1224
+ fs.utimes(file, mtime, mtime, (err) => {
1225
+ if (err) {
1226
+ return callback(err);
1227
+ }
1228
+ fs.stat(file, (err2, stat) => {
1229
+ if (err2) {
1230
+ return callback(err2);
1231
+ }
1232
+ const precision = stat.mtime.getTime() % 1000 === 0 ? "s" : "ms";
1233
+ Object.defineProperty(fs, cacheSymbol, { value: precision });
1234
+ callback(null, stat.mtime, precision);
1235
+ });
1236
+ });
1237
+ }
1238
+ function getMtime(precision) {
1239
+ let now = Date.now();
1240
+ if (precision === "s") {
1241
+ now = Math.ceil(now / 1000) * 1000;
1242
+ }
1243
+ return new Date(now);
1244
+ }
1245
+ exports.probe = probe;
1246
+ exports.getMtime = getMtime;
1247
+ });
1248
+
1249
+ // node_modules/.bun/proper-lockfile@4.1.2/node_modules/proper-lockfile/lib/lockfile.js
1250
+ var require_lockfile = __commonJS((exports, module) => {
1251
+ var path = __require("path");
1252
+ var fs = require_graceful_fs();
1253
+ var retry = require_retry();
1254
+ var onExit = require_signal_exit();
1255
+ var mtimePrecision = require_mtime_precision();
1256
+ var locks = {};
1257
+ function getLockFile(file, options) {
1258
+ return options.lockfilePath || `${file}.lock`;
1259
+ }
1260
+ function resolveCanonicalPath(file, options, callback) {
1261
+ if (!options.realpath) {
1262
+ return callback(null, path.resolve(file));
1263
+ }
1264
+ options.fs.realpath(file, callback);
1265
+ }
1266
+ function acquireLock(file, options, callback) {
1267
+ const lockfilePath = getLockFile(file, options);
1268
+ options.fs.mkdir(lockfilePath, (err) => {
1269
+ if (!err) {
1270
+ return mtimePrecision.probe(lockfilePath, options.fs, (err2, mtime, mtimePrecision2) => {
1271
+ if (err2) {
1272
+ options.fs.rmdir(lockfilePath, () => {});
1273
+ return callback(err2);
1274
+ }
1275
+ callback(null, mtime, mtimePrecision2);
1276
+ });
1277
+ }
1278
+ if (err.code !== "EEXIST") {
1279
+ return callback(err);
1280
+ }
1281
+ if (options.stale <= 0) {
1282
+ return callback(Object.assign(new Error("Lock file is already being held"), { code: "ELOCKED", file }));
1283
+ }
1284
+ options.fs.stat(lockfilePath, (err2, stat) => {
1285
+ if (err2) {
1286
+ if (err2.code === "ENOENT") {
1287
+ return acquireLock(file, { ...options, stale: 0 }, callback);
1288
+ }
1289
+ return callback(err2);
1290
+ }
1291
+ if (!isLockStale(stat, options)) {
1292
+ return callback(Object.assign(new Error("Lock file is already being held"), { code: "ELOCKED", file }));
1293
+ }
1294
+ removeLock(file, options, (err3) => {
1295
+ if (err3) {
1296
+ return callback(err3);
1297
+ }
1298
+ acquireLock(file, { ...options, stale: 0 }, callback);
1299
+ });
1300
+ });
1301
+ });
1302
+ }
1303
+ function isLockStale(stat, options) {
1304
+ return stat.mtime.getTime() < Date.now() - options.stale;
1305
+ }
1306
+ function removeLock(file, options, callback) {
1307
+ options.fs.rmdir(getLockFile(file, options), (err) => {
1308
+ if (err && err.code !== "ENOENT") {
1309
+ return callback(err);
1310
+ }
1311
+ callback();
1312
+ });
1313
+ }
1314
+ function updateLock(file, options) {
1315
+ const lock2 = locks[file];
1316
+ if (lock2.updateTimeout) {
1317
+ return;
1318
+ }
1319
+ lock2.updateDelay = lock2.updateDelay || options.update;
1320
+ lock2.updateTimeout = setTimeout(() => {
1321
+ lock2.updateTimeout = null;
1322
+ options.fs.stat(lock2.lockfilePath, (err, stat) => {
1323
+ const isOverThreshold = lock2.lastUpdate + options.stale < Date.now();
1324
+ if (err) {
1325
+ if (err.code === "ENOENT" || isOverThreshold) {
1326
+ return setLockAsCompromised(file, lock2, Object.assign(err, { code: "ECOMPROMISED" }));
1327
+ }
1328
+ lock2.updateDelay = 1000;
1329
+ return updateLock(file, options);
1330
+ }
1331
+ const isMtimeOurs = lock2.mtime.getTime() === stat.mtime.getTime();
1332
+ if (!isMtimeOurs) {
1333
+ return setLockAsCompromised(file, lock2, Object.assign(new Error("Unable to update lock within the stale threshold"), { code: "ECOMPROMISED" }));
1334
+ }
1335
+ const mtime = mtimePrecision.getMtime(lock2.mtimePrecision);
1336
+ options.fs.utimes(lock2.lockfilePath, mtime, mtime, (err2) => {
1337
+ const isOverThreshold2 = lock2.lastUpdate + options.stale < Date.now();
1338
+ if (lock2.released) {
1339
+ return;
1340
+ }
1341
+ if (err2) {
1342
+ if (err2.code === "ENOENT" || isOverThreshold2) {
1343
+ return setLockAsCompromised(file, lock2, Object.assign(err2, { code: "ECOMPROMISED" }));
1344
+ }
1345
+ lock2.updateDelay = 1000;
1346
+ return updateLock(file, options);
1347
+ }
1348
+ lock2.mtime = mtime;
1349
+ lock2.lastUpdate = Date.now();
1350
+ lock2.updateDelay = null;
1351
+ updateLock(file, options);
1352
+ });
1353
+ });
1354
+ }, lock2.updateDelay);
1355
+ if (lock2.updateTimeout.unref) {
1356
+ lock2.updateTimeout.unref();
1357
+ }
1358
+ }
1359
+ function setLockAsCompromised(file, lock2, err) {
1360
+ lock2.released = true;
1361
+ if (lock2.updateTimeout) {
1362
+ clearTimeout(lock2.updateTimeout);
1363
+ }
1364
+ if (locks[file] === lock2) {
1365
+ delete locks[file];
1366
+ }
1367
+ lock2.options.onCompromised(err);
1368
+ }
1369
+ function lock(file, options, callback) {
1370
+ options = {
1371
+ stale: 1e4,
1372
+ update: null,
1373
+ realpath: true,
1374
+ retries: 0,
1375
+ fs,
1376
+ onCompromised: (err) => {
1377
+ throw err;
1378
+ },
1379
+ ...options
1380
+ };
1381
+ options.retries = options.retries || 0;
1382
+ options.retries = typeof options.retries === "number" ? { retries: options.retries } : options.retries;
1383
+ options.stale = Math.max(options.stale || 0, 2000);
1384
+ options.update = options.update == null ? options.stale / 2 : options.update || 0;
1385
+ options.update = Math.max(Math.min(options.update, options.stale / 2), 1000);
1386
+ resolveCanonicalPath(file, options, (err, file2) => {
1387
+ if (err) {
1388
+ return callback(err);
1389
+ }
1390
+ const operation = retry.operation(options.retries);
1391
+ operation.attempt(() => {
1392
+ acquireLock(file2, options, (err2, mtime, mtimePrecision2) => {
1393
+ if (operation.retry(err2)) {
1394
+ return;
1395
+ }
1396
+ if (err2) {
1397
+ return callback(operation.mainError());
1398
+ }
1399
+ const lock2 = locks[file2] = {
1400
+ lockfilePath: getLockFile(file2, options),
1401
+ mtime,
1402
+ mtimePrecision: mtimePrecision2,
1403
+ options,
1404
+ lastUpdate: Date.now()
1405
+ };
1406
+ updateLock(file2, options);
1407
+ callback(null, (releasedCallback) => {
1408
+ if (lock2.released) {
1409
+ return releasedCallback && releasedCallback(Object.assign(new Error("Lock is already released"), { code: "ERELEASED" }));
1410
+ }
1411
+ unlock(file2, { ...options, realpath: false }, releasedCallback);
1412
+ });
1413
+ });
1414
+ });
1415
+ });
1416
+ }
1417
+ function unlock(file, options, callback) {
1418
+ options = {
1419
+ fs,
1420
+ realpath: true,
1421
+ ...options
1422
+ };
1423
+ resolveCanonicalPath(file, options, (err, file2) => {
1424
+ if (err) {
1425
+ return callback(err);
1426
+ }
1427
+ const lock2 = locks[file2];
1428
+ if (!lock2) {
1429
+ return callback(Object.assign(new Error("Lock is not acquired/owned by you"), { code: "ENOTACQUIRED" }));
1430
+ }
1431
+ lock2.updateTimeout && clearTimeout(lock2.updateTimeout);
1432
+ lock2.released = true;
1433
+ delete locks[file2];
1434
+ removeLock(file2, options, callback);
1435
+ });
1436
+ }
1437
+ function check(file, options, callback) {
1438
+ options = {
1439
+ stale: 1e4,
1440
+ realpath: true,
1441
+ fs,
1442
+ ...options
1443
+ };
1444
+ options.stale = Math.max(options.stale || 0, 2000);
1445
+ resolveCanonicalPath(file, options, (err, file2) => {
1446
+ if (err) {
1447
+ return callback(err);
1448
+ }
1449
+ options.fs.stat(getLockFile(file2, options), (err2, stat) => {
1450
+ if (err2) {
1451
+ return err2.code === "ENOENT" ? callback(null, false) : callback(err2);
1452
+ }
1453
+ return callback(null, !isLockStale(stat, options));
1454
+ });
1455
+ });
1456
+ }
1457
+ function getLocks() {
1458
+ return locks;
1459
+ }
1460
+ onExit(() => {
1461
+ for (const file in locks) {
1462
+ const options = locks[file].options;
1463
+ try {
1464
+ options.fs.rmdirSync(getLockFile(file, options));
1465
+ } catch (e) {}
1466
+ }
1467
+ });
1468
+ exports.lock = lock;
1469
+ exports.unlock = unlock;
1470
+ exports.check = check;
1471
+ exports.getLocks = getLocks;
1472
+ });
1473
+
1474
+ // node_modules/.bun/proper-lockfile@4.1.2/node_modules/proper-lockfile/lib/adapter.js
1475
+ var require_adapter = __commonJS((exports, module) => {
1476
+ var fs = require_graceful_fs();
1477
+ function createSyncFs(fs2) {
1478
+ const methods = ["mkdir", "realpath", "stat", "rmdir", "utimes"];
1479
+ const newFs = { ...fs2 };
1480
+ methods.forEach((method) => {
1481
+ newFs[method] = (...args) => {
1482
+ const callback = args.pop();
1483
+ let ret;
1484
+ try {
1485
+ ret = fs2[`${method}Sync`](...args);
1486
+ } catch (err) {
1487
+ return callback(err);
1488
+ }
1489
+ callback(null, ret);
1490
+ };
1491
+ });
1492
+ return newFs;
1493
+ }
1494
+ function toPromise(method) {
1495
+ return (...args) => new Promise((resolve, reject) => {
1496
+ args.push((err, result) => {
1497
+ if (err) {
1498
+ reject(err);
1499
+ } else {
1500
+ resolve(result);
1501
+ }
1502
+ });
1503
+ method(...args);
1504
+ });
1505
+ }
1506
+ function toSync(method) {
1507
+ return (...args) => {
1508
+ let err;
1509
+ let result;
1510
+ args.push((_err, _result) => {
1511
+ err = _err;
1512
+ result = _result;
1513
+ });
1514
+ method(...args);
1515
+ if (err) {
1516
+ throw err;
1517
+ }
1518
+ return result;
1519
+ };
1520
+ }
1521
+ function toSyncOptions(options) {
1522
+ options = { ...options };
1523
+ options.fs = createSyncFs(options.fs || fs);
1524
+ if (typeof options.retries === "number" && options.retries > 0 || options.retries && typeof options.retries.retries === "number" && options.retries.retries > 0) {
1525
+ throw Object.assign(new Error("Cannot use retries with the sync api"), { code: "ESYNC" });
1526
+ }
1527
+ return options;
1528
+ }
1529
+ module.exports = {
1530
+ toPromise,
1531
+ toSync,
1532
+ toSyncOptions
1533
+ };
1534
+ });
1535
+
1536
+ // node_modules/.bun/proper-lockfile@4.1.2/node_modules/proper-lockfile/index.js
1537
+ var require_proper_lockfile = __commonJS((exports, module) => {
1538
+ var lockfile = require_lockfile();
1539
+ var { toPromise, toSync, toSyncOptions } = require_adapter();
1540
+ async function lock(file, options) {
1541
+ const release = await toPromise(lockfile.lock)(file, options);
1542
+ return toPromise(release);
1543
+ }
1544
+ function lockSync(file, options) {
1545
+ const release = toSync(lockfile.lock)(file, toSyncOptions(options));
1546
+ return toSync(release);
1547
+ }
1548
+ function unlock(file, options) {
1549
+ return toPromise(lockfile.unlock)(file, options);
1550
+ }
1551
+ function unlockSync(file, options) {
1552
+ return toSync(lockfile.unlock)(file, toSyncOptions(options));
1553
+ }
1554
+ function check(file, options) {
1555
+ return toPromise(lockfile.check)(file, options);
1556
+ }
1557
+ function checkSync(file, options) {
1558
+ return toSync(lockfile.check)(file, toSyncOptions(options));
1559
+ }
1560
+ module.exports = lock;
1561
+ module.exports.lock = lock;
1562
+ module.exports.unlock = unlock;
1563
+ module.exports.lockSync = lockSync;
1564
+ module.exports.unlockSync = unlockSync;
1565
+ module.exports.check = check;
1566
+ module.exports.checkSync = checkSync;
1567
+ });
19
1568
 
20
1569
  // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/identity.js
21
1570
  var require_identity = __commonJS((exports) => {
@@ -11224,7 +12773,7 @@ var init_schema = __esm(() => {
11224
12773
  }).optional()
11225
12774
  });
11226
12775
  VaultConfigSchema = exports_external.object({
11227
- path: exports_external.string().default("~/.switchroom/vault.enc").describe("Path to encrypted vault file"),
12776
+ path: exports_external.string().default("~/.switchroom/vault/vault.enc").describe("Path to encrypted vault file. v0.7.12+ canonical default is " + "`~/.switchroom/vault/vault.enc` (parent-dir bind-mount enables " + "atomic-rename writes from the broker container). Older installs " + "with `~/.switchroom/vault.enc` are auto-migrated on `switchroom " + "apply`; the legacy path becomes a symlink for v0.7.10/.11 CLI " + "compatibility (sunset in v0.7.14)."),
11228
12777
  broker: exports_external.object({
11229
12778
  socket: exports_external.string().default("~/.switchroom/vault-broker.sock").describe("Unix domain socket path for the vault-broker daemon"),
11230
12779
  enabled: exports_external.boolean().default(true).describe("Whether to start the vault-broker daemon on agent launch"),
@@ -11257,8 +12806,8 @@ var init_schema = __esm(() => {
11257
12806
  });
11258
12807
 
11259
12808
  // src/config/paths.ts
11260
- import { existsSync as existsSync2 } from "node:fs";
11261
- import { resolve } from "node:path";
12809
+ import { existsSync as existsSync3 } from "node:fs";
12810
+ import { resolve as resolve2 } from "node:path";
11262
12811
  function home() {
11263
12812
  return process.env.HOME ?? "/root";
11264
12813
  }
@@ -11266,18 +12815,18 @@ function resolveDualPath(pathStr) {
11266
12815
  const h = home();
11267
12816
  if (pathStr.startsWith("~/")) {
11268
12817
  const rest = pathStr.slice(2);
11269
- const absolute = resolve(h, rest);
12818
+ const absolute = resolve2(h, rest);
11270
12819
  if (rest.startsWith(`${DEFAULT_STATE_DIR}/`)) {
11271
12820
  const frag = rest.slice(DEFAULT_STATE_DIR.length + 1);
11272
- if (!existsSync2(absolute)) {
11273
- const legacy = resolve(h, LEGACY_STATE_DIR, frag);
11274
- if (existsSync2(legacy))
12821
+ if (!existsSync3(absolute)) {
12822
+ const legacy = resolve2(h, LEGACY_STATE_DIR, frag);
12823
+ if (existsSync3(legacy))
11275
12824
  return legacy;
11276
12825
  }
11277
12826
  }
11278
12827
  return absolute;
11279
12828
  }
11280
- return resolve(pathStr);
12829
+ return resolve2(pathStr);
11281
12830
  }
11282
12831
  var DEFAULT_STATE_DIR = ".switchroom", LEGACY_STATE_DIR = ".clerk";
11283
12832
  var init_paths = () => {};
@@ -11291,9 +12840,9 @@ __export(exports_loader, {
11291
12840
  findConfigFile: () => findConfigFile,
11292
12841
  ConfigError: () => ConfigError
11293
12842
  });
11294
- import { readFileSync as readFileSync2, existsSync as existsSync3 } from "node:fs";
12843
+ import { readFileSync as readFileSync3, existsSync as existsSync4 } from "node:fs";
11295
12844
  import { homedir } from "node:os";
11296
- import { resolve as resolve2 } from "node:path";
12845
+ import { resolve as resolve3 } from "node:path";
11297
12846
  function formatZodErrors(error) {
11298
12847
  return error.errors.map((e) => {
11299
12848
  const path = e.path.join(".");
@@ -11303,24 +12852,24 @@ function formatZodErrors(error) {
11303
12852
  function findConfigFile(startDir) {
11304
12853
  const envPath = process.env.SWITCHROOM_CONFIG;
11305
12854
  const home2 = homedir();
11306
- const userDir = resolve2(home2, ".switchroom");
12855
+ const userDir = resolve3(home2, ".switchroom");
11307
12856
  const searchPaths = [
11308
- envPath ? resolve2(envPath) : null,
11309
- startDir ? resolve2(startDir, "switchroom.yaml") : null,
11310
- startDir ? resolve2(startDir, "switchroom.yml") : null,
11311
- startDir ? resolve2(startDir, "clerk.yaml") : null,
11312
- startDir ? resolve2(startDir, "clerk.yml") : null,
11313
- resolve2(process.cwd(), "switchroom.yaml"),
11314
- resolve2(process.cwd(), "switchroom.yml"),
11315
- resolve2(process.cwd(), "clerk.yaml"),
11316
- resolve2(process.cwd(), "clerk.yml"),
11317
- resolve2(userDir, "switchroom.yaml"),
11318
- resolve2(userDir, "switchroom.yml"),
11319
- resolve2(userDir, "clerk.yaml"),
11320
- resolve2(userDir, "clerk.yml")
12857
+ envPath ? resolve3(envPath) : null,
12858
+ startDir ? resolve3(startDir, "switchroom.yaml") : null,
12859
+ startDir ? resolve3(startDir, "switchroom.yml") : null,
12860
+ startDir ? resolve3(startDir, "clerk.yaml") : null,
12861
+ startDir ? resolve3(startDir, "clerk.yml") : null,
12862
+ resolve3(process.cwd(), "switchroom.yaml"),
12863
+ resolve3(process.cwd(), "switchroom.yml"),
12864
+ resolve3(process.cwd(), "clerk.yaml"),
12865
+ resolve3(process.cwd(), "clerk.yml"),
12866
+ resolve3(userDir, "switchroom.yaml"),
12867
+ resolve3(userDir, "switchroom.yml"),
12868
+ resolve3(userDir, "clerk.yaml"),
12869
+ resolve3(userDir, "clerk.yml")
11321
12870
  ].filter(Boolean);
11322
12871
  for (const path of searchPaths) {
11323
- if (existsSync3(path)) {
12872
+ if (existsSync4(path)) {
11324
12873
  return path;
11325
12874
  }
11326
12875
  }
@@ -11328,12 +12877,12 @@ function findConfigFile(startDir) {
11328
12877
  }
11329
12878
  function loadConfig(configPath) {
11330
12879
  const filePath = configPath ?? findConfigFile();
11331
- if (!existsSync3(filePath)) {
12880
+ if (!existsSync4(filePath)) {
11332
12881
  throw new ConfigError(`Config file not found: ${filePath}`);
11333
12882
  }
11334
12883
  let raw;
11335
12884
  try {
11336
- raw = readFileSync2(filePath, "utf-8");
12885
+ raw = readFileSync3(filePath, "utf-8");
11337
12886
  } catch (err) {
11338
12887
  throw new ConfigError(`Failed to read config file: ${filePath}`, [
11339
12888
  ` ${err.message}`
@@ -11385,7 +12934,7 @@ var init_loader = __esm(() => {
11385
12934
 
11386
12935
  // src/vault/broker/server.ts
11387
12936
  import * as net from "node:net";
11388
- import { mkdirSync as mkdirSync4, chmodSync as chmodSync3, chownSync, existsSync as existsSync5, readFileSync as readFileSync5, readdirSync, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3, renameSync as renameSync2 } from "node:fs";
12937
+ import { mkdirSync as mkdirSync5, chmodSync as chmodSync4, chownSync, existsSync as existsSync6, readFileSync as readFileSync6, readdirSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync3, renameSync as renameSync3 } from "node:fs";
11389
12938
 
11390
12939
  // src/agents/compose.ts
11391
12940
  import { createHash } from "node:crypto";
@@ -11676,11 +13225,12 @@ function allocateAgentUid(name) {
11676
13225
  }
11677
13226
 
11678
13227
  // src/vault/broker/server.ts
11679
- import { dirname as dirname2, resolve as resolve3 } from "node:path";
13228
+ import { dirname as dirname4, resolve as resolve4, basename as basename3 } from "node:path";
11680
13229
  import * as os3 from "node:os";
11681
13230
  import * as path3 from "node:path";
11682
13231
 
11683
13232
  // src/vault/vault.ts
13233
+ var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
11684
13234
  import { randomBytes, scryptSync, createCipheriv, createDecipheriv } from "node:crypto";
11685
13235
  import {
11686
13236
  readFileSync,
@@ -11690,10 +13240,34 @@ import {
11690
13240
  mkdirSync,
11691
13241
  unlinkSync
11692
13242
  } from "node:fs";
13243
+ import { dirname, basename, resolve } from "node:path";
13244
+ var KNOWN_VAULT_ARTIFACT_NAMES = new Set([
13245
+ "vault.enc",
13246
+ "vault.enc.bak",
13247
+ "vault.enc.tmp",
13248
+ "vault.enc.lock",
13249
+ ".vault.enc.symlink-tmp"
13250
+ ]);
13251
+ var SAVE_VAULT_LOCK_RETRY_MS = 5000;
11693
13252
  var SCRYPT_N = 32768;
11694
13253
  var SCRYPT_R = 8;
11695
13254
  var SCRYPT_P = 1;
11696
13255
  var SCRYPT_MAXMEM = 128 * 1024 * 1024;
13256
+ function atomicWriteFileSync(path, data, mode) {
13257
+ const dir = dirname(resolve(path));
13258
+ const tmp = resolve(dir, `.${basename(path)}.${process.pid}.${Date.now()}.tmp`);
13259
+ try {
13260
+ writeFileSync(tmp, data, { encoding: "utf8", mode });
13261
+ renameSync(tmp, path);
13262
+ } catch (err) {
13263
+ try {
13264
+ if (existsSync(tmp))
13265
+ unlinkSync(tmp);
13266
+ } catch {}
13267
+ throw err;
13268
+ }
13269
+ }
13270
+
11697
13271
  class VaultError extends Error {
11698
13272
  constructor(message) {
11699
13273
  super(message);
@@ -11709,6 +13283,17 @@ function deriveKey(passphrase, salt, params = { N: SCRYPT_N, r: SCRYPT_R, p: SCR
11709
13283
  maxmem: SCRYPT_MAXMEM
11710
13284
  });
11711
13285
  }
13286
+ function encrypt(key, plaintext) {
13287
+ const iv = randomBytes(12);
13288
+ const cipher = createCipheriv("aes-256-gcm", key, iv);
13289
+ const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
13290
+ const tag = cipher.getAuthTag();
13291
+ return {
13292
+ iv: iv.toString("hex"),
13293
+ data: encrypted.toString("hex"),
13294
+ tag: tag.toString("hex")
13295
+ };
13296
+ }
11712
13297
  function decrypt(key, iv, data, tag) {
11713
13298
  const decipher = createDecipheriv("aes-256-gcm", key, Buffer.from(iv, "hex"));
11714
13299
  decipher.setAuthTag(Buffer.from(tag, "hex"));
@@ -11758,13 +13343,212 @@ function openVault(passphrase, vaultPath) {
11758
13343
  }
11759
13344
  return normalizeSecrets(vaultData.secrets ?? {});
11760
13345
  }
13346
+ function saveVault(passphrase, vaultPath, secrets) {
13347
+ if (!existsSync(vaultPath)) {
13348
+ throw new VaultError(`Vault file not found: ${vaultPath}`);
13349
+ }
13350
+ let releaseLock = null;
13351
+ const lockStart = Date.now();
13352
+ let lastErr = null;
13353
+ const sleepBuf = new Int32Array(new SharedArrayBuffer(4));
13354
+ while (Date.now() - lockStart < SAVE_VAULT_LOCK_RETRY_MS) {
13355
+ try {
13356
+ releaseLock = import_proper_lockfile.default.lockSync(vaultPath, {
13357
+ stale: SAVE_VAULT_LOCK_RETRY_MS * 2,
13358
+ realpath: true
13359
+ });
13360
+ lastErr = null;
13361
+ break;
13362
+ } catch (err) {
13363
+ lastErr = err;
13364
+ const code = err?.code ?? "";
13365
+ if (code !== "ELOCKED")
13366
+ throw err;
13367
+ Atomics.wait(sleepBuf, 0, 0, 100);
13368
+ }
13369
+ }
13370
+ if (releaseLock === null) {
13371
+ if (lastErr) {
13372
+ throw new VaultError(`vault busy: another writer holds the lock at ${vaultPath} ` + `(retried for ${SAVE_VAULT_LOCK_RETRY_MS}ms). Try again in a moment.`);
13373
+ }
13374
+ }
13375
+ try {
13376
+ let vaultFile;
13377
+ try {
13378
+ vaultFile = JSON.parse(readFileSync(vaultPath, "utf8"));
13379
+ } catch {
13380
+ throw new VaultError(`Failed to read vault file: ${vaultPath}`);
13381
+ }
13382
+ const salt = Buffer.from(vaultFile.salt, "hex");
13383
+ const key = deriveKey(passphrase, salt, { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P });
13384
+ vaultFile.kdf = { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P };
13385
+ const vaultData = { secrets };
13386
+ const { iv, data, tag } = encrypt(key, JSON.stringify(vaultData));
13387
+ vaultFile.iv = iv;
13388
+ vaultFile.data = data;
13389
+ vaultFile.tag = tag;
13390
+ atomicWriteFileSync(vaultPath, JSON.stringify(vaultFile, null, 2), 384);
13391
+ } finally {
13392
+ try {
13393
+ releaseLock();
13394
+ } catch {}
13395
+ }
13396
+ }
13397
+ function acquireVaultLock(vaultPath) {
13398
+ const start = Date.now();
13399
+ const sleepBuf = new Int32Array(new SharedArrayBuffer(4));
13400
+ while (Date.now() - start < SAVE_VAULT_LOCK_RETRY_MS) {
13401
+ try {
13402
+ return import_proper_lockfile.default.lockSync(vaultPath, {
13403
+ stale: SAVE_VAULT_LOCK_RETRY_MS * 2,
13404
+ realpath: true
13405
+ });
13406
+ } catch (err) {
13407
+ const code = err?.code ?? "";
13408
+ if (code !== "ELOCKED")
13409
+ throw err;
13410
+ Atomics.wait(sleepBuf, 0, 0, 100);
13411
+ }
13412
+ }
13413
+ throw new VaultError(`vault busy: another writer holds the lock at ${vaultPath} ` + `(retried for ${SAVE_VAULT_LOCK_RETRY_MS}ms).`);
13414
+ }
13415
+
13416
+ // src/vault/migrate-layout.ts
13417
+ import {
13418
+ copyFileSync,
13419
+ chmodSync,
13420
+ existsSync as existsSync2,
13421
+ fsyncSync as fsyncSync2,
13422
+ lstatSync,
13423
+ mkdirSync as mkdirSync2,
13424
+ openSync as openSync2,
13425
+ closeSync as closeSync2,
13426
+ readFileSync as readFileSync2,
13427
+ renameSync as renameSync2,
13428
+ statSync,
13429
+ symlinkSync,
13430
+ unlinkSync as unlinkSync2
13431
+ } from "node:fs";
13432
+ import { createHash as createHash2 } from "node:crypto";
13433
+ import { basename as basename2, dirname as dirname2, join } from "node:path";
13434
+ function vaultLayoutPaths(home) {
13435
+ const switchroomRoot = join(home, ".switchroom");
13436
+ return {
13437
+ oldPath: join(switchroomRoot, "vault.enc"),
13438
+ newPath: join(switchroomRoot, "vault", "vault.enc"),
13439
+ parent: join(switchroomRoot, "vault"),
13440
+ switchroomRoot
13441
+ };
13442
+ }
13443
+ function inspectVaultLayout(home) {
13444
+ return runMigration(home, { dryRun: true });
13445
+ }
13446
+ function runMigration(home, opts) {
13447
+ const { oldPath, newPath, parent, switchroomRoot } = vaultLayoutPaths(home);
13448
+ const lockTarget = existsSync2(newPath) ? newPath : existsSync2(oldPath) ? oldPath : null;
13449
+ const release = !opts.dryRun && lockTarget !== null ? acquireVaultLock(lockTarget) : null;
13450
+ try {
13451
+ const oldStat = lstatSyncOrNull(oldPath);
13452
+ const newExists = existsSync2(newPath);
13453
+ if (oldStat === null && !newExists) {
13454
+ return { kind: "no-vault" };
13455
+ }
13456
+ if (oldStat?.isSymbolicLink() && newExists) {
13457
+ return { kind: "already-migrated" };
13458
+ }
13459
+ if (oldStat?.isFile() && newExists) {
13460
+ const oldHash = sha256File(oldPath);
13461
+ const newHash = sha256File(newPath);
13462
+ if (oldHash === newHash) {
13463
+ if (opts.dryRun)
13464
+ return { kind: "completed-partial" };
13465
+ atomicReplaceWithSymlink(oldPath, "vault/vault.enc");
13466
+ fsyncDir(switchroomRoot);
13467
+ return { kind: "completed-partial" };
13468
+ }
13469
+ const oldRealStat = statSync(oldPath);
13470
+ const newRealStat = statSync(newPath);
13471
+ return {
13472
+ kind: "divergent",
13473
+ details: {
13474
+ oldPath,
13475
+ newPath,
13476
+ oldHash,
13477
+ newHash,
13478
+ oldSize: oldRealStat.size,
13479
+ newSize: newRealStat.size,
13480
+ oldMtime: oldRealStat.mtime.toISOString(),
13481
+ newMtime: newRealStat.mtime.toISOString()
13482
+ }
13483
+ };
13484
+ }
13485
+ if (oldStat?.isFile() && !newExists) {
13486
+ if (opts.dryRun)
13487
+ return { kind: "migrated" };
13488
+ mkdirSync2(parent, { recursive: true, mode: 448 });
13489
+ const tempNew = `${newPath}.tmp`;
13490
+ copyFileSync(oldPath, tempNew);
13491
+ chmodSync(tempNew, 384);
13492
+ fsyncFile(tempNew);
13493
+ renameSync2(tempNew, newPath);
13494
+ fsyncDir(parent);
13495
+ atomicReplaceWithSymlink(oldPath, "vault/vault.enc");
13496
+ fsyncDir(switchroomRoot);
13497
+ return { kind: "migrated" };
13498
+ }
13499
+ return { kind: "no-vault" };
13500
+ } finally {
13501
+ if (release !== null) {
13502
+ try {
13503
+ release();
13504
+ } catch {}
13505
+ }
13506
+ }
13507
+ }
13508
+ function lstatSyncOrNull(path) {
13509
+ try {
13510
+ return lstatSync(path);
13511
+ } catch {
13512
+ return null;
13513
+ }
13514
+ }
13515
+ function sha256File(path) {
13516
+ const data = readFileSync2(path);
13517
+ return createHash2("sha256").update(data).digest("hex");
13518
+ }
13519
+ function atomicReplaceWithSymlink(target, linkTarget) {
13520
+ const tmp = join(dirname2(target), `.${basename2(target)}.symlink-tmp`);
13521
+ if (existsSync2(tmp)) {
13522
+ try {
13523
+ unlinkSync2(tmp);
13524
+ } catch {}
13525
+ }
13526
+ symlinkSync(linkTarget, tmp);
13527
+ renameSync2(tmp, target);
13528
+ }
13529
+ function fsyncFile(path) {
13530
+ const fd = openSync2(path, "r+");
13531
+ try {
13532
+ fsyncSync2(fd);
13533
+ } finally {
13534
+ closeSync2(fd);
13535
+ }
13536
+ }
13537
+ function fsyncDir(path) {
13538
+ const fd = openSync2(path, "r");
13539
+ try {
13540
+ fsyncSync2(fd);
13541
+ } finally {
13542
+ closeSync2(fd);
13543
+ }
13544
+ }
11761
13545
 
11762
13546
  // src/vault/broker/server.ts
11763
13547
  init_loader();
11764
13548
 
11765
13549
  // src/vault/auto-unlock.ts
11766
13550
  import { createHmac, randomBytes as randomBytes2, createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2 } from "node:crypto";
11767
- import { chmodSync, existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
13551
+ import { chmodSync as chmodSync2, existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
11768
13552
  var FORMAT_VERSION = 1;
11769
13553
  var SALT_LEN = 16;
11770
13554
  var NONCE_LEN = 12;
@@ -11792,7 +13576,7 @@ class AutoUnlockDecryptError extends Error {
11792
13576
  function readMachineId() {
11793
13577
  for (const path of [MACHINE_ID_PRIMARY, MACHINE_ID_FALLBACK]) {
11794
13578
  try {
11795
- const id = readFileSync3(path, "utf8").trim();
13579
+ const id = readFileSync4(path, "utf8").trim();
11796
13580
  if (id.length > 0)
11797
13581
  return id;
11798
13582
  } catch {}
@@ -11829,12 +13613,12 @@ function decryptAutoUnlock(blob, machineId) {
11829
13613
  }
11830
13614
  }
11831
13615
  function readAutoUnlockFile(filePath) {
11832
- if (!existsSync4(filePath)) {
13616
+ if (!existsSync5(filePath)) {
11833
13617
  throw new AutoUnlockDecryptError("io");
11834
13618
  }
11835
13619
  let blob;
11836
13620
  try {
11837
- blob = readFileSync3(filePath);
13621
+ blob = readFileSync4(filePath);
11838
13622
  } catch {
11839
13623
  throw new AutoUnlockDecryptError("io");
11840
13624
  }
@@ -11844,7 +13628,7 @@ var DEFAULT_AUTO_UNLOCK_PATH = "~/.switchroom/vault-auto-unlock";
11844
13628
 
11845
13629
  // src/vault/broker/peercred.ts
11846
13630
  import { execFileSync } from "node:child_process";
11847
- import { readFileSync as readFileSync4, readlinkSync, fstatSync } from "node:fs";
13631
+ import { readFileSync as readFileSync5, readlinkSync, fstatSync } from "node:fs";
11848
13632
 
11849
13633
  // src/vault/broker/peercred-ffi.ts
11850
13634
  function getPeerCred(fd) {
@@ -11970,7 +13754,7 @@ function findClientPidByServerInode(rows, socketPath, serverInode) {
11970
13754
  }
11971
13755
  function readUid(pid) {
11972
13756
  try {
11973
- const status = readFileSync4(`/proc/${pid}/status`, "utf8");
13757
+ const status = readFileSync5(`/proc/${pid}/status`, "utf8");
11974
13758
  const m = status.match(/^Uid:\s+(\d+)/m);
11975
13759
  if (!m)
11976
13760
  return null;
@@ -11988,7 +13772,7 @@ function readExe(pid) {
11988
13772
  }
11989
13773
  function readSystemdUnit(pid) {
11990
13774
  try {
11991
- const content = readFileSync4(`/proc/${pid}/cgroup`, "utf8");
13775
+ const content = readFileSync5(`/proc/${pid}/cgroup`, "utf8");
11992
13776
  const lines = content.split(`
11993
13777
  `);
11994
13778
  for (const line of lines) {
@@ -12243,6 +14027,16 @@ var GetRequestSchema = exports_external.object({
12243
14027
  filename: exports_external.string().optional(),
12244
14028
  token: exports_external.string().optional()
12245
14029
  });
14030
+ var PutRequestSchema = exports_external.object({
14031
+ v: exports_external.literal(1),
14032
+ op: exports_external.literal("put"),
14033
+ key: exports_external.string().min(1),
14034
+ entry: exports_external.union([
14035
+ exports_external.object({ kind: exports_external.literal("string"), value: exports_external.string() }),
14036
+ exports_external.object({ kind: exports_external.literal("binary"), value: exports_external.string() })
14037
+ ]),
14038
+ token: exports_external.string().optional()
14039
+ });
12246
14040
  var ListRequestSchema = exports_external.object({
12247
14041
  v: exports_external.literal(1),
12248
14042
  op: exports_external.literal("list"),
@@ -12327,6 +14121,7 @@ var ApprovalRecordRequestSchema = exports_external.object({
12327
14121
  });
12328
14122
  var RequestSchema = exports_external.discriminatedUnion("op", [
12329
14123
  GetRequestSchema,
14124
+ PutRequestSchema,
12330
14125
  ListRequestSchema,
12331
14126
  StatusRequestSchema,
12332
14127
  LockRequestSchema,
@@ -12379,6 +14174,11 @@ var OkLockResponseSchema = exports_external.object({
12379
14174
  ok: exports_external.literal(true),
12380
14175
  locked: exports_external.literal(true)
12381
14176
  });
14177
+ var OkPutResponseSchema = exports_external.object({
14178
+ ok: exports_external.literal(true),
14179
+ put: exports_external.literal(true),
14180
+ key: exports_external.string()
14181
+ });
12382
14182
  var OkMintGrantResponseSchema = exports_external.object({
12383
14183
  ok: exports_external.literal(true),
12384
14184
  token: exports_external.string(),
@@ -12464,6 +14264,7 @@ var ResponseSchema = exports_external.union([
12464
14264
  OkKeysResponseSchema,
12465
14265
  OkStatusResponseSchema,
12466
14266
  OkLockResponseSchema,
14267
+ OkPutResponseSchema,
12467
14268
  OkMintGrantResponseSchema,
12468
14269
  OkListGrantsResponseSchema,
12469
14270
  OkRevokeGrantResponseSchema,
@@ -12613,13 +14414,13 @@ function genSalt(rounds, seed_length, callback) {
12613
14414
  throw Error("Illegal callback: " + typeof callback);
12614
14415
  _async(callback);
12615
14416
  } else
12616
- return new Promise(function(resolve3, reject) {
14417
+ return new Promise(function(resolve4, reject) {
12617
14418
  _async(function(err, res) {
12618
14419
  if (err) {
12619
14420
  reject(err);
12620
14421
  return;
12621
14422
  }
12622
- resolve3(res);
14423
+ resolve4(res);
12623
14424
  });
12624
14425
  });
12625
14426
  }
@@ -12639,13 +14440,13 @@ function hash(password, salt, callback, progressCallback) {
12639
14440
  throw Error("Illegal callback: " + typeof callback);
12640
14441
  _async(callback);
12641
14442
  } else
12642
- return new Promise(function(resolve3, reject) {
14443
+ return new Promise(function(resolve4, reject) {
12643
14444
  _async(function(err, res) {
12644
14445
  if (err) {
12645
14446
  reject(err);
12646
14447
  return;
12647
14448
  }
12648
- resolve3(res);
14449
+ resolve4(res);
12649
14450
  });
12650
14451
  });
12651
14452
  }
@@ -12678,13 +14479,13 @@ function compare(password, hashValue, callback, progressCallback) {
12678
14479
  throw Error("Illegal callback: " + typeof callback);
12679
14480
  _async(callback);
12680
14481
  } else
12681
- return new Promise(function(resolve3, reject) {
14482
+ return new Promise(function(resolve4, reject) {
12682
14483
  _async(function(err, res) {
12683
14484
  if (err) {
12684
14485
  reject(err);
12685
14486
  return;
12686
14487
  }
12687
- resolve3(res);
14488
+ resolve4(res);
12688
14489
  });
12689
14490
  });
12690
14491
  }
@@ -14478,12 +16279,12 @@ function countPendingNonces(db, now = Date.now()) {
14478
16279
  WHERE consumed_at IS NULL AND expires_at > ?
14479
16280
  GROUP BY agent_unit`).all(now);
14480
16281
  const perAgent = new Map;
14481
- let global = 0;
16282
+ let global2 = 0;
14482
16283
  for (const r of rows) {
14483
16284
  perAgent.set(r.agent_unit, r.n);
14484
- global += r.n;
16285
+ global2 += r.n;
14485
16286
  }
14486
- return { perAgent, global };
16287
+ return { perAgent, global: global2 };
14487
16288
  }
14488
16289
  function computeRetryAfterMs(db, agent_unit, now = Date.now()) {
14489
16290
  const row = agent_unit ? db.query(`SELECT MIN(expires_at) AS expires_at FROM approval_nonces
@@ -14709,6 +16510,7 @@ var PID_FILE_DEFAULT = "~/.switchroom/vault-broker.pid";
14709
16510
  class VaultBroker {
14710
16511
  testOpts;
14711
16512
  secrets = null;
16513
+ passphrase = null;
14712
16514
  config = null;
14713
16515
  startedAt = Date.now();
14714
16516
  server = null;
@@ -14721,9 +16523,12 @@ class VaultBroker {
14721
16523
  grantsDb;
14722
16524
  constructor(testOpts = {}) {
14723
16525
  this.testOpts = testOpts;
14724
- const usingTestOpt = testOpts._testSecrets !== undefined || testOpts._testConfig !== undefined || testOpts._testIdentify !== undefined || testOpts._testAuditLogger !== undefined || testOpts._testGrantsDb !== undefined;
16526
+ const usingTestOpt = testOpts._testSecrets !== undefined || testOpts._testConfig !== undefined || testOpts._testIdentify !== undefined || testOpts._testAuditLogger !== undefined || testOpts._testGrantsDb !== undefined || testOpts._testVaultPath !== undefined;
14725
16527
  if (usingTestOpt && true) {
14726
- throw new Error("VaultBroker: BrokerTestOpts (_testSecrets/_testConfig/_testIdentify/_testAuditLogger/_testGrantsDb) " + "must not be set outside tests. Set NODE_ENV=test if you really mean it.");
16528
+ throw new Error("VaultBroker: BrokerTestOpts (_testSecrets/_testConfig/_testIdentify/_testAuditLogger/_testGrantsDb/_testVaultPath) " + "must not be set outside tests. Set NODE_ENV=test if you really mean it.");
16529
+ }
16530
+ if (testOpts._testVaultPath !== undefined) {
16531
+ this.vaultPath = testOpts._testVaultPath;
14727
16532
  }
14728
16533
  this.auditLogger = testOpts._testAuditLogger ?? createAuditLogger();
14729
16534
  if (testOpts._testGrantsDb !== undefined) {
@@ -14736,7 +16541,7 @@ class VaultBroker {
14736
16541
  if (process.platform !== "linux" && process.env.SWITCHROOM_BROKER_ALLOW_NON_LINUX !== "1") {
14737
16542
  throw new Error(`vault-broker is Linux-only (running on ${process.platform}). ` + `The broker's ACL relies on cgroup-based systemd unit identification, ` + `which is not available on this platform. ` + `Use 'switchroom vault get --no-broker' for direct vault access. ` + `If you need to run the broker for development on this platform, ` + `set SWITCHROOM_BROKER_ALLOW_NON_LINUX=1 — but understand that the ` + `broker will accept any same-user caller without per-cron ACL enforcement.`);
14738
16543
  }
14739
- this.socketPath = resolve3(socketPath);
16544
+ this.socketPath = resolve4(socketPath);
14740
16545
  this.unlockSocketPath = this.socketPath.replace(/\.sock$/, ".unlock.sock");
14741
16546
  this.startedAt = Date.now();
14742
16547
  if (this.testOpts._testConfig) {
@@ -14746,7 +16551,7 @@ class VaultBroker {
14746
16551
  this.config = loadConfig2(configPath);
14747
16552
  }
14748
16553
  if (vaultPath) {
14749
- this.vaultPath = resolve3(vaultPath);
16554
+ this.vaultPath = resolve4(vaultPath);
14750
16555
  } else {
14751
16556
  this.vaultPath = resolvePath(this.config.vault?.path ?? "~/.switchroom/vault.enc");
14752
16557
  }
@@ -14754,15 +16559,15 @@ class VaultBroker {
14754
16559
  this.secrets = { ...this.testOpts._testSecrets };
14755
16560
  }
14756
16561
  process.umask(63);
14757
- const parentDir = dirname2(this.socketPath);
14758
- mkdirSync4(parentDir, { recursive: true, mode: 448 });
16562
+ const parentDir = dirname4(this.socketPath);
16563
+ mkdirSync5(parentDir, { recursive: true, mode: 448 });
14759
16564
  try {
14760
- chmodSync3(parentDir, 448);
16565
+ chmodSync4(parentDir, 448);
14761
16566
  } catch {}
14762
16567
  for (const p of [this.socketPath, this.unlockSocketPath]) {
14763
- if (existsSync5(p)) {
16568
+ if (existsSync6(p)) {
14764
16569
  try {
14765
- unlinkSync2(p);
16570
+ unlinkSync3(p);
14766
16571
  } catch {}
14767
16572
  }
14768
16573
  }
@@ -14778,8 +16583,10 @@ class VaultBroker {
14778
16583
  }
14779
16584
  }
14780
16585
  unlockFromPassphrase(passphrase) {
16586
+ detectVaultLayoutDrift(this.vaultPath);
14781
16587
  const secrets = openVault(passphrase, this.vaultPath);
14782
16588
  this.secrets = secrets;
16589
+ this.passphrase = passphrase;
14783
16590
  }
14784
16591
  lock() {
14785
16592
  if (this.secrets !== null) {
@@ -14792,6 +16599,7 @@ class VaultBroker {
14792
16599
  }
14793
16600
  this.secrets = null;
14794
16601
  }
16602
+ this.passphrase = null;
14795
16603
  }
14796
16604
  stop() {
14797
16605
  this.lock();
@@ -14807,24 +16615,24 @@ class VaultBroker {
14807
16615
  try {
14808
16616
  entry.server.close();
14809
16617
  } catch {}
14810
- if (existsSync5(sockPath)) {
16618
+ if (existsSync6(sockPath)) {
14811
16619
  try {
14812
- unlinkSync2(sockPath);
16620
+ unlinkSync3(sockPath);
14813
16621
  } catch {}
14814
16622
  }
14815
16623
  }
14816
16624
  this.agentServers.clear();
14817
16625
  for (const p of [this.socketPath, this.unlockSocketPath]) {
14818
- if (p && existsSync5(p)) {
16626
+ if (p && existsSync6(p)) {
14819
16627
  try {
14820
- unlinkSync2(p);
16628
+ unlinkSync3(p);
14821
16629
  } catch {}
14822
16630
  }
14823
16631
  }
14824
16632
  try {
14825
16633
  const pidPath = resolvePath(PID_FILE_DEFAULT);
14826
- if (existsSync5(pidPath))
14827
- unlinkSync2(pidPath);
16634
+ if (existsSync6(pidPath))
16635
+ unlinkSync3(pidPath);
14828
16636
  } catch {}
14829
16637
  }
14830
16638
  getStatus() {
@@ -14838,7 +16646,7 @@ class VaultBroker {
14838
16646
  return this.secrets;
14839
16647
  }
14840
16648
  bindAgentSocket(socketPath) {
14841
- const abs = resolve3(socketPath);
16649
+ const abs = resolve4(socketPath);
14842
16650
  const agentName = socketPathToAgent(abs);
14843
16651
  if (agentName === null) {
14844
16652
  return Promise.reject(new Error(`bindAgentSocket: socket path '${abs}' does not match the canonical ` + `/run/switchroom/broker/<agent>.sock shape — refusing to bind without ` + `a verifiable agent identity`));
@@ -14846,18 +16654,18 @@ class VaultBroker {
14846
16654
  return new Promise((resolveP, rejectP) => {
14847
16655
  if (abs.endsWith("/sock")) {
14848
16656
  const dir = abs.slice(0, -"/sock".length);
14849
- if (existsSync5(dir)) {
16657
+ if (existsSync6(dir)) {
14850
16658
  try {
14851
16659
  chownSync(dir, 0, 0);
14852
16660
  } catch {}
14853
16661
  try {
14854
- chmodSync3(dir, 448);
16662
+ chmodSync4(dir, 448);
14855
16663
  } catch {}
14856
16664
  }
14857
16665
  }
14858
- if (existsSync5(abs)) {
16666
+ if (existsSync6(abs)) {
14859
16667
  try {
14860
- unlinkSync2(abs);
16668
+ unlinkSync3(abs);
14861
16669
  } catch (err) {
14862
16670
  const msg = err instanceof Error ? err.message : String(err);
14863
16671
  process.stderr.write(`[vault-broker] could not unlink stale socket agent=${agentName} sock=${abs}: ${msg}
@@ -14870,7 +16678,7 @@ class VaultBroker {
14870
16678
  server.on("error", (err) => rejectP(err));
14871
16679
  server.listen(abs, () => {
14872
16680
  try {
14873
- chmodSync3(abs, 432);
16681
+ chmodSync4(abs, 432);
14874
16682
  } catch {}
14875
16683
  try {
14876
16684
  const uid = allocateAgentUid(agentName);
@@ -14890,7 +16698,7 @@ class VaultBroker {
14890
16698
  });
14891
16699
  }
14892
16700
  _bindDataSocket() {
14893
- return new Promise((resolve4, reject) => {
16701
+ return new Promise((resolve5, reject) => {
14894
16702
  const server = net.createServer((socket) => {
14895
16703
  this._handleDataConnection(socket);
14896
16704
  });
@@ -14899,15 +16707,15 @@ class VaultBroker {
14899
16707
  });
14900
16708
  server.listen(this.socketPath, () => {
14901
16709
  try {
14902
- chmodSync3(this.socketPath, 384);
16710
+ chmodSync4(this.socketPath, 384);
14903
16711
  } catch {}
14904
16712
  this.server = server;
14905
- resolve4();
16713
+ resolve5();
14906
16714
  });
14907
16715
  });
14908
16716
  }
14909
16717
  _bindUnlockSocket() {
14910
- return new Promise((resolve4, reject) => {
16718
+ return new Promise((resolve5, reject) => {
14911
16719
  const server = net.createServer((socket) => {
14912
16720
  this._handleUnlockConnection(socket);
14913
16721
  });
@@ -14916,10 +16724,10 @@ class VaultBroker {
14916
16724
  });
14917
16725
  server.listen(this.unlockSocketPath, () => {
14918
16726
  try {
14919
- chmodSync3(this.unlockSocketPath, 384);
16727
+ chmodSync4(this.unlockSocketPath, 384);
14920
16728
  } catch {}
14921
16729
  this.unlockServer = server;
14922
- resolve4();
16730
+ resolve5();
14923
16731
  });
14924
16732
  });
14925
16733
  }
@@ -15205,6 +17013,90 @@ class VaultBroker {
15205
17013
  socket.write(encodeResponse(entryResponse(entry)));
15206
17014
  return;
15207
17015
  }
17016
+ if (req.op === "put") {
17017
+ if (this.secrets === null || this.passphrase === null) {
17018
+ socket.write(encodeResponse(errorResponse("LOCKED", "Vault is locked")));
17019
+ return;
17020
+ }
17021
+ if (agentName === null) {
17022
+ socket.write(encodeResponse(errorResponse("DENIED", "put requires path-as-identity (token-based grants are read-only)")));
17023
+ return;
17024
+ }
17025
+ if (this.config === null) {
17026
+ socket.write(encodeResponse(errorResponse("INTERNAL", "Broker config not loaded")));
17027
+ return;
17028
+ }
17029
+ const aclResult = checkAclByAgent(this.config, agentName, req.key);
17030
+ if (!aclResult.allow) {
17031
+ this.auditLogger.write({
17032
+ ts: new Date().toISOString(),
17033
+ op: "put",
17034
+ key: req.key,
17035
+ caller: auditCaller,
17036
+ pid: auditPid,
17037
+ cgroup: auditCgroup,
17038
+ result: `denied:${aclResult.reason}`
17039
+ });
17040
+ socket.write(encodeResponse(errorResponse("DENIED", aclResult.reason)));
17041
+ return;
17042
+ }
17043
+ const existing = this.secrets[req.key];
17044
+ if (existing === undefined) {
17045
+ this.auditLogger.write({
17046
+ ts: new Date().toISOString(),
17047
+ op: "put",
17048
+ key: req.key,
17049
+ caller: auditCaller,
17050
+ pid: auditPid,
17051
+ cgroup: auditCgroup,
17052
+ result: "denied:unknown_key"
17053
+ });
17054
+ socket.write(encodeResponse(errorResponse("UNKNOWN_KEY", `Key not found: ${req.key} (broker put cannot introduce new keys; ask operator to set it once via 'switchroom vault set' from the host)`)));
17055
+ return;
17056
+ }
17057
+ if (existing.kind !== req.entry.kind) {
17058
+ this.auditLogger.write({
17059
+ ts: new Date().toISOString(),
17060
+ op: "put",
17061
+ key: req.key,
17062
+ caller: auditCaller,
17063
+ pid: auditPid,
17064
+ cgroup: auditCgroup,
17065
+ result: `denied:kind_mismatch ${existing.kind}→${req.entry.kind}`
17066
+ });
17067
+ socket.write(encodeResponse(errorResponse("BAD_REQUEST", `kind mismatch: existing entry is '${existing.kind}', new entry is '${req.entry.kind}'`)));
17068
+ return;
17069
+ }
17070
+ const previousEntry = existing;
17071
+ this.secrets[req.key] = req.entry;
17072
+ try {
17073
+ saveVault(this.passphrase, this.vaultPath, this.secrets);
17074
+ } catch (err) {
17075
+ this.secrets[req.key] = previousEntry;
17076
+ this.auditLogger.write({
17077
+ ts: new Date().toISOString(),
17078
+ op: "put",
17079
+ key: req.key,
17080
+ caller: auditCaller,
17081
+ pid: auditPid,
17082
+ cgroup: auditCgroup,
17083
+ result: `error:${err?.message ?? "save failed"}`
17084
+ });
17085
+ socket.write(encodeResponse(errorResponse("INTERNAL", `Failed to persist: ${err?.message ?? "unknown"}`)));
17086
+ return;
17087
+ }
17088
+ this.auditLogger.write({
17089
+ ts: new Date().toISOString(),
17090
+ op: "put",
17091
+ key: req.key,
17092
+ caller: auditCaller,
17093
+ pid: auditPid,
17094
+ cgroup: auditCgroup,
17095
+ result: "allowed"
17096
+ });
17097
+ socket.write(encodeResponse({ ok: true, put: true, key: req.key }));
17098
+ return;
17099
+ }
15208
17100
  if (req.op === "approval_request" || req.op === "approval_lookup" || req.op === "approval_consume" || req.op === "approval_revoke" || req.op === "approval_list" || req.op === "approval_record") {
15209
17101
  await this._handleApprovalOp(socket, req);
15210
17102
  return;
@@ -15272,11 +17164,11 @@ class VaultBroker {
15272
17164
  }
15273
17165
  try {
15274
17166
  const tokenDir = path3.join(os3.homedir(), ".switchroom", "agents", agent);
15275
- mkdirSync4(tokenDir, { recursive: true });
17167
+ mkdirSync5(tokenDir, { recursive: true });
15276
17168
  const tokenPath = path3.join(tokenDir, ".vault-token");
15277
17169
  const tmpPath = `${tokenPath}.tmp.${process.pid}`;
15278
17170
  writeFileSync3(tmpPath, mintResult.token, { mode: 384 });
15279
- renameSync2(tmpPath, tokenPath);
17171
+ renameSync3(tmpPath, tokenPath);
15280
17172
  } catch (err) {
15281
17173
  process.stderr.write(`[vault-broker] mint_grant: failed to write token file for agent ${agent}: ${err.message}
15282
17174
  `);
@@ -15327,9 +17219,9 @@ class VaultBroker {
15327
17219
  const row = this.grantsDb.query("SELECT agent_slug FROM vault_grants WHERE id = ?").get(id);
15328
17220
  if (row) {
15329
17221
  const tokenPath = path3.join(os3.homedir(), ".switchroom", "agents", row.agent_slug, ".vault-token");
15330
- if (existsSync5(tokenPath)) {
17222
+ if (existsSync6(tokenPath)) {
15331
17223
  try {
15332
- unlinkSync2(tokenPath);
17224
+ unlinkSync3(tokenPath);
15333
17225
  } catch {}
15334
17226
  }
15335
17227
  }
@@ -15570,7 +17462,7 @@ class VaultBroker {
15570
17462
  const envPath = process.env.SWITCHROOM_VAULT_BROKER_AUTO_UNLOCK_PATH;
15571
17463
  const configuredPath = (envPath && envPath.length > 0 ? envPath : undefined) ?? this.config?.vault?.broker?.autoUnlockCredentialPath ?? DEFAULT_AUTO_UNLOCK_PATH;
15572
17464
  const filePath = resolvePath(configuredPath);
15573
- if (!existsSync5(filePath))
17465
+ if (!existsSync6(filePath))
15574
17466
  return false;
15575
17467
  let passphrase;
15576
17468
  try {
@@ -15607,7 +17499,7 @@ class VaultBroker {
15607
17499
  const credPath = `${dir}/vault-passphrase`;
15608
17500
  let passphrase;
15609
17501
  try {
15610
- passphrase = readFileSync5(credPath, "utf8").replace(/\n+$/, "");
17502
+ passphrase = readFileSync6(credPath, "utf8").replace(/\n+$/, "");
15611
17503
  } catch (err) {
15612
17504
  const code = err.code;
15613
17505
  if (code === "ENOENT") {
@@ -15644,6 +17536,21 @@ class VaultBroker {
15644
17536
  } catch {}
15645
17537
  }
15646
17538
  }
17539
+ function detectVaultLayoutDrift(vaultPath) {
17540
+ const dir = dirname4(vaultPath);
17541
+ if (basename3(dir) !== "vault")
17542
+ return;
17543
+ if (basename3(vaultPath) !== "vault.enc")
17544
+ return;
17545
+ const switchroomDir = dirname4(dir);
17546
+ if (basename3(switchroomDir) !== ".switchroom")
17547
+ return;
17548
+ const home2 = dirname4(switchroomDir);
17549
+ const result = inspectVaultLayout(home2);
17550
+ if (result.kind === "divergent") {
17551
+ throw new VaultError(`Vault layout divergence detected at boot: ${result.details.oldPath} and ${result.details.newPath} are both regular files with different content. An older switchroom CLI may have written to the legacy path after migration ran. Run \`switchroom apply\` from the host to surface the recovery recipe (state E refusal with literal \`mv\` commands). See docs/operators/state-e-recovery.md.`);
17552
+ }
17553
+ }
15647
17554
  var _globalBroker = null;
15648
17555
  function registerShutdownHandlers(broker) {
15649
17556
  _globalBroker = broker;
@@ -15664,7 +17571,7 @@ async function main() {
15664
17571
  const vaultPath = process.env.SWITCHROOM_VAULT_PATH;
15665
17572
  let perAgentTargets = [];
15666
17573
  try {
15667
- if (existsSync5(perAgentDir)) {
17574
+ if (existsSync6(perAgentDir)) {
15668
17575
  const entries = readdirSync(perAgentDir, { withFileTypes: true });
15669
17576
  const flat = [];
15670
17577
  const subdirs = [];
@@ -15672,11 +17579,11 @@ async function main() {
15672
17579
  if (e.name.startsWith("."))
15673
17580
  continue;
15674
17581
  if ((e.isFile() || e.isSocket()) && e.name.endsWith(".sock")) {
15675
- flat.push(resolve3(perAgentDir, e.name));
17582
+ flat.push(resolve4(perAgentDir, e.name));
15676
17583
  continue;
15677
17584
  }
15678
17585
  if (e.isDirectory()) {
15679
- const candidate = resolve3(perAgentDir, e.name, "sock");
17586
+ const candidate = resolve4(perAgentDir, e.name, "sock");
15680
17587
  if (socketPathToAgent(candidate) !== null) {
15681
17588
  subdirs.push(candidate);
15682
17589
  }