@great-arrow/cli 0.1.64 → 0.1.65
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.js +1799 -546
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -108,7 +108,7 @@ var require_polyfills = __commonJS({
|
|
|
108
108
|
}
|
|
109
109
|
if (platform2 === "win32") {
|
|
110
110
|
fs6.rename = typeof fs6.rename !== "function" ? fs6.rename : (function(fs$rename) {
|
|
111
|
-
function
|
|
111
|
+
function rename3(from, to, cb) {
|
|
112
112
|
var start = Date.now();
|
|
113
113
|
var backoff = 0;
|
|
114
114
|
fs$rename(from, to, function CB(er) {
|
|
@@ -128,8 +128,8 @@ var require_polyfills = __commonJS({
|
|
|
128
128
|
if (cb) cb(er);
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
|
-
if (Object.setPrototypeOf) Object.setPrototypeOf(
|
|
132
|
-
return
|
|
131
|
+
if (Object.setPrototypeOf) Object.setPrototypeOf(rename3, fs$rename);
|
|
132
|
+
return rename3;
|
|
133
133
|
})(fs6.rename);
|
|
134
134
|
}
|
|
135
135
|
fs6.read = typeof fs6.read !== "function" ? fs6.read : (function(fs$read) {
|
|
@@ -172,14 +172,14 @@ var require_polyfills = __commonJS({
|
|
|
172
172
|
path10,
|
|
173
173
|
constants2.O_WRONLY | constants2.O_SYMLINK,
|
|
174
174
|
mode,
|
|
175
|
-
function(
|
|
176
|
-
if (
|
|
177
|
-
if (callback) callback(
|
|
175
|
+
function(err2, fd) {
|
|
176
|
+
if (err2) {
|
|
177
|
+
if (callback) callback(err2);
|
|
178
178
|
return;
|
|
179
179
|
}
|
|
180
|
-
fs7.fchmod(fd, mode, function(
|
|
180
|
+
fs7.fchmod(fd, mode, function(err3) {
|
|
181
181
|
fs7.close(fd, function(err22) {
|
|
182
|
-
if (callback) callback(
|
|
182
|
+
if (callback) callback(err3 || err22);
|
|
183
183
|
});
|
|
184
184
|
});
|
|
185
185
|
}
|
|
@@ -377,9 +377,9 @@ var require_legacy_streams = __commonJS({
|
|
|
377
377
|
});
|
|
378
378
|
return;
|
|
379
379
|
}
|
|
380
|
-
fs6.open(this.path, this.flags, this.mode, function(
|
|
381
|
-
if (
|
|
382
|
-
self.emit("error",
|
|
380
|
+
fs6.open(this.path, this.flags, this.mode, function(err2, fd) {
|
|
381
|
+
if (err2) {
|
|
382
|
+
self.emit("error", err2);
|
|
383
383
|
self.readable = false;
|
|
384
384
|
return;
|
|
385
385
|
}
|
|
@@ -488,8 +488,8 @@ var require_graceful_fs = __commonJS({
|
|
|
488
488
|
publishQueue(fs6, queue);
|
|
489
489
|
fs6.close = (function(fs$close) {
|
|
490
490
|
function close(fd, cb) {
|
|
491
|
-
return fs$close.call(fs6, fd, function(
|
|
492
|
-
if (!
|
|
491
|
+
return fs$close.call(fs6, fd, function(err2) {
|
|
492
|
+
if (!err2) {
|
|
493
493
|
resetQueue();
|
|
494
494
|
}
|
|
495
495
|
if (typeof cb === "function")
|
|
@@ -533,15 +533,15 @@ var require_graceful_fs = __commonJS({
|
|
|
533
533
|
fs7.createReadStream = createReadStream;
|
|
534
534
|
fs7.createWriteStream = createWriteStream;
|
|
535
535
|
var fs$readFile = fs7.readFile;
|
|
536
|
-
fs7.readFile =
|
|
537
|
-
function
|
|
536
|
+
fs7.readFile = readFile9;
|
|
537
|
+
function readFile9(path10, options, cb) {
|
|
538
538
|
if (typeof options === "function")
|
|
539
539
|
cb = options, options = null;
|
|
540
540
|
return go$readFile(path10, options, cb);
|
|
541
541
|
function go$readFile(path11, options2, cb2, startTime) {
|
|
542
|
-
return fs$readFile(path11, options2, function(
|
|
543
|
-
if (
|
|
544
|
-
enqueue([go$readFile, [path11, options2, cb2],
|
|
542
|
+
return fs$readFile(path11, options2, function(err2) {
|
|
543
|
+
if (err2 && (err2.code === "EMFILE" || err2.code === "ENFILE"))
|
|
544
|
+
enqueue([go$readFile, [path11, options2, cb2], err2, startTime || Date.now(), Date.now()]);
|
|
545
545
|
else {
|
|
546
546
|
if (typeof cb2 === "function")
|
|
547
547
|
cb2.apply(this, arguments);
|
|
@@ -550,15 +550,15 @@ var require_graceful_fs = __commonJS({
|
|
|
550
550
|
}
|
|
551
551
|
}
|
|
552
552
|
var fs$writeFile = fs7.writeFile;
|
|
553
|
-
fs7.writeFile =
|
|
554
|
-
function
|
|
553
|
+
fs7.writeFile = writeFile7;
|
|
554
|
+
function writeFile7(path10, data, options, cb) {
|
|
555
555
|
if (typeof options === "function")
|
|
556
556
|
cb = options, options = null;
|
|
557
557
|
return go$writeFile(path10, data, options, cb);
|
|
558
558
|
function go$writeFile(path11, data2, options2, cb2, startTime) {
|
|
559
|
-
return fs$writeFile(path11, data2, options2, function(
|
|
560
|
-
if (
|
|
561
|
-
enqueue([go$writeFile, [path11, data2, options2, cb2],
|
|
559
|
+
return fs$writeFile(path11, data2, options2, function(err2) {
|
|
560
|
+
if (err2 && (err2.code === "EMFILE" || err2.code === "ENFILE"))
|
|
561
|
+
enqueue([go$writeFile, [path11, data2, options2, cb2], err2, startTime || Date.now(), Date.now()]);
|
|
562
562
|
else {
|
|
563
563
|
if (typeof cb2 === "function")
|
|
564
564
|
cb2.apply(this, arguments);
|
|
@@ -574,9 +574,9 @@ var require_graceful_fs = __commonJS({
|
|
|
574
574
|
cb = options, options = null;
|
|
575
575
|
return go$appendFile(path10, data, options, cb);
|
|
576
576
|
function go$appendFile(path11, data2, options2, cb2, startTime) {
|
|
577
|
-
return fs$appendFile(path11, data2, options2, function(
|
|
578
|
-
if (
|
|
579
|
-
enqueue([go$appendFile, [path11, data2, options2, cb2],
|
|
577
|
+
return fs$appendFile(path11, data2, options2, function(err2) {
|
|
578
|
+
if (err2 && (err2.code === "EMFILE" || err2.code === "ENFILE"))
|
|
579
|
+
enqueue([go$appendFile, [path11, data2, options2, cb2], err2, startTime || Date.now(), Date.now()]);
|
|
580
580
|
else {
|
|
581
581
|
if (typeof cb2 === "function")
|
|
582
582
|
cb2.apply(this, arguments);
|
|
@@ -594,9 +594,9 @@ var require_graceful_fs = __commonJS({
|
|
|
594
594
|
}
|
|
595
595
|
return go$copyFile(src, dest, flags, cb);
|
|
596
596
|
function go$copyFile(src2, dest2, flags2, cb2, startTime) {
|
|
597
|
-
return fs$copyFile(src2, dest2, flags2, function(
|
|
598
|
-
if (
|
|
599
|
-
enqueue([go$copyFile, [src2, dest2, flags2, cb2],
|
|
597
|
+
return fs$copyFile(src2, dest2, flags2, function(err2) {
|
|
598
|
+
if (err2 && (err2.code === "EMFILE" || err2.code === "ENFILE"))
|
|
599
|
+
enqueue([go$copyFile, [src2, dest2, flags2, cb2], err2, startTime || Date.now(), Date.now()]);
|
|
600
600
|
else {
|
|
601
601
|
if (typeof cb2 === "function")
|
|
602
602
|
cb2.apply(this, arguments);
|
|
@@ -627,12 +627,12 @@ var require_graceful_fs = __commonJS({
|
|
|
627
627
|
};
|
|
628
628
|
return go$readdir(path10, options, cb);
|
|
629
629
|
function fs$readdirCallback(path11, options2, cb2, startTime) {
|
|
630
|
-
return function(
|
|
631
|
-
if (
|
|
630
|
+
return function(err2, files) {
|
|
631
|
+
if (err2 && (err2.code === "EMFILE" || err2.code === "ENFILE"))
|
|
632
632
|
enqueue([
|
|
633
633
|
go$readdir,
|
|
634
634
|
[path11, options2, cb2],
|
|
635
|
-
|
|
635
|
+
err2,
|
|
636
636
|
startTime || Date.now(),
|
|
637
637
|
Date.now()
|
|
638
638
|
]);
|
|
@@ -640,7 +640,7 @@ var require_graceful_fs = __commonJS({
|
|
|
640
640
|
if (files && files.sort)
|
|
641
641
|
files.sort();
|
|
642
642
|
if (typeof cb2 === "function")
|
|
643
|
-
cb2.call(this,
|
|
643
|
+
cb2.call(this, err2, files);
|
|
644
644
|
}
|
|
645
645
|
};
|
|
646
646
|
}
|
|
@@ -710,11 +710,11 @@ var require_graceful_fs = __commonJS({
|
|
|
710
710
|
}
|
|
711
711
|
function ReadStream$open() {
|
|
712
712
|
var that = this;
|
|
713
|
-
open4(that.path, that.flags, that.mode, function(
|
|
714
|
-
if (
|
|
713
|
+
open4(that.path, that.flags, that.mode, function(err2, fd) {
|
|
714
|
+
if (err2) {
|
|
715
715
|
if (that.autoClose)
|
|
716
716
|
that.destroy();
|
|
717
|
-
that.emit("error",
|
|
717
|
+
that.emit("error", err2);
|
|
718
718
|
} else {
|
|
719
719
|
that.fd = fd;
|
|
720
720
|
that.emit("open", fd);
|
|
@@ -730,10 +730,10 @@ var require_graceful_fs = __commonJS({
|
|
|
730
730
|
}
|
|
731
731
|
function WriteStream$open() {
|
|
732
732
|
var that = this;
|
|
733
|
-
open4(that.path, that.flags, that.mode, function(
|
|
734
|
-
if (
|
|
733
|
+
open4(that.path, that.flags, that.mode, function(err2, fd) {
|
|
734
|
+
if (err2) {
|
|
735
735
|
that.destroy();
|
|
736
|
-
that.emit("error",
|
|
736
|
+
that.emit("error", err2);
|
|
737
737
|
} else {
|
|
738
738
|
that.fd = fd;
|
|
739
739
|
that.emit("open", fd);
|
|
@@ -753,9 +753,9 @@ var require_graceful_fs = __commonJS({
|
|
|
753
753
|
cb = mode, mode = null;
|
|
754
754
|
return go$open(path10, flags, mode, cb);
|
|
755
755
|
function go$open(path11, flags2, mode2, cb2, startTime) {
|
|
756
|
-
return fs$open(path11, flags2, mode2, function(
|
|
757
|
-
if (
|
|
758
|
-
enqueue([go$open, [path11, flags2, mode2, cb2],
|
|
756
|
+
return fs$open(path11, flags2, mode2, function(err2, fd) {
|
|
757
|
+
if (err2 && (err2.code === "EMFILE" || err2.code === "ENFILE"))
|
|
758
|
+
enqueue([go$open, [path11, flags2, mode2, cb2], err2, startTime || Date.now(), Date.now()]);
|
|
759
759
|
else {
|
|
760
760
|
if (typeof cb2 === "function")
|
|
761
761
|
cb2.apply(this, arguments);
|
|
@@ -789,7 +789,7 @@ var require_graceful_fs = __commonJS({
|
|
|
789
789
|
var elem = fs6[gracefulQueue].shift();
|
|
790
790
|
var fn = elem[0];
|
|
791
791
|
var args = elem[1];
|
|
792
|
-
var
|
|
792
|
+
var err2 = elem[2];
|
|
793
793
|
var startTime = elem[3];
|
|
794
794
|
var lastTime = elem[4];
|
|
795
795
|
if (startTime === void 0) {
|
|
@@ -799,7 +799,7 @@ var require_graceful_fs = __commonJS({
|
|
|
799
799
|
debug("TIMEOUT", fn.name, args);
|
|
800
800
|
var cb = args.pop();
|
|
801
801
|
if (typeof cb === "function")
|
|
802
|
-
cb.call(null,
|
|
802
|
+
cb.call(null, err2);
|
|
803
803
|
} else {
|
|
804
804
|
var sinceAttempt = Date.now() - lastTime;
|
|
805
805
|
var sinceStart = Math.max(lastTime - startTime, 1);
|
|
@@ -1367,7 +1367,7 @@ var require_ini = __commonJS({
|
|
|
1367
1367
|
var eol = typeof process !== "undefined" && process.platform === "win32" ? "\r\n" : "\n";
|
|
1368
1368
|
function encode3(obj, opt) {
|
|
1369
1369
|
var children = [];
|
|
1370
|
-
var
|
|
1370
|
+
var out2 = "";
|
|
1371
1371
|
if (typeof opt === "string") {
|
|
1372
1372
|
opt = {
|
|
1373
1373
|
section: opt,
|
|
@@ -1382,15 +1382,15 @@ var require_ini = __commonJS({
|
|
|
1382
1382
|
var val = obj[k];
|
|
1383
1383
|
if (val && Array.isArray(val)) {
|
|
1384
1384
|
val.forEach(function(item) {
|
|
1385
|
-
|
|
1385
|
+
out2 += safe(k + "[]") + separator + safe(item) + "\n";
|
|
1386
1386
|
});
|
|
1387
1387
|
} else if (val && typeof val === "object")
|
|
1388
1388
|
children.push(k);
|
|
1389
1389
|
else
|
|
1390
|
-
|
|
1390
|
+
out2 += safe(k) + separator + safe(val) + eol;
|
|
1391
1391
|
});
|
|
1392
|
-
if (opt.section &&
|
|
1393
|
-
|
|
1392
|
+
if (opt.section && out2.length)
|
|
1393
|
+
out2 = "[" + safe(opt.section) + "]" + eol + out2;
|
|
1394
1394
|
children.forEach(function(k, _, __) {
|
|
1395
1395
|
var nk = dotSplit(k).join("\\.");
|
|
1396
1396
|
var section = (opt.section ? opt.section + "." : "") + nk;
|
|
@@ -1398,11 +1398,11 @@ var require_ini = __commonJS({
|
|
|
1398
1398
|
section,
|
|
1399
1399
|
whitespace: opt.whitespace
|
|
1400
1400
|
});
|
|
1401
|
-
if (
|
|
1402
|
-
|
|
1403
|
-
|
|
1401
|
+
if (out2.length && child.length)
|
|
1402
|
+
out2 += eol;
|
|
1403
|
+
out2 += child;
|
|
1404
1404
|
});
|
|
1405
|
-
return
|
|
1405
|
+
return out2;
|
|
1406
1406
|
}
|
|
1407
1407
|
function dotSplit(str) {
|
|
1408
1408
|
return str.replace(/\1/g, "LITERAL\\1LITERAL").replace(/\\\./g, "").split(/\./).map(function(part) {
|
|
@@ -1410,8 +1410,8 @@ var require_ini = __commonJS({
|
|
|
1410
1410
|
});
|
|
1411
1411
|
}
|
|
1412
1412
|
function decode3(str) {
|
|
1413
|
-
var
|
|
1414
|
-
var p =
|
|
1413
|
+
var out2 = {};
|
|
1414
|
+
var p = out2;
|
|
1415
1415
|
var section = null;
|
|
1416
1416
|
var re = /^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i;
|
|
1417
1417
|
var lines = str.split(/[\r\n]+/g);
|
|
@@ -1427,7 +1427,7 @@ var require_ini = __commonJS({
|
|
|
1427
1427
|
p = {};
|
|
1428
1428
|
return;
|
|
1429
1429
|
}
|
|
1430
|
-
p =
|
|
1430
|
+
p = out2[section] = out2[section] || {};
|
|
1431
1431
|
return;
|
|
1432
1432
|
}
|
|
1433
1433
|
var key = unsafe(match[2]);
|
|
@@ -1454,11 +1454,11 @@ var require_ini = __commonJS({
|
|
|
1454
1454
|
else
|
|
1455
1455
|
p[key] = value;
|
|
1456
1456
|
});
|
|
1457
|
-
Object.keys(
|
|
1458
|
-
if (!
|
|
1457
|
+
Object.keys(out2).filter(function(k, _, __) {
|
|
1458
|
+
if (!out2[k] || typeof out2[k] !== "object" || Array.isArray(out2[k]))
|
|
1459
1459
|
return false;
|
|
1460
1460
|
var parts = dotSplit(k);
|
|
1461
|
-
var p2 =
|
|
1461
|
+
var p2 = out2;
|
|
1462
1462
|
var l = parts.pop();
|
|
1463
1463
|
var nl = l.replace(/\\\./g, ".");
|
|
1464
1464
|
parts.forEach(function(part, _2, __2) {
|
|
@@ -1468,14 +1468,14 @@ var require_ini = __commonJS({
|
|
|
1468
1468
|
p2[part] = {};
|
|
1469
1469
|
p2 = p2[part];
|
|
1470
1470
|
});
|
|
1471
|
-
if (p2 ===
|
|
1471
|
+
if (p2 === out2 && nl === l)
|
|
1472
1472
|
return false;
|
|
1473
|
-
p2[nl] =
|
|
1473
|
+
p2[nl] = out2[k];
|
|
1474
1474
|
return true;
|
|
1475
1475
|
}).forEach(function(del, _, __) {
|
|
1476
|
-
delete
|
|
1476
|
+
delete out2[del];
|
|
1477
1477
|
});
|
|
1478
|
-
return
|
|
1478
|
+
return out2;
|
|
1479
1479
|
}
|
|
1480
1480
|
function isQuoted(val) {
|
|
1481
1481
|
return val.charAt(0) === '"' && val.slice(-1) === '"' || val.charAt(0) === "'" && val.slice(-1) === "'";
|
|
@@ -1610,7 +1610,7 @@ var require_utils = __commonJS({
|
|
|
1610
1610
|
var content;
|
|
1611
1611
|
try {
|
|
1612
1612
|
return fs6.readFileSync(file3, "utf-8");
|
|
1613
|
-
} catch (
|
|
1613
|
+
} catch (err2) {
|
|
1614
1614
|
return;
|
|
1615
1615
|
}
|
|
1616
1616
|
};
|
|
@@ -1650,7 +1650,7 @@ var require_utils = __commonJS({
|
|
|
1650
1650
|
try {
|
|
1651
1651
|
fs6.statSync(file3);
|
|
1652
1652
|
return file3;
|
|
1653
|
-
} catch (
|
|
1653
|
+
} catch (err2) {
|
|
1654
1654
|
if (path10.dirname(start) !== start)
|
|
1655
1655
|
return find2(path10.dirname(start), rel2);
|
|
1656
1656
|
}
|
|
@@ -1968,7 +1968,7 @@ var require_minimist = __commonJS({
|
|
|
1968
1968
|
var require_rc = __commonJS({
|
|
1969
1969
|
"node_modules/.pnpm/rc@1.2.8/node_modules/rc/index.js"(exports, module) {
|
|
1970
1970
|
var cc = require_utils();
|
|
1971
|
-
var
|
|
1971
|
+
var join13 = __require("path").join;
|
|
1972
1972
|
var deepExtend = require_deep_extend();
|
|
1973
1973
|
var etc = "/etc";
|
|
1974
1974
|
var win = process.platform === "win32";
|
|
@@ -1993,15 +1993,15 @@ var require_rc = __commonJS({
|
|
|
1993
1993
|
}
|
|
1994
1994
|
if (!win)
|
|
1995
1995
|
[
|
|
1996
|
-
|
|
1997
|
-
|
|
1996
|
+
join13(etc, name23, "config"),
|
|
1997
|
+
join13(etc, name23 + "rc")
|
|
1998
1998
|
].forEach(addConfigFile);
|
|
1999
1999
|
if (home)
|
|
2000
2000
|
[
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2001
|
+
join13(home, ".config", name23, "config"),
|
|
2002
|
+
join13(home, ".config", name23),
|
|
2003
|
+
join13(home, "." + name23, "config"),
|
|
2004
|
+
join13(home, "." + name23 + "rc")
|
|
2005
2005
|
].forEach(addConfigFile);
|
|
2006
2006
|
addConfigFile(cc.find("." + name23 + "rc"));
|
|
2007
2007
|
if (env4.config) addConfigFile(env4.config);
|
|
@@ -2082,7 +2082,7 @@ var require_polyfills2 = __commonJS({
|
|
|
2082
2082
|
}
|
|
2083
2083
|
if (platform2 === "win32") {
|
|
2084
2084
|
fs6.rename = typeof fs6.rename !== "function" ? fs6.rename : (function(fs$rename) {
|
|
2085
|
-
function
|
|
2085
|
+
function rename3(from, to, cb) {
|
|
2086
2086
|
var start = Date.now();
|
|
2087
2087
|
var backoff = 0;
|
|
2088
2088
|
fs$rename(from, to, function CB(er) {
|
|
@@ -2102,8 +2102,8 @@ var require_polyfills2 = __commonJS({
|
|
|
2102
2102
|
if (cb) cb(er);
|
|
2103
2103
|
});
|
|
2104
2104
|
}
|
|
2105
|
-
if (Object.setPrototypeOf) Object.setPrototypeOf(
|
|
2106
|
-
return
|
|
2105
|
+
if (Object.setPrototypeOf) Object.setPrototypeOf(rename3, fs$rename);
|
|
2106
|
+
return rename3;
|
|
2107
2107
|
})(fs6.rename);
|
|
2108
2108
|
}
|
|
2109
2109
|
fs6.read = typeof fs6.read !== "function" ? fs6.read : (function(fs$read) {
|
|
@@ -2146,14 +2146,14 @@ var require_polyfills2 = __commonJS({
|
|
|
2146
2146
|
path10,
|
|
2147
2147
|
constants2.O_WRONLY | constants2.O_SYMLINK,
|
|
2148
2148
|
mode,
|
|
2149
|
-
function(
|
|
2150
|
-
if (
|
|
2151
|
-
if (callback) callback(
|
|
2149
|
+
function(err2, fd) {
|
|
2150
|
+
if (err2) {
|
|
2151
|
+
if (callback) callback(err2);
|
|
2152
2152
|
return;
|
|
2153
2153
|
}
|
|
2154
|
-
fs7.fchmod(fd, mode, function(
|
|
2154
|
+
fs7.fchmod(fd, mode, function(err3) {
|
|
2155
2155
|
fs7.close(fd, function(err22) {
|
|
2156
|
-
if (callback) callback(
|
|
2156
|
+
if (callback) callback(err3 || err22);
|
|
2157
2157
|
});
|
|
2158
2158
|
});
|
|
2159
2159
|
}
|
|
@@ -2351,9 +2351,9 @@ var require_legacy_streams2 = __commonJS({
|
|
|
2351
2351
|
});
|
|
2352
2352
|
return;
|
|
2353
2353
|
}
|
|
2354
|
-
fs6.open(this.path, this.flags, this.mode, function(
|
|
2355
|
-
if (
|
|
2356
|
-
self.emit("error",
|
|
2354
|
+
fs6.open(this.path, this.flags, this.mode, function(err2, fd) {
|
|
2355
|
+
if (err2) {
|
|
2356
|
+
self.emit("error", err2);
|
|
2357
2357
|
self.readable = false;
|
|
2358
2358
|
return;
|
|
2359
2359
|
}
|
|
@@ -2462,8 +2462,8 @@ var require_graceful_fs2 = __commonJS({
|
|
|
2462
2462
|
publishQueue(fs6, queue);
|
|
2463
2463
|
fs6.close = (function(fs$close) {
|
|
2464
2464
|
function close(fd, cb) {
|
|
2465
|
-
return fs$close.call(fs6, fd, function(
|
|
2466
|
-
if (!
|
|
2465
|
+
return fs$close.call(fs6, fd, function(err2) {
|
|
2466
|
+
if (!err2) {
|
|
2467
2467
|
resetQueue();
|
|
2468
2468
|
}
|
|
2469
2469
|
if (typeof cb === "function")
|
|
@@ -2507,15 +2507,15 @@ var require_graceful_fs2 = __commonJS({
|
|
|
2507
2507
|
fs7.createReadStream = createReadStream;
|
|
2508
2508
|
fs7.createWriteStream = createWriteStream;
|
|
2509
2509
|
var fs$readFile = fs7.readFile;
|
|
2510
|
-
fs7.readFile =
|
|
2511
|
-
function
|
|
2510
|
+
fs7.readFile = readFile9;
|
|
2511
|
+
function readFile9(path10, options, cb) {
|
|
2512
2512
|
if (typeof options === "function")
|
|
2513
2513
|
cb = options, options = null;
|
|
2514
2514
|
return go$readFile(path10, options, cb);
|
|
2515
2515
|
function go$readFile(path11, options2, cb2, startTime) {
|
|
2516
|
-
return fs$readFile(path11, options2, function(
|
|
2517
|
-
if (
|
|
2518
|
-
enqueue([go$readFile, [path11, options2, cb2],
|
|
2516
|
+
return fs$readFile(path11, options2, function(err2) {
|
|
2517
|
+
if (err2 && (err2.code === "EMFILE" || err2.code === "ENFILE"))
|
|
2518
|
+
enqueue([go$readFile, [path11, options2, cb2], err2, startTime || Date.now(), Date.now()]);
|
|
2519
2519
|
else {
|
|
2520
2520
|
if (typeof cb2 === "function")
|
|
2521
2521
|
cb2.apply(this, arguments);
|
|
@@ -2524,15 +2524,15 @@ var require_graceful_fs2 = __commonJS({
|
|
|
2524
2524
|
}
|
|
2525
2525
|
}
|
|
2526
2526
|
var fs$writeFile = fs7.writeFile;
|
|
2527
|
-
fs7.writeFile =
|
|
2528
|
-
function
|
|
2527
|
+
fs7.writeFile = writeFile7;
|
|
2528
|
+
function writeFile7(path10, data, options, cb) {
|
|
2529
2529
|
if (typeof options === "function")
|
|
2530
2530
|
cb = options, options = null;
|
|
2531
2531
|
return go$writeFile(path10, data, options, cb);
|
|
2532
2532
|
function go$writeFile(path11, data2, options2, cb2, startTime) {
|
|
2533
|
-
return fs$writeFile(path11, data2, options2, function(
|
|
2534
|
-
if (
|
|
2535
|
-
enqueue([go$writeFile, [path11, data2, options2, cb2],
|
|
2533
|
+
return fs$writeFile(path11, data2, options2, function(err2) {
|
|
2534
|
+
if (err2 && (err2.code === "EMFILE" || err2.code === "ENFILE"))
|
|
2535
|
+
enqueue([go$writeFile, [path11, data2, options2, cb2], err2, startTime || Date.now(), Date.now()]);
|
|
2536
2536
|
else {
|
|
2537
2537
|
if (typeof cb2 === "function")
|
|
2538
2538
|
cb2.apply(this, arguments);
|
|
@@ -2548,9 +2548,9 @@ var require_graceful_fs2 = __commonJS({
|
|
|
2548
2548
|
cb = options, options = null;
|
|
2549
2549
|
return go$appendFile(path10, data, options, cb);
|
|
2550
2550
|
function go$appendFile(path11, data2, options2, cb2, startTime) {
|
|
2551
|
-
return fs$appendFile(path11, data2, options2, function(
|
|
2552
|
-
if (
|
|
2553
|
-
enqueue([go$appendFile, [path11, data2, options2, cb2],
|
|
2551
|
+
return fs$appendFile(path11, data2, options2, function(err2) {
|
|
2552
|
+
if (err2 && (err2.code === "EMFILE" || err2.code === "ENFILE"))
|
|
2553
|
+
enqueue([go$appendFile, [path11, data2, options2, cb2], err2, startTime || Date.now(), Date.now()]);
|
|
2554
2554
|
else {
|
|
2555
2555
|
if (typeof cb2 === "function")
|
|
2556
2556
|
cb2.apply(this, arguments);
|
|
@@ -2568,9 +2568,9 @@ var require_graceful_fs2 = __commonJS({
|
|
|
2568
2568
|
}
|
|
2569
2569
|
return go$copyFile(src, dest, flags, cb);
|
|
2570
2570
|
function go$copyFile(src2, dest2, flags2, cb2, startTime) {
|
|
2571
|
-
return fs$copyFile(src2, dest2, flags2, function(
|
|
2572
|
-
if (
|
|
2573
|
-
enqueue([go$copyFile, [src2, dest2, flags2, cb2],
|
|
2571
|
+
return fs$copyFile(src2, dest2, flags2, function(err2) {
|
|
2572
|
+
if (err2 && (err2.code === "EMFILE" || err2.code === "ENFILE"))
|
|
2573
|
+
enqueue([go$copyFile, [src2, dest2, flags2, cb2], err2, startTime || Date.now(), Date.now()]);
|
|
2574
2574
|
else {
|
|
2575
2575
|
if (typeof cb2 === "function")
|
|
2576
2576
|
cb2.apply(this, arguments);
|
|
@@ -2601,12 +2601,12 @@ var require_graceful_fs2 = __commonJS({
|
|
|
2601
2601
|
};
|
|
2602
2602
|
return go$readdir(path10, options, cb);
|
|
2603
2603
|
function fs$readdirCallback(path11, options2, cb2, startTime) {
|
|
2604
|
-
return function(
|
|
2605
|
-
if (
|
|
2604
|
+
return function(err2, files) {
|
|
2605
|
+
if (err2 && (err2.code === "EMFILE" || err2.code === "ENFILE"))
|
|
2606
2606
|
enqueue([
|
|
2607
2607
|
go$readdir,
|
|
2608
2608
|
[path11, options2, cb2],
|
|
2609
|
-
|
|
2609
|
+
err2,
|
|
2610
2610
|
startTime || Date.now(),
|
|
2611
2611
|
Date.now()
|
|
2612
2612
|
]);
|
|
@@ -2614,7 +2614,7 @@ var require_graceful_fs2 = __commonJS({
|
|
|
2614
2614
|
if (files && files.sort)
|
|
2615
2615
|
files.sort();
|
|
2616
2616
|
if (typeof cb2 === "function")
|
|
2617
|
-
cb2.call(this,
|
|
2617
|
+
cb2.call(this, err2, files);
|
|
2618
2618
|
}
|
|
2619
2619
|
};
|
|
2620
2620
|
}
|
|
@@ -2684,11 +2684,11 @@ var require_graceful_fs2 = __commonJS({
|
|
|
2684
2684
|
}
|
|
2685
2685
|
function ReadStream$open() {
|
|
2686
2686
|
var that = this;
|
|
2687
|
-
open4(that.path, that.flags, that.mode, function(
|
|
2688
|
-
if (
|
|
2687
|
+
open4(that.path, that.flags, that.mode, function(err2, fd) {
|
|
2688
|
+
if (err2) {
|
|
2689
2689
|
if (that.autoClose)
|
|
2690
2690
|
that.destroy();
|
|
2691
|
-
that.emit("error",
|
|
2691
|
+
that.emit("error", err2);
|
|
2692
2692
|
} else {
|
|
2693
2693
|
that.fd = fd;
|
|
2694
2694
|
that.emit("open", fd);
|
|
@@ -2704,10 +2704,10 @@ var require_graceful_fs2 = __commonJS({
|
|
|
2704
2704
|
}
|
|
2705
2705
|
function WriteStream$open() {
|
|
2706
2706
|
var that = this;
|
|
2707
|
-
open4(that.path, that.flags, that.mode, function(
|
|
2708
|
-
if (
|
|
2707
|
+
open4(that.path, that.flags, that.mode, function(err2, fd) {
|
|
2708
|
+
if (err2) {
|
|
2709
2709
|
that.destroy();
|
|
2710
|
-
that.emit("error",
|
|
2710
|
+
that.emit("error", err2);
|
|
2711
2711
|
} else {
|
|
2712
2712
|
that.fd = fd;
|
|
2713
2713
|
that.emit("open", fd);
|
|
@@ -2727,9 +2727,9 @@ var require_graceful_fs2 = __commonJS({
|
|
|
2727
2727
|
cb = mode, mode = null;
|
|
2728
2728
|
return go$open(path10, flags, mode, cb);
|
|
2729
2729
|
function go$open(path11, flags2, mode2, cb2, startTime) {
|
|
2730
|
-
return fs$open(path11, flags2, mode2, function(
|
|
2731
|
-
if (
|
|
2732
|
-
enqueue([go$open, [path11, flags2, mode2, cb2],
|
|
2730
|
+
return fs$open(path11, flags2, mode2, function(err2, fd) {
|
|
2731
|
+
if (err2 && (err2.code === "EMFILE" || err2.code === "ENFILE"))
|
|
2732
|
+
enqueue([go$open, [path11, flags2, mode2, cb2], err2, startTime || Date.now(), Date.now()]);
|
|
2733
2733
|
else {
|
|
2734
2734
|
if (typeof cb2 === "function")
|
|
2735
2735
|
cb2.apply(this, arguments);
|
|
@@ -2763,7 +2763,7 @@ var require_graceful_fs2 = __commonJS({
|
|
|
2763
2763
|
var elem = fs6[gracefulQueue].shift();
|
|
2764
2764
|
var fn = elem[0];
|
|
2765
2765
|
var args = elem[1];
|
|
2766
|
-
var
|
|
2766
|
+
var err2 = elem[2];
|
|
2767
2767
|
var startTime = elem[3];
|
|
2768
2768
|
var lastTime = elem[4];
|
|
2769
2769
|
if (startTime === void 0) {
|
|
@@ -2773,7 +2773,7 @@ var require_graceful_fs2 = __commonJS({
|
|
|
2773
2773
|
debug("TIMEOUT", fn.name, args);
|
|
2774
2774
|
var cb = args.pop();
|
|
2775
2775
|
if (typeof cb === "function")
|
|
2776
|
-
cb.call(null,
|
|
2776
|
+
cb.call(null, err2);
|
|
2777
2777
|
} else {
|
|
2778
2778
|
var sinceAttempt = Date.now() - lastTime;
|
|
2779
2779
|
var sinceStart = Math.max(lastTime - startTime, 1);
|
|
@@ -2808,10 +2808,10 @@ var require_ca_file = __commonJS({
|
|
|
2808
2808
|
const delim = "-----END CERTIFICATE-----";
|
|
2809
2809
|
const output2 = contents.split(delim).filter((ca) => Boolean(ca.trim())).map((ca) => `${ca.trimLeft()}${delim}`);
|
|
2810
2810
|
return output2;
|
|
2811
|
-
} catch (
|
|
2812
|
-
if (
|
|
2811
|
+
} catch (err2) {
|
|
2812
|
+
if (err2.code === "ENOENT")
|
|
2813
2813
|
return void 0;
|
|
2814
|
-
throw
|
|
2814
|
+
throw err2;
|
|
2815
2815
|
}
|
|
2816
2816
|
}
|
|
2817
2817
|
exports.readCAFileSync = readCAFileSync;
|
|
@@ -2963,7 +2963,7 @@ var require_config_chain = __commonJS({
|
|
|
2963
2963
|
try {
|
|
2964
2964
|
fs6.statSync(file2);
|
|
2965
2965
|
return file2;
|
|
2966
|
-
} catch (
|
|
2966
|
+
} catch (err2) {
|
|
2967
2967
|
if (path10.dirname(start) !== start)
|
|
2968
2968
|
return find2(path10.dirname(start), rel2);
|
|
2969
2969
|
}
|
|
@@ -3000,7 +3000,7 @@ var require_config_chain = __commonJS({
|
|
|
3000
3000
|
var content;
|
|
3001
3001
|
try {
|
|
3002
3002
|
content = fs6.readFileSync(file2, "utf-8");
|
|
3003
|
-
} catch (
|
|
3003
|
+
} catch (err2) {
|
|
3004
3004
|
return;
|
|
3005
3005
|
}
|
|
3006
3006
|
return parse3(content, file2, "json");
|
|
@@ -3193,12 +3193,12 @@ var require_envKeyToSetting = __commonJS({
|
|
|
3193
3193
|
const secondPart = x.substr(colonIndex + 1);
|
|
3194
3194
|
return `${firstPart}:${normalize2(secondPart)}`;
|
|
3195
3195
|
};
|
|
3196
|
-
function normalize2(
|
|
3197
|
-
|
|
3198
|
-
if (
|
|
3199
|
-
let r =
|
|
3200
|
-
for (let i = 1; i <
|
|
3201
|
-
r +=
|
|
3196
|
+
function normalize2(s2) {
|
|
3197
|
+
s2 = s2.toLowerCase();
|
|
3198
|
+
if (s2 === "_authtoken") return "_authToken";
|
|
3199
|
+
let r = s2[0];
|
|
3200
|
+
for (let i = 1; i < s2.length; i++) {
|
|
3201
|
+
r += s2[i] === "_" ? "-" : s2[i];
|
|
3202
3202
|
}
|
|
3203
3203
|
return r;
|
|
3204
3204
|
}
|
|
@@ -3339,11 +3339,11 @@ var require_util = __commonJS({
|
|
|
3339
3339
|
if (files.includes("node_modules") || files.includes("package.json") || files.includes("package.json5") || files.includes("package.yaml") || files.includes("pnpm-workspace.yaml")) {
|
|
3340
3340
|
return name24;
|
|
3341
3341
|
}
|
|
3342
|
-
const
|
|
3343
|
-
if (
|
|
3342
|
+
const dirname9 = path10.dirname(name24);
|
|
3343
|
+
if (dirname9 === name24) {
|
|
3344
3344
|
return original;
|
|
3345
3345
|
}
|
|
3346
|
-
return find(
|
|
3346
|
+
return find(dirname9, original);
|
|
3347
3347
|
} catch (error62) {
|
|
3348
3348
|
if (name24 === original) {
|
|
3349
3349
|
if (error62.code === "ENOENT") {
|
|
@@ -4032,8 +4032,8 @@ var require_clean = __commonJS({
|
|
|
4032
4032
|
"use strict";
|
|
4033
4033
|
var parse3 = require_parse();
|
|
4034
4034
|
var clean = (version2, options) => {
|
|
4035
|
-
const
|
|
4036
|
-
return
|
|
4035
|
+
const s2 = parse3(version2.trim().replace(/^[=v]+/, ""), options);
|
|
4036
|
+
return s2 ? s2.version : null;
|
|
4037
4037
|
};
|
|
4038
4038
|
module.exports = clean;
|
|
4039
4039
|
}
|
|
@@ -5474,22 +5474,22 @@ var require_ini2 = __commonJS({
|
|
|
5474
5474
|
keys.filter((k) => obj[k] === null || Array.isArray(obj[k]) || typeof obj[k] !== "object").map((k) => Array.isArray(obj[k]) ? `${k}[]` : k).concat([""]).reduce((a, b) => safe(a).length >= safe(b).length ? a : b)
|
|
5475
5475
|
).length;
|
|
5476
5476
|
}
|
|
5477
|
-
let
|
|
5477
|
+
let out2 = "";
|
|
5478
5478
|
const arraySuffix = opt.bracketedArray ? "[]" : "";
|
|
5479
5479
|
for (const k of keys) {
|
|
5480
5480
|
const val = obj[k];
|
|
5481
5481
|
if (val && Array.isArray(val)) {
|
|
5482
5482
|
for (const item of val) {
|
|
5483
|
-
|
|
5483
|
+
out2 += safe(`${k}${arraySuffix}`).padEnd(padToChars, " ") + separator + safe(item) + eol;
|
|
5484
5484
|
}
|
|
5485
5485
|
} else if (val && typeof val === "object") {
|
|
5486
5486
|
children.push(k);
|
|
5487
5487
|
} else {
|
|
5488
|
-
|
|
5488
|
+
out2 += safe(k).padEnd(padToChars, " ") + separator + safe(val) + eol;
|
|
5489
5489
|
}
|
|
5490
5490
|
}
|
|
5491
|
-
if (opt.section &&
|
|
5492
|
-
|
|
5491
|
+
if (opt.section && out2.length) {
|
|
5492
|
+
out2 = "[" + safe(opt.section) + "]" + (opt.newline ? eol + eol : eol) + out2;
|
|
5493
5493
|
}
|
|
5494
5494
|
for (const k of children) {
|
|
5495
5495
|
const nk = splitSections(k, ".").join("\\.");
|
|
@@ -5498,12 +5498,12 @@ var require_ini2 = __commonJS({
|
|
|
5498
5498
|
...opt,
|
|
5499
5499
|
section
|
|
5500
5500
|
});
|
|
5501
|
-
if (
|
|
5502
|
-
|
|
5501
|
+
if (out2.length && child.length) {
|
|
5502
|
+
out2 += eol;
|
|
5503
5503
|
}
|
|
5504
|
-
|
|
5504
|
+
out2 += child;
|
|
5505
5505
|
}
|
|
5506
|
-
return
|
|
5506
|
+
return out2;
|
|
5507
5507
|
};
|
|
5508
5508
|
function splitSections(str, separator) {
|
|
5509
5509
|
var lastMatchIndex = 0;
|
|
@@ -5526,8 +5526,8 @@ var require_ini2 = __commonJS({
|
|
|
5526
5526
|
}
|
|
5527
5527
|
var decode3 = (str, opt = {}) => {
|
|
5528
5528
|
opt.bracketedArray = opt.bracketedArray !== false;
|
|
5529
|
-
const
|
|
5530
|
-
let p =
|
|
5529
|
+
const out2 = /* @__PURE__ */ Object.create(null);
|
|
5530
|
+
let p = out2;
|
|
5531
5531
|
let section = null;
|
|
5532
5532
|
const re = /^\[([^\]]*)\]\s*$|^([^=]+)(=(.*))?$/i;
|
|
5533
5533
|
const lines = str.split(/[\r\n]+/g);
|
|
@@ -5546,7 +5546,7 @@ var require_ini2 = __commonJS({
|
|
|
5546
5546
|
p = /* @__PURE__ */ Object.create(null);
|
|
5547
5547
|
continue;
|
|
5548
5548
|
}
|
|
5549
|
-
p =
|
|
5549
|
+
p = out2[section] = out2[section] || /* @__PURE__ */ Object.create(null);
|
|
5550
5550
|
continue;
|
|
5551
5551
|
}
|
|
5552
5552
|
const keyRaw = unsafe(match[2]);
|
|
@@ -5577,12 +5577,12 @@ var require_ini2 = __commonJS({
|
|
|
5577
5577
|
}
|
|
5578
5578
|
}
|
|
5579
5579
|
const remove = [];
|
|
5580
|
-
for (const k of Object.keys(
|
|
5581
|
-
if (!hasOwnProperty.call(
|
|
5580
|
+
for (const k of Object.keys(out2)) {
|
|
5581
|
+
if (!hasOwnProperty.call(out2, k) || typeof out2[k] !== "object" || Array.isArray(out2[k])) {
|
|
5582
5582
|
continue;
|
|
5583
5583
|
}
|
|
5584
5584
|
const parts = splitSections(k, ".");
|
|
5585
|
-
p =
|
|
5585
|
+
p = out2;
|
|
5586
5586
|
const l = parts.pop();
|
|
5587
5587
|
const nl = l.replace(/\\\./g, ".");
|
|
5588
5588
|
for (const part of parts) {
|
|
@@ -5594,16 +5594,16 @@ var require_ini2 = __commonJS({
|
|
|
5594
5594
|
}
|
|
5595
5595
|
p = p[part];
|
|
5596
5596
|
}
|
|
5597
|
-
if (p ===
|
|
5597
|
+
if (p === out2 && nl === l) {
|
|
5598
5598
|
continue;
|
|
5599
5599
|
}
|
|
5600
|
-
p[nl] =
|
|
5600
|
+
p[nl] = out2[k];
|
|
5601
5601
|
remove.push(k);
|
|
5602
5602
|
}
|
|
5603
5603
|
for (const del of remove) {
|
|
5604
|
-
delete
|
|
5604
|
+
delete out2[del];
|
|
5605
5605
|
}
|
|
5606
|
-
return
|
|
5606
|
+
return out2;
|
|
5607
5607
|
};
|
|
5608
5608
|
var isQuoted = (val) => {
|
|
5609
5609
|
return val.startsWith('"') && val.endsWith('"') || val.startsWith("'") && val.endsWith("'");
|
|
@@ -7475,9 +7475,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
7475
7475
|
if (fn) {
|
|
7476
7476
|
this._exitCallback = fn;
|
|
7477
7477
|
} else {
|
|
7478
|
-
this._exitCallback = (
|
|
7479
|
-
if (
|
|
7480
|
-
throw
|
|
7478
|
+
this._exitCallback = (err2) => {
|
|
7479
|
+
if (err2.code !== "commander.executeSubCommandAsync") {
|
|
7480
|
+
throw err2;
|
|
7481
7481
|
} else {
|
|
7482
7482
|
}
|
|
7483
7483
|
};
|
|
@@ -7553,12 +7553,12 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
7553
7553
|
_callParseArg(target, value, previous, invalidArgumentMessage) {
|
|
7554
7554
|
try {
|
|
7555
7555
|
return target.parseArg(value, previous);
|
|
7556
|
-
} catch (
|
|
7557
|
-
if (
|
|
7558
|
-
const message = `${invalidArgumentMessage} ${
|
|
7559
|
-
this.error(message, { exitCode:
|
|
7556
|
+
} catch (err2) {
|
|
7557
|
+
if (err2.code === "commander.invalidArgument") {
|
|
7558
|
+
const message = `${invalidArgumentMessage} ${err2.message}`;
|
|
7559
|
+
this.error(message, { exitCode: err2.exitCode, code: err2.code });
|
|
7560
7560
|
}
|
|
7561
|
-
throw
|
|
7561
|
+
throw err2;
|
|
7562
7562
|
}
|
|
7563
7563
|
}
|
|
7564
7564
|
/**
|
|
@@ -8149,14 +8149,14 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
8149
8149
|
);
|
|
8150
8150
|
}
|
|
8151
8151
|
});
|
|
8152
|
-
proc.on("error", (
|
|
8153
|
-
if (
|
|
8152
|
+
proc.on("error", (err2) => {
|
|
8153
|
+
if (err2.code === "ENOENT") {
|
|
8154
8154
|
this._checkForMissingExecutable(
|
|
8155
8155
|
executableFile,
|
|
8156
8156
|
executableDir,
|
|
8157
8157
|
subcommand._name
|
|
8158
8158
|
);
|
|
8159
|
-
} else if (
|
|
8159
|
+
} else if (err2.code === "EACCES") {
|
|
8160
8160
|
throw new Error(`'${executableFile}' not executable`);
|
|
8161
8161
|
}
|
|
8162
8162
|
if (!exitCallback) {
|
|
@@ -8167,7 +8167,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
8167
8167
|
"commander.executeSubCommandAsync",
|
|
8168
8168
|
"(error)"
|
|
8169
8169
|
);
|
|
8170
|
-
wrappedError.nestedError =
|
|
8170
|
+
wrappedError.nestedError = err2;
|
|
8171
8171
|
exitCallback(wrappedError);
|
|
8172
8172
|
}
|
|
8173
8173
|
});
|
|
@@ -8794,11 +8794,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
8794
8794
|
_excessArguments(receivedArgs) {
|
|
8795
8795
|
if (this._allowExcessArguments) return;
|
|
8796
8796
|
const expected = this.registeredArguments.length;
|
|
8797
|
-
const
|
|
8797
|
+
const s2 = expected === 1 ? "" : "s";
|
|
8798
8798
|
const received = receivedArgs.length;
|
|
8799
8799
|
const forSubcommand = this.parent ? ` for '${this.name()}'` : "";
|
|
8800
8800
|
const details = receivedArgs.join(", ");
|
|
8801
|
-
const message = `error: too many arguments${forSubcommand}. Expected ${expected} argument${
|
|
8801
|
+
const message = `error: too many arguments${forSubcommand}. Expected ${expected} argument${s2} but got ${received}: ${details}.`;
|
|
8802
8802
|
this.error(message, { code: "commander.excessArguments" });
|
|
8803
8803
|
}
|
|
8804
8804
|
/**
|
|
@@ -9373,6 +9373,25 @@ function classifyRequestFailure(error62) {
|
|
|
9373
9373
|
}
|
|
9374
9374
|
return { kind, message, hint: FAILURE_HINTS[kind] };
|
|
9375
9375
|
}
|
|
9376
|
+
var SERVER_CODE = /^[a-z][a-z0-9_]{0,63}$/;
|
|
9377
|
+
function withServerCode(error62, body) {
|
|
9378
|
+
try {
|
|
9379
|
+
const code = JSON.parse(body)?.error;
|
|
9380
|
+
if (typeof code === "string" && SERVER_CODE.test(code)) {
|
|
9381
|
+
Object.defineProperty(error62, "serverCode", {
|
|
9382
|
+
value: code,
|
|
9383
|
+
enumerable: false
|
|
9384
|
+
});
|
|
9385
|
+
}
|
|
9386
|
+
} catch {
|
|
9387
|
+
return error62;
|
|
9388
|
+
}
|
|
9389
|
+
return error62;
|
|
9390
|
+
}
|
|
9391
|
+
function serverCodeOf(error62) {
|
|
9392
|
+
const code = error62?.serverCode;
|
|
9393
|
+
return typeof code === "string" ? code : null;
|
|
9394
|
+
}
|
|
9376
9395
|
function authError(message, hint) {
|
|
9377
9396
|
return new CliError(
|
|
9378
9397
|
message,
|
|
@@ -9418,7 +9437,7 @@ function isNodeError(value) {
|
|
|
9418
9437
|
|
|
9419
9438
|
// src/lib/version.ts
|
|
9420
9439
|
var CLI_PACKAGE_NAME = "@great-arrow/cli";
|
|
9421
|
-
var CLI_VERSION = "0.1.
|
|
9440
|
+
var CLI_VERSION = "0.1.65";
|
|
9422
9441
|
var GAD_INSTALL_VERSION = "2026.08.08";
|
|
9423
9442
|
var GAD_INSTALL_MIN_VERSION = "2026.06.22";
|
|
9424
9443
|
var GAD_INSTALL_HEADER = "X-GAD-Install-Version";
|
|
@@ -9436,9 +9455,9 @@ import { homedir } from "node:os";
|
|
|
9436
9455
|
import { join, dirname } from "node:path";
|
|
9437
9456
|
|
|
9438
9457
|
// src/lib/debug.ts
|
|
9439
|
-
function debugSwallow(scope,
|
|
9458
|
+
function debugSwallow(scope, err2) {
|
|
9440
9459
|
if (!process.env.GAD_DEBUG) return;
|
|
9441
|
-
const detail =
|
|
9460
|
+
const detail = err2 instanceof Error ? err2.stack ?? err2.message : String(err2);
|
|
9442
9461
|
process.stderr.write(`gad: [debug] ${scope} swallowed: ${detail}
|
|
9443
9462
|
`);
|
|
9444
9463
|
}
|
|
@@ -9446,81 +9465,91 @@ function debugSwallow(scope, err) {
|
|
|
9446
9465
|
// src/lib/keychain.ts
|
|
9447
9466
|
var SERVICE = "GreatArrowDigital";
|
|
9448
9467
|
var ACCOUNT = "api-token";
|
|
9449
|
-
function
|
|
9450
|
-
return join(homedir(), ".great-arrow", "credential");
|
|
9468
|
+
function slotFilePath(account) {
|
|
9469
|
+
if (account === ACCOUNT) return join(homedir(), ".great-arrow", "credential");
|
|
9470
|
+
return join(homedir(), ".great-arrow", "slots", encodeURIComponent(account));
|
|
9451
9471
|
}
|
|
9452
|
-
async function loadEntry() {
|
|
9472
|
+
async function loadEntry(account) {
|
|
9453
9473
|
try {
|
|
9454
9474
|
const { AsyncEntry } = await import("@napi-rs/keyring");
|
|
9455
|
-
return new AsyncEntry(SERVICE,
|
|
9475
|
+
return new AsyncEntry(SERVICE, account);
|
|
9456
9476
|
} catch {
|
|
9457
9477
|
return null;
|
|
9458
9478
|
}
|
|
9459
9479
|
}
|
|
9460
|
-
async function readFileFallback() {
|
|
9480
|
+
async function readFileFallback(account) {
|
|
9461
9481
|
try {
|
|
9462
|
-
const raw = await readFile(
|
|
9482
|
+
const raw = await readFile(slotFilePath(account), "utf-8");
|
|
9463
9483
|
const trimmed = raw.trim();
|
|
9464
9484
|
return trimmed === "" ? null : trimmed;
|
|
9465
9485
|
} catch {
|
|
9466
9486
|
return null;
|
|
9467
9487
|
}
|
|
9468
9488
|
}
|
|
9469
|
-
async function
|
|
9470
|
-
const entry = await loadEntry();
|
|
9489
|
+
async function getSecretSlot(account) {
|
|
9490
|
+
const entry = await loadEntry(account);
|
|
9471
9491
|
if (entry) {
|
|
9472
9492
|
try {
|
|
9473
9493
|
const value = await entry.getPassword();
|
|
9474
9494
|
if (value) return value;
|
|
9475
|
-
} catch (
|
|
9476
|
-
debugSwallow("keychain.
|
|
9495
|
+
} catch (err2) {
|
|
9496
|
+
debugSwallow("keychain.getSecretSlot", err2);
|
|
9477
9497
|
}
|
|
9478
9498
|
}
|
|
9479
|
-
return readFileFallback();
|
|
9499
|
+
return readFileFallback(account);
|
|
9480
9500
|
}
|
|
9481
|
-
async function
|
|
9482
|
-
const entry = await loadEntry();
|
|
9501
|
+
async function setSecretSlot(account, value) {
|
|
9502
|
+
const entry = await loadEntry(account);
|
|
9483
9503
|
if (entry) {
|
|
9484
9504
|
try {
|
|
9485
|
-
await entry.setPassword(
|
|
9486
|
-
await removeFileFallback();
|
|
9505
|
+
await entry.setPassword(value);
|
|
9506
|
+
await removeFileFallback(account);
|
|
9487
9507
|
return true;
|
|
9488
|
-
} catch (
|
|
9489
|
-
debugSwallow("keychain.
|
|
9508
|
+
} catch (err2) {
|
|
9509
|
+
debugSwallow("keychain.setSecretSlot", err2);
|
|
9490
9510
|
}
|
|
9491
9511
|
try {
|
|
9492
9512
|
await entry.deletePassword();
|
|
9493
|
-
} catch (
|
|
9494
|
-
debugSwallow("keychain.
|
|
9513
|
+
} catch (err2) {
|
|
9514
|
+
debugSwallow("keychain.setSecretSlot(delete stale)", err2);
|
|
9495
9515
|
return false;
|
|
9496
9516
|
}
|
|
9497
9517
|
}
|
|
9498
9518
|
try {
|
|
9499
|
-
const path10 =
|
|
9519
|
+
const path10 = slotFilePath(account);
|
|
9500
9520
|
await mkdir(dirname(path10), { recursive: true, mode: 448 });
|
|
9501
|
-
await writeFile(path10,
|
|
9521
|
+
await writeFile(path10, value, { mode: 384 });
|
|
9502
9522
|
return true;
|
|
9503
9523
|
} catch {
|
|
9504
9524
|
return false;
|
|
9505
9525
|
}
|
|
9506
9526
|
}
|
|
9507
|
-
async function
|
|
9508
|
-
const entry = await loadEntry();
|
|
9527
|
+
async function deleteSecretSlot(account) {
|
|
9528
|
+
const entry = await loadEntry(account);
|
|
9509
9529
|
if (entry) {
|
|
9510
9530
|
try {
|
|
9511
9531
|
await entry.deletePassword();
|
|
9512
|
-
} catch (
|
|
9513
|
-
debugSwallow("keychain.
|
|
9532
|
+
} catch (err2) {
|
|
9533
|
+
debugSwallow("keychain.deleteSecretSlot", err2);
|
|
9514
9534
|
}
|
|
9515
9535
|
}
|
|
9516
|
-
await removeFileFallback();
|
|
9536
|
+
await removeFileFallback(account);
|
|
9537
|
+
}
|
|
9538
|
+
function getToken() {
|
|
9539
|
+
return getSecretSlot(ACCOUNT);
|
|
9540
|
+
}
|
|
9541
|
+
function setToken(token) {
|
|
9542
|
+
return setSecretSlot(ACCOUNT, token);
|
|
9517
9543
|
}
|
|
9518
|
-
|
|
9544
|
+
function deleteToken() {
|
|
9545
|
+
return deleteSecretSlot(ACCOUNT);
|
|
9546
|
+
}
|
|
9547
|
+
async function removeFileFallback(account) {
|
|
9519
9548
|
try {
|
|
9520
|
-
await unlink(
|
|
9521
|
-
} catch (
|
|
9522
|
-
if (
|
|
9523
|
-
debugSwallow("keychain.removeFileFallback",
|
|
9549
|
+
await unlink(slotFilePath(account));
|
|
9550
|
+
} catch (err2) {
|
|
9551
|
+
if (err2?.code !== "ENOENT") {
|
|
9552
|
+
debugSwallow("keychain.removeFileFallback", err2);
|
|
9524
9553
|
}
|
|
9525
9554
|
}
|
|
9526
9555
|
}
|
|
@@ -9585,8 +9614,8 @@ function writeCliLocator(home = homedir2(), entry = process.argv[1]) {
|
|
|
9585
9614
|
let resolved = entry;
|
|
9586
9615
|
try {
|
|
9587
9616
|
resolved = realpathSync(entry);
|
|
9588
|
-
} catch (
|
|
9589
|
-
debugSwallow("cli-locator.realpath",
|
|
9617
|
+
} catch (err2) {
|
|
9618
|
+
debugSwallow("cli-locator.realpath", err2);
|
|
9590
9619
|
}
|
|
9591
9620
|
mkdirSync(dir, { recursive: true });
|
|
9592
9621
|
writeFileSync(
|
|
@@ -9600,8 +9629,8 @@ function writeCliLocator(home = homedir2(), entry = process.argv[1]) {
|
|
|
9600
9629
|
);
|
|
9601
9630
|
chmodSync(tmp, 384);
|
|
9602
9631
|
renameSync(tmp, target);
|
|
9603
|
-
} catch (
|
|
9604
|
-
debugSwallow("cli-locator.write",
|
|
9632
|
+
} catch (err2) {
|
|
9633
|
+
debugSwallow("cli-locator.write", err2);
|
|
9605
9634
|
try {
|
|
9606
9635
|
rmSync(tmp, { force: true });
|
|
9607
9636
|
} catch (cleanupErr) {
|
|
@@ -9699,8 +9728,8 @@ async function loadConfig() {
|
|
|
9699
9728
|
const content = await readFile2(configPath, "utf-8");
|
|
9700
9729
|
const parsed = parseConfig(content);
|
|
9701
9730
|
return { ...DEFAULTS, ...stripEmpty(parsed) };
|
|
9702
|
-
} catch (
|
|
9703
|
-
if (isNodeError2(
|
|
9731
|
+
} catch (err2) {
|
|
9732
|
+
if (isNodeError2(err2) && err2.code === "ENOENT") {
|
|
9704
9733
|
return { ...DEFAULTS };
|
|
9705
9734
|
}
|
|
9706
9735
|
return { ...DEFAULTS };
|
|
@@ -9737,8 +9766,8 @@ function stripEmpty(config2) {
|
|
|
9737
9766
|
result.telemetry_enabled = config2.telemetry_enabled;
|
|
9738
9767
|
return result;
|
|
9739
9768
|
}
|
|
9740
|
-
function isNodeError2(
|
|
9741
|
-
return
|
|
9769
|
+
function isNodeError2(err2) {
|
|
9770
|
+
return err2 instanceof Error && "code" in err2;
|
|
9742
9771
|
}
|
|
9743
9772
|
|
|
9744
9773
|
// src/lib/oauth/pkce.ts
|
|
@@ -9770,8 +9799,8 @@ var DEFAULT_CALLBACK_PORT = 51789;
|
|
|
9770
9799
|
var CALLBACK_PATH = "/callback";
|
|
9771
9800
|
var LOOPBACK_HOST = "127.0.0.1";
|
|
9772
9801
|
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
9773
|
-
function escapeHtml(
|
|
9774
|
-
return
|
|
9802
|
+
function escapeHtml(s2) {
|
|
9803
|
+
return s2.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
9775
9804
|
}
|
|
9776
9805
|
var CLOSE_TAB_HTML = (ok, detail) => `<!doctype html>
|
|
9777
9806
|
<html><head><meta charset="utf-8"><title>Great Arrow CLI</title>
|
|
@@ -9782,12 +9811,12 @@ h1{font-size:1.25rem;margin:0 0 .5rem}p{color:#9a9aa3;margin:0}</style></head>
|
|
|
9782
9811
|
<body><div class="card"><h1>${ok ? "\u2713 Signed in to Great Arrow" : "\u2717 Sign-in failed"}</h1>
|
|
9783
9812
|
<p>${escapeHtml(detail)}</p></div></body></html>`;
|
|
9784
9813
|
function listen(port) {
|
|
9785
|
-
return new Promise((
|
|
9814
|
+
return new Promise((resolve5, reject) => {
|
|
9786
9815
|
const server = createServer();
|
|
9787
9816
|
server.on("error", reject);
|
|
9788
9817
|
server.listen(port, LOOPBACK_HOST, () => {
|
|
9789
9818
|
const addr = server.address();
|
|
9790
|
-
|
|
9819
|
+
resolve5({ server, port: addr.port });
|
|
9791
9820
|
});
|
|
9792
9821
|
});
|
|
9793
9822
|
}
|
|
@@ -9812,7 +9841,7 @@ async function startLoopbackServer(opts) {
|
|
|
9812
9841
|
port,
|
|
9813
9842
|
close: () => server.close(),
|
|
9814
9843
|
waitForCallback({ timeoutMs = DEFAULT_TIMEOUT_MS } = {}) {
|
|
9815
|
-
return new Promise((
|
|
9844
|
+
return new Promise((resolve5, reject) => {
|
|
9816
9845
|
const timer = setTimeout(() => {
|
|
9817
9846
|
server.close();
|
|
9818
9847
|
reject(new Error("Timed out waiting for the browser callback."));
|
|
@@ -9852,7 +9881,7 @@ async function startLoopbackServer(opts) {
|
|
|
9852
9881
|
"You can close this tab and return to your terminal."
|
|
9853
9882
|
)
|
|
9854
9883
|
);
|
|
9855
|
-
settle2(() =>
|
|
9884
|
+
settle2(() => resolve5({ code, state }));
|
|
9856
9885
|
});
|
|
9857
9886
|
});
|
|
9858
9887
|
}
|
|
@@ -10137,16 +10166,16 @@ async function confirm(message) {
|
|
|
10137
10166
|
input: process.stdin,
|
|
10138
10167
|
output: process.stdout
|
|
10139
10168
|
});
|
|
10140
|
-
return new Promise((
|
|
10169
|
+
return new Promise((resolve5) => {
|
|
10141
10170
|
rl.question(`${message} [y/N] `, (answer) => {
|
|
10142
10171
|
rl.close();
|
|
10143
10172
|
const normalized = answer.trim().toLowerCase();
|
|
10144
|
-
|
|
10173
|
+
resolve5(normalized === "y" || normalized === "yes");
|
|
10145
10174
|
});
|
|
10146
10175
|
});
|
|
10147
10176
|
}
|
|
10148
|
-
function stripControlChars(
|
|
10149
|
-
return String(
|
|
10177
|
+
function stripControlChars(s2) {
|
|
10178
|
+
return String(s2).replace(/[\u0000-\u001f\u007f-\u009f]/g, "");
|
|
10150
10179
|
}
|
|
10151
10180
|
|
|
10152
10181
|
// src/lib/formatter.ts
|
|
@@ -10307,8 +10336,8 @@ function createFormatter(options) {
|
|
|
10307
10336
|
var DEFAULT_API_URL = "https://www.greatarrow.ai";
|
|
10308
10337
|
function isLegacyApiUrl(value) {
|
|
10309
10338
|
try {
|
|
10310
|
-
const
|
|
10311
|
-
return
|
|
10339
|
+
const hostname6 = new URL(value).hostname.toLowerCase();
|
|
10340
|
+
return hostname6 === "www.greatarrowdigital.com" || hostname6 === "greatarrowdigital.com";
|
|
10312
10341
|
} catch {
|
|
10313
10342
|
return false;
|
|
10314
10343
|
}
|
|
@@ -10328,10 +10357,10 @@ function maskToken(token) {
|
|
|
10328
10357
|
}
|
|
10329
10358
|
function openBrowser(url2) {
|
|
10330
10359
|
if (!/^https?:\/\//i.test(url2)) return Promise.resolve(false);
|
|
10331
|
-
return new Promise((
|
|
10360
|
+
return new Promise((resolve5) => {
|
|
10332
10361
|
const platform2 = process.platform;
|
|
10333
10362
|
const [cmd, args] = platform2 === "darwin" ? ["open", [url2]] : platform2 === "win32" ? ["cmd", ["/c", "start", "", url2]] : ["xdg-open", [url2]];
|
|
10334
|
-
execFile(cmd, args, (error62) =>
|
|
10363
|
+
execFile(cmd, args, (error62) => resolve5(!error62));
|
|
10335
10364
|
});
|
|
10336
10365
|
}
|
|
10337
10366
|
var loginCommand = new Command("login").description("Authenticate the CLI with your Great Arrow Digital account").option(
|
|
@@ -10394,8 +10423,8 @@ var loginCommand = new Command("login").description("Authenticate the CLI with y
|
|
|
10394
10423
|
fmt.success(
|
|
10395
10424
|
"Signed in. Your session will refresh automatically \u2014 no need to log in again."
|
|
10396
10425
|
);
|
|
10397
|
-
} catch (
|
|
10398
|
-
const msg =
|
|
10426
|
+
} catch (err2) {
|
|
10427
|
+
const msg = err2 instanceof Error ? err2.message : String(err2);
|
|
10399
10428
|
fmt.error(`Login failed: ${msg}`);
|
|
10400
10429
|
fmt.info(
|
|
10401
10430
|
`You can also run \`gad login --token <token>\` with a token from ${apiUrl}/install/cli`
|
|
@@ -10436,8 +10465,8 @@ async function acquireRefreshLock() {
|
|
|
10436
10465
|
const path10 = refreshLockPath();
|
|
10437
10466
|
try {
|
|
10438
10467
|
await mkdir3(join4(homedir4(), ".great-arrow"), { recursive: true });
|
|
10439
|
-
} catch (
|
|
10440
|
-
debugSwallow("refresh-lock.mkdir",
|
|
10468
|
+
} catch (err2) {
|
|
10469
|
+
debugSwallow("refresh-lock.mkdir", err2);
|
|
10441
10470
|
}
|
|
10442
10471
|
const deadline = Date.now() + REFRESH_LOCK_WAIT_MS;
|
|
10443
10472
|
for (; ; ) {
|
|
@@ -10446,8 +10475,8 @@ async function acquireRefreshLock() {
|
|
|
10446
10475
|
await handle.writeFile(String(process.pid));
|
|
10447
10476
|
await handle.close();
|
|
10448
10477
|
return true;
|
|
10449
|
-
} catch (
|
|
10450
|
-
if (
|
|
10478
|
+
} catch (err2) {
|
|
10479
|
+
if (err2.code !== "EEXIST") {
|
|
10451
10480
|
throw networkError(
|
|
10452
10481
|
"Could not lock session renewal.",
|
|
10453
10482
|
"Check local credential storage and retry; your session has been kept."
|
|
@@ -10458,8 +10487,8 @@ async function acquireRefreshLock() {
|
|
|
10458
10487
|
if (age > REFRESH_LOCK_STALE_MS) {
|
|
10459
10488
|
try {
|
|
10460
10489
|
await rm(path10, { force: true });
|
|
10461
|
-
} catch (
|
|
10462
|
-
debugSwallow("refresh-lock.stale-rm",
|
|
10490
|
+
} catch (err2) {
|
|
10491
|
+
debugSwallow("refresh-lock.stale-rm", err2);
|
|
10463
10492
|
}
|
|
10464
10493
|
continue;
|
|
10465
10494
|
}
|
|
@@ -10470,16 +10499,16 @@ async function acquireRefreshLock() {
|
|
|
10470
10499
|
async function releaseRefreshLock() {
|
|
10471
10500
|
try {
|
|
10472
10501
|
await rm(refreshLockPath(), { force: true });
|
|
10473
|
-
} catch (
|
|
10474
|
-
debugSwallow("refresh-lock.release",
|
|
10502
|
+
} catch (err2) {
|
|
10503
|
+
debugSwallow("refresh-lock.release", err2);
|
|
10475
10504
|
}
|
|
10476
10505
|
}
|
|
10477
10506
|
async function storedPairOtherThan(ours) {
|
|
10478
10507
|
let stored = null;
|
|
10479
10508
|
try {
|
|
10480
10509
|
stored = await loadStoredCredential();
|
|
10481
|
-
} catch (
|
|
10482
|
-
debugSwallow("refresh.reread",
|
|
10510
|
+
} catch (err2) {
|
|
10511
|
+
debugSwallow("refresh.reread", err2);
|
|
10483
10512
|
}
|
|
10484
10513
|
if (stored?.kind !== "oauth") {
|
|
10485
10514
|
throw authError(
|
|
@@ -10643,8 +10672,8 @@ async function doRefresh(credential) {
|
|
|
10643
10672
|
);
|
|
10644
10673
|
}
|
|
10645
10674
|
return refreshed;
|
|
10646
|
-
} catch (
|
|
10647
|
-
if (
|
|
10675
|
+
} catch (err2) {
|
|
10676
|
+
if (err2 instanceof RefreshRejected) {
|
|
10648
10677
|
const theirs = await storedPairOtherThan(current);
|
|
10649
10678
|
if (theirs) {
|
|
10650
10679
|
if (Date.now() < theirs.accessExpiresAt) return theirs;
|
|
@@ -10656,7 +10685,7 @@ async function doRefresh(credential) {
|
|
|
10656
10685
|
await clearStoredCredential();
|
|
10657
10686
|
throw sessionExpired();
|
|
10658
10687
|
}
|
|
10659
|
-
throw
|
|
10688
|
+
throw err2;
|
|
10660
10689
|
} finally {
|
|
10661
10690
|
if (held) await releaseRefreshLock();
|
|
10662
10691
|
}
|
|
@@ -10943,14 +10972,14 @@ function luhnValid(candidate) {
|
|
|
10943
10972
|
}
|
|
10944
10973
|
var SECRET_TOKEN_RE = /\b(?:gad_[A-Za-z0-9_-]{20,}|sk-[A-Za-z0-9-]{20,}|Bearer\s+[A-Za-z0-9._~+/=-]{8,})\b/gi;
|
|
10945
10974
|
var SENSITIVE_QUERY_VALUE_RE = /((?:^|[?&])(?:code|token|token_hash|data_step_token|passkey_proof|access_token|refresh_token|id_token|api_key|apikey|api_secret|apisecret|key|secret|client_secret|password|state|sig|signature|t)=)[^&#\s]+/gi;
|
|
10946
|
-
function scrubPiiFromText(
|
|
10947
|
-
return
|
|
10975
|
+
function scrubPiiFromText(s2) {
|
|
10976
|
+
return s2.replace(EMAIL_RE, "[redacted-email]").replace(
|
|
10948
10977
|
CREDIT_CARD_RE,
|
|
10949
10978
|
(m) => luhnValid(m) ? "[redacted-credit-card]" : m
|
|
10950
10979
|
).replace(SSN_RE, "[redacted-ssn]").replace(PHONE_RE, "[redacted-phone]");
|
|
10951
10980
|
}
|
|
10952
|
-
function scrubTelemetryText(
|
|
10953
|
-
return scrubPiiFromText(
|
|
10981
|
+
function scrubTelemetryText(s2) {
|
|
10982
|
+
return scrubPiiFromText(s2).replace(SENSITIVE_QUERY_VALUE_RE, "$1[redacted]").replace(
|
|
10954
10983
|
SECRET_TOKEN_RE,
|
|
10955
10984
|
(match) => match.toLowerCase().startsWith("bearer ") ? "Bearer [redacted]" : "[redacted-secret]"
|
|
10956
10985
|
);
|
|
@@ -10979,11 +11008,11 @@ function redact(value, depth = 0) {
|
|
|
10979
11008
|
if (Array.isArray(value))
|
|
10980
11009
|
return value.slice(0, 20).map((v) => redact(v, depth + 1));
|
|
10981
11010
|
if (value && typeof value === "object") {
|
|
10982
|
-
const
|
|
11011
|
+
const out2 = {};
|
|
10983
11012
|
for (const [key, v] of Object.entries(value).slice(0, 30)) {
|
|
10984
|
-
|
|
11013
|
+
out2[key] = /token|secret|password|authorization|cookie|email/i.test(key) ? "[redacted]" : redact(v, depth + 1);
|
|
10985
11014
|
}
|
|
10986
|
-
return
|
|
11015
|
+
return out2;
|
|
10987
11016
|
}
|
|
10988
11017
|
return value;
|
|
10989
11018
|
}
|
|
@@ -11026,8 +11055,8 @@ async function captureCliEvent(input2) {
|
|
|
11026
11055
|
);
|
|
11027
11056
|
if (!response.ok)
|
|
11028
11057
|
debugSwallow("telemetry.send", new Error(`HTTP ${response.status}`));
|
|
11029
|
-
} catch (
|
|
11030
|
-
debugSwallow("telemetry.send",
|
|
11058
|
+
} catch (err2) {
|
|
11059
|
+
debugSwallow("telemetry.send", err2);
|
|
11031
11060
|
}
|
|
11032
11061
|
}
|
|
11033
11062
|
|
|
@@ -11043,8 +11072,8 @@ function getCommandWorkspaceTarget(options = {}) {
|
|
|
11043
11072
|
}
|
|
11044
11073
|
|
|
11045
11074
|
// ../local-runtime/src/abortable.ts
|
|
11046
|
-
function abortable(
|
|
11047
|
-
return new Promise((
|
|
11075
|
+
function abortable(run3, signal) {
|
|
11076
|
+
return new Promise((resolve5, reject) => {
|
|
11048
11077
|
const abort = () => {
|
|
11049
11078
|
signal.removeEventListener("abort", abort);
|
|
11050
11079
|
reject(signal.reason ?? new Error("Local operation stopped"));
|
|
@@ -11053,11 +11082,11 @@ function abortable(run2, signal) {
|
|
|
11053
11082
|
signal.addEventListener("abort", abort, { once: true });
|
|
11054
11083
|
Promise.resolve().then(() => {
|
|
11055
11084
|
signal.throwIfAborted();
|
|
11056
|
-
return
|
|
11057
|
-
}).then(
|
|
11085
|
+
return run3();
|
|
11086
|
+
}).then(resolve5, reject).finally(() => signal.removeEventListener("abort", abort));
|
|
11058
11087
|
});
|
|
11059
11088
|
}
|
|
11060
|
-
async function withLocalDeadline(deadlineMs,
|
|
11089
|
+
async function withLocalDeadline(deadlineMs, run3, parentSignal) {
|
|
11061
11090
|
if (!Number.isSafeInteger(deadlineMs) || deadlineMs <= 0 || deadlineMs > 36e5)
|
|
11062
11091
|
throw new Error("Invalid local operation deadline");
|
|
11063
11092
|
const controller = new AbortController();
|
|
@@ -11067,7 +11096,7 @@ async function withLocalDeadline(deadlineMs, run2, parentSignal) {
|
|
|
11067
11096
|
deadlineMs
|
|
11068
11097
|
);
|
|
11069
11098
|
try {
|
|
11070
|
-
return await abortable(() =>
|
|
11099
|
+
return await abortable(() => run3(signal), signal);
|
|
11071
11100
|
} finally {
|
|
11072
11101
|
clearTimeout(timer);
|
|
11073
11102
|
}
|
|
@@ -11313,7 +11342,7 @@ function describeError(error62) {
|
|
|
11313
11342
|
return String(error62);
|
|
11314
11343
|
}
|
|
11315
11344
|
function sleep(ms) {
|
|
11316
|
-
return new Promise((
|
|
11345
|
+
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
11317
11346
|
}
|
|
11318
11347
|
var GadClient = class {
|
|
11319
11348
|
token;
|
|
@@ -11438,16 +11467,22 @@ var GadClient = class {
|
|
|
11438
11467
|
const status = response.status;
|
|
11439
11468
|
const body = await response.text().catch(() => "");
|
|
11440
11469
|
if (status === 403) {
|
|
11441
|
-
throw
|
|
11442
|
-
|
|
11443
|
-
|
|
11444
|
-
|
|
11470
|
+
throw withServerCode(
|
|
11471
|
+
new CliError(
|
|
11472
|
+
"Permission denied (HTTP 403).",
|
|
11473
|
+
1 /* AUTH_ERROR */,
|
|
11474
|
+
"Check this connection's scopes and workspace permissions at /account/connections."
|
|
11475
|
+
),
|
|
11476
|
+
body
|
|
11445
11477
|
);
|
|
11446
11478
|
}
|
|
11447
11479
|
if (status === 401) {
|
|
11448
|
-
throw
|
|
11449
|
-
|
|
11450
|
-
|
|
11480
|
+
throw withServerCode(
|
|
11481
|
+
authError(
|
|
11482
|
+
`Authentication failed (HTTP ${status}).`,
|
|
11483
|
+
"Run 'gad login' to re-authenticate, or check your GAD_TOKEN."
|
|
11484
|
+
),
|
|
11485
|
+
body
|
|
11451
11486
|
);
|
|
11452
11487
|
}
|
|
11453
11488
|
if (status >= 500) {
|
|
@@ -11457,10 +11492,13 @@ var GadClient = class {
|
|
|
11457
11492
|
);
|
|
11458
11493
|
}
|
|
11459
11494
|
const message = body ? `Request failed (HTTP ${status}): ${body.slice(0, 200)}` : `Request failed (HTTP ${status}).`;
|
|
11460
|
-
throw
|
|
11461
|
-
|
|
11462
|
-
|
|
11463
|
-
|
|
11495
|
+
throw withServerCode(
|
|
11496
|
+
new CliError(
|
|
11497
|
+
message,
|
|
11498
|
+
mapErrorToExitCode(status),
|
|
11499
|
+
"Check the command usage with --help."
|
|
11500
|
+
),
|
|
11501
|
+
body
|
|
11464
11502
|
);
|
|
11465
11503
|
}
|
|
11466
11504
|
/**
|
|
@@ -11685,6 +11723,38 @@ var GadClient = class {
|
|
|
11685
11723
|
}
|
|
11686
11724
|
return this.handleResponse(response);
|
|
11687
11725
|
}
|
|
11726
|
+
/**
|
|
11727
|
+
* Make a DELETE request to a REST API endpoint. Like POST, it is retried
|
|
11728
|
+
* only when the connection never reached the server.
|
|
11729
|
+
*/
|
|
11730
|
+
async delete(path10) {
|
|
11731
|
+
const url2 = `${this.apiUrl}${path10}`;
|
|
11732
|
+
const headers = this.buildHeaders();
|
|
11733
|
+
delete headers["Content-Type"];
|
|
11734
|
+
let response;
|
|
11735
|
+
try {
|
|
11736
|
+
response = await this.fetchWithRetry(
|
|
11737
|
+
url2,
|
|
11738
|
+
{ method: "DELETE", headers },
|
|
11739
|
+
void 0,
|
|
11740
|
+
"connection-only"
|
|
11741
|
+
);
|
|
11742
|
+
} catch (error62) {
|
|
11743
|
+
if (error62 instanceof CliError) throw error62;
|
|
11744
|
+
void captureCliEvent({
|
|
11745
|
+
apiUrl: this.apiUrl,
|
|
11746
|
+
token: this.token,
|
|
11747
|
+
name: "network_error",
|
|
11748
|
+
error: error62,
|
|
11749
|
+
context: { method: "DELETE", path: path10 }
|
|
11750
|
+
});
|
|
11751
|
+
throw networkError(
|
|
11752
|
+
`Network error on DELETE ${path10}.`,
|
|
11753
|
+
"Check your internet connection or run 'gad doctor'."
|
|
11754
|
+
);
|
|
11755
|
+
}
|
|
11756
|
+
return this.handleResponse(response);
|
|
11757
|
+
}
|
|
11688
11758
|
};
|
|
11689
11759
|
|
|
11690
11760
|
// src/lib/global-opts.ts
|
|
@@ -11778,10 +11848,10 @@ ${tryThese.map((t) => ` \u2022 ${t}`).join("\n")}`
|
|
|
11778
11848
|
|
|
11779
11849
|
// src/lib/stdin.ts
|
|
11780
11850
|
function readStream(stream) {
|
|
11781
|
-
return new Promise((
|
|
11851
|
+
return new Promise((resolve5, reject) => {
|
|
11782
11852
|
const chunks = [];
|
|
11783
11853
|
stream.on("data", (chunk) => chunks.push(chunk));
|
|
11784
|
-
stream.on("end", () =>
|
|
11854
|
+
stream.on("end", () => resolve5(Buffer.concat(chunks).toString("utf8")));
|
|
11785
11855
|
stream.on("error", reject);
|
|
11786
11856
|
});
|
|
11787
11857
|
}
|
|
@@ -12323,8 +12393,8 @@ function text(value) {
|
|
|
12323
12393
|
}
|
|
12324
12394
|
function formatTodoDetail(todo) {
|
|
12325
12395
|
const assignees = Array.isArray(todo.assignees) ? todo.assignees.map((a) => `${text(a.displayName)} (${text(a.type)})`).join(", ") : "";
|
|
12326
|
-
const
|
|
12327
|
-
const lastRun =
|
|
12396
|
+
const run3 = todo.lastRun ?? null;
|
|
12397
|
+
const lastRun = run3 ? `${text(run3.status)} \u2014 ${text(run3.agentName)}` : "";
|
|
12328
12398
|
return {
|
|
12329
12399
|
id: text(todo.id),
|
|
12330
12400
|
title: text(todo.title),
|
|
@@ -12460,8 +12530,8 @@ var todo_default = todoCommand;
|
|
|
12460
12530
|
import { execFileSync } from "node:child_process";
|
|
12461
12531
|
|
|
12462
12532
|
// src/lib/claim-preflight.ts
|
|
12463
|
-
function normalize(
|
|
12464
|
-
return
|
|
12533
|
+
function normalize(s2) {
|
|
12534
|
+
return s2.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
|
|
12465
12535
|
}
|
|
12466
12536
|
function mentions(haystack, normSlug) {
|
|
12467
12537
|
if (!haystack || !normSlug) return false;
|
|
@@ -12549,8 +12619,8 @@ var claimCommand = new Command("claim").description("Preflight + atomically clai
|
|
|
12549
12619
|
todos.push(
|
|
12550
12620
|
...asArray(await client2.mcpCall("todo_list", { status }))
|
|
12551
12621
|
);
|
|
12552
|
-
} catch (
|
|
12553
|
-
debugSwallow(`claim.preflight(${status})`,
|
|
12622
|
+
} catch (err2) {
|
|
12623
|
+
debugSwallow(`claim.preflight(${status})`, err2);
|
|
12554
12624
|
}
|
|
12555
12625
|
}
|
|
12556
12626
|
let activeClaims = [];
|
|
@@ -12559,8 +12629,8 @@ var claimCommand = new Command("claim").description("Preflight + atomically clai
|
|
|
12559
12629
|
activeClaims = Array.isArray(
|
|
12560
12630
|
intro?.activeClaims
|
|
12561
12631
|
) ? intro.activeClaims : [];
|
|
12562
|
-
} catch (
|
|
12563
|
-
debugSwallow("claim.preflight(introspect)",
|
|
12632
|
+
} catch (err2) {
|
|
12633
|
+
debugSwallow("claim.preflight(introspect)", err2);
|
|
12564
12634
|
activeClaims = [];
|
|
12565
12635
|
}
|
|
12566
12636
|
const conflicts = findPreflightConflicts({
|
|
@@ -12649,8 +12719,8 @@ function run(command, args, cwd) {
|
|
|
12649
12719
|
timeout: LOCAL_COMMAND_TIMEOUT_MS
|
|
12650
12720
|
});
|
|
12651
12721
|
return { status: 0, stdout, stderr: "", timedOut: false };
|
|
12652
|
-
} catch (
|
|
12653
|
-
const e =
|
|
12722
|
+
} catch (err2) {
|
|
12723
|
+
const e = err2;
|
|
12654
12724
|
return {
|
|
12655
12725
|
status: e.status ?? 1,
|
|
12656
12726
|
stdout: e.stdout ?? "",
|
|
@@ -12665,7 +12735,7 @@ function git(args, cwd) {
|
|
|
12665
12735
|
var WORKTREE_STATUS_CONCURRENCY = 8;
|
|
12666
12736
|
var WORKTREE_STATUS_TIMEOUT_MS = 2e3;
|
|
12667
12737
|
function gitAsync(args, cwd) {
|
|
12668
|
-
return new Promise((
|
|
12738
|
+
return new Promise((resolve5) => {
|
|
12669
12739
|
execFile2(
|
|
12670
12740
|
"git",
|
|
12671
12741
|
args,
|
|
@@ -12676,7 +12746,7 @@ function gitAsync(args, cwd) {
|
|
|
12676
12746
|
timeout: WORKTREE_STATUS_TIMEOUT_MS
|
|
12677
12747
|
},
|
|
12678
12748
|
(error62, stdout, stderr) => {
|
|
12679
|
-
|
|
12749
|
+
resolve5({
|
|
12680
12750
|
status: error62 ? 1 : 0,
|
|
12681
12751
|
stdout: stdout ?? "",
|
|
12682
12752
|
stderr: stderr ?? "",
|
|
@@ -13181,12 +13251,12 @@ import { execFileSync as execFileSync3 } from "node:child_process";
|
|
|
13181
13251
|
import { existsSync, readFileSync as readFileSync2, statSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
13182
13252
|
import { basename, dirname as dirname3, isAbsolute, join as join5, resolve } from "node:path";
|
|
13183
13253
|
var realExec = (cmd, args, opts) => {
|
|
13184
|
-
const
|
|
13254
|
+
const out2 = execFileSync3(cmd, args, {
|
|
13185
13255
|
cwd: opts?.cwd,
|
|
13186
13256
|
encoding: "utf8",
|
|
13187
13257
|
stdio: opts?.inherit ? ["ignore", "inherit", "inherit"] : ["ignore", "pipe", "pipe"]
|
|
13188
13258
|
});
|
|
13189
|
-
return typeof
|
|
13259
|
+
return typeof out2 === "string" ? out2 : "";
|
|
13190
13260
|
};
|
|
13191
13261
|
function assertCleanTree(statusPorcelain) {
|
|
13192
13262
|
if (statusPorcelain.trim().length === 0) return;
|
|
@@ -14478,19 +14548,19 @@ function collectConfiguredHooks(scope, file2, content) {
|
|
|
14478
14548
|
}
|
|
14479
14549
|
const hooks = asObject(asObject(parsed)?.hooks ?? null);
|
|
14480
14550
|
if (!hooks) return [];
|
|
14481
|
-
const
|
|
14551
|
+
const out2 = [];
|
|
14482
14552
|
for (const [event, groups] of Object.entries(hooks)) {
|
|
14483
14553
|
if (!Array.isArray(groups)) continue;
|
|
14484
14554
|
for (const group of groups) {
|
|
14485
14555
|
if (!group || !Array.isArray(group.hooks)) continue;
|
|
14486
14556
|
for (const hook of group.hooks) {
|
|
14487
14557
|
if (hook && typeof hook.command === "string" && hook.command.trim()) {
|
|
14488
|
-
|
|
14558
|
+
out2.push({ scope, file: file2, event, command: hook.command });
|
|
14489
14559
|
}
|
|
14490
14560
|
}
|
|
14491
14561
|
}
|
|
14492
14562
|
}
|
|
14493
|
-
return
|
|
14563
|
+
return out2;
|
|
14494
14564
|
}
|
|
14495
14565
|
function nodeScriptTarget(command) {
|
|
14496
14566
|
const m = command.match(/\bnode\s+(?:"([^"]+)"|'([^']+)'|(\S+))/);
|
|
@@ -14785,11 +14855,11 @@ async function ensureHookCredential(opts) {
|
|
|
14785
14855
|
status: verified ? "pass" : "fail",
|
|
14786
14856
|
message: verified ? "Rewritten token authenticates" : `Rewritten token still failing (HTTP ${status})`
|
|
14787
14857
|
});
|
|
14788
|
-
} catch (
|
|
14858
|
+
} catch (err2) {
|
|
14789
14859
|
checks.push({
|
|
14790
14860
|
name: "Hook credential: after repair",
|
|
14791
14861
|
status: "warn",
|
|
14792
|
-
message: `Rewrote the token but could not re-probe it (${
|
|
14862
|
+
message: `Rewrote the token but could not re-probe it (${err2 instanceof Error ? err2.message : String(err2)})`,
|
|
14793
14863
|
hint: "Re-run `gad doctor` once the network is reachable to confirm."
|
|
14794
14864
|
});
|
|
14795
14865
|
}
|
|
@@ -16335,9 +16405,9 @@ async function resolveBridgeAuth(options = {}) {
|
|
|
16335
16405
|
apiUrl: (apiUrlOverride || stored.apiUrl).replace(/\/$/, ""),
|
|
16336
16406
|
source: "stored"
|
|
16337
16407
|
};
|
|
16338
|
-
} catch (
|
|
16339
|
-
if (
|
|
16340
|
-
throw
|
|
16408
|
+
} catch (err2) {
|
|
16409
|
+
if (err2 instanceof CliError && err2.code === 1 /* AUTH_ERROR */ && /expired/i.test(err2.message)) {
|
|
16410
|
+
throw err2;
|
|
16341
16411
|
}
|
|
16342
16412
|
throw missingTokenError();
|
|
16343
16413
|
}
|
|
@@ -16429,9 +16499,9 @@ async function forwardLine(line, config2) {
|
|
|
16429
16499
|
return rpcError(id, -32603, "Upstream MCP endpoint returned non-JSON");
|
|
16430
16500
|
}
|
|
16431
16501
|
return text3.trim();
|
|
16432
|
-
} catch (
|
|
16502
|
+
} catch (err2) {
|
|
16433
16503
|
if (isNotification) return null;
|
|
16434
|
-
const message =
|
|
16504
|
+
const message = err2 instanceof Error ? err2.message : String(err2);
|
|
16435
16505
|
return rpcError(
|
|
16436
16506
|
id,
|
|
16437
16507
|
-32603,
|
|
@@ -16472,8 +16542,8 @@ async function runStdioBridge(options) {
|
|
|
16472
16542
|
if (response) writeLine(response);
|
|
16473
16543
|
});
|
|
16474
16544
|
});
|
|
16475
|
-
await new Promise((
|
|
16476
|
-
rl.on("close", () =>
|
|
16545
|
+
await new Promise((resolve5) => {
|
|
16546
|
+
rl.on("close", () => resolve5());
|
|
16477
16547
|
});
|
|
16478
16548
|
}
|
|
16479
16549
|
|
|
@@ -16506,7 +16576,7 @@ async function enableSuggestTools(home, deps = {}) {
|
|
|
16506
16576
|
return { verified: credential.verified };
|
|
16507
16577
|
}
|
|
16508
16578
|
async function applySuggestToolsChoice(choice2, home = homedir6(), deps = {}) {
|
|
16509
|
-
const
|
|
16579
|
+
const out2 = deps.out ?? createFormatter({
|
|
16510
16580
|
json: false,
|
|
16511
16581
|
quiet: false,
|
|
16512
16582
|
isTTY: isTTY(),
|
|
@@ -16516,7 +16586,7 @@ async function applySuggestToolsChoice(choice2, home = homedir6(), deps = {}) {
|
|
|
16516
16586
|
const outcome = await runSuggestHookOptIn({
|
|
16517
16587
|
choice: choice2,
|
|
16518
16588
|
interactive: deps.interactive ?? Boolean(process.stdin.isTTY && process.stdout.isTTY),
|
|
16519
|
-
print: (line) =>
|
|
16589
|
+
print: (line) => out2.info(line),
|
|
16520
16590
|
confirm: deps.confirm ?? confirm,
|
|
16521
16591
|
enable: async () => {
|
|
16522
16592
|
verified = (await enableSuggestTools(home, deps)).verified;
|
|
@@ -16525,10 +16595,10 @@ async function applySuggestToolsChoice(choice2, home = homedir6(), deps = {}) {
|
|
|
16525
16595
|
});
|
|
16526
16596
|
const { settingsPath } = suggestHookPaths(home);
|
|
16527
16597
|
if (outcome === "enabled") {
|
|
16528
|
-
|
|
16529
|
-
if (!verified)
|
|
16598
|
+
out2.success(`Tool suggestions ON (registered in ${settingsPath}).`);
|
|
16599
|
+
if (!verified) out2.warn(HOOK_CREDENTIAL_FIX_LINE);
|
|
16530
16600
|
} else if (outcome === "disabled") {
|
|
16531
|
-
|
|
16601
|
+
out2.success("Tool suggestions OFF (our hook entry removed).");
|
|
16532
16602
|
}
|
|
16533
16603
|
return outcome;
|
|
16534
16604
|
}
|
|
@@ -16596,12 +16666,12 @@ var CLIENT_IDS = {
|
|
|
16596
16666
|
};
|
|
16597
16667
|
async function mcpJsonAtRiskOfCommit(dir) {
|
|
16598
16668
|
try {
|
|
16599
|
-
const { execFile:
|
|
16669
|
+
const { execFile: execFile5 } = await import("node:child_process");
|
|
16600
16670
|
const { promisify: promisify2 } = await import("node:util");
|
|
16601
|
-
const
|
|
16602
|
-
await
|
|
16671
|
+
const run3 = promisify2(execFile5);
|
|
16672
|
+
await run3("git", ["rev-parse", "--is-inside-work-tree"], { cwd: dir });
|
|
16603
16673
|
try {
|
|
16604
|
-
await
|
|
16674
|
+
await run3("git", ["check-ignore", "-q", ".mcp.json"], { cwd: dir });
|
|
16605
16675
|
return false;
|
|
16606
16676
|
} catch {
|
|
16607
16677
|
return true;
|
|
@@ -16691,33 +16761,33 @@ async function pathExists(path10) {
|
|
|
16691
16761
|
}
|
|
16692
16762
|
}
|
|
16693
16763
|
async function installCodexConfig(apiUrl, token, repoUrl) {
|
|
16694
|
-
const { homedir:
|
|
16695
|
-
const { join:
|
|
16696
|
-
const { chmod:
|
|
16697
|
-
const codexDir =
|
|
16698
|
-
const configPath =
|
|
16699
|
-
const envPath =
|
|
16764
|
+
const { homedir: homedir11 } = await import("node:os");
|
|
16765
|
+
const { join: join13 } = await import("node:path");
|
|
16766
|
+
const { chmod: chmod3, copyFile: copyFile3, mkdir: mkdir9, readFile: readFile9, writeFile: writeFile7 } = await import("node:fs/promises");
|
|
16767
|
+
const codexDir = join13(homedir11(), ".codex");
|
|
16768
|
+
const configPath = join13(codexDir, "config.toml");
|
|
16769
|
+
const envPath = join13(codexDir, ".env");
|
|
16700
16770
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
16701
|
-
await
|
|
16702
|
-
const existingConfig = await pathExists(configPath) ? await
|
|
16771
|
+
await mkdir9(codexDir, { recursive: true });
|
|
16772
|
+
const existingConfig = await pathExists(configPath) ? await readFile9(configPath, "utf8") : "";
|
|
16703
16773
|
if (existingConfig.trim()) {
|
|
16704
16774
|
await copyFile3(configPath, `${configPath}.bak.${timestamp}`);
|
|
16705
16775
|
}
|
|
16706
|
-
await
|
|
16776
|
+
await writeFile7(
|
|
16707
16777
|
configPath,
|
|
16708
16778
|
upsertCodexServerBlock(existingConfig, apiUrl, repoUrl),
|
|
16709
16779
|
"utf8"
|
|
16710
16780
|
);
|
|
16711
|
-
const existingEnv = await pathExists(envPath) ? await
|
|
16781
|
+
const existingEnv = await pathExists(envPath) ? await readFile9(envPath, "utf8") : "";
|
|
16712
16782
|
if (existingEnv.trim()) {
|
|
16713
16783
|
await copyFile3(envPath, `${envPath}.bak.${timestamp}`);
|
|
16714
16784
|
}
|
|
16715
|
-
await
|
|
16785
|
+
await writeFile7(
|
|
16716
16786
|
envPath,
|
|
16717
16787
|
upsertEnvValue(existingEnv, "GREAT_ARROW_TOKEN", token),
|
|
16718
16788
|
"utf8"
|
|
16719
16789
|
);
|
|
16720
|
-
await
|
|
16790
|
+
await chmod3(envPath, 384);
|
|
16721
16791
|
return { configPath, envPath };
|
|
16722
16792
|
}
|
|
16723
16793
|
var startCommand = new Command("start").description(
|
|
@@ -16846,8 +16916,8 @@ async function checkDns(apiUrl, verbose, c) {
|
|
|
16846
16916
|
if (verbose) process.stdout.write(`${c.green("\u2713")}
|
|
16847
16917
|
`);
|
|
16848
16918
|
return { check: "DNS Resolution", status: "pass", detail: url2.hostname };
|
|
16849
|
-
} catch (
|
|
16850
|
-
const msg =
|
|
16919
|
+
} catch (err2) {
|
|
16920
|
+
const msg = err2 instanceof Error ? err2.message : "failed";
|
|
16851
16921
|
if (verbose) process.stdout.write(`${c.red("\u2717")} ${msg}
|
|
16852
16922
|
`);
|
|
16853
16923
|
return { check: "DNS Resolution", status: "fail", detail: msg };
|
|
@@ -16871,8 +16941,8 @@ async function checkEdgePing(apiUrl, verbose, c) {
|
|
|
16871
16941
|
if (verbose) process.stdout.write(`${c.yellow("\u26A0")} ${detail}
|
|
16872
16942
|
`);
|
|
16873
16943
|
return { check: "Edge Ping", status: "warn", detail };
|
|
16874
|
-
} catch (
|
|
16875
|
-
const msg =
|
|
16944
|
+
} catch (err2) {
|
|
16945
|
+
const msg = err2 instanceof Error ? err2.message : "failed";
|
|
16876
16946
|
if (verbose) process.stdout.write(`${c.red("\u2717")} ${msg}
|
|
16877
16947
|
`);
|
|
16878
16948
|
return { check: "Edge Ping", status: "fail", detail: msg };
|
|
@@ -16894,8 +16964,8 @@ async function checkJsonRpc(client2, verbose, c) {
|
|
|
16894
16964
|
if (verbose) process.stdout.write(`${c.green("\u2713")} ${detail}
|
|
16895
16965
|
`);
|
|
16896
16966
|
return { check: "JSON-RPC Handshake", status: "pass", detail };
|
|
16897
|
-
} catch (
|
|
16898
|
-
const msg =
|
|
16967
|
+
} catch (err2) {
|
|
16968
|
+
const msg = err2 instanceof Error ? err2.message : "failed";
|
|
16899
16969
|
if (verbose) process.stdout.write(`${c.red("\u2717")} ${msg}
|
|
16900
16970
|
`);
|
|
16901
16971
|
return { check: "JSON-RPC Handshake", status: "fail", detail: msg };
|
|
@@ -17005,15 +17075,15 @@ var installCommand = new Command("install").description("Generate MCP configurat
|
|
|
17005
17075
|
process.stdout.write(configJson2 + "\n");
|
|
17006
17076
|
return;
|
|
17007
17077
|
}
|
|
17008
|
-
const { homedir:
|
|
17009
|
-
const { join:
|
|
17010
|
-
const { mkdir:
|
|
17011
|
-
const geminiDir =
|
|
17012
|
-
const mcpPath =
|
|
17013
|
-
await
|
|
17078
|
+
const { homedir: homedir11 } = await import("node:os");
|
|
17079
|
+
const { join: join14 } = await import("node:path");
|
|
17080
|
+
const { mkdir: mkdir9, readFile: readFile9, writeFile: writeFile8 } = await import("node:fs/promises");
|
|
17081
|
+
const geminiDir = join14(homedir11(), ".gemini");
|
|
17082
|
+
const mcpPath = join14(geminiDir, "settings.json");
|
|
17083
|
+
await mkdir9(geminiDir, { recursive: true });
|
|
17014
17084
|
let existingConfig = {};
|
|
17015
17085
|
try {
|
|
17016
|
-
const content = await
|
|
17086
|
+
const content = await readFile9(mcpPath, "utf-8");
|
|
17017
17087
|
existingConfig = JSON.parse(content);
|
|
17018
17088
|
} catch {
|
|
17019
17089
|
existingConfig = {};
|
|
@@ -17025,20 +17095,20 @@ var installCommand = new Command("install").description("Generate MCP configurat
|
|
|
17025
17095
|
...config3.mcpServers
|
|
17026
17096
|
}
|
|
17027
17097
|
};
|
|
17028
|
-
await
|
|
17098
|
+
await writeFile8(
|
|
17029
17099
|
mcpPath,
|
|
17030
17100
|
JSON.stringify(existingConfig, null, 2) + "\n",
|
|
17031
17101
|
"utf-8"
|
|
17032
17102
|
);
|
|
17033
17103
|
fmt.success(`Wrote gemini MCP config to ${mcpPath}`);
|
|
17034
|
-
const agyMcpDir =
|
|
17104
|
+
const agyMcpDir = join14(
|
|
17035
17105
|
geminiDir,
|
|
17036
17106
|
"antigravity-cli",
|
|
17037
17107
|
"mcp",
|
|
17038
17108
|
MCP_SERVER_NAME
|
|
17039
17109
|
);
|
|
17040
|
-
await
|
|
17041
|
-
const instructionsPath =
|
|
17110
|
+
await mkdir9(agyMcpDir, { recursive: true });
|
|
17111
|
+
const instructionsPath = join14(agyMcpDir, "instructions.md");
|
|
17042
17112
|
const instructionsContent = `You are connected to greatarrow.ai - the user's private workspace memory + integrations brain.
|
|
17043
17113
|
|
|
17044
17114
|
CRITICAL DIRECTIVE (MANDATORY STANDARD):
|
|
@@ -17054,7 +17124,7 @@ THREE-LAYER LIVE TASK TRACKING:
|
|
|
17054
17124
|
- Maintain client-native harness plans, Great Arrow Kanban cards (\`todo_create\`, \`todo_update\`), and resume states.
|
|
17055
17125
|
|
|
17056
17126
|
Always assume full autonomy to leverage these tools to their maximum extent.`;
|
|
17057
|
-
await
|
|
17127
|
+
await writeFile8(instructionsPath, instructionsContent, "utf-8");
|
|
17058
17128
|
fmt.success(`Wrote gemini MCP instructions to ${instructionsPath}`);
|
|
17059
17129
|
return;
|
|
17060
17130
|
}
|
|
@@ -17069,10 +17139,10 @@ Always assume full autonomy to leverage these tools to their maximum extent.`;
|
|
|
17069
17139
|
process.stdout.write(configJson + "\n");
|
|
17070
17140
|
return;
|
|
17071
17141
|
}
|
|
17072
|
-
const { writeFile:
|
|
17073
|
-
const { join:
|
|
17074
|
-
const outputPath =
|
|
17075
|
-
await
|
|
17142
|
+
const { writeFile: writeFile7 } = await import("node:fs/promises");
|
|
17143
|
+
const { join: join13 } = await import("node:path");
|
|
17144
|
+
const outputPath = join13(process.cwd(), ".mcp.json");
|
|
17145
|
+
await writeFile7(outputPath, configJson + "\n", { mode: 384 });
|
|
17076
17146
|
fmt.success(`Wrote ${clientName} MCP config to .mcp.json`);
|
|
17077
17147
|
if (await mcpJsonAtRiskOfCommit(process.cwd())) {
|
|
17078
17148
|
fmt.warn(
|
|
@@ -17088,9 +17158,9 @@ var KEYCHAIN_SERVICE = "GreatArrowDigital";
|
|
|
17088
17158
|
var KEYCHAIN_ACCOUNT = "api-token";
|
|
17089
17159
|
var OAUTH_CRED_FILENAME = "oauth-credential.json";
|
|
17090
17160
|
async function readIfExists(path10) {
|
|
17091
|
-
const { readFile:
|
|
17161
|
+
const { readFile: readFile9 } = await import("node:fs/promises");
|
|
17092
17162
|
try {
|
|
17093
|
-
return await
|
|
17163
|
+
return await readFile9(path10, "utf8");
|
|
17094
17164
|
} catch {
|
|
17095
17165
|
return null;
|
|
17096
17166
|
}
|
|
@@ -17105,13 +17175,13 @@ async function readKeychainOnly() {
|
|
|
17105
17175
|
}
|
|
17106
17176
|
}
|
|
17107
17177
|
async function resolveProxyScript(override) {
|
|
17108
|
-
const { homedir:
|
|
17109
|
-
const { join:
|
|
17178
|
+
const { homedir: homedir11 } = await import("node:os");
|
|
17179
|
+
const { join: join13 } = await import("node:path");
|
|
17110
17180
|
const candidates = [
|
|
17111
17181
|
override,
|
|
17112
17182
|
process.env.GAD_PROXY_SCRIPT,
|
|
17113
|
-
|
|
17114
|
-
|
|
17183
|
+
join13(homedir11(), ".great-arrow", "mcp-server.mjs"),
|
|
17184
|
+
join13(process.cwd(), "scripts", "mcp-server.mjs")
|
|
17115
17185
|
].filter((c) => Boolean(c));
|
|
17116
17186
|
for (const candidate of candidates) {
|
|
17117
17187
|
if (await pathExists(candidate)) return candidate;
|
|
@@ -17119,11 +17189,11 @@ async function resolveProxyScript(override) {
|
|
|
17119
17189
|
return null;
|
|
17120
17190
|
}
|
|
17121
17191
|
async function runProxyDiagnostics(scriptPath) {
|
|
17122
|
-
const { execFile:
|
|
17192
|
+
const { execFile: execFile5 } = await import("node:child_process");
|
|
17123
17193
|
const { promisify: promisify2 } = await import("node:util");
|
|
17124
|
-
const
|
|
17194
|
+
const run3 = promisify2(execFile5);
|
|
17125
17195
|
try {
|
|
17126
|
-
const { stdout } = await
|
|
17196
|
+
const { stdout } = await run3(
|
|
17127
17197
|
process.execPath,
|
|
17128
17198
|
[scriptPath, "--print-diagnostics"],
|
|
17129
17199
|
{ timeout: 1e4, maxBuffer: 1024 * 1024 }
|
|
@@ -17135,22 +17205,22 @@ async function runProxyDiagnostics(scriptPath) {
|
|
|
17135
17205
|
}
|
|
17136
17206
|
}
|
|
17137
17207
|
async function findLegacyStores(cwd) {
|
|
17138
|
-
const { join:
|
|
17208
|
+
const { join: join13 } = await import("node:path");
|
|
17139
17209
|
const { readdir } = await import("node:fs/promises");
|
|
17140
17210
|
const dirs = /* @__PURE__ */ new Set([cwd]);
|
|
17141
17211
|
try {
|
|
17142
|
-
const worktreeRoot =
|
|
17212
|
+
const worktreeRoot = join13(cwd, ".claude", "worktrees");
|
|
17143
17213
|
for (const entry of await readdir(worktreeRoot, { withFileTypes: true })) {
|
|
17144
|
-
if (entry.isDirectory()) dirs.add(
|
|
17214
|
+
if (entry.isDirectory()) dirs.add(join13(worktreeRoot, entry.name));
|
|
17145
17215
|
}
|
|
17146
|
-
} catch (
|
|
17147
|
-
debugSwallow("mcp.findLegacyStores(worktrees)",
|
|
17216
|
+
} catch (err2) {
|
|
17217
|
+
debugSwallow("mcp.findLegacyStores(worktrees)", err2);
|
|
17148
17218
|
}
|
|
17149
17219
|
try {
|
|
17150
|
-
const { execFile:
|
|
17220
|
+
const { execFile: execFile5 } = await import("node:child_process");
|
|
17151
17221
|
const { promisify: promisify2 } = await import("node:util");
|
|
17152
|
-
const
|
|
17153
|
-
const { stdout } = await
|
|
17222
|
+
const run3 = promisify2(execFile5);
|
|
17223
|
+
const { stdout } = await run3("git", ["worktree", "list", "--porcelain"], {
|
|
17154
17224
|
cwd,
|
|
17155
17225
|
timeout: 5e3
|
|
17156
17226
|
});
|
|
@@ -17158,23 +17228,23 @@ async function findLegacyStores(cwd) {
|
|
|
17158
17228
|
if (line.startsWith("worktree "))
|
|
17159
17229
|
dirs.add(line.slice("worktree ".length));
|
|
17160
17230
|
}
|
|
17161
|
-
} catch (
|
|
17162
|
-
debugSwallow("mcp.findLegacyStores(git)",
|
|
17231
|
+
} catch (err2) {
|
|
17232
|
+
debugSwallow("mcp.findLegacyStores(git)", err2);
|
|
17163
17233
|
}
|
|
17164
17234
|
const stores = [];
|
|
17165
17235
|
for (const dir of dirs) {
|
|
17166
|
-
const path10 =
|
|
17236
|
+
const path10 = join13(dir, ".mcp", OAUTH_CRED_FILENAME);
|
|
17167
17237
|
const raw = await readIfExists(path10);
|
|
17168
17238
|
if (raw !== null) stores.push({ path: path10, raw });
|
|
17169
17239
|
}
|
|
17170
17240
|
return stores;
|
|
17171
17241
|
}
|
|
17172
17242
|
async function scanConnections() {
|
|
17173
|
-
const { homedir:
|
|
17174
|
-
const { join:
|
|
17175
|
-
const home =
|
|
17243
|
+
const { homedir: homedir11 } = await import("node:os");
|
|
17244
|
+
const { join: join13 } = await import("node:path");
|
|
17245
|
+
const home = homedir11();
|
|
17176
17246
|
const hookSettings = await readIfExists(
|
|
17177
|
-
|
|
17247
|
+
join13(home, ".claude", "settings.json")
|
|
17178
17248
|
);
|
|
17179
17249
|
const hooksInstalled = hookSettings ? hasGreatArrowHooks(hookSettings) : false;
|
|
17180
17250
|
const entries = [];
|
|
@@ -17207,29 +17277,29 @@ async function probeEndpoint() {
|
|
|
17207
17277
|
}
|
|
17208
17278
|
}
|
|
17209
17279
|
async function applyMigration(plan) {
|
|
17210
|
-
const { homedir:
|
|
17211
|
-
const { join:
|
|
17212
|
-
const { mkdir:
|
|
17280
|
+
const { homedir: homedir11 } = await import("node:os");
|
|
17281
|
+
const { join: join13 } = await import("node:path");
|
|
17282
|
+
const { mkdir: mkdir9, rename: rename3, writeFile: writeFile7 } = await import("node:fs/promises");
|
|
17213
17283
|
const applied = [];
|
|
17214
|
-
const dir =
|
|
17215
|
-
await
|
|
17284
|
+
const dir = join13(homedir11(), ".great-arrow");
|
|
17285
|
+
await mkdir9(dir, { recursive: true, mode: 448 });
|
|
17216
17286
|
if (plan.seedFrom) {
|
|
17217
17287
|
const raw = await readIfExists(plan.seedFrom);
|
|
17218
17288
|
if (raw !== null) {
|
|
17219
|
-
const target =
|
|
17289
|
+
const target = join13(dir, OAUTH_CRED_FILENAME);
|
|
17220
17290
|
const tmp = `${target}.tmp`;
|
|
17221
|
-
await
|
|
17222
|
-
await
|
|
17291
|
+
await writeFile7(tmp, raw, { mode: 384 });
|
|
17292
|
+
await rename3(tmp, target);
|
|
17223
17293
|
applied.push(`Copied ${plan.seedFrom} \u2192 ${target}`);
|
|
17224
17294
|
}
|
|
17225
17295
|
}
|
|
17226
17296
|
if (plan.syncKeychainToFile) {
|
|
17227
17297
|
const raw = await readKeychainOnly();
|
|
17228
17298
|
if (raw) {
|
|
17229
|
-
const target =
|
|
17299
|
+
const target = join13(dir, "credential");
|
|
17230
17300
|
const tmp = `${target}.tmp`;
|
|
17231
|
-
await
|
|
17232
|
-
await
|
|
17301
|
+
await writeFile7(tmp, raw, { mode: 384 });
|
|
17302
|
+
await rename3(tmp, target);
|
|
17233
17303
|
applied.push(`Wrote the keychain credential to ${target}`);
|
|
17234
17304
|
}
|
|
17235
17305
|
}
|
|
@@ -17252,19 +17322,19 @@ var doctorSubcommand = new Command("doctor").description(
|
|
|
17252
17322
|
noColor: false
|
|
17253
17323
|
});
|
|
17254
17324
|
const c = createColor(jsonFlag);
|
|
17255
|
-
const { homedir:
|
|
17256
|
-
const { join:
|
|
17257
|
-
const home =
|
|
17325
|
+
const { homedir: homedir11 } = await import("node:os");
|
|
17326
|
+
const { join: join13 } = await import("node:path");
|
|
17327
|
+
const home = homedir11();
|
|
17258
17328
|
const proxyPath = await resolveProxyScript(options.proxy);
|
|
17259
17329
|
const diagnostics = proxyPath ? await runProxyDiagnostics(proxyPath) : null;
|
|
17260
17330
|
const entries = await scanConnections();
|
|
17261
17331
|
const duplicates = detectDuplicates(entries);
|
|
17262
17332
|
const keychain = await readKeychainOnly();
|
|
17263
17333
|
const credentialFile = await readIfExists(
|
|
17264
|
-
|
|
17334
|
+
join13(home, ".great-arrow", "credential")
|
|
17265
17335
|
);
|
|
17266
17336
|
const userStore = await readIfExists(
|
|
17267
|
-
|
|
17337
|
+
join13(home, ".great-arrow", OAUTH_CRED_FILENAME)
|
|
17268
17338
|
);
|
|
17269
17339
|
const legacyStores = await findLegacyStores(process.cwd());
|
|
17270
17340
|
const findings = [
|
|
@@ -17404,9 +17474,9 @@ async function runSmokeTest(client2, test) {
|
|
|
17404
17474
|
await client2.mcpCall(test.tool, test.args);
|
|
17405
17475
|
const durationMs = Math.round(performance.now() - start);
|
|
17406
17476
|
return { name: test.name, tool: test.tool, status: "pass", durationMs };
|
|
17407
|
-
} catch (
|
|
17477
|
+
} catch (err2) {
|
|
17408
17478
|
const durationMs = Math.round(performance.now() - start);
|
|
17409
|
-
const error62 =
|
|
17479
|
+
const error62 = err2 instanceof Error ? err2.message : "Unknown error";
|
|
17410
17480
|
return {
|
|
17411
17481
|
name: test.name,
|
|
17412
17482
|
tool: test.tool,
|
|
@@ -17931,8 +18001,8 @@ async function maybeShowGlanceFooter(argv) {
|
|
|
17931
18001
|
token: auth.token,
|
|
17932
18002
|
keys: printed
|
|
17933
18003
|
});
|
|
17934
|
-
} catch (
|
|
17935
|
-
debugSwallow("glance-footer",
|
|
18004
|
+
} catch (err2) {
|
|
18005
|
+
debugSwallow("glance-footer", err2);
|
|
17936
18006
|
}
|
|
17937
18007
|
}
|
|
17938
18008
|
function shouldRunGlanceFooter(argv) {
|
|
@@ -18161,6 +18231,17 @@ function normalizeGlance(raw) {
|
|
|
18161
18231
|
dismissKey: r.dismissKey
|
|
18162
18232
|
} : null;
|
|
18163
18233
|
})(),
|
|
18234
|
+
// Same rule: both counts must be counts, or the line is dropped.
|
|
18235
|
+
keyRotation: (() => {
|
|
18236
|
+
const raw2 = obj.keyRotation;
|
|
18237
|
+
if (typeof raw2 !== "object" || raw2 === null) return null;
|
|
18238
|
+
const r = raw2;
|
|
18239
|
+
const count2 = (v) => typeof v === "number" && Number.isInteger(v) && v >= 0;
|
|
18240
|
+
return count2(r.needsYou) && count2(r.pendingDevices) ? {
|
|
18241
|
+
needsYou: r.needsYou,
|
|
18242
|
+
pendingDevices: r.pendingDevices
|
|
18243
|
+
} : null;
|
|
18244
|
+
})(),
|
|
18164
18245
|
...(() => {
|
|
18165
18246
|
const raw2 = obj.landing;
|
|
18166
18247
|
if (typeof raw2 !== "object" || raw2 === null) return {};
|
|
@@ -18195,9 +18276,9 @@ function asNullableString(value) {
|
|
|
18195
18276
|
function normalizeTodaySections(raw) {
|
|
18196
18277
|
return raw.flatMap((section) => {
|
|
18197
18278
|
if (typeof section !== "object" || section === null) return [];
|
|
18198
|
-
const
|
|
18199
|
-
if (typeof
|
|
18200
|
-
const rows = asArray2(
|
|
18279
|
+
const s2 = section;
|
|
18280
|
+
if (typeof s2.key !== "string" || typeof s2.title !== "string") return [];
|
|
18281
|
+
const rows = asArray2(s2.rows).flatMap((row) => {
|
|
18201
18282
|
if (typeof row !== "object" || row === null) return [];
|
|
18202
18283
|
const r = row;
|
|
18203
18284
|
if (typeof r.id !== "string" || typeof r.title !== "string") return [];
|
|
@@ -18212,7 +18293,7 @@ function normalizeTodaySections(raw) {
|
|
|
18212
18293
|
}
|
|
18213
18294
|
];
|
|
18214
18295
|
});
|
|
18215
|
-
return rows.length > 0 ? [{ key:
|
|
18296
|
+
return rows.length > 0 ? [{ key: s2.key, title: s2.title, rows }] : [];
|
|
18216
18297
|
});
|
|
18217
18298
|
}
|
|
18218
18299
|
function asArray2(value) {
|
|
@@ -18688,8 +18769,8 @@ function createLocalDeviceLocator(scope, directory = join10(homedir9(), ".great-
|
|
|
18688
18769
|
let file2;
|
|
18689
18770
|
try {
|
|
18690
18771
|
file2 = await open2(path10, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
18691
|
-
} catch (
|
|
18692
|
-
if (
|
|
18772
|
+
} catch (err2) {
|
|
18773
|
+
if (err2.code === "ENOENT") return null;
|
|
18693
18774
|
throw new Error("Device locator could not be read");
|
|
18694
18775
|
}
|
|
18695
18776
|
try {
|
|
@@ -20786,10 +20867,10 @@ function defineLazyInternal(inst, key, compute) {
|
|
|
20786
20867
|
Object.defineProperty(this, key, { configurable: true, writable: true, value });
|
|
20787
20868
|
broke = broke || outer;
|
|
20788
20869
|
return value;
|
|
20789
|
-
} catch (
|
|
20870
|
+
} catch (err2) {
|
|
20790
20871
|
delete this[key];
|
|
20791
20872
|
broke = broke || outer;
|
|
20792
|
-
throw
|
|
20873
|
+
throw err2;
|
|
20793
20874
|
}
|
|
20794
20875
|
},
|
|
20795
20876
|
set(value) {
|
|
@@ -22212,9 +22293,9 @@ var asciiTabOrNewline = /[\t\n\r]/g;
|
|
|
22212
22293
|
function stripTabAndNewline(value) {
|
|
22213
22294
|
return value.replace(asciiTabOrNewline, "");
|
|
22214
22295
|
}
|
|
22215
|
-
function urlHostnameOk(url2,
|
|
22216
|
-
|
|
22217
|
-
return
|
|
22296
|
+
function urlHostnameOk(url2, hostname6) {
|
|
22297
|
+
hostname6.lastIndex = 0;
|
|
22298
|
+
return hostname6.test(url2.hostname);
|
|
22218
22299
|
}
|
|
22219
22300
|
function urlProtocolOk(url2, protocol) {
|
|
22220
22301
|
protocol.lastIndex = 0;
|
|
@@ -23406,7 +23487,7 @@ function handleIntersectionResults(result, left, right) {
|
|
|
23406
23487
|
const unrecKeys = /* @__PURE__ */ new Map();
|
|
23407
23488
|
let unrecIssue;
|
|
23408
23489
|
const keyIssues = /* @__PURE__ */ new Map();
|
|
23409
|
-
const
|
|
23490
|
+
const collect3 = (iss, side) => {
|
|
23410
23491
|
let keys;
|
|
23411
23492
|
if (iss.code === "unrecognized_keys" && !iss.path?.length) {
|
|
23412
23493
|
unrecIssue ?? (unrecIssue = iss);
|
|
@@ -23427,11 +23508,11 @@ function handleIntersectionResults(result, left, right) {
|
|
|
23427
23508
|
return true;
|
|
23428
23509
|
};
|
|
23429
23510
|
for (const iss of left.issues) {
|
|
23430
|
-
if (!
|
|
23511
|
+
if (!collect3(iss, "l"))
|
|
23431
23512
|
result.issues.push(iss);
|
|
23432
23513
|
}
|
|
23433
23514
|
for (const iss of right.issues) {
|
|
23434
|
-
if (!
|
|
23515
|
+
if (!collect3(iss, "r"))
|
|
23435
23516
|
result.issues.push(iss);
|
|
23436
23517
|
}
|
|
23437
23518
|
const bothKeys = [...unrecKeys].filter(([, f]) => f.l && f.r).map(([k]) => k);
|
|
@@ -24255,7 +24336,7 @@ function partPattern(schema) {
|
|
|
24255
24336
|
if (def.options) {
|
|
24256
24337
|
const sources = def.options.map(partPattern);
|
|
24257
24338
|
if (sources.every(Boolean))
|
|
24258
|
-
return `^(${sources.map((
|
|
24339
|
+
return `^(${sources.map((s2) => cleanRegex(s2)).join("|")})$`;
|
|
24259
24340
|
}
|
|
24260
24341
|
return leafPattern(schema);
|
|
24261
24342
|
}
|
|
@@ -24453,7 +24534,7 @@ var recursive = /* @__PURE__ */ new WeakMap();
|
|
|
24453
24534
|
var NONE = 0;
|
|
24454
24535
|
var ASSUMED = 1;
|
|
24455
24536
|
var PROVEN = 2;
|
|
24456
|
-
function isRecursive(inst, stack,
|
|
24537
|
+
function isRecursive(inst, stack, resolve5) {
|
|
24457
24538
|
const cached2 = recursive.get(inst);
|
|
24458
24539
|
if (cached2 !== void 0)
|
|
24459
24540
|
return cached2 ? PROVEN : NONE;
|
|
@@ -24463,7 +24544,7 @@ function isRecursive(inst, stack, resolve4) {
|
|
|
24463
24544
|
let result = NONE;
|
|
24464
24545
|
const check2 = (child) => {
|
|
24465
24546
|
if (result !== PROVEN && child?._zod) {
|
|
24466
|
-
const answer = isRecursive(child, stack,
|
|
24547
|
+
const answer = isRecursive(child, stack, resolve5);
|
|
24467
24548
|
if (answer > result)
|
|
24468
24549
|
result = answer;
|
|
24469
24550
|
}
|
|
@@ -24474,7 +24555,7 @@ function isRecursive(inst, stack, resolve4) {
|
|
|
24474
24555
|
const desc = Object.getOwnPropertyDescriptor(sh, key);
|
|
24475
24556
|
if (spread && !desc.enumerable)
|
|
24476
24557
|
continue;
|
|
24477
|
-
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack,
|
|
24558
|
+
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve5) : NONE;
|
|
24478
24559
|
if (child > answer)
|
|
24479
24560
|
answer = child;
|
|
24480
24561
|
}
|
|
@@ -24538,7 +24619,7 @@ function isRecursive(inst, stack, resolve4) {
|
|
|
24538
24619
|
break;
|
|
24539
24620
|
// `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
|
|
24540
24621
|
case "lazy": {
|
|
24541
|
-
const inner = def._cachedInner ?? (
|
|
24622
|
+
const inner = def._cachedInner ?? (resolve5 ? inst._zod.innerType : void 0);
|
|
24542
24623
|
merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
|
|
24543
24624
|
break;
|
|
24544
24625
|
}
|
|
@@ -32357,9 +32438,9 @@ function compile(schema, options) {
|
|
|
32357
32438
|
const clone2 = withParser(schema, parser);
|
|
32358
32439
|
clone2._zod.bag.validator = compileValidator(schema, parser);
|
|
32359
32440
|
return clone2;
|
|
32360
|
-
} catch (
|
|
32441
|
+
} catch (err2) {
|
|
32361
32442
|
if (options?.strict)
|
|
32362
|
-
throw
|
|
32443
|
+
throw err2;
|
|
32363
32444
|
return schema;
|
|
32364
32445
|
}
|
|
32365
32446
|
}
|
|
@@ -32377,9 +32458,9 @@ function withParser(schema, parser) {
|
|
|
32377
32458
|
if (ctx && isBackEdge(ctx, payload.value)) {
|
|
32378
32459
|
return originalRun(payload, ctx);
|
|
32379
32460
|
}
|
|
32380
|
-
const
|
|
32381
|
-
if (
|
|
32382
|
-
payload.value =
|
|
32461
|
+
const out2 = parser(payload.value);
|
|
32462
|
+
if (out2 !== INVALID) {
|
|
32463
|
+
payload.value = out2;
|
|
32383
32464
|
return payload;
|
|
32384
32465
|
}
|
|
32385
32466
|
if (ctx)
|
|
@@ -32400,9 +32481,9 @@ function installCompiledUserMethods(target, source, parser) {
|
|
|
32400
32481
|
if (typeof sourceAny.safeParse === "function") {
|
|
32401
32482
|
const originalSafeParse = sourceAny.safeParse;
|
|
32402
32483
|
targetAny.safeParse = (data, params) => {
|
|
32403
|
-
const
|
|
32404
|
-
if (
|
|
32405
|
-
return { success: true, data:
|
|
32484
|
+
const out2 = parser(data);
|
|
32485
|
+
if (out2 !== INVALID) {
|
|
32486
|
+
return { success: true, data: out2 };
|
|
32406
32487
|
}
|
|
32407
32488
|
return originalSafeParse(data, params);
|
|
32408
32489
|
};
|
|
@@ -32410,9 +32491,9 @@ function installCompiledUserMethods(target, source, parser) {
|
|
|
32410
32491
|
if (typeof sourceAny.parse === "function") {
|
|
32411
32492
|
const originalParse = sourceAny.parse;
|
|
32412
32493
|
targetAny.parse = (data, params) => {
|
|
32413
|
-
const
|
|
32414
|
-
if (
|
|
32415
|
-
return
|
|
32494
|
+
const out2 = parser(data);
|
|
32495
|
+
if (out2 !== INVALID) {
|
|
32496
|
+
return out2;
|
|
32416
32497
|
}
|
|
32417
32498
|
return originalParse(data, params);
|
|
32418
32499
|
};
|
|
@@ -32449,8 +32530,8 @@ ${code}
|
|
|
32449
32530
|
try {
|
|
32450
32531
|
const factory = new F(...constantNames, factoryCode);
|
|
32451
32532
|
fn = factory(...constantValues);
|
|
32452
|
-
} catch (
|
|
32453
|
-
throw new ZodCompileUnsupportedError(`this schema (generated code failed to evaluate: ${
|
|
32533
|
+
} catch (err2) {
|
|
32534
|
+
throw new ZodCompileUnsupportedError(`this schema (generated code failed to evaluate: ${err2.message})`);
|
|
32454
32535
|
}
|
|
32455
32536
|
if (options?.debug) {
|
|
32456
32537
|
fn.code = fullCode;
|
|
@@ -32488,9 +32569,9 @@ function compileChild(doc, ctx, schema, accessor, needsValue = true) {
|
|
|
32488
32569
|
const varCounter = ctx.varCounter;
|
|
32489
32570
|
try {
|
|
32490
32571
|
return generateCheck(doc, ctx, schema, accessor, needsValue);
|
|
32491
|
-
} catch (
|
|
32492
|
-
if (!(
|
|
32493
|
-
throw
|
|
32572
|
+
} catch (err2) {
|
|
32573
|
+
if (!(err2 instanceof ZodCompileUnsupportedError) || !err2.islandable)
|
|
32574
|
+
throw err2;
|
|
32494
32575
|
doc.content.length = contentLen;
|
|
32495
32576
|
if (ctx.constants.size > constantCount) {
|
|
32496
32577
|
const trailing = Array.from(ctx.constants.keys()).slice(constantCount);
|
|
@@ -33173,13 +33254,13 @@ function generateObjectCheck(doc, ctx, schema, accessor, buildsValue = true) {
|
|
|
33173
33254
|
doc.write(`const ${outputVar} = {};`);
|
|
33174
33255
|
for (const k of allKeys) {
|
|
33175
33256
|
const kx = keyExpr(k);
|
|
33176
|
-
const
|
|
33257
|
+
const out2 = propOutputs.get(k);
|
|
33177
33258
|
if (dropsWhenAbsent(propShape[k])) {
|
|
33178
|
-
doc.write(`if (${kx} in ${accessor}) ${outputVar}[${kx}] = ${
|
|
33259
|
+
doc.write(`if (${kx} in ${accessor}) ${outputVar}[${kx}] = ${out2};`);
|
|
33179
33260
|
} else if (mayOmitUndefined(propShape[k])) {
|
|
33180
|
-
doc.write(`if (${
|
|
33261
|
+
doc.write(`if (${out2} !== undefined || ${kx} in ${accessor}) ${outputVar}[${kx}] = ${out2};`);
|
|
33181
33262
|
} else {
|
|
33182
|
-
doc.write(`${outputVar}[${kx}] = ${
|
|
33263
|
+
doc.write(`${outputVar}[${kx}] = ${out2};`);
|
|
33183
33264
|
}
|
|
33184
33265
|
}
|
|
33185
33266
|
}
|
|
@@ -34811,11 +34892,11 @@ function _catch(Class2, innerType, catchValue) {
|
|
|
34811
34892
|
});
|
|
34812
34893
|
}
|
|
34813
34894
|
// @__NO_SIDE_EFFECTS__
|
|
34814
|
-
function _pipe(Class2, in_,
|
|
34895
|
+
function _pipe(Class2, in_, out2) {
|
|
34815
34896
|
return new Class2({
|
|
34816
34897
|
type: "pipe",
|
|
34817
34898
|
in: in_,
|
|
34818
|
-
out
|
|
34899
|
+
out: out2
|
|
34819
34900
|
});
|
|
34820
34901
|
}
|
|
34821
34902
|
// @__NO_SIDE_EFFECTS__
|
|
@@ -37930,11 +38011,11 @@ var ZodPipe = /* @__PURE__ */ $constructor("ZodPipe", (inst, def) => {
|
|
|
37930
38011
|
inst.in = def.in;
|
|
37931
38012
|
inst.out = def.out;
|
|
37932
38013
|
});
|
|
37933
|
-
function pipe(in_,
|
|
38014
|
+
function pipe(in_, out2) {
|
|
37934
38015
|
return new ZodPipe({
|
|
37935
38016
|
type: "pipe",
|
|
37936
38017
|
in: in_,
|
|
37937
|
-
out
|
|
38018
|
+
out: out2
|
|
37938
38019
|
// ...util.normalizeParams(params),
|
|
37939
38020
|
});
|
|
37940
38021
|
}
|
|
@@ -37942,11 +38023,11 @@ var ZodCodec = /* @__PURE__ */ $constructor("ZodCodec", (inst, def) => {
|
|
|
37942
38023
|
ZodPipe.init(inst, def);
|
|
37943
38024
|
$ZodCodec.init(inst, def);
|
|
37944
38025
|
});
|
|
37945
|
-
function codec(in_,
|
|
38026
|
+
function codec(in_, out2, params) {
|
|
37946
38027
|
return new ZodCodec({
|
|
37947
38028
|
type: "pipe",
|
|
37948
38029
|
in: in_,
|
|
37949
|
-
out,
|
|
38030
|
+
out: out2,
|
|
37950
38031
|
transform: params.decode,
|
|
37951
38032
|
reverseTransform: params.encode
|
|
37952
38033
|
});
|
|
@@ -38784,12 +38865,12 @@ function convertSchema(schema, ctx) {
|
|
|
38784
38865
|
let baseSchema = convertBaseSchema(schema, ctx);
|
|
38785
38866
|
const hasExplicitType = schema.type || schema.enum !== void 0 || schema.const !== void 0;
|
|
38786
38867
|
if (schema.anyOf && Array.isArray(schema.anyOf)) {
|
|
38787
|
-
const options = schema.anyOf.map((
|
|
38868
|
+
const options = schema.anyOf.map((s2) => convertSchema(s2, ctx));
|
|
38788
38869
|
const anyOfUnion = z.union(options);
|
|
38789
38870
|
baseSchema = hasExplicitType ? z.intersection(baseSchema, anyOfUnion) : anyOfUnion;
|
|
38790
38871
|
}
|
|
38791
38872
|
if (schema.oneOf && Array.isArray(schema.oneOf)) {
|
|
38792
|
-
const options = schema.oneOf.map((
|
|
38873
|
+
const options = schema.oneOf.map((s2) => convertSchema(s2, ctx));
|
|
38793
38874
|
const oneOfUnion = z.xor(options);
|
|
38794
38875
|
baseSchema = hasExplicitType ? z.intersection(baseSchema, oneOfUnion) : oneOfUnion;
|
|
38795
38876
|
}
|
|
@@ -38889,24 +38970,24 @@ function visit(schema, fnOrHandlers) {
|
|
|
38889
38970
|
return h ? h(node2, rewritten) : node2;
|
|
38890
38971
|
};
|
|
38891
38972
|
const cache = /* @__PURE__ */ new Map();
|
|
38892
|
-
function
|
|
38893
|
-
const cached2 = cache.get(
|
|
38973
|
+
function run3(s2) {
|
|
38974
|
+
const cached2 = cache.get(s2);
|
|
38894
38975
|
if (cached2 === RESOLVING) {
|
|
38895
38976
|
return new $ZodLazy({
|
|
38896
38977
|
type: "lazy",
|
|
38897
|
-
getter: () => cache.get(
|
|
38978
|
+
getter: () => cache.get(s2)
|
|
38898
38979
|
});
|
|
38899
38980
|
}
|
|
38900
38981
|
if (cached2 !== void 0)
|
|
38901
38982
|
return cached2;
|
|
38902
|
-
cache.set(
|
|
38903
|
-
const inner = mapInner(
|
|
38904
|
-
const mapped = fn(inner, inner !==
|
|
38905
|
-
cache.set(
|
|
38983
|
+
cache.set(s2, RESOLVING);
|
|
38984
|
+
const inner = mapInner(s2);
|
|
38985
|
+
const mapped = fn(inner, inner !== s2);
|
|
38986
|
+
cache.set(s2, mapped);
|
|
38906
38987
|
return mapped;
|
|
38907
38988
|
}
|
|
38908
|
-
function mapInner(
|
|
38909
|
-
const def =
|
|
38989
|
+
function mapInner(s2) {
|
|
38990
|
+
const def = s2._zod.def;
|
|
38910
38991
|
const kind = def.type;
|
|
38911
38992
|
switch (kind) {
|
|
38912
38993
|
case "object": {
|
|
@@ -38915,67 +38996,67 @@ function visit(schema, fnOrHandlers) {
|
|
|
38915
38996
|
let changed = false;
|
|
38916
38997
|
const newShape = {};
|
|
38917
38998
|
for (const k of keys) {
|
|
38918
|
-
const mapped =
|
|
38999
|
+
const mapped = run3(oldShape[k]);
|
|
38919
39000
|
if (mapped !== oldShape[k])
|
|
38920
39001
|
changed = true;
|
|
38921
39002
|
newShape[k] = mapped;
|
|
38922
39003
|
}
|
|
38923
39004
|
let newCatchall = def.catchall;
|
|
38924
39005
|
if (def.catchall) {
|
|
38925
|
-
newCatchall =
|
|
39006
|
+
newCatchall = run3(def.catchall);
|
|
38926
39007
|
if (newCatchall !== def.catchall)
|
|
38927
39008
|
changed = true;
|
|
38928
39009
|
}
|
|
38929
|
-
return changed ? clone(
|
|
39010
|
+
return changed ? clone(s2, { ...def, shape: newShape, catchall: newCatchall }) : s2;
|
|
38930
39011
|
}
|
|
38931
39012
|
case "array": {
|
|
38932
|
-
const mapped =
|
|
38933
|
-
return mapped === def.element ?
|
|
39013
|
+
const mapped = run3(def.element);
|
|
39014
|
+
return mapped === def.element ? s2 : clone(s2, { ...def, element: mapped });
|
|
38934
39015
|
}
|
|
38935
39016
|
case "tuple": {
|
|
38936
39017
|
const oldItems = def.items;
|
|
38937
39018
|
let changed = false;
|
|
38938
39019
|
const newItems = [];
|
|
38939
39020
|
for (const item of oldItems) {
|
|
38940
|
-
const mapped =
|
|
39021
|
+
const mapped = run3(item);
|
|
38941
39022
|
if (mapped !== item)
|
|
38942
39023
|
changed = true;
|
|
38943
39024
|
newItems.push(mapped);
|
|
38944
39025
|
}
|
|
38945
39026
|
let newRest = def.rest;
|
|
38946
39027
|
if (def.rest) {
|
|
38947
|
-
newRest =
|
|
39028
|
+
newRest = run3(def.rest);
|
|
38948
39029
|
if (newRest !== def.rest)
|
|
38949
39030
|
changed = true;
|
|
38950
39031
|
}
|
|
38951
|
-
return changed ? clone(
|
|
39032
|
+
return changed ? clone(s2, { ...def, items: newItems, rest: newRest }) : s2;
|
|
38952
39033
|
}
|
|
38953
39034
|
case "record":
|
|
38954
39035
|
case "map": {
|
|
38955
|
-
const newKey =
|
|
38956
|
-
const newVal =
|
|
38957
|
-
return newKey === def.keyType && newVal === def.valueType ?
|
|
39036
|
+
const newKey = run3(def.keyType);
|
|
39037
|
+
const newVal = run3(def.valueType);
|
|
39038
|
+
return newKey === def.keyType && newVal === def.valueType ? s2 : clone(s2, { ...def, keyType: newKey, valueType: newVal });
|
|
38958
39039
|
}
|
|
38959
39040
|
case "set": {
|
|
38960
|
-
const newVal =
|
|
38961
|
-
return newVal === def.valueType ?
|
|
39041
|
+
const newVal = run3(def.valueType);
|
|
39042
|
+
return newVal === def.valueType ? s2 : clone(s2, { ...def, valueType: newVal });
|
|
38962
39043
|
}
|
|
38963
39044
|
case "union": {
|
|
38964
39045
|
const oldOptions = def.options;
|
|
38965
39046
|
let changed = false;
|
|
38966
39047
|
const newOptions = [];
|
|
38967
39048
|
for (const opt of oldOptions) {
|
|
38968
|
-
const mapped =
|
|
39049
|
+
const mapped = run3(opt);
|
|
38969
39050
|
if (mapped !== opt)
|
|
38970
39051
|
changed = true;
|
|
38971
39052
|
newOptions.push(mapped);
|
|
38972
39053
|
}
|
|
38973
|
-
return changed ? clone(
|
|
39054
|
+
return changed ? clone(s2, { ...def, options: newOptions }) : s2;
|
|
38974
39055
|
}
|
|
38975
39056
|
case "intersection": {
|
|
38976
|
-
const newLeft =
|
|
38977
|
-
const newRight =
|
|
38978
|
-
return newLeft === def.left && newRight === def.right ?
|
|
39057
|
+
const newLeft = run3(def.left);
|
|
39058
|
+
const newRight = run3(def.right);
|
|
39059
|
+
return newLeft === def.left && newRight === def.right ? s2 : clone(s2, { ...def, left: newLeft, right: newRight });
|
|
38979
39060
|
}
|
|
38980
39061
|
case "optional":
|
|
38981
39062
|
case "nullable":
|
|
@@ -38986,23 +39067,23 @@ function visit(schema, fnOrHandlers) {
|
|
|
38986
39067
|
case "nonoptional":
|
|
38987
39068
|
case "promise":
|
|
38988
39069
|
case "success": {
|
|
38989
|
-
const newInner =
|
|
38990
|
-
return newInner === def.innerType ?
|
|
39070
|
+
const newInner = run3(def.innerType);
|
|
39071
|
+
return newInner === def.innerType ? s2 : clone(s2, { ...def, innerType: newInner });
|
|
38991
39072
|
}
|
|
38992
39073
|
case "pipe": {
|
|
38993
|
-
const newIn =
|
|
38994
|
-
const newOut =
|
|
38995
|
-
return newIn === def.in && newOut === def.out ?
|
|
39074
|
+
const newIn = run3(def.in);
|
|
39075
|
+
const newOut = run3(def.out);
|
|
39076
|
+
return newIn === def.in && newOut === def.out ? s2 : clone(s2, { ...def, in: newIn, out: newOut });
|
|
38996
39077
|
}
|
|
38997
39078
|
case "function": {
|
|
38998
|
-
const newInput =
|
|
38999
|
-
const newOutput =
|
|
39000
|
-
return newInput === def.input && newOutput === def.output ?
|
|
39079
|
+
const newInput = run3(def.input);
|
|
39080
|
+
const newOutput = run3(def.output);
|
|
39081
|
+
return newInput === def.input && newOutput === def.output ? s2 : clone(s2, { ...def, input: newInput, output: newOutput });
|
|
39001
39082
|
}
|
|
39002
39083
|
case "lazy": {
|
|
39003
39084
|
const original = def.getter;
|
|
39004
39085
|
const { _cachedInner, ...rest } = def;
|
|
39005
|
-
return clone(
|
|
39086
|
+
return clone(s2, { ...rest, getter: () => run3(original()) });
|
|
39006
39087
|
}
|
|
39007
39088
|
// A leaf by choice: `parts` are regex fragments, not data positions.
|
|
39008
39089
|
case "template_literal":
|
|
@@ -39026,24 +39107,24 @@ function visit(schema, fnOrHandlers) {
|
|
|
39026
39107
|
case "file":
|
|
39027
39108
|
case "transform":
|
|
39028
39109
|
case "custom":
|
|
39029
|
-
return
|
|
39110
|
+
return s2;
|
|
39030
39111
|
default: {
|
|
39031
39112
|
kind;
|
|
39032
|
-
return
|
|
39113
|
+
return s2;
|
|
39033
39114
|
}
|
|
39034
39115
|
}
|
|
39035
39116
|
}
|
|
39036
|
-
return
|
|
39117
|
+
return run3(schema);
|
|
39037
39118
|
}
|
|
39038
39119
|
|
|
39039
39120
|
// ../../node_modules/zod/v4/classic/deep-partial.js
|
|
39040
39121
|
function deepPartial(schema) {
|
|
39041
39122
|
return visit(schema, {
|
|
39042
|
-
object: (
|
|
39123
|
+
object: (s2) => s2.partial(),
|
|
39043
39124
|
// Every partialed option now admits `undefined`, which the constructor rejects as a duplicate.
|
|
39044
|
-
union: (
|
|
39045
|
-
const def =
|
|
39046
|
-
return def.discriminator === void 0 ?
|
|
39125
|
+
union: (s2) => {
|
|
39126
|
+
const def = s2._zod.def;
|
|
39127
|
+
return def.discriminator === void 0 ? s2 : union(def.options);
|
|
39047
39128
|
}
|
|
39048
39129
|
});
|
|
39049
39130
|
}
|
|
@@ -39063,18 +39144,18 @@ function inSide(def) {
|
|
|
39063
39144
|
}
|
|
39064
39145
|
function input(schema) {
|
|
39065
39146
|
return visit(schema, {
|
|
39066
|
-
pipe: (
|
|
39147
|
+
pipe: (s2) => inSide(s2._zod.def),
|
|
39067
39148
|
// A default value belongs to the output side, so a rewritten inner type leaves it stranded. `.default()` widens the declared input type with `undefined`, and `optional` is what carries that across.
|
|
39068
|
-
default: (
|
|
39149
|
+
default: (s2, rewritten) => rewritten ? optional(s2._zod.def.innerType) : s2,
|
|
39069
39150
|
// A catch value is output-side too, but `.catch()` leaves the declared input type alone, so the inner schema stands on its own.
|
|
39070
|
-
catch: (
|
|
39151
|
+
catch: (s2, rewritten) => rewritten ? s2._zod.def.innerType : s2
|
|
39071
39152
|
});
|
|
39072
39153
|
}
|
|
39073
39154
|
function output(schema) {
|
|
39074
39155
|
return visit(schema, {
|
|
39075
|
-
pipe: (
|
|
39156
|
+
pipe: (s2) => outSide(s2._zod.def),
|
|
39076
39157
|
// A prefault value is fed through the schema, which makes it input-side, so a rewritten inner type leaves it stranded.
|
|
39077
|
-
prefault: (
|
|
39158
|
+
prefault: (s2, rewritten) => rewritten ? s2._zod.def.innerType : s2
|
|
39078
39159
|
});
|
|
39079
39160
|
}
|
|
39080
39161
|
|
|
@@ -39534,12 +39615,12 @@ var ParseStatus = class _ParseStatus {
|
|
|
39534
39615
|
}
|
|
39535
39616
|
static mergeArray(status, results) {
|
|
39536
39617
|
const arrayValue = [];
|
|
39537
|
-
for (const
|
|
39538
|
-
if (
|
|
39618
|
+
for (const s2 of results) {
|
|
39619
|
+
if (s2.status === "aborted")
|
|
39539
39620
|
return INVALID2;
|
|
39540
|
-
if (
|
|
39621
|
+
if (s2.status === "dirty")
|
|
39541
39622
|
status.dirty();
|
|
39542
|
-
arrayValue.push(
|
|
39623
|
+
arrayValue.push(s2.value);
|
|
39543
39624
|
}
|
|
39544
39625
|
return { status: status.value, value: arrayValue };
|
|
39545
39626
|
}
|
|
@@ -39736,8 +39817,8 @@ var ZodType2 = class {
|
|
|
39736
39817
|
} : {
|
|
39737
39818
|
issues: ctx.common.issues
|
|
39738
39819
|
};
|
|
39739
|
-
} catch (
|
|
39740
|
-
if (
|
|
39820
|
+
} catch (err2) {
|
|
39821
|
+
if (err2?.message?.toLowerCase()?.includes("encountered")) {
|
|
39741
39822
|
this["~standard"].async = true;
|
|
39742
39823
|
}
|
|
39743
39824
|
ctx.common = {
|
|
@@ -43260,34 +43341,34 @@ function validateDownloadUrl(url2) {
|
|
|
43260
43341
|
message: `URL scheme must be http, https, or data, got ${parsed.protocol}`
|
|
43261
43342
|
});
|
|
43262
43343
|
}
|
|
43263
|
-
const
|
|
43264
|
-
if (!
|
|
43344
|
+
const hostname6 = parsed.hostname.toLowerCase().replace(/\.+$/, "");
|
|
43345
|
+
if (!hostname6) {
|
|
43265
43346
|
throw new DownloadError({
|
|
43266
43347
|
url: url2,
|
|
43267
43348
|
message: `URL must have a hostname`
|
|
43268
43349
|
});
|
|
43269
43350
|
}
|
|
43270
|
-
if (
|
|
43351
|
+
if (hostname6 === "localhost" || hostname6.endsWith(".local") || hostname6.endsWith(".localhost") || hostname6.endsWith(".internal")) {
|
|
43271
43352
|
throw new DownloadError({
|
|
43272
43353
|
url: url2,
|
|
43273
|
-
message: `URL with hostname ${
|
|
43354
|
+
message: `URL with hostname ${hostname6} is not allowed`
|
|
43274
43355
|
});
|
|
43275
43356
|
}
|
|
43276
|
-
if (
|
|
43277
|
-
const ipv63 =
|
|
43357
|
+
if (hostname6.startsWith("[") && hostname6.endsWith("]")) {
|
|
43358
|
+
const ipv63 = hostname6.slice(1, -1);
|
|
43278
43359
|
if (isPrivateIPv6(ipv63)) {
|
|
43279
43360
|
throw new DownloadError({
|
|
43280
43361
|
url: url2,
|
|
43281
|
-
message: `URL with IPv6 address ${
|
|
43362
|
+
message: `URL with IPv6 address ${hostname6} is not allowed`
|
|
43282
43363
|
});
|
|
43283
43364
|
}
|
|
43284
43365
|
return;
|
|
43285
43366
|
}
|
|
43286
|
-
if (isIPv4(
|
|
43287
|
-
if (isPrivateIPv4(
|
|
43367
|
+
if (isIPv4(hostname6)) {
|
|
43368
|
+
if (isPrivateIPv4(hostname6)) {
|
|
43288
43369
|
throw new DownloadError({
|
|
43289
43370
|
url: url2,
|
|
43290
|
-
message: `URL with IP address ${
|
|
43371
|
+
message: `URL with IP address ${hostname6} is not allowed`
|
|
43291
43372
|
});
|
|
43292
43373
|
}
|
|
43293
43374
|
}
|
|
@@ -43295,18 +43376,18 @@ function validateDownloadUrl(url2) {
|
|
|
43295
43376
|
function validateDownloadAddress({
|
|
43296
43377
|
address,
|
|
43297
43378
|
family,
|
|
43298
|
-
hostname:
|
|
43379
|
+
hostname: hostname6
|
|
43299
43380
|
}) {
|
|
43300
43381
|
const isUnsafe = family === 4 ? !isIPv4(address) || isPrivateIPv4(address) : family === 6 ? isPrivateIPv6(address) : true;
|
|
43301
43382
|
if (isUnsafe) {
|
|
43302
43383
|
throw new DownloadError({
|
|
43303
|
-
url:
|
|
43304
|
-
message: `Hostname ${
|
|
43384
|
+
url: hostname6,
|
|
43385
|
+
message: `Hostname ${hostname6} resolved to disallowed IP address ${address}`
|
|
43305
43386
|
});
|
|
43306
43387
|
}
|
|
43307
43388
|
}
|
|
43308
|
-
function isIPv4(
|
|
43309
|
-
const parts =
|
|
43389
|
+
function isIPv4(hostname6) {
|
|
43390
|
+
const parts = hostname6.split(".");
|
|
43310
43391
|
if (parts.length !== 4) return false;
|
|
43311
43392
|
return parts.every((part) => {
|
|
43312
43393
|
const num = Number(part);
|
|
@@ -43391,8 +43472,8 @@ function isPrivateIPv6(ip) {
|
|
|
43391
43472
|
return false;
|
|
43392
43473
|
}
|
|
43393
43474
|
function createSafeLookup(lookup) {
|
|
43394
|
-
return ((
|
|
43395
|
-
lookup(
|
|
43475
|
+
return ((hostname6, options, callback) => {
|
|
43476
|
+
lookup(hostname6, { ...options, all: true }, (error62, addresses) => {
|
|
43396
43477
|
if (error62) {
|
|
43397
43478
|
callback(error62);
|
|
43398
43479
|
return;
|
|
@@ -43400,10 +43481,10 @@ function createSafeLookup(lookup) {
|
|
|
43400
43481
|
try {
|
|
43401
43482
|
const [firstAddress] = addresses;
|
|
43402
43483
|
if (firstAddress == null) {
|
|
43403
|
-
throw new Error(`Hostname ${
|
|
43484
|
+
throw new Error(`Hostname ${hostname6} did not resolve to an address`);
|
|
43404
43485
|
}
|
|
43405
43486
|
for (const { address, family } of addresses) {
|
|
43406
|
-
validateDownloadAddress({ address, family, hostname:
|
|
43487
|
+
validateDownloadAddress({ address, family, hostname: hostname6 });
|
|
43407
43488
|
}
|
|
43408
43489
|
if (options.all === true) {
|
|
43409
43490
|
callback(null, addresses);
|
|
@@ -47105,9 +47186,9 @@ function createAsyncIterableStream(source) {
|
|
|
47105
47186
|
* @param err The error to throw.
|
|
47106
47187
|
* @returns A promise that rejects with the provided error.
|
|
47107
47188
|
*/
|
|
47108
|
-
async throw(
|
|
47189
|
+
async throw(err2) {
|
|
47109
47190
|
await cleanup(true);
|
|
47110
|
-
throw
|
|
47191
|
+
throw err2;
|
|
47111
47192
|
}
|
|
47112
47193
|
};
|
|
47113
47194
|
};
|
|
@@ -47711,9 +47792,9 @@ function platformFetch(apiUrl, transport, engineFetch) {
|
|
|
47711
47792
|
if (input2 instanceof Request)
|
|
47712
47793
|
throw new Error("Local turn transport requires an explicit request path");
|
|
47713
47794
|
const raw = String(input2);
|
|
47714
|
-
const
|
|
47795
|
+
const relative2 = raw.startsWith("/");
|
|
47715
47796
|
const target = new URL(raw, platform2);
|
|
47716
|
-
if (!
|
|
47797
|
+
if (!relative2 && target.origin !== platform2.origin)
|
|
47717
47798
|
return engineFetch(input2, init);
|
|
47718
47799
|
if (target.origin !== platform2.origin || !target.pathname.startsWith("/api/") || target.username || target.password || target.hash)
|
|
47719
47800
|
throw new Error("Local turn requests must use a platform API path");
|
|
@@ -47890,18 +47971,18 @@ function argumentsAsText(value) {
|
|
|
47890
47971
|
function readOllamaToolCalls(message) {
|
|
47891
47972
|
const raw = message?.tool_calls;
|
|
47892
47973
|
if (!Array.isArray(raw)) return [];
|
|
47893
|
-
const
|
|
47974
|
+
const out2 = [];
|
|
47894
47975
|
raw.forEach((entry, position) => {
|
|
47895
47976
|
if (!entry || typeof entry !== "object") return;
|
|
47896
47977
|
const fn = entry.function;
|
|
47897
47978
|
if (typeof fn?.name !== "string") return;
|
|
47898
|
-
|
|
47979
|
+
out2.push({
|
|
47899
47980
|
position,
|
|
47900
47981
|
name: fn.name,
|
|
47901
47982
|
argumentsFragment: argumentsAsText(fn.arguments)
|
|
47902
47983
|
});
|
|
47903
47984
|
});
|
|
47904
|
-
return
|
|
47985
|
+
return out2;
|
|
47905
47986
|
}
|
|
47906
47987
|
function readOllamaLine(line) {
|
|
47907
47988
|
let parsed;
|
|
@@ -47926,19 +48007,19 @@ function readOllamaLine(line) {
|
|
|
47926
48007
|
function readOpenAiToolCalls(deltaObj) {
|
|
47927
48008
|
const raw = deltaObj?.tool_calls;
|
|
47928
48009
|
if (!Array.isArray(raw)) return [];
|
|
47929
|
-
const
|
|
48010
|
+
const out2 = [];
|
|
47930
48011
|
raw.forEach((entry, fallbackPosition) => {
|
|
47931
48012
|
if (!entry || typeof entry !== "object") return;
|
|
47932
48013
|
const row = entry;
|
|
47933
48014
|
const fn = row.function;
|
|
47934
|
-
|
|
48015
|
+
out2.push({
|
|
47935
48016
|
position: typeof row.index === "number" ? row.index : fallbackPosition,
|
|
47936
48017
|
id: typeof row.id === "string" ? row.id : void 0,
|
|
47937
48018
|
name: typeof fn?.name === "string" ? fn.name : void 0,
|
|
47938
48019
|
argumentsFragment: typeof fn?.arguments === "string" ? fn.arguments : void 0
|
|
47939
48020
|
});
|
|
47940
48021
|
});
|
|
47941
|
-
return
|
|
48022
|
+
return out2;
|
|
47942
48023
|
}
|
|
47943
48024
|
function readOpenAiLine(line) {
|
|
47944
48025
|
if (!line.startsWith("data:")) return null;
|
|
@@ -48184,11 +48265,11 @@ function origin(apiUrl) {
|
|
|
48184
48265
|
function appAwareFetch(apiUrl, token, base, getToken2) {
|
|
48185
48266
|
return async (input2, init) => {
|
|
48186
48267
|
const target = typeof input2 === "string" ? input2 : String(input2);
|
|
48187
|
-
const
|
|
48188
|
-
if (!
|
|
48268
|
+
const relative2 = target.startsWith("/") && !target.startsWith("//");
|
|
48269
|
+
if (!relative2 && !target.startsWith(`${origin(apiUrl)}/`))
|
|
48189
48270
|
return base(input2, init);
|
|
48190
48271
|
const currentToken = getToken2 ? await renewToken(getToken2) : token;
|
|
48191
|
-
return base(
|
|
48272
|
+
return base(relative2 ? `${origin(apiUrl)}${target}` : target, {
|
|
48192
48273
|
...init,
|
|
48193
48274
|
headers: {
|
|
48194
48275
|
...init?.headers,
|
|
@@ -48316,10 +48397,10 @@ async function askForTheTurn(opts) {
|
|
|
48316
48397
|
};
|
|
48317
48398
|
response = received.response;
|
|
48318
48399
|
responseText = received.text;
|
|
48319
|
-
} catch (
|
|
48400
|
+
} catch (err2) {
|
|
48320
48401
|
throw new LocalTurnFailed(
|
|
48321
48402
|
"handoff",
|
|
48322
|
-
opts.signal?.aborted ? "Stopped this request." :
|
|
48403
|
+
opts.signal?.aborted ? "Stopped this request." : err2 instanceof Error && err2.name === "AbortError" ? "Great Arrow did not answer in time." : cloudSessionId ? "Great Arrow\u2019s reply was interrupted." : "Could not reach Great Arrow.",
|
|
48323
48404
|
false,
|
|
48324
48405
|
cloudSessionId
|
|
48325
48406
|
);
|
|
@@ -48509,17 +48590,17 @@ function firstString(...candidates) {
|
|
|
48509
48590
|
}
|
|
48510
48591
|
function collect(entries, read) {
|
|
48511
48592
|
if (!Array.isArray(entries)) return [];
|
|
48512
|
-
const
|
|
48593
|
+
const out2 = [];
|
|
48513
48594
|
const seen = /* @__PURE__ */ new Set();
|
|
48514
48595
|
for (const entry of entries) {
|
|
48515
|
-
if (
|
|
48596
|
+
if (out2.length >= MAX_LOCAL_MODELS) break;
|
|
48516
48597
|
if (!entry || typeof entry !== "object") continue;
|
|
48517
48598
|
const { id, label, contextLength } = read(entry);
|
|
48518
48599
|
if (!isValidLocalModelId(id)) continue;
|
|
48519
48600
|
if (seen.has(id)) continue;
|
|
48520
48601
|
if (isEmbeddingOnlyModelId(id)) continue;
|
|
48521
48602
|
seen.add(id);
|
|
48522
|
-
|
|
48603
|
+
out2.push({
|
|
48523
48604
|
id,
|
|
48524
48605
|
label: typeof label === "string" && label.length > 0 ? label : id,
|
|
48525
48606
|
// Never assumed. A model is only marked tool-capable once the provider
|
|
@@ -48529,7 +48610,7 @@ function collect(entries, read) {
|
|
|
48529
48610
|
contextLength: positiveInt(contextLength)
|
|
48530
48611
|
});
|
|
48531
48612
|
}
|
|
48532
|
-
return
|
|
48613
|
+
return out2;
|
|
48533
48614
|
}
|
|
48534
48615
|
function normalizeOllamaTags(json3) {
|
|
48535
48616
|
if (!json3 || typeof json3 !== "object") return [];
|
|
@@ -48634,10 +48715,10 @@ async function findInstalledModels(opts) {
|
|
|
48634
48715
|
let response;
|
|
48635
48716
|
try {
|
|
48636
48717
|
response = await ask(doFetch, url2, { method: "GET" }, timeoutMs);
|
|
48637
|
-
} catch (
|
|
48718
|
+
} catch (err2) {
|
|
48638
48719
|
throw new LocalAppUnreachable(
|
|
48639
48720
|
opts.baseUrl,
|
|
48640
|
-
|
|
48721
|
+
err2 instanceof Error && err2.name === "AbortError" ? "It did not answer in time." : "Nothing answered there."
|
|
48641
48722
|
);
|
|
48642
48723
|
}
|
|
48643
48724
|
if (!response.ok) {
|
|
@@ -48730,15 +48811,15 @@ function checkCommand() {
|
|
|
48730
48811
|
let models;
|
|
48731
48812
|
try {
|
|
48732
48813
|
models = await findInstalledModels({ baseUrl, provider });
|
|
48733
|
-
} catch (
|
|
48734
|
-
if (
|
|
48814
|
+
} catch (err2) {
|
|
48815
|
+
if (err2 instanceof LocalAppUnreachable) {
|
|
48735
48816
|
throw new CliError(
|
|
48736
|
-
`Could not reach ${LOCAL_PROVIDER_PRESETS[provider].label} at ${
|
|
48817
|
+
`Could not reach ${LOCAL_PROVIDER_PRESETS[provider].label} at ${err2.baseUrl}. ${err2.message}`,
|
|
48737
48818
|
2 /* NETWORK_ERROR */,
|
|
48738
48819
|
`Start it on this computer and try again, or point somewhere else with --url.`
|
|
48739
48820
|
);
|
|
48740
48821
|
}
|
|
48741
|
-
throw
|
|
48822
|
+
throw err2;
|
|
48742
48823
|
}
|
|
48743
48824
|
const saved = await client2.mcpCall(
|
|
48744
48825
|
"model_local_set",
|
|
@@ -48927,15 +49008,15 @@ function askHereCommand() {
|
|
|
48927
49008
|
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
48928
49009
|
...g.json ? {} : { onWords: (delta) => process.stdout.write(delta) }
|
|
48929
49010
|
});
|
|
48930
|
-
} catch (
|
|
48931
|
-
if (
|
|
49011
|
+
} catch (err2) {
|
|
49012
|
+
if (err2 instanceof LocalTurnFailed) {
|
|
48932
49013
|
throw new CliError(
|
|
48933
|
-
|
|
49014
|
+
err2.message,
|
|
48934
49015
|
2 /* NETWORK_ERROR */,
|
|
48935
|
-
|
|
49016
|
+
err2.closed ? void 0 : "Your conversation may show this one as unfinished."
|
|
48936
49017
|
);
|
|
48937
49018
|
}
|
|
48938
|
-
throw
|
|
49019
|
+
throw err2;
|
|
48939
49020
|
} finally {
|
|
48940
49021
|
process.off("SIGINT", stop2);
|
|
48941
49022
|
}
|
|
@@ -49220,8 +49301,8 @@ function statusCommand3() {
|
|
|
49220
49301
|
let result;
|
|
49221
49302
|
try {
|
|
49222
49303
|
result = await client2.mcpCall("glance", {});
|
|
49223
|
-
} catch (
|
|
49224
|
-
if (
|
|
49304
|
+
} catch (err2) {
|
|
49305
|
+
if (err2 instanceof CliError) throw err2;
|
|
49225
49306
|
fmt.error(
|
|
49226
49307
|
"Couldn't reach Great Arrow. Check your connection, or run 'gad doctor'."
|
|
49227
49308
|
);
|
|
@@ -49255,7 +49336,7 @@ function renderStatus2(payload, plain, apiUrl) {
|
|
|
49255
49336
|
lines.push(c.badge(` ${payload.workspace} `));
|
|
49256
49337
|
lines.push("");
|
|
49257
49338
|
}
|
|
49258
|
-
const hasAny = payload.needsYou.length > 0 || payload.topGoal !== null || payload.integrations.length > 0 || payload.agents.length > 0 || Boolean(payload.healthTriage) || Boolean(payload.credentialRotation) || Boolean(payload.landing) || payload.warRoom !== null && payload.warRoom.priorityCount > 0;
|
|
49339
|
+
const hasAny = payload.needsYou.length > 0 || payload.topGoal !== null || payload.integrations.length > 0 || payload.agents.length > 0 || Boolean(payload.healthTriage) || Boolean(payload.credentialRotation) || Boolean(payload.keyRotation) || Boolean(payload.landing) || payload.warRoom !== null && payload.warRoom.priorityCount > 0;
|
|
49259
49340
|
if (!hasAny) {
|
|
49260
49341
|
lines.push(
|
|
49261
49342
|
`${c.green("\u2713")} You're all clear \u2014 nothing needs you right now.`
|
|
@@ -49329,6 +49410,17 @@ function renderStatus2(payload, plain, apiUrl) {
|
|
|
49329
49410
|
if (url2) lines.push(` ${c.dim("\u2192")} ${link("Open rotation", url2)}`);
|
|
49330
49411
|
lines.push("");
|
|
49331
49412
|
}
|
|
49413
|
+
if (payload.keyRotation) {
|
|
49414
|
+
const k = payload.keyRotation;
|
|
49415
|
+
lines.push(c.bold("Key rotation"));
|
|
49416
|
+
lines.push(
|
|
49417
|
+
` ${k.needsYou} need you \xB7 ${k.pendingDevices} machine updates pending`
|
|
49418
|
+
);
|
|
49419
|
+
const url2 = glanceItemUrl("/settings/key-rotation", apiUrl);
|
|
49420
|
+
if (url2)
|
|
49421
|
+
lines.push(` ${c.dim("\u2192")} ${link("Open key rotation", url2)}`);
|
|
49422
|
+
lines.push("");
|
|
49423
|
+
}
|
|
49332
49424
|
if (payload.landing) {
|
|
49333
49425
|
lines.push(c.bold("Merge queue"));
|
|
49334
49426
|
for (const r of payload.landing.repos) {
|
|
@@ -49385,8 +49477,8 @@ function browserLaunchCommand(url2, platform2 = process.platform) {
|
|
|
49385
49477
|
function openBrowser2(url2) {
|
|
49386
49478
|
const command = browserLaunchCommand(url2);
|
|
49387
49479
|
if (!command) return Promise.resolve(false);
|
|
49388
|
-
return new Promise((
|
|
49389
|
-
execFile3(command.file, command.args, (error62) =>
|
|
49480
|
+
return new Promise((resolve5) => {
|
|
49481
|
+
execFile3(command.file, command.args, (error62) => resolve5(!error62));
|
|
49390
49482
|
});
|
|
49391
49483
|
}
|
|
49392
49484
|
function toSurfaceRow(value) {
|
|
@@ -49644,6 +49736,1166 @@ function callCommand() {
|
|
|
49644
49736
|
});
|
|
49645
49737
|
}
|
|
49646
49738
|
|
|
49739
|
+
// src/commands/keys.ts
|
|
49740
|
+
import { createInterface as createInterface3 } from "node:readline";
|
|
49741
|
+
import { Writable } from "node:stream";
|
|
49742
|
+
|
|
49743
|
+
// src/lib/keys-apply.ts
|
|
49744
|
+
import { spawn } from "node:child_process";
|
|
49745
|
+
import {
|
|
49746
|
+
chmod as chmod2,
|
|
49747
|
+
mkdir as mkdir8,
|
|
49748
|
+
readFile as readFile7,
|
|
49749
|
+
realpath,
|
|
49750
|
+
rename as rename2,
|
|
49751
|
+
stat as stat2,
|
|
49752
|
+
writeFile as writeFile6
|
|
49753
|
+
} from "node:fs/promises";
|
|
49754
|
+
import { homedir as homedir10 } from "node:os";
|
|
49755
|
+
import { basename as basename2, dirname as dirname8, isAbsolute as isAbsolute3, join as join12, relative, sep } from "node:path";
|
|
49756
|
+
var GH_APPLY_TIMEOUT_MS = 3e4;
|
|
49757
|
+
var GIT_APPLY_TIMEOUT_MS = 3e4;
|
|
49758
|
+
function runWithStdin(file2, args, input2, timeoutMs) {
|
|
49759
|
+
return new Promise((resolve5) => {
|
|
49760
|
+
let settled = false;
|
|
49761
|
+
const done = (o) => {
|
|
49762
|
+
if (settled) return;
|
|
49763
|
+
settled = true;
|
|
49764
|
+
clearTimeout(timer);
|
|
49765
|
+
resolve5(o);
|
|
49766
|
+
};
|
|
49767
|
+
let child;
|
|
49768
|
+
try {
|
|
49769
|
+
child = spawn(file2, args, { stdio: ["pipe", "ignore", "ignore"] });
|
|
49770
|
+
} catch {
|
|
49771
|
+
resolve5("not_found");
|
|
49772
|
+
return;
|
|
49773
|
+
}
|
|
49774
|
+
const timer = setTimeout(() => {
|
|
49775
|
+
child.kill("SIGKILL");
|
|
49776
|
+
done("timeout");
|
|
49777
|
+
}, timeoutMs);
|
|
49778
|
+
child.on(
|
|
49779
|
+
"error",
|
|
49780
|
+
(err2) => done(
|
|
49781
|
+
err2.code === "ENOENT" ? "not_found" : "failed"
|
|
49782
|
+
)
|
|
49783
|
+
);
|
|
49784
|
+
child.on("close", (code) => done(code === 0 ? "ok" : "failed"));
|
|
49785
|
+
child.stdin?.on("error", () => done("failed"));
|
|
49786
|
+
child.stdin?.end(input2);
|
|
49787
|
+
});
|
|
49788
|
+
}
|
|
49789
|
+
async function applyGhCli(value) {
|
|
49790
|
+
const outcome = await runWithStdin(
|
|
49791
|
+
"gh",
|
|
49792
|
+
["auth", "login", "--hostname", "github.com", "--with-token"],
|
|
49793
|
+
value,
|
|
49794
|
+
GH_APPLY_TIMEOUT_MS
|
|
49795
|
+
);
|
|
49796
|
+
if (outcome === "ok") return { ok: true, code: "applied" };
|
|
49797
|
+
return { ok: false, code: `gh_${outcome}` };
|
|
49798
|
+
}
|
|
49799
|
+
async function applyGitCredential(value, helper) {
|
|
49800
|
+
if (helper === "gh") return { ok: true, code: "via_gh" };
|
|
49801
|
+
const rejected = await runWithStdin(
|
|
49802
|
+
"git",
|
|
49803
|
+
["credential", "reject"],
|
|
49804
|
+
"protocol=https\nhost=github.com\n\n",
|
|
49805
|
+
GIT_APPLY_TIMEOUT_MS
|
|
49806
|
+
);
|
|
49807
|
+
if (rejected === "not_found" || rejected === "timeout") {
|
|
49808
|
+
return { ok: false, code: `git_${rejected}` };
|
|
49809
|
+
}
|
|
49810
|
+
const approved = await runWithStdin(
|
|
49811
|
+
"git",
|
|
49812
|
+
["credential", "approve"],
|
|
49813
|
+
`protocol=https
|
|
49814
|
+
host=github.com
|
|
49815
|
+
username=x-access-token
|
|
49816
|
+
password=${value}
|
|
49817
|
+
|
|
49818
|
+
`,
|
|
49819
|
+
GIT_APPLY_TIMEOUT_MS
|
|
49820
|
+
);
|
|
49821
|
+
if (approved === "ok") return { ok: true, code: "applied" };
|
|
49822
|
+
return { ok: false, code: `git_${approved}` };
|
|
49823
|
+
}
|
|
49824
|
+
function expandHome(path10) {
|
|
49825
|
+
if (path10 === "~") return homedir10();
|
|
49826
|
+
if (path10.startsWith("~/")) return join12(homedir10(), path10.slice(2));
|
|
49827
|
+
return path10;
|
|
49828
|
+
}
|
|
49829
|
+
function escapeRegExp(s2) {
|
|
49830
|
+
return s2.replace(/[.*+?^${}()|[\]\\-]/g, "\\$&");
|
|
49831
|
+
}
|
|
49832
|
+
function unquote(raw) {
|
|
49833
|
+
const t = raw.trim();
|
|
49834
|
+
if (t.length >= 2) {
|
|
49835
|
+
const q = t[0];
|
|
49836
|
+
if ((q === '"' || q === "'") && t.endsWith(q)) {
|
|
49837
|
+
return { inner: t.slice(1, -1), quote: q };
|
|
49838
|
+
}
|
|
49839
|
+
}
|
|
49840
|
+
return { inner: t, quote: "" };
|
|
49841
|
+
}
|
|
49842
|
+
function formatEnvValue(value, quote) {
|
|
49843
|
+
const needsDouble = /[\n\r]/.test(value);
|
|
49844
|
+
if (quote === "'" && !needsDouble && !value.includes("'")) {
|
|
49845
|
+
return `'${value}'`;
|
|
49846
|
+
}
|
|
49847
|
+
if (quote !== "" || needsDouble || /[\s#"'`$\\]/.test(value)) {
|
|
49848
|
+
const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\r/g, "\\r").replace(/\n/g, "\\n");
|
|
49849
|
+
return `"${escaped}"`;
|
|
49850
|
+
}
|
|
49851
|
+
return value;
|
|
49852
|
+
}
|
|
49853
|
+
async function writeAtomic(path10, content, mode) {
|
|
49854
|
+
const tmp = `${path10}.tmp`;
|
|
49855
|
+
await writeFile6(tmp, content, { mode });
|
|
49856
|
+
await chmod2(tmp, mode);
|
|
49857
|
+
await rename2(tmp, path10);
|
|
49858
|
+
}
|
|
49859
|
+
async function applyEnvFile(path10, key, value) {
|
|
49860
|
+
const file2 = expandHome(path10);
|
|
49861
|
+
let original;
|
|
49862
|
+
let mode = 384;
|
|
49863
|
+
try {
|
|
49864
|
+
original = await readFile7(file2, "utf8");
|
|
49865
|
+
mode = (await stat2(file2)).mode & 511;
|
|
49866
|
+
} catch (err2) {
|
|
49867
|
+
if (err2?.code !== "ENOENT") {
|
|
49868
|
+
return { ok: false, code: "env_read_failed" };
|
|
49869
|
+
}
|
|
49870
|
+
original = null;
|
|
49871
|
+
}
|
|
49872
|
+
const lineRe = new RegExp(
|
|
49873
|
+
`^(\\s*(?:export\\s+)?${escapeRegExp(key)}\\s*=\\s*)(.*?)(\\r?)$`
|
|
49874
|
+
);
|
|
49875
|
+
const lines = original === null ? [] : original.split("\n");
|
|
49876
|
+
let found = false;
|
|
49877
|
+
for (const [i, line] of lines.entries()) {
|
|
49878
|
+
const m = lineRe.exec(line);
|
|
49879
|
+
if (!m) continue;
|
|
49880
|
+
const head = m[1] ?? "";
|
|
49881
|
+
const raw = m[2] ?? "";
|
|
49882
|
+
const cr = m[3] ?? "";
|
|
49883
|
+
const { inner, quote } = unquote(raw);
|
|
49884
|
+
if (inner.startsWith("op://")) {
|
|
49885
|
+
return { ok: true, code: "reference_reread" };
|
|
49886
|
+
}
|
|
49887
|
+
lines[i] = `${head}${formatEnvValue(value, quote)}${cr}`;
|
|
49888
|
+
found = true;
|
|
49889
|
+
}
|
|
49890
|
+
if (!found) {
|
|
49891
|
+
const entry = `${key}=${formatEnvValue(value, "")}`;
|
|
49892
|
+
if (lines.length === 0) {
|
|
49893
|
+
lines.push(entry, "");
|
|
49894
|
+
} else if (lines[lines.length - 1] === "") {
|
|
49895
|
+
lines.splice(lines.length - 1, 0, entry);
|
|
49896
|
+
} else {
|
|
49897
|
+
lines.push(entry);
|
|
49898
|
+
}
|
|
49899
|
+
}
|
|
49900
|
+
try {
|
|
49901
|
+
await writeAtomic(file2, lines.join("\n"), mode);
|
|
49902
|
+
} catch {
|
|
49903
|
+
return { ok: false, code: "env_write_failed" };
|
|
49904
|
+
}
|
|
49905
|
+
return { ok: true, code: "applied" };
|
|
49906
|
+
}
|
|
49907
|
+
async function applySshKey(path10, privatePem) {
|
|
49908
|
+
const file2 = expandHome(path10);
|
|
49909
|
+
const content = privatePem.endsWith("\n") ? privatePem : `${privatePem}
|
|
49910
|
+
`;
|
|
49911
|
+
try {
|
|
49912
|
+
await mkdir8(dirname8(file2), { recursive: true, mode: 448 });
|
|
49913
|
+
await writeAtomic(file2, content, 384);
|
|
49914
|
+
} catch {
|
|
49915
|
+
return { ok: false, code: "ssh_write_failed" };
|
|
49916
|
+
}
|
|
49917
|
+
return { ok: true, code: "applied" };
|
|
49918
|
+
}
|
|
49919
|
+
function envTargetRefusal(path10, key, reported) {
|
|
49920
|
+
if (!isAbsolute3(path10)) return { ok: false, code: "target_invalid" };
|
|
49921
|
+
const known = reported.some((r) => r.path === path10 && r.key === key);
|
|
49922
|
+
return known ? null : { ok: false, code: "target_not_reported" };
|
|
49923
|
+
}
|
|
49924
|
+
var SSH_NOT_A_KEY = /* @__PURE__ */ new Set([
|
|
49925
|
+
"authorized_keys",
|
|
49926
|
+
"authorized_keys2",
|
|
49927
|
+
"config",
|
|
49928
|
+
"known_hosts"
|
|
49929
|
+
]);
|
|
49930
|
+
async function sshTargetRefusal(path10, sshDir = join12(homedir10(), ".ssh")) {
|
|
49931
|
+
const file2 = expandHome(path10);
|
|
49932
|
+
if (!isAbsolute3(file2)) return { ok: false, code: "target_invalid" };
|
|
49933
|
+
if (SSH_NOT_A_KEY.has(basename2(file2))) {
|
|
49934
|
+
return { ok: false, code: "target_not_a_key" };
|
|
49935
|
+
}
|
|
49936
|
+
let root;
|
|
49937
|
+
let parent;
|
|
49938
|
+
try {
|
|
49939
|
+
root = await realpath(sshDir);
|
|
49940
|
+
parent = await realpath(dirname8(file2));
|
|
49941
|
+
} catch {
|
|
49942
|
+
return { ok: false, code: "target_outside_ssh_dir" };
|
|
49943
|
+
}
|
|
49944
|
+
const rel = relative(root, parent);
|
|
49945
|
+
if (rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute3(rel)) {
|
|
49946
|
+
return { ok: false, code: "target_outside_ssh_dir" };
|
|
49947
|
+
}
|
|
49948
|
+
return null;
|
|
49949
|
+
}
|
|
49950
|
+
async function applyUpdate(targetKind, targetRef, value, scope) {
|
|
49951
|
+
try {
|
|
49952
|
+
switch (targetKind) {
|
|
49953
|
+
case "machine_gh_cli":
|
|
49954
|
+
return await applyGhCli(value);
|
|
49955
|
+
case "machine_git_credential":
|
|
49956
|
+
return await applyGitCredential(value, targetRef.helper ?? "other");
|
|
49957
|
+
case "machine_env_file": {
|
|
49958
|
+
if (!targetRef.path || !targetRef.key) {
|
|
49959
|
+
return { ok: false, code: "target_invalid" };
|
|
49960
|
+
}
|
|
49961
|
+
const refused = envTargetRefusal(
|
|
49962
|
+
targetRef.path,
|
|
49963
|
+
targetRef.key,
|
|
49964
|
+
scope.reported
|
|
49965
|
+
);
|
|
49966
|
+
if (refused) return refused;
|
|
49967
|
+
return await applyEnvFile(targetRef.path, targetRef.key, value);
|
|
49968
|
+
}
|
|
49969
|
+
case "machine_ssh_key": {
|
|
49970
|
+
if (!targetRef.path) return { ok: false, code: "target_invalid" };
|
|
49971
|
+
const refused = await sshTargetRefusal(targetRef.path, scope.sshDir);
|
|
49972
|
+
if (refused) return refused;
|
|
49973
|
+
return await applySshKey(targetRef.path, value);
|
|
49974
|
+
}
|
|
49975
|
+
default:
|
|
49976
|
+
return { ok: false, code: "unsupported_target" };
|
|
49977
|
+
}
|
|
49978
|
+
} catch {
|
|
49979
|
+
return { ok: false, code: "apply_error" };
|
|
49980
|
+
}
|
|
49981
|
+
}
|
|
49982
|
+
|
|
49983
|
+
// src/lib/keys-device.ts
|
|
49984
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
49985
|
+
import { readFile as readFile8 } from "node:fs/promises";
|
|
49986
|
+
import { hostname as hostname5 } from "node:os";
|
|
49987
|
+
import { resolve as resolve4 } from "node:path";
|
|
49988
|
+
|
|
49989
|
+
// src/lib/keys-envelope.ts
|
|
49990
|
+
import {
|
|
49991
|
+
createDecipheriv,
|
|
49992
|
+
createPrivateKey,
|
|
49993
|
+
createPublicKey,
|
|
49994
|
+
diffieHellman,
|
|
49995
|
+
generateKeyPairSync,
|
|
49996
|
+
hkdfSync
|
|
49997
|
+
} from "node:crypto";
|
|
49998
|
+
var DEVICE_ENVELOPE_INFO = "gad:key-rotation-device:v1";
|
|
49999
|
+
var MAGIC = Buffer.from("kd1", "ascii");
|
|
50000
|
+
var KEY_LEN = 32;
|
|
50001
|
+
var IV_LEN = 12;
|
|
50002
|
+
var TAG_LEN = 16;
|
|
50003
|
+
var HEADER_LEN = MAGIC.length + KEY_LEN + IV_LEN + TAG_LEN;
|
|
50004
|
+
var SPKI_PREFIX = Buffer.from("302a300506032b656e032100", "hex");
|
|
50005
|
+
var PKCS8_PREFIX = Buffer.from("302e020100300506032b656e04220420", "hex");
|
|
50006
|
+
var EnvelopeError = class extends Error {
|
|
50007
|
+
constructor(code) {
|
|
50008
|
+
super(code);
|
|
50009
|
+
this.code = code;
|
|
50010
|
+
this.name = "EnvelopeError";
|
|
50011
|
+
}
|
|
50012
|
+
code;
|
|
50013
|
+
};
|
|
50014
|
+
function rawKey(b64) {
|
|
50015
|
+
const raw = Buffer.from(b64, "base64");
|
|
50016
|
+
if (raw.length !== KEY_LEN || raw.toString("base64") !== b64) {
|
|
50017
|
+
throw new EnvelopeError("device_key_invalid");
|
|
50018
|
+
}
|
|
50019
|
+
return raw;
|
|
50020
|
+
}
|
|
50021
|
+
function rawPublic(key) {
|
|
50022
|
+
const der = key.export({ format: "der", type: "spki" });
|
|
50023
|
+
return Buffer.from(der.subarray(der.length - KEY_LEN));
|
|
50024
|
+
}
|
|
50025
|
+
function rawPrivate(key) {
|
|
50026
|
+
const der = key.export({ format: "der", type: "pkcs8" });
|
|
50027
|
+
return Buffer.from(der.subarray(der.length - KEY_LEN));
|
|
50028
|
+
}
|
|
50029
|
+
function generateDeviceKeyPair() {
|
|
50030
|
+
const pair = generateKeyPairSync("x25519");
|
|
50031
|
+
return {
|
|
50032
|
+
publicKey: rawPublic(pair.publicKey).toString("base64"),
|
|
50033
|
+
privateKey: rawPrivate(pair.privateKey).toString("base64")
|
|
50034
|
+
};
|
|
50035
|
+
}
|
|
50036
|
+
function openFromServer(sealed, devicePrivateKeyB64) {
|
|
50037
|
+
if (sealed.length < HEADER_LEN || !sealed.subarray(0, MAGIC.length).equals(MAGIC)) {
|
|
50038
|
+
throw new EnvelopeError("envelope_invalid");
|
|
50039
|
+
}
|
|
50040
|
+
const priv = createPrivateKey({
|
|
50041
|
+
key: Buffer.concat([PKCS8_PREFIX, rawKey(devicePrivateKeyB64)]),
|
|
50042
|
+
format: "der",
|
|
50043
|
+
type: "pkcs8"
|
|
50044
|
+
});
|
|
50045
|
+
const devicePub = rawPublic(createPublicKey(priv));
|
|
50046
|
+
let o = MAGIC.length;
|
|
50047
|
+
const ephPub = Buffer.from(sealed.subarray(o, o += KEY_LEN));
|
|
50048
|
+
const iv = sealed.subarray(o, o += IV_LEN);
|
|
50049
|
+
const tag = sealed.subarray(o, o += TAG_LEN);
|
|
50050
|
+
const ct = sealed.subarray(o);
|
|
50051
|
+
let shared;
|
|
50052
|
+
try {
|
|
50053
|
+
shared = diffieHellman({
|
|
50054
|
+
privateKey: priv,
|
|
50055
|
+
publicKey: createPublicKey({
|
|
50056
|
+
key: Buffer.concat([SPKI_PREFIX, ephPub]),
|
|
50057
|
+
format: "der",
|
|
50058
|
+
type: "spki"
|
|
50059
|
+
})
|
|
50060
|
+
});
|
|
50061
|
+
} catch {
|
|
50062
|
+
throw new EnvelopeError("envelope_invalid");
|
|
50063
|
+
}
|
|
50064
|
+
if (shared.every((b) => b === 0)) {
|
|
50065
|
+
throw new EnvelopeError("envelope_invalid");
|
|
50066
|
+
}
|
|
50067
|
+
const key = Buffer.from(
|
|
50068
|
+
hkdfSync(
|
|
50069
|
+
"sha256",
|
|
50070
|
+
shared,
|
|
50071
|
+
Buffer.concat([ephPub, devicePub]),
|
|
50072
|
+
Buffer.from(DEVICE_ENVELOPE_INFO, "utf8"),
|
|
50073
|
+
KEY_LEN
|
|
50074
|
+
)
|
|
50075
|
+
);
|
|
50076
|
+
try {
|
|
50077
|
+
const decipher = createDecipheriv("aes-256-gcm", key, iv);
|
|
50078
|
+
decipher.setAuthTag(tag);
|
|
50079
|
+
return Buffer.concat([decipher.update(ct), decipher.final()]).toString(
|
|
50080
|
+
"utf8"
|
|
50081
|
+
);
|
|
50082
|
+
} catch {
|
|
50083
|
+
throw new EnvelopeError("envelope_invalid");
|
|
50084
|
+
}
|
|
50085
|
+
}
|
|
50086
|
+
|
|
50087
|
+
// src/lib/keys-handoff.ts
|
|
50088
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
50089
|
+
|
|
50090
|
+
// src/lib/keys-paths.ts
|
|
50091
|
+
function keyRotationPath() {
|
|
50092
|
+
return "/settings/key-rotation";
|
|
50093
|
+
}
|
|
50094
|
+
function keyRotationRunPath(runId) {
|
|
50095
|
+
return `/settings/key-rotation/runs/${encodeURIComponent(runId)}`;
|
|
50096
|
+
}
|
|
50097
|
+
function keyRotationHandoffPath(jti) {
|
|
50098
|
+
return `/settings/key-rotation/handoff/${encodeURIComponent(jti)}`;
|
|
50099
|
+
}
|
|
50100
|
+
|
|
50101
|
+
// src/lib/keys-handoff.ts
|
|
50102
|
+
var HANDOFF_POLL_INTERVAL_MS = 2e3;
|
|
50103
|
+
var HANDOFF_DEADLINE_MS = 5 * 6e4;
|
|
50104
|
+
var BROWSER_LAUNCH_TIMEOUT_MS = 5e3;
|
|
50105
|
+
function openInBrowser(url2) {
|
|
50106
|
+
const command = browserLaunchCommand(url2);
|
|
50107
|
+
if (!command) return Promise.resolve(false);
|
|
50108
|
+
return new Promise((resolve5) => {
|
|
50109
|
+
let settled = false;
|
|
50110
|
+
const done = (ok) => {
|
|
50111
|
+
if (settled) return;
|
|
50112
|
+
settled = true;
|
|
50113
|
+
clearTimeout(timer);
|
|
50114
|
+
resolve5(ok);
|
|
50115
|
+
};
|
|
50116
|
+
const timer = setTimeout(() => done(false), BROWSER_LAUNCH_TIMEOUT_MS);
|
|
50117
|
+
timer.unref?.();
|
|
50118
|
+
try {
|
|
50119
|
+
const child = spawn2(command.file, command.args, {
|
|
50120
|
+
detached: true,
|
|
50121
|
+
stdio: "ignore"
|
|
50122
|
+
});
|
|
50123
|
+
child.once("error", () => done(false));
|
|
50124
|
+
child.once("spawn", () => {
|
|
50125
|
+
child.unref();
|
|
50126
|
+
done(true);
|
|
50127
|
+
});
|
|
50128
|
+
} catch {
|
|
50129
|
+
done(false);
|
|
50130
|
+
}
|
|
50131
|
+
});
|
|
50132
|
+
}
|
|
50133
|
+
var defaultSleep = (ms) => new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
50134
|
+
function stepUpError(message, hint) {
|
|
50135
|
+
return new CliError(message, 1 /* AUTH_ERROR */, hint);
|
|
50136
|
+
}
|
|
50137
|
+
async function requestBrowserStepUp(client2, kind, subjectId, opts = {}) {
|
|
50138
|
+
const openUrl = opts.openUrl ?? openInBrowser;
|
|
50139
|
+
const notify = opts.notify ?? ((line) => process.stderr.write(`${line}
|
|
50140
|
+
`));
|
|
50141
|
+
const sleep2 = opts.sleep ?? defaultSleep;
|
|
50142
|
+
const now = opts.now ?? Date.now;
|
|
50143
|
+
const interval = opts.pollIntervalMs ?? HANDOFF_POLL_INTERVAL_MS;
|
|
50144
|
+
const deadline = now() + (opts.deadlineMs ?? HANDOFF_DEADLINE_MS);
|
|
50145
|
+
const created = await client2.post("/api/key-rotation/handoffs", {
|
|
50146
|
+
kind,
|
|
50147
|
+
subjectId
|
|
50148
|
+
});
|
|
50149
|
+
const jti = typeof created?.jti === "string" ? created.jti : null;
|
|
50150
|
+
if (!jti || !/^[A-Za-z0-9-]{1,64}$/.test(jti)) {
|
|
50151
|
+
throw stepUpError("The server did not return a browser approval.");
|
|
50152
|
+
}
|
|
50153
|
+
const url2 = `${client2.apiOrigin}${keyRotationHandoffPath(jti)}`;
|
|
50154
|
+
notify(`Approve this in your browser (passkey or two-step code): ${url2}`);
|
|
50155
|
+
if (!await openUrl(url2)) {
|
|
50156
|
+
notify("Couldn't launch a browser. Open the URL above to approve.");
|
|
50157
|
+
}
|
|
50158
|
+
while (now() < deadline) {
|
|
50159
|
+
const polled = await client2.get(
|
|
50160
|
+
`/api/key-rotation/handoffs/${encodeURIComponent(jti)}`
|
|
50161
|
+
);
|
|
50162
|
+
const status = polled?.status;
|
|
50163
|
+
if (status === "approved") {
|
|
50164
|
+
if (typeof polled.token === "string" && polled.token.length > 0) {
|
|
50165
|
+
return polled.token;
|
|
50166
|
+
}
|
|
50167
|
+
throw stepUpError(
|
|
50168
|
+
"This approval was already collected by another request.",
|
|
50169
|
+
"Run the command again to request a new approval."
|
|
50170
|
+
);
|
|
50171
|
+
}
|
|
50172
|
+
if (status === "consumed") {
|
|
50173
|
+
throw stepUpError(
|
|
50174
|
+
"This approval was already used.",
|
|
50175
|
+
"Run the command again to request a new approval."
|
|
50176
|
+
);
|
|
50177
|
+
}
|
|
50178
|
+
if (status === "expired") {
|
|
50179
|
+
throw stepUpError(
|
|
50180
|
+
"The browser approval expired.",
|
|
50181
|
+
"Run the command again and approve within 5 minutes."
|
|
50182
|
+
);
|
|
50183
|
+
}
|
|
50184
|
+
await sleep2(interval);
|
|
50185
|
+
}
|
|
50186
|
+
throw stepUpError(
|
|
50187
|
+
"Timed out waiting for the browser approval.",
|
|
50188
|
+
"Run the command again and approve within 5 minutes."
|
|
50189
|
+
);
|
|
50190
|
+
}
|
|
50191
|
+
|
|
50192
|
+
// src/lib/keys-device.ts
|
|
50193
|
+
var DEFAULT_ENV_FILE = ".env.local";
|
|
50194
|
+
var DETECT_TIMEOUT_MS = 5e3;
|
|
50195
|
+
var MAX_ENV_KEYS = 500;
|
|
50196
|
+
var REPORT_KEY = /^[A-Z_][A-Z0-9_]{0,127}$/;
|
|
50197
|
+
var REPORT_PATH = /^[ -~]{1,200}$/;
|
|
50198
|
+
var TOKEN_SHAPED = /[A-Za-z0-9]{33,}/;
|
|
50199
|
+
var SECRET_PREFIX = /(gh[pousr]_|github_pat_|-----BEGIN)/;
|
|
50200
|
+
var UUID5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
50201
|
+
function deviceSlot(workspaceId) {
|
|
50202
|
+
return `key-rotation-device:${workspaceId}`;
|
|
50203
|
+
}
|
|
50204
|
+
function parseReported(v) {
|
|
50205
|
+
if (!Array.isArray(v)) return [];
|
|
50206
|
+
return v.flatMap((r) => {
|
|
50207
|
+
const o = r;
|
|
50208
|
+
return typeof o?.path === "string" && typeof o.key === "string" ? [{ path: o.path, key: o.key }] : [];
|
|
50209
|
+
});
|
|
50210
|
+
}
|
|
50211
|
+
function parsePending(v) {
|
|
50212
|
+
const o = v;
|
|
50213
|
+
if (typeof o?.publicKey !== "string" || typeof o.privateKey !== "string") {
|
|
50214
|
+
return null;
|
|
50215
|
+
}
|
|
50216
|
+
return {
|
|
50217
|
+
enrollmentId: typeof o.enrollmentId === "string" ? o.enrollmentId : null,
|
|
50218
|
+
publicKey: o.publicKey,
|
|
50219
|
+
privateKey: o.privateKey,
|
|
50220
|
+
reported: parseReported(o.reported)
|
|
50221
|
+
};
|
|
50222
|
+
}
|
|
50223
|
+
async function loadDevice(workspaceId) {
|
|
50224
|
+
const raw = await getSecretSlot(deviceSlot(workspaceId));
|
|
50225
|
+
if (!raw) return null;
|
|
50226
|
+
try {
|
|
50227
|
+
const parsed = JSON.parse(raw);
|
|
50228
|
+
if (parsed?.v !== 1 || typeof parsed.privateKey !== "string" || typeof parsed.publicKey !== "string") {
|
|
50229
|
+
return null;
|
|
50230
|
+
}
|
|
50231
|
+
return {
|
|
50232
|
+
v: 1,
|
|
50233
|
+
deviceId: typeof parsed.deviceId === "string" ? parsed.deviceId : null,
|
|
50234
|
+
enrollmentId: typeof parsed.enrollmentId === "string" ? parsed.enrollmentId : null,
|
|
50235
|
+
publicKey: parsed.publicKey,
|
|
50236
|
+
privateKey: parsed.privateKey,
|
|
50237
|
+
reported: parseReported(parsed.reported),
|
|
50238
|
+
pendingReplacement: parsePending(parsed.pendingReplacement)
|
|
50239
|
+
};
|
|
50240
|
+
} catch {
|
|
50241
|
+
return null;
|
|
50242
|
+
}
|
|
50243
|
+
}
|
|
50244
|
+
async function saveDevice(workspaceId, device) {
|
|
50245
|
+
if (!await setSecretSlot(deviceSlot(workspaceId), JSON.stringify(device))) {
|
|
50246
|
+
throw new CliError(
|
|
50247
|
+
"Could not store this machine's device key in the keychain.",
|
|
50248
|
+
3 /* VALIDATION_ERROR */,
|
|
50249
|
+
"Unlock your keychain (or check ~/.great-arrow permissions) and try again."
|
|
50250
|
+
);
|
|
50251
|
+
}
|
|
50252
|
+
}
|
|
50253
|
+
async function requireEnrolledDevice(workspaceId) {
|
|
50254
|
+
const device = await loadDevice(workspaceId);
|
|
50255
|
+
if (!device?.deviceId) {
|
|
50256
|
+
throw new CliError(
|
|
50257
|
+
"This machine is not enrolled for key rotation in this workspace.",
|
|
50258
|
+
3 /* VALIDATION_ERROR */,
|
|
50259
|
+
"Run 'gad keys enroll' first."
|
|
50260
|
+
);
|
|
50261
|
+
}
|
|
50262
|
+
return { ...device, deviceId: device.deviceId };
|
|
50263
|
+
}
|
|
50264
|
+
function nameOk(s2) {
|
|
50265
|
+
return !TOKEN_SHAPED.test(s2) && !SECRET_PREFIX.test(s2);
|
|
50266
|
+
}
|
|
50267
|
+
function isOpReference(rawValue) {
|
|
50268
|
+
const t = rawValue.trim();
|
|
50269
|
+
const q = t[0];
|
|
50270
|
+
const inner = t.length >= 2 && (q === '"' || q === "'") && t.endsWith(q) ? t.slice(1, -1) : t;
|
|
50271
|
+
return inner.startsWith("op://");
|
|
50272
|
+
}
|
|
50273
|
+
async function scanEnvKeys(paths) {
|
|
50274
|
+
const out2 = [];
|
|
50275
|
+
const seen = /* @__PURE__ */ new Set();
|
|
50276
|
+
for (const p of paths) {
|
|
50277
|
+
const path10 = resolve4(p);
|
|
50278
|
+
if (seen.has(path10)) continue;
|
|
50279
|
+
seen.add(path10);
|
|
50280
|
+
if (!REPORT_PATH.test(path10) || !nameOk(path10)) continue;
|
|
50281
|
+
let text3;
|
|
50282
|
+
try {
|
|
50283
|
+
text3 = await readFile8(path10, "utf8");
|
|
50284
|
+
} catch {
|
|
50285
|
+
continue;
|
|
50286
|
+
}
|
|
50287
|
+
for (const line of text3.split(/\r?\n/)) {
|
|
50288
|
+
const m = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_.-]*)\s*=(.*)$/.exec(
|
|
50289
|
+
line
|
|
50290
|
+
);
|
|
50291
|
+
const key = m?.[1];
|
|
50292
|
+
if (!key || !REPORT_KEY.test(key)) continue;
|
|
50293
|
+
out2.push({ path: path10, key, isReference: isOpReference(m?.[2] ?? "") });
|
|
50294
|
+
if (out2.length >= MAX_ENV_KEYS) return out2;
|
|
50295
|
+
}
|
|
50296
|
+
}
|
|
50297
|
+
return out2;
|
|
50298
|
+
}
|
|
50299
|
+
function helperKind(raw) {
|
|
50300
|
+
const v = raw.trim();
|
|
50301
|
+
if (!v) return null;
|
|
50302
|
+
if (/\bgh(\.exe)?\s+auth\s+git-credential\b/.test(v)) return "gh";
|
|
50303
|
+
if (/osxkeychain/.test(v)) return "osxkeychain";
|
|
50304
|
+
if (/^store\b/.test(v)) return "store";
|
|
50305
|
+
return "other";
|
|
50306
|
+
}
|
|
50307
|
+
function run2(file2, args) {
|
|
50308
|
+
return new Promise((done) => {
|
|
50309
|
+
execFile4(
|
|
50310
|
+
file2,
|
|
50311
|
+
args,
|
|
50312
|
+
{ timeout: DETECT_TIMEOUT_MS, encoding: "utf8" },
|
|
50313
|
+
(error62, stdout) => done(error62 ? null : String(stdout))
|
|
50314
|
+
);
|
|
50315
|
+
});
|
|
50316
|
+
}
|
|
50317
|
+
async function detectGhCli() {
|
|
50318
|
+
return await run2("gh", ["--version"]) !== null;
|
|
50319
|
+
}
|
|
50320
|
+
async function detectGitHelper() {
|
|
50321
|
+
const out2 = await run2("git", [
|
|
50322
|
+
"config",
|
|
50323
|
+
"--get-urlmatch",
|
|
50324
|
+
"credential.helper",
|
|
50325
|
+
"https://github.com"
|
|
50326
|
+
]);
|
|
50327
|
+
return out2 === null ? null : helperKind(out2);
|
|
50328
|
+
}
|
|
50329
|
+
async function buildDeviceReport(envFiles) {
|
|
50330
|
+
const [envKeys, ghCli, gitHelper] = await Promise.all([
|
|
50331
|
+
scanEnvKeys([...envFiles, DEFAULT_ENV_FILE]),
|
|
50332
|
+
detectGhCli(),
|
|
50333
|
+
detectGitHelper()
|
|
50334
|
+
]);
|
|
50335
|
+
return { envKeys, ghCli, gitHelper };
|
|
50336
|
+
}
|
|
50337
|
+
function defaultDeviceLabel() {
|
|
50338
|
+
const label = hostname5().replace(/[^ -~]/g, "-").slice(0, 80).trim();
|
|
50339
|
+
return label && nameOk(label) ? label : "this machine";
|
|
50340
|
+
}
|
|
50341
|
+
async function enroll(client2, workspaceId, opts = {}) {
|
|
50342
|
+
const existing = await loadDevice(workspaceId);
|
|
50343
|
+
const replacing = existing?.deviceId ? existing : null;
|
|
50344
|
+
if (replacing && !opts.replace) {
|
|
50345
|
+
throw new CliError(
|
|
50346
|
+
"This machine is already enrolled for key rotation in this workspace.",
|
|
50347
|
+
3 /* VALIDATION_ERROR */,
|
|
50348
|
+
"Run 'gad keys pending' to see its updates, or 'gad keys enroll --replace' to enroll it again with a new key."
|
|
50349
|
+
);
|
|
50350
|
+
}
|
|
50351
|
+
const label = opts.label ?? defaultDeviceLabel();
|
|
50352
|
+
const report = await (opts.report ?? buildDeviceReport)(opts.envFiles ?? []);
|
|
50353
|
+
const pair = generateDeviceKeyPair();
|
|
50354
|
+
const pending = {
|
|
50355
|
+
enrollmentId: null,
|
|
50356
|
+
publicKey: pair.publicKey,
|
|
50357
|
+
privateKey: pair.privateKey,
|
|
50358
|
+
reported: report.envKeys.map(({ path: path10, key }) => ({ path: path10, key }))
|
|
50359
|
+
};
|
|
50360
|
+
const savePending = () => saveDevice(
|
|
50361
|
+
workspaceId,
|
|
50362
|
+
replacing ? { ...replacing, pendingReplacement: { ...pending } } : {
|
|
50363
|
+
v: 1,
|
|
50364
|
+
deviceId: null,
|
|
50365
|
+
enrollmentId: pending.enrollmentId,
|
|
50366
|
+
publicKey: pending.publicKey,
|
|
50367
|
+
privateKey: pending.privateKey,
|
|
50368
|
+
reported: pending.reported,
|
|
50369
|
+
pendingReplacement: null
|
|
50370
|
+
}
|
|
50371
|
+
);
|
|
50372
|
+
await savePending();
|
|
50373
|
+
const begun = await client2.post("/api/key-rotation/devices", {
|
|
50374
|
+
label,
|
|
50375
|
+
publicKey: pair.publicKey,
|
|
50376
|
+
report
|
|
50377
|
+
});
|
|
50378
|
+
const enrollmentId = typeof begun?.enrollmentId === "string" && UUID5.test(begun.enrollmentId) ? begun.enrollmentId : null;
|
|
50379
|
+
if (!enrollmentId) {
|
|
50380
|
+
throw new CliError(
|
|
50381
|
+
"The server did not start the enrollment.",
|
|
50382
|
+
2 /* NETWORK_ERROR */
|
|
50383
|
+
);
|
|
50384
|
+
}
|
|
50385
|
+
pending.enrollmentId = enrollmentId;
|
|
50386
|
+
await savePending();
|
|
50387
|
+
const approvalToken = await (opts.stepUp ?? requestBrowserStepUp)(
|
|
50388
|
+
client2,
|
|
50389
|
+
"device_enroll",
|
|
50390
|
+
enrollmentId
|
|
50391
|
+
);
|
|
50392
|
+
const done = await client2.post(`/api/key-rotation/devices/${enrollmentId}`, {
|
|
50393
|
+
action: "enroll",
|
|
50394
|
+
approvalToken
|
|
50395
|
+
});
|
|
50396
|
+
const deviceId = typeof done?.deviceId === "string" && UUID5.test(done.deviceId) ? done.deviceId : null;
|
|
50397
|
+
if (!deviceId) {
|
|
50398
|
+
throw new CliError(
|
|
50399
|
+
"The server did not complete the enrollment.",
|
|
50400
|
+
2 /* NETWORK_ERROR */
|
|
50401
|
+
);
|
|
50402
|
+
}
|
|
50403
|
+
await saveDevice(workspaceId, {
|
|
50404
|
+
v: 1,
|
|
50405
|
+
deviceId,
|
|
50406
|
+
enrollmentId,
|
|
50407
|
+
publicKey: pending.publicKey,
|
|
50408
|
+
privateKey: pending.privateKey,
|
|
50409
|
+
reported: pending.reported,
|
|
50410
|
+
pendingReplacement: null
|
|
50411
|
+
});
|
|
50412
|
+
let replaced = null;
|
|
50413
|
+
if (replacing?.deviceId && replacing.deviceId !== deviceId) {
|
|
50414
|
+
try {
|
|
50415
|
+
await client2.delete(`/api/key-rotation/devices/${replacing.deviceId}`);
|
|
50416
|
+
replaced = { deviceId: replacing.deviceId, revoked: true };
|
|
50417
|
+
} catch {
|
|
50418
|
+
replaced = { deviceId: replacing.deviceId, revoked: false };
|
|
50419
|
+
}
|
|
50420
|
+
}
|
|
50421
|
+
return { deviceId, report, replaced };
|
|
50422
|
+
}
|
|
50423
|
+
|
|
50424
|
+
// src/commands/keys.ts
|
|
50425
|
+
var UUID6 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
50426
|
+
function patRequired(apiUrl) {
|
|
50427
|
+
return authError(
|
|
50428
|
+
"gad keys needs a personal access token; this sign-in is an OAuth session.",
|
|
50429
|
+
`Create a token at ${apiUrl}/install/cli, then run 'gad login --token <PAT>'.`
|
|
50430
|
+
);
|
|
50431
|
+
}
|
|
50432
|
+
function keyRotationError(error62, apiUrl) {
|
|
50433
|
+
switch (serverCodeOf(error62)) {
|
|
50434
|
+
case "oauth_not_allowed":
|
|
50435
|
+
return patRequired(apiUrl);
|
|
50436
|
+
case "web_session_required":
|
|
50437
|
+
return new CliError(
|
|
50438
|
+
"This key-rotation action is only available in a signed-in browser.",
|
|
50439
|
+
1 /* AUTH_ERROR */,
|
|
50440
|
+
`Open ${apiUrl}${keyRotationPath()} to do it there.`
|
|
50441
|
+
);
|
|
50442
|
+
case "step_up_required":
|
|
50443
|
+
return new CliError(
|
|
50444
|
+
"The browser approval was missing, expired or already used.",
|
|
50445
|
+
1 /* AUTH_ERROR */,
|
|
50446
|
+
"Run the command again and approve it in your browser."
|
|
50447
|
+
);
|
|
50448
|
+
default:
|
|
50449
|
+
return error62;
|
|
50450
|
+
}
|
|
50451
|
+
}
|
|
50452
|
+
function keysClient(inner, apiUrl) {
|
|
50453
|
+
const mapped = async (call) => {
|
|
50454
|
+
try {
|
|
50455
|
+
return await call();
|
|
50456
|
+
} catch (e) {
|
|
50457
|
+
throw keyRotationError(e, apiUrl);
|
|
50458
|
+
}
|
|
50459
|
+
};
|
|
50460
|
+
return {
|
|
50461
|
+
apiOrigin: new URL(apiUrl).origin,
|
|
50462
|
+
get: (path10, params) => mapped(() => inner.get(path10, params)),
|
|
50463
|
+
post: (path10, body) => mapped(() => inner.post(path10, body)),
|
|
50464
|
+
delete: (path10) => mapped(() => inner.delete(path10))
|
|
50465
|
+
};
|
|
50466
|
+
}
|
|
50467
|
+
async function keysContext() {
|
|
50468
|
+
const auth = await resolveAuth();
|
|
50469
|
+
const apiUrl = auth.apiUrl.replace(/\/$/, "");
|
|
50470
|
+
if (auth.tokenType === "oauth") throw patRequired(apiUrl);
|
|
50471
|
+
const probe = new GadClient({
|
|
50472
|
+
token: auth.token,
|
|
50473
|
+
getToken: auth.getToken,
|
|
50474
|
+
apiUrl: auth.apiUrl
|
|
50475
|
+
});
|
|
50476
|
+
const value = await probe.mcpCall("workspace_introspect", {}, 5e3);
|
|
50477
|
+
const workspaceId = value?.workspace?.id;
|
|
50478
|
+
if (value?.error || !workspaceId || !UUID6.test(workspaceId)) {
|
|
50479
|
+
throw validationError(
|
|
50480
|
+
"GreatArrow.ai could not confirm your workspace.",
|
|
50481
|
+
"Run 'gad whoami', or choose one with 'gad --workspace <id>'."
|
|
50482
|
+
);
|
|
50483
|
+
}
|
|
50484
|
+
return {
|
|
50485
|
+
client: keysClient(
|
|
50486
|
+
new GadClient({
|
|
50487
|
+
token: auth.token,
|
|
50488
|
+
getToken: auth.getToken,
|
|
50489
|
+
apiUrl: auth.apiUrl,
|
|
50490
|
+
workspaceId
|
|
50491
|
+
}),
|
|
50492
|
+
apiUrl
|
|
50493
|
+
),
|
|
50494
|
+
workspaceId,
|
|
50495
|
+
apiUrl
|
|
50496
|
+
};
|
|
50497
|
+
}
|
|
50498
|
+
function requireRunId(runId) {
|
|
50499
|
+
if (!UUID6.test(runId)) {
|
|
50500
|
+
throw validationError(
|
|
50501
|
+
`'${stripControlChars(runId)}' is not a run id.`,
|
|
50502
|
+
"Copy the run id from 'gad keys list' or the run page."
|
|
50503
|
+
);
|
|
50504
|
+
}
|
|
50505
|
+
return runId.toLowerCase();
|
|
50506
|
+
}
|
|
50507
|
+
var s = (v) => typeof v === "string" ? stripControlChars(v) : "";
|
|
50508
|
+
function out(line) {
|
|
50509
|
+
process.stdout.write(`${line}
|
|
50510
|
+
`);
|
|
50511
|
+
}
|
|
50512
|
+
function err(line) {
|
|
50513
|
+
process.stderr.write(`${line}
|
|
50514
|
+
`);
|
|
50515
|
+
}
|
|
50516
|
+
function listCommand4() {
|
|
50517
|
+
return new Command("list").description("List the credentials registered for key rotation").action(async (_opts, command) => {
|
|
50518
|
+
const g = globalOutputOpts(command);
|
|
50519
|
+
const { client: client2 } = await keysContext();
|
|
50520
|
+
const res = await client2.get("/api/key-rotation/credentials");
|
|
50521
|
+
const rows = Array.isArray(res?.credentials) ? res.credentials : [];
|
|
50522
|
+
if (g.json) {
|
|
50523
|
+
out(JSON.stringify(rows));
|
|
50524
|
+
return;
|
|
50525
|
+
}
|
|
50526
|
+
if (rows.length === 0) {
|
|
50527
|
+
out(
|
|
50528
|
+
"No credentials registered. Add one under Settings \u2192 Key rotation."
|
|
50529
|
+
);
|
|
50530
|
+
return;
|
|
50531
|
+
}
|
|
50532
|
+
const c = createColor(g.noColor || g.quiet);
|
|
50533
|
+
for (const r of rows) {
|
|
50534
|
+
const flags = [
|
|
50535
|
+
r.openLeak === true ? c.red("leak") : "",
|
|
50536
|
+
typeof r.liveRunId === "string" ? `run ${s(r.liveRunId)}` : ""
|
|
50537
|
+
].filter(Boolean).join(" \xB7 ");
|
|
50538
|
+
out(
|
|
50539
|
+
`${c.bold(s(r.label))} ${c.dim(s(r.kind))} ${s(r.id)} usages ${typeof r.usageCount === "number" ? r.usageCount : 0} rotated ${s(r.lastRotatedAt) || "never"}` + (flags ? ` ${flags}` : "")
|
|
50540
|
+
);
|
|
50541
|
+
}
|
|
50542
|
+
});
|
|
50543
|
+
}
|
|
50544
|
+
function statusCommand4() {
|
|
50545
|
+
return new Command("status").description("Show one rotation run: steps, checklist and devices").argument("<run>", "Run id").action(async (runArg, _opts, command) => {
|
|
50546
|
+
const g = globalOutputOpts(command);
|
|
50547
|
+
const runId = requireRunId(runArg);
|
|
50548
|
+
const { client: client2, apiUrl } = await keysContext();
|
|
50549
|
+
const res = await client2.get(`/api/key-rotation/runs/${runId}`);
|
|
50550
|
+
const run3 = res?.run ?? {};
|
|
50551
|
+
if (g.json) {
|
|
50552
|
+
out(JSON.stringify(run3));
|
|
50553
|
+
return;
|
|
50554
|
+
}
|
|
50555
|
+
const c = createColor(g.noColor || g.quiet);
|
|
50556
|
+
out(
|
|
50557
|
+
`${c.bold(`Run ${runId}`)} ${s(run3.state)}` + (s(run3.waitingOn) ? c.dim(` waiting on ${s(run3.waitingOn)}`) : "")
|
|
50558
|
+
);
|
|
50559
|
+
for (const st of run3.steps ?? []) {
|
|
50560
|
+
const detail = s(st.detailCode);
|
|
50561
|
+
out(
|
|
50562
|
+
` ${s(st.step)} ${c.dim(s(st.targetKind))} ${s(st.status)}` + (detail ? c.dim(` (${detail})`) : "")
|
|
50563
|
+
);
|
|
50564
|
+
}
|
|
50565
|
+
const open4 = (run3.checklist ?? []).filter((i) => i.ticked !== true);
|
|
50566
|
+
if (open4.length > 0) {
|
|
50567
|
+
out(c.yellow("Checklist (tick these in the browser):"));
|
|
50568
|
+
for (const item of open4) {
|
|
50569
|
+
out(` \u2610 ${s(item.label)} ${c.cyan(s(item.href))}`);
|
|
50570
|
+
}
|
|
50571
|
+
}
|
|
50572
|
+
for (const d of run3.devices ?? []) {
|
|
50573
|
+
out(` device ${s(d.label)} ${s(d.state)}`);
|
|
50574
|
+
}
|
|
50575
|
+
out(c.dim(`${apiUrl}${keyRotationRunPath(runId)}`));
|
|
50576
|
+
});
|
|
50577
|
+
}
|
|
50578
|
+
function collect2(value, previous) {
|
|
50579
|
+
return [...previous, value];
|
|
50580
|
+
}
|
|
50581
|
+
function enrollCommand() {
|
|
50582
|
+
return new Command("enroll").description(
|
|
50583
|
+
"Enroll this machine to receive rotated keys (approve in the browser)"
|
|
50584
|
+
).option("--label <label>", "Device label (defaults to the host name)").option(
|
|
50585
|
+
"--env-file <path>",
|
|
50586
|
+
"An env file to report key NAMES from (repeatable; ./.env.local is always included)",
|
|
50587
|
+
collect2,
|
|
50588
|
+
[]
|
|
50589
|
+
).option(
|
|
50590
|
+
"--replace",
|
|
50591
|
+
"Enroll again with a new key, replacing this machine's"
|
|
50592
|
+
).action(async (opts, command) => {
|
|
50593
|
+
const g = globalOutputOpts(command);
|
|
50594
|
+
const { client: client2, workspaceId } = await keysContext();
|
|
50595
|
+
const { deviceId, report, replaced } = await enroll(client2, workspaceId, {
|
|
50596
|
+
...typeof opts.label === "string" ? { label: opts.label } : {},
|
|
50597
|
+
envFiles: Array.isArray(opts.envFile) ? opts.envFile : [],
|
|
50598
|
+
replace: opts.replace === true
|
|
50599
|
+
});
|
|
50600
|
+
if (g.json) {
|
|
50601
|
+
out(JSON.stringify({ deviceId, report, replaced }));
|
|
50602
|
+
} else {
|
|
50603
|
+
out(`Enrolled this machine as device ${deviceId}.`);
|
|
50604
|
+
out(
|
|
50605
|
+
`Reported ${report.envKeys.length} env key name(s), gh CLI ${report.ghCli ? "found" : "not found"}, git helper ${report.gitHelper ?? "none"}.`
|
|
50606
|
+
);
|
|
50607
|
+
if (replaced?.revoked) {
|
|
50608
|
+
out(
|
|
50609
|
+
`Revoked the device it replaced (${replaced.deviceId}); its queued updates expired.`
|
|
50610
|
+
);
|
|
50611
|
+
out(
|
|
50612
|
+
"Usages confirmed for that device still point at it: confirm them for this one under Settings \u2192 Key rotation."
|
|
50613
|
+
);
|
|
50614
|
+
}
|
|
50615
|
+
}
|
|
50616
|
+
if (replaced && !replaced.revoked) {
|
|
50617
|
+
throw new CliError(
|
|
50618
|
+
`Enrolled, but the device it replaced (${replaced.deviceId}) could not be revoked.`,
|
|
50619
|
+
2 /* NETWORK_ERROR */,
|
|
50620
|
+
"Revoke it under Settings \u2192 Key rotation; updates sealed to it can no longer be opened on this machine."
|
|
50621
|
+
);
|
|
50622
|
+
}
|
|
50623
|
+
});
|
|
50624
|
+
}
|
|
50625
|
+
function toUpdateRow(v) {
|
|
50626
|
+
if (typeof v !== "object" || v === null) return null;
|
|
50627
|
+
const r = v;
|
|
50628
|
+
if (typeof r.id !== "string" || !UUID6.test(r.id)) return null;
|
|
50629
|
+
const ref = {};
|
|
50630
|
+
if (typeof r.targetRef === "object" && r.targetRef !== null) {
|
|
50631
|
+
for (const [k, val] of Object.entries(r.targetRef)) {
|
|
50632
|
+
if (typeof val === "string") ref[k] = val;
|
|
50633
|
+
}
|
|
50634
|
+
}
|
|
50635
|
+
return {
|
|
50636
|
+
id: r.id,
|
|
50637
|
+
runId: typeof r.runId === "string" ? r.runId : "",
|
|
50638
|
+
targetKind: typeof r.targetKind === "string" ? r.targetKind : "",
|
|
50639
|
+
targetRef: ref
|
|
50640
|
+
};
|
|
50641
|
+
}
|
|
50642
|
+
function describeTarget(u) {
|
|
50643
|
+
const ref = u.targetRef;
|
|
50644
|
+
switch (u.targetKind) {
|
|
50645
|
+
case "machine_env_file":
|
|
50646
|
+
return `${s(ref.key)} in ${s(ref.path)}`;
|
|
50647
|
+
case "machine_ssh_key":
|
|
50648
|
+
return `SSH key ${s(ref.path)}`;
|
|
50649
|
+
case "machine_git_credential":
|
|
50650
|
+
return `git credential (${s(ref.helper)})`;
|
|
50651
|
+
case "machine_gh_cli":
|
|
50652
|
+
return "gh CLI login";
|
|
50653
|
+
default:
|
|
50654
|
+
return s(u.targetKind);
|
|
50655
|
+
}
|
|
50656
|
+
}
|
|
50657
|
+
async function listUpdates(client2, deviceId) {
|
|
50658
|
+
const res = await client2.get(
|
|
50659
|
+
`/api/key-rotation/devices/${deviceId}/updates`
|
|
50660
|
+
);
|
|
50661
|
+
return (Array.isArray(res?.updates) ? res.updates : []).map(toUpdateRow).filter((u) => u !== null);
|
|
50662
|
+
}
|
|
50663
|
+
function pendingCommand() {
|
|
50664
|
+
return new Command("pending").description("List the key updates queued for this machine").action(async (_opts, command) => {
|
|
50665
|
+
const g = globalOutputOpts(command);
|
|
50666
|
+
const { client: client2, workspaceId } = await keysContext();
|
|
50667
|
+
const device = await requireEnrolledDevice(workspaceId);
|
|
50668
|
+
const updates = await listUpdates(client2, device.deviceId);
|
|
50669
|
+
if (g.json) {
|
|
50670
|
+
out(JSON.stringify(updates));
|
|
50671
|
+
return;
|
|
50672
|
+
}
|
|
50673
|
+
if (updates.length === 0) {
|
|
50674
|
+
out("No key updates are waiting for this machine.");
|
|
50675
|
+
return;
|
|
50676
|
+
}
|
|
50677
|
+
for (const u of updates) out(` ${describeTarget(u)} ${u.id}`);
|
|
50678
|
+
out("Run 'gad keys apply' to apply them.");
|
|
50679
|
+
});
|
|
50680
|
+
}
|
|
50681
|
+
async function ack(client2, deviceId, updateId, result) {
|
|
50682
|
+
await client2.post(
|
|
50683
|
+
`/api/key-rotation/devices/${deviceId}/updates/${updateId}`,
|
|
50684
|
+
{
|
|
50685
|
+
action: "ack",
|
|
50686
|
+
ok: result.ok,
|
|
50687
|
+
detailCode: result.code
|
|
50688
|
+
}
|
|
50689
|
+
);
|
|
50690
|
+
}
|
|
50691
|
+
async function fetchOpenApply(client2, device, u, approvalToken) {
|
|
50692
|
+
let sealed;
|
|
50693
|
+
try {
|
|
50694
|
+
const fetched = await client2.post(
|
|
50695
|
+
`/api/key-rotation/devices/${device.deviceId}/updates/${u.id}`,
|
|
50696
|
+
{ action: "fetch", approvalToken }
|
|
50697
|
+
);
|
|
50698
|
+
if (typeof fetched?.sealedPayload !== "string") {
|
|
50699
|
+
return { ack: false, ok: false, code: "fetch_failed" };
|
|
50700
|
+
}
|
|
50701
|
+
sealed = fetched.sealedPayload;
|
|
50702
|
+
} catch {
|
|
50703
|
+
return { ack: false, ok: false, code: "fetch_failed" };
|
|
50704
|
+
}
|
|
50705
|
+
let value;
|
|
50706
|
+
try {
|
|
50707
|
+
value = openFromServer(Buffer.from(sealed, "base64"), device.privateKey);
|
|
50708
|
+
} catch (e) {
|
|
50709
|
+
return {
|
|
50710
|
+
ack: true,
|
|
50711
|
+
ok: false,
|
|
50712
|
+
code: e instanceof EnvelopeError ? e.code : "envelope_invalid"
|
|
50713
|
+
};
|
|
50714
|
+
}
|
|
50715
|
+
const result = await applyUpdate(u.targetKind, u.targetRef, value, {
|
|
50716
|
+
reported: device.reported
|
|
50717
|
+
});
|
|
50718
|
+
return { ack: true, ...result };
|
|
50719
|
+
}
|
|
50720
|
+
async function applyBatch(client2, device, updates) {
|
|
50721
|
+
if (updates.length === 0) return [];
|
|
50722
|
+
const approvalToken = await requestBrowserStepUp(
|
|
50723
|
+
client2,
|
|
50724
|
+
"device_apply",
|
|
50725
|
+
device.deviceId
|
|
50726
|
+
);
|
|
50727
|
+
const results = [];
|
|
50728
|
+
for (const u of updates) {
|
|
50729
|
+
const { ack: shouldAck, ...result } = await fetchOpenApply(
|
|
50730
|
+
client2,
|
|
50731
|
+
device,
|
|
50732
|
+
u,
|
|
50733
|
+
approvalToken
|
|
50734
|
+
);
|
|
50735
|
+
if (!shouldAck) {
|
|
50736
|
+
results.push({ id: u.id, targetKind: u.targetKind, ...result });
|
|
50737
|
+
continue;
|
|
50738
|
+
}
|
|
50739
|
+
try {
|
|
50740
|
+
await ack(client2, device.deviceId, u.id, result);
|
|
50741
|
+
results.push({ id: u.id, targetKind: u.targetKind, ...result });
|
|
50742
|
+
} catch {
|
|
50743
|
+
results.push({
|
|
50744
|
+
id: u.id,
|
|
50745
|
+
targetKind: u.targetKind,
|
|
50746
|
+
ok: false,
|
|
50747
|
+
code: "ack_failed"
|
|
50748
|
+
});
|
|
50749
|
+
}
|
|
50750
|
+
}
|
|
50751
|
+
return results;
|
|
50752
|
+
}
|
|
50753
|
+
function applyCommand() {
|
|
50754
|
+
return new Command("apply").description(
|
|
50755
|
+
"Apply the key updates queued for this machine (one browser approval)"
|
|
50756
|
+
).option("--yes", "Apply without the local confirmation prompt").action(async (opts, command) => {
|
|
50757
|
+
const g = globalOutputOpts(command);
|
|
50758
|
+
const { client: client2, workspaceId } = await keysContext();
|
|
50759
|
+
const device = await requireEnrolledDevice(workspaceId);
|
|
50760
|
+
const updates = await listUpdates(client2, device.deviceId);
|
|
50761
|
+
if (updates.length === 0) {
|
|
50762
|
+
if (g.json) out("[]");
|
|
50763
|
+
else out("No key updates are waiting for this machine.");
|
|
50764
|
+
return;
|
|
50765
|
+
}
|
|
50766
|
+
if (opts.yes !== true) {
|
|
50767
|
+
if (!process.stdin.isTTY) {
|
|
50768
|
+
throw validationError(
|
|
50769
|
+
"Refusing to apply key updates without confirmation.",
|
|
50770
|
+
"Run 'gad keys apply --yes' in a script."
|
|
50771
|
+
);
|
|
50772
|
+
}
|
|
50773
|
+
for (const u of updates) err(` ${describeTarget(u)}`);
|
|
50774
|
+
if (!await confirm(`Apply ${updates.length} key update(s)?`)) {
|
|
50775
|
+
err("Nothing applied.");
|
|
50776
|
+
return;
|
|
50777
|
+
}
|
|
50778
|
+
}
|
|
50779
|
+
const results = await applyBatch(client2, device, updates);
|
|
50780
|
+
if (g.json) {
|
|
50781
|
+
out(JSON.stringify(results));
|
|
50782
|
+
} else {
|
|
50783
|
+
const c = createColor(g.noColor || g.quiet);
|
|
50784
|
+
for (const r of results) {
|
|
50785
|
+
const u = updates.find((x) => x.id === r.id);
|
|
50786
|
+
const where = u ? describeTarget(u) : r.targetKind;
|
|
50787
|
+
out(`${r.ok ? c.green("\u2713") : c.red("\u2717")} ${where} ${c.dim(r.code)}`);
|
|
50788
|
+
}
|
|
50789
|
+
}
|
|
50790
|
+
const failed = results.filter((r) => !r.ok).length;
|
|
50791
|
+
if (failed > 0) {
|
|
50792
|
+
throw new CliError(
|
|
50793
|
+
`${failed} of ${results.length} key update(s) failed on this machine.`,
|
|
50794
|
+
3 /* VALIDATION_ERROR */,
|
|
50795
|
+
"An update that could not be fetched stays queued: run 'gad keys apply' again. The run page shows every other failed step."
|
|
50796
|
+
);
|
|
50797
|
+
}
|
|
50798
|
+
});
|
|
50799
|
+
}
|
|
50800
|
+
function readHiddenFromTty(prompt, io = {
|
|
50801
|
+
input: process.stdin,
|
|
50802
|
+
output: process.stderr
|
|
50803
|
+
}) {
|
|
50804
|
+
let muted = false;
|
|
50805
|
+
const sink = new Writable({
|
|
50806
|
+
write(chunk, encoding, callback) {
|
|
50807
|
+
if (!muted) io.output.write(chunk, encoding);
|
|
50808
|
+
callback();
|
|
50809
|
+
}
|
|
50810
|
+
});
|
|
50811
|
+
const rl = createInterface3({
|
|
50812
|
+
input: io.input,
|
|
50813
|
+
output: sink,
|
|
50814
|
+
terminal: true
|
|
50815
|
+
});
|
|
50816
|
+
io.output.write(prompt);
|
|
50817
|
+
muted = true;
|
|
50818
|
+
return new Promise((resolve5, reject) => {
|
|
50819
|
+
const lines = [];
|
|
50820
|
+
let pem = false;
|
|
50821
|
+
const finish = () => {
|
|
50822
|
+
rl.close();
|
|
50823
|
+
io.output.write("\n");
|
|
50824
|
+
resolve5(lines.join("\n"));
|
|
50825
|
+
};
|
|
50826
|
+
rl.on("line", (line) => {
|
|
50827
|
+
if (lines.length === 0) pem = /^-----BEGIN /.test(line.trim());
|
|
50828
|
+
lines.push(line);
|
|
50829
|
+
if (!pem || /^-----END .*-----\s*$/.test(line.trim())) finish();
|
|
50830
|
+
});
|
|
50831
|
+
rl.on("SIGINT", () => {
|
|
50832
|
+
rl.close();
|
|
50833
|
+
reject(new CliError("Paste cancelled.", 3 /* VALIDATION_ERROR */));
|
|
50834
|
+
});
|
|
50835
|
+
});
|
|
50836
|
+
}
|
|
50837
|
+
function pasteRefusal(error62, apiUrl, runId) {
|
|
50838
|
+
const code = serverCodeOf(error62);
|
|
50839
|
+
if (code !== null && (code === "invalid_grants" || code === "storage_token_missing" || code.startsWith("onepassword_"))) {
|
|
50840
|
+
return new CliError(
|
|
50841
|
+
"This run needs its 1Password access granted again, which the CLI cannot send.",
|
|
50842
|
+
3 /* VALIDATION_ERROR */,
|
|
50843
|
+
`Paste the key on the run page instead: ${apiUrl}${keyRotationRunPath(runId)}`
|
|
50844
|
+
);
|
|
50845
|
+
}
|
|
50846
|
+
return error62;
|
|
50847
|
+
}
|
|
50848
|
+
function pasteCommand() {
|
|
50849
|
+
return new Command("paste").description(
|
|
50850
|
+
"Paste the new PAT or App private key for a run (no echo; browser step-up)"
|
|
50851
|
+
).argument("<run>", "Run id").option("--stdin", "Read the value from piped stdin instead of a prompt").action(async (runArg, opts, command) => {
|
|
50852
|
+
const g = globalOutputOpts(command);
|
|
50853
|
+
const runId = requireRunId(runArg);
|
|
50854
|
+
const fromStdin = opts.stdin === true;
|
|
50855
|
+
if (!fromStdin && !process.stdin.isTTY) {
|
|
50856
|
+
throw validationError(
|
|
50857
|
+
"Refusing to read a key from a non-interactive stdin.",
|
|
50858
|
+
"Pass --stdin to read the value from a pipe."
|
|
50859
|
+
);
|
|
50860
|
+
}
|
|
50861
|
+
const { client: client2, apiUrl } = await keysContext();
|
|
50862
|
+
const approvalToken = await requestBrowserStepUp(client2, "paste", runId);
|
|
50863
|
+
const raw = fromStdin ? await readStream(process.stdin) : await readHiddenFromTty("Paste the new key (input hidden): ");
|
|
50864
|
+
const value = raw.trim();
|
|
50865
|
+
if (!value) {
|
|
50866
|
+
throw validationError("Nothing was pasted.");
|
|
50867
|
+
}
|
|
50868
|
+
try {
|
|
50869
|
+
await client2.post(`/api/key-rotation/runs/${runId}/paste`, {
|
|
50870
|
+
value,
|
|
50871
|
+
approvalToken
|
|
50872
|
+
});
|
|
50873
|
+
} catch (e) {
|
|
50874
|
+
throw pasteRefusal(e, apiUrl, runId);
|
|
50875
|
+
}
|
|
50876
|
+
if (g.json) out(JSON.stringify({ ok: true, runId }));
|
|
50877
|
+
else out("Pasted. The run continues on GreatArrow.ai.");
|
|
50878
|
+
});
|
|
50879
|
+
}
|
|
50880
|
+
function approveCommand() {
|
|
50881
|
+
return new Command("approve").description("Open a run's approval page in the browser").argument("<run>", "Run id").action(async (runArg, _opts, command) => {
|
|
50882
|
+
const g = globalOutputOpts(command);
|
|
50883
|
+
const runId = requireRunId(runArg);
|
|
50884
|
+
const auth = await resolveAuth();
|
|
50885
|
+
const url2 = `${auth.apiUrl.replace(/\/$/, "")}${keyRotationRunPath(runId)}`;
|
|
50886
|
+
if (g.json) {
|
|
50887
|
+
out(JSON.stringify({ url: url2 }));
|
|
50888
|
+
return;
|
|
50889
|
+
}
|
|
50890
|
+
const opened = await openInBrowser(url2);
|
|
50891
|
+
out(url2);
|
|
50892
|
+
if (!opened) err("Couldn't launch a browser \u2014 open the URL above.");
|
|
50893
|
+
});
|
|
50894
|
+
}
|
|
50895
|
+
function keysCommand() {
|
|
50896
|
+
return new Command("keys").description("Rotate leaked or expiring keys (GreatArrow.ai key rotation)").addCommand(listCommand4()).addCommand(statusCommand4()).addCommand(enrollCommand()).addCommand(pendingCommand()).addCommand(applyCommand()).addCommand(pasteCommand()).addCommand(approveCommand());
|
|
50897
|
+
}
|
|
50898
|
+
|
|
49647
50899
|
// src/lib/completions.ts
|
|
49648
50900
|
var COMMANDS = [
|
|
49649
50901
|
"login",
|
|
@@ -49898,7 +51150,7 @@ function completionsCommand() {
|
|
|
49898
51150
|
|
|
49899
51151
|
// node_modules/.pnpm/update-notifier@7.3.1/node_modules/update-notifier/update-notifier.js
|
|
49900
51152
|
import process11 from "node:process";
|
|
49901
|
-
import { spawn } from "node:child_process";
|
|
51153
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
49902
51154
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
49903
51155
|
import path9 from "node:path";
|
|
49904
51156
|
import { format } from "node:util";
|
|
@@ -49974,7 +51226,7 @@ var retryifyAsync = (fn, options) => {
|
|
|
49974
51226
|
throw error62;
|
|
49975
51227
|
const delay2 = Math.round(interval * Math.random());
|
|
49976
51228
|
if (delay2 > 0) {
|
|
49977
|
-
const delayPromise = new Promise((
|
|
51229
|
+
const delayPromise = new Promise((resolve5) => setTimeout(resolve5, delay2));
|
|
49978
51230
|
return delayPromise.then(() => attempt.apply(void 0, args));
|
|
49979
51231
|
} else {
|
|
49980
51232
|
return attempt.apply(void 0, args);
|
|
@@ -50233,14 +51485,14 @@ var Temp = {
|
|
|
50233
51485
|
}
|
|
50234
51486
|
},
|
|
50235
51487
|
truncate: (filePath) => {
|
|
50236
|
-
const
|
|
50237
|
-
if (
|
|
51488
|
+
const basename3 = path3.basename(filePath);
|
|
51489
|
+
if (basename3.length <= LIMIT_BASENAME_LENGTH)
|
|
50238
51490
|
return filePath;
|
|
50239
|
-
const truncable = /^(\.?)(.*?)((?:\.[^.]+)?(?:\.tmp-\d{10}[a-f0-9]{6})?)$/.exec(
|
|
51491
|
+
const truncable = /^(\.?)(.*?)((?:\.[^.]+)?(?:\.tmp-\d{10}[a-f0-9]{6})?)$/.exec(basename3);
|
|
50240
51492
|
if (!truncable)
|
|
50241
51493
|
return filePath;
|
|
50242
|
-
const truncationLength =
|
|
50243
|
-
return `${filePath.slice(0, -
|
|
51494
|
+
const truncationLength = basename3.length - LIMIT_BASENAME_LENGTH;
|
|
51495
|
+
return `${filePath.slice(0, -basename3.length)}${truncable[1]}${truncable[2].slice(0, -truncationLength)}${truncable[3]}`;
|
|
50244
51496
|
}
|
|
50245
51497
|
};
|
|
50246
51498
|
node_default(Temp.purgeSyncAll);
|
|
@@ -51540,14 +52792,14 @@ var TimeoutError = class extends Error {
|
|
|
51540
52792
|
|
|
51541
52793
|
// node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/timeout.js
|
|
51542
52794
|
async function timeout(request, init, abortController, options) {
|
|
51543
|
-
return new Promise((
|
|
52795
|
+
return new Promise((resolve5, reject) => {
|
|
51544
52796
|
const timeoutId = setTimeout(() => {
|
|
51545
52797
|
if (abortController) {
|
|
51546
52798
|
abortController.abort();
|
|
51547
52799
|
}
|
|
51548
52800
|
reject(new TimeoutError(request));
|
|
51549
52801
|
}, options.timeout);
|
|
51550
|
-
void options.fetch(request, init).then(
|
|
52802
|
+
void options.fetch(request, init).then(resolve5).catch(reject).then(() => {
|
|
51551
52803
|
clearTimeout(timeoutId);
|
|
51552
52804
|
});
|
|
51553
52805
|
});
|
|
@@ -51555,7 +52807,7 @@ async function timeout(request, init, abortController, options) {
|
|
|
51555
52807
|
|
|
51556
52808
|
// node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/delay.js
|
|
51557
52809
|
async function delay(ms, { signal }) {
|
|
51558
|
-
return new Promise((
|
|
52810
|
+
return new Promise((resolve5, reject) => {
|
|
51559
52811
|
if (signal) {
|
|
51560
52812
|
signal.throwIfAborted();
|
|
51561
52813
|
signal.addEventListener("abort", abortHandler, { once: true });
|
|
@@ -51566,7 +52818,7 @@ async function delay(ms, { signal }) {
|
|
|
51566
52818
|
}
|
|
51567
52819
|
const timeoutId = setTimeout(() => {
|
|
51568
52820
|
signal?.removeEventListener("abort", abortHandler);
|
|
51569
|
-
|
|
52821
|
+
resolve5();
|
|
51570
52822
|
}, ms);
|
|
51571
52823
|
});
|
|
51572
52824
|
}
|
|
@@ -52868,7 +54120,7 @@ var makeContentText = (text3, { padding, width, textAlignment, height }) => {
|
|
|
52868
54120
|
const createdLines = wrapAnsi(line, max, { hard: true });
|
|
52869
54121
|
const alignedLines = (0, import_ansi_align.default)(createdLines, { align: textAlignment });
|
|
52870
54122
|
const alignedLinesArray = alignedLines.split("\n");
|
|
52871
|
-
const longestLength = Math.max(...alignedLinesArray.map((
|
|
54123
|
+
const longestLength = Math.max(...alignedLinesArray.map((s2) => stringWidth(s2)));
|
|
52872
54124
|
for (const alignedLine of alignedLinesArray) {
|
|
52873
54125
|
let paddedLine;
|
|
52874
54126
|
switch (textAlignment) {
|
|
@@ -53195,7 +54447,7 @@ var UpdateNotifier = class {
|
|
|
53195
54447
|
if (Date.now() - this.config.get("lastUpdateCheck") < this.#updateCheckInterval) {
|
|
53196
54448
|
return;
|
|
53197
54449
|
}
|
|
53198
|
-
|
|
54450
|
+
spawn3(process11.execPath, [path9.join(__dirname3, "check.js"), JSON.stringify(this.#options)], {
|
|
53199
54451
|
detached: true,
|
|
53200
54452
|
stdio: "ignore"
|
|
53201
54453
|
}).unref();
|
|
@@ -53318,6 +54570,7 @@ program2.addCommand(askCommand());
|
|
|
53318
54570
|
program2.addCommand(localCommand());
|
|
53319
54571
|
program2.addCommand(runtimeCommand());
|
|
53320
54572
|
program2.addCommand(smokeCommand());
|
|
54573
|
+
program2.addCommand(keysCommand());
|
|
53321
54574
|
program2.addCommand(openCommand());
|
|
53322
54575
|
program2.addCommand(completionsCommand());
|
|
53323
54576
|
try {
|