@great-arrow/cli 0.7.2 → 0.8.0

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 +19 -0
  2. package/dist/index.js +1606 -264
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -44,7 +44,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
44
44
  // node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/polyfills.js
45
45
  var require_polyfills = __commonJS({
46
46
  "node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/polyfills.js"(exports, module) {
47
- var constants2 = __require("constants");
47
+ var constants3 = __require("constants");
48
48
  var origCwd = process.cwd;
49
49
  var cwd = null;
50
50
  var platform2 = process.env.GRACEFUL_FS_PLATFORM || process.platform;
@@ -68,7 +68,7 @@ var require_polyfills = __commonJS({
68
68
  var chdir;
69
69
  module.exports = patch;
70
70
  function patch(fs6) {
71
- if (constants2.hasOwnProperty("O_SYMLINK") && process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) {
71
+ if (constants3.hasOwnProperty("O_SYMLINK") && process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) {
72
72
  patchLchmod(fs6);
73
73
  }
74
74
  if (!fs6.lutimes) {
@@ -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 rename4(from, to, cb) {
111
+ function rename5(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(rename4, fs$rename);
132
- return rename4;
131
+ if (Object.setPrototypeOf) Object.setPrototypeOf(rename5, fs$rename);
132
+ return rename5;
133
133
  })(fs6.rename);
134
134
  }
135
135
  fs6.read = typeof fs6.read !== "function" ? fs6.read : (function(fs$read) {
@@ -170,7 +170,7 @@ var require_polyfills = __commonJS({
170
170
  fs7.lchmod = function(path10, mode, callback) {
171
171
  fs7.open(
172
172
  path10,
173
- constants2.O_WRONLY | constants2.O_SYMLINK,
173
+ constants3.O_WRONLY | constants3.O_SYMLINK,
174
174
  mode,
175
175
  function(err2, fd) {
176
176
  if (err2) {
@@ -186,7 +186,7 @@ var require_polyfills = __commonJS({
186
186
  );
187
187
  };
188
188
  fs7.lchmodSync = function(path10, mode) {
189
- var fd = fs7.openSync(path10, constants2.O_WRONLY | constants2.O_SYMLINK, mode);
189
+ var fd = fs7.openSync(path10, constants3.O_WRONLY | constants3.O_SYMLINK, mode);
190
190
  var threw = true;
191
191
  var ret;
192
192
  try {
@@ -206,9 +206,9 @@ var require_polyfills = __commonJS({
206
206
  };
207
207
  }
208
208
  function patchLutimes(fs7) {
209
- if (constants2.hasOwnProperty("O_SYMLINK") && fs7.futimes) {
209
+ if (constants3.hasOwnProperty("O_SYMLINK") && fs7.futimes) {
210
210
  fs7.lutimes = function(path10, at, mt, cb) {
211
- fs7.open(path10, constants2.O_SYMLINK, function(er, fd) {
211
+ fs7.open(path10, constants3.O_SYMLINK, function(er, fd) {
212
212
  if (er) {
213
213
  if (cb) cb(er);
214
214
  return;
@@ -221,7 +221,7 @@ var require_polyfills = __commonJS({
221
221
  });
222
222
  };
223
223
  fs7.lutimesSync = function(path10, at, mt) {
224
- var fd = fs7.openSync(path10, constants2.O_SYMLINK);
224
+ var fd = fs7.openSync(path10, constants3.O_SYMLINK);
225
225
  var ret;
226
226
  var threw = true;
227
227
  try {
@@ -502,14 +502,14 @@ var require_graceful_fs = __commonJS({
502
502
  return close;
503
503
  })(fs6.close);
504
504
  fs6.closeSync = (function(fs$closeSync) {
505
- function closeSync(fd) {
505
+ function closeSync2(fd) {
506
506
  fs$closeSync.apply(fs6, arguments);
507
507
  resetQueue();
508
508
  }
509
- Object.defineProperty(closeSync, previousSymbol, {
509
+ Object.defineProperty(closeSync2, previousSymbol, {
510
510
  value: fs$closeSync
511
511
  });
512
- return closeSync;
512
+ return closeSync2;
513
513
  })(fs6.closeSync);
514
514
  if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || "")) {
515
515
  process.on("exit", function() {
@@ -533,8 +533,8 @@ 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 = readFile9;
537
- function readFile9(path10, options, cb) {
536
+ fs7.readFile = readFile11;
537
+ function readFile11(path10, options, cb) {
538
538
  if (typeof options === "function")
539
539
  cb = options, options = null;
540
540
  return go$readFile(path10, options, cb);
@@ -550,8 +550,8 @@ var require_graceful_fs = __commonJS({
550
550
  }
551
551
  }
552
552
  var fs$writeFile = fs7.writeFile;
553
- fs7.writeFile = writeFile7;
554
- function writeFile7(path10, data, options, cb) {
553
+ fs7.writeFile = writeFile10;
554
+ function writeFile10(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);
@@ -1155,8 +1155,8 @@ var require_semver = __commonJS({
1155
1155
  }
1156
1156
  // preminor will bump the version up to the next minor release, and immediately
1157
1157
  // down to pre-release. premajor and prepatch work the same way.
1158
- inc(release, identifier, identifierBase) {
1159
- if (release.startsWith("pre")) {
1158
+ inc(release2, identifier, identifierBase) {
1159
+ if (release2.startsWith("pre")) {
1160
1160
  if (!identifier && identifierBase === false) {
1161
1161
  throw new Error("invalid increment argument: identifier is empty");
1162
1162
  }
@@ -1167,7 +1167,7 @@ var require_semver = __commonJS({
1167
1167
  }
1168
1168
  }
1169
1169
  }
1170
- switch (release) {
1170
+ switch (release2) {
1171
1171
  case "premajor":
1172
1172
  this.prerelease.length = 0;
1173
1173
  this.patch = 0;
@@ -1258,7 +1258,7 @@ var require_semver = __commonJS({
1258
1258
  break;
1259
1259
  }
1260
1260
  default:
1261
- throw new Error(`invalid increment argument: ${release}`);
1261
+ throw new Error(`invalid increment argument: ${release2}`);
1262
1262
  }
1263
1263
  this.raw = this.format();
1264
1264
  if (this.build.length) {
@@ -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 join13 = __require("path").join;
1971
+ var join18 = __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
- join13(etc, name23, "config"),
1997
- join13(etc, name23 + "rc")
1996
+ join18(etc, name23, "config"),
1997
+ join18(etc, name23 + "rc")
1998
1998
  ].forEach(addConfigFile);
1999
1999
  if (home)
2000
2000
  [
2001
- join13(home, ".config", name23, "config"),
2002
- join13(home, ".config", name23),
2003
- join13(home, "." + name23, "config"),
2004
- join13(home, "." + name23 + "rc")
2001
+ join18(home, ".config", name23, "config"),
2002
+ join18(home, ".config", name23),
2003
+ join18(home, "." + name23, "config"),
2004
+ join18(home, "." + name23 + "rc")
2005
2005
  ].forEach(addConfigFile);
2006
2006
  addConfigFile(cc.find("." + name23 + "rc"));
2007
2007
  if (env4.config) addConfigFile(env4.config);
@@ -2018,7 +2018,7 @@ var require_rc = __commonJS({
2018
2018
  // node_modules/.pnpm/graceful-fs@4.2.10/node_modules/graceful-fs/polyfills.js
2019
2019
  var require_polyfills2 = __commonJS({
2020
2020
  "node_modules/.pnpm/graceful-fs@4.2.10/node_modules/graceful-fs/polyfills.js"(exports, module) {
2021
- var constants2 = __require("constants");
2021
+ var constants3 = __require("constants");
2022
2022
  var origCwd = process.cwd;
2023
2023
  var cwd = null;
2024
2024
  var platform2 = process.env.GRACEFUL_FS_PLATFORM || process.platform;
@@ -2042,7 +2042,7 @@ var require_polyfills2 = __commonJS({
2042
2042
  var chdir;
2043
2043
  module.exports = patch;
2044
2044
  function patch(fs6) {
2045
- if (constants2.hasOwnProperty("O_SYMLINK") && process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) {
2045
+ if (constants3.hasOwnProperty("O_SYMLINK") && process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) {
2046
2046
  patchLchmod(fs6);
2047
2047
  }
2048
2048
  if (!fs6.lutimes) {
@@ -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 rename4(from, to, cb) {
2085
+ function rename5(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(rename4, fs$rename);
2106
- return rename4;
2105
+ if (Object.setPrototypeOf) Object.setPrototypeOf(rename5, fs$rename);
2106
+ return rename5;
2107
2107
  })(fs6.rename);
2108
2108
  }
2109
2109
  fs6.read = typeof fs6.read !== "function" ? fs6.read : (function(fs$read) {
@@ -2144,7 +2144,7 @@ var require_polyfills2 = __commonJS({
2144
2144
  fs7.lchmod = function(path10, mode, callback) {
2145
2145
  fs7.open(
2146
2146
  path10,
2147
- constants2.O_WRONLY | constants2.O_SYMLINK,
2147
+ constants3.O_WRONLY | constants3.O_SYMLINK,
2148
2148
  mode,
2149
2149
  function(err2, fd) {
2150
2150
  if (err2) {
@@ -2160,7 +2160,7 @@ var require_polyfills2 = __commonJS({
2160
2160
  );
2161
2161
  };
2162
2162
  fs7.lchmodSync = function(path10, mode) {
2163
- var fd = fs7.openSync(path10, constants2.O_WRONLY | constants2.O_SYMLINK, mode);
2163
+ var fd = fs7.openSync(path10, constants3.O_WRONLY | constants3.O_SYMLINK, mode);
2164
2164
  var threw = true;
2165
2165
  var ret;
2166
2166
  try {
@@ -2180,9 +2180,9 @@ var require_polyfills2 = __commonJS({
2180
2180
  };
2181
2181
  }
2182
2182
  function patchLutimes(fs7) {
2183
- if (constants2.hasOwnProperty("O_SYMLINK") && fs7.futimes) {
2183
+ if (constants3.hasOwnProperty("O_SYMLINK") && fs7.futimes) {
2184
2184
  fs7.lutimes = function(path10, at, mt, cb) {
2185
- fs7.open(path10, constants2.O_SYMLINK, function(er, fd) {
2185
+ fs7.open(path10, constants3.O_SYMLINK, function(er, fd) {
2186
2186
  if (er) {
2187
2187
  if (cb) cb(er);
2188
2188
  return;
@@ -2195,7 +2195,7 @@ var require_polyfills2 = __commonJS({
2195
2195
  });
2196
2196
  };
2197
2197
  fs7.lutimesSync = function(path10, at, mt) {
2198
- var fd = fs7.openSync(path10, constants2.O_SYMLINK);
2198
+ var fd = fs7.openSync(path10, constants3.O_SYMLINK);
2199
2199
  var ret;
2200
2200
  var threw = true;
2201
2201
  try {
@@ -2476,14 +2476,14 @@ var require_graceful_fs2 = __commonJS({
2476
2476
  return close;
2477
2477
  })(fs6.close);
2478
2478
  fs6.closeSync = (function(fs$closeSync) {
2479
- function closeSync(fd) {
2479
+ function closeSync2(fd) {
2480
2480
  fs$closeSync.apply(fs6, arguments);
2481
2481
  resetQueue();
2482
2482
  }
2483
- Object.defineProperty(closeSync, previousSymbol, {
2483
+ Object.defineProperty(closeSync2, previousSymbol, {
2484
2484
  value: fs$closeSync
2485
2485
  });
2486
- return closeSync;
2486
+ return closeSync2;
2487
2487
  })(fs6.closeSync);
2488
2488
  if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || "")) {
2489
2489
  process.on("exit", function() {
@@ -2507,8 +2507,8 @@ 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 = readFile9;
2511
- function readFile9(path10, options, cb) {
2510
+ fs7.readFile = readFile11;
2511
+ function readFile11(path10, options, cb) {
2512
2512
  if (typeof options === "function")
2513
2513
  cb = options, options = null;
2514
2514
  return go$readFile(path10, options, cb);
@@ -2524,8 +2524,8 @@ var require_graceful_fs2 = __commonJS({
2524
2524
  }
2525
2525
  }
2526
2526
  var fs$writeFile = fs7.writeFile;
2527
- fs7.writeFile = writeFile7;
2528
- function writeFile7(path10, data, options, cb) {
2527
+ fs7.writeFile = writeFile10;
2528
+ function writeFile10(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);
@@ -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 dirname9 = path10.dirname(name24);
3343
- if (dirname9 === name24) {
3342
+ const dirname10 = path10.dirname(name24);
3343
+ if (dirname10 === name24) {
3344
3344
  return original;
3345
3345
  }
3346
- return find(dirname9, original);
3346
+ return find(dirname10, original);
3347
3347
  } catch (error62) {
3348
3348
  if (name24 === original) {
3349
3349
  if (error62.code === "ENOENT") {
@@ -4044,7 +4044,7 @@ var require_inc = __commonJS({
4044
4044
  "node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/inc.js"(exports, module) {
4045
4045
  "use strict";
4046
4046
  var SemVer = require_semver();
4047
- var inc = (version2, release, options, identifier, identifierBase) => {
4047
+ var inc = (version2, release2, options, identifier, identifierBase) => {
4048
4048
  if (typeof options === "string") {
4049
4049
  identifierBase = identifier;
4050
4050
  identifier = options;
@@ -4054,7 +4054,7 @@ var require_inc = __commonJS({
4054
4054
  return new SemVer(
4055
4055
  version2 instanceof SemVer ? version2.version : version2,
4056
4056
  options
4057
- ).inc(release, identifier, identifierBase).version;
4057
+ ).inc(release2, identifier, identifierBase).version;
4058
4058
  } catch (er) {
4059
4059
  return null;
4060
4060
  }
@@ -4311,10 +4311,10 @@ var require_truncate = __commonJS({
4311
4311
  "node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/truncate.js"(exports, module) {
4312
4312
  "use strict";
4313
4313
  var parse3 = require_parse();
4314
- var constants2 = require_constants();
4314
+ var constants3 = require_constants();
4315
4315
  var SemVer = require_semver();
4316
4316
  var truncate = (version2, truncation, options) => {
4317
- if (!constants2.RELEASE_TYPES.includes(truncation)) {
4317
+ if (!constants3.RELEASE_TYPES.includes(truncation)) {
4318
4318
  return null;
4319
4319
  }
4320
4320
  const clonedVersion = cloneInputVersion(version2, options);
@@ -5358,7 +5358,7 @@ var require_semver2 = __commonJS({
5358
5358
  "node_modules/.pnpm/semver@7.8.1/node_modules/semver/index.js"(exports, module) {
5359
5359
  "use strict";
5360
5360
  var internalRe = require_re();
5361
- var constants2 = require_constants();
5361
+ var constants3 = require_constants();
5362
5362
  var SemVer = require_semver();
5363
5363
  var identifiers = require_identifiers();
5364
5364
  var parse3 = require_parse();
@@ -5442,8 +5442,8 @@ var require_semver2 = __commonJS({
5442
5442
  re: internalRe.re,
5443
5443
  src: internalRe.src,
5444
5444
  tokens: internalRe.t,
5445
- SEMVER_SPEC_VERSION: constants2.SEMVER_SPEC_VERSION,
5446
- RELEASE_TYPES: constants2.RELEASE_TYPES,
5445
+ SEMVER_SPEC_VERSION: constants3.SEMVER_SPEC_VERSION,
5446
+ RELEASE_TYPES: constants3.RELEASE_TYPES,
5447
5447
  compareIdentifiers: identifiers.compareIdentifiers,
5448
5448
  rcompareIdentifiers: identifiers.rcompareIdentifiers
5449
5449
  };
@@ -8515,7 +8515,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
8515
8515
  const negativeNumberArg = (arg) => {
8516
8516
  if (!/^-(\d+|\d*\.\d+)(e[+-]?\d+)?$/.test(arg)) return false;
8517
8517
  return !this._getCommandAndAncestors().some(
8518
- (cmd) => cmd.options.map((opt) => opt.short).some((short) => /^-\d$/.test(short))
8518
+ (cmd) => cmd.options.map((opt) => opt.short).some((short2) => /^-\d$/.test(short2))
8519
8519
  );
8520
8520
  };
8521
8521
  let activeVariadicOption = null;
@@ -9483,7 +9483,7 @@ function isNodeError(value) {
9483
9483
 
9484
9484
  // src/lib/version.ts
9485
9485
  var CLI_PACKAGE_NAME = "@great-arrow/cli";
9486
- var CLI_VERSION = "0.7.2";
9486
+ var CLI_VERSION = "0.8.0";
9487
9487
  var GAD_INSTALL_VERSION = "2026.08.08";
9488
9488
  var GAD_INSTALL_MIN_VERSION = "2026.06.22";
9489
9489
  var GAD_INSTALL_HEADER = "X-GAD-Install-Version";
@@ -10056,12 +10056,12 @@ h1{font-size:1.25rem;margin:0 0 .5rem}p{color:#9a9aa3;margin:0}</style></head>
10056
10056
  <body><div class="card"><h1>${ok ? "\u2713 Signed in to Great Arrow" : "\u2717 Sign-in failed"}</h1>
10057
10057
  <p>${escapeHtml(detail)}</p></div></body></html>`;
10058
10058
  function listen(port) {
10059
- return new Promise((resolve5, reject) => {
10059
+ return new Promise((resolve7, reject) => {
10060
10060
  const server = createServer();
10061
10061
  server.on("error", reject);
10062
10062
  server.listen(port, LOOPBACK_HOST, () => {
10063
10063
  const addr = server.address();
10064
- resolve5({ server, port: addr.port });
10064
+ resolve7({ server, port: addr.port });
10065
10065
  });
10066
10066
  });
10067
10067
  }
@@ -10086,7 +10086,7 @@ async function startLoopbackServer(opts) {
10086
10086
  port,
10087
10087
  close: () => server.close(),
10088
10088
  waitForCallback({ timeoutMs = DEFAULT_TIMEOUT_MS } = {}) {
10089
- return new Promise((resolve5, reject) => {
10089
+ return new Promise((resolve7, reject) => {
10090
10090
  const timer = setTimeout(() => {
10091
10091
  server.close();
10092
10092
  reject(new Error("Timed out waiting for the browser callback."));
@@ -10126,7 +10126,7 @@ async function startLoopbackServer(opts) {
10126
10126
  "You can close this tab and return to your terminal."
10127
10127
  )
10128
10128
  );
10129
- settle2(() => resolve5({ code, state }));
10129
+ settle2(() => resolve7({ code, state }));
10130
10130
  });
10131
10131
  });
10132
10132
  }
@@ -10411,11 +10411,11 @@ async function confirm(message) {
10411
10411
  input: process.stdin,
10412
10412
  output: process.stdout
10413
10413
  });
10414
- return new Promise((resolve5) => {
10414
+ return new Promise((resolve7) => {
10415
10415
  rl.question(`${message} [y/N] `, (answer) => {
10416
10416
  rl.close();
10417
10417
  const normalized = answer.trim().toLowerCase();
10418
- resolve5(normalized === "y" || normalized === "yes");
10418
+ resolve7(normalized === "y" || normalized === "yes");
10419
10419
  });
10420
10420
  });
10421
10421
  }
@@ -10590,8 +10590,8 @@ function createFormatter(options) {
10590
10590
  var DEFAULT_API_URL = "https://www.greatarrow.ai";
10591
10591
  function isLegacyApiUrl(value) {
10592
10592
  try {
10593
- const hostname6 = new URL(value).hostname.toLowerCase();
10594
- return hostname6 === "www.greatarrowdigital.com" || hostname6 === "greatarrowdigital.com";
10593
+ const hostname7 = new URL(value).hostname.toLowerCase();
10594
+ return hostname7 === "www.greatarrowdigital.com" || hostname7 === "greatarrowdigital.com";
10595
10595
  } catch {
10596
10596
  return false;
10597
10597
  }
@@ -10611,10 +10611,10 @@ function maskToken(token) {
10611
10611
  }
10612
10612
  function openBrowser(url2) {
10613
10613
  if (!/^https?:\/\//i.test(url2)) return Promise.resolve(false);
10614
- return new Promise((resolve5) => {
10614
+ return new Promise((resolve7) => {
10615
10615
  const platform2 = process.platform;
10616
10616
  const [cmd, args] = platform2 === "darwin" ? ["open", [url2]] : platform2 === "win32" ? ["cmd", ["/c", "start", "", url2]] : ["xdg-open", [url2]];
10617
- execFile(cmd, args, (error62) => resolve5(!error62));
10617
+ execFile(cmd, args, (error62) => resolve7(!error62));
10618
10618
  });
10619
10619
  }
10620
10620
  var loginCommand = new Command("login").description("Authenticate the CLI with your Great Arrow Digital account").option(
@@ -11364,7 +11364,7 @@ function getCommandWorkspaceTarget(options = {}) {
11364
11364
 
11365
11365
  // ../local-runtime/src/abortable.ts
11366
11366
  function abortable(run4, signal) {
11367
- return new Promise((resolve5, reject) => {
11367
+ return new Promise((resolve7, reject) => {
11368
11368
  const abort = () => {
11369
11369
  signal.removeEventListener("abort", abort);
11370
11370
  reject(signal.reason ?? new Error("Local operation stopped"));
@@ -11374,7 +11374,7 @@ function abortable(run4, signal) {
11374
11374
  Promise.resolve().then(() => {
11375
11375
  signal.throwIfAborted();
11376
11376
  return run4();
11377
- }).then(resolve5, reject).finally(() => signal.removeEventListener("abort", abort));
11377
+ }).then(resolve7, reject).finally(() => signal.removeEventListener("abort", abort));
11378
11378
  });
11379
11379
  }
11380
11380
  async function withLocalDeadline(deadlineMs, run4, parentSignal) {
@@ -11634,7 +11634,7 @@ function describeError(error62) {
11634
11634
  return String(error62);
11635
11635
  }
11636
11636
  function sleep(ms) {
11637
- return new Promise((resolve5) => setTimeout(resolve5, ms));
11637
+ return new Promise((resolve7) => setTimeout(resolve7, ms));
11638
11638
  }
11639
11639
  var GadClient = class {
11640
11640
  token;
@@ -11759,11 +11759,11 @@ var GadClient = class {
11759
11759
  const status = response.status;
11760
11760
  const body = await response.text().catch(() => "");
11761
11761
  if (status === 403) {
11762
- const refusal2 = policyRefusal(body, this.apiUrl);
11763
- if (refusal2) {
11762
+ const refusal3 = policyRefusal(body, this.apiUrl);
11763
+ if (refusal3) {
11764
11764
  throw withServerCode(
11765
- new CliError(refusal2.message, 1 /* AUTH_ERROR */, refusal2.hint),
11766
- JSON.stringify({ error: refusal2.code })
11765
+ new CliError(refusal3.message, 1 /* AUTH_ERROR */, refusal3.hint),
11766
+ JSON.stringify({ error: refusal3.code })
11767
11767
  );
11768
11768
  }
11769
11769
  throw withServerCode(
@@ -11858,9 +11858,9 @@ var GadClient = class {
11858
11858
  message: data.error.message
11859
11859
  }
11860
11860
  });
11861
- const refusal2 = policyRefusal(data, this.apiUrl);
11862
- if (refusal2) {
11863
- throw new CliError(refusal2.message, 1 /* AUTH_ERROR */, refusal2.hint);
11861
+ const refusal3 = policyRefusal(data, this.apiUrl);
11862
+ if (refusal3) {
11863
+ throw new CliError(refusal3.message, 1 /* AUTH_ERROR */, refusal3.hint);
11864
11864
  }
11865
11865
  const code = data.error.code === -32001 ? 1 /* AUTH_ERROR */ : 2 /* NETWORK_ERROR */;
11866
11866
  throw new CliError(
@@ -11967,13 +11967,13 @@ var GadClient = class {
11967
11967
  if (this.getToken) {
11968
11968
  const getToken2 = this.getToken;
11969
11969
  headers.Authorization = `Bearer ${await new Promise(
11970
- (resolve5, reject) => {
11970
+ (resolve7, reject) => {
11971
11971
  signal.addEventListener(
11972
11972
  "abort",
11973
11973
  () => reject(networkError("Session renewal timed out.")),
11974
11974
  { once: true }
11975
11975
  );
11976
- getToken2().then(resolve5, reject);
11976
+ getToken2().then(resolve7, reject);
11977
11977
  }
11978
11978
  )}`;
11979
11979
  }
@@ -12192,10 +12192,10 @@ ${tryThese.map((t) => ` \u2022 ${t}`).join("\n")}`
12192
12192
 
12193
12193
  // src/lib/stdin.ts
12194
12194
  function readStream(stream) {
12195
- return new Promise((resolve5, reject) => {
12195
+ return new Promise((resolve7, reject) => {
12196
12196
  const chunks = [];
12197
12197
  stream.on("data", (chunk) => chunks.push(chunk));
12198
- stream.on("end", () => resolve5(Buffer.concat(chunks).toString("utf8")));
12198
+ stream.on("end", () => resolve7(Buffer.concat(chunks).toString("utf8")));
12199
12199
  stream.on("error", reject);
12200
12200
  });
12201
12201
  }
@@ -13130,7 +13130,7 @@ function git(args, cwd) {
13130
13130
  var WORKTREE_STATUS_CONCURRENCY = 8;
13131
13131
  var WORKTREE_STATUS_TIMEOUT_MS = 2e3;
13132
13132
  function gitAsync(args, cwd) {
13133
- return new Promise((resolve5) => {
13133
+ return new Promise((resolve7) => {
13134
13134
  execFile2(
13135
13135
  "git",
13136
13136
  args,
@@ -13141,7 +13141,7 @@ function gitAsync(args, cwd) {
13141
13141
  timeout: WORKTREE_STATUS_TIMEOUT_MS
13142
13142
  },
13143
13143
  (error62, stdout, stderr) => {
13144
- resolve5({
13144
+ resolve7({
13145
13145
  status: error62 ? 1 : 0,
13146
13146
  stdout: stdout ?? "",
13147
13147
  stderr: stderr ?? "",
@@ -16941,8 +16941,8 @@ async function runStdioBridge(options) {
16941
16941
  if (response) writeLine(response);
16942
16942
  });
16943
16943
  });
16944
- await new Promise((resolve5) => {
16945
- rl.on("close", () => resolve5());
16944
+ await new Promise((resolve7) => {
16945
+ rl.on("close", () => resolve7());
16946
16946
  });
16947
16947
  }
16948
16948
 
@@ -17065,9 +17065,9 @@ var CLIENT_IDS = {
17065
17065
  };
17066
17066
  async function mcpJsonAtRiskOfCommit(dir) {
17067
17067
  try {
17068
- const { execFile: execFile5 } = await import("node:child_process");
17068
+ const { execFile: execFile6 } = await import("node:child_process");
17069
17069
  const { promisify: promisify2 } = await import("node:util");
17070
- const run4 = promisify2(execFile5);
17070
+ const run4 = promisify2(execFile6);
17071
17071
  await run4("git", ["rev-parse", "--is-inside-work-tree"], { cwd: dir });
17072
17072
  try {
17073
17073
  await run4("git", ["check-ignore", "-q", ".mcp.json"], { cwd: dir });
@@ -17160,33 +17160,33 @@ async function pathExists(path10) {
17160
17160
  }
17161
17161
  }
17162
17162
  async function installCodexConfig(apiUrl, token, repoUrl) {
17163
- const { homedir: homedir11 } = await import("node:os");
17164
- const { join: join13 } = await import("node:path");
17165
- const { chmod: chmod4, copyFile: copyFile3, mkdir: mkdir9, readFile: readFile9, writeFile: writeFile7 } = await import("node:fs/promises");
17166
- const codexDir = join13(homedir11(), ".codex");
17167
- const configPath = join13(codexDir, "config.toml");
17168
- const envPath = join13(codexDir, ".env");
17163
+ const { homedir: homedir12 } = await import("node:os");
17164
+ const { join: join18 } = await import("node:path");
17165
+ const { chmod: chmod7, copyFile: copyFile3, mkdir: mkdir11, readFile: readFile11, writeFile: writeFile10 } = await import("node:fs/promises");
17166
+ const codexDir = join18(homedir12(), ".codex");
17167
+ const configPath = join18(codexDir, "config.toml");
17168
+ const envPath = join18(codexDir, ".env");
17169
17169
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
17170
- await mkdir9(codexDir, { recursive: true });
17171
- const existingConfig = await pathExists(configPath) ? await readFile9(configPath, "utf8") : "";
17170
+ await mkdir11(codexDir, { recursive: true });
17171
+ const existingConfig = await pathExists(configPath) ? await readFile11(configPath, "utf8") : "";
17172
17172
  if (existingConfig.trim()) {
17173
17173
  await copyFile3(configPath, `${configPath}.bak.${timestamp}`);
17174
17174
  }
17175
- await writeFile7(
17175
+ await writeFile10(
17176
17176
  configPath,
17177
17177
  upsertCodexServerBlock(existingConfig, apiUrl, repoUrl),
17178
17178
  "utf8"
17179
17179
  );
17180
- const existingEnv = await pathExists(envPath) ? await readFile9(envPath, "utf8") : "";
17180
+ const existingEnv = await pathExists(envPath) ? await readFile11(envPath, "utf8") : "";
17181
17181
  if (existingEnv.trim()) {
17182
17182
  await copyFile3(envPath, `${envPath}.bak.${timestamp}`);
17183
17183
  }
17184
- await writeFile7(
17184
+ await writeFile10(
17185
17185
  envPath,
17186
17186
  upsertEnvValue(existingEnv, "GREAT_ARROW_TOKEN", token),
17187
17187
  "utf8"
17188
17188
  );
17189
- await chmod4(envPath, 384);
17189
+ await chmod7(envPath, 384);
17190
17190
  return { configPath, envPath };
17191
17191
  }
17192
17192
  var startCommand = new Command("start").description(
@@ -17474,15 +17474,15 @@ var installCommand = new Command("install").description("Generate MCP configurat
17474
17474
  process.stdout.write(configJson2 + "\n");
17475
17475
  return;
17476
17476
  }
17477
- const { homedir: homedir11 } = await import("node:os");
17478
- const { join: join14 } = await import("node:path");
17479
- const { mkdir: mkdir9, readFile: readFile9, writeFile: writeFile8 } = await import("node:fs/promises");
17480
- const geminiDir = join14(homedir11(), ".gemini");
17481
- const mcpPath = join14(geminiDir, "settings.json");
17482
- await mkdir9(geminiDir, { recursive: true });
17477
+ const { homedir: homedir12 } = await import("node:os");
17478
+ const { join: join19 } = await import("node:path");
17479
+ const { mkdir: mkdir11, readFile: readFile11, writeFile: writeFile11 } = await import("node:fs/promises");
17480
+ const geminiDir = join19(homedir12(), ".gemini");
17481
+ const mcpPath = join19(geminiDir, "settings.json");
17482
+ await mkdir11(geminiDir, { recursive: true });
17483
17483
  let existingConfig = {};
17484
17484
  try {
17485
- const content = await readFile9(mcpPath, "utf-8");
17485
+ const content = await readFile11(mcpPath, "utf-8");
17486
17486
  existingConfig = JSON.parse(content);
17487
17487
  } catch {
17488
17488
  existingConfig = {};
@@ -17494,20 +17494,20 @@ var installCommand = new Command("install").description("Generate MCP configurat
17494
17494
  ...config3.mcpServers
17495
17495
  }
17496
17496
  };
17497
- await writeFile8(
17497
+ await writeFile11(
17498
17498
  mcpPath,
17499
17499
  JSON.stringify(existingConfig, null, 2) + "\n",
17500
17500
  "utf-8"
17501
17501
  );
17502
17502
  fmt.success(`Wrote gemini MCP config to ${mcpPath}`);
17503
- const agyMcpDir = join14(
17503
+ const agyMcpDir = join19(
17504
17504
  geminiDir,
17505
17505
  "antigravity-cli",
17506
17506
  "mcp",
17507
17507
  MCP_SERVER_NAME
17508
17508
  );
17509
- await mkdir9(agyMcpDir, { recursive: true });
17510
- const instructionsPath = join14(agyMcpDir, "instructions.md");
17509
+ await mkdir11(agyMcpDir, { recursive: true });
17510
+ const instructionsPath = join19(agyMcpDir, "instructions.md");
17511
17511
  const instructionsContent = `You are connected to greatarrow.ai - the user's private workspace memory + integrations brain.
17512
17512
 
17513
17513
  CRITICAL DIRECTIVE (MANDATORY STANDARD):
@@ -17523,7 +17523,7 @@ THREE-LAYER LIVE TASK TRACKING:
17523
17523
  - Maintain client-native harness plans, Great Arrow Kanban cards (\`todo_create\`, \`todo_update\`), and resume states.
17524
17524
 
17525
17525
  Always assume full autonomy to leverage these tools to their maximum extent.`;
17526
- await writeFile8(instructionsPath, instructionsContent, "utf-8");
17526
+ await writeFile11(instructionsPath, instructionsContent, "utf-8");
17527
17527
  fmt.success(`Wrote gemini MCP instructions to ${instructionsPath}`);
17528
17528
  return;
17529
17529
  }
@@ -17538,10 +17538,10 @@ Always assume full autonomy to leverage these tools to their maximum extent.`;
17538
17538
  process.stdout.write(configJson + "\n");
17539
17539
  return;
17540
17540
  }
17541
- const { writeFile: writeFile7 } = await import("node:fs/promises");
17542
- const { join: join13 } = await import("node:path");
17543
- const outputPath = join13(process.cwd(), ".mcp.json");
17544
- await writeFile7(outputPath, configJson + "\n", { mode: 384 });
17541
+ const { writeFile: writeFile10 } = await import("node:fs/promises");
17542
+ const { join: join18 } = await import("node:path");
17543
+ const outputPath = join18(process.cwd(), ".mcp.json");
17544
+ await writeFile10(outputPath, configJson + "\n", { mode: 384 });
17545
17545
  fmt.success(`Wrote ${clientName} MCP config to .mcp.json`);
17546
17546
  if (await mcpJsonAtRiskOfCommit(process.cwd())) {
17547
17547
  fmt.warn(
@@ -17557,9 +17557,9 @@ var KEYCHAIN_SERVICE = "GreatArrowDigital";
17557
17557
  var KEYCHAIN_ACCOUNT = "api-token";
17558
17558
  var OAUTH_CRED_FILENAME = "oauth-credential.json";
17559
17559
  async function readIfExists(path10) {
17560
- const { readFile: readFile9 } = await import("node:fs/promises");
17560
+ const { readFile: readFile11 } = await import("node:fs/promises");
17561
17561
  try {
17562
- return await readFile9(path10, "utf8");
17562
+ return await readFile11(path10, "utf8");
17563
17563
  } catch {
17564
17564
  return null;
17565
17565
  }
@@ -17574,13 +17574,13 @@ async function readKeychainOnly() {
17574
17574
  }
17575
17575
  }
17576
17576
  async function resolveProxyScript(override) {
17577
- const { homedir: homedir11 } = await import("node:os");
17578
- const { join: join13 } = await import("node:path");
17577
+ const { homedir: homedir12 } = await import("node:os");
17578
+ const { join: join18 } = await import("node:path");
17579
17579
  const candidates = [
17580
17580
  override,
17581
17581
  process.env.GAD_PROXY_SCRIPT,
17582
- join13(homedir11(), ".great-arrow", "mcp-server.mjs"),
17583
- join13(process.cwd(), "scripts", "mcp-server.mjs")
17582
+ join18(homedir12(), ".great-arrow", "mcp-server.mjs"),
17583
+ join18(process.cwd(), "scripts", "mcp-server.mjs")
17584
17584
  ].filter((c) => Boolean(c));
17585
17585
  for (const candidate of candidates) {
17586
17586
  if (await pathExists(candidate)) return candidate;
@@ -17588,9 +17588,9 @@ async function resolveProxyScript(override) {
17588
17588
  return null;
17589
17589
  }
17590
17590
  async function runProxyDiagnostics(scriptPath) {
17591
- const { execFile: execFile5 } = await import("node:child_process");
17591
+ const { execFile: execFile6 } = await import("node:child_process");
17592
17592
  const { promisify: promisify2 } = await import("node:util");
17593
- const run4 = promisify2(execFile5);
17593
+ const run4 = promisify2(execFile6);
17594
17594
  try {
17595
17595
  const { stdout } = await run4(
17596
17596
  process.execPath,
@@ -17604,21 +17604,21 @@ async function runProxyDiagnostics(scriptPath) {
17604
17604
  }
17605
17605
  }
17606
17606
  async function findLegacyStores(cwd) {
17607
- const { join: join13 } = await import("node:path");
17607
+ const { join: join18 } = await import("node:path");
17608
17608
  const { readdir } = await import("node:fs/promises");
17609
17609
  const dirs = /* @__PURE__ */ new Set([cwd]);
17610
17610
  try {
17611
- const worktreeRoot = join13(cwd, ".claude", "worktrees");
17611
+ const worktreeRoot = join18(cwd, ".claude", "worktrees");
17612
17612
  for (const entry of await readdir(worktreeRoot, { withFileTypes: true })) {
17613
- if (entry.isDirectory()) dirs.add(join13(worktreeRoot, entry.name));
17613
+ if (entry.isDirectory()) dirs.add(join18(worktreeRoot, entry.name));
17614
17614
  }
17615
17615
  } catch (err2) {
17616
17616
  debugSwallow("mcp.findLegacyStores(worktrees)", err2);
17617
17617
  }
17618
17618
  try {
17619
- const { execFile: execFile5 } = await import("node:child_process");
17619
+ const { execFile: execFile6 } = await import("node:child_process");
17620
17620
  const { promisify: promisify2 } = await import("node:util");
17621
- const run4 = promisify2(execFile5);
17621
+ const run4 = promisify2(execFile6);
17622
17622
  const { stdout } = await run4("git", ["worktree", "list", "--porcelain"], {
17623
17623
  cwd,
17624
17624
  timeout: 5e3
@@ -17632,18 +17632,18 @@ async function findLegacyStores(cwd) {
17632
17632
  }
17633
17633
  const stores = [];
17634
17634
  for (const dir of dirs) {
17635
- const path10 = join13(dir, ".mcp", OAUTH_CRED_FILENAME);
17635
+ const path10 = join18(dir, ".mcp", OAUTH_CRED_FILENAME);
17636
17636
  const raw = await readIfExists(path10);
17637
17637
  if (raw !== null) stores.push({ path: path10, raw });
17638
17638
  }
17639
17639
  return stores;
17640
17640
  }
17641
17641
  async function scanConnections() {
17642
- const { homedir: homedir11 } = await import("node:os");
17643
- const { join: join13 } = await import("node:path");
17644
- const home = homedir11();
17642
+ const { homedir: homedir12 } = await import("node:os");
17643
+ const { join: join18 } = await import("node:path");
17644
+ const home = homedir12();
17645
17645
  const hookSettings = await readIfExists(
17646
- join13(home, ".claude", "settings.json")
17646
+ join18(home, ".claude", "settings.json")
17647
17647
  );
17648
17648
  const hooksInstalled = hookSettings ? hasGreatArrowHooks(hookSettings) : false;
17649
17649
  const entries = [];
@@ -17676,19 +17676,19 @@ async function probeEndpoint() {
17676
17676
  }
17677
17677
  }
17678
17678
  async function applyMigration(plan) {
17679
- const { homedir: homedir11 } = await import("node:os");
17680
- const { join: join13 } = await import("node:path");
17681
- const { chmod: chmod4, mkdir: mkdir9, rename: rename4, unlink: unlink3, writeFile: writeFile7 } = await import("node:fs/promises");
17679
+ const { homedir: homedir12 } = await import("node:os");
17680
+ const { join: join18 } = await import("node:path");
17681
+ const { chmod: chmod7, mkdir: mkdir11, rename: rename5, unlink: unlink3, writeFile: writeFile10 } = await import("node:fs/promises");
17682
17682
  const applied = [];
17683
- const dir = join13(homedir11(), ".great-arrow");
17684
- await mkdir9(dir, { recursive: true, mode: 448 });
17685
- await chmod4(dir, 448);
17683
+ const dir = join18(homedir12(), ".great-arrow");
17684
+ await mkdir11(dir, { recursive: true, mode: 448 });
17685
+ await chmod7(dir, 448);
17686
17686
  const writeAtomic0600 = async (target, raw) => {
17687
17687
  const tmp = `${target}.tmp.${process.pid}.${Date.now()}`;
17688
17688
  try {
17689
- await writeFile7(tmp, raw, { mode: 384, flag: "wx" });
17690
- await chmod4(tmp, 384);
17691
- await rename4(tmp, target);
17689
+ await writeFile10(tmp, raw, { mode: 384, flag: "wx" });
17690
+ await chmod7(tmp, 384);
17691
+ await rename5(tmp, target);
17692
17692
  } catch (err2) {
17693
17693
  try {
17694
17694
  await unlink3(tmp);
@@ -17701,7 +17701,7 @@ async function applyMigration(plan) {
17701
17701
  if (plan.seedFrom) {
17702
17702
  const raw = await readIfExists(plan.seedFrom);
17703
17703
  if (raw !== null) {
17704
- const target = join13(dir, OAUTH_CRED_FILENAME);
17704
+ const target = join18(dir, OAUTH_CRED_FILENAME);
17705
17705
  await writeAtomic0600(target, raw);
17706
17706
  applied.push(`Copied ${plan.seedFrom} \u2192 ${target}`);
17707
17707
  }
@@ -17709,9 +17709,9 @@ async function applyMigration(plan) {
17709
17709
  if (plan.syncKeychainToFile) {
17710
17710
  const raw = await readKeychainOnly();
17711
17711
  if (raw) {
17712
- const target = join13(dir, "credential");
17712
+ const target = join18(dir, "credential");
17713
17713
  await writeAtomic0600(target, raw);
17714
- await writeAtomic0600(join13(dir, "credential.migrated"), "1");
17714
+ await writeAtomic0600(join18(dir, "credential.migrated"), "1");
17715
17715
  applied.push(`Wrote the keychain credential to ${target}`);
17716
17716
  }
17717
17717
  }
@@ -17734,23 +17734,23 @@ var doctorSubcommand = new Command("doctor").description(
17734
17734
  noColor: false
17735
17735
  });
17736
17736
  const c = createColor(jsonFlag);
17737
- const { homedir: homedir11 } = await import("node:os");
17738
- const { join: join13 } = await import("node:path");
17739
- const home = homedir11();
17737
+ const { homedir: homedir12 } = await import("node:os");
17738
+ const { join: join18 } = await import("node:path");
17739
+ const home = homedir12();
17740
17740
  const proxyPath = await resolveProxyScript(options.proxy);
17741
17741
  const diagnostics = proxyPath ? await runProxyDiagnostics(proxyPath) : null;
17742
17742
  const entries = await scanConnections();
17743
17743
  const duplicates = detectDuplicates(entries);
17744
17744
  const credentialFile = await readIfExists(
17745
- join13(home, ".great-arrow", "credential")
17745
+ join18(home, ".great-arrow", "credential")
17746
17746
  );
17747
17747
  const credentialMigrated = await readIfExists(
17748
- join13(home, ".great-arrow", "credential.migrated")
17748
+ join18(home, ".great-arrow", "credential.migrated")
17749
17749
  ) !== null;
17750
17750
  const fileAuthoritative = credentialFile?.trim() === "LOGGED_OUT" || credentialMigrated || process.platform === "darwin" && credentialFile !== null;
17751
17751
  const keychain = fileAuthoritative ? null : await readKeychainOnly();
17752
17752
  const userStore = await readIfExists(
17753
- join13(home, ".great-arrow", OAUTH_CRED_FILENAME)
17753
+ join18(home, ".great-arrow", OAUTH_CRED_FILENAME)
17754
17754
  );
17755
17755
  const legacyStores = await findLegacyStores(process.cwd());
17756
17756
  const findings = [
@@ -18127,6 +18127,10 @@ function itemLine(item) {
18127
18127
  const detail = item.detail ? stripControlChars(String(item.detail)) : "";
18128
18128
  return detail ? ` ${who} \u2014 ${detail}` : ` ${who}`;
18129
18129
  }
18130
+ function liveLines(live) {
18131
+ if (!live) return [];
18132
+ return [live.activity?.line, live.spend?.line].filter((l) => typeof l === "string" && l.length > 0).map((l) => ` ${stripControlChars(l)}`);
18133
+ }
18130
18134
  function count(n) {
18131
18135
  return typeof n === "number" && Number.isFinite(n) ? n : 0;
18132
18136
  }
@@ -18135,14 +18139,30 @@ function renderAgentsNow(payload) {
18135
18139
  const groups = (Array.isArray(safe.working) ? safe.working : []).filter(
18136
18140
  (g) => g && Array.isArray(g.items) && g.items.length > 0
18137
18141
  );
18142
+ const sessions = (Array.isArray(safe.sessions) ? safe.sessions : []).filter(
18143
+ (s2) => s2 && typeof s2.name === "string"
18144
+ );
18145
+ const byId = new Map(
18146
+ (Array.isArray(safe.agents) ? safe.agents : []).map((a) => [a?.id, a])
18147
+ );
18138
18148
  const counts = safe.counts ?? {};
18139
18149
  const lines = [];
18140
- if (groups.length === 0) {
18150
+ if (groups.length === 0 && sessions.length === 0) {
18141
18151
  lines.push("No agent is working right now.");
18142
18152
  } else {
18143
18153
  for (const g of groups) {
18144
18154
  lines.push(groupTitle(g.where, g.machine));
18145
- for (const item of g.items) lines.push(itemLine(item));
18155
+ for (const item of g.items) {
18156
+ lines.push(itemLine(item));
18157
+ if (item.connectionId)
18158
+ lines.push(...liveLines(byId.get(item.connectionId)));
18159
+ }
18160
+ lines.push("");
18161
+ }
18162
+ for (const s2 of sessions) {
18163
+ lines.push(groupTitle(s2.where, s2.machine));
18164
+ lines.push(itemLine({ who: s2.name }));
18165
+ lines.push(...liveLines(s2));
18146
18166
  lines.push("");
18147
18167
  }
18148
18168
  if (lines[lines.length - 1] === "") lines.pop();
@@ -18182,7 +18202,7 @@ function asMessage(body) {
18182
18202
  return b.status === "message" && typeof b.messageId === "string" && typeof b.block === "string" ? { messageId: b.messageId, block: b.block } : null;
18183
18203
  }
18184
18204
  async function runInboxWait(o) {
18185
- const sleep2 = o.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
18205
+ const sleep3 = o.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
18186
18206
  const now = o.now ?? Date.now;
18187
18207
  const write = o.write ?? ((t) => void process.stdout.write(t));
18188
18208
  const writeErr = o.writeErr ?? ((t) => void process.stderr.write(t));
@@ -18212,7 +18232,7 @@ async function runInboxWait(o) {
18212
18232
  return 0;
18213
18233
  }
18214
18234
  const gap = Math.min(waitBackoffMs(emptyHolds++), stopAt - now());
18215
- if (gap > 0) await sleep2(gap);
18235
+ if (gap > 0) await sleep3(gap);
18216
18236
  }
18217
18237
  return 3;
18218
18238
  }
@@ -19124,10 +19144,10 @@ async function exclusive(slot, action) {
19124
19144
  const controller = new AbortController();
19125
19145
  let timer;
19126
19146
  const operation = Promise.resolve().then(() => action(controller.signal));
19127
- const release = () => {
19147
+ const release2 = () => {
19128
19148
  if (!controller.signal.aborted) busy.delete(slot);
19129
19149
  };
19130
- void operation.then(release, release);
19150
+ void operation.then(release2, release2);
19131
19151
  const timeout2 = new Promise((_resolve, reject) => {
19132
19152
  timer = setTimeout(() => {
19133
19153
  controller.abort();
@@ -22047,8 +22067,8 @@ function emoji() {
22047
22067
  }
22048
22068
  var ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
22049
22069
  var ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
22050
- var mac = (delimiter) => {
22051
- const escapedDelim = escapeRegex(delimiter ?? ":");
22070
+ var mac = (delimiter2) => {
22071
+ const escapedDelim = escapeRegex(delimiter2 ?? ":");
22052
22072
  return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
22053
22073
  };
22054
22074
  var cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
@@ -22863,9 +22883,9 @@ var asciiTabOrNewline = /[\t\n\r]/g;
22863
22883
  function stripTabAndNewline(value) {
22864
22884
  return value.replace(asciiTabOrNewline, "");
22865
22885
  }
22866
- function urlHostnameOk(url2, hostname6) {
22867
- hostname6.lastIndex = 0;
22868
- return hostname6.test(url2.hostname);
22886
+ function urlHostnameOk(url2, hostname7) {
22887
+ hostname7.lastIndex = 0;
22888
+ return hostname7.test(url2.hostname);
22869
22889
  }
22870
22890
  function urlProtocolOk(url2, protocol) {
22871
22891
  protocol.lastIndex = 0;
@@ -25104,7 +25124,7 @@ var recursive = /* @__PURE__ */ new WeakMap();
25104
25124
  var NONE = 0;
25105
25125
  var ASSUMED = 1;
25106
25126
  var PROVEN = 2;
25107
- function isRecursive(inst, stack, resolve5) {
25127
+ function isRecursive(inst, stack, resolve7) {
25108
25128
  const cached2 = recursive.get(inst);
25109
25129
  if (cached2 !== void 0)
25110
25130
  return cached2 ? PROVEN : NONE;
@@ -25114,7 +25134,7 @@ function isRecursive(inst, stack, resolve5) {
25114
25134
  let result = NONE;
25115
25135
  const check2 = (child) => {
25116
25136
  if (result !== PROVEN && child?._zod) {
25117
- const answer = isRecursive(child, stack, resolve5);
25137
+ const answer = isRecursive(child, stack, resolve7);
25118
25138
  if (answer > result)
25119
25139
  result = answer;
25120
25140
  }
@@ -25125,7 +25145,7 @@ function isRecursive(inst, stack, resolve5) {
25125
25145
  const desc = Object.getOwnPropertyDescriptor(sh, key);
25126
25146
  if (spread && !desc.enumerable)
25127
25147
  continue;
25128
- const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve5) : NONE;
25148
+ const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve7) : NONE;
25129
25149
  if (child > answer)
25130
25150
  answer = child;
25131
25151
  }
@@ -25189,7 +25209,7 @@ function isRecursive(inst, stack, resolve5) {
25189
25209
  break;
25190
25210
  // `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
25191
25211
  case "lazy": {
25192
- const inner = def._cachedInner ?? (resolve5 ? inst._zod.innerType : void 0);
25212
+ const inner = def._cachedInner ?? (resolve7 ? inst._zod.innerType : void 0);
25193
25213
  merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
25194
25214
  break;
25195
25215
  }
@@ -43911,34 +43931,34 @@ function validateDownloadUrl(url2) {
43911
43931
  message: `URL scheme must be http, https, or data, got ${parsed.protocol}`
43912
43932
  });
43913
43933
  }
43914
- const hostname6 = parsed.hostname.toLowerCase().replace(/\.+$/, "");
43915
- if (!hostname6) {
43934
+ const hostname7 = parsed.hostname.toLowerCase().replace(/\.+$/, "");
43935
+ if (!hostname7) {
43916
43936
  throw new DownloadError({
43917
43937
  url: url2,
43918
43938
  message: `URL must have a hostname`
43919
43939
  });
43920
43940
  }
43921
- if (hostname6 === "localhost" || hostname6.endsWith(".local") || hostname6.endsWith(".localhost") || hostname6.endsWith(".internal")) {
43941
+ if (hostname7 === "localhost" || hostname7.endsWith(".local") || hostname7.endsWith(".localhost") || hostname7.endsWith(".internal")) {
43922
43942
  throw new DownloadError({
43923
43943
  url: url2,
43924
- message: `URL with hostname ${hostname6} is not allowed`
43944
+ message: `URL with hostname ${hostname7} is not allowed`
43925
43945
  });
43926
43946
  }
43927
- if (hostname6.startsWith("[") && hostname6.endsWith("]")) {
43928
- const ipv63 = hostname6.slice(1, -1);
43947
+ if (hostname7.startsWith("[") && hostname7.endsWith("]")) {
43948
+ const ipv63 = hostname7.slice(1, -1);
43929
43949
  if (isPrivateIPv6(ipv63)) {
43930
43950
  throw new DownloadError({
43931
43951
  url: url2,
43932
- message: `URL with IPv6 address ${hostname6} is not allowed`
43952
+ message: `URL with IPv6 address ${hostname7} is not allowed`
43933
43953
  });
43934
43954
  }
43935
43955
  return;
43936
43956
  }
43937
- if (isIPv4(hostname6)) {
43938
- if (isPrivateIPv4(hostname6)) {
43957
+ if (isIPv4(hostname7)) {
43958
+ if (isPrivateIPv4(hostname7)) {
43939
43959
  throw new DownloadError({
43940
43960
  url: url2,
43941
- message: `URL with IP address ${hostname6} is not allowed`
43961
+ message: `URL with IP address ${hostname7} is not allowed`
43942
43962
  });
43943
43963
  }
43944
43964
  }
@@ -43946,18 +43966,18 @@ function validateDownloadUrl(url2) {
43946
43966
  function validateDownloadAddress({
43947
43967
  address,
43948
43968
  family,
43949
- hostname: hostname6
43969
+ hostname: hostname7
43950
43970
  }) {
43951
43971
  const isUnsafe = family === 4 ? !isIPv4(address) || isPrivateIPv4(address) : family === 6 ? isPrivateIPv6(address) : true;
43952
43972
  if (isUnsafe) {
43953
43973
  throw new DownloadError({
43954
- url: hostname6,
43955
- message: `Hostname ${hostname6} resolved to disallowed IP address ${address}`
43974
+ url: hostname7,
43975
+ message: `Hostname ${hostname7} resolved to disallowed IP address ${address}`
43956
43976
  });
43957
43977
  }
43958
43978
  }
43959
- function isIPv4(hostname6) {
43960
- const parts = hostname6.split(".");
43979
+ function isIPv4(hostname7) {
43980
+ const parts = hostname7.split(".");
43961
43981
  if (parts.length !== 4) return false;
43962
43982
  return parts.every((part) => {
43963
43983
  const num = Number(part);
@@ -44042,8 +44062,8 @@ function isPrivateIPv6(ip) {
44042
44062
  return false;
44043
44063
  }
44044
44064
  function createSafeLookup(lookup) {
44045
- return ((hostname6, options, callback) => {
44046
- lookup(hostname6, { ...options, all: true }, (error62, addresses) => {
44065
+ return ((hostname7, options, callback) => {
44066
+ lookup(hostname7, { ...options, all: true }, (error62, addresses) => {
44047
44067
  if (error62) {
44048
44068
  callback(error62);
44049
44069
  return;
@@ -44051,10 +44071,10 @@ function createSafeLookup(lookup) {
44051
44071
  try {
44052
44072
  const [firstAddress] = addresses;
44053
44073
  if (firstAddress == null) {
44054
- throw new Error(`Hostname ${hostname6} did not resolve to an address`);
44074
+ throw new Error(`Hostname ${hostname7} did not resolve to an address`);
44055
44075
  }
44056
44076
  for (const { address, family } of addresses) {
44057
- validateDownloadAddress({ address, family, hostname: hostname6 });
44077
+ validateDownloadAddress({ address, family, hostname: hostname7 });
44058
44078
  }
44059
44079
  if (options.all === true) {
44060
44080
  callback(null, addresses);
@@ -48199,7 +48219,7 @@ async function readCloudConversationReply(options) {
48199
48219
  let bytes = 0;
48200
48220
  let lineBytes = 0;
48201
48221
  let released = false;
48202
- const release = () => {
48222
+ const release2 = () => {
48203
48223
  if (!released) {
48204
48224
  released = true;
48205
48225
  source.releaseLock();
@@ -48208,14 +48228,14 @@ async function readCloudConversationReply(options) {
48208
48228
  const cancel = () => {
48209
48229
  if (released) return;
48210
48230
  void source.cancel().catch((error62) => logger.warn(error62));
48211
- release();
48231
+ release2();
48212
48232
  };
48213
48233
  const bounded3 = new ReadableStream({
48214
48234
  async pull(controller) {
48215
48235
  try {
48216
48236
  const chunk = await abortable(() => source.read(), signal);
48217
48237
  if (chunk.done) {
48218
- release();
48238
+ release2();
48219
48239
  controller.close();
48220
48240
  return;
48221
48241
  }
@@ -48362,9 +48382,9 @@ function platformFetch(apiUrl, transport, engineFetch) {
48362
48382
  if (input2 instanceof Request)
48363
48383
  throw new Error("Local turn transport requires an explicit request path");
48364
48384
  const raw = String(input2);
48365
- const relative2 = raw.startsWith("/");
48385
+ const relative3 = raw.startsWith("/");
48366
48386
  const target = new URL(raw, platform2);
48367
- if (!relative2 && target.origin !== platform2.origin)
48387
+ if (!relative3 && target.origin !== platform2.origin)
48368
48388
  return engineFetch(input2, init);
48369
48389
  if (target.origin !== platform2.origin || !target.pathname.startsWith("/api/") || target.username || target.password || target.hash)
48370
48390
  throw new Error("Local turn requests must use a platform API path");
@@ -48835,11 +48855,11 @@ function origin(apiUrl) {
48835
48855
  function appAwareFetch(apiUrl, token, base, getToken2) {
48836
48856
  return async (input2, init) => {
48837
48857
  const target = typeof input2 === "string" ? input2 : String(input2);
48838
- const relative2 = target.startsWith("/") && !target.startsWith("//");
48839
- if (!relative2 && !target.startsWith(`${origin(apiUrl)}/`))
48858
+ const relative3 = target.startsWith("/") && !target.startsWith("//");
48859
+ if (!relative3 && !target.startsWith(`${origin(apiUrl)}/`))
48840
48860
  return base(input2, init);
48841
48861
  const currentToken = getToken2 ? await renewToken(getToken2) : token;
48842
- return base(relative2 ? `${origin(apiUrl)}${target}` : target, {
48862
+ return base(relative3 ? `${origin(apiUrl)}${target}` : target, {
48843
48863
  ...init,
48844
48864
  headers: {
48845
48865
  ...init?.headers,
@@ -50052,8 +50072,8 @@ function browserLaunchCommand(url2, platform2 = process.platform) {
50052
50072
  function openBrowser2(url2) {
50053
50073
  const command = browserLaunchCommand(url2);
50054
50074
  if (!command) return Promise.resolve(false);
50055
- return new Promise((resolve5) => {
50056
- execFile3(command.file, command.args, (error62) => resolve5(!error62));
50075
+ return new Promise((resolve7) => {
50076
+ execFile3(command.file, command.args, (error62) => resolve7(!error62));
50057
50077
  });
50058
50078
  }
50059
50079
  function toSurfaceRow(value) {
@@ -50311,6 +50331,1312 @@ function callCommand() {
50311
50331
  });
50312
50332
  }
50313
50333
 
50334
+ // src/lib/runner/approval.ts
50335
+ import { createHash as createHash6 } from "node:crypto";
50336
+ import { chmod as chmod4, mkdir as mkdir9, readFile as readFile8, rename as rename3, writeFile as writeFile7 } from "node:fs/promises";
50337
+ import { join as join14 } from "node:path";
50338
+
50339
+ // src/lib/runner/repo.ts
50340
+ import { chmod as chmod3, mkdir as mkdir8, realpath as realpath2, writeFile as writeFile6 } from "node:fs/promises";
50341
+ import { homedir as homedir10 } from "node:os";
50342
+ import { isAbsolute as isAbsolute3, join as join13, relative, resolve as resolve5 } from "node:path";
50343
+
50344
+ // src/lib/runner/git.ts
50345
+ import { execFile as execFile4 } from "node:child_process";
50346
+ var GIT_DEADLINE_MS = 12e4;
50347
+ var REDIRECT_ENV = /* @__PURE__ */ new Set([
50348
+ "GIT_DIR",
50349
+ "GIT_WORK_TREE",
50350
+ "GIT_INDEX_FILE",
50351
+ "GIT_COMMON_DIR",
50352
+ "GIT_OBJECT_DIRECTORY",
50353
+ "GIT_ALTERNATE_OBJECT_DIRECTORIES",
50354
+ "GIT_CONFIG",
50355
+ "GIT_CONFIG_PARAMETERS",
50356
+ "GIT_CONFIG_COUNT",
50357
+ "GIT_CEILING_DIRECTORIES"
50358
+ ]);
50359
+ function gitEnv() {
50360
+ const env4 = {};
50361
+ for (const [name23, value] of Object.entries(process.env)) {
50362
+ if (REDIRECT_ENV.has(name23) || /^GIT_CONFIG_(KEY|VALUE)_/.test(name23))
50363
+ continue;
50364
+ env4[name23] = value;
50365
+ }
50366
+ env4.GIT_TERMINAL_PROMPT = "0";
50367
+ return env4;
50368
+ }
50369
+ function safeGit(cwd, args, opts = {}) {
50370
+ const argv = [
50371
+ "-c",
50372
+ "core.hooksPath=/dev/null",
50373
+ "-c",
50374
+ "core.fsmonitor=false",
50375
+ ...args
50376
+ ];
50377
+ return new Promise((resolve7) => {
50378
+ execFile4(
50379
+ "git",
50380
+ argv,
50381
+ {
50382
+ cwd,
50383
+ env: gitEnv(),
50384
+ timeout: opts.timeoutMs ?? GIT_DEADLINE_MS,
50385
+ killSignal: "SIGKILL",
50386
+ maxBuffer: 16 * 1024 * 1024,
50387
+ ...opts.signal ? { signal: opts.signal } : {}
50388
+ },
50389
+ (error62, stdout, stderr) => {
50390
+ const status = error62?.code;
50391
+ const code = !error62 ? 0 : typeof status === "number" ? status : 1;
50392
+ resolve7({ code, stdout: String(stdout), stderr: String(stderr) });
50393
+ }
50394
+ );
50395
+ });
50396
+ }
50397
+ function worktreeGit(layout, args, opts = {}) {
50398
+ return safeGit(
50399
+ layout.worktree,
50400
+ [
50401
+ `--git-dir=${layout.worktreeGitDir}`,
50402
+ `--work-tree=${layout.worktree}`,
50403
+ ...args
50404
+ ],
50405
+ opts
50406
+ );
50407
+ }
50408
+
50409
+ // src/lib/runner/text.ts
50410
+ function cleanLine(text3) {
50411
+ return text3.replace(/[\u0000-\u001f\u007f-\u009f]+/g, " ").trim();
50412
+ }
50413
+ function cleanText(text3) {
50414
+ return text3.replace(/\r\n?/g, "\n").replace(/\t/g, " ").replace(/[\u0000-\u0009\u000b-\u001f\u007f-\u009f]+/g, " ");
50415
+ }
50416
+ var PREVIEW_LINES = 3;
50417
+ var PREVIEW_CHARS = 240;
50418
+ function preview(text3) {
50419
+ const lines = cleanText(text3).split("\n").map((l) => l.trimEnd()).filter((l) => l.trim() !== "");
50420
+ const out2 = [];
50421
+ let used = 0;
50422
+ for (const line of lines) {
50423
+ if (out2.length === PREVIEW_LINES) {
50424
+ out2[out2.length - 1] = `${out2[out2.length - 1]} \u2026`;
50425
+ break;
50426
+ }
50427
+ const room = PREVIEW_CHARS - used;
50428
+ if (line.length > room) {
50429
+ out2.push(`${line.slice(0, Math.max(room - 1, 0))}\u2026`);
50430
+ break;
50431
+ }
50432
+ out2.push(line);
50433
+ used += line.length;
50434
+ }
50435
+ return out2;
50436
+ }
50437
+
50438
+ // src/lib/runner/sandbox.ts
50439
+ import { lstat, readFile as readFile7, realpath } from "node:fs/promises";
50440
+ import { dirname as dirname8, join as join12, resolve as resolve4 } from "node:path";
50441
+ var TASK_FILE = ".gad/task.md";
50442
+ var CLAUDE_ALLOWED_DOMAINS = [
50443
+ "api.anthropic.com",
50444
+ "www.greatarrow.ai",
50445
+ "registry.npmjs.org",
50446
+ "registry.yarnpkg.com",
50447
+ "pypi.org",
50448
+ "files.pythonhosted.org",
50449
+ "crates.io",
50450
+ "index.crates.io",
50451
+ "static.crates.io"
50452
+ ];
50453
+ var DENY_RULES = [
50454
+ "Bash(git push)",
50455
+ "Bash(git push:*)",
50456
+ "Bash(git remote:*)",
50457
+ "Bash(git config:*)",
50458
+ "Bash(gh:*)",
50459
+ "Bash(gh)"
50460
+ ];
50461
+ var CREDENTIAL_ENV = [
50462
+ "GH_TOKEN",
50463
+ "GITHUB_TOKEN",
50464
+ "GH_ENTERPRISE_TOKEN",
50465
+ "GITHUB_ENTERPRISE_TOKEN",
50466
+ "GITLAB_TOKEN",
50467
+ "SSH_AUTH_SOCK",
50468
+ "SSH_ASKPASS",
50469
+ "GIT_ASKPASS",
50470
+ "GIT_SSH",
50471
+ "GIT_SSH_COMMAND",
50472
+ "GIT_CONFIG_PARAMETERS",
50473
+ "GIT_CREDENTIAL_HELPER"
50474
+ ];
50475
+ var HOME_DENY = [
50476
+ ".gitconfig",
50477
+ ".config",
50478
+ ".ssh",
50479
+ ".aws",
50480
+ ".gnupg",
50481
+ ".zshrc",
50482
+ ".zshenv",
50483
+ ".zprofile",
50484
+ ".zlogin",
50485
+ ".bashrc",
50486
+ ".bash_profile",
50487
+ ".bash_login",
50488
+ ".profile",
50489
+ ".netrc",
50490
+ ".git-credentials",
50491
+ "Library",
50492
+ ".docker"
50493
+ ];
50494
+ var CLI_CREDENTIAL_ENV = [
50495
+ "GIT_CONFIG_COUNT",
50496
+ "GIT_DIR",
50497
+ "GIT_WORK_TREE",
50498
+ "GIT_INDEX_FILE",
50499
+ "NPM_TOKEN",
50500
+ "NODE_AUTH_TOKEN",
50501
+ "AWS_ACCESS_KEY_ID",
50502
+ "AWS_SECRET_ACCESS_KEY",
50503
+ "AWS_SESSION_TOKEN",
50504
+ "GOOGLE_APPLICATION_CREDENTIALS",
50505
+ "VERCEL_TOKEN",
50506
+ "SUPABASE_ACCESS_TOKEN",
50507
+ "OP_SERVICE_ACCOUNT_TOKEN"
50508
+ ];
50509
+ var CLI_CREDENTIAL_ENV_PREFIXES = [
50510
+ "GAD_",
50511
+ "GREAT_ARROW_",
50512
+ "GIT_CONFIG_KEY_",
50513
+ "GIT_CONFIG_VALUE_",
50514
+ "AZURE_",
50515
+ "OP_SESSION_"
50516
+ ];
50517
+ var CLI_HARDENING = [".git"];
50518
+ var CLI_READ_HARDENING = [
50519
+ ".gadrc",
50520
+ ".great-arrow",
50521
+ ".claude.json",
50522
+ ".claude/.credentials.json",
50523
+ ".codex/auth.json",
50524
+ ".npmrc",
50525
+ ".config/configstore",
50526
+ ".config/gh",
50527
+ ".netrc",
50528
+ ".git-credentials",
50529
+ ".ssh",
50530
+ ".gnupg",
50531
+ ".config/gcloud",
50532
+ ".aws",
50533
+ ".azure",
50534
+ ".kube",
50535
+ ".docker/config.json",
50536
+ ".config/op",
50537
+ ".config/1Password",
50538
+ ".pypirc",
50539
+ ".cargo/credentials.toml",
50540
+ ".terraform.d/credentials.tfrc.json"
50541
+ ];
50542
+ function approvalFile(layout) {
50543
+ return join12(dirname8(dirname8(layout.worktree)), "approved.json");
50544
+ }
50545
+ function denyRead(layout) {
50546
+ return [
50547
+ ...CLI_READ_HARDENING.map((rel) => join12(layout.home, rel)),
50548
+ approvalFile(layout)
50549
+ ];
50550
+ }
50551
+ var CREDENTIAL_SET = new Set(
50552
+ [...CREDENTIAL_ENV, ...CLI_CREDENTIAL_ENV].map((n) => n.toLowerCase())
50553
+ );
50554
+ function isCredentialEnv(name23) {
50555
+ const lower = name23.toLowerCase();
50556
+ return CREDENTIAL_SET.has(lower) || CLI_CREDENTIAL_ENV_PREFIXES.some(
50557
+ (prefix) => lower.startsWith(prefix.toLowerCase())
50558
+ );
50559
+ }
50560
+ function stripCredentialEnv(env4) {
50561
+ const out2 = {};
50562
+ for (const [name23, value] of Object.entries(env4)) {
50563
+ if (!isCredentialEnv(name23)) out2[name23] = value;
50564
+ }
50565
+ return out2;
50566
+ }
50567
+ function arrowdeckCommitWrites(layout) {
50568
+ const wt = layout.worktreeGitDir;
50569
+ return [
50570
+ { path: join12(layout.commonDir, "objects"), dir: true },
50571
+ { path: join12(layout.commonDir, "refs"), dir: true },
50572
+ { path: join12(layout.commonDir, "logs"), dir: true },
50573
+ { path: join12(wt, "HEAD"), dir: false },
50574
+ { path: join12(wt, "HEAD.lock"), dir: false },
50575
+ { path: join12(wt, "index"), dir: false },
50576
+ { path: join12(wt, "index.lock"), dir: false },
50577
+ { path: join12(wt, "logs"), dir: true },
50578
+ { path: join12(wt, "ORIG_HEAD"), dir: false },
50579
+ { path: join12(wt, "COMMIT_EDITMSG"), dir: false },
50580
+ { path: join12(wt, "AUTO_MERGE"), dir: false }
50581
+ ];
50582
+ }
50583
+ function allowWrite(layout) {
50584
+ return [layout.worktree];
50585
+ }
50586
+ function denyWrite(layout) {
50587
+ return [
50588
+ join12(layout.commonDir, "hooks"),
50589
+ join12(layout.commonDir, "config"),
50590
+ join12(layout.commonDir, "info"),
50591
+ join12(layout.commonDir, "modules"),
50592
+ join12(layout.commonDir, "packed-refs"),
50593
+ join12(layout.worktreeGitDir, "config.worktree"),
50594
+ join12(layout.worktreeGitDir, "commondir"),
50595
+ join12(layout.worktreeGitDir, "gitdir"),
50596
+ layout.hooksDir,
50597
+ ...HOME_DENY.map((rel) => join12(layout.home, rel)),
50598
+ ...CLI_HARDENING.map((rel) => join12(layout.worktree, rel)),
50599
+ ...arrowdeckCommitWrites(layout).map((w) => w.path)
50600
+ ];
50601
+ }
50602
+ function claudeSettings(layout) {
50603
+ const deny = denyWrite(layout);
50604
+ const unreadable = denyRead(layout);
50605
+ const rules = [...DENY_RULES];
50606
+ for (const path10 of deny) {
50607
+ rules.push(`Edit(/${path10}/**)`);
50608
+ rules.push(`Edit(/${path10})`);
50609
+ }
50610
+ for (const path10 of unreadable) {
50611
+ rules.push(`Read(/${path10}/**)`);
50612
+ rules.push(`Read(/${path10})`);
50613
+ }
50614
+ return JSON.stringify(
50615
+ {
50616
+ permissions: { defaultMode: "acceptEdits", deny: rules },
50617
+ sandbox: {
50618
+ allowUnsandboxedCommands: false,
50619
+ autoAllowBashIfSandboxed: true,
50620
+ enabled: true,
50621
+ failIfUnavailable: true,
50622
+ filesystem: {
50623
+ allowWrite: allowWrite(layout),
50624
+ denyRead: unreadable,
50625
+ denyWrite: deny
50626
+ },
50627
+ network: { allowedDomains: [...CLAUDE_ALLOWED_DOMAINS] }
50628
+ }
50629
+ },
50630
+ null,
50631
+ 2
50632
+ );
50633
+ }
50634
+ var CLAUDE_NO_MCP = [
50635
+ "--strict-mcp-config",
50636
+ "--mcp-config",
50637
+ '{"mcpServers":{}}'
50638
+ ];
50639
+ function claudeArgs(settingsPath) {
50640
+ return [
50641
+ "--settings",
50642
+ settingsPath,
50643
+ "--permission-mode",
50644
+ "acceptEdits",
50645
+ ...CLAUDE_NO_MCP
50646
+ ];
50647
+ }
50648
+ var CODEX_PROFILE = "gad_runner";
50649
+ function codexArgs(layout) {
50650
+ const filesystem = [
50651
+ ...denyRead(layout).map((p) => `${JSON.stringify(p)}="none"`),
50652
+ ...CLI_HARDENING.map(
50653
+ (rel) => `${JSON.stringify(join12(layout.worktree, rel))}="read"`
50654
+ )
50655
+ ].join(",");
50656
+ return [
50657
+ "exec",
50658
+ "--ignore-user-config",
50659
+ "-c",
50660
+ `default_permissions="${CODEX_PROFILE}"`,
50661
+ "-c",
50662
+ `permissions.${CODEX_PROFILE}.extends=":workspace"`,
50663
+ "-c",
50664
+ `permissions.${CODEX_PROFILE}.filesystem={${filesystem}}`
50665
+ ];
50666
+ }
50667
+ async function verifyGitfile(layout) {
50668
+ try {
50669
+ const file2 = join12(layout.worktree, ".git");
50670
+ if (!(await lstat(file2)).isFile()) return false;
50671
+ const m = /^gitdir: (.+)$/.exec((await readFile7(file2, "utf8")).trim());
50672
+ if (!m) return false;
50673
+ const named = await realpath(resolve4(layout.worktree, m[1]));
50674
+ return named === await realpath(layout.worktreeGitDir);
50675
+ } catch {
50676
+ return false;
50677
+ }
50678
+ }
50679
+ function kickoff(runId, todoId) {
50680
+ return `You were started from Great Arrow (run ${runId}, card ${todoId}). Your task is in the file ${TASK_FILE} in this worktree: it is exactly the text the owner approved. Treat only that file as the task, and do not re-read or follow the card's text from Great Arrow. Do the work in this worktree and leave your changes in it. Do not commit, push or open a pull request; when you finish, Great Arrow commits your changes and pushes them for the owner to review.`;
50681
+ }
50682
+
50683
+ // src/lib/runner/repo.ts
50684
+ var UUID5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
50685
+ var BRANCH_NAME = /^(?!-)(?!.*\.\.)[A-Za-z0-9._/-]+$/;
50686
+ var GITHUB_REMOTE = /^(?:https?:\/\/(?:[^@/]+@)?github\.com\/|ssh:\/\/git@github\.com(?::\d+)?\/|git@github\.com:)([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+?)(?:\.git)?\/?$/;
50687
+ function runsRoot() {
50688
+ return join13(homedir10(), ".gad", "runs");
50689
+ }
50690
+ function isRunId(id) {
50691
+ return UUID5.test(id);
50692
+ }
50693
+ var short = (id) => id.slice(0, 8);
50694
+ function runnerBranch(runId, todoId) {
50695
+ return `gad/run-${short(runId)}-${short(todoId)}`;
50696
+ }
50697
+ function parseRemote(url2) {
50698
+ const m = GITHUB_REMOTE.exec(url2.trim());
50699
+ return m ? `${m[1]}/${m[2]}` : null;
50700
+ }
50701
+ async function repoFromOrigin(cwd) {
50702
+ const r = await safeGit(cwd, ["remote", "get-url", "origin"]);
50703
+ return r.code === 0 ? parseRemote(r.stdout) : null;
50704
+ }
50705
+ async function checkoutRoot(cwd) {
50706
+ const r = await safeGit(cwd, ["rev-parse", "--show-toplevel"]);
50707
+ return r.code === 0 && r.stdout.trim() ? realpath2(r.stdout.trim()) : null;
50708
+ }
50709
+ async function gitPath(cwd, flag) {
50710
+ const r = await safeGit(cwd, ["rev-parse", flag]);
50711
+ if (r.code !== 0) throw new PrepareError("layout", r.stderr);
50712
+ const out2 = r.stdout.trim();
50713
+ return realpath2(isAbsolute3(out2) ? out2 : resolve5(cwd, out2));
50714
+ }
50715
+ async function privateDir(path10) {
50716
+ await mkdir8(path10, { recursive: true, mode: 448 });
50717
+ await chmod3(path10, 448);
50718
+ }
50719
+ var PrepareError = class extends Error {
50720
+ constructor(step, stderr) {
50721
+ const first = cleanLine(stderr.split("\n").find((l) => l.trim()) ?? "");
50722
+ super(first ? `${step}: ${first.slice(0, 200)}` : step);
50723
+ this.step = step;
50724
+ this.name = "PrepareError";
50725
+ this.gitLine = first.slice(0, 200);
50726
+ }
50727
+ step;
50728
+ gitLine;
50729
+ };
50730
+ function hooksPathSetting(stdout) {
50731
+ const own2 = stdout.split("\n").filter((l) => l.trim() && !l.startsWith("command ")).pop();
50732
+ return own2 ? own2.slice(own2.indexOf(" ") + 1).trim() : null;
50733
+ }
50734
+ async function resolveHooksPath(raw, base) {
50735
+ const path10 = raw.startsWith("~/") ? join13(homedir10(), raw.slice(2)) : raw;
50736
+ const abs = isAbsolute3(path10) ? path10 : resolve5(base, path10);
50737
+ return realpath2(abs).catch(() => abs);
50738
+ }
50739
+ var readHooksPath = (cwd) => safeGit(cwd, ["config", "--show-scope", "--get-all", "core.hooksPath"]);
50740
+ async function configuredHooksDir(worktree, commonDir) {
50741
+ const raw = hooksPathSetting((await readHooksPath(worktree)).stdout);
50742
+ return raw ? resolveHooksPath(raw, worktree) : join13(commonDir, "hooks");
50743
+ }
50744
+ async function repoHooksDir(root) {
50745
+ const raw = hooksPathSetting((await readHooksPath(root)).stdout);
50746
+ if (!raw) return null;
50747
+ const abs = await resolveHooksPath(raw, root);
50748
+ const rel = relative(root, abs);
50749
+ return rel && !rel.startsWith("..") && !isAbsolute3(rel) ? rel : null;
50750
+ }
50751
+ async function prepareWorktree(input2) {
50752
+ const { repoRoot, runId, todoId, base, text: text3 } = input2;
50753
+ if (!isRunId(runId) || !isRunId(todoId))
50754
+ throw new Error("run and card ids must be UUIDs");
50755
+ if (!BRANCH_NAME.test(base)) throw new Error(`bad base branch: ${base}`);
50756
+ const runDir = join13(input2.runsDir ?? runsRoot(), runId);
50757
+ await privateDir(runDir);
50758
+ await privateDir(join13(runDir, "wt"));
50759
+ const path10 = join13(runDir, "wt", short(todoId));
50760
+ const branch = runnerBranch(runId, todoId);
50761
+ const fetch2 = await safeGit(repoRoot, [
50762
+ "fetch",
50763
+ "--no-tags",
50764
+ "origin",
50765
+ `+refs/heads/${base}:refs/remotes/origin/${base}`
50766
+ ]);
50767
+ if (fetch2.code !== 0) throw new PrepareError("fetch", fetch2.stderr);
50768
+ const add = await safeGit(repoRoot, [
50769
+ "worktree",
50770
+ "add",
50771
+ "--no-track",
50772
+ "-b",
50773
+ branch,
50774
+ path10,
50775
+ `refs/remotes/origin/${base}`
50776
+ ]);
50777
+ if (add.code !== 0) throw new PrepareError("worktree", add.stderr);
50778
+ const worktree = await realpath2(path10);
50779
+ const commonDir = await gitPath(worktree, "--git-common-dir");
50780
+ const layout = {
50781
+ worktree,
50782
+ commonDir,
50783
+ worktreeGitDir: await gitPath(worktree, "--absolute-git-dir"),
50784
+ home: homedir10(),
50785
+ hooksDir: await configuredHooksDir(worktree, commonDir),
50786
+ branch
50787
+ };
50788
+ const gad = join13(worktree, ".gad");
50789
+ await privateDir(gad);
50790
+ await writeFile6(join13(gad, ".gitignore"), "*\n", { mode: 384 });
50791
+ const task = join13(worktree, TASK_FILE);
50792
+ await writeFile6(task, text3, { mode: 384 });
50793
+ await chmod3(task, 384);
50794
+ return layout;
50795
+ }
50796
+
50797
+ // src/lib/runner/approval.ts
50798
+ function sha256(text3) {
50799
+ return createHash6("sha256").update(text3, "utf8").digest("hex");
50800
+ }
50801
+ var plainTitle = cleanLine;
50802
+ function approvedFile(runsDir, runId) {
50803
+ if (!isRunId(runId)) throw new Error("run id must be a UUID");
50804
+ return join14(runsDir, runId, "approved.json");
50805
+ }
50806
+ function approveShown(cards) {
50807
+ return new Map(
50808
+ cards.map((c) => [
50809
+ c.todoId,
50810
+ { title: plainTitle(c.title), text: c.text, sha: sha256(c.text) }
50811
+ ])
50812
+ );
50813
+ }
50814
+ async function saveApproved(runsDir, runId, approved) {
50815
+ const file2 = approvedFile(runsDir, runId);
50816
+ const dir = join14(runsDir, runId);
50817
+ await mkdir9(dir, { recursive: true, mode: 448 });
50818
+ await chmod4(runsDir, 448);
50819
+ await chmod4(dir, 448);
50820
+ const body = [...approved].map(([todoId, c]) => ({ todoId, ...c }));
50821
+ const tmp = `${file2}.tmp`;
50822
+ await writeFile7(tmp, JSON.stringify(body, null, 2), { mode: 384 });
50823
+ await chmod4(tmp, 384);
50824
+ await rename3(tmp, file2);
50825
+ }
50826
+ async function loadApproved(runsDir, runId) {
50827
+ let raw;
50828
+ try {
50829
+ raw = JSON.parse(await readFile8(approvedFile(runsDir, runId), "utf8"));
50830
+ } catch {
50831
+ return null;
50832
+ }
50833
+ if (!Array.isArray(raw)) return null;
50834
+ const out2 = /* @__PURE__ */ new Map();
50835
+ for (const entry of raw) {
50836
+ const { todoId, title, text: text3, sha } = entry ?? {};
50837
+ if (typeof todoId !== "string" || typeof title !== "string" || typeof text3 !== "string" || sha !== sha256(text3))
50838
+ continue;
50839
+ out2.set(todoId, { title: plainTitle(title), text: text3, sha });
50840
+ }
50841
+ return out2;
50842
+ }
50843
+ function canResume(saved, runner, now) {
50844
+ if (!saved || !runner || new Date(runner.expiresAt).getTime() <= now)
50845
+ return false;
50846
+ return runner.cards.length > 0 && runner.cards.every((c) => saved.get(c.todoId)?.sha === c.contentSha256);
50847
+ }
50848
+
50849
+ // src/lib/runner/loop.ts
50850
+ var RUNNER_CARD_DEADLINE_MS = 2 * 60 * 6e4;
50851
+ var AGENT_DEADLINE_MS = RUNNER_CARD_DEADLINE_MS - 10 * 6e4;
50852
+ var POLL_MS = 1e4;
50853
+ var HEARTBEAT_MS = 3e4;
50854
+ var CLAIM_TTL_MINUTES = 125;
50855
+ var PUSH_HINT = 'Git could not push from this terminal. Run "gh auth login" (or set up your git credentials) and run the command again.';
50856
+ var FETCH_HINT = 'Git could not fetch from this terminal. Run "gh auth login" (or set up your git credentials) and run the command again.';
50857
+ var AUTH_FAILURE = /authentication|permission denied|could not read (username|password)|terminal prompts disabled|publickey|(?:HTTP|returned error|status)[: ]+(?:code )?\b(?:401|403)\b/i;
50858
+ var DETAIL_CODE = /^(?:[a-z_]+|prepare_failed: (?:fetch|worktree|layout)|agent_exit_(?:\d{1,3}|signal))$/;
50859
+ var RunnerCallError = class extends Error {
50860
+ constructor(code, message) {
50861
+ super(message);
50862
+ this.code = code;
50863
+ this.name = "RunnerCallError";
50864
+ }
50865
+ code;
50866
+ };
50867
+ function asNext(data) {
50868
+ const kind = data.kind;
50869
+ if (kind === "card" && typeof data.todoId === "string")
50870
+ return {
50871
+ kind,
50872
+ todoId: data.todoId,
50873
+ contentSha256: String(data.contentSha256 ?? "")
50874
+ };
50875
+ if (kind === "stop") return { kind, reason: String(data.reason ?? "") };
50876
+ if (kind === "wait" || kind === "done") return { kind };
50877
+ throw new Error("Great Arrow sent an answer this CLI does not understand.");
50878
+ }
50879
+ function describe3(o) {
50880
+ if (o.outcome === "pushed") return "PR opened";
50881
+ if (o.outcome === "no_changes") return "no changes";
50882
+ if (o.outcome === "stopped") return "stopped";
50883
+ if (o.outcome === "card_edited") return "failed: card_edited";
50884
+ return `failed: ${o.detail}`;
50885
+ }
50886
+ async function claimCard(call, todoId) {
50887
+ const claim2 = await call("work_claim", {
50888
+ claim_key: `board-run:${todoId}`,
50889
+ card_id: todoId,
50890
+ ttl_minutes: CLAIM_TTL_MINUTES
50891
+ }).catch(() => null);
50892
+ if (!claim2) return { outcome: "failed", detail: "claim_failed" };
50893
+ return claim2.granted === true ? null : { outcome: "failed", detail: "claimed_elsewhere" };
50894
+ }
50895
+ async function workCard(deps, todoId, card) {
50896
+ let prepared;
50897
+ try {
50898
+ prepared = await deps.prepare(todoId, card.text);
50899
+ } catch (error62) {
50900
+ if (!(error62 instanceof PrepareError))
50901
+ return { outcome: "failed", detail: "prepare_failed" };
50902
+ return {
50903
+ outcome: "failed",
50904
+ detail: `prepare_failed: ${error62.step}`,
50905
+ ...error62.gitLine ? { local: error62.gitLine } : {}
50906
+ };
50907
+ }
50908
+ let ran;
50909
+ try {
50910
+ ran = await deps.launch(prepared, todoId, deps.signal);
50911
+ } catch {
50912
+ return { outcome: "failed", detail: "agent_did_not_start" };
50913
+ }
50914
+ if (deps.signal.aborted) return { outcome: "stopped" };
50915
+ if (!ran.groupGone) return { outcome: "failed", detail: "sandbox_tampered" };
50916
+ if (ran.killed) return { outcome: "failed", detail: "timed_out" };
50917
+ if (ran.exit !== 0)
50918
+ return { outcome: "failed", detail: `agent_exit_${ran.exit ?? "signal"}` };
50919
+ const result = await deps.publish(prepared, todoId, card.title, deps.signal).catch(() => ({ failed: "publish_failed" }));
50920
+ if (deps.signal.aborted) return { outcome: "stopped" };
50921
+ if (result === "no_changes") return { outcome: "no_changes" };
50922
+ if ("pushed" in result)
50923
+ return {
50924
+ outcome: "pushed",
50925
+ branch: prepared.branch,
50926
+ headSha: result.pushed
50927
+ };
50928
+ return {
50929
+ outcome: "failed",
50930
+ detail: result.failed,
50931
+ ...result.file ? {
50932
+ say: `A possible secret was found in ${cleanLine(result.file)}; nothing was committed or pushed.`
50933
+ } : {}
50934
+ };
50935
+ }
50936
+ function reportFields(o) {
50937
+ if (o.outcome === "pushed")
50938
+ return { outcome: o.outcome, branch: o.branch, head_sha: o.headSha };
50939
+ if (o.outcome === "failed")
50940
+ return {
50941
+ outcome: "failed",
50942
+ detail: DETAIL_CODE.test(o.detail) ? o.detail : "failed"
50943
+ };
50944
+ return { outcome: o.outcome };
50945
+ }
50946
+ async function release(deps, todoId) {
50947
+ try {
50948
+ await deps.call("work_release", { card_id: todoId });
50949
+ } catch {
50950
+ deps.print(
50951
+ `Could not release the claim on card ${short(todoId)}; it lapses on its own.`
50952
+ );
50953
+ }
50954
+ }
50955
+ function heartbeat(deps, runId, runEnded) {
50956
+ let inFlight = false;
50957
+ let missed = 0;
50958
+ const stop2 = deps.every(HEARTBEAT_MS, () => {
50959
+ if (inFlight) return;
50960
+ inFlight = true;
50961
+ deps.call("board_autopilot", { action: "runner_get" }).then(
50962
+ (view) => {
50963
+ missed = 0;
50964
+ if (view.runId !== runId || view.status !== "running") runEnded();
50965
+ },
50966
+ (error62) => {
50967
+ if (error62 instanceof RunnerCallError && error62.code === "no_runner_run")
50968
+ runEnded();
50969
+ else missed += 1;
50970
+ }
50971
+ ).finally(() => {
50972
+ inFlight = false;
50973
+ });
50974
+ });
50975
+ return () => {
50976
+ stop2();
50977
+ if (missed > 0)
50978
+ deps.print(
50979
+ `(Great Arrow did not hear from this terminal ${missed} times.)`
50980
+ );
50981
+ };
50982
+ }
50983
+ async function runLoop(deps, input2) {
50984
+ const { runId, approved } = input2;
50985
+ const board = (action, extra = {}) => deps.call("board_autopilot", { action, run_id: runId, ...extra });
50986
+ const total = approved.size;
50987
+ const result = {
50988
+ pushed: 0,
50989
+ noChanges: 0,
50990
+ failed: 0,
50991
+ stopped: false
50992
+ };
50993
+ const numbers = /* @__PURE__ */ new Map();
50994
+ while (!deps.signal.aborted) {
50995
+ const next = asNext(await board("runner_next"));
50996
+ if (next.kind === "done") break;
50997
+ if (next.kind === "stop") {
50998
+ deps.print(`Great Arrow ended the run (${cleanLine(next.reason)}).`);
50999
+ break;
51000
+ }
51001
+ if (next.kind === "wait") {
51002
+ await deps.sleep(POLL_MS, deps.signal);
51003
+ continue;
51004
+ }
51005
+ const card = approved.get(next.todoId);
51006
+ if (card && !numbers.has(next.todoId))
51007
+ numbers.set(next.todoId, numbers.size + 1);
51008
+ const label = card ? `[${numbers.get(next.todoId)}/${total}] ${card.title}` : `[-] card ${short(next.todoId)}`;
51009
+ let claimed = false;
51010
+ let outcome;
51011
+ if (!card) outcome = { outcome: "failed", detail: "not_approved" };
51012
+ else if (next.contentSha256 !== card.sha)
51013
+ outcome = { outcome: "card_edited" };
51014
+ else {
51015
+ const refused = await claimCard(deps.call, next.todoId);
51016
+ claimed = refused === null;
51017
+ if (refused) outcome = refused;
51018
+ else {
51019
+ const cardStop = new AbortController();
51020
+ const abort = () => cardStop.abort();
51021
+ deps.signal.addEventListener("abort", abort, { once: true });
51022
+ const stopBeat = heartbeat(deps, runId, () => {
51023
+ if (!cardStop.signal.aborted)
51024
+ deps.print("The run was stopped on the board. Stopping the agent\u2026");
51025
+ abort();
51026
+ });
51027
+ try {
51028
+ outcome = await workCard(
51029
+ { ...deps, signal: cardStop.signal },
51030
+ next.todoId,
51031
+ card
51032
+ );
51033
+ } finally {
51034
+ stopBeat();
51035
+ deps.signal.removeEventListener("abort", abort);
51036
+ }
51037
+ }
51038
+ }
51039
+ try {
51040
+ await board("runner_report", {
51041
+ card_id: next.todoId,
51042
+ runner: reportFields(outcome)
51043
+ });
51044
+ } catch (error62) {
51045
+ if (!(error62 instanceof RunnerCallError && error62.code === "card_released"))
51046
+ throw error62;
51047
+ deps.print(`${label} \u2026 taken back on the board`);
51048
+ continue;
51049
+ } finally {
51050
+ if (claimed) await release(deps, next.todoId);
51051
+ }
51052
+ if (outcome.outcome === "stopped") {
51053
+ if (deps.signal.aborted) return { ...result, stopped: true };
51054
+ deps.print(`${label} \u2026 stopped`);
51055
+ continue;
51056
+ }
51057
+ deps.print(`${label} \u2026 ${describe3(outcome)}`);
51058
+ if (outcome.outcome === "failed") {
51059
+ if (outcome.say) deps.print(` ${outcome.say}`);
51060
+ if (outcome.local) {
51061
+ deps.print(` git said: ${outcome.local}`);
51062
+ deps.note(next.todoId, `git said: ${outcome.local}`);
51063
+ }
51064
+ if (outcome.detail === "push_failed") deps.print(PUSH_HINT);
51065
+ if (outcome.detail === "prepare_failed: fetch" && AUTH_FAILURE.test(outcome.local ?? ""))
51066
+ deps.print(FETCH_HINT);
51067
+ }
51068
+ if (outcome.outcome === "pushed") result.pushed += 1;
51069
+ else if (outcome.outcome === "no_changes") result.noChanges += 1;
51070
+ else result.failed += 1;
51071
+ }
51072
+ return { ...result, stopped: deps.signal.aborted };
51073
+ }
51074
+
51075
+ // src/lib/runner/command.ts
51076
+ var STOPPED_MESSAGE = "Stopped. This card is closed for this run; run the same command to go on with the remaining cards.";
51077
+ var AGENT_NAME = {
51078
+ claude: "Claude Code",
51079
+ codex: "Codex"
51080
+ };
51081
+ function agentOf(raw) {
51082
+ const agent = raw ?? "claude";
51083
+ return agent === "claude" || agent === "codex" ? agent : null;
51084
+ }
51085
+ function skippedCount(raw) {
51086
+ const n = raw?.notOwnerAuthored;
51087
+ return typeof n === "number" && Number.isInteger(n) && n > 0 ? n : 0;
51088
+ }
51089
+ function skippedMessage(n) {
51090
+ return `${n} ${n === 1 ? "card was" : "cards were"} skipped: someone else or an agent last edited ${n === 1 ? "it" : "them"}. Open and save a card yourself to run it here.`;
51091
+ }
51092
+ function asView(data) {
51093
+ if (typeof data.runId !== "string" || !isRunId(data.runId)) return null;
51094
+ const cards = Array.isArray(data.cards) ? data.cards : [];
51095
+ return {
51096
+ runId: data.runId,
51097
+ repo: typeof data.repo === "string" ? data.repo : "",
51098
+ base: typeof data.base === "string" ? data.base : "",
51099
+ cards: cards.filter(
51100
+ (c) => !!c && typeof c.todoId === "string" && typeof c.title === "string" && typeof c.text === "string"
51101
+ ),
51102
+ runner: data.runner ?? null,
51103
+ skippedNotOwnerAuthored: skippedCount(data.skipped)
51104
+ };
51105
+ }
51106
+ function refusal2(deps, error62) {
51107
+ if (error62 instanceof RunnerCallError)
51108
+ deps.exit(
51109
+ 1,
51110
+ cleanLine(error62.message) || `Great Arrow refused (${cleanLine(error62.code)}).`
51111
+ );
51112
+ throw error62;
51113
+ }
51114
+ async function checkFolder(deps, repo) {
51115
+ const { root, origin: origin2 } = await deps.checkout();
51116
+ if (!repo || !root || origin2?.toLowerCase() !== repo.toLowerCase())
51117
+ deps.exit(
51118
+ 1,
51119
+ `Run this inside your ${cleanLine(repo) || "code repository"} checkout.`
51120
+ );
51121
+ return root;
51122
+ }
51123
+ async function consent(deps, view, shown, agent, yes) {
51124
+ deps.print("");
51125
+ deps.print(
51126
+ `Clear the board in ${cleanLine(view.repo)}, worked by ${AGENT_NAME[agent]} on this computer:`
51127
+ );
51128
+ [...shown.values()].forEach((c, i) => {
51129
+ deps.print(` ${i + 1}. ${c.title}`);
51130
+ for (const line of preview(c.text)) deps.print(` ${line}`);
51131
+ });
51132
+ deps.print("Approval lasts 24 hours.");
51133
+ deps.print("");
51134
+ if (yes) return;
51135
+ if (!deps.interactive)
51136
+ deps.exit(1, "Run this in a terminal to approve the cards, or pass --yes.");
51137
+ for (; ; ) {
51138
+ const answer = (await deps.ask(
51139
+ `Run these ${shown.size} cards here? [y/N, v to view them in full] `
51140
+ )).trim().toLowerCase();
51141
+ if (answer === "y" || answer === "yes") return;
51142
+ if (answer !== "v") deps.exit(0, "Nothing was run.");
51143
+ [...shown.values()].forEach((c, i) => {
51144
+ deps.print(`--- ${i + 1}. ${c.title} ---`);
51145
+ for (const line of cleanText(c.text).split("\n")) deps.print(line);
51146
+ deps.print("");
51147
+ });
51148
+ }
51149
+ }
51150
+ async function approve(deps, view, agent, yes) {
51151
+ const shown = approveShown(view.cards);
51152
+ await consent(deps, view, shown, agent, yes);
51153
+ let state;
51154
+ try {
51155
+ const data = await deps.call("board_autopilot", {
51156
+ action: "runner_approve",
51157
+ run_id: view.runId,
51158
+ runner: {
51159
+ machine: deps.machine.slice(0, 200),
51160
+ agent,
51161
+ cards: [...shown].map(([todoId, c]) => ({
51162
+ todoId,
51163
+ contentSha256: c.sha
51164
+ }))
51165
+ }
51166
+ });
51167
+ state = data.runner;
51168
+ } catch (error62) {
51169
+ refusal2(deps, error62);
51170
+ }
51171
+ const agreed = new Set(
51172
+ (state?.cards ?? []).map((c) => `${c.todoId}:${c.contentSha256}`)
51173
+ );
51174
+ for (const [todoId, c] of shown)
51175
+ if (!agreed.has(`${todoId}:${c.sha}`)) shown.delete(todoId);
51176
+ if (shown.size === 0)
51177
+ deps.exit(
51178
+ 1,
51179
+ "None of the cards shown here are the ones approved for this run. Run the command again to see the current cards."
51180
+ );
51181
+ return shown;
51182
+ }
51183
+ async function runBoardWith(deps, opts) {
51184
+ const agent = agentOf(opts.agent);
51185
+ if (!agent) deps.exit(1, "--agent must be claude or codex.");
51186
+ const check2 = await deps.preflight(agent);
51187
+ if (!check2.ok) deps.exit(1, check2.message);
51188
+ let view = null;
51189
+ try {
51190
+ view = asView(await deps.call("board_autopilot", { action: "runner_get" }));
51191
+ } catch (error62) {
51192
+ refusal2(deps, error62);
51193
+ }
51194
+ if (!view) deps.exit(1, "Great Arrow sent a run this CLI cannot use.");
51195
+ const repoRoot = await checkFolder(deps, view.repo);
51196
+ const hooks = await deps.repoHooksDir(repoRoot);
51197
+ if (hooks)
51198
+ deps.print(
51199
+ `The agent can't change files in ${cleanLine(hooks)} (git hooks) on this computer.`
51200
+ );
51201
+ const saved = await loadApproved(deps.runsDir, view.runId);
51202
+ let approved;
51203
+ if (saved && canResume(saved, view.runner, deps.now())) {
51204
+ approved = saved;
51205
+ deps.print(
51206
+ `Picking up run ${short(view.runId)} where it left off (${saved.size} cards approved).`
51207
+ );
51208
+ } else {
51209
+ if (view.skippedNotOwnerAuthored > 0)
51210
+ deps.print(skippedMessage(view.skippedNotOwnerAuthored));
51211
+ if (view.cards.length === 0)
51212
+ deps.exit(
51213
+ 0,
51214
+ view.skippedNotOwnerAuthored > 0 ? "Nothing was run." : "No cards are ready to run."
51215
+ );
51216
+ approved = await approve(deps, view, agent, opts.yes === true);
51217
+ await saveApproved(deps.runsDir, view.runId, approved);
51218
+ }
51219
+ const controller = new AbortController();
51220
+ let group = null;
51221
+ deps.onInterrupt(() => {
51222
+ if (controller.signal.aborted) {
51223
+ if (group !== null) deps.killGroup(group);
51224
+ deps.exit(130, STOPPED_MESSAGE);
51225
+ }
51226
+ deps.print("Stopping the agent\u2026");
51227
+ controller.abort();
51228
+ });
51229
+ const work2 = deps.work({
51230
+ view,
51231
+ repoRoot,
51232
+ agent,
51233
+ bin: check2.bin,
51234
+ onSpawn: (pgid) => {
51235
+ group = pgid;
51236
+ },
51237
+ onReaped: () => {
51238
+ group = null;
51239
+ }
51240
+ });
51241
+ let result;
51242
+ try {
51243
+ result = await runLoop(
51244
+ {
51245
+ ...work2,
51246
+ call: deps.call,
51247
+ signal: controller.signal,
51248
+ print: deps.print
51249
+ },
51250
+ { runId: view.runId, approved }
51251
+ );
51252
+ } catch (error62) {
51253
+ refusal2(deps, error62);
51254
+ }
51255
+ if (result.stopped) deps.exit(130, STOPPED_MESSAGE);
51256
+ deps.print("");
51257
+ deps.print(
51258
+ `Finished: ${result.pushed} PRs opened, ${result.noChanges} with no changes, ${result.failed} not done. Logs are in ${deps.runsDir}/${view.runId}.`
51259
+ );
51260
+ }
51261
+
51262
+ // src/commands/board-run.ts
51263
+ import { appendFileSync } from "node:fs";
51264
+ import { chmod as chmod5, writeFile as writeFile8 } from "node:fs/promises";
51265
+ import { hostname as hostname5 } from "node:os";
51266
+ import { join as join16 } from "node:path";
51267
+ import { createInterface as createInterface3 } from "node:readline";
51268
+
51269
+ // src/lib/runner/agent.ts
51270
+ import { spawn } from "node:child_process";
51271
+ import { accessSync, chmodSync as chmodSync3, closeSync, constants as constants2, openSync } from "node:fs";
51272
+ import { delimiter, join as join15 } from "node:path";
51273
+ var KILL_GRACE_MS = 5e3;
51274
+ var INSTALL_MESSAGE = {
51275
+ claude: "Install Claude Code (https://claude.com/claude-code), then run the command again.",
51276
+ codex: "Install Codex (npm install -g @openai/codex), then run the command again.",
51277
+ bwrap: "Install bubblewrap (for example: sudo apt install bubblewrap), then run the command again."
51278
+ };
51279
+ function onPath(name23, env4) {
51280
+ for (const dir of (env4.PATH ?? "").split(delimiter)) {
51281
+ if (!dir) continue;
51282
+ const candidate = join15(dir, name23);
51283
+ try {
51284
+ accessSync(candidate, constants2.X_OK);
51285
+ return candidate;
51286
+ } catch {
51287
+ continue;
51288
+ }
51289
+ }
51290
+ return null;
51291
+ }
51292
+ async function preflightAgent(agent, platform2, env4 = process.env) {
51293
+ if (platform2 === "win32") {
51294
+ return {
51295
+ ok: false,
51296
+ message: "Clear the board runs on macOS, Linux or WSL."
51297
+ };
51298
+ }
51299
+ const bin = onPath(agent, env4);
51300
+ if (!bin) return { ok: false, message: INSTALL_MESSAGE[agent] };
51301
+ if (platform2 === "linux" && !onPath("bwrap", env4)) {
51302
+ return { ok: false, message: INSTALL_MESSAGE.bwrap };
51303
+ }
51304
+ return { ok: true, bin };
51305
+ }
51306
+ function agentArgv(input2) {
51307
+ return input2.agent === "claude" ? [...claudeArgs(input2.settingsPath), "-p", input2.kickoff] : [...codexArgs(input2.layout), input2.kickoff];
51308
+ }
51309
+ async function runAgent(input2) {
51310
+ if (input2.signal.aborted) return { exit: null, killed: true, pgid: null };
51311
+ const fd = openSync(input2.logPath, "a", 384);
51312
+ chmodSync3(input2.logPath, 384);
51313
+ const env4 = { ...stripCredentialEnv(process.env), GIT_TERMINAL_PROMPT: "0" };
51314
+ let child;
51315
+ try {
51316
+ child = spawn(input2.bin, agentArgv(input2), {
51317
+ cwd: input2.layout.worktree,
51318
+ detached: true,
51319
+ stdio: ["ignore", fd, fd],
51320
+ env: env4
51321
+ });
51322
+ } finally {
51323
+ closeSync(fd);
51324
+ }
51325
+ const pid = child.pid;
51326
+ if (pid !== void 0) input2.onSpawn?.(pid);
51327
+ return new Promise((resolve7, reject) => {
51328
+ let killed = false;
51329
+ let killTimer;
51330
+ const signalGroup = (sig) => {
51331
+ if (pid === void 0) return;
51332
+ try {
51333
+ process.kill(-pid, sig);
51334
+ } catch {
51335
+ return;
51336
+ }
51337
+ };
51338
+ const terminate = () => {
51339
+ if (killed) return;
51340
+ killed = true;
51341
+ signalGroup("SIGTERM");
51342
+ killTimer = setTimeout(() => signalGroup("SIGKILL"), KILL_GRACE_MS);
51343
+ };
51344
+ const deadline = setTimeout(terminate, input2.deadlineMs);
51345
+ input2.signal.addEventListener("abort", terminate, { once: true });
51346
+ const cleanup = () => {
51347
+ clearTimeout(deadline);
51348
+ if (killTimer) clearTimeout(killTimer);
51349
+ input2.signal.removeEventListener("abort", terminate);
51350
+ };
51351
+ child.once("error", (err2) => {
51352
+ cleanup();
51353
+ reject(err2);
51354
+ });
51355
+ child.once("close", (code) => {
51356
+ cleanup();
51357
+ if (killed) signalGroup("SIGKILL");
51358
+ resolve7({ exit: code, killed, pgid: pid ?? null });
51359
+ });
51360
+ });
51361
+ }
51362
+ var REAP_WAIT_MS = 2e3;
51363
+ function groupAlive(pgid) {
51364
+ try {
51365
+ process.kill(-pgid, 0);
51366
+ return true;
51367
+ } catch (error62) {
51368
+ return error62.code !== "ESRCH";
51369
+ }
51370
+ }
51371
+ async function reapGroup(pgid, waitMs = REAP_WAIT_MS) {
51372
+ try {
51373
+ process.kill(-pgid, "SIGKILL");
51374
+ } catch (error62) {
51375
+ if (error62.code === "ESRCH") return true;
51376
+ }
51377
+ const until = Date.now() + waitMs;
51378
+ while (groupAlive(pgid)) {
51379
+ if (Date.now() >= until) return false;
51380
+ await new Promise((resolve7) => setTimeout(resolve7, 25));
51381
+ }
51382
+ return true;
51383
+ }
51384
+
51385
+ // src/lib/runner/secrets.ts
51386
+ var SECRET_PATTERNS = [
51387
+ /-----BEGIN [A-Z ]*PRIVATE KEY-----/,
51388
+ /gh[pousr]_[A-Za-z0-9]{36,}/,
51389
+ /github_pat_[A-Za-z0-9_]{60,}/,
51390
+ /sk_live_[A-Za-z0-9]{20,}/,
51391
+ /AKIA[0-9A-Z]{16}/,
51392
+ /xox[baprs]-[A-Za-z0-9-]{10,}/,
51393
+ /gad_v1_[A-Za-z0-9_-]{20,}/
51394
+ ];
51395
+ function fileWithSecret(diff) {
51396
+ let file2 = null;
51397
+ for (const line of diff.split("\n")) {
51398
+ if (line.startsWith("+++ ")) {
51399
+ file2 = line.startsWith("+++ b/") ? line.slice(6) : line.slice(4);
51400
+ continue;
51401
+ }
51402
+ if (!line.startsWith("+")) continue;
51403
+ if (SECRET_PATTERNS.some((p) => p.test(line))) return file2 ?? "a file";
51404
+ }
51405
+ return null;
51406
+ }
51407
+
51408
+ // src/lib/runner/publish.ts
51409
+ var RUNNER_BRANCH = /^gad\/run-[0-9a-f]{8}-[0-9a-f]{8}$/;
51410
+ function commitMessage(title, runId, todoId) {
51411
+ const subject = title.replace(/\s+/g, " ").trim() || "Clear the board card";
51412
+ return `${subject}
51413
+
51414
+ Clear the board run ${short(runId)}, card ${short(todoId)}`;
51415
+ }
51416
+ async function publishBranch(layout, branch, base, message, signal) {
51417
+ if (!await verifyGitfile(layout)) return { failed: "sandbox_tampered" };
51418
+ if (!RUNNER_BRANCH.test(branch) || branch === base)
51419
+ return { failed: "bad_branch" };
51420
+ const git2 = (args) => worktreeGit(layout, args, signal ? { signal } : {});
51421
+ if ((await git2(["add", "-A"])).code !== 0) return { failed: "commit_failed" };
51422
+ if ((await git2(["reset", "-q", "--", ".gad"])).code !== 0)
51423
+ return { failed: "commit_failed" };
51424
+ const diff = await git2([
51425
+ "diff",
51426
+ "--cached",
51427
+ "-U0",
51428
+ "--no-color",
51429
+ "--no-ext-diff",
51430
+ "--no-textconv"
51431
+ ]);
51432
+ if (diff.code !== 0) return { failed: "commit_failed" };
51433
+ const leaked = fileWithSecret(diff.stdout);
51434
+ if (leaked) return { failed: "secret_in_diff", file: leaked };
51435
+ const staged = await git2(["diff", "--cached", "--quiet"]);
51436
+ if (staged.code > 1) return { failed: "commit_failed" };
51437
+ if (staged.code === 1 && (await git2(["commit", "-q", "-m", message])).code !== 0)
51438
+ return { failed: "commit_failed" };
51439
+ const ahead = await git2([
51440
+ "rev-list",
51441
+ "--count",
51442
+ `refs/remotes/origin/${base}..HEAD`
51443
+ ]);
51444
+ if (ahead.code !== 0) return { failed: "commit_failed" };
51445
+ if (Number(ahead.stdout.trim()) === 0) return "no_changes";
51446
+ const task = await git2([
51447
+ "ls-tree",
51448
+ "-r",
51449
+ "--name-only",
51450
+ "HEAD",
51451
+ "--",
51452
+ ".gad"
51453
+ ]);
51454
+ if (task.code !== 0 || task.stdout.trim() !== "")
51455
+ return { failed: "task_file_committed" };
51456
+ const head = await git2(["rev-parse", "HEAD"]);
51457
+ const sha = head.stdout.trim();
51458
+ if (head.code !== 0 || !/^[0-9a-f]{40}$/.test(sha))
51459
+ return { failed: "commit_failed" };
51460
+ const push = await git2(["push", "origin", `${sha}:refs/heads/${branch}`]);
51461
+ return push.code === 0 ? { pushed: sha } : { failed: "push_failed" };
51462
+ }
51463
+
51464
+ // src/commands/board-run.ts
51465
+ function parseData(result) {
51466
+ if (result && typeof result === "object" && !Array.isArray(result))
51467
+ return result;
51468
+ if (typeof result !== "string") return {};
51469
+ const tail = result.slice(result.lastIndexOf("\n") + 1).trim();
51470
+ try {
51471
+ const data = JSON.parse(tail);
51472
+ return data && typeof data === "object" ? data : {};
51473
+ } catch {
51474
+ return {};
51475
+ }
51476
+ }
51477
+ function makeCall(client2) {
51478
+ return async (tool2, args) => {
51479
+ const heartbeat2 = args.action === "runner_get";
51480
+ let result;
51481
+ try {
51482
+ result = tool2 === "board_autopilot" ? await client2.mcpCall(
51483
+ "gad_call",
51484
+ gadCallArgs(tool2, args),
51485
+ heartbeat2 ? 2e4 : 6e4
51486
+ ) : await client2.mcpCall(tool2, args, 3e4);
51487
+ } catch (error62) {
51488
+ if (error62 instanceof McpToolError)
51489
+ throw new RunnerCallError(error62.toolCode, error62.message);
51490
+ throw error62;
51491
+ }
51492
+ const failure2 = callFailure(result);
51493
+ if (failure2) throw new RunnerCallError(failure2.code, failure2.message);
51494
+ return parseData(result);
51495
+ };
51496
+ }
51497
+ function exit(code, message) {
51498
+ if (message)
51499
+ (code === 1 ? process.stderr : process.stdout).write(`${message}
51500
+ `);
51501
+ process.exit(code);
51502
+ }
51503
+ function ask2(question) {
51504
+ const rl = createInterface3({ input: process.stdin, output: process.stdout });
51505
+ return new Promise(
51506
+ (resolve7) => rl.question(question, (answer) => {
51507
+ rl.close();
51508
+ resolve7(answer);
51509
+ })
51510
+ );
51511
+ }
51512
+ function sleep2(ms, signal) {
51513
+ return new Promise((resolve7) => {
51514
+ if (signal.aborted) return resolve7();
51515
+ const timer = setTimeout(done, ms);
51516
+ function done() {
51517
+ clearTimeout(timer);
51518
+ signal.removeEventListener("abort", done);
51519
+ resolve7();
51520
+ }
51521
+ signal.addEventListener("abort", done, { once: true });
51522
+ });
51523
+ }
51524
+ var work = ({
51525
+ view,
51526
+ repoRoot,
51527
+ agent,
51528
+ bin,
51529
+ onSpawn,
51530
+ onReaped
51531
+ }) => {
51532
+ const runsDir = runsRoot();
51533
+ const runDir = join16(runsDir, view.runId);
51534
+ const deps = {
51535
+ prepare: (todoId, text3) => prepareWorktree({
51536
+ repoRoot,
51537
+ runId: view.runId,
51538
+ todoId,
51539
+ base: view.base,
51540
+ text: text3,
51541
+ runsDir
51542
+ }),
51543
+ launch: async (prepared, todoId, signal) => {
51544
+ const settingsPath = join16(runDir, `${short(todoId)}.settings.json`);
51545
+ await writeFile8(settingsPath, claudeSettings(prepared), { mode: 384 });
51546
+ await chmod5(settingsPath, 384);
51547
+ const ran = await runAgent({
51548
+ agent,
51549
+ bin,
51550
+ layout: prepared,
51551
+ settingsPath,
51552
+ kickoff: kickoff(view.runId, todoId),
51553
+ logPath: join16(runDir, `${short(todoId)}.log`),
51554
+ deadlineMs: AGENT_DEADLINE_MS,
51555
+ signal,
51556
+ onSpawn
51557
+ });
51558
+ const groupGone = ran.pgid === null ? true : await reapGroup(ran.pgid);
51559
+ if (groupGone) onReaped();
51560
+ return { exit: ran.exit, killed: ran.killed, groupGone };
51561
+ },
51562
+ publish: (prepared, todoId, title, signal) => publishBranch(
51563
+ prepared,
51564
+ prepared.branch,
51565
+ view.base,
51566
+ commitMessage(title, view.runId, todoId),
51567
+ signal
51568
+ ),
51569
+ sleep: sleep2,
51570
+ note: (todoId, line) => {
51571
+ try {
51572
+ appendFileSync(join16(runDir, `${short(todoId)}.log`), `${line}
51573
+ `, {
51574
+ mode: 384
51575
+ });
51576
+ } catch (error62) {
51577
+ process.stderr.write(
51578
+ `Could not write the card's log: ${error62.message}
51579
+ `
51580
+ );
51581
+ }
51582
+ },
51583
+ every: (ms, tick) => {
51584
+ const timer = setInterval(tick, ms);
51585
+ return () => clearInterval(timer);
51586
+ }
51587
+ };
51588
+ return deps;
51589
+ };
51590
+ async function commandDeps() {
51591
+ const auth = await resolveAuth();
51592
+ const call = makeCall(
51593
+ new GadClient({
51594
+ token: auth.token,
51595
+ getToken: auth.getToken,
51596
+ apiUrl: auth.apiUrl
51597
+ })
51598
+ );
51599
+ return {
51600
+ preflight: (agent) => preflightAgent(agent, process.platform),
51601
+ checkout: async () => {
51602
+ const cwd = process.cwd();
51603
+ const [root, origin2] = await Promise.all([
51604
+ checkoutRoot(cwd),
51605
+ repoFromOrigin(cwd)
51606
+ ]);
51607
+ return { root, origin: origin2 };
51608
+ },
51609
+ repoHooksDir,
51610
+ call,
51611
+ ask: ask2,
51612
+ interactive: process.stdin.isTTY === true && process.stdout.isTTY === true,
51613
+ print: (line) => process.stdout.write(`${line}
51614
+ `),
51615
+ exit,
51616
+ now: () => Date.now(),
51617
+ runsDir: runsRoot(),
51618
+ machine: hostname5(),
51619
+ onInterrupt: (handler) => {
51620
+ process.on("SIGINT", handler);
51621
+ process.on("SIGTERM", handler);
51622
+ },
51623
+ killGroup: (pgid) => {
51624
+ try {
51625
+ process.kill(-pgid, "SIGKILL");
51626
+ } catch (error62) {
51627
+ if (error62.code !== "ESRCH") throw error62;
51628
+ }
51629
+ },
51630
+ work
51631
+ };
51632
+ }
51633
+ async function runBoard(opts) {
51634
+ await runBoardWith(await commandDeps(), opts);
51635
+ }
51636
+ function boardRunCommand() {
51637
+ return new Command("run").description("Work the cards of a Clear the board run on this computer").option("--agent <name>", "claude or codex (default: claude)").option("--yes", "Approve the listed cards without asking").action((opts) => runBoard(opts));
51638
+ }
51639
+
50314
51640
  // src/commands/board.ts
50315
51641
  var TOOL = "board_autopilot";
50316
51642
  function asObject4(json3) {
@@ -50491,7 +51817,16 @@ function emit(result, json3, quiet = false) {
50491
51817
  return data;
50492
51818
  }
50493
51819
  async function runClear(opts, command) {
50494
- if (opts.yes)
51820
+ const here = opts.here === true;
51821
+ let runner = null;
51822
+ if (here) {
51823
+ const agent = agentOf(opts.agent);
51824
+ if (!agent) throw validation("--agent must be claude or codex.");
51825
+ runner = await commandDeps();
51826
+ const check2 = await runner.preflight(agent);
51827
+ if (!check2.ok) runner.exit(1, check2.message);
51828
+ }
51829
+ if (opts.yes || here)
50495
51830
  buildStartArgs(
50496
51831
  "pending",
50497
51832
  { quotes: [{ executor: "hosted", p90Usd: 1 }] },
@@ -50503,10 +51838,10 @@ async function runClear(opts, command) {
50503
51838
  action: "plan",
50504
51839
  ...opts.goal ? { goal_id: opts.goal } : {}
50505
51840
  });
50506
- const data = emit(planResult, g.json && !opts.yes, g.quiet);
51841
+ const data = emit(planResult, g.json && !opts.yes && !here, g.quiet);
50507
51842
  const run4 = data?.run ?? null;
50508
51843
  if (!g.json && !g.quiet && run4?.plan) printPlan(fmt, run4.plan);
50509
- if (!opts.yes) {
51844
+ if (!opts.yes && !here) {
50510
51845
  if (!g.json && !g.quiet && run4?.id)
50511
51846
  process.stdout.write(
50512
51847
  `
@@ -50516,11 +51851,18 @@ Nothing has changed. Start with: gad board clear${opts.goal ? ` --goal ${opts.go
50516
51851
  return;
50517
51852
  }
50518
51853
  if (!run4?.id) throw validation("The plan reply carried no run id.");
50519
- const startResult = await callBoard(
50520
- client2,
50521
- buildStartArgs(run4.id, run4.plan, opts)
50522
- );
51854
+ if (runner) {
51855
+ await checkFolder(runner, run4.plan?.repo ?? "");
51856
+ process.stdout.write(
51857
+ opts.yes ? "Starting the run on Great Arrow.\n" : "Starting the run on Great Arrow; nothing runs on this computer until you type y.\n"
51858
+ );
51859
+ }
51860
+ const startResult = await callBoard(client2, {
51861
+ ...buildStartArgs(run4.id, run4.plan, opts),
51862
+ ...here ? { executor: "runner" } : {}
51863
+ });
50523
51864
  emit(startResult, g.json, g.quiet);
51865
+ if (runner) await runBoardWith(runner, { agent: opts.agent, yes: opts.yes });
50524
51866
  }
50525
51867
  function actionCommand(action) {
50526
51868
  return new Command(action).description(`${action} a clear-the-board run`).option("--run <id>", "Run id (status defaults to the latest run)").option("--card <id>", "Undo only this card (undo)").action(async (opts, command) => {
@@ -50545,47 +51887,47 @@ function boardCommand() {
50545
51887
  ).option("--cap <usd>", "Spend cap in USD (default: hosted p90 quote)").option("--types <list>", "Comma-separated card types, e.g. code").option("--no-email", "Do not email when the run finishes").option("--no-push", "Do not push-notify when the run finishes").option(
50546
51888
  "--reject <findingId...>",
50547
51889
  "Finding ids to leave out of the accepted set"
50548
- ).option("--json", "Output the raw tool result");
51890
+ ).option("--here", "Start the run and work its cards in this terminal").option("--agent <name>", "With --here: claude or codex (default: claude)").option("--json", "Output the raw tool result");
50549
51891
  clear.action(runClear);
50550
51892
  clear.addCommand(actionCommand("status"));
50551
51893
  clear.addCommand(actionCommand("stop"));
50552
51894
  clear.addCommand(actionCommand("undo"));
50553
- return new Command("board").description("Clear the board: tidy cards and run the safe ones").addCommand(clear);
51895
+ return new Command("board").description("Clear the board: tidy cards and run the safe ones").addCommand(clear).addCommand(boardRunCommand());
50554
51896
  }
50555
51897
 
50556
51898
  // src/commands/keys.ts
50557
- import { createInterface as createInterface3 } from "node:readline";
51899
+ import { createInterface as createInterface4 } from "node:readline";
50558
51900
  import { Writable } from "node:stream";
50559
51901
 
50560
51902
  // src/lib/keys-apply.ts
50561
- import { spawn } from "node:child_process";
51903
+ import { spawn as spawn2 } from "node:child_process";
50562
51904
  import {
50563
- chmod as chmod3,
50564
- mkdir as mkdir8,
50565
- readFile as readFile7,
50566
- realpath,
50567
- rename as rename3,
51905
+ chmod as chmod6,
51906
+ mkdir as mkdir10,
51907
+ readFile as readFile9,
51908
+ realpath as realpath3,
51909
+ rename as rename4,
50568
51910
  stat as stat2,
50569
- writeFile as writeFile6
51911
+ writeFile as writeFile9
50570
51912
  } from "node:fs/promises";
50571
- import { homedir as homedir10 } from "node:os";
50572
- import { basename as basename2, dirname as dirname8, isAbsolute as isAbsolute3, join as join12, relative, sep } from "node:path";
51913
+ import { homedir as homedir11 } from "node:os";
51914
+ import { basename as basename2, dirname as dirname9, isAbsolute as isAbsolute4, join as join17, relative as relative2, sep } from "node:path";
50573
51915
  var GH_APPLY_TIMEOUT_MS = 3e4;
50574
51916
  var GIT_APPLY_TIMEOUT_MS = 3e4;
50575
51917
  function runWithStdin(file2, args, input2, timeoutMs) {
50576
- return new Promise((resolve5) => {
51918
+ return new Promise((resolve7) => {
50577
51919
  let settled = false;
50578
51920
  const done = (o) => {
50579
51921
  if (settled) return;
50580
51922
  settled = true;
50581
51923
  clearTimeout(timer);
50582
- resolve5(o);
51924
+ resolve7(o);
50583
51925
  };
50584
51926
  let child;
50585
51927
  try {
50586
- child = spawn(file2, args, { stdio: ["pipe", "ignore", "ignore"] });
51928
+ child = spawn2(file2, args, { stdio: ["pipe", "ignore", "ignore"] });
50587
51929
  } catch {
50588
- resolve5("not_found");
51930
+ resolve7("not_found");
50589
51931
  return;
50590
51932
  }
50591
51933
  const timer = setTimeout(() => {
@@ -50639,8 +51981,8 @@ password=${value}
50639
51981
  return { ok: false, code: `git_${approved}` };
50640
51982
  }
50641
51983
  function expandHome(path10) {
50642
- if (path10 === "~") return homedir10();
50643
- if (path10.startsWith("~/")) return join12(homedir10(), path10.slice(2));
51984
+ if (path10 === "~") return homedir11();
51985
+ if (path10.startsWith("~/")) return join17(homedir11(), path10.slice(2));
50644
51986
  return path10;
50645
51987
  }
50646
51988
  function escapeRegExp(s2) {
@@ -50669,16 +52011,16 @@ function formatEnvValue(value, quote) {
50669
52011
  }
50670
52012
  async function writeAtomic(path10, content, mode) {
50671
52013
  const tmp = `${path10}.tmp`;
50672
- await writeFile6(tmp, content, { mode });
50673
- await chmod3(tmp, mode);
50674
- await rename3(tmp, path10);
52014
+ await writeFile9(tmp, content, { mode });
52015
+ await chmod6(tmp, mode);
52016
+ await rename4(tmp, path10);
50675
52017
  }
50676
52018
  async function applyEnvFile(path10, key, value) {
50677
52019
  const file2 = expandHome(path10);
50678
52020
  let original;
50679
52021
  let mode = 384;
50680
52022
  try {
50681
- original = await readFile7(file2, "utf8");
52023
+ original = await readFile9(file2, "utf8");
50682
52024
  mode = (await stat2(file2)).mode & 511;
50683
52025
  } catch (err2) {
50684
52026
  if (err2?.code !== "ENOENT") {
@@ -50726,7 +52068,7 @@ async function applySshKey(path10, privatePem) {
50726
52068
  const content = privatePem.endsWith("\n") ? privatePem : `${privatePem}
50727
52069
  `;
50728
52070
  try {
50729
- await mkdir8(dirname8(file2), { recursive: true, mode: 448 });
52071
+ await mkdir10(dirname9(file2), { recursive: true, mode: 448 });
50730
52072
  await writeAtomic(file2, content, 384);
50731
52073
  } catch {
50732
52074
  return { ok: false, code: "ssh_write_failed" };
@@ -50734,7 +52076,7 @@ async function applySshKey(path10, privatePem) {
50734
52076
  return { ok: true, code: "applied" };
50735
52077
  }
50736
52078
  function envTargetRefusal(path10, key, reported) {
50737
- if (!isAbsolute3(path10)) return { ok: false, code: "target_invalid" };
52079
+ if (!isAbsolute4(path10)) return { ok: false, code: "target_invalid" };
50738
52080
  const known = reported.some((r) => r.path === path10 && r.key === key);
50739
52081
  return known ? null : { ok: false, code: "target_not_reported" };
50740
52082
  }
@@ -50744,22 +52086,22 @@ var SSH_NOT_A_KEY = /* @__PURE__ */ new Set([
50744
52086
  "config",
50745
52087
  "known_hosts"
50746
52088
  ]);
50747
- async function sshTargetRefusal(path10, sshDir = join12(homedir10(), ".ssh")) {
52089
+ async function sshTargetRefusal(path10, sshDir = join17(homedir11(), ".ssh")) {
50748
52090
  const file2 = expandHome(path10);
50749
- if (!isAbsolute3(file2)) return { ok: false, code: "target_invalid" };
52091
+ if (!isAbsolute4(file2)) return { ok: false, code: "target_invalid" };
50750
52092
  if (SSH_NOT_A_KEY.has(basename2(file2))) {
50751
52093
  return { ok: false, code: "target_not_a_key" };
50752
52094
  }
50753
52095
  let root;
50754
52096
  let parent;
50755
52097
  try {
50756
- root = await realpath(sshDir);
50757
- parent = await realpath(dirname8(file2));
52098
+ root = await realpath3(sshDir);
52099
+ parent = await realpath3(dirname9(file2));
50758
52100
  } catch {
50759
52101
  return { ok: false, code: "target_outside_ssh_dir" };
50760
52102
  }
50761
- const rel = relative(root, parent);
50762
- if (rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute3(rel)) {
52103
+ const rel = relative2(root, parent);
52104
+ if (rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute4(rel)) {
50763
52105
  return { ok: false, code: "target_outside_ssh_dir" };
50764
52106
  }
50765
52107
  return null;
@@ -50798,10 +52140,10 @@ async function applyUpdate(targetKind, targetRef, value, scope) {
50798
52140
  }
50799
52141
 
50800
52142
  // src/lib/keys-device.ts
50801
- import { execFile as execFile4 } from "node:child_process";
50802
- import { readFile as readFile8 } from "node:fs/promises";
50803
- import { hostname as hostname5 } from "node:os";
50804
- import { resolve as resolve4 } from "node:path";
52143
+ import { execFile as execFile5 } from "node:child_process";
52144
+ import { readFile as readFile10 } from "node:fs/promises";
52145
+ import { hostname as hostname6 } from "node:os";
52146
+ import { resolve as resolve6 } from "node:path";
50805
52147
 
50806
52148
  // src/lib/keys-envelope.ts
50807
52149
  import {
@@ -50902,7 +52244,7 @@ function openFromServer(sealed, devicePrivateKeyB64) {
50902
52244
  }
50903
52245
 
50904
52246
  // src/lib/keys-handoff.ts
50905
- import { spawn as spawn2 } from "node:child_process";
52247
+ import { spawn as spawn3 } from "node:child_process";
50906
52248
 
50907
52249
  // src/lib/keys-paths.ts
50908
52250
  function keyRotationPath() {
@@ -50922,18 +52264,18 @@ var BROWSER_LAUNCH_TIMEOUT_MS = 5e3;
50922
52264
  function openInBrowser(url2) {
50923
52265
  const command = browserLaunchCommand(url2);
50924
52266
  if (!command) return Promise.resolve(false);
50925
- return new Promise((resolve5) => {
52267
+ return new Promise((resolve7) => {
50926
52268
  let settled = false;
50927
52269
  const done = (ok) => {
50928
52270
  if (settled) return;
50929
52271
  settled = true;
50930
52272
  clearTimeout(timer);
50931
- resolve5(ok);
52273
+ resolve7(ok);
50932
52274
  };
50933
52275
  const timer = setTimeout(() => done(false), BROWSER_LAUNCH_TIMEOUT_MS);
50934
52276
  timer.unref?.();
50935
52277
  try {
50936
- const child = spawn2(command.file, command.args, {
52278
+ const child = spawn3(command.file, command.args, {
50937
52279
  detached: true,
50938
52280
  stdio: "ignore"
50939
52281
  });
@@ -50947,7 +52289,7 @@ function openInBrowser(url2) {
50947
52289
  }
50948
52290
  });
50949
52291
  }
50950
- var defaultSleep = (ms) => new Promise((resolve5) => setTimeout(resolve5, ms));
52292
+ var defaultSleep = (ms) => new Promise((resolve7) => setTimeout(resolve7, ms));
50951
52293
  function stepUpError(message, hint) {
50952
52294
  return new CliError(message, 1 /* AUTH_ERROR */, hint);
50953
52295
  }
@@ -50955,7 +52297,7 @@ async function requestBrowserStepUp(client2, kind, subjectId, opts = {}) {
50955
52297
  const openUrl = opts.openUrl ?? openInBrowser;
50956
52298
  const notify = opts.notify ?? ((line) => process.stderr.write(`${line}
50957
52299
  `));
50958
- const sleep2 = opts.sleep ?? defaultSleep;
52300
+ const sleep3 = opts.sleep ?? defaultSleep;
50959
52301
  const now = opts.now ?? Date.now;
50960
52302
  const interval = opts.pollIntervalMs ?? HANDOFF_POLL_INTERVAL_MS;
50961
52303
  const deadline = now() + (opts.deadlineMs ?? HANDOFF_DEADLINE_MS);
@@ -50998,7 +52340,7 @@ async function requestBrowserStepUp(client2, kind, subjectId, opts = {}) {
50998
52340
  "Run the command again and approve within 5 minutes."
50999
52341
  );
51000
52342
  }
51001
- await sleep2(interval);
52343
+ await sleep3(interval);
51002
52344
  }
51003
52345
  throw stepUpError(
51004
52346
  "Timed out waiting for the browser approval.",
@@ -51014,7 +52356,7 @@ var REPORT_KEY = /^[A-Z_][A-Z0-9_]{0,127}$/;
51014
52356
  var REPORT_PATH = /^[ -~]{1,200}$/;
51015
52357
  var TOKEN_SHAPED = /[A-Za-z0-9]{33,}/;
51016
52358
  var SECRET_PREFIX = /(gh[pousr]_|github_pat_|-----BEGIN)/;
51017
- var UUID5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
52359
+ var UUID6 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
51018
52360
  function deviceSlot(workspaceId) {
51019
52361
  return `key-rotation-device:${workspaceId}`;
51020
52362
  }
@@ -51091,13 +52433,13 @@ async function scanEnvKeys(paths) {
51091
52433
  const out2 = [];
51092
52434
  const seen = /* @__PURE__ */ new Set();
51093
52435
  for (const p of paths) {
51094
- const path10 = resolve4(p);
52436
+ const path10 = resolve6(p);
51095
52437
  if (seen.has(path10)) continue;
51096
52438
  seen.add(path10);
51097
52439
  if (!REPORT_PATH.test(path10) || !nameOk(path10)) continue;
51098
52440
  let text3;
51099
52441
  try {
51100
- text3 = await readFile8(path10, "utf8");
52442
+ text3 = await readFile10(path10, "utf8");
51101
52443
  } catch {
51102
52444
  continue;
51103
52445
  }
@@ -51123,7 +52465,7 @@ function helperKind(raw) {
51123
52465
  }
51124
52466
  function run3(file2, args) {
51125
52467
  return new Promise((done) => {
51126
- execFile4(
52468
+ execFile5(
51127
52469
  file2,
51128
52470
  args,
51129
52471
  { timeout: DETECT_TIMEOUT_MS, encoding: "utf8" },
@@ -51152,7 +52494,7 @@ async function buildDeviceReport(envFiles) {
51152
52494
  return { envKeys, ghCli, gitHelper };
51153
52495
  }
51154
52496
  function defaultDeviceLabel() {
51155
- const label = hostname5().replace(/[^ -~]/g, "-").slice(0, 80).trim();
52497
+ const label = hostname6().replace(/[^ -~]/g, "-").slice(0, 80).trim();
51156
52498
  return label && nameOk(label) ? label : "this machine";
51157
52499
  }
51158
52500
  async function enroll(client2, workspaceId, opts = {}) {
@@ -51192,7 +52534,7 @@ async function enroll(client2, workspaceId, opts = {}) {
51192
52534
  publicKey: pair.publicKey,
51193
52535
  report
51194
52536
  });
51195
- const enrollmentId = typeof begun?.enrollmentId === "string" && UUID5.test(begun.enrollmentId) ? begun.enrollmentId : null;
52537
+ const enrollmentId = typeof begun?.enrollmentId === "string" && UUID6.test(begun.enrollmentId) ? begun.enrollmentId : null;
51196
52538
  if (!enrollmentId) {
51197
52539
  throw new CliError(
51198
52540
  "The server did not start the enrollment.",
@@ -51210,7 +52552,7 @@ async function enroll(client2, workspaceId, opts = {}) {
51210
52552
  action: "enroll",
51211
52553
  approvalToken
51212
52554
  });
51213
- const deviceId = typeof done?.deviceId === "string" && UUID5.test(done.deviceId) ? done.deviceId : null;
52555
+ const deviceId = typeof done?.deviceId === "string" && UUID6.test(done.deviceId) ? done.deviceId : null;
51214
52556
  if (!deviceId) {
51215
52557
  throw new CliError(
51216
52558
  "The server did not complete the enrollment.",
@@ -51239,7 +52581,7 @@ async function enroll(client2, workspaceId, opts = {}) {
51239
52581
  }
51240
52582
 
51241
52583
  // src/commands/keys.ts
51242
- var UUID6 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
52584
+ var UUID7 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
51243
52585
  function patRequired(apiUrl) {
51244
52586
  return authError(
51245
52587
  "gad keys needs a personal access token; this sign-in is an OAuth session.",
@@ -51292,7 +52634,7 @@ async function keysContext() {
51292
52634
  });
51293
52635
  const value = await probe.mcpCall("workspace_introspect", {}, 5e3);
51294
52636
  const workspaceId = value?.workspace?.id;
51295
- if (value?.error || !workspaceId || !UUID6.test(workspaceId)) {
52637
+ if (value?.error || !workspaceId || !UUID7.test(workspaceId)) {
51296
52638
  throw validationError(
51297
52639
  "GreatArrow.ai could not confirm your workspace.",
51298
52640
  "Run 'gad whoami', or choose one with 'gad --workspace <id>'."
@@ -51313,7 +52655,7 @@ async function keysContext() {
51313
52655
  };
51314
52656
  }
51315
52657
  function requireRunId(runId) {
51316
- if (!UUID6.test(runId)) {
52658
+ if (!UUID7.test(runId)) {
51317
52659
  throw validationError(
51318
52660
  `'${stripControlChars(runId)}' is not a run id.`,
51319
52661
  "Copy the run id from 'gad keys list' or the run page."
@@ -51442,7 +52784,7 @@ function enrollCommand() {
51442
52784
  function toUpdateRow(v) {
51443
52785
  if (typeof v !== "object" || v === null) return null;
51444
52786
  const r = v;
51445
- if (typeof r.id !== "string" || !UUID6.test(r.id)) return null;
52787
+ if (typeof r.id !== "string" || !UUID7.test(r.id)) return null;
51446
52788
  const ref = {};
51447
52789
  if (typeof r.targetRef === "object" && r.targetRef !== null) {
51448
52790
  for (const [k, val] of Object.entries(r.targetRef)) {
@@ -51625,20 +52967,20 @@ function readHiddenFromTty(prompt, io = {
51625
52967
  callback();
51626
52968
  }
51627
52969
  });
51628
- const rl = createInterface3({
52970
+ const rl = createInterface4({
51629
52971
  input: io.input,
51630
52972
  output: sink,
51631
52973
  terminal: true
51632
52974
  });
51633
52975
  io.output.write(prompt);
51634
52976
  muted = true;
51635
- return new Promise((resolve5, reject) => {
52977
+ return new Promise((resolve7, reject) => {
51636
52978
  const lines = [];
51637
52979
  let pem = false;
51638
52980
  const finish = () => {
51639
52981
  rl.close();
51640
52982
  io.output.write("\n");
51641
- resolve5(lines.join("\n"));
52983
+ resolve7(lines.join("\n"));
51642
52984
  };
51643
52985
  rl.on("line", (line) => {
51644
52986
  if (lines.length === 0) pem = /^-----BEGIN /.test(line.trim());
@@ -51994,7 +53336,7 @@ function completionsCommand() {
51994
53336
 
51995
53337
  // node_modules/.pnpm/update-notifier@7.3.1/node_modules/update-notifier/update-notifier.js
51996
53338
  import process11 from "node:process";
51997
- import { spawn as spawn3 } from "node:child_process";
53339
+ import { spawn as spawn4 } from "node:child_process";
51998
53340
  import { fileURLToPath as fileURLToPath3 } from "node:url";
51999
53341
  import path9 from "node:path";
52000
53342
  import { format } from "node:util";
@@ -52070,7 +53412,7 @@ var retryifyAsync = (fn, options) => {
52070
53412
  throw error62;
52071
53413
  const delay2 = Math.round(interval * Math.random());
52072
53414
  if (delay2 > 0) {
52073
- const delayPromise = new Promise((resolve5) => setTimeout(resolve5, delay2));
53415
+ const delayPromise = new Promise((resolve7) => setTimeout(resolve7, delay2));
52074
53416
  return delayPromise.then(() => attempt.apply(void 0, args));
52075
53417
  } else {
52076
53418
  return attempt.apply(void 0, args);
@@ -53636,14 +54978,14 @@ var TimeoutError = class extends Error {
53636
54978
 
53637
54979
  // node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/timeout.js
53638
54980
  async function timeout(request, init, abortController, options) {
53639
- return new Promise((resolve5, reject) => {
54981
+ return new Promise((resolve7, reject) => {
53640
54982
  const timeoutId = setTimeout(() => {
53641
54983
  if (abortController) {
53642
54984
  abortController.abort();
53643
54985
  }
53644
54986
  reject(new TimeoutError(request));
53645
54987
  }, options.timeout);
53646
- void options.fetch(request, init).then(resolve5).catch(reject).then(() => {
54988
+ void options.fetch(request, init).then(resolve7).catch(reject).then(() => {
53647
54989
  clearTimeout(timeoutId);
53648
54990
  });
53649
54991
  });
@@ -53651,7 +54993,7 @@ async function timeout(request, init, abortController, options) {
53651
54993
 
53652
54994
  // node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/delay.js
53653
54995
  async function delay(ms, { signal }) {
53654
- return new Promise((resolve5, reject) => {
54996
+ return new Promise((resolve7, reject) => {
53655
54997
  if (signal) {
53656
54998
  signal.throwIfAborted();
53657
54999
  signal.addEventListener("abort", abortHandler, { once: true });
@@ -53662,7 +55004,7 @@ async function delay(ms, { signal }) {
53662
55004
  }
53663
55005
  const timeoutId = setTimeout(() => {
53664
55006
  signal?.removeEventListener("abort", abortHandler);
53665
- resolve5();
55007
+ resolve7();
53666
55008
  }, ms);
53667
55009
  });
53668
55010
  }
@@ -55291,7 +56633,7 @@ var UpdateNotifier = class {
55291
56633
  if (Date.now() - this.config.get("lastUpdateCheck") < this.#updateCheckInterval) {
55292
56634
  return;
55293
56635
  }
55294
- spawn3(process11.execPath, [path9.join(__dirname3, "check.js"), JSON.stringify(this.#options)], {
56636
+ spawn4(process11.execPath, [path9.join(__dirname3, "check.js"), JSON.stringify(this.#options)], {
55295
56637
  detached: true,
55296
56638
  stdio: "ignore"
55297
56639
  }).unref();