@great-arrow/cli 0.1.64 → 0.1.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +3 -1
  2. package/dist/index.js +2034 -547
  3. 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 rename2(from, to, cb) {
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(rename2, fs$rename);
132
- return rename2;
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(err, fd) {
176
- if (err) {
177
- if (callback) callback(err);
175
+ function(err2, fd) {
176
+ if (err2) {
177
+ if (callback) callback(err2);
178
178
  return;
179
179
  }
180
- fs7.fchmod(fd, mode, function(err2) {
180
+ fs7.fchmod(fd, mode, function(err3) {
181
181
  fs7.close(fd, function(err22) {
182
- if (callback) callback(err2 || err22);
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(err, fd) {
381
- if (err) {
382
- self.emit("error", err);
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(err) {
492
- if (!err) {
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 = readFile7;
537
- function readFile7(path10, options, cb) {
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(err) {
543
- if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
544
- enqueue([go$readFile, [path11, options2, cb2], err, startTime || Date.now(), Date.now()]);
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 = writeFile6;
554
- function writeFile6(path10, data, options, cb) {
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(err) {
560
- if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
561
- enqueue([go$writeFile, [path11, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
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(err) {
578
- if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
579
- enqueue([go$appendFile, [path11, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
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(err) {
598
- if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
599
- enqueue([go$copyFile, [src2, dest2, flags2, cb2], err, startTime || Date.now(), Date.now()]);
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(err, files) {
631
- if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
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
- err,
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, err, files);
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(err, fd) {
714
- if (err) {
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", err);
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(err, fd) {
734
- if (err) {
733
+ open4(that.path, that.flags, that.mode, function(err2, fd) {
734
+ if (err2) {
735
735
  that.destroy();
736
- that.emit("error", err);
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(err, fd) {
757
- if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
758
- enqueue([go$open, [path11, flags2, mode2, cb2], err, startTime || Date.now(), Date.now()]);
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 err = elem[2];
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, err);
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 out = "";
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
- out += safe(k + "[]") + separator + safe(item) + "\n";
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
- out += safe(k) + separator + safe(val) + eol;
1390
+ out2 += safe(k) + separator + safe(val) + eol;
1391
1391
  });
1392
- if (opt.section && out.length)
1393
- out = "[" + safe(opt.section) + "]" + eol + out;
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 (out.length && child.length)
1402
- out += eol;
1403
- out += child;
1401
+ if (out2.length && child.length)
1402
+ out2 += eol;
1403
+ out2 += child;
1404
1404
  });
1405
- return out;
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 out = {};
1414
- var p = out;
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 = out[section] = out[section] || {};
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(out).filter(function(k, _, __) {
1458
- if (!out[k] || typeof out[k] !== "object" || Array.isArray(out[k]))
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 = out;
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 === out && nl === l)
1471
+ if (p2 === out2 && nl === l)
1472
1472
  return false;
1473
- p2[nl] = out[k];
1473
+ p2[nl] = out2[k];
1474
1474
  return true;
1475
1475
  }).forEach(function(del, _, __) {
1476
- delete out[del];
1476
+ delete out2[del];
1477
1477
  });
1478
- return out;
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 (err) {
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 (err) {
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 join12 = __require("path").join;
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
- join12(etc, name23, "config"),
1997
- join12(etc, name23 + "rc")
1996
+ join13(etc, name23, "config"),
1997
+ join13(etc, name23 + "rc")
1998
1998
  ].forEach(addConfigFile);
1999
1999
  if (home)
2000
2000
  [
2001
- join12(home, ".config", name23, "config"),
2002
- join12(home, ".config", name23),
2003
- join12(home, "." + name23, "config"),
2004
- join12(home, "." + name23 + "rc")
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 rename2(from, to, cb) {
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(rename2, fs$rename);
2106
- return rename2;
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(err, fd) {
2150
- if (err) {
2151
- if (callback) callback(err);
2149
+ function(err2, fd) {
2150
+ if (err2) {
2151
+ if (callback) callback(err2);
2152
2152
  return;
2153
2153
  }
2154
- fs7.fchmod(fd, mode, function(err2) {
2154
+ fs7.fchmod(fd, mode, function(err3) {
2155
2155
  fs7.close(fd, function(err22) {
2156
- if (callback) callback(err2 || err22);
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(err, fd) {
2355
- if (err) {
2356
- self.emit("error", err);
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(err) {
2466
- if (!err) {
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 = readFile7;
2511
- function readFile7(path10, options, cb) {
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(err) {
2517
- if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
2518
- enqueue([go$readFile, [path11, options2, cb2], err, startTime || Date.now(), Date.now()]);
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 = writeFile6;
2528
- function writeFile6(path10, data, options, cb) {
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(err) {
2534
- if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
2535
- enqueue([go$writeFile, [path11, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
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(err) {
2552
- if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
2553
- enqueue([go$appendFile, [path11, data2, options2, cb2], err, startTime || Date.now(), Date.now()]);
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(err) {
2572
- if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
2573
- enqueue([go$copyFile, [src2, dest2, flags2, cb2], err, startTime || Date.now(), Date.now()]);
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(err, files) {
2605
- if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
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
- err,
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, err, files);
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(err, fd) {
2688
- if (err) {
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", err);
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(err, fd) {
2708
- if (err) {
2707
+ open4(that.path, that.flags, that.mode, function(err2, fd) {
2708
+ if (err2) {
2709
2709
  that.destroy();
2710
- that.emit("error", err);
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(err, fd) {
2731
- if (err && (err.code === "EMFILE" || err.code === "ENFILE"))
2732
- enqueue([go$open, [path11, flags2, mode2, cb2], err, startTime || Date.now(), Date.now()]);
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 err = elem[2];
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, err);
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 (err) {
2812
- if (err.code === "ENOENT")
2811
+ } catch (err2) {
2812
+ if (err2.code === "ENOENT")
2813
2813
  return void 0;
2814
- throw err;
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 (err) {
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 (err) {
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(s) {
3197
- s = s.toLowerCase();
3198
- if (s === "_authtoken") return "_authToken";
3199
- let r = s[0];
3200
- for (let i = 1; i < s.length; i++) {
3201
- r += s[i] === "_" ? "-" : s[i];
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 dirname8 = path10.dirname(name24);
3343
- if (dirname8 === name24) {
3342
+ const dirname9 = path10.dirname(name24);
3343
+ if (dirname9 === name24) {
3344
3344
  return original;
3345
3345
  }
3346
- return find(dirname8, original);
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 s = parse3(version2.trim().replace(/^[=v]+/, ""), options);
4036
- return s ? s.version : null;
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 out = "";
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
- out += safe(`${k}${arraySuffix}`).padEnd(padToChars, " ") + separator + safe(item) + eol;
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
- out += safe(k).padEnd(padToChars, " ") + separator + safe(val) + eol;
5488
+ out2 += safe(k).padEnd(padToChars, " ") + separator + safe(val) + eol;
5489
5489
  }
5490
5490
  }
5491
- if (opt.section && out.length) {
5492
- out = "[" + safe(opt.section) + "]" + (opt.newline ? eol + eol : eol) + out;
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 (out.length && child.length) {
5502
- out += eol;
5501
+ if (out2.length && child.length) {
5502
+ out2 += eol;
5503
5503
  }
5504
- out += child;
5504
+ out2 += child;
5505
5505
  }
5506
- return out;
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 out = /* @__PURE__ */ Object.create(null);
5530
- let p = out;
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 = out[section] = out[section] || /* @__PURE__ */ Object.create(null);
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(out)) {
5581
- if (!hasOwnProperty.call(out, k) || typeof out[k] !== "object" || Array.isArray(out[k])) {
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 = out;
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 === out && nl === l) {
5597
+ if (p === out2 && nl === l) {
5598
5598
  continue;
5599
5599
  }
5600
- p[nl] = out[k];
5600
+ p[nl] = out2[k];
5601
5601
  remove.push(k);
5602
5602
  }
5603
5603
  for (const del of remove) {
5604
- delete out[del];
5604
+ delete out2[del];
5605
5605
  }
5606
- return out;
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 = (err) => {
7479
- if (err.code !== "commander.executeSubCommandAsync") {
7480
- throw err;
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 (err) {
7557
- if (err.code === "commander.invalidArgument") {
7558
- const message = `${invalidArgumentMessage} ${err.message}`;
7559
- this.error(message, { exitCode: err.exitCode, code: err.code });
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 err;
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", (err) => {
8153
- if (err.code === "ENOENT") {
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 (err.code === "EACCES") {
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 = err;
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 s = expected === 1 ? "" : "s";
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${s} but got ${received}: ${details}.`;
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.64";
9440
+ var CLI_VERSION = "0.1.66";
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, err) {
9458
+ function debugSwallow(scope, err2) {
9440
9459
  if (!process.env.GAD_DEBUG) return;
9441
- const detail = err instanceof Error ? err.stack ?? err.message : String(err);
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 credentialFilePath() {
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, ACCOUNT);
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(credentialFilePath(), "utf-8");
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 getToken() {
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 (err) {
9476
- debugSwallow("keychain.getToken", err);
9495
+ } catch (err2) {
9496
+ debugSwallow("keychain.getSecretSlot", err2);
9477
9497
  }
9478
9498
  }
9479
- return readFileFallback();
9499
+ return readFileFallback(account);
9480
9500
  }
9481
- async function setToken(token) {
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(token);
9486
- await removeFileFallback();
9505
+ await entry.setPassword(value);
9506
+ await removeFileFallback(account);
9487
9507
  return true;
9488
- } catch (err) {
9489
- debugSwallow("keychain.setToken", err);
9508
+ } catch (err2) {
9509
+ debugSwallow("keychain.setSecretSlot", err2);
9490
9510
  }
9491
9511
  try {
9492
9512
  await entry.deletePassword();
9493
- } catch (err) {
9494
- debugSwallow("keychain.setToken(delete stale)", err);
9513
+ } catch (err2) {
9514
+ debugSwallow("keychain.setSecretSlot(delete stale)", err2);
9495
9515
  return false;
9496
9516
  }
9497
9517
  }
9498
9518
  try {
9499
- const path10 = credentialFilePath();
9519
+ const path10 = slotFilePath(account);
9500
9520
  await mkdir(dirname(path10), { recursive: true, mode: 448 });
9501
- await writeFile(path10, token, { mode: 384 });
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 deleteToken() {
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 (err) {
9513
- debugSwallow("keychain.deleteToken", err);
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);
9543
+ }
9544
+ function deleteToken() {
9545
+ return deleteSecretSlot(ACCOUNT);
9517
9546
  }
9518
- async function removeFileFallback() {
9547
+ async function removeFileFallback(account) {
9519
9548
  try {
9520
- await unlink(credentialFilePath());
9521
- } catch (err) {
9522
- if (err?.code !== "ENOENT") {
9523
- debugSwallow("keychain.removeFileFallback", err);
9549
+ await unlink(slotFilePath(account));
9550
+ } catch (err2) {
9551
+ if (err2?.code !== "ENOENT") {
9552
+ debugSwallow("keychain.removeFileFallback", err2);
9524
9553
  }
9525
9554
  }
9526
9555
  }
@@ -9565,6 +9594,17 @@ async function clearStoredCredential() {
9565
9594
  await deleteToken();
9566
9595
  }
9567
9596
 
9597
+ // src/lib/token-login-guard.ts
9598
+ function decideTokenLogin(input2) {
9599
+ const { token, stored, force } = input2;
9600
+ if (stored?.kind !== "oauth") return { action: "store" };
9601
+ if (token === stored.credential.accessToken) {
9602
+ return { action: "keep-oauth", reason: "same-access-token" };
9603
+ }
9604
+ if (token.startsWith("gad_v1_") || force) return { action: "store" };
9605
+ return { action: "refuse", reason: "would-replace-oauth" };
9606
+ }
9607
+
9568
9608
  // src/lib/cli-locator.ts
9569
9609
  import {
9570
9610
  chmodSync,
@@ -9585,8 +9625,8 @@ function writeCliLocator(home = homedir2(), entry = process.argv[1]) {
9585
9625
  let resolved = entry;
9586
9626
  try {
9587
9627
  resolved = realpathSync(entry);
9588
- } catch (err) {
9589
- debugSwallow("cli-locator.realpath", err);
9628
+ } catch (err2) {
9629
+ debugSwallow("cli-locator.realpath", err2);
9590
9630
  }
9591
9631
  mkdirSync(dir, { recursive: true });
9592
9632
  writeFileSync(
@@ -9600,8 +9640,8 @@ function writeCliLocator(home = homedir2(), entry = process.argv[1]) {
9600
9640
  );
9601
9641
  chmodSync(tmp, 384);
9602
9642
  renameSync(tmp, target);
9603
- } catch (err) {
9604
- debugSwallow("cli-locator.write", err);
9643
+ } catch (err2) {
9644
+ debugSwallow("cli-locator.write", err2);
9605
9645
  try {
9606
9646
  rmSync(tmp, { force: true });
9607
9647
  } catch (cleanupErr) {
@@ -9699,8 +9739,8 @@ async function loadConfig() {
9699
9739
  const content = await readFile2(configPath, "utf-8");
9700
9740
  const parsed = parseConfig(content);
9701
9741
  return { ...DEFAULTS, ...stripEmpty(parsed) };
9702
- } catch (err) {
9703
- if (isNodeError2(err) && err.code === "ENOENT") {
9742
+ } catch (err2) {
9743
+ if (isNodeError2(err2) && err2.code === "ENOENT") {
9704
9744
  return { ...DEFAULTS };
9705
9745
  }
9706
9746
  return { ...DEFAULTS };
@@ -9737,8 +9777,8 @@ function stripEmpty(config2) {
9737
9777
  result.telemetry_enabled = config2.telemetry_enabled;
9738
9778
  return result;
9739
9779
  }
9740
- function isNodeError2(err) {
9741
- return err instanceof Error && "code" in err;
9780
+ function isNodeError2(err2) {
9781
+ return err2 instanceof Error && "code" in err2;
9742
9782
  }
9743
9783
 
9744
9784
  // src/lib/oauth/pkce.ts
@@ -9770,8 +9810,8 @@ var DEFAULT_CALLBACK_PORT = 51789;
9770
9810
  var CALLBACK_PATH = "/callback";
9771
9811
  var LOOPBACK_HOST = "127.0.0.1";
9772
9812
  var DEFAULT_TIMEOUT_MS = 12e4;
9773
- function escapeHtml(s) {
9774
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
9813
+ function escapeHtml(s2) {
9814
+ return s2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
9775
9815
  }
9776
9816
  var CLOSE_TAB_HTML = (ok, detail) => `<!doctype html>
9777
9817
  <html><head><meta charset="utf-8"><title>Great Arrow CLI</title>
@@ -9782,12 +9822,12 @@ h1{font-size:1.25rem;margin:0 0 .5rem}p{color:#9a9aa3;margin:0}</style></head>
9782
9822
  <body><div class="card"><h1>${ok ? "\u2713 Signed in to Great Arrow" : "\u2717 Sign-in failed"}</h1>
9783
9823
  <p>${escapeHtml(detail)}</p></div></body></html>`;
9784
9824
  function listen(port) {
9785
- return new Promise((resolve4, reject) => {
9825
+ return new Promise((resolve5, reject) => {
9786
9826
  const server = createServer();
9787
9827
  server.on("error", reject);
9788
9828
  server.listen(port, LOOPBACK_HOST, () => {
9789
9829
  const addr = server.address();
9790
- resolve4({ server, port: addr.port });
9830
+ resolve5({ server, port: addr.port });
9791
9831
  });
9792
9832
  });
9793
9833
  }
@@ -9812,7 +9852,7 @@ async function startLoopbackServer(opts) {
9812
9852
  port,
9813
9853
  close: () => server.close(),
9814
9854
  waitForCallback({ timeoutMs = DEFAULT_TIMEOUT_MS } = {}) {
9815
- return new Promise((resolve4, reject) => {
9855
+ return new Promise((resolve5, reject) => {
9816
9856
  const timer = setTimeout(() => {
9817
9857
  server.close();
9818
9858
  reject(new Error("Timed out waiting for the browser callback."));
@@ -9852,7 +9892,7 @@ async function startLoopbackServer(opts) {
9852
9892
  "You can close this tab and return to your terminal."
9853
9893
  )
9854
9894
  );
9855
- settle2(() => resolve4({ code, state }));
9895
+ settle2(() => resolve5({ code, state }));
9856
9896
  });
9857
9897
  });
9858
9898
  }
@@ -10137,16 +10177,16 @@ async function confirm(message) {
10137
10177
  input: process.stdin,
10138
10178
  output: process.stdout
10139
10179
  });
10140
- return new Promise((resolve4) => {
10180
+ return new Promise((resolve5) => {
10141
10181
  rl.question(`${message} [y/N] `, (answer) => {
10142
10182
  rl.close();
10143
10183
  const normalized = answer.trim().toLowerCase();
10144
- resolve4(normalized === "y" || normalized === "yes");
10184
+ resolve5(normalized === "y" || normalized === "yes");
10145
10185
  });
10146
10186
  });
10147
10187
  }
10148
- function stripControlChars(s) {
10149
- return String(s).replace(/[\u0000-\u001f\u007f-\u009f]/g, "");
10188
+ function stripControlChars(s2) {
10189
+ return String(s2).replace(/[\u0000-\u001f\u007f-\u009f]/g, "");
10150
10190
  }
10151
10191
 
10152
10192
  // src/lib/formatter.ts
@@ -10307,8 +10347,8 @@ function createFormatter(options) {
10307
10347
  var DEFAULT_API_URL = "https://www.greatarrow.ai";
10308
10348
  function isLegacyApiUrl(value) {
10309
10349
  try {
10310
- const hostname5 = new URL(value).hostname.toLowerCase();
10311
- return hostname5 === "www.greatarrowdigital.com" || hostname5 === "greatarrowdigital.com";
10350
+ const hostname6 = new URL(value).hostname.toLowerCase();
10351
+ return hostname6 === "www.greatarrowdigital.com" || hostname6 === "greatarrowdigital.com";
10312
10352
  } catch {
10313
10353
  return false;
10314
10354
  }
@@ -10328,10 +10368,10 @@ function maskToken(token) {
10328
10368
  }
10329
10369
  function openBrowser(url2) {
10330
10370
  if (!/^https?:\/\//i.test(url2)) return Promise.resolve(false);
10331
- return new Promise((resolve4) => {
10371
+ return new Promise((resolve5) => {
10332
10372
  const platform2 = process.platform;
10333
10373
  const [cmd, args] = platform2 === "darwin" ? ["open", [url2]] : platform2 === "win32" ? ["cmd", ["/c", "start", "", url2]] : ["xdg-open", [url2]];
10334
- execFile(cmd, args, (error62) => resolve4(!error62));
10374
+ execFile(cmd, args, (error62) => resolve5(!error62));
10335
10375
  });
10336
10376
  }
10337
10377
  var loginCommand = new Command("login").description("Authenticate the CLI with your Great Arrow Digital account").option(
@@ -10340,7 +10380,10 @@ var loginCommand = new Command("login").description("Authenticate the CLI with y
10340
10380
  ).option(
10341
10381
  "--no-browser",
10342
10382
  "Print the authorize URL instead of opening a browser"
10343
- ).option("--scope <list>", "OAuth scope to request", "mcp").action(
10383
+ ).option("--scope <list>", "OAuth scope to request", "mcp").option(
10384
+ "--force",
10385
+ "With --token: replace a signed-in OAuth session even if the token may be short-lived"
10386
+ ).action(
10344
10387
  async (options) => {
10345
10388
  const fmt = createFormatter({
10346
10389
  json: false,
@@ -10351,6 +10394,24 @@ var loginCommand = new Command("login").description("Authenticate the CLI with y
10351
10394
  const config2 = await loadConfig();
10352
10395
  const apiUrl = DEFAULT_API_URL;
10353
10396
  if (options.token) {
10397
+ const decision = decideTokenLogin({
10398
+ token: options.token,
10399
+ stored: await loadStoredCredential(),
10400
+ force: options.force === true
10401
+ });
10402
+ if (decision.action === "keep-oauth") {
10403
+ fmt.success(
10404
+ "Already signed in: that is your OAuth session's current access token. Keeping the self-refreshing session."
10405
+ );
10406
+ return;
10407
+ }
10408
+ if (decision.action === "refuse") {
10409
+ fmt.error(
10410
+ "You are signed in with a self-refreshing OAuth session, and this token is not a personal API token (gad_v1_\u2026). Storing it would replace the session, and if it is an OAuth access token it stops working within the hour. Use a gad_v1_ token, or pass --force to replace the session anyway."
10411
+ );
10412
+ process.exitCode = 1;
10413
+ return;
10414
+ }
10354
10415
  const stored = await savePatToken(options.token);
10355
10416
  if (!stored) {
10356
10417
  fmt.error(
@@ -10394,8 +10455,8 @@ var loginCommand = new Command("login").description("Authenticate the CLI with y
10394
10455
  fmt.success(
10395
10456
  "Signed in. Your session will refresh automatically \u2014 no need to log in again."
10396
10457
  );
10397
- } catch (err) {
10398
- const msg = err instanceof Error ? err.message : String(err);
10458
+ } catch (err2) {
10459
+ const msg = err2 instanceof Error ? err2.message : String(err2);
10399
10460
  fmt.error(`Login failed: ${msg}`);
10400
10461
  fmt.info(
10401
10462
  `You can also run \`gad login --token <token>\` with a token from ${apiUrl}/install/cli`
@@ -10436,8 +10497,8 @@ async function acquireRefreshLock() {
10436
10497
  const path10 = refreshLockPath();
10437
10498
  try {
10438
10499
  await mkdir3(join4(homedir4(), ".great-arrow"), { recursive: true });
10439
- } catch (err) {
10440
- debugSwallow("refresh-lock.mkdir", err);
10500
+ } catch (err2) {
10501
+ debugSwallow("refresh-lock.mkdir", err2);
10441
10502
  }
10442
10503
  const deadline = Date.now() + REFRESH_LOCK_WAIT_MS;
10443
10504
  for (; ; ) {
@@ -10446,8 +10507,8 @@ async function acquireRefreshLock() {
10446
10507
  await handle.writeFile(String(process.pid));
10447
10508
  await handle.close();
10448
10509
  return true;
10449
- } catch (err) {
10450
- if (err.code !== "EEXIST") {
10510
+ } catch (err2) {
10511
+ if (err2.code !== "EEXIST") {
10451
10512
  throw networkError(
10452
10513
  "Could not lock session renewal.",
10453
10514
  "Check local credential storage and retry; your session has been kept."
@@ -10458,8 +10519,8 @@ async function acquireRefreshLock() {
10458
10519
  if (age > REFRESH_LOCK_STALE_MS) {
10459
10520
  try {
10460
10521
  await rm(path10, { force: true });
10461
- } catch (err) {
10462
- debugSwallow("refresh-lock.stale-rm", err);
10522
+ } catch (err2) {
10523
+ debugSwallow("refresh-lock.stale-rm", err2);
10463
10524
  }
10464
10525
  continue;
10465
10526
  }
@@ -10470,16 +10531,16 @@ async function acquireRefreshLock() {
10470
10531
  async function releaseRefreshLock() {
10471
10532
  try {
10472
10533
  await rm(refreshLockPath(), { force: true });
10473
- } catch (err) {
10474
- debugSwallow("refresh-lock.release", err);
10534
+ } catch (err2) {
10535
+ debugSwallow("refresh-lock.release", err2);
10475
10536
  }
10476
10537
  }
10477
10538
  async function storedPairOtherThan(ours) {
10478
10539
  let stored = null;
10479
10540
  try {
10480
10541
  stored = await loadStoredCredential();
10481
- } catch (err) {
10482
- debugSwallow("refresh.reread", err);
10542
+ } catch (err2) {
10543
+ debugSwallow("refresh.reread", err2);
10483
10544
  }
10484
10545
  if (stored?.kind !== "oauth") {
10485
10546
  throw authError(
@@ -10643,8 +10704,8 @@ async function doRefresh(credential) {
10643
10704
  );
10644
10705
  }
10645
10706
  return refreshed;
10646
- } catch (err) {
10647
- if (err instanceof RefreshRejected) {
10707
+ } catch (err2) {
10708
+ if (err2 instanceof RefreshRejected) {
10648
10709
  const theirs = await storedPairOtherThan(current);
10649
10710
  if (theirs) {
10650
10711
  if (Date.now() < theirs.accessExpiresAt) return theirs;
@@ -10656,7 +10717,7 @@ async function doRefresh(credential) {
10656
10717
  await clearStoredCredential();
10657
10718
  throw sessionExpired();
10658
10719
  }
10659
- throw err;
10720
+ throw err2;
10660
10721
  } finally {
10661
10722
  if (held) await releaseRefreshLock();
10662
10723
  }
@@ -10943,14 +11004,14 @@ function luhnValid(candidate) {
10943
11004
  }
10944
11005
  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
11006
  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(s) {
10947
- return s.replace(EMAIL_RE, "[redacted-email]").replace(
11007
+ function scrubPiiFromText(s2) {
11008
+ return s2.replace(EMAIL_RE, "[redacted-email]").replace(
10948
11009
  CREDIT_CARD_RE,
10949
11010
  (m) => luhnValid(m) ? "[redacted-credit-card]" : m
10950
11011
  ).replace(SSN_RE, "[redacted-ssn]").replace(PHONE_RE, "[redacted-phone]");
10951
11012
  }
10952
- function scrubTelemetryText(s) {
10953
- return scrubPiiFromText(s).replace(SENSITIVE_QUERY_VALUE_RE, "$1[redacted]").replace(
11013
+ function scrubTelemetryText(s2) {
11014
+ return scrubPiiFromText(s2).replace(SENSITIVE_QUERY_VALUE_RE, "$1[redacted]").replace(
10954
11015
  SECRET_TOKEN_RE,
10955
11016
  (match) => match.toLowerCase().startsWith("bearer ") ? "Bearer [redacted]" : "[redacted-secret]"
10956
11017
  );
@@ -10979,11 +11040,11 @@ function redact(value, depth = 0) {
10979
11040
  if (Array.isArray(value))
10980
11041
  return value.slice(0, 20).map((v) => redact(v, depth + 1));
10981
11042
  if (value && typeof value === "object") {
10982
- const out = {};
11043
+ const out2 = {};
10983
11044
  for (const [key, v] of Object.entries(value).slice(0, 30)) {
10984
- out[key] = /token|secret|password|authorization|cookie|email/i.test(key) ? "[redacted]" : redact(v, depth + 1);
11045
+ out2[key] = /token|secret|password|authorization|cookie|email/i.test(key) ? "[redacted]" : redact(v, depth + 1);
10985
11046
  }
10986
- return out;
11047
+ return out2;
10987
11048
  }
10988
11049
  return value;
10989
11050
  }
@@ -11026,8 +11087,8 @@ async function captureCliEvent(input2) {
11026
11087
  );
11027
11088
  if (!response.ok)
11028
11089
  debugSwallow("telemetry.send", new Error(`HTTP ${response.status}`));
11029
- } catch (err) {
11030
- debugSwallow("telemetry.send", err);
11090
+ } catch (err2) {
11091
+ debugSwallow("telemetry.send", err2);
11031
11092
  }
11032
11093
  }
11033
11094
 
@@ -11043,8 +11104,8 @@ function getCommandWorkspaceTarget(options = {}) {
11043
11104
  }
11044
11105
 
11045
11106
  // ../local-runtime/src/abortable.ts
11046
- function abortable(run2, signal) {
11047
- return new Promise((resolve4, reject) => {
11107
+ function abortable(run4, signal) {
11108
+ return new Promise((resolve5, reject) => {
11048
11109
  const abort = () => {
11049
11110
  signal.removeEventListener("abort", abort);
11050
11111
  reject(signal.reason ?? new Error("Local operation stopped"));
@@ -11053,11 +11114,11 @@ function abortable(run2, signal) {
11053
11114
  signal.addEventListener("abort", abort, { once: true });
11054
11115
  Promise.resolve().then(() => {
11055
11116
  signal.throwIfAborted();
11056
- return run2();
11057
- }).then(resolve4, reject).finally(() => signal.removeEventListener("abort", abort));
11117
+ return run4();
11118
+ }).then(resolve5, reject).finally(() => signal.removeEventListener("abort", abort));
11058
11119
  });
11059
11120
  }
11060
- async function withLocalDeadline(deadlineMs, run2, parentSignal) {
11121
+ async function withLocalDeadline(deadlineMs, run4, parentSignal) {
11061
11122
  if (!Number.isSafeInteger(deadlineMs) || deadlineMs <= 0 || deadlineMs > 36e5)
11062
11123
  throw new Error("Invalid local operation deadline");
11063
11124
  const controller = new AbortController();
@@ -11067,7 +11128,7 @@ async function withLocalDeadline(deadlineMs, run2, parentSignal) {
11067
11128
  deadlineMs
11068
11129
  );
11069
11130
  try {
11070
- return await abortable(() => run2(signal), signal);
11131
+ return await abortable(() => run4(signal), signal);
11071
11132
  } finally {
11072
11133
  clearTimeout(timer);
11073
11134
  }
@@ -11229,6 +11290,7 @@ async function withNativeResponse(context2, path10, init, consume, parentSignal)
11229
11290
 
11230
11291
  // src/lib/client.ts
11231
11292
  var DEFAULT_TIMEOUT_MS2 = 3e4;
11293
+ var PRESENCE_TIMEOUT_MS = 4e4;
11232
11294
  var MAX_RETRIES = 5;
11233
11295
  var BASE_DELAY_MS = 1e3;
11234
11296
  function detectGitOrigin() {
@@ -11313,7 +11375,7 @@ function describeError(error62) {
11313
11375
  return String(error62);
11314
11376
  }
11315
11377
  function sleep(ms) {
11316
- return new Promise((resolve4) => setTimeout(resolve4, ms));
11378
+ return new Promise((resolve5) => setTimeout(resolve5, ms));
11317
11379
  }
11318
11380
  var GadClient = class {
11319
11381
  token;
@@ -11438,16 +11500,22 @@ var GadClient = class {
11438
11500
  const status = response.status;
11439
11501
  const body = await response.text().catch(() => "");
11440
11502
  if (status === 403) {
11441
- throw new CliError(
11442
- "Permission denied (HTTP 403).",
11443
- 1 /* AUTH_ERROR */,
11444
- "Check this connection's scopes and workspace permissions at /account/connections."
11503
+ throw withServerCode(
11504
+ new CliError(
11505
+ "Permission denied (HTTP 403).",
11506
+ 1 /* AUTH_ERROR */,
11507
+ "Check this connection's scopes and workspace permissions at /account/connections."
11508
+ ),
11509
+ body
11445
11510
  );
11446
11511
  }
11447
11512
  if (status === 401) {
11448
- throw authError(
11449
- `Authentication failed (HTTP ${status}).`,
11450
- "Run 'gad login' to re-authenticate, or check your GAD_TOKEN."
11513
+ throw withServerCode(
11514
+ authError(
11515
+ `Authentication failed (HTTP ${status}).`,
11516
+ "Run 'gad login' to re-authenticate, or check your GAD_TOKEN."
11517
+ ),
11518
+ body
11451
11519
  );
11452
11520
  }
11453
11521
  if (status >= 500) {
@@ -11457,10 +11525,13 @@ var GadClient = class {
11457
11525
  );
11458
11526
  }
11459
11527
  const message = body ? `Request failed (HTTP ${status}): ${body.slice(0, 200)}` : `Request failed (HTTP ${status}).`;
11460
- throw new CliError(
11461
- message,
11462
- mapErrorToExitCode(status),
11463
- "Check the command usage with --help."
11528
+ throw withServerCode(
11529
+ new CliError(
11530
+ message,
11531
+ mapErrorToExitCode(status),
11532
+ "Check the command usage with --help."
11533
+ ),
11534
+ body
11464
11535
  );
11465
11536
  }
11466
11537
  /**
@@ -11611,6 +11682,47 @@ var GadClient = class {
11611
11682
  })();
11612
11683
  }
11613
11684
  }
11685
+ /**
11686
+ * One request with NO retry, bounded by `AbortSignal.timeout`. For the
11687
+ * agent-presence routes: a replayed long-poll doubles a hold and the caller
11688
+ * already owns the loop and its backoff. Returns the status and parsed body
11689
+ * (null when not JSON) so the caller can read a 404 itself; a timeout or
11690
+ * network failure throws.
11691
+ */
11692
+ async requestOnce(method, path10, opts = {}) {
11693
+ const qs = opts.params && Object.keys(opts.params).length > 0 ? `?${new URLSearchParams(opts.params).toString()}` : "";
11694
+ const signal = AbortSignal.timeout(opts.timeoutMs ?? PRESENCE_TIMEOUT_MS);
11695
+ const headers = this.buildHeaders();
11696
+ if (method === "GET") delete headers["Content-Type"];
11697
+ if (this.getToken) {
11698
+ const getToken2 = this.getToken;
11699
+ headers.Authorization = `Bearer ${await new Promise(
11700
+ (resolve5, reject) => {
11701
+ signal.addEventListener(
11702
+ "abort",
11703
+ () => reject(networkError("Session renewal timed out.")),
11704
+ { once: true }
11705
+ );
11706
+ getToken2().then(resolve5, reject);
11707
+ }
11708
+ )}`;
11709
+ }
11710
+ const response = await fetch(`${this.apiUrl}${path10}${qs}`, {
11711
+ method,
11712
+ headers,
11713
+ ...opts.body !== void 0 && { body: JSON.stringify(opts.body) },
11714
+ redirect: "error",
11715
+ cache: "no-store",
11716
+ signal
11717
+ });
11718
+ let body = null;
11719
+ try {
11720
+ body = await response.json();
11721
+ } catch {
11722
+ body = null;
11723
+ }
11724
+ return { status: response.status, body };
11725
+ }
11614
11726
  /**
11615
11727
  * Make a GET request to a REST API endpoint.
11616
11728
  *
@@ -11685,6 +11797,38 @@ var GadClient = class {
11685
11797
  }
11686
11798
  return this.handleResponse(response);
11687
11799
  }
11800
+ /**
11801
+ * Make a DELETE request to a REST API endpoint. Like POST, it is retried
11802
+ * only when the connection never reached the server.
11803
+ */
11804
+ async delete(path10) {
11805
+ const url2 = `${this.apiUrl}${path10}`;
11806
+ const headers = this.buildHeaders();
11807
+ delete headers["Content-Type"];
11808
+ let response;
11809
+ try {
11810
+ response = await this.fetchWithRetry(
11811
+ url2,
11812
+ { method: "DELETE", headers },
11813
+ void 0,
11814
+ "connection-only"
11815
+ );
11816
+ } catch (error62) {
11817
+ if (error62 instanceof CliError) throw error62;
11818
+ void captureCliEvent({
11819
+ apiUrl: this.apiUrl,
11820
+ token: this.token,
11821
+ name: "network_error",
11822
+ error: error62,
11823
+ context: { method: "DELETE", path: path10 }
11824
+ });
11825
+ throw networkError(
11826
+ `Network error on DELETE ${path10}.`,
11827
+ "Check your internet connection or run 'gad doctor'."
11828
+ );
11829
+ }
11830
+ return this.handleResponse(response);
11831
+ }
11688
11832
  };
11689
11833
 
11690
11834
  // src/lib/global-opts.ts
@@ -11778,10 +11922,10 @@ ${tryThese.map((t) => ` \u2022 ${t}`).join("\n")}`
11778
11922
 
11779
11923
  // src/lib/stdin.ts
11780
11924
  function readStream(stream) {
11781
- return new Promise((resolve4, reject) => {
11925
+ return new Promise((resolve5, reject) => {
11782
11926
  const chunks = [];
11783
11927
  stream.on("data", (chunk) => chunks.push(chunk));
11784
- stream.on("end", () => resolve4(Buffer.concat(chunks).toString("utf8")));
11928
+ stream.on("end", () => resolve5(Buffer.concat(chunks).toString("utf8")));
11785
11929
  stream.on("error", reject);
11786
11930
  });
11787
11931
  }
@@ -12323,8 +12467,8 @@ function text(value) {
12323
12467
  }
12324
12468
  function formatTodoDetail(todo) {
12325
12469
  const assignees = Array.isArray(todo.assignees) ? todo.assignees.map((a) => `${text(a.displayName)} (${text(a.type)})`).join(", ") : "";
12326
- const run2 = todo.lastRun ?? null;
12327
- const lastRun = run2 ? `${text(run2.status)} \u2014 ${text(run2.agentName)}` : "";
12470
+ const run4 = todo.lastRun ?? null;
12471
+ const lastRun = run4 ? `${text(run4.status)} \u2014 ${text(run4.agentName)}` : "";
12328
12472
  return {
12329
12473
  id: text(todo.id),
12330
12474
  title: text(todo.title),
@@ -12460,8 +12604,8 @@ var todo_default = todoCommand;
12460
12604
  import { execFileSync } from "node:child_process";
12461
12605
 
12462
12606
  // src/lib/claim-preflight.ts
12463
- function normalize(s) {
12464
- return s.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
12607
+ function normalize(s2) {
12608
+ return s2.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
12465
12609
  }
12466
12610
  function mentions(haystack, normSlug) {
12467
12611
  if (!haystack || !normSlug) return false;
@@ -12549,8 +12693,8 @@ var claimCommand = new Command("claim").description("Preflight + atomically clai
12549
12693
  todos.push(
12550
12694
  ...asArray(await client2.mcpCall("todo_list", { status }))
12551
12695
  );
12552
- } catch (err) {
12553
- debugSwallow(`claim.preflight(${status})`, err);
12696
+ } catch (err2) {
12697
+ debugSwallow(`claim.preflight(${status})`, err2);
12554
12698
  }
12555
12699
  }
12556
12700
  let activeClaims = [];
@@ -12559,8 +12703,8 @@ var claimCommand = new Command("claim").description("Preflight + atomically clai
12559
12703
  activeClaims = Array.isArray(
12560
12704
  intro?.activeClaims
12561
12705
  ) ? intro.activeClaims : [];
12562
- } catch (err) {
12563
- debugSwallow("claim.preflight(introspect)", err);
12706
+ } catch (err2) {
12707
+ debugSwallow("claim.preflight(introspect)", err2);
12564
12708
  activeClaims = [];
12565
12709
  }
12566
12710
  const conflicts = findPreflightConflicts({
@@ -12649,8 +12793,8 @@ function run(command, args, cwd) {
12649
12793
  timeout: LOCAL_COMMAND_TIMEOUT_MS
12650
12794
  });
12651
12795
  return { status: 0, stdout, stderr: "", timedOut: false };
12652
- } catch (err) {
12653
- const e = err;
12796
+ } catch (err2) {
12797
+ const e = err2;
12654
12798
  return {
12655
12799
  status: e.status ?? 1,
12656
12800
  stdout: e.stdout ?? "",
@@ -12665,7 +12809,7 @@ function git(args, cwd) {
12665
12809
  var WORKTREE_STATUS_CONCURRENCY = 8;
12666
12810
  var WORKTREE_STATUS_TIMEOUT_MS = 2e3;
12667
12811
  function gitAsync(args, cwd) {
12668
- return new Promise((resolve4) => {
12812
+ return new Promise((resolve5) => {
12669
12813
  execFile2(
12670
12814
  "git",
12671
12815
  args,
@@ -12676,7 +12820,7 @@ function gitAsync(args, cwd) {
12676
12820
  timeout: WORKTREE_STATUS_TIMEOUT_MS
12677
12821
  },
12678
12822
  (error62, stdout, stderr) => {
12679
- resolve4({
12823
+ resolve5({
12680
12824
  status: error62 ? 1 : 0,
12681
12825
  stdout: stdout ?? "",
12682
12826
  stderr: stderr ?? "",
@@ -13181,12 +13325,12 @@ import { execFileSync as execFileSync3 } from "node:child_process";
13181
13325
  import { existsSync, readFileSync as readFileSync2, statSync, writeFileSync as writeFileSync2 } from "node:fs";
13182
13326
  import { basename, dirname as dirname3, isAbsolute, join as join5, resolve } from "node:path";
13183
13327
  var realExec = (cmd, args, opts) => {
13184
- const out = execFileSync3(cmd, args, {
13328
+ const out2 = execFileSync3(cmd, args, {
13185
13329
  cwd: opts?.cwd,
13186
13330
  encoding: "utf8",
13187
13331
  stdio: opts?.inherit ? ["ignore", "inherit", "inherit"] : ["ignore", "pipe", "pipe"]
13188
13332
  });
13189
- return typeof out === "string" ? out : "";
13333
+ return typeof out2 === "string" ? out2 : "";
13190
13334
  };
13191
13335
  function assertCleanTree(statusPorcelain) {
13192
13336
  if (statusPorcelain.trim().length === 0) return;
@@ -14478,19 +14622,19 @@ function collectConfiguredHooks(scope, file2, content) {
14478
14622
  }
14479
14623
  const hooks = asObject(asObject(parsed)?.hooks ?? null);
14480
14624
  if (!hooks) return [];
14481
- const out = [];
14625
+ const out2 = [];
14482
14626
  for (const [event, groups] of Object.entries(hooks)) {
14483
14627
  if (!Array.isArray(groups)) continue;
14484
14628
  for (const group of groups) {
14485
14629
  if (!group || !Array.isArray(group.hooks)) continue;
14486
14630
  for (const hook of group.hooks) {
14487
14631
  if (hook && typeof hook.command === "string" && hook.command.trim()) {
14488
- out.push({ scope, file: file2, event, command: hook.command });
14632
+ out2.push({ scope, file: file2, event, command: hook.command });
14489
14633
  }
14490
14634
  }
14491
14635
  }
14492
14636
  }
14493
- return out;
14637
+ return out2;
14494
14638
  }
14495
14639
  function nodeScriptTarget(command) {
14496
14640
  const m = command.match(/\bnode\s+(?:"([^"]+)"|'([^']+)'|(\S+))/);
@@ -14785,11 +14929,11 @@ async function ensureHookCredential(opts) {
14785
14929
  status: verified ? "pass" : "fail",
14786
14930
  message: verified ? "Rewritten token authenticates" : `Rewritten token still failing (HTTP ${status})`
14787
14931
  });
14788
- } catch (err) {
14932
+ } catch (err2) {
14789
14933
  checks.push({
14790
14934
  name: "Hook credential: after repair",
14791
14935
  status: "warn",
14792
- message: `Rewrote the token but could not re-probe it (${err instanceof Error ? err.message : String(err)})`,
14936
+ message: `Rewrote the token but could not re-probe it (${err2 instanceof Error ? err2.message : String(err2)})`,
14793
14937
  hint: "Re-run `gad doctor` once the network is reachable to confirm."
14794
14938
  });
14795
14939
  }
@@ -16335,9 +16479,9 @@ async function resolveBridgeAuth(options = {}) {
16335
16479
  apiUrl: (apiUrlOverride || stored.apiUrl).replace(/\/$/, ""),
16336
16480
  source: "stored"
16337
16481
  };
16338
- } catch (err) {
16339
- if (err instanceof CliError && err.code === 1 /* AUTH_ERROR */ && /expired/i.test(err.message)) {
16340
- throw err;
16482
+ } catch (err2) {
16483
+ if (err2 instanceof CliError && err2.code === 1 /* AUTH_ERROR */ && /expired/i.test(err2.message)) {
16484
+ throw err2;
16341
16485
  }
16342
16486
  throw missingTokenError();
16343
16487
  }
@@ -16429,9 +16573,9 @@ async function forwardLine(line, config2) {
16429
16573
  return rpcError(id, -32603, "Upstream MCP endpoint returned non-JSON");
16430
16574
  }
16431
16575
  return text3.trim();
16432
- } catch (err) {
16576
+ } catch (err2) {
16433
16577
  if (isNotification) return null;
16434
- const message = err instanceof Error ? err.message : String(err);
16578
+ const message = err2 instanceof Error ? err2.message : String(err2);
16435
16579
  return rpcError(
16436
16580
  id,
16437
16581
  -32603,
@@ -16472,8 +16616,8 @@ async function runStdioBridge(options) {
16472
16616
  if (response) writeLine(response);
16473
16617
  });
16474
16618
  });
16475
- await new Promise((resolve4) => {
16476
- rl.on("close", () => resolve4());
16619
+ await new Promise((resolve5) => {
16620
+ rl.on("close", () => resolve5());
16477
16621
  });
16478
16622
  }
16479
16623
 
@@ -16506,7 +16650,7 @@ async function enableSuggestTools(home, deps = {}) {
16506
16650
  return { verified: credential.verified };
16507
16651
  }
16508
16652
  async function applySuggestToolsChoice(choice2, home = homedir6(), deps = {}) {
16509
- const out = deps.out ?? createFormatter({
16653
+ const out2 = deps.out ?? createFormatter({
16510
16654
  json: false,
16511
16655
  quiet: false,
16512
16656
  isTTY: isTTY(),
@@ -16516,7 +16660,7 @@ async function applySuggestToolsChoice(choice2, home = homedir6(), deps = {}) {
16516
16660
  const outcome = await runSuggestHookOptIn({
16517
16661
  choice: choice2,
16518
16662
  interactive: deps.interactive ?? Boolean(process.stdin.isTTY && process.stdout.isTTY),
16519
- print: (line) => out.info(line),
16663
+ print: (line) => out2.info(line),
16520
16664
  confirm: deps.confirm ?? confirm,
16521
16665
  enable: async () => {
16522
16666
  verified = (await enableSuggestTools(home, deps)).verified;
@@ -16525,10 +16669,10 @@ async function applySuggestToolsChoice(choice2, home = homedir6(), deps = {}) {
16525
16669
  });
16526
16670
  const { settingsPath } = suggestHookPaths(home);
16527
16671
  if (outcome === "enabled") {
16528
- out.success(`Tool suggestions ON (registered in ${settingsPath}).`);
16529
- if (!verified) out.warn(HOOK_CREDENTIAL_FIX_LINE);
16672
+ out2.success(`Tool suggestions ON (registered in ${settingsPath}).`);
16673
+ if (!verified) out2.warn(HOOK_CREDENTIAL_FIX_LINE);
16530
16674
  } else if (outcome === "disabled") {
16531
- out.success("Tool suggestions OFF (our hook entry removed).");
16675
+ out2.success("Tool suggestions OFF (our hook entry removed).");
16532
16676
  }
16533
16677
  return outcome;
16534
16678
  }
@@ -16596,12 +16740,12 @@ var CLIENT_IDS = {
16596
16740
  };
16597
16741
  async function mcpJsonAtRiskOfCommit(dir) {
16598
16742
  try {
16599
- const { execFile: execFile4 } = await import("node:child_process");
16743
+ const { execFile: execFile5 } = await import("node:child_process");
16600
16744
  const { promisify: promisify2 } = await import("node:util");
16601
- const run2 = promisify2(execFile4);
16602
- await run2("git", ["rev-parse", "--is-inside-work-tree"], { cwd: dir });
16745
+ const run4 = promisify2(execFile5);
16746
+ await run4("git", ["rev-parse", "--is-inside-work-tree"], { cwd: dir });
16603
16747
  try {
16604
- await run2("git", ["check-ignore", "-q", ".mcp.json"], { cwd: dir });
16748
+ await run4("git", ["check-ignore", "-q", ".mcp.json"], { cwd: dir });
16605
16749
  return false;
16606
16750
  } catch {
16607
16751
  return true;
@@ -16691,33 +16835,33 @@ async function pathExists(path10) {
16691
16835
  }
16692
16836
  }
16693
16837
  async function installCodexConfig(apiUrl, token, repoUrl) {
16694
- const { homedir: homedir10 } = await import("node:os");
16695
- const { join: join12 } = await import("node:path");
16696
- const { chmod: chmod2, copyFile: copyFile3, mkdir: mkdir8, readFile: readFile7, writeFile: writeFile6 } = await import("node:fs/promises");
16697
- const codexDir = join12(homedir10(), ".codex");
16698
- const configPath = join12(codexDir, "config.toml");
16699
- const envPath = join12(codexDir, ".env");
16838
+ const { homedir: homedir11 } = await import("node:os");
16839
+ const { join: join13 } = await import("node:path");
16840
+ const { chmod: chmod3, copyFile: copyFile3, mkdir: mkdir9, readFile: readFile9, writeFile: writeFile7 } = await import("node:fs/promises");
16841
+ const codexDir = join13(homedir11(), ".codex");
16842
+ const configPath = join13(codexDir, "config.toml");
16843
+ const envPath = join13(codexDir, ".env");
16700
16844
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
16701
- await mkdir8(codexDir, { recursive: true });
16702
- const existingConfig = await pathExists(configPath) ? await readFile7(configPath, "utf8") : "";
16845
+ await mkdir9(codexDir, { recursive: true });
16846
+ const existingConfig = await pathExists(configPath) ? await readFile9(configPath, "utf8") : "";
16703
16847
  if (existingConfig.trim()) {
16704
16848
  await copyFile3(configPath, `${configPath}.bak.${timestamp}`);
16705
16849
  }
16706
- await writeFile6(
16850
+ await writeFile7(
16707
16851
  configPath,
16708
16852
  upsertCodexServerBlock(existingConfig, apiUrl, repoUrl),
16709
16853
  "utf8"
16710
16854
  );
16711
- const existingEnv = await pathExists(envPath) ? await readFile7(envPath, "utf8") : "";
16855
+ const existingEnv = await pathExists(envPath) ? await readFile9(envPath, "utf8") : "";
16712
16856
  if (existingEnv.trim()) {
16713
16857
  await copyFile3(envPath, `${envPath}.bak.${timestamp}`);
16714
16858
  }
16715
- await writeFile6(
16859
+ await writeFile7(
16716
16860
  envPath,
16717
16861
  upsertEnvValue(existingEnv, "GREAT_ARROW_TOKEN", token),
16718
16862
  "utf8"
16719
16863
  );
16720
- await chmod2(envPath, 384);
16864
+ await chmod3(envPath, 384);
16721
16865
  return { configPath, envPath };
16722
16866
  }
16723
16867
  var startCommand = new Command("start").description(
@@ -16846,8 +16990,8 @@ async function checkDns(apiUrl, verbose, c) {
16846
16990
  if (verbose) process.stdout.write(`${c.green("\u2713")}
16847
16991
  `);
16848
16992
  return { check: "DNS Resolution", status: "pass", detail: url2.hostname };
16849
- } catch (err) {
16850
- const msg = err instanceof Error ? err.message : "failed";
16993
+ } catch (err2) {
16994
+ const msg = err2 instanceof Error ? err2.message : "failed";
16851
16995
  if (verbose) process.stdout.write(`${c.red("\u2717")} ${msg}
16852
16996
  `);
16853
16997
  return { check: "DNS Resolution", status: "fail", detail: msg };
@@ -16871,8 +17015,8 @@ async function checkEdgePing(apiUrl, verbose, c) {
16871
17015
  if (verbose) process.stdout.write(`${c.yellow("\u26A0")} ${detail}
16872
17016
  `);
16873
17017
  return { check: "Edge Ping", status: "warn", detail };
16874
- } catch (err) {
16875
- const msg = err instanceof Error ? err.message : "failed";
17018
+ } catch (err2) {
17019
+ const msg = err2 instanceof Error ? err2.message : "failed";
16876
17020
  if (verbose) process.stdout.write(`${c.red("\u2717")} ${msg}
16877
17021
  `);
16878
17022
  return { check: "Edge Ping", status: "fail", detail: msg };
@@ -16894,8 +17038,8 @@ async function checkJsonRpc(client2, verbose, c) {
16894
17038
  if (verbose) process.stdout.write(`${c.green("\u2713")} ${detail}
16895
17039
  `);
16896
17040
  return { check: "JSON-RPC Handshake", status: "pass", detail };
16897
- } catch (err) {
16898
- const msg = err instanceof Error ? err.message : "failed";
17041
+ } catch (err2) {
17042
+ const msg = err2 instanceof Error ? err2.message : "failed";
16899
17043
  if (verbose) process.stdout.write(`${c.red("\u2717")} ${msg}
16900
17044
  `);
16901
17045
  return { check: "JSON-RPC Handshake", status: "fail", detail: msg };
@@ -17005,15 +17149,15 @@ var installCommand = new Command("install").description("Generate MCP configurat
17005
17149
  process.stdout.write(configJson2 + "\n");
17006
17150
  return;
17007
17151
  }
17008
- const { homedir: homedir10 } = await import("node:os");
17009
- const { join: join13 } = await import("node:path");
17010
- const { mkdir: mkdir8, readFile: readFile7, writeFile: writeFile7 } = await import("node:fs/promises");
17011
- const geminiDir = join13(homedir10(), ".gemini");
17012
- const mcpPath = join13(geminiDir, "settings.json");
17013
- await mkdir8(geminiDir, { recursive: true });
17152
+ const { homedir: homedir11 } = await import("node:os");
17153
+ const { join: join14 } = await import("node:path");
17154
+ const { mkdir: mkdir9, readFile: readFile9, writeFile: writeFile8 } = await import("node:fs/promises");
17155
+ const geminiDir = join14(homedir11(), ".gemini");
17156
+ const mcpPath = join14(geminiDir, "settings.json");
17157
+ await mkdir9(geminiDir, { recursive: true });
17014
17158
  let existingConfig = {};
17015
17159
  try {
17016
- const content = await readFile7(mcpPath, "utf-8");
17160
+ const content = await readFile9(mcpPath, "utf-8");
17017
17161
  existingConfig = JSON.parse(content);
17018
17162
  } catch {
17019
17163
  existingConfig = {};
@@ -17025,20 +17169,20 @@ var installCommand = new Command("install").description("Generate MCP configurat
17025
17169
  ...config3.mcpServers
17026
17170
  }
17027
17171
  };
17028
- await writeFile7(
17172
+ await writeFile8(
17029
17173
  mcpPath,
17030
17174
  JSON.stringify(existingConfig, null, 2) + "\n",
17031
17175
  "utf-8"
17032
17176
  );
17033
17177
  fmt.success(`Wrote gemini MCP config to ${mcpPath}`);
17034
- const agyMcpDir = join13(
17178
+ const agyMcpDir = join14(
17035
17179
  geminiDir,
17036
17180
  "antigravity-cli",
17037
17181
  "mcp",
17038
17182
  MCP_SERVER_NAME
17039
17183
  );
17040
- await mkdir8(agyMcpDir, { recursive: true });
17041
- const instructionsPath = join13(agyMcpDir, "instructions.md");
17184
+ await mkdir9(agyMcpDir, { recursive: true });
17185
+ const instructionsPath = join14(agyMcpDir, "instructions.md");
17042
17186
  const instructionsContent = `You are connected to greatarrow.ai - the user's private workspace memory + integrations brain.
17043
17187
 
17044
17188
  CRITICAL DIRECTIVE (MANDATORY STANDARD):
@@ -17054,7 +17198,7 @@ THREE-LAYER LIVE TASK TRACKING:
17054
17198
  - Maintain client-native harness plans, Great Arrow Kanban cards (\`todo_create\`, \`todo_update\`), and resume states.
17055
17199
 
17056
17200
  Always assume full autonomy to leverage these tools to their maximum extent.`;
17057
- await writeFile7(instructionsPath, instructionsContent, "utf-8");
17201
+ await writeFile8(instructionsPath, instructionsContent, "utf-8");
17058
17202
  fmt.success(`Wrote gemini MCP instructions to ${instructionsPath}`);
17059
17203
  return;
17060
17204
  }
@@ -17069,10 +17213,10 @@ Always assume full autonomy to leverage these tools to their maximum extent.`;
17069
17213
  process.stdout.write(configJson + "\n");
17070
17214
  return;
17071
17215
  }
17072
- const { writeFile: writeFile6 } = await import("node:fs/promises");
17073
- const { join: join12 } = await import("node:path");
17074
- const outputPath = join12(process.cwd(), ".mcp.json");
17075
- await writeFile6(outputPath, configJson + "\n", { mode: 384 });
17216
+ const { writeFile: writeFile7 } = await import("node:fs/promises");
17217
+ const { join: join13 } = await import("node:path");
17218
+ const outputPath = join13(process.cwd(), ".mcp.json");
17219
+ await writeFile7(outputPath, configJson + "\n", { mode: 384 });
17076
17220
  fmt.success(`Wrote ${clientName} MCP config to .mcp.json`);
17077
17221
  if (await mcpJsonAtRiskOfCommit(process.cwd())) {
17078
17222
  fmt.warn(
@@ -17088,9 +17232,9 @@ var KEYCHAIN_SERVICE = "GreatArrowDigital";
17088
17232
  var KEYCHAIN_ACCOUNT = "api-token";
17089
17233
  var OAUTH_CRED_FILENAME = "oauth-credential.json";
17090
17234
  async function readIfExists(path10) {
17091
- const { readFile: readFile7 } = await import("node:fs/promises");
17235
+ const { readFile: readFile9 } = await import("node:fs/promises");
17092
17236
  try {
17093
- return await readFile7(path10, "utf8");
17237
+ return await readFile9(path10, "utf8");
17094
17238
  } catch {
17095
17239
  return null;
17096
17240
  }
@@ -17105,13 +17249,13 @@ async function readKeychainOnly() {
17105
17249
  }
17106
17250
  }
17107
17251
  async function resolveProxyScript(override) {
17108
- const { homedir: homedir10 } = await import("node:os");
17109
- const { join: join12 } = await import("node:path");
17252
+ const { homedir: homedir11 } = await import("node:os");
17253
+ const { join: join13 } = await import("node:path");
17110
17254
  const candidates = [
17111
17255
  override,
17112
17256
  process.env.GAD_PROXY_SCRIPT,
17113
- join12(homedir10(), ".great-arrow", "mcp-server.mjs"),
17114
- join12(process.cwd(), "scripts", "mcp-server.mjs")
17257
+ join13(homedir11(), ".great-arrow", "mcp-server.mjs"),
17258
+ join13(process.cwd(), "scripts", "mcp-server.mjs")
17115
17259
  ].filter((c) => Boolean(c));
17116
17260
  for (const candidate of candidates) {
17117
17261
  if (await pathExists(candidate)) return candidate;
@@ -17119,11 +17263,11 @@ async function resolveProxyScript(override) {
17119
17263
  return null;
17120
17264
  }
17121
17265
  async function runProxyDiagnostics(scriptPath) {
17122
- const { execFile: execFile4 } = await import("node:child_process");
17266
+ const { execFile: execFile5 } = await import("node:child_process");
17123
17267
  const { promisify: promisify2 } = await import("node:util");
17124
- const run2 = promisify2(execFile4);
17268
+ const run4 = promisify2(execFile5);
17125
17269
  try {
17126
- const { stdout } = await run2(
17270
+ const { stdout } = await run4(
17127
17271
  process.execPath,
17128
17272
  [scriptPath, "--print-diagnostics"],
17129
17273
  { timeout: 1e4, maxBuffer: 1024 * 1024 }
@@ -17135,22 +17279,22 @@ async function runProxyDiagnostics(scriptPath) {
17135
17279
  }
17136
17280
  }
17137
17281
  async function findLegacyStores(cwd) {
17138
- const { join: join12 } = await import("node:path");
17282
+ const { join: join13 } = await import("node:path");
17139
17283
  const { readdir } = await import("node:fs/promises");
17140
17284
  const dirs = /* @__PURE__ */ new Set([cwd]);
17141
17285
  try {
17142
- const worktreeRoot = join12(cwd, ".claude", "worktrees");
17286
+ const worktreeRoot = join13(cwd, ".claude", "worktrees");
17143
17287
  for (const entry of await readdir(worktreeRoot, { withFileTypes: true })) {
17144
- if (entry.isDirectory()) dirs.add(join12(worktreeRoot, entry.name));
17288
+ if (entry.isDirectory()) dirs.add(join13(worktreeRoot, entry.name));
17145
17289
  }
17146
- } catch (err) {
17147
- debugSwallow("mcp.findLegacyStores(worktrees)", err);
17290
+ } catch (err2) {
17291
+ debugSwallow("mcp.findLegacyStores(worktrees)", err2);
17148
17292
  }
17149
17293
  try {
17150
- const { execFile: execFile4 } = await import("node:child_process");
17294
+ const { execFile: execFile5 } = await import("node:child_process");
17151
17295
  const { promisify: promisify2 } = await import("node:util");
17152
- const run2 = promisify2(execFile4);
17153
- const { stdout } = await run2("git", ["worktree", "list", "--porcelain"], {
17296
+ const run4 = promisify2(execFile5);
17297
+ const { stdout } = await run4("git", ["worktree", "list", "--porcelain"], {
17154
17298
  cwd,
17155
17299
  timeout: 5e3
17156
17300
  });
@@ -17158,23 +17302,23 @@ async function findLegacyStores(cwd) {
17158
17302
  if (line.startsWith("worktree "))
17159
17303
  dirs.add(line.slice("worktree ".length));
17160
17304
  }
17161
- } catch (err) {
17162
- debugSwallow("mcp.findLegacyStores(git)", err);
17305
+ } catch (err2) {
17306
+ debugSwallow("mcp.findLegacyStores(git)", err2);
17163
17307
  }
17164
17308
  const stores = [];
17165
17309
  for (const dir of dirs) {
17166
- const path10 = join12(dir, ".mcp", OAUTH_CRED_FILENAME);
17310
+ const path10 = join13(dir, ".mcp", OAUTH_CRED_FILENAME);
17167
17311
  const raw = await readIfExists(path10);
17168
17312
  if (raw !== null) stores.push({ path: path10, raw });
17169
17313
  }
17170
17314
  return stores;
17171
17315
  }
17172
17316
  async function scanConnections() {
17173
- const { homedir: homedir10 } = await import("node:os");
17174
- const { join: join12 } = await import("node:path");
17175
- const home = homedir10();
17317
+ const { homedir: homedir11 } = await import("node:os");
17318
+ const { join: join13 } = await import("node:path");
17319
+ const home = homedir11();
17176
17320
  const hookSettings = await readIfExists(
17177
- join12(home, ".claude", "settings.json")
17321
+ join13(home, ".claude", "settings.json")
17178
17322
  );
17179
17323
  const hooksInstalled = hookSettings ? hasGreatArrowHooks(hookSettings) : false;
17180
17324
  const entries = [];
@@ -17207,29 +17351,29 @@ async function probeEndpoint() {
17207
17351
  }
17208
17352
  }
17209
17353
  async function applyMigration(plan) {
17210
- const { homedir: homedir10 } = await import("node:os");
17211
- const { join: join12 } = await import("node:path");
17212
- const { mkdir: mkdir8, rename: rename2, writeFile: writeFile6 } = await import("node:fs/promises");
17354
+ const { homedir: homedir11 } = await import("node:os");
17355
+ const { join: join13 } = await import("node:path");
17356
+ const { mkdir: mkdir9, rename: rename3, writeFile: writeFile7 } = await import("node:fs/promises");
17213
17357
  const applied = [];
17214
- const dir = join12(homedir10(), ".great-arrow");
17215
- await mkdir8(dir, { recursive: true, mode: 448 });
17358
+ const dir = join13(homedir11(), ".great-arrow");
17359
+ await mkdir9(dir, { recursive: true, mode: 448 });
17216
17360
  if (plan.seedFrom) {
17217
17361
  const raw = await readIfExists(plan.seedFrom);
17218
17362
  if (raw !== null) {
17219
- const target = join12(dir, OAUTH_CRED_FILENAME);
17363
+ const target = join13(dir, OAUTH_CRED_FILENAME);
17220
17364
  const tmp = `${target}.tmp`;
17221
- await writeFile6(tmp, raw, { mode: 384 });
17222
- await rename2(tmp, target);
17365
+ await writeFile7(tmp, raw, { mode: 384 });
17366
+ await rename3(tmp, target);
17223
17367
  applied.push(`Copied ${plan.seedFrom} \u2192 ${target}`);
17224
17368
  }
17225
17369
  }
17226
17370
  if (plan.syncKeychainToFile) {
17227
17371
  const raw = await readKeychainOnly();
17228
17372
  if (raw) {
17229
- const target = join12(dir, "credential");
17373
+ const target = join13(dir, "credential");
17230
17374
  const tmp = `${target}.tmp`;
17231
- await writeFile6(tmp, raw, { mode: 384 });
17232
- await rename2(tmp, target);
17375
+ await writeFile7(tmp, raw, { mode: 384 });
17376
+ await rename3(tmp, target);
17233
17377
  applied.push(`Wrote the keychain credential to ${target}`);
17234
17378
  }
17235
17379
  }
@@ -17252,19 +17396,19 @@ var doctorSubcommand = new Command("doctor").description(
17252
17396
  noColor: false
17253
17397
  });
17254
17398
  const c = createColor(jsonFlag);
17255
- const { homedir: homedir10 } = await import("node:os");
17256
- const { join: join12 } = await import("node:path");
17257
- const home = homedir10();
17399
+ const { homedir: homedir11 } = await import("node:os");
17400
+ const { join: join13 } = await import("node:path");
17401
+ const home = homedir11();
17258
17402
  const proxyPath = await resolveProxyScript(options.proxy);
17259
17403
  const diagnostics = proxyPath ? await runProxyDiagnostics(proxyPath) : null;
17260
17404
  const entries = await scanConnections();
17261
17405
  const duplicates = detectDuplicates(entries);
17262
17406
  const keychain = await readKeychainOnly();
17263
17407
  const credentialFile = await readIfExists(
17264
- join12(home, ".great-arrow", "credential")
17408
+ join13(home, ".great-arrow", "credential")
17265
17409
  );
17266
17410
  const userStore = await readIfExists(
17267
- join12(home, ".great-arrow", OAUTH_CRED_FILENAME)
17411
+ join13(home, ".great-arrow", OAUTH_CRED_FILENAME)
17268
17412
  );
17269
17413
  const legacyStores = await findLegacyStores(process.cwd());
17270
17414
  const findings = [
@@ -17404,9 +17548,9 @@ async function runSmokeTest(client2, test) {
17404
17548
  await client2.mcpCall(test.tool, test.args);
17405
17549
  const durationMs = Math.round(performance.now() - start);
17406
17550
  return { name: test.name, tool: test.tool, status: "pass", durationMs };
17407
- } catch (err) {
17551
+ } catch (err2) {
17408
17552
  const durationMs = Math.round(performance.now() - start);
17409
- const error62 = err instanceof Error ? err.message : "Unknown error";
17553
+ const error62 = err2 instanceof Error ? err2.message : "Unknown error";
17410
17554
  return {
17411
17555
  name: test.name,
17412
17556
  tool: test.tool,
@@ -17679,6 +17823,137 @@ var agentsCommand = new Command("agents").description(
17679
17823
  process.stdout.write(renderAgentsNow(result) + "\n");
17680
17824
  });
17681
17825
 
17826
+ // src/commands/inbox.ts
17827
+ var BACKOFF_BASE_MS = 15e3;
17828
+ var BACKOFF_MAX_MS = 12e4;
17829
+ var DEFAULT_MAX_MINUTES = 50;
17830
+ var PRESENCE_NOT_ENABLED = "Agent presence is not enabled.";
17831
+ function waitBackoffMs(emptyHolds) {
17832
+ if (emptyHolds < 3) return 0;
17833
+ return Math.min(2 ** (emptyHolds - 3) * BACKOFF_BASE_MS, BACKOFF_MAX_MS);
17834
+ }
17835
+ function asMessage(body) {
17836
+ if (!body || typeof body !== "object") return null;
17837
+ const b = body;
17838
+ return b.status === "message" && typeof b.messageId === "string" && typeof b.block === "string" ? { messageId: b.messageId, block: b.block } : null;
17839
+ }
17840
+ async function runInboxWait(o) {
17841
+ const sleep2 = o.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
17842
+ const now = o.now ?? Date.now;
17843
+ const write = o.write ?? ((t) => void process.stdout.write(t));
17844
+ const writeErr = o.writeErr ?? ((t) => void process.stderr.write(t));
17845
+ const stopAt = now() + (o.maxMinutes ?? DEFAULT_MAX_MINUTES) * 6e4;
17846
+ let emptyHolds = 0;
17847
+ while (now() < stopAt) {
17848
+ const params = { as: o.as };
17849
+ if (o.after) params.after = o.after;
17850
+ if (o.waitingOn !== void 0) params.waiting_on = o.waitingOn;
17851
+ let res = null;
17852
+ try {
17853
+ res = await o.request(params);
17854
+ } catch {
17855
+ res = null;
17856
+ }
17857
+ if (res?.status === 404) {
17858
+ writeErr(`${PRESENCE_NOT_ENABLED}
17859
+ `);
17860
+ return 2;
17861
+ }
17862
+ const msg = res && res.status === 200 ? asMessage(res.body) : null;
17863
+ if (msg) {
17864
+ const block = msg.block.endsWith("\n") ? msg.block : `${msg.block}
17865
+ `;
17866
+ write(`${block}after=${msg.messageId}
17867
+ `);
17868
+ return 0;
17869
+ }
17870
+ const gap = Math.min(waitBackoffMs(emptyHolds++), stopAt - now());
17871
+ if (gap > 0) await sleep2(gap);
17872
+ }
17873
+ return 3;
17874
+ }
17875
+ function parseMaxMinutes(raw) {
17876
+ const n = Number(raw);
17877
+ return Number.isFinite(n) && n > 0 ? n : DEFAULT_MAX_MINUTES;
17878
+ }
17879
+ var waitCommand = new Command("wait").description(
17880
+ "Wait for a peer's message to this connection; run as a background task"
17881
+ ).requiredOption("--as <id>", "Your connection id (from agent_inbox)").option("--after <id>", "Only wake for messages newer than this id").option("--waiting-on <text>", "What you are waiting on, shown to peers").option("--max-minutes <n>", "Give up after this many minutes", "50").action(
17882
+ async (opts) => {
17883
+ const auth = await resolveAuth();
17884
+ const client2 = new GadClient({
17885
+ token: auth.token,
17886
+ getToken: auth.getToken,
17887
+ apiUrl: auth.apiUrl
17888
+ });
17889
+ process.exitCode = await runInboxWait({
17890
+ request: (params) => client2.requestOnce("GET", "/api/agent-comms/wait", { params }),
17891
+ as: opts.as,
17892
+ after: opts.after,
17893
+ waitingOn: opts.waitingOn,
17894
+ maxMinutes: parseMaxMinutes(opts.maxMinutes)
17895
+ });
17896
+ }
17897
+ );
17898
+ var inboxCommand = new Command("inbox").description("Agent inbox \u2014 wait for a peer's message").addCommand(waitCommand);
17899
+
17900
+ // src/commands/presence.ts
17901
+ function doNotDisturbBody(raw, as) {
17902
+ if (raw.trim().toLowerCase() === "off") {
17903
+ return { action: "do_not_disturb", as, minutes: null };
17904
+ }
17905
+ const minutes = Number(raw);
17906
+ if (!Number.isFinite(minutes) || minutes <= 0) {
17907
+ throw new CliError(
17908
+ `Expected a number of minutes or "off", got "${raw}".`,
17909
+ 3 /* VALIDATION_ERROR */
17910
+ );
17911
+ }
17912
+ return { action: "do_not_disturb", as, minutes };
17913
+ }
17914
+ async function sendPresence(o) {
17915
+ const write = o.write ?? ((t) => void process.stdout.write(t));
17916
+ const writeErr = o.writeErr ?? ((t) => void process.stderr.write(t));
17917
+ const res = await o.request(o.body);
17918
+ if (res.status === 404) {
17919
+ writeErr(`${PRESENCE_NOT_ENABLED}
17920
+ `);
17921
+ return 2;
17922
+ }
17923
+ if (res.status < 200 || res.status >= 300) {
17924
+ writeErr(`Presence update failed (HTTP ${res.status}).
17925
+ `);
17926
+ return res.status === 401 || res.status === 403 ? 1 /* AUTH_ERROR */ : res.status === 400 ? 3 /* VALIDATION_ERROR */ : 2 /* NETWORK_ERROR */;
17927
+ }
17928
+ const b = o.body;
17929
+ write(
17930
+ b.action === "sign_off" ? "Signed off.\n" : b.minutes === null ? "Do not disturb is off.\n" : `Do not disturb for ${b.minutes} minutes.
17931
+ `
17932
+ );
17933
+ return 0;
17934
+ }
17935
+ async function run2(body) {
17936
+ const auth = await resolveAuth();
17937
+ const client2 = new GadClient({
17938
+ token: auth.token,
17939
+ getToken: auth.getToken,
17940
+ apiUrl: auth.apiUrl
17941
+ });
17942
+ process.exitCode = await sendPresence({
17943
+ request: (b) => client2.requestOnce("POST", "/api/agent-comms/presence", { body: b }),
17944
+ body
17945
+ });
17946
+ }
17947
+ var presenceCommand = new Command("presence").description("Tell peers you are away: do not disturb, or sign off").addCommand(
17948
+ new Command("do-not-disturb").description("Tell peers not to disturb you for a while, or turn it off").argument("<minutes|off>", "Minutes (up to 480), or off").requiredOption("--as <id>", "Your connection id (from agent_inbox)").action(async (raw, opts) => {
17949
+ await run2(doNotDisturbBody(raw, opts.as));
17950
+ })
17951
+ ).addCommand(
17952
+ new Command("sign-off").description("Mark this connection as signed off").requiredOption("--as <id>", "Your connection id (from agent_inbox)").action(async (opts) => {
17953
+ await run2({ action: "sign_off", as: opts.as });
17954
+ })
17955
+ );
17956
+
17682
17957
  // src/commands/ask.ts
17683
17958
  var ORCHESTRATOR_TIMEOUT_MS = 9e4;
17684
17959
  var ANSWER_FIELDS = [
@@ -17931,8 +18206,8 @@ async function maybeShowGlanceFooter(argv) {
17931
18206
  token: auth.token,
17932
18207
  keys: printed
17933
18208
  });
17934
- } catch (err) {
17935
- debugSwallow("glance-footer", err);
18209
+ } catch (err2) {
18210
+ debugSwallow("glance-footer", err2);
17936
18211
  }
17937
18212
  }
17938
18213
  function shouldRunGlanceFooter(argv) {
@@ -18161,6 +18436,17 @@ function normalizeGlance(raw) {
18161
18436
  dismissKey: r.dismissKey
18162
18437
  } : null;
18163
18438
  })(),
18439
+ // Same rule: both counts must be counts, or the line is dropped.
18440
+ keyRotation: (() => {
18441
+ const raw2 = obj.keyRotation;
18442
+ if (typeof raw2 !== "object" || raw2 === null) return null;
18443
+ const r = raw2;
18444
+ const count2 = (v) => typeof v === "number" && Number.isInteger(v) && v >= 0;
18445
+ return count2(r.needsYou) && count2(r.pendingDevices) ? {
18446
+ needsYou: r.needsYou,
18447
+ pendingDevices: r.pendingDevices
18448
+ } : null;
18449
+ })(),
18164
18450
  ...(() => {
18165
18451
  const raw2 = obj.landing;
18166
18452
  if (typeof raw2 !== "object" || raw2 === null) return {};
@@ -18195,9 +18481,9 @@ function asNullableString(value) {
18195
18481
  function normalizeTodaySections(raw) {
18196
18482
  return raw.flatMap((section) => {
18197
18483
  if (typeof section !== "object" || section === null) return [];
18198
- const s = section;
18199
- if (typeof s.key !== "string" || typeof s.title !== "string") return [];
18200
- const rows = asArray2(s.rows).flatMap((row) => {
18484
+ const s2 = section;
18485
+ if (typeof s2.key !== "string" || typeof s2.title !== "string") return [];
18486
+ const rows = asArray2(s2.rows).flatMap((row) => {
18201
18487
  if (typeof row !== "object" || row === null) return [];
18202
18488
  const r = row;
18203
18489
  if (typeof r.id !== "string" || typeof r.title !== "string") return [];
@@ -18212,7 +18498,7 @@ function normalizeTodaySections(raw) {
18212
18498
  }
18213
18499
  ];
18214
18500
  });
18215
- return rows.length > 0 ? [{ key: s.key, title: s.title, rows }] : [];
18501
+ return rows.length > 0 ? [{ key: s2.key, title: s2.title, rows }] : [];
18216
18502
  });
18217
18503
  }
18218
18504
  function asArray2(value) {
@@ -18688,8 +18974,8 @@ function createLocalDeviceLocator(scope, directory = join10(homedir9(), ".great-
18688
18974
  let file2;
18689
18975
  try {
18690
18976
  file2 = await open2(path10, constants.O_RDONLY | constants.O_NOFOLLOW);
18691
- } catch (err) {
18692
- if (err.code === "ENOENT") return null;
18977
+ } catch (err2) {
18978
+ if (err2.code === "ENOENT") return null;
18693
18979
  throw new Error("Device locator could not be read");
18694
18980
  }
18695
18981
  try {
@@ -20786,10 +21072,10 @@ function defineLazyInternal(inst, key, compute) {
20786
21072
  Object.defineProperty(this, key, { configurable: true, writable: true, value });
20787
21073
  broke = broke || outer;
20788
21074
  return value;
20789
- } catch (err) {
21075
+ } catch (err2) {
20790
21076
  delete this[key];
20791
21077
  broke = broke || outer;
20792
- throw err;
21078
+ throw err2;
20793
21079
  }
20794
21080
  },
20795
21081
  set(value) {
@@ -22212,9 +22498,9 @@ var asciiTabOrNewline = /[\t\n\r]/g;
22212
22498
  function stripTabAndNewline(value) {
22213
22499
  return value.replace(asciiTabOrNewline, "");
22214
22500
  }
22215
- function urlHostnameOk(url2, hostname5) {
22216
- hostname5.lastIndex = 0;
22217
- return hostname5.test(url2.hostname);
22501
+ function urlHostnameOk(url2, hostname6) {
22502
+ hostname6.lastIndex = 0;
22503
+ return hostname6.test(url2.hostname);
22218
22504
  }
22219
22505
  function urlProtocolOk(url2, protocol) {
22220
22506
  protocol.lastIndex = 0;
@@ -23406,7 +23692,7 @@ function handleIntersectionResults(result, left, right) {
23406
23692
  const unrecKeys = /* @__PURE__ */ new Map();
23407
23693
  let unrecIssue;
23408
23694
  const keyIssues = /* @__PURE__ */ new Map();
23409
- const collect2 = (iss, side) => {
23695
+ const collect3 = (iss, side) => {
23410
23696
  let keys;
23411
23697
  if (iss.code === "unrecognized_keys" && !iss.path?.length) {
23412
23698
  unrecIssue ?? (unrecIssue = iss);
@@ -23427,11 +23713,11 @@ function handleIntersectionResults(result, left, right) {
23427
23713
  return true;
23428
23714
  };
23429
23715
  for (const iss of left.issues) {
23430
- if (!collect2(iss, "l"))
23716
+ if (!collect3(iss, "l"))
23431
23717
  result.issues.push(iss);
23432
23718
  }
23433
23719
  for (const iss of right.issues) {
23434
- if (!collect2(iss, "r"))
23720
+ if (!collect3(iss, "r"))
23435
23721
  result.issues.push(iss);
23436
23722
  }
23437
23723
  const bothKeys = [...unrecKeys].filter(([, f]) => f.l && f.r).map(([k]) => k);
@@ -24255,7 +24541,7 @@ function partPattern(schema) {
24255
24541
  if (def.options) {
24256
24542
  const sources = def.options.map(partPattern);
24257
24543
  if (sources.every(Boolean))
24258
- return `^(${sources.map((s) => cleanRegex(s)).join("|")})$`;
24544
+ return `^(${sources.map((s2) => cleanRegex(s2)).join("|")})$`;
24259
24545
  }
24260
24546
  return leafPattern(schema);
24261
24547
  }
@@ -24453,7 +24739,7 @@ var recursive = /* @__PURE__ */ new WeakMap();
24453
24739
  var NONE = 0;
24454
24740
  var ASSUMED = 1;
24455
24741
  var PROVEN = 2;
24456
- function isRecursive(inst, stack, resolve4) {
24742
+ function isRecursive(inst, stack, resolve5) {
24457
24743
  const cached2 = recursive.get(inst);
24458
24744
  if (cached2 !== void 0)
24459
24745
  return cached2 ? PROVEN : NONE;
@@ -24463,7 +24749,7 @@ function isRecursive(inst, stack, resolve4) {
24463
24749
  let result = NONE;
24464
24750
  const check2 = (child) => {
24465
24751
  if (result !== PROVEN && child?._zod) {
24466
- const answer = isRecursive(child, stack, resolve4);
24752
+ const answer = isRecursive(child, stack, resolve5);
24467
24753
  if (answer > result)
24468
24754
  result = answer;
24469
24755
  }
@@ -24474,7 +24760,7 @@ function isRecursive(inst, stack, resolve4) {
24474
24760
  const desc = Object.getOwnPropertyDescriptor(sh, key);
24475
24761
  if (spread && !desc.enumerable)
24476
24762
  continue;
24477
- const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve4) : NONE;
24763
+ const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve5) : NONE;
24478
24764
  if (child > answer)
24479
24765
  answer = child;
24480
24766
  }
@@ -24538,7 +24824,7 @@ function isRecursive(inst, stack, resolve4) {
24538
24824
  break;
24539
24825
  // `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
24540
24826
  case "lazy": {
24541
- const inner = def._cachedInner ?? (resolve4 ? inst._zod.innerType : void 0);
24827
+ const inner = def._cachedInner ?? (resolve5 ? inst._zod.innerType : void 0);
24542
24828
  merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
24543
24829
  break;
24544
24830
  }
@@ -32357,9 +32643,9 @@ function compile(schema, options) {
32357
32643
  const clone2 = withParser(schema, parser);
32358
32644
  clone2._zod.bag.validator = compileValidator(schema, parser);
32359
32645
  return clone2;
32360
- } catch (err) {
32646
+ } catch (err2) {
32361
32647
  if (options?.strict)
32362
- throw err;
32648
+ throw err2;
32363
32649
  return schema;
32364
32650
  }
32365
32651
  }
@@ -32377,9 +32663,9 @@ function withParser(schema, parser) {
32377
32663
  if (ctx && isBackEdge(ctx, payload.value)) {
32378
32664
  return originalRun(payload, ctx);
32379
32665
  }
32380
- const out = parser(payload.value);
32381
- if (out !== INVALID) {
32382
- payload.value = out;
32666
+ const out2 = parser(payload.value);
32667
+ if (out2 !== INVALID) {
32668
+ payload.value = out2;
32383
32669
  return payload;
32384
32670
  }
32385
32671
  if (ctx)
@@ -32400,9 +32686,9 @@ function installCompiledUserMethods(target, source, parser) {
32400
32686
  if (typeof sourceAny.safeParse === "function") {
32401
32687
  const originalSafeParse = sourceAny.safeParse;
32402
32688
  targetAny.safeParse = (data, params) => {
32403
- const out = parser(data);
32404
- if (out !== INVALID) {
32405
- return { success: true, data: out };
32689
+ const out2 = parser(data);
32690
+ if (out2 !== INVALID) {
32691
+ return { success: true, data: out2 };
32406
32692
  }
32407
32693
  return originalSafeParse(data, params);
32408
32694
  };
@@ -32410,9 +32696,9 @@ function installCompiledUserMethods(target, source, parser) {
32410
32696
  if (typeof sourceAny.parse === "function") {
32411
32697
  const originalParse = sourceAny.parse;
32412
32698
  targetAny.parse = (data, params) => {
32413
- const out = parser(data);
32414
- if (out !== INVALID) {
32415
- return out;
32699
+ const out2 = parser(data);
32700
+ if (out2 !== INVALID) {
32701
+ return out2;
32416
32702
  }
32417
32703
  return originalParse(data, params);
32418
32704
  };
@@ -32449,8 +32735,8 @@ ${code}
32449
32735
  try {
32450
32736
  const factory = new F(...constantNames, factoryCode);
32451
32737
  fn = factory(...constantValues);
32452
- } catch (err) {
32453
- throw new ZodCompileUnsupportedError(`this schema (generated code failed to evaluate: ${err.message})`);
32738
+ } catch (err2) {
32739
+ throw new ZodCompileUnsupportedError(`this schema (generated code failed to evaluate: ${err2.message})`);
32454
32740
  }
32455
32741
  if (options?.debug) {
32456
32742
  fn.code = fullCode;
@@ -32488,9 +32774,9 @@ function compileChild(doc, ctx, schema, accessor, needsValue = true) {
32488
32774
  const varCounter = ctx.varCounter;
32489
32775
  try {
32490
32776
  return generateCheck(doc, ctx, schema, accessor, needsValue);
32491
- } catch (err) {
32492
- if (!(err instanceof ZodCompileUnsupportedError) || !err.islandable)
32493
- throw err;
32777
+ } catch (err2) {
32778
+ if (!(err2 instanceof ZodCompileUnsupportedError) || !err2.islandable)
32779
+ throw err2;
32494
32780
  doc.content.length = contentLen;
32495
32781
  if (ctx.constants.size > constantCount) {
32496
32782
  const trailing = Array.from(ctx.constants.keys()).slice(constantCount);
@@ -33173,13 +33459,13 @@ function generateObjectCheck(doc, ctx, schema, accessor, buildsValue = true) {
33173
33459
  doc.write(`const ${outputVar} = {};`);
33174
33460
  for (const k of allKeys) {
33175
33461
  const kx = keyExpr(k);
33176
- const out = propOutputs.get(k);
33462
+ const out2 = propOutputs.get(k);
33177
33463
  if (dropsWhenAbsent(propShape[k])) {
33178
- doc.write(`if (${kx} in ${accessor}) ${outputVar}[${kx}] = ${out};`);
33464
+ doc.write(`if (${kx} in ${accessor}) ${outputVar}[${kx}] = ${out2};`);
33179
33465
  } else if (mayOmitUndefined(propShape[k])) {
33180
- doc.write(`if (${out} !== undefined || ${kx} in ${accessor}) ${outputVar}[${kx}] = ${out};`);
33466
+ doc.write(`if (${out2} !== undefined || ${kx} in ${accessor}) ${outputVar}[${kx}] = ${out2};`);
33181
33467
  } else {
33182
- doc.write(`${outputVar}[${kx}] = ${out};`);
33468
+ doc.write(`${outputVar}[${kx}] = ${out2};`);
33183
33469
  }
33184
33470
  }
33185
33471
  }
@@ -34811,11 +35097,11 @@ function _catch(Class2, innerType, catchValue) {
34811
35097
  });
34812
35098
  }
34813
35099
  // @__NO_SIDE_EFFECTS__
34814
- function _pipe(Class2, in_, out) {
35100
+ function _pipe(Class2, in_, out2) {
34815
35101
  return new Class2({
34816
35102
  type: "pipe",
34817
35103
  in: in_,
34818
- out
35104
+ out: out2
34819
35105
  });
34820
35106
  }
34821
35107
  // @__NO_SIDE_EFFECTS__
@@ -37930,11 +38216,11 @@ var ZodPipe = /* @__PURE__ */ $constructor("ZodPipe", (inst, def) => {
37930
38216
  inst.in = def.in;
37931
38217
  inst.out = def.out;
37932
38218
  });
37933
- function pipe(in_, out) {
38219
+ function pipe(in_, out2) {
37934
38220
  return new ZodPipe({
37935
38221
  type: "pipe",
37936
38222
  in: in_,
37937
- out
38223
+ out: out2
37938
38224
  // ...util.normalizeParams(params),
37939
38225
  });
37940
38226
  }
@@ -37942,11 +38228,11 @@ var ZodCodec = /* @__PURE__ */ $constructor("ZodCodec", (inst, def) => {
37942
38228
  ZodPipe.init(inst, def);
37943
38229
  $ZodCodec.init(inst, def);
37944
38230
  });
37945
- function codec(in_, out, params) {
38231
+ function codec(in_, out2, params) {
37946
38232
  return new ZodCodec({
37947
38233
  type: "pipe",
37948
38234
  in: in_,
37949
- out,
38235
+ out: out2,
37950
38236
  transform: params.decode,
37951
38237
  reverseTransform: params.encode
37952
38238
  });
@@ -38784,12 +39070,12 @@ function convertSchema(schema, ctx) {
38784
39070
  let baseSchema = convertBaseSchema(schema, ctx);
38785
39071
  const hasExplicitType = schema.type || schema.enum !== void 0 || schema.const !== void 0;
38786
39072
  if (schema.anyOf && Array.isArray(schema.anyOf)) {
38787
- const options = schema.anyOf.map((s) => convertSchema(s, ctx));
39073
+ const options = schema.anyOf.map((s2) => convertSchema(s2, ctx));
38788
39074
  const anyOfUnion = z.union(options);
38789
39075
  baseSchema = hasExplicitType ? z.intersection(baseSchema, anyOfUnion) : anyOfUnion;
38790
39076
  }
38791
39077
  if (schema.oneOf && Array.isArray(schema.oneOf)) {
38792
- const options = schema.oneOf.map((s) => convertSchema(s, ctx));
39078
+ const options = schema.oneOf.map((s2) => convertSchema(s2, ctx));
38793
39079
  const oneOfUnion = z.xor(options);
38794
39080
  baseSchema = hasExplicitType ? z.intersection(baseSchema, oneOfUnion) : oneOfUnion;
38795
39081
  }
@@ -38889,24 +39175,24 @@ function visit(schema, fnOrHandlers) {
38889
39175
  return h ? h(node2, rewritten) : node2;
38890
39176
  };
38891
39177
  const cache = /* @__PURE__ */ new Map();
38892
- function run2(s) {
38893
- const cached2 = cache.get(s);
39178
+ function run4(s2) {
39179
+ const cached2 = cache.get(s2);
38894
39180
  if (cached2 === RESOLVING) {
38895
39181
  return new $ZodLazy({
38896
39182
  type: "lazy",
38897
- getter: () => cache.get(s)
39183
+ getter: () => cache.get(s2)
38898
39184
  });
38899
39185
  }
38900
39186
  if (cached2 !== void 0)
38901
39187
  return cached2;
38902
- cache.set(s, RESOLVING);
38903
- const inner = mapInner(s);
38904
- const mapped = fn(inner, inner !== s);
38905
- cache.set(s, mapped);
39188
+ cache.set(s2, RESOLVING);
39189
+ const inner = mapInner(s2);
39190
+ const mapped = fn(inner, inner !== s2);
39191
+ cache.set(s2, mapped);
38906
39192
  return mapped;
38907
39193
  }
38908
- function mapInner(s) {
38909
- const def = s._zod.def;
39194
+ function mapInner(s2) {
39195
+ const def = s2._zod.def;
38910
39196
  const kind = def.type;
38911
39197
  switch (kind) {
38912
39198
  case "object": {
@@ -38915,67 +39201,67 @@ function visit(schema, fnOrHandlers) {
38915
39201
  let changed = false;
38916
39202
  const newShape = {};
38917
39203
  for (const k of keys) {
38918
- const mapped = run2(oldShape[k]);
39204
+ const mapped = run4(oldShape[k]);
38919
39205
  if (mapped !== oldShape[k])
38920
39206
  changed = true;
38921
39207
  newShape[k] = mapped;
38922
39208
  }
38923
39209
  let newCatchall = def.catchall;
38924
39210
  if (def.catchall) {
38925
- newCatchall = run2(def.catchall);
39211
+ newCatchall = run4(def.catchall);
38926
39212
  if (newCatchall !== def.catchall)
38927
39213
  changed = true;
38928
39214
  }
38929
- return changed ? clone(s, { ...def, shape: newShape, catchall: newCatchall }) : s;
39215
+ return changed ? clone(s2, { ...def, shape: newShape, catchall: newCatchall }) : s2;
38930
39216
  }
38931
39217
  case "array": {
38932
- const mapped = run2(def.element);
38933
- return mapped === def.element ? s : clone(s, { ...def, element: mapped });
39218
+ const mapped = run4(def.element);
39219
+ return mapped === def.element ? s2 : clone(s2, { ...def, element: mapped });
38934
39220
  }
38935
39221
  case "tuple": {
38936
39222
  const oldItems = def.items;
38937
39223
  let changed = false;
38938
39224
  const newItems = [];
38939
39225
  for (const item of oldItems) {
38940
- const mapped = run2(item);
39226
+ const mapped = run4(item);
38941
39227
  if (mapped !== item)
38942
39228
  changed = true;
38943
39229
  newItems.push(mapped);
38944
39230
  }
38945
39231
  let newRest = def.rest;
38946
39232
  if (def.rest) {
38947
- newRest = run2(def.rest);
39233
+ newRest = run4(def.rest);
38948
39234
  if (newRest !== def.rest)
38949
39235
  changed = true;
38950
39236
  }
38951
- return changed ? clone(s, { ...def, items: newItems, rest: newRest }) : s;
39237
+ return changed ? clone(s2, { ...def, items: newItems, rest: newRest }) : s2;
38952
39238
  }
38953
39239
  case "record":
38954
39240
  case "map": {
38955
- const newKey = run2(def.keyType);
38956
- const newVal = run2(def.valueType);
38957
- return newKey === def.keyType && newVal === def.valueType ? s : clone(s, { ...def, keyType: newKey, valueType: newVal });
39241
+ const newKey = run4(def.keyType);
39242
+ const newVal = run4(def.valueType);
39243
+ return newKey === def.keyType && newVal === def.valueType ? s2 : clone(s2, { ...def, keyType: newKey, valueType: newVal });
38958
39244
  }
38959
39245
  case "set": {
38960
- const newVal = run2(def.valueType);
38961
- return newVal === def.valueType ? s : clone(s, { ...def, valueType: newVal });
39246
+ const newVal = run4(def.valueType);
39247
+ return newVal === def.valueType ? s2 : clone(s2, { ...def, valueType: newVal });
38962
39248
  }
38963
39249
  case "union": {
38964
39250
  const oldOptions = def.options;
38965
39251
  let changed = false;
38966
39252
  const newOptions = [];
38967
39253
  for (const opt of oldOptions) {
38968
- const mapped = run2(opt);
39254
+ const mapped = run4(opt);
38969
39255
  if (mapped !== opt)
38970
39256
  changed = true;
38971
39257
  newOptions.push(mapped);
38972
39258
  }
38973
- return changed ? clone(s, { ...def, options: newOptions }) : s;
39259
+ return changed ? clone(s2, { ...def, options: newOptions }) : s2;
38974
39260
  }
38975
39261
  case "intersection": {
38976
- const newLeft = run2(def.left);
38977
- const newRight = run2(def.right);
38978
- return newLeft === def.left && newRight === def.right ? s : clone(s, { ...def, left: newLeft, right: newRight });
39262
+ const newLeft = run4(def.left);
39263
+ const newRight = run4(def.right);
39264
+ return newLeft === def.left && newRight === def.right ? s2 : clone(s2, { ...def, left: newLeft, right: newRight });
38979
39265
  }
38980
39266
  case "optional":
38981
39267
  case "nullable":
@@ -38986,23 +39272,23 @@ function visit(schema, fnOrHandlers) {
38986
39272
  case "nonoptional":
38987
39273
  case "promise":
38988
39274
  case "success": {
38989
- const newInner = run2(def.innerType);
38990
- return newInner === def.innerType ? s : clone(s, { ...def, innerType: newInner });
39275
+ const newInner = run4(def.innerType);
39276
+ return newInner === def.innerType ? s2 : clone(s2, { ...def, innerType: newInner });
38991
39277
  }
38992
39278
  case "pipe": {
38993
- const newIn = run2(def.in);
38994
- const newOut = run2(def.out);
38995
- return newIn === def.in && newOut === def.out ? s : clone(s, { ...def, in: newIn, out: newOut });
39279
+ const newIn = run4(def.in);
39280
+ const newOut = run4(def.out);
39281
+ return newIn === def.in && newOut === def.out ? s2 : clone(s2, { ...def, in: newIn, out: newOut });
38996
39282
  }
38997
39283
  case "function": {
38998
- const newInput = run2(def.input);
38999
- const newOutput = run2(def.output);
39000
- return newInput === def.input && newOutput === def.output ? s : clone(s, { ...def, input: newInput, output: newOutput });
39284
+ const newInput = run4(def.input);
39285
+ const newOutput = run4(def.output);
39286
+ return newInput === def.input && newOutput === def.output ? s2 : clone(s2, { ...def, input: newInput, output: newOutput });
39001
39287
  }
39002
39288
  case "lazy": {
39003
39289
  const original = def.getter;
39004
39290
  const { _cachedInner, ...rest } = def;
39005
- return clone(s, { ...rest, getter: () => run2(original()) });
39291
+ return clone(s2, { ...rest, getter: () => run4(original()) });
39006
39292
  }
39007
39293
  // A leaf by choice: `parts` are regex fragments, not data positions.
39008
39294
  case "template_literal":
@@ -39026,24 +39312,24 @@ function visit(schema, fnOrHandlers) {
39026
39312
  case "file":
39027
39313
  case "transform":
39028
39314
  case "custom":
39029
- return s;
39315
+ return s2;
39030
39316
  default: {
39031
39317
  kind;
39032
- return s;
39318
+ return s2;
39033
39319
  }
39034
39320
  }
39035
39321
  }
39036
- return run2(schema);
39322
+ return run4(schema);
39037
39323
  }
39038
39324
 
39039
39325
  // ../../node_modules/zod/v4/classic/deep-partial.js
39040
39326
  function deepPartial(schema) {
39041
39327
  return visit(schema, {
39042
- object: (s) => s.partial(),
39328
+ object: (s2) => s2.partial(),
39043
39329
  // Every partialed option now admits `undefined`, which the constructor rejects as a duplicate.
39044
- union: (s) => {
39045
- const def = s._zod.def;
39046
- return def.discriminator === void 0 ? s : union(def.options);
39330
+ union: (s2) => {
39331
+ const def = s2._zod.def;
39332
+ return def.discriminator === void 0 ? s2 : union(def.options);
39047
39333
  }
39048
39334
  });
39049
39335
  }
@@ -39063,18 +39349,18 @@ function inSide(def) {
39063
39349
  }
39064
39350
  function input(schema) {
39065
39351
  return visit(schema, {
39066
- pipe: (s) => inSide(s._zod.def),
39352
+ pipe: (s2) => inSide(s2._zod.def),
39067
39353
  // 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: (s, rewritten) => rewritten ? optional(s._zod.def.innerType) : s,
39354
+ default: (s2, rewritten) => rewritten ? optional(s2._zod.def.innerType) : s2,
39069
39355
  // 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: (s, rewritten) => rewritten ? s._zod.def.innerType : s
39356
+ catch: (s2, rewritten) => rewritten ? s2._zod.def.innerType : s2
39071
39357
  });
39072
39358
  }
39073
39359
  function output(schema) {
39074
39360
  return visit(schema, {
39075
- pipe: (s) => outSide(s._zod.def),
39361
+ pipe: (s2) => outSide(s2._zod.def),
39076
39362
  // A prefault value is fed through the schema, which makes it input-side, so a rewritten inner type leaves it stranded.
39077
- prefault: (s, rewritten) => rewritten ? s._zod.def.innerType : s
39363
+ prefault: (s2, rewritten) => rewritten ? s2._zod.def.innerType : s2
39078
39364
  });
39079
39365
  }
39080
39366
 
@@ -39534,12 +39820,12 @@ var ParseStatus = class _ParseStatus {
39534
39820
  }
39535
39821
  static mergeArray(status, results) {
39536
39822
  const arrayValue = [];
39537
- for (const s of results) {
39538
- if (s.status === "aborted")
39823
+ for (const s2 of results) {
39824
+ if (s2.status === "aborted")
39539
39825
  return INVALID2;
39540
- if (s.status === "dirty")
39826
+ if (s2.status === "dirty")
39541
39827
  status.dirty();
39542
- arrayValue.push(s.value);
39828
+ arrayValue.push(s2.value);
39543
39829
  }
39544
39830
  return { status: status.value, value: arrayValue };
39545
39831
  }
@@ -39736,8 +40022,8 @@ var ZodType2 = class {
39736
40022
  } : {
39737
40023
  issues: ctx.common.issues
39738
40024
  };
39739
- } catch (err) {
39740
- if (err?.message?.toLowerCase()?.includes("encountered")) {
40025
+ } catch (err2) {
40026
+ if (err2?.message?.toLowerCase()?.includes("encountered")) {
39741
40027
  this["~standard"].async = true;
39742
40028
  }
39743
40029
  ctx.common = {
@@ -43260,34 +43546,34 @@ function validateDownloadUrl(url2) {
43260
43546
  message: `URL scheme must be http, https, or data, got ${parsed.protocol}`
43261
43547
  });
43262
43548
  }
43263
- const hostname5 = parsed.hostname.toLowerCase().replace(/\.+$/, "");
43264
- if (!hostname5) {
43549
+ const hostname6 = parsed.hostname.toLowerCase().replace(/\.+$/, "");
43550
+ if (!hostname6) {
43265
43551
  throw new DownloadError({
43266
43552
  url: url2,
43267
43553
  message: `URL must have a hostname`
43268
43554
  });
43269
43555
  }
43270
- if (hostname5 === "localhost" || hostname5.endsWith(".local") || hostname5.endsWith(".localhost") || hostname5.endsWith(".internal")) {
43556
+ if (hostname6 === "localhost" || hostname6.endsWith(".local") || hostname6.endsWith(".localhost") || hostname6.endsWith(".internal")) {
43271
43557
  throw new DownloadError({
43272
43558
  url: url2,
43273
- message: `URL with hostname ${hostname5} is not allowed`
43559
+ message: `URL with hostname ${hostname6} is not allowed`
43274
43560
  });
43275
43561
  }
43276
- if (hostname5.startsWith("[") && hostname5.endsWith("]")) {
43277
- const ipv63 = hostname5.slice(1, -1);
43562
+ if (hostname6.startsWith("[") && hostname6.endsWith("]")) {
43563
+ const ipv63 = hostname6.slice(1, -1);
43278
43564
  if (isPrivateIPv6(ipv63)) {
43279
43565
  throw new DownloadError({
43280
43566
  url: url2,
43281
- message: `URL with IPv6 address ${hostname5} is not allowed`
43567
+ message: `URL with IPv6 address ${hostname6} is not allowed`
43282
43568
  });
43283
43569
  }
43284
43570
  return;
43285
43571
  }
43286
- if (isIPv4(hostname5)) {
43287
- if (isPrivateIPv4(hostname5)) {
43572
+ if (isIPv4(hostname6)) {
43573
+ if (isPrivateIPv4(hostname6)) {
43288
43574
  throw new DownloadError({
43289
43575
  url: url2,
43290
- message: `URL with IP address ${hostname5} is not allowed`
43576
+ message: `URL with IP address ${hostname6} is not allowed`
43291
43577
  });
43292
43578
  }
43293
43579
  }
@@ -43295,18 +43581,18 @@ function validateDownloadUrl(url2) {
43295
43581
  function validateDownloadAddress({
43296
43582
  address,
43297
43583
  family,
43298
- hostname: hostname5
43584
+ hostname: hostname6
43299
43585
  }) {
43300
43586
  const isUnsafe = family === 4 ? !isIPv4(address) || isPrivateIPv4(address) : family === 6 ? isPrivateIPv6(address) : true;
43301
43587
  if (isUnsafe) {
43302
43588
  throw new DownloadError({
43303
- url: hostname5,
43304
- message: `Hostname ${hostname5} resolved to disallowed IP address ${address}`
43589
+ url: hostname6,
43590
+ message: `Hostname ${hostname6} resolved to disallowed IP address ${address}`
43305
43591
  });
43306
43592
  }
43307
43593
  }
43308
- function isIPv4(hostname5) {
43309
- const parts = hostname5.split(".");
43594
+ function isIPv4(hostname6) {
43595
+ const parts = hostname6.split(".");
43310
43596
  if (parts.length !== 4) return false;
43311
43597
  return parts.every((part) => {
43312
43598
  const num = Number(part);
@@ -43391,8 +43677,8 @@ function isPrivateIPv6(ip) {
43391
43677
  return false;
43392
43678
  }
43393
43679
  function createSafeLookup(lookup) {
43394
- return ((hostname5, options, callback) => {
43395
- lookup(hostname5, { ...options, all: true }, (error62, addresses) => {
43680
+ return ((hostname6, options, callback) => {
43681
+ lookup(hostname6, { ...options, all: true }, (error62, addresses) => {
43396
43682
  if (error62) {
43397
43683
  callback(error62);
43398
43684
  return;
@@ -43400,10 +43686,10 @@ function createSafeLookup(lookup) {
43400
43686
  try {
43401
43687
  const [firstAddress] = addresses;
43402
43688
  if (firstAddress == null) {
43403
- throw new Error(`Hostname ${hostname5} did not resolve to an address`);
43689
+ throw new Error(`Hostname ${hostname6} did not resolve to an address`);
43404
43690
  }
43405
43691
  for (const { address, family } of addresses) {
43406
- validateDownloadAddress({ address, family, hostname: hostname5 });
43692
+ validateDownloadAddress({ address, family, hostname: hostname6 });
43407
43693
  }
43408
43694
  if (options.all === true) {
43409
43695
  callback(null, addresses);
@@ -47105,9 +47391,9 @@ function createAsyncIterableStream(source) {
47105
47391
  * @param err The error to throw.
47106
47392
  * @returns A promise that rejects with the provided error.
47107
47393
  */
47108
- async throw(err) {
47394
+ async throw(err2) {
47109
47395
  await cleanup(true);
47110
- throw err;
47396
+ throw err2;
47111
47397
  }
47112
47398
  };
47113
47399
  };
@@ -47711,9 +47997,9 @@ function platformFetch(apiUrl, transport, engineFetch) {
47711
47997
  if (input2 instanceof Request)
47712
47998
  throw new Error("Local turn transport requires an explicit request path");
47713
47999
  const raw = String(input2);
47714
- const relative = raw.startsWith("/");
48000
+ const relative2 = raw.startsWith("/");
47715
48001
  const target = new URL(raw, platform2);
47716
- if (!relative && target.origin !== platform2.origin)
48002
+ if (!relative2 && target.origin !== platform2.origin)
47717
48003
  return engineFetch(input2, init);
47718
48004
  if (target.origin !== platform2.origin || !target.pathname.startsWith("/api/") || target.username || target.password || target.hash)
47719
48005
  throw new Error("Local turn requests must use a platform API path");
@@ -47890,18 +48176,18 @@ function argumentsAsText(value) {
47890
48176
  function readOllamaToolCalls(message) {
47891
48177
  const raw = message?.tool_calls;
47892
48178
  if (!Array.isArray(raw)) return [];
47893
- const out = [];
48179
+ const out2 = [];
47894
48180
  raw.forEach((entry, position) => {
47895
48181
  if (!entry || typeof entry !== "object") return;
47896
48182
  const fn = entry.function;
47897
48183
  if (typeof fn?.name !== "string") return;
47898
- out.push({
48184
+ out2.push({
47899
48185
  position,
47900
48186
  name: fn.name,
47901
48187
  argumentsFragment: argumentsAsText(fn.arguments)
47902
48188
  });
47903
48189
  });
47904
- return out;
48190
+ return out2;
47905
48191
  }
47906
48192
  function readOllamaLine(line) {
47907
48193
  let parsed;
@@ -47926,19 +48212,19 @@ function readOllamaLine(line) {
47926
48212
  function readOpenAiToolCalls(deltaObj) {
47927
48213
  const raw = deltaObj?.tool_calls;
47928
48214
  if (!Array.isArray(raw)) return [];
47929
- const out = [];
48215
+ const out2 = [];
47930
48216
  raw.forEach((entry, fallbackPosition) => {
47931
48217
  if (!entry || typeof entry !== "object") return;
47932
48218
  const row = entry;
47933
48219
  const fn = row.function;
47934
- out.push({
48220
+ out2.push({
47935
48221
  position: typeof row.index === "number" ? row.index : fallbackPosition,
47936
48222
  id: typeof row.id === "string" ? row.id : void 0,
47937
48223
  name: typeof fn?.name === "string" ? fn.name : void 0,
47938
48224
  argumentsFragment: typeof fn?.arguments === "string" ? fn.arguments : void 0
47939
48225
  });
47940
48226
  });
47941
- return out;
48227
+ return out2;
47942
48228
  }
47943
48229
  function readOpenAiLine(line) {
47944
48230
  if (!line.startsWith("data:")) return null;
@@ -48184,11 +48470,11 @@ function origin(apiUrl) {
48184
48470
  function appAwareFetch(apiUrl, token, base, getToken2) {
48185
48471
  return async (input2, init) => {
48186
48472
  const target = typeof input2 === "string" ? input2 : String(input2);
48187
- const relative = target.startsWith("/") && !target.startsWith("//");
48188
- if (!relative && !target.startsWith(`${origin(apiUrl)}/`))
48473
+ const relative2 = target.startsWith("/") && !target.startsWith("//");
48474
+ if (!relative2 && !target.startsWith(`${origin(apiUrl)}/`))
48189
48475
  return base(input2, init);
48190
48476
  const currentToken = getToken2 ? await renewToken(getToken2) : token;
48191
- return base(relative ? `${origin(apiUrl)}${target}` : target, {
48477
+ return base(relative2 ? `${origin(apiUrl)}${target}` : target, {
48192
48478
  ...init,
48193
48479
  headers: {
48194
48480
  ...init?.headers,
@@ -48316,10 +48602,10 @@ async function askForTheTurn(opts) {
48316
48602
  };
48317
48603
  response = received.response;
48318
48604
  responseText = received.text;
48319
- } catch (err) {
48605
+ } catch (err2) {
48320
48606
  throw new LocalTurnFailed(
48321
48607
  "handoff",
48322
- opts.signal?.aborted ? "Stopped this request." : err instanceof Error && err.name === "AbortError" ? "Great Arrow did not answer in time." : cloudSessionId ? "Great Arrow\u2019s reply was interrupted." : "Could not reach Great Arrow.",
48608
+ 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
48609
  false,
48324
48610
  cloudSessionId
48325
48611
  );
@@ -48509,17 +48795,17 @@ function firstString(...candidates) {
48509
48795
  }
48510
48796
  function collect(entries, read) {
48511
48797
  if (!Array.isArray(entries)) return [];
48512
- const out = [];
48798
+ const out2 = [];
48513
48799
  const seen = /* @__PURE__ */ new Set();
48514
48800
  for (const entry of entries) {
48515
- if (out.length >= MAX_LOCAL_MODELS) break;
48801
+ if (out2.length >= MAX_LOCAL_MODELS) break;
48516
48802
  if (!entry || typeof entry !== "object") continue;
48517
48803
  const { id, label, contextLength } = read(entry);
48518
48804
  if (!isValidLocalModelId(id)) continue;
48519
48805
  if (seen.has(id)) continue;
48520
48806
  if (isEmbeddingOnlyModelId(id)) continue;
48521
48807
  seen.add(id);
48522
- out.push({
48808
+ out2.push({
48523
48809
  id,
48524
48810
  label: typeof label === "string" && label.length > 0 ? label : id,
48525
48811
  // Never assumed. A model is only marked tool-capable once the provider
@@ -48529,7 +48815,7 @@ function collect(entries, read) {
48529
48815
  contextLength: positiveInt(contextLength)
48530
48816
  });
48531
48817
  }
48532
- return out;
48818
+ return out2;
48533
48819
  }
48534
48820
  function normalizeOllamaTags(json3) {
48535
48821
  if (!json3 || typeof json3 !== "object") return [];
@@ -48634,10 +48920,10 @@ async function findInstalledModels(opts) {
48634
48920
  let response;
48635
48921
  try {
48636
48922
  response = await ask(doFetch, url2, { method: "GET" }, timeoutMs);
48637
- } catch (err) {
48923
+ } catch (err2) {
48638
48924
  throw new LocalAppUnreachable(
48639
48925
  opts.baseUrl,
48640
- err instanceof Error && err.name === "AbortError" ? "It did not answer in time." : "Nothing answered there."
48926
+ err2 instanceof Error && err2.name === "AbortError" ? "It did not answer in time." : "Nothing answered there."
48641
48927
  );
48642
48928
  }
48643
48929
  if (!response.ok) {
@@ -48730,15 +49016,15 @@ function checkCommand() {
48730
49016
  let models;
48731
49017
  try {
48732
49018
  models = await findInstalledModels({ baseUrl, provider });
48733
- } catch (err) {
48734
- if (err instanceof LocalAppUnreachable) {
49019
+ } catch (err2) {
49020
+ if (err2 instanceof LocalAppUnreachable) {
48735
49021
  throw new CliError(
48736
- `Could not reach ${LOCAL_PROVIDER_PRESETS[provider].label} at ${err.baseUrl}. ${err.message}`,
49022
+ `Could not reach ${LOCAL_PROVIDER_PRESETS[provider].label} at ${err2.baseUrl}. ${err2.message}`,
48737
49023
  2 /* NETWORK_ERROR */,
48738
49024
  `Start it on this computer and try again, or point somewhere else with --url.`
48739
49025
  );
48740
49026
  }
48741
- throw err;
49027
+ throw err2;
48742
49028
  }
48743
49029
  const saved = await client2.mcpCall(
48744
49030
  "model_local_set",
@@ -48927,15 +49213,15 @@ function askHereCommand() {
48927
49213
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
48928
49214
  ...g.json ? {} : { onWords: (delta) => process.stdout.write(delta) }
48929
49215
  });
48930
- } catch (err) {
48931
- if (err instanceof LocalTurnFailed) {
49216
+ } catch (err2) {
49217
+ if (err2 instanceof LocalTurnFailed) {
48932
49218
  throw new CliError(
48933
- err.message,
49219
+ err2.message,
48934
49220
  2 /* NETWORK_ERROR */,
48935
- err.closed ? void 0 : "Your conversation may show this one as unfinished."
49221
+ err2.closed ? void 0 : "Your conversation may show this one as unfinished."
48936
49222
  );
48937
49223
  }
48938
- throw err;
49224
+ throw err2;
48939
49225
  } finally {
48940
49226
  process.off("SIGINT", stop2);
48941
49227
  }
@@ -49220,8 +49506,8 @@ function statusCommand3() {
49220
49506
  let result;
49221
49507
  try {
49222
49508
  result = await client2.mcpCall("glance", {});
49223
- } catch (err) {
49224
- if (err instanceof CliError) throw err;
49509
+ } catch (err2) {
49510
+ if (err2 instanceof CliError) throw err2;
49225
49511
  fmt.error(
49226
49512
  "Couldn't reach Great Arrow. Check your connection, or run 'gad doctor'."
49227
49513
  );
@@ -49255,7 +49541,7 @@ function renderStatus2(payload, plain, apiUrl) {
49255
49541
  lines.push(c.badge(` ${payload.workspace} `));
49256
49542
  lines.push("");
49257
49543
  }
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;
49544
+ 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
49545
  if (!hasAny) {
49260
49546
  lines.push(
49261
49547
  `${c.green("\u2713")} You're all clear \u2014 nothing needs you right now.`
@@ -49329,6 +49615,17 @@ function renderStatus2(payload, plain, apiUrl) {
49329
49615
  if (url2) lines.push(` ${c.dim("\u2192")} ${link("Open rotation", url2)}`);
49330
49616
  lines.push("");
49331
49617
  }
49618
+ if (payload.keyRotation) {
49619
+ const k = payload.keyRotation;
49620
+ lines.push(c.bold("Key rotation"));
49621
+ lines.push(
49622
+ ` ${k.needsYou} need you \xB7 ${k.pendingDevices} machine updates pending`
49623
+ );
49624
+ const url2 = glanceItemUrl("/settings/key-rotation", apiUrl);
49625
+ if (url2)
49626
+ lines.push(` ${c.dim("\u2192")} ${link("Open key rotation", url2)}`);
49627
+ lines.push("");
49628
+ }
49332
49629
  if (payload.landing) {
49333
49630
  lines.push(c.bold("Merge queue"));
49334
49631
  for (const r of payload.landing.repos) {
@@ -49385,8 +49682,8 @@ function browserLaunchCommand(url2, platform2 = process.platform) {
49385
49682
  function openBrowser2(url2) {
49386
49683
  const command = browserLaunchCommand(url2);
49387
49684
  if (!command) return Promise.resolve(false);
49388
- return new Promise((resolve4) => {
49389
- execFile3(command.file, command.args, (error62) => resolve4(!error62));
49685
+ return new Promise((resolve5) => {
49686
+ execFile3(command.file, command.args, (error62) => resolve5(!error62));
49390
49687
  });
49391
49688
  }
49392
49689
  function toSurfaceRow(value) {
@@ -49644,6 +49941,1166 @@ function callCommand() {
49644
49941
  });
49645
49942
  }
49646
49943
 
49944
+ // src/commands/keys.ts
49945
+ import { createInterface as createInterface3 } from "node:readline";
49946
+ import { Writable } from "node:stream";
49947
+
49948
+ // src/lib/keys-apply.ts
49949
+ import { spawn } from "node:child_process";
49950
+ import {
49951
+ chmod as chmod2,
49952
+ mkdir as mkdir8,
49953
+ readFile as readFile7,
49954
+ realpath,
49955
+ rename as rename2,
49956
+ stat as stat2,
49957
+ writeFile as writeFile6
49958
+ } from "node:fs/promises";
49959
+ import { homedir as homedir10 } from "node:os";
49960
+ import { basename as basename2, dirname as dirname8, isAbsolute as isAbsolute3, join as join12, relative, sep } from "node:path";
49961
+ var GH_APPLY_TIMEOUT_MS = 3e4;
49962
+ var GIT_APPLY_TIMEOUT_MS = 3e4;
49963
+ function runWithStdin(file2, args, input2, timeoutMs) {
49964
+ return new Promise((resolve5) => {
49965
+ let settled = false;
49966
+ const done = (o) => {
49967
+ if (settled) return;
49968
+ settled = true;
49969
+ clearTimeout(timer);
49970
+ resolve5(o);
49971
+ };
49972
+ let child;
49973
+ try {
49974
+ child = spawn(file2, args, { stdio: ["pipe", "ignore", "ignore"] });
49975
+ } catch {
49976
+ resolve5("not_found");
49977
+ return;
49978
+ }
49979
+ const timer = setTimeout(() => {
49980
+ child.kill("SIGKILL");
49981
+ done("timeout");
49982
+ }, timeoutMs);
49983
+ child.on(
49984
+ "error",
49985
+ (err2) => done(
49986
+ err2.code === "ENOENT" ? "not_found" : "failed"
49987
+ )
49988
+ );
49989
+ child.on("close", (code) => done(code === 0 ? "ok" : "failed"));
49990
+ child.stdin?.on("error", () => done("failed"));
49991
+ child.stdin?.end(input2);
49992
+ });
49993
+ }
49994
+ async function applyGhCli(value) {
49995
+ const outcome = await runWithStdin(
49996
+ "gh",
49997
+ ["auth", "login", "--hostname", "github.com", "--with-token"],
49998
+ value,
49999
+ GH_APPLY_TIMEOUT_MS
50000
+ );
50001
+ if (outcome === "ok") return { ok: true, code: "applied" };
50002
+ return { ok: false, code: `gh_${outcome}` };
50003
+ }
50004
+ async function applyGitCredential(value, helper) {
50005
+ if (helper === "gh") return { ok: true, code: "via_gh" };
50006
+ const rejected = await runWithStdin(
50007
+ "git",
50008
+ ["credential", "reject"],
50009
+ "protocol=https\nhost=github.com\n\n",
50010
+ GIT_APPLY_TIMEOUT_MS
50011
+ );
50012
+ if (rejected === "not_found" || rejected === "timeout") {
50013
+ return { ok: false, code: `git_${rejected}` };
50014
+ }
50015
+ const approved = await runWithStdin(
50016
+ "git",
50017
+ ["credential", "approve"],
50018
+ `protocol=https
50019
+ host=github.com
50020
+ username=x-access-token
50021
+ password=${value}
50022
+
50023
+ `,
50024
+ GIT_APPLY_TIMEOUT_MS
50025
+ );
50026
+ if (approved === "ok") return { ok: true, code: "applied" };
50027
+ return { ok: false, code: `git_${approved}` };
50028
+ }
50029
+ function expandHome(path10) {
50030
+ if (path10 === "~") return homedir10();
50031
+ if (path10.startsWith("~/")) return join12(homedir10(), path10.slice(2));
50032
+ return path10;
50033
+ }
50034
+ function escapeRegExp(s2) {
50035
+ return s2.replace(/[.*+?^${}()|[\]\\-]/g, "\\$&");
50036
+ }
50037
+ function unquote(raw) {
50038
+ const t = raw.trim();
50039
+ if (t.length >= 2) {
50040
+ const q = t[0];
50041
+ if ((q === '"' || q === "'") && t.endsWith(q)) {
50042
+ return { inner: t.slice(1, -1), quote: q };
50043
+ }
50044
+ }
50045
+ return { inner: t, quote: "" };
50046
+ }
50047
+ function formatEnvValue(value, quote) {
50048
+ const needsDouble = /[\n\r]/.test(value);
50049
+ if (quote === "'" && !needsDouble && !value.includes("'")) {
50050
+ return `'${value}'`;
50051
+ }
50052
+ if (quote !== "" || needsDouble || /[\s#"'`$\\]/.test(value)) {
50053
+ const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\r/g, "\\r").replace(/\n/g, "\\n");
50054
+ return `"${escaped}"`;
50055
+ }
50056
+ return value;
50057
+ }
50058
+ async function writeAtomic(path10, content, mode) {
50059
+ const tmp = `${path10}.tmp`;
50060
+ await writeFile6(tmp, content, { mode });
50061
+ await chmod2(tmp, mode);
50062
+ await rename2(tmp, path10);
50063
+ }
50064
+ async function applyEnvFile(path10, key, value) {
50065
+ const file2 = expandHome(path10);
50066
+ let original;
50067
+ let mode = 384;
50068
+ try {
50069
+ original = await readFile7(file2, "utf8");
50070
+ mode = (await stat2(file2)).mode & 511;
50071
+ } catch (err2) {
50072
+ if (err2?.code !== "ENOENT") {
50073
+ return { ok: false, code: "env_read_failed" };
50074
+ }
50075
+ original = null;
50076
+ }
50077
+ const lineRe = new RegExp(
50078
+ `^(\\s*(?:export\\s+)?${escapeRegExp(key)}\\s*=\\s*)(.*?)(\\r?)$`
50079
+ );
50080
+ const lines = original === null ? [] : original.split("\n");
50081
+ let found = false;
50082
+ for (const [i, line] of lines.entries()) {
50083
+ const m = lineRe.exec(line);
50084
+ if (!m) continue;
50085
+ const head = m[1] ?? "";
50086
+ const raw = m[2] ?? "";
50087
+ const cr = m[3] ?? "";
50088
+ const { inner, quote } = unquote(raw);
50089
+ if (inner.startsWith("op://")) {
50090
+ return { ok: true, code: "reference_reread" };
50091
+ }
50092
+ lines[i] = `${head}${formatEnvValue(value, quote)}${cr}`;
50093
+ found = true;
50094
+ }
50095
+ if (!found) {
50096
+ const entry = `${key}=${formatEnvValue(value, "")}`;
50097
+ if (lines.length === 0) {
50098
+ lines.push(entry, "");
50099
+ } else if (lines[lines.length - 1] === "") {
50100
+ lines.splice(lines.length - 1, 0, entry);
50101
+ } else {
50102
+ lines.push(entry);
50103
+ }
50104
+ }
50105
+ try {
50106
+ await writeAtomic(file2, lines.join("\n"), mode);
50107
+ } catch {
50108
+ return { ok: false, code: "env_write_failed" };
50109
+ }
50110
+ return { ok: true, code: "applied" };
50111
+ }
50112
+ async function applySshKey(path10, privatePem) {
50113
+ const file2 = expandHome(path10);
50114
+ const content = privatePem.endsWith("\n") ? privatePem : `${privatePem}
50115
+ `;
50116
+ try {
50117
+ await mkdir8(dirname8(file2), { recursive: true, mode: 448 });
50118
+ await writeAtomic(file2, content, 384);
50119
+ } catch {
50120
+ return { ok: false, code: "ssh_write_failed" };
50121
+ }
50122
+ return { ok: true, code: "applied" };
50123
+ }
50124
+ function envTargetRefusal(path10, key, reported) {
50125
+ if (!isAbsolute3(path10)) return { ok: false, code: "target_invalid" };
50126
+ const known = reported.some((r) => r.path === path10 && r.key === key);
50127
+ return known ? null : { ok: false, code: "target_not_reported" };
50128
+ }
50129
+ var SSH_NOT_A_KEY = /* @__PURE__ */ new Set([
50130
+ "authorized_keys",
50131
+ "authorized_keys2",
50132
+ "config",
50133
+ "known_hosts"
50134
+ ]);
50135
+ async function sshTargetRefusal(path10, sshDir = join12(homedir10(), ".ssh")) {
50136
+ const file2 = expandHome(path10);
50137
+ if (!isAbsolute3(file2)) return { ok: false, code: "target_invalid" };
50138
+ if (SSH_NOT_A_KEY.has(basename2(file2))) {
50139
+ return { ok: false, code: "target_not_a_key" };
50140
+ }
50141
+ let root;
50142
+ let parent;
50143
+ try {
50144
+ root = await realpath(sshDir);
50145
+ parent = await realpath(dirname8(file2));
50146
+ } catch {
50147
+ return { ok: false, code: "target_outside_ssh_dir" };
50148
+ }
50149
+ const rel = relative(root, parent);
50150
+ if (rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute3(rel)) {
50151
+ return { ok: false, code: "target_outside_ssh_dir" };
50152
+ }
50153
+ return null;
50154
+ }
50155
+ async function applyUpdate(targetKind, targetRef, value, scope) {
50156
+ try {
50157
+ switch (targetKind) {
50158
+ case "machine_gh_cli":
50159
+ return await applyGhCli(value);
50160
+ case "machine_git_credential":
50161
+ return await applyGitCredential(value, targetRef.helper ?? "other");
50162
+ case "machine_env_file": {
50163
+ if (!targetRef.path || !targetRef.key) {
50164
+ return { ok: false, code: "target_invalid" };
50165
+ }
50166
+ const refused = envTargetRefusal(
50167
+ targetRef.path,
50168
+ targetRef.key,
50169
+ scope.reported
50170
+ );
50171
+ if (refused) return refused;
50172
+ return await applyEnvFile(targetRef.path, targetRef.key, value);
50173
+ }
50174
+ case "machine_ssh_key": {
50175
+ if (!targetRef.path) return { ok: false, code: "target_invalid" };
50176
+ const refused = await sshTargetRefusal(targetRef.path, scope.sshDir);
50177
+ if (refused) return refused;
50178
+ return await applySshKey(targetRef.path, value);
50179
+ }
50180
+ default:
50181
+ return { ok: false, code: "unsupported_target" };
50182
+ }
50183
+ } catch {
50184
+ return { ok: false, code: "apply_error" };
50185
+ }
50186
+ }
50187
+
50188
+ // src/lib/keys-device.ts
50189
+ import { execFile as execFile4 } from "node:child_process";
50190
+ import { readFile as readFile8 } from "node:fs/promises";
50191
+ import { hostname as hostname5 } from "node:os";
50192
+ import { resolve as resolve4 } from "node:path";
50193
+
50194
+ // src/lib/keys-envelope.ts
50195
+ import {
50196
+ createDecipheriv,
50197
+ createPrivateKey,
50198
+ createPublicKey,
50199
+ diffieHellman,
50200
+ generateKeyPairSync,
50201
+ hkdfSync
50202
+ } from "node:crypto";
50203
+ var DEVICE_ENVELOPE_INFO = "gad:key-rotation-device:v1";
50204
+ var MAGIC = Buffer.from("kd1", "ascii");
50205
+ var KEY_LEN = 32;
50206
+ var IV_LEN = 12;
50207
+ var TAG_LEN = 16;
50208
+ var HEADER_LEN = MAGIC.length + KEY_LEN + IV_LEN + TAG_LEN;
50209
+ var SPKI_PREFIX = Buffer.from("302a300506032b656e032100", "hex");
50210
+ var PKCS8_PREFIX = Buffer.from("302e020100300506032b656e04220420", "hex");
50211
+ var EnvelopeError = class extends Error {
50212
+ constructor(code) {
50213
+ super(code);
50214
+ this.code = code;
50215
+ this.name = "EnvelopeError";
50216
+ }
50217
+ code;
50218
+ };
50219
+ function rawKey(b64) {
50220
+ const raw = Buffer.from(b64, "base64");
50221
+ if (raw.length !== KEY_LEN || raw.toString("base64") !== b64) {
50222
+ throw new EnvelopeError("device_key_invalid");
50223
+ }
50224
+ return raw;
50225
+ }
50226
+ function rawPublic(key) {
50227
+ const der = key.export({ format: "der", type: "spki" });
50228
+ return Buffer.from(der.subarray(der.length - KEY_LEN));
50229
+ }
50230
+ function rawPrivate(key) {
50231
+ const der = key.export({ format: "der", type: "pkcs8" });
50232
+ return Buffer.from(der.subarray(der.length - KEY_LEN));
50233
+ }
50234
+ function generateDeviceKeyPair() {
50235
+ const pair = generateKeyPairSync("x25519");
50236
+ return {
50237
+ publicKey: rawPublic(pair.publicKey).toString("base64"),
50238
+ privateKey: rawPrivate(pair.privateKey).toString("base64")
50239
+ };
50240
+ }
50241
+ function openFromServer(sealed, devicePrivateKeyB64) {
50242
+ if (sealed.length < HEADER_LEN || !sealed.subarray(0, MAGIC.length).equals(MAGIC)) {
50243
+ throw new EnvelopeError("envelope_invalid");
50244
+ }
50245
+ const priv = createPrivateKey({
50246
+ key: Buffer.concat([PKCS8_PREFIX, rawKey(devicePrivateKeyB64)]),
50247
+ format: "der",
50248
+ type: "pkcs8"
50249
+ });
50250
+ const devicePub = rawPublic(createPublicKey(priv));
50251
+ let o = MAGIC.length;
50252
+ const ephPub = Buffer.from(sealed.subarray(o, o += KEY_LEN));
50253
+ const iv = sealed.subarray(o, o += IV_LEN);
50254
+ const tag = sealed.subarray(o, o += TAG_LEN);
50255
+ const ct = sealed.subarray(o);
50256
+ let shared;
50257
+ try {
50258
+ shared = diffieHellman({
50259
+ privateKey: priv,
50260
+ publicKey: createPublicKey({
50261
+ key: Buffer.concat([SPKI_PREFIX, ephPub]),
50262
+ format: "der",
50263
+ type: "spki"
50264
+ })
50265
+ });
50266
+ } catch {
50267
+ throw new EnvelopeError("envelope_invalid");
50268
+ }
50269
+ if (shared.every((b) => b === 0)) {
50270
+ throw new EnvelopeError("envelope_invalid");
50271
+ }
50272
+ const key = Buffer.from(
50273
+ hkdfSync(
50274
+ "sha256",
50275
+ shared,
50276
+ Buffer.concat([ephPub, devicePub]),
50277
+ Buffer.from(DEVICE_ENVELOPE_INFO, "utf8"),
50278
+ KEY_LEN
50279
+ )
50280
+ );
50281
+ try {
50282
+ const decipher = createDecipheriv("aes-256-gcm", key, iv);
50283
+ decipher.setAuthTag(tag);
50284
+ return Buffer.concat([decipher.update(ct), decipher.final()]).toString(
50285
+ "utf8"
50286
+ );
50287
+ } catch {
50288
+ throw new EnvelopeError("envelope_invalid");
50289
+ }
50290
+ }
50291
+
50292
+ // src/lib/keys-handoff.ts
50293
+ import { spawn as spawn2 } from "node:child_process";
50294
+
50295
+ // src/lib/keys-paths.ts
50296
+ function keyRotationPath() {
50297
+ return "/settings/key-rotation";
50298
+ }
50299
+ function keyRotationRunPath(runId) {
50300
+ return `/settings/key-rotation/runs/${encodeURIComponent(runId)}`;
50301
+ }
50302
+ function keyRotationHandoffPath(jti) {
50303
+ return `/settings/key-rotation/handoff/${encodeURIComponent(jti)}`;
50304
+ }
50305
+
50306
+ // src/lib/keys-handoff.ts
50307
+ var HANDOFF_POLL_INTERVAL_MS = 2e3;
50308
+ var HANDOFF_DEADLINE_MS = 5 * 6e4;
50309
+ var BROWSER_LAUNCH_TIMEOUT_MS = 5e3;
50310
+ function openInBrowser(url2) {
50311
+ const command = browserLaunchCommand(url2);
50312
+ if (!command) return Promise.resolve(false);
50313
+ return new Promise((resolve5) => {
50314
+ let settled = false;
50315
+ const done = (ok) => {
50316
+ if (settled) return;
50317
+ settled = true;
50318
+ clearTimeout(timer);
50319
+ resolve5(ok);
50320
+ };
50321
+ const timer = setTimeout(() => done(false), BROWSER_LAUNCH_TIMEOUT_MS);
50322
+ timer.unref?.();
50323
+ try {
50324
+ const child = spawn2(command.file, command.args, {
50325
+ detached: true,
50326
+ stdio: "ignore"
50327
+ });
50328
+ child.once("error", () => done(false));
50329
+ child.once("spawn", () => {
50330
+ child.unref();
50331
+ done(true);
50332
+ });
50333
+ } catch {
50334
+ done(false);
50335
+ }
50336
+ });
50337
+ }
50338
+ var defaultSleep = (ms) => new Promise((resolve5) => setTimeout(resolve5, ms));
50339
+ function stepUpError(message, hint) {
50340
+ return new CliError(message, 1 /* AUTH_ERROR */, hint);
50341
+ }
50342
+ async function requestBrowserStepUp(client2, kind, subjectId, opts = {}) {
50343
+ const openUrl = opts.openUrl ?? openInBrowser;
50344
+ const notify = opts.notify ?? ((line) => process.stderr.write(`${line}
50345
+ `));
50346
+ const sleep2 = opts.sleep ?? defaultSleep;
50347
+ const now = opts.now ?? Date.now;
50348
+ const interval = opts.pollIntervalMs ?? HANDOFF_POLL_INTERVAL_MS;
50349
+ const deadline = now() + (opts.deadlineMs ?? HANDOFF_DEADLINE_MS);
50350
+ const created = await client2.post("/api/key-rotation/handoffs", {
50351
+ kind,
50352
+ subjectId
50353
+ });
50354
+ const jti = typeof created?.jti === "string" ? created.jti : null;
50355
+ if (!jti || !/^[A-Za-z0-9-]{1,64}$/.test(jti)) {
50356
+ throw stepUpError("The server did not return a browser approval.");
50357
+ }
50358
+ const url2 = `${client2.apiOrigin}${keyRotationHandoffPath(jti)}`;
50359
+ notify(`Approve this in your browser (passkey or two-step code): ${url2}`);
50360
+ if (!await openUrl(url2)) {
50361
+ notify("Couldn't launch a browser. Open the URL above to approve.");
50362
+ }
50363
+ while (now() < deadline) {
50364
+ const polled = await client2.get(
50365
+ `/api/key-rotation/handoffs/${encodeURIComponent(jti)}`
50366
+ );
50367
+ const status = polled?.status;
50368
+ if (status === "approved") {
50369
+ if (typeof polled.token === "string" && polled.token.length > 0) {
50370
+ return polled.token;
50371
+ }
50372
+ throw stepUpError(
50373
+ "This approval was already collected by another request.",
50374
+ "Run the command again to request a new approval."
50375
+ );
50376
+ }
50377
+ if (status === "consumed") {
50378
+ throw stepUpError(
50379
+ "This approval was already used.",
50380
+ "Run the command again to request a new approval."
50381
+ );
50382
+ }
50383
+ if (status === "expired") {
50384
+ throw stepUpError(
50385
+ "The browser approval expired.",
50386
+ "Run the command again and approve within 5 minutes."
50387
+ );
50388
+ }
50389
+ await sleep2(interval);
50390
+ }
50391
+ throw stepUpError(
50392
+ "Timed out waiting for the browser approval.",
50393
+ "Run the command again and approve within 5 minutes."
50394
+ );
50395
+ }
50396
+
50397
+ // src/lib/keys-device.ts
50398
+ var DEFAULT_ENV_FILE = ".env.local";
50399
+ var DETECT_TIMEOUT_MS = 5e3;
50400
+ var MAX_ENV_KEYS = 500;
50401
+ var REPORT_KEY = /^[A-Z_][A-Z0-9_]{0,127}$/;
50402
+ var REPORT_PATH = /^[ -~]{1,200}$/;
50403
+ var TOKEN_SHAPED = /[A-Za-z0-9]{33,}/;
50404
+ var SECRET_PREFIX = /(gh[pousr]_|github_pat_|-----BEGIN)/;
50405
+ var UUID5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
50406
+ function deviceSlot(workspaceId) {
50407
+ return `key-rotation-device:${workspaceId}`;
50408
+ }
50409
+ function parseReported(v) {
50410
+ if (!Array.isArray(v)) return [];
50411
+ return v.flatMap((r) => {
50412
+ const o = r;
50413
+ return typeof o?.path === "string" && typeof o.key === "string" ? [{ path: o.path, key: o.key }] : [];
50414
+ });
50415
+ }
50416
+ function parsePending(v) {
50417
+ const o = v;
50418
+ if (typeof o?.publicKey !== "string" || typeof o.privateKey !== "string") {
50419
+ return null;
50420
+ }
50421
+ return {
50422
+ enrollmentId: typeof o.enrollmentId === "string" ? o.enrollmentId : null,
50423
+ publicKey: o.publicKey,
50424
+ privateKey: o.privateKey,
50425
+ reported: parseReported(o.reported)
50426
+ };
50427
+ }
50428
+ async function loadDevice(workspaceId) {
50429
+ const raw = await getSecretSlot(deviceSlot(workspaceId));
50430
+ if (!raw) return null;
50431
+ try {
50432
+ const parsed = JSON.parse(raw);
50433
+ if (parsed?.v !== 1 || typeof parsed.privateKey !== "string" || typeof parsed.publicKey !== "string") {
50434
+ return null;
50435
+ }
50436
+ return {
50437
+ v: 1,
50438
+ deviceId: typeof parsed.deviceId === "string" ? parsed.deviceId : null,
50439
+ enrollmentId: typeof parsed.enrollmentId === "string" ? parsed.enrollmentId : null,
50440
+ publicKey: parsed.publicKey,
50441
+ privateKey: parsed.privateKey,
50442
+ reported: parseReported(parsed.reported),
50443
+ pendingReplacement: parsePending(parsed.pendingReplacement)
50444
+ };
50445
+ } catch {
50446
+ return null;
50447
+ }
50448
+ }
50449
+ async function saveDevice(workspaceId, device) {
50450
+ if (!await setSecretSlot(deviceSlot(workspaceId), JSON.stringify(device))) {
50451
+ throw new CliError(
50452
+ "Could not store this machine's device key in the keychain.",
50453
+ 3 /* VALIDATION_ERROR */,
50454
+ "Unlock your keychain (or check ~/.great-arrow permissions) and try again."
50455
+ );
50456
+ }
50457
+ }
50458
+ async function requireEnrolledDevice(workspaceId) {
50459
+ const device = await loadDevice(workspaceId);
50460
+ if (!device?.deviceId) {
50461
+ throw new CliError(
50462
+ "This machine is not enrolled for key rotation in this workspace.",
50463
+ 3 /* VALIDATION_ERROR */,
50464
+ "Run 'gad keys enroll' first."
50465
+ );
50466
+ }
50467
+ return { ...device, deviceId: device.deviceId };
50468
+ }
50469
+ function nameOk(s2) {
50470
+ return !TOKEN_SHAPED.test(s2) && !SECRET_PREFIX.test(s2);
50471
+ }
50472
+ function isOpReference(rawValue) {
50473
+ const t = rawValue.trim();
50474
+ const q = t[0];
50475
+ const inner = t.length >= 2 && (q === '"' || q === "'") && t.endsWith(q) ? t.slice(1, -1) : t;
50476
+ return inner.startsWith("op://");
50477
+ }
50478
+ async function scanEnvKeys(paths) {
50479
+ const out2 = [];
50480
+ const seen = /* @__PURE__ */ new Set();
50481
+ for (const p of paths) {
50482
+ const path10 = resolve4(p);
50483
+ if (seen.has(path10)) continue;
50484
+ seen.add(path10);
50485
+ if (!REPORT_PATH.test(path10) || !nameOk(path10)) continue;
50486
+ let text3;
50487
+ try {
50488
+ text3 = await readFile8(path10, "utf8");
50489
+ } catch {
50490
+ continue;
50491
+ }
50492
+ for (const line of text3.split(/\r?\n/)) {
50493
+ const m = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_.-]*)\s*=(.*)$/.exec(
50494
+ line
50495
+ );
50496
+ const key = m?.[1];
50497
+ if (!key || !REPORT_KEY.test(key)) continue;
50498
+ out2.push({ path: path10, key, isReference: isOpReference(m?.[2] ?? "") });
50499
+ if (out2.length >= MAX_ENV_KEYS) return out2;
50500
+ }
50501
+ }
50502
+ return out2;
50503
+ }
50504
+ function helperKind(raw) {
50505
+ const v = raw.trim();
50506
+ if (!v) return null;
50507
+ if (/\bgh(\.exe)?\s+auth\s+git-credential\b/.test(v)) return "gh";
50508
+ if (/osxkeychain/.test(v)) return "osxkeychain";
50509
+ if (/^store\b/.test(v)) return "store";
50510
+ return "other";
50511
+ }
50512
+ function run3(file2, args) {
50513
+ return new Promise((done) => {
50514
+ execFile4(
50515
+ file2,
50516
+ args,
50517
+ { timeout: DETECT_TIMEOUT_MS, encoding: "utf8" },
50518
+ (error62, stdout) => done(error62 ? null : String(stdout))
50519
+ );
50520
+ });
50521
+ }
50522
+ async function detectGhCli() {
50523
+ return await run3("gh", ["--version"]) !== null;
50524
+ }
50525
+ async function detectGitHelper() {
50526
+ const out2 = await run3("git", [
50527
+ "config",
50528
+ "--get-urlmatch",
50529
+ "credential.helper",
50530
+ "https://github.com"
50531
+ ]);
50532
+ return out2 === null ? null : helperKind(out2);
50533
+ }
50534
+ async function buildDeviceReport(envFiles) {
50535
+ const [envKeys, ghCli, gitHelper] = await Promise.all([
50536
+ scanEnvKeys([...envFiles, DEFAULT_ENV_FILE]),
50537
+ detectGhCli(),
50538
+ detectGitHelper()
50539
+ ]);
50540
+ return { envKeys, ghCli, gitHelper };
50541
+ }
50542
+ function defaultDeviceLabel() {
50543
+ const label = hostname5().replace(/[^ -~]/g, "-").slice(0, 80).trim();
50544
+ return label && nameOk(label) ? label : "this machine";
50545
+ }
50546
+ async function enroll(client2, workspaceId, opts = {}) {
50547
+ const existing = await loadDevice(workspaceId);
50548
+ const replacing = existing?.deviceId ? existing : null;
50549
+ if (replacing && !opts.replace) {
50550
+ throw new CliError(
50551
+ "This machine is already enrolled for key rotation in this workspace.",
50552
+ 3 /* VALIDATION_ERROR */,
50553
+ "Run 'gad keys pending' to see its updates, or 'gad keys enroll --replace' to enroll it again with a new key."
50554
+ );
50555
+ }
50556
+ const label = opts.label ?? defaultDeviceLabel();
50557
+ const report = await (opts.report ?? buildDeviceReport)(opts.envFiles ?? []);
50558
+ const pair = generateDeviceKeyPair();
50559
+ const pending = {
50560
+ enrollmentId: null,
50561
+ publicKey: pair.publicKey,
50562
+ privateKey: pair.privateKey,
50563
+ reported: report.envKeys.map(({ path: path10, key }) => ({ path: path10, key }))
50564
+ };
50565
+ const savePending = () => saveDevice(
50566
+ workspaceId,
50567
+ replacing ? { ...replacing, pendingReplacement: { ...pending } } : {
50568
+ v: 1,
50569
+ deviceId: null,
50570
+ enrollmentId: pending.enrollmentId,
50571
+ publicKey: pending.publicKey,
50572
+ privateKey: pending.privateKey,
50573
+ reported: pending.reported,
50574
+ pendingReplacement: null
50575
+ }
50576
+ );
50577
+ await savePending();
50578
+ const begun = await client2.post("/api/key-rotation/devices", {
50579
+ label,
50580
+ publicKey: pair.publicKey,
50581
+ report
50582
+ });
50583
+ const enrollmentId = typeof begun?.enrollmentId === "string" && UUID5.test(begun.enrollmentId) ? begun.enrollmentId : null;
50584
+ if (!enrollmentId) {
50585
+ throw new CliError(
50586
+ "The server did not start the enrollment.",
50587
+ 2 /* NETWORK_ERROR */
50588
+ );
50589
+ }
50590
+ pending.enrollmentId = enrollmentId;
50591
+ await savePending();
50592
+ const approvalToken = await (opts.stepUp ?? requestBrowserStepUp)(
50593
+ client2,
50594
+ "device_enroll",
50595
+ enrollmentId
50596
+ );
50597
+ const done = await client2.post(`/api/key-rotation/devices/${enrollmentId}`, {
50598
+ action: "enroll",
50599
+ approvalToken
50600
+ });
50601
+ const deviceId = typeof done?.deviceId === "string" && UUID5.test(done.deviceId) ? done.deviceId : null;
50602
+ if (!deviceId) {
50603
+ throw new CliError(
50604
+ "The server did not complete the enrollment.",
50605
+ 2 /* NETWORK_ERROR */
50606
+ );
50607
+ }
50608
+ await saveDevice(workspaceId, {
50609
+ v: 1,
50610
+ deviceId,
50611
+ enrollmentId,
50612
+ publicKey: pending.publicKey,
50613
+ privateKey: pending.privateKey,
50614
+ reported: pending.reported,
50615
+ pendingReplacement: null
50616
+ });
50617
+ let replaced = null;
50618
+ if (replacing?.deviceId && replacing.deviceId !== deviceId) {
50619
+ try {
50620
+ await client2.delete(`/api/key-rotation/devices/${replacing.deviceId}`);
50621
+ replaced = { deviceId: replacing.deviceId, revoked: true };
50622
+ } catch {
50623
+ replaced = { deviceId: replacing.deviceId, revoked: false };
50624
+ }
50625
+ }
50626
+ return { deviceId, report, replaced };
50627
+ }
50628
+
50629
+ // src/commands/keys.ts
50630
+ var UUID6 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
50631
+ function patRequired(apiUrl) {
50632
+ return authError(
50633
+ "gad keys needs a personal access token; this sign-in is an OAuth session.",
50634
+ `Create a token at ${apiUrl}/install/cli, then run 'gad login --token <PAT>'.`
50635
+ );
50636
+ }
50637
+ function keyRotationError(error62, apiUrl) {
50638
+ switch (serverCodeOf(error62)) {
50639
+ case "oauth_not_allowed":
50640
+ return patRequired(apiUrl);
50641
+ case "web_session_required":
50642
+ return new CliError(
50643
+ "This key-rotation action is only available in a signed-in browser.",
50644
+ 1 /* AUTH_ERROR */,
50645
+ `Open ${apiUrl}${keyRotationPath()} to do it there.`
50646
+ );
50647
+ case "step_up_required":
50648
+ return new CliError(
50649
+ "The browser approval was missing, expired or already used.",
50650
+ 1 /* AUTH_ERROR */,
50651
+ "Run the command again and approve it in your browser."
50652
+ );
50653
+ default:
50654
+ return error62;
50655
+ }
50656
+ }
50657
+ function keysClient(inner, apiUrl) {
50658
+ const mapped = async (call) => {
50659
+ try {
50660
+ return await call();
50661
+ } catch (e) {
50662
+ throw keyRotationError(e, apiUrl);
50663
+ }
50664
+ };
50665
+ return {
50666
+ apiOrigin: new URL(apiUrl).origin,
50667
+ get: (path10, params) => mapped(() => inner.get(path10, params)),
50668
+ post: (path10, body) => mapped(() => inner.post(path10, body)),
50669
+ delete: (path10) => mapped(() => inner.delete(path10))
50670
+ };
50671
+ }
50672
+ async function keysContext() {
50673
+ const auth = await resolveAuth();
50674
+ const apiUrl = auth.apiUrl.replace(/\/$/, "");
50675
+ if (auth.tokenType === "oauth") throw patRequired(apiUrl);
50676
+ const probe = new GadClient({
50677
+ token: auth.token,
50678
+ getToken: auth.getToken,
50679
+ apiUrl: auth.apiUrl
50680
+ });
50681
+ const value = await probe.mcpCall("workspace_introspect", {}, 5e3);
50682
+ const workspaceId = value?.workspace?.id;
50683
+ if (value?.error || !workspaceId || !UUID6.test(workspaceId)) {
50684
+ throw validationError(
50685
+ "GreatArrow.ai could not confirm your workspace.",
50686
+ "Run 'gad whoami', or choose one with 'gad --workspace <id>'."
50687
+ );
50688
+ }
50689
+ return {
50690
+ client: keysClient(
50691
+ new GadClient({
50692
+ token: auth.token,
50693
+ getToken: auth.getToken,
50694
+ apiUrl: auth.apiUrl,
50695
+ workspaceId
50696
+ }),
50697
+ apiUrl
50698
+ ),
50699
+ workspaceId,
50700
+ apiUrl
50701
+ };
50702
+ }
50703
+ function requireRunId(runId) {
50704
+ if (!UUID6.test(runId)) {
50705
+ throw validationError(
50706
+ `'${stripControlChars(runId)}' is not a run id.`,
50707
+ "Copy the run id from 'gad keys list' or the run page."
50708
+ );
50709
+ }
50710
+ return runId.toLowerCase();
50711
+ }
50712
+ var s = (v) => typeof v === "string" ? stripControlChars(v) : "";
50713
+ function out(line) {
50714
+ process.stdout.write(`${line}
50715
+ `);
50716
+ }
50717
+ function err(line) {
50718
+ process.stderr.write(`${line}
50719
+ `);
50720
+ }
50721
+ function listCommand4() {
50722
+ return new Command("list").description("List the credentials registered for key rotation").action(async (_opts, command) => {
50723
+ const g = globalOutputOpts(command);
50724
+ const { client: client2 } = await keysContext();
50725
+ const res = await client2.get("/api/key-rotation/credentials");
50726
+ const rows = Array.isArray(res?.credentials) ? res.credentials : [];
50727
+ if (g.json) {
50728
+ out(JSON.stringify(rows));
50729
+ return;
50730
+ }
50731
+ if (rows.length === 0) {
50732
+ out(
50733
+ "No credentials registered. Add one under Settings \u2192 Key rotation."
50734
+ );
50735
+ return;
50736
+ }
50737
+ const c = createColor(g.noColor || g.quiet);
50738
+ for (const r of rows) {
50739
+ const flags = [
50740
+ r.openLeak === true ? c.red("leak") : "",
50741
+ typeof r.liveRunId === "string" ? `run ${s(r.liveRunId)}` : ""
50742
+ ].filter(Boolean).join(" \xB7 ");
50743
+ out(
50744
+ `${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}` : "")
50745
+ );
50746
+ }
50747
+ });
50748
+ }
50749
+ function statusCommand4() {
50750
+ return new Command("status").description("Show one rotation run: steps, checklist and devices").argument("<run>", "Run id").action(async (runArg, _opts, command) => {
50751
+ const g = globalOutputOpts(command);
50752
+ const runId = requireRunId(runArg);
50753
+ const { client: client2, apiUrl } = await keysContext();
50754
+ const res = await client2.get(`/api/key-rotation/runs/${runId}`);
50755
+ const run4 = res?.run ?? {};
50756
+ if (g.json) {
50757
+ out(JSON.stringify(run4));
50758
+ return;
50759
+ }
50760
+ const c = createColor(g.noColor || g.quiet);
50761
+ out(
50762
+ `${c.bold(`Run ${runId}`)} ${s(run4.state)}` + (s(run4.waitingOn) ? c.dim(` waiting on ${s(run4.waitingOn)}`) : "")
50763
+ );
50764
+ for (const st of run4.steps ?? []) {
50765
+ const detail = s(st.detailCode);
50766
+ out(
50767
+ ` ${s(st.step)} ${c.dim(s(st.targetKind))} ${s(st.status)}` + (detail ? c.dim(` (${detail})`) : "")
50768
+ );
50769
+ }
50770
+ const open4 = (run4.checklist ?? []).filter((i) => i.ticked !== true);
50771
+ if (open4.length > 0) {
50772
+ out(c.yellow("Checklist (tick these in the browser):"));
50773
+ for (const item of open4) {
50774
+ out(` \u2610 ${s(item.label)} ${c.cyan(s(item.href))}`);
50775
+ }
50776
+ }
50777
+ for (const d of run4.devices ?? []) {
50778
+ out(` device ${s(d.label)} ${s(d.state)}`);
50779
+ }
50780
+ out(c.dim(`${apiUrl}${keyRotationRunPath(runId)}`));
50781
+ });
50782
+ }
50783
+ function collect2(value, previous) {
50784
+ return [...previous, value];
50785
+ }
50786
+ function enrollCommand() {
50787
+ return new Command("enroll").description(
50788
+ "Enroll this machine to receive rotated keys (approve in the browser)"
50789
+ ).option("--label <label>", "Device label (defaults to the host name)").option(
50790
+ "--env-file <path>",
50791
+ "An env file to report key NAMES from (repeatable; ./.env.local is always included)",
50792
+ collect2,
50793
+ []
50794
+ ).option(
50795
+ "--replace",
50796
+ "Enroll again with a new key, replacing this machine's"
50797
+ ).action(async (opts, command) => {
50798
+ const g = globalOutputOpts(command);
50799
+ const { client: client2, workspaceId } = await keysContext();
50800
+ const { deviceId, report, replaced } = await enroll(client2, workspaceId, {
50801
+ ...typeof opts.label === "string" ? { label: opts.label } : {},
50802
+ envFiles: Array.isArray(opts.envFile) ? opts.envFile : [],
50803
+ replace: opts.replace === true
50804
+ });
50805
+ if (g.json) {
50806
+ out(JSON.stringify({ deviceId, report, replaced }));
50807
+ } else {
50808
+ out(`Enrolled this machine as device ${deviceId}.`);
50809
+ out(
50810
+ `Reported ${report.envKeys.length} env key name(s), gh CLI ${report.ghCli ? "found" : "not found"}, git helper ${report.gitHelper ?? "none"}.`
50811
+ );
50812
+ if (replaced?.revoked) {
50813
+ out(
50814
+ `Revoked the device it replaced (${replaced.deviceId}); its queued updates expired.`
50815
+ );
50816
+ out(
50817
+ "Usages confirmed for that device still point at it: confirm them for this one under Settings \u2192 Key rotation."
50818
+ );
50819
+ }
50820
+ }
50821
+ if (replaced && !replaced.revoked) {
50822
+ throw new CliError(
50823
+ `Enrolled, but the device it replaced (${replaced.deviceId}) could not be revoked.`,
50824
+ 2 /* NETWORK_ERROR */,
50825
+ "Revoke it under Settings \u2192 Key rotation; updates sealed to it can no longer be opened on this machine."
50826
+ );
50827
+ }
50828
+ });
50829
+ }
50830
+ function toUpdateRow(v) {
50831
+ if (typeof v !== "object" || v === null) return null;
50832
+ const r = v;
50833
+ if (typeof r.id !== "string" || !UUID6.test(r.id)) return null;
50834
+ const ref = {};
50835
+ if (typeof r.targetRef === "object" && r.targetRef !== null) {
50836
+ for (const [k, val] of Object.entries(r.targetRef)) {
50837
+ if (typeof val === "string") ref[k] = val;
50838
+ }
50839
+ }
50840
+ return {
50841
+ id: r.id,
50842
+ runId: typeof r.runId === "string" ? r.runId : "",
50843
+ targetKind: typeof r.targetKind === "string" ? r.targetKind : "",
50844
+ targetRef: ref
50845
+ };
50846
+ }
50847
+ function describeTarget(u) {
50848
+ const ref = u.targetRef;
50849
+ switch (u.targetKind) {
50850
+ case "machine_env_file":
50851
+ return `${s(ref.key)} in ${s(ref.path)}`;
50852
+ case "machine_ssh_key":
50853
+ return `SSH key ${s(ref.path)}`;
50854
+ case "machine_git_credential":
50855
+ return `git credential (${s(ref.helper)})`;
50856
+ case "machine_gh_cli":
50857
+ return "gh CLI login";
50858
+ default:
50859
+ return s(u.targetKind);
50860
+ }
50861
+ }
50862
+ async function listUpdates(client2, deviceId) {
50863
+ const res = await client2.get(
50864
+ `/api/key-rotation/devices/${deviceId}/updates`
50865
+ );
50866
+ return (Array.isArray(res?.updates) ? res.updates : []).map(toUpdateRow).filter((u) => u !== null);
50867
+ }
50868
+ function pendingCommand() {
50869
+ return new Command("pending").description("List the key updates queued for this machine").action(async (_opts, command) => {
50870
+ const g = globalOutputOpts(command);
50871
+ const { client: client2, workspaceId } = await keysContext();
50872
+ const device = await requireEnrolledDevice(workspaceId);
50873
+ const updates = await listUpdates(client2, device.deviceId);
50874
+ if (g.json) {
50875
+ out(JSON.stringify(updates));
50876
+ return;
50877
+ }
50878
+ if (updates.length === 0) {
50879
+ out("No key updates are waiting for this machine.");
50880
+ return;
50881
+ }
50882
+ for (const u of updates) out(` ${describeTarget(u)} ${u.id}`);
50883
+ out("Run 'gad keys apply' to apply them.");
50884
+ });
50885
+ }
50886
+ async function ack(client2, deviceId, updateId, result) {
50887
+ await client2.post(
50888
+ `/api/key-rotation/devices/${deviceId}/updates/${updateId}`,
50889
+ {
50890
+ action: "ack",
50891
+ ok: result.ok,
50892
+ detailCode: result.code
50893
+ }
50894
+ );
50895
+ }
50896
+ async function fetchOpenApply(client2, device, u, approvalToken) {
50897
+ let sealed;
50898
+ try {
50899
+ const fetched = await client2.post(
50900
+ `/api/key-rotation/devices/${device.deviceId}/updates/${u.id}`,
50901
+ { action: "fetch", approvalToken }
50902
+ );
50903
+ if (typeof fetched?.sealedPayload !== "string") {
50904
+ return { ack: false, ok: false, code: "fetch_failed" };
50905
+ }
50906
+ sealed = fetched.sealedPayload;
50907
+ } catch {
50908
+ return { ack: false, ok: false, code: "fetch_failed" };
50909
+ }
50910
+ let value;
50911
+ try {
50912
+ value = openFromServer(Buffer.from(sealed, "base64"), device.privateKey);
50913
+ } catch (e) {
50914
+ return {
50915
+ ack: true,
50916
+ ok: false,
50917
+ code: e instanceof EnvelopeError ? e.code : "envelope_invalid"
50918
+ };
50919
+ }
50920
+ const result = await applyUpdate(u.targetKind, u.targetRef, value, {
50921
+ reported: device.reported
50922
+ });
50923
+ return { ack: true, ...result };
50924
+ }
50925
+ async function applyBatch(client2, device, updates) {
50926
+ if (updates.length === 0) return [];
50927
+ const approvalToken = await requestBrowserStepUp(
50928
+ client2,
50929
+ "device_apply",
50930
+ device.deviceId
50931
+ );
50932
+ const results = [];
50933
+ for (const u of updates) {
50934
+ const { ack: shouldAck, ...result } = await fetchOpenApply(
50935
+ client2,
50936
+ device,
50937
+ u,
50938
+ approvalToken
50939
+ );
50940
+ if (!shouldAck) {
50941
+ results.push({ id: u.id, targetKind: u.targetKind, ...result });
50942
+ continue;
50943
+ }
50944
+ try {
50945
+ await ack(client2, device.deviceId, u.id, result);
50946
+ results.push({ id: u.id, targetKind: u.targetKind, ...result });
50947
+ } catch {
50948
+ results.push({
50949
+ id: u.id,
50950
+ targetKind: u.targetKind,
50951
+ ok: false,
50952
+ code: "ack_failed"
50953
+ });
50954
+ }
50955
+ }
50956
+ return results;
50957
+ }
50958
+ function applyCommand() {
50959
+ return new Command("apply").description(
50960
+ "Apply the key updates queued for this machine (one browser approval)"
50961
+ ).option("--yes", "Apply without the local confirmation prompt").action(async (opts, command) => {
50962
+ const g = globalOutputOpts(command);
50963
+ const { client: client2, workspaceId } = await keysContext();
50964
+ const device = await requireEnrolledDevice(workspaceId);
50965
+ const updates = await listUpdates(client2, device.deviceId);
50966
+ if (updates.length === 0) {
50967
+ if (g.json) out("[]");
50968
+ else out("No key updates are waiting for this machine.");
50969
+ return;
50970
+ }
50971
+ if (opts.yes !== true) {
50972
+ if (!process.stdin.isTTY) {
50973
+ throw validationError(
50974
+ "Refusing to apply key updates without confirmation.",
50975
+ "Run 'gad keys apply --yes' in a script."
50976
+ );
50977
+ }
50978
+ for (const u of updates) err(` ${describeTarget(u)}`);
50979
+ if (!await confirm(`Apply ${updates.length} key update(s)?`)) {
50980
+ err("Nothing applied.");
50981
+ return;
50982
+ }
50983
+ }
50984
+ const results = await applyBatch(client2, device, updates);
50985
+ if (g.json) {
50986
+ out(JSON.stringify(results));
50987
+ } else {
50988
+ const c = createColor(g.noColor || g.quiet);
50989
+ for (const r of results) {
50990
+ const u = updates.find((x) => x.id === r.id);
50991
+ const where = u ? describeTarget(u) : r.targetKind;
50992
+ out(`${r.ok ? c.green("\u2713") : c.red("\u2717")} ${where} ${c.dim(r.code)}`);
50993
+ }
50994
+ }
50995
+ const failed = results.filter((r) => !r.ok).length;
50996
+ if (failed > 0) {
50997
+ throw new CliError(
50998
+ `${failed} of ${results.length} key update(s) failed on this machine.`,
50999
+ 3 /* VALIDATION_ERROR */,
51000
+ "An update that could not be fetched stays queued: run 'gad keys apply' again. The run page shows every other failed step."
51001
+ );
51002
+ }
51003
+ });
51004
+ }
51005
+ function readHiddenFromTty(prompt, io = {
51006
+ input: process.stdin,
51007
+ output: process.stderr
51008
+ }) {
51009
+ let muted = false;
51010
+ const sink = new Writable({
51011
+ write(chunk, encoding, callback) {
51012
+ if (!muted) io.output.write(chunk, encoding);
51013
+ callback();
51014
+ }
51015
+ });
51016
+ const rl = createInterface3({
51017
+ input: io.input,
51018
+ output: sink,
51019
+ terminal: true
51020
+ });
51021
+ io.output.write(prompt);
51022
+ muted = true;
51023
+ return new Promise((resolve5, reject) => {
51024
+ const lines = [];
51025
+ let pem = false;
51026
+ const finish = () => {
51027
+ rl.close();
51028
+ io.output.write("\n");
51029
+ resolve5(lines.join("\n"));
51030
+ };
51031
+ rl.on("line", (line) => {
51032
+ if (lines.length === 0) pem = /^-----BEGIN /.test(line.trim());
51033
+ lines.push(line);
51034
+ if (!pem || /^-----END .*-----\s*$/.test(line.trim())) finish();
51035
+ });
51036
+ rl.on("SIGINT", () => {
51037
+ rl.close();
51038
+ reject(new CliError("Paste cancelled.", 3 /* VALIDATION_ERROR */));
51039
+ });
51040
+ });
51041
+ }
51042
+ function pasteRefusal(error62, apiUrl, runId) {
51043
+ const code = serverCodeOf(error62);
51044
+ if (code !== null && (code === "invalid_grants" || code === "storage_token_missing" || code.startsWith("onepassword_"))) {
51045
+ return new CliError(
51046
+ "This run needs its 1Password access granted again, which the CLI cannot send.",
51047
+ 3 /* VALIDATION_ERROR */,
51048
+ `Paste the key on the run page instead: ${apiUrl}${keyRotationRunPath(runId)}`
51049
+ );
51050
+ }
51051
+ return error62;
51052
+ }
51053
+ function pasteCommand() {
51054
+ return new Command("paste").description(
51055
+ "Paste the new PAT or App private key for a run (no echo; browser step-up)"
51056
+ ).argument("<run>", "Run id").option("--stdin", "Read the value from piped stdin instead of a prompt").action(async (runArg, opts, command) => {
51057
+ const g = globalOutputOpts(command);
51058
+ const runId = requireRunId(runArg);
51059
+ const fromStdin = opts.stdin === true;
51060
+ if (!fromStdin && !process.stdin.isTTY) {
51061
+ throw validationError(
51062
+ "Refusing to read a key from a non-interactive stdin.",
51063
+ "Pass --stdin to read the value from a pipe."
51064
+ );
51065
+ }
51066
+ const { client: client2, apiUrl } = await keysContext();
51067
+ const approvalToken = await requestBrowserStepUp(client2, "paste", runId);
51068
+ const raw = fromStdin ? await readStream(process.stdin) : await readHiddenFromTty("Paste the new key (input hidden): ");
51069
+ const value = raw.trim();
51070
+ if (!value) {
51071
+ throw validationError("Nothing was pasted.");
51072
+ }
51073
+ try {
51074
+ await client2.post(`/api/key-rotation/runs/${runId}/paste`, {
51075
+ value,
51076
+ approvalToken
51077
+ });
51078
+ } catch (e) {
51079
+ throw pasteRefusal(e, apiUrl, runId);
51080
+ }
51081
+ if (g.json) out(JSON.stringify({ ok: true, runId }));
51082
+ else out("Pasted. The run continues on GreatArrow.ai.");
51083
+ });
51084
+ }
51085
+ function approveCommand() {
51086
+ return new Command("approve").description("Open a run's approval page in the browser").argument("<run>", "Run id").action(async (runArg, _opts, command) => {
51087
+ const g = globalOutputOpts(command);
51088
+ const runId = requireRunId(runArg);
51089
+ const auth = await resolveAuth();
51090
+ const url2 = `${auth.apiUrl.replace(/\/$/, "")}${keyRotationRunPath(runId)}`;
51091
+ if (g.json) {
51092
+ out(JSON.stringify({ url: url2 }));
51093
+ return;
51094
+ }
51095
+ const opened = await openInBrowser(url2);
51096
+ out(url2);
51097
+ if (!opened) err("Couldn't launch a browser \u2014 open the URL above.");
51098
+ });
51099
+ }
51100
+ function keysCommand() {
51101
+ 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());
51102
+ }
51103
+
49647
51104
  // src/lib/completions.ts
49648
51105
  var COMMANDS = [
49649
51106
  "login",
@@ -49658,6 +51115,8 @@ var COMMANDS = [
49658
51115
  "smoke",
49659
51116
  "agent",
49660
51117
  "ask",
51118
+ "inbox",
51119
+ "presence",
49661
51120
  "runtime",
49662
51121
  "open",
49663
51122
  "completions"
@@ -49699,6 +51158,12 @@ _gad_completions() {
49699
51158
  agent)
49700
51159
  COMPREPLY=( $(compgen -W "list invoke" -- "\${cur}") )
49701
51160
  ;;
51161
+ inbox)
51162
+ COMPREPLY=( $(compgen -W "wait" -- "\${cur}") )
51163
+ ;;
51164
+ presence)
51165
+ COMPREPLY=( $(compgen -W "do-not-disturb sign-off" -- "\${cur}") )
51166
+ ;;
49702
51167
  runtime)
49703
51168
  COMPREPLY=( $(compgen -W "status set sync policy" -- "\${cur}") )
49704
51169
  ;;
@@ -49734,6 +51199,8 @@ _gad() {
49734
51199
  'smoke:Run smoke tests'
49735
51200
  'agent:Manage agents (list, invoke)'
49736
51201
  'ask:Ask the orchestrator a question'
51202
+ 'inbox:Agent inbox (wait)'
51203
+ 'presence:Agent presence (do-not-disturb, sign-off)'
49737
51204
  'runtime:Choose your computer or the cloud per lane'
49738
51205
  'open:Open an app surface in the browser'
49739
51206
  'completions:Generate shell completions'
@@ -49769,6 +51236,14 @@ _gad() {
49769
51236
  subcommands=('list:List agents' 'invoke:Invoke an agent')
49770
51237
  _describe -t subcommands 'agent subcommands' subcommands
49771
51238
  ;;
51239
+ inbox)
51240
+ subcommands=('wait:Wait for a peer message')
51241
+ _describe -t subcommands 'inbox subcommands' subcommands
51242
+ ;;
51243
+ presence)
51244
+ subcommands=('do-not-disturb:Do not disturb for a while, or off' 'sign-off:Sign off this connection')
51245
+ _describe -t subcommands 'presence subcommands' subcommands
51246
+ ;;
49772
51247
  runtime)
49773
51248
  subcommands=('status:Where each lane runs' 'set:Set a lane' 'sync:Apply to this checkout' 'policy:Workspace policy')
49774
51249
  _describe -t subcommands 'runtime subcommands' subcommands
@@ -49797,6 +51272,8 @@ function generateFish() {
49797
51272
  smoke: "Run smoke tests",
49798
51273
  agent: "Manage agents",
49799
51274
  ask: "Ask the orchestrator a question",
51275
+ inbox: "Agent inbox",
51276
+ presence: "Agent presence",
49800
51277
  runtime: "Choose your computer or the cloud per lane",
49801
51278
  open: "Open an app surface in the browser",
49802
51279
  completions: "Generate shell completions"
@@ -49835,6 +51312,13 @@ function generateFish() {
49835
51312
  list: "List agents",
49836
51313
  invoke: "Invoke an agent"
49837
51314
  },
51315
+ inbox: {
51316
+ wait: "Wait for a peer message"
51317
+ },
51318
+ presence: {
51319
+ "do-not-disturb": "Do not disturb for a while, or off",
51320
+ "sign-off": "Sign off this connection"
51321
+ },
49838
51322
  runtime: {
49839
51323
  status: "Where each lane runs",
49840
51324
  set: "Set a lane",
@@ -49898,7 +51382,7 @@ function completionsCommand() {
49898
51382
 
49899
51383
  // node_modules/.pnpm/update-notifier@7.3.1/node_modules/update-notifier/update-notifier.js
49900
51384
  import process11 from "node:process";
49901
- import { spawn } from "node:child_process";
51385
+ import { spawn as spawn3 } from "node:child_process";
49902
51386
  import { fileURLToPath as fileURLToPath3 } from "node:url";
49903
51387
  import path9 from "node:path";
49904
51388
  import { format } from "node:util";
@@ -49974,7 +51458,7 @@ var retryifyAsync = (fn, options) => {
49974
51458
  throw error62;
49975
51459
  const delay2 = Math.round(interval * Math.random());
49976
51460
  if (delay2 > 0) {
49977
- const delayPromise = new Promise((resolve4) => setTimeout(resolve4, delay2));
51461
+ const delayPromise = new Promise((resolve5) => setTimeout(resolve5, delay2));
49978
51462
  return delayPromise.then(() => attempt.apply(void 0, args));
49979
51463
  } else {
49980
51464
  return attempt.apply(void 0, args);
@@ -50233,14 +51717,14 @@ var Temp = {
50233
51717
  }
50234
51718
  },
50235
51719
  truncate: (filePath) => {
50236
- const basename2 = path3.basename(filePath);
50237
- if (basename2.length <= LIMIT_BASENAME_LENGTH)
51720
+ const basename3 = path3.basename(filePath);
51721
+ if (basename3.length <= LIMIT_BASENAME_LENGTH)
50238
51722
  return filePath;
50239
- const truncable = /^(\.?)(.*?)((?:\.[^.]+)?(?:\.tmp-\d{10}[a-f0-9]{6})?)$/.exec(basename2);
51723
+ const truncable = /^(\.?)(.*?)((?:\.[^.]+)?(?:\.tmp-\d{10}[a-f0-9]{6})?)$/.exec(basename3);
50240
51724
  if (!truncable)
50241
51725
  return filePath;
50242
- const truncationLength = basename2.length - LIMIT_BASENAME_LENGTH;
50243
- return `${filePath.slice(0, -basename2.length)}${truncable[1]}${truncable[2].slice(0, -truncationLength)}${truncable[3]}`;
51726
+ const truncationLength = basename3.length - LIMIT_BASENAME_LENGTH;
51727
+ return `${filePath.slice(0, -basename3.length)}${truncable[1]}${truncable[2].slice(0, -truncationLength)}${truncable[3]}`;
50244
51728
  }
50245
51729
  };
50246
51730
  node_default(Temp.purgeSyncAll);
@@ -51540,14 +53024,14 @@ var TimeoutError = class extends Error {
51540
53024
 
51541
53025
  // node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/timeout.js
51542
53026
  async function timeout(request, init, abortController, options) {
51543
- return new Promise((resolve4, reject) => {
53027
+ return new Promise((resolve5, reject) => {
51544
53028
  const timeoutId = setTimeout(() => {
51545
53029
  if (abortController) {
51546
53030
  abortController.abort();
51547
53031
  }
51548
53032
  reject(new TimeoutError(request));
51549
53033
  }, options.timeout);
51550
- void options.fetch(request, init).then(resolve4).catch(reject).then(() => {
53034
+ void options.fetch(request, init).then(resolve5).catch(reject).then(() => {
51551
53035
  clearTimeout(timeoutId);
51552
53036
  });
51553
53037
  });
@@ -51555,7 +53039,7 @@ async function timeout(request, init, abortController, options) {
51555
53039
 
51556
53040
  // node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/delay.js
51557
53041
  async function delay(ms, { signal }) {
51558
- return new Promise((resolve4, reject) => {
53042
+ return new Promise((resolve5, reject) => {
51559
53043
  if (signal) {
51560
53044
  signal.throwIfAborted();
51561
53045
  signal.addEventListener("abort", abortHandler, { once: true });
@@ -51566,7 +53050,7 @@ async function delay(ms, { signal }) {
51566
53050
  }
51567
53051
  const timeoutId = setTimeout(() => {
51568
53052
  signal?.removeEventListener("abort", abortHandler);
51569
- resolve4();
53053
+ resolve5();
51570
53054
  }, ms);
51571
53055
  });
51572
53056
  }
@@ -52868,7 +54352,7 @@ var makeContentText = (text3, { padding, width, textAlignment, height }) => {
52868
54352
  const createdLines = wrapAnsi(line, max, { hard: true });
52869
54353
  const alignedLines = (0, import_ansi_align.default)(createdLines, { align: textAlignment });
52870
54354
  const alignedLinesArray = alignedLines.split("\n");
52871
- const longestLength = Math.max(...alignedLinesArray.map((s) => stringWidth(s)));
54355
+ const longestLength = Math.max(...alignedLinesArray.map((s2) => stringWidth(s2)));
52872
54356
  for (const alignedLine of alignedLinesArray) {
52873
54357
  let paddedLine;
52874
54358
  switch (textAlignment) {
@@ -53195,7 +54679,7 @@ var UpdateNotifier = class {
53195
54679
  if (Date.now() - this.config.get("lastUpdateCheck") < this.#updateCheckInterval) {
53196
54680
  return;
53197
54681
  }
53198
- spawn(process11.execPath, [path9.join(__dirname3, "check.js"), JSON.stringify(this.#options)], {
54682
+ spawn3(process11.execPath, [path9.join(__dirname3, "check.js"), JSON.stringify(this.#options)], {
53199
54683
  detached: true,
53200
54684
  stdio: "ignore"
53201
54685
  }).unref();
@@ -53314,10 +54798,13 @@ program2.addCommand(integrations_default);
53314
54798
  program2.addCommand(mcp_default);
53315
54799
  program2.addCommand(agentCommand);
53316
54800
  program2.addCommand(agentsCommand);
54801
+ program2.addCommand(inboxCommand);
54802
+ program2.addCommand(presenceCommand);
53317
54803
  program2.addCommand(askCommand());
53318
54804
  program2.addCommand(localCommand());
53319
54805
  program2.addCommand(runtimeCommand());
53320
54806
  program2.addCommand(smokeCommand());
54807
+ program2.addCommand(keysCommand());
53321
54808
  program2.addCommand(openCommand());
53322
54809
  program2.addCommand(completionsCommand());
53323
54810
  try {