heyio 4.1.3 → 4.1.4

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.
@@ -80,7 +80,7 @@ var init_constants = __esm({
80
80
  "packages/shared/dist/constants.js"() {
81
81
  "use strict";
82
82
  APP_NAME = "io";
83
- APP_VERSION = "4.1.3";
83
+ APP_VERSION = "4.1.4";
84
84
  API_PORT = 7777;
85
85
  API_HOST = "0.0.0.0";
86
86
  DEFAULT_MODEL = "gpt-4o";
@@ -2112,6 +2112,18 @@ var init_db = __esm({
2112
2112
  "CREATE INDEX IF NOT EXISTS idx_squad_instances_status ON squad_instances(status)",
2113
2113
  "CREATE INDEX IF NOT EXISTS idx_squad_instances_objective_id ON squad_instances(objective_id)"
2114
2114
  ]
2115
+ },
2116
+ {
2117
+ version: 4,
2118
+ name: "denormalize-usage-names",
2119
+ statements: [
2120
+ "ALTER TABLE token_usage ADD COLUMN squad_name TEXT",
2121
+ "ALTER TABLE token_usage ADD COLUMN agent_name TEXT",
2122
+ `UPDATE token_usage SET
2123
+ squad_name = (SELECT s.name FROM squads s WHERE s.id = token_usage.squad_id),
2124
+ agent_name = (SELECT sm.name FROM squad_members sm WHERE sm.id = token_usage.agent_id)
2125
+ WHERE squad_id IS NOT NULL OR agent_id IS NOT NULL`
2126
+ ]
2115
2127
  }
2116
2128
  ];
2117
2129
  client = null;
@@ -11606,8 +11618,8 @@ var require_CronFileParser = __commonJS({
11606
11618
  * @throws If file cannot be read
11607
11619
  */
11608
11620
  static async parseFile(filePath) {
11609
- const { readFile: readFile10 } = await Promise.resolve().then(() => __importStar(__require("fs/promises")));
11610
- const data = await readFile10(filePath, "utf8");
11621
+ const { readFile: readFile11 } = await Promise.resolve().then(() => __importStar(__require("fs/promises")));
11622
+ const data = await readFile11(filePath, "utf8");
11611
11623
  return _CronFileParser.#parseContent(data);
11612
11624
  }
11613
11625
  /**
@@ -11876,8 +11888,8 @@ async function recordUsage(data, db) {
11876
11888
  createdAt: data.createdAt ?? nowIso()
11877
11889
  };
11878
11890
  await database.execute({
11879
- sql: `INSERT INTO token_usage (id, squad_id, agent_id, model, input_tokens, output_tokens, cost, premium_request_cost, token_unit_cost, created_at)
11880
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
11891
+ sql: `INSERT INTO token_usage (id, squad_id, agent_id, model, input_tokens, output_tokens, cost, premium_request_cost, token_unit_cost, squad_name, agent_name, created_at)
11892
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
11881
11893
  args: [
11882
11894
  usage.id,
11883
11895
  usage.squadId,
@@ -11888,6 +11900,8 @@ async function recordUsage(data, db) {
11888
11900
  usage.cost,
11889
11901
  data.premiumRequestCost ?? null,
11890
11902
  data.tokenUnitCost ?? null,
11903
+ data.squadName ?? null,
11904
+ data.agentName ?? null,
11891
11905
  usage.createdAt
11892
11906
  ]
11893
11907
  });
@@ -11952,8 +11966,8 @@ async function getUsageRecords(params = {}, db) {
11952
11966
  const result = await database.execute({
11953
11967
  sql: `SELECT tu.model, tu.input_tokens, tu.output_tokens, tu.cost,
11954
11968
  tu.created_at, tu.squad_id, tu.agent_id,
11955
- COALESCE(s.name, '') AS squad_name,
11956
- COALESCE(sm.name, '') AS agent_name
11969
+ COALESCE(s.name, tu.squad_name, '') AS squad_name,
11970
+ COALESCE(sm.name, tu.agent_name, '') AS agent_name
11957
11971
  FROM token_usage tu
11958
11972
  LEFT JOIN squads s ON s.id = tu.squad_id
11959
11973
  LEFT JOIN squad_members sm ON sm.id = tu.agent_id
@@ -31315,7 +31329,7 @@ var require_view = __commonJS({
31315
31329
  var dirname9 = path.dirname;
31316
31330
  var basename6 = path.basename;
31317
31331
  var extname4 = path.extname;
31318
- var join16 = path.join;
31332
+ var join17 = path.join;
31319
31333
  var resolve5 = path.resolve;
31320
31334
  module2.exports = View;
31321
31335
  function View(name, options2) {
@@ -31377,14 +31391,14 @@ var require_view = __commonJS({
31377
31391
  };
31378
31392
  View.prototype.resolve = function resolve6(dir, file2) {
31379
31393
  var ext = this.ext;
31380
- var path2 = join16(dir, file2);
31381
- var stat4 = tryStat(path2);
31382
- if (stat4 && stat4.isFile()) {
31394
+ var path2 = join17(dir, file2);
31395
+ var stat5 = tryStat(path2);
31396
+ if (stat5 && stat5.isFile()) {
31383
31397
  return path2;
31384
31398
  }
31385
- path2 = join16(dir, basename6(file2, ext), "index" + ext);
31386
- stat4 = tryStat(path2);
31387
- if (stat4 && stat4.isFile()) {
31399
+ path2 = join17(dir, basename6(file2, ext), "index" + ext);
31400
+ stat5 = tryStat(path2);
31401
+ if (stat5 && stat5.isFile()) {
31388
31402
  return path2;
31389
31403
  }
31390
31404
  };
@@ -31433,9 +31447,9 @@ var require_etag = __commonJS({
31433
31447
  }
31434
31448
  return obj && typeof obj === "object" && "ctime" in obj && toString.call(obj.ctime) === "[object Date]" && "mtime" in obj && toString.call(obj.mtime) === "[object Date]" && "ino" in obj && typeof obj.ino === "number" && "size" in obj && typeof obj.size === "number";
31435
31449
  }
31436
- function stattag(stat4) {
31437
- var mtime = stat4.mtime.getTime().toString(16);
31438
- var size = stat4.size.toString(16);
31450
+ function stattag(stat5) {
31451
+ var mtime = stat5.mtime.getTime().toString(16);
31452
+ var size = stat5.size.toString(16);
31439
31453
  return '"' + size + "-" + mtime + '"';
31440
31454
  }
31441
31455
  }
@@ -35087,7 +35101,7 @@ var require_send = __commonJS({
35087
35101
  var Stream = __require("stream");
35088
35102
  var util = __require("util");
35089
35103
  var extname4 = path.extname;
35090
- var join16 = path.join;
35104
+ var join17 = path.join;
35091
35105
  var normalize = path.normalize;
35092
35106
  var resolve5 = path.resolve;
35093
35107
  var sep = path.sep;
@@ -35259,7 +35273,7 @@ var require_send = __commonJS({
35259
35273
  return res;
35260
35274
  }
35261
35275
  parts = path2.split(sep);
35262
- path2 = normalize(join16(root, path2));
35276
+ path2 = normalize(join17(root, path2));
35263
35277
  } else {
35264
35278
  if (UP_PATH_REGEXP.test(path2)) {
35265
35279
  debug('malicious path "%s"', path2);
@@ -35290,8 +35304,8 @@ var require_send = __commonJS({
35290
35304
  this.sendFile(path2);
35291
35305
  return res;
35292
35306
  };
35293
- SendStream.prototype.send = function send3(path2, stat4) {
35294
- var len = stat4.size;
35307
+ SendStream.prototype.send = function send3(path2, stat5) {
35308
+ var len = stat5.size;
35295
35309
  var options2 = this.options;
35296
35310
  var opts = {};
35297
35311
  var res = this.res;
@@ -35303,7 +35317,7 @@ var require_send = __commonJS({
35303
35317
  return;
35304
35318
  }
35305
35319
  debug('pipe "%s"', path2);
35306
- this.setHeader(path2, stat4);
35320
+ this.setHeader(path2, stat5);
35307
35321
  this.type(path2);
35308
35322
  if (this.isConditionalGET()) {
35309
35323
  if (this.isPreconditionFailure()) {
@@ -35359,16 +35373,16 @@ var require_send = __commonJS({
35359
35373
  var i = 0;
35360
35374
  var self = this;
35361
35375
  debug('stat "%s"', path2);
35362
- fs.stat(path2, function onstat(err, stat4) {
35376
+ fs.stat(path2, function onstat(err, stat5) {
35363
35377
  var pathEndsWithSep = path2[path2.length - 1] === sep;
35364
35378
  if (err && err.code === "ENOENT" && !extname4(path2) && !pathEndsWithSep) {
35365
35379
  return next(err);
35366
35380
  }
35367
35381
  if (err) return self.onStatError(err);
35368
- if (stat4.isDirectory()) return self.redirect(path2);
35382
+ if (stat5.isDirectory()) return self.redirect(path2);
35369
35383
  if (pathEndsWithSep) return self.error(404);
35370
- self.emit("file", path2, stat4);
35371
- self.send(path2, stat4);
35384
+ self.emit("file", path2, stat5);
35385
+ self.send(path2, stat5);
35372
35386
  });
35373
35387
  function next(err) {
35374
35388
  if (self._extensions.length <= i) {
@@ -35376,11 +35390,11 @@ var require_send = __commonJS({
35376
35390
  }
35377
35391
  var p = path2 + "." + self._extensions[i++];
35378
35392
  debug('stat "%s"', p);
35379
- fs.stat(p, function(err2, stat4) {
35393
+ fs.stat(p, function(err2, stat5) {
35380
35394
  if (err2) return next(err2);
35381
- if (stat4.isDirectory()) return next();
35382
- self.emit("file", p, stat4);
35383
- self.send(p, stat4);
35395
+ if (stat5.isDirectory()) return next();
35396
+ self.emit("file", p, stat5);
35397
+ self.send(p, stat5);
35384
35398
  });
35385
35399
  }
35386
35400
  };
@@ -35392,13 +35406,13 @@ var require_send = __commonJS({
35392
35406
  if (err) return self.onStatError(err);
35393
35407
  return self.error(404);
35394
35408
  }
35395
- var p = join16(path2, self._index[i]);
35409
+ var p = join17(path2, self._index[i]);
35396
35410
  debug('stat "%s"', p);
35397
- fs.stat(p, function(err2, stat4) {
35411
+ fs.stat(p, function(err2, stat5) {
35398
35412
  if (err2) return next(err2);
35399
- if (stat4.isDirectory()) return next();
35400
- self.emit("file", p, stat4);
35401
- self.send(p, stat4);
35413
+ if (stat5.isDirectory()) return next();
35414
+ self.emit("file", p, stat5);
35415
+ self.send(p, stat5);
35402
35416
  });
35403
35417
  }
35404
35418
  next();
@@ -35429,9 +35443,9 @@ var require_send = __commonJS({
35429
35443
  debug("content-type %s", type2);
35430
35444
  res.setHeader("Content-Type", type2);
35431
35445
  };
35432
- SendStream.prototype.setHeader = function setHeader(path2, stat4) {
35446
+ SendStream.prototype.setHeader = function setHeader(path2, stat5) {
35433
35447
  var res = this.res;
35434
- this.emit("headers", res, path2, stat4);
35448
+ this.emit("headers", res, path2, stat5);
35435
35449
  if (this._acceptRanges && !res.getHeader("Accept-Ranges")) {
35436
35450
  debug("accept ranges");
35437
35451
  res.setHeader("Accept-Ranges", "bytes");
@@ -35445,12 +35459,12 @@ var require_send = __commonJS({
35445
35459
  res.setHeader("Cache-Control", cacheControl);
35446
35460
  }
35447
35461
  if (this._lastModified && !res.getHeader("Last-Modified")) {
35448
- var modified = stat4.mtime.toUTCString();
35462
+ var modified = stat5.mtime.toUTCString();
35449
35463
  debug("modified %s", modified);
35450
35464
  res.setHeader("Last-Modified", modified);
35451
35465
  }
35452
35466
  if (this._etag && !res.getHeader("ETag")) {
35453
- var val = etag(stat4);
35467
+ var val = etag(stat5);
35454
35468
  debug("etag %s", val);
35455
35469
  res.setHeader("ETag", val);
35456
35470
  }
@@ -52395,10 +52409,10 @@ async function spawnInstance(input2) {
52395
52409
  async function startInstance(instanceId, repoPath, baseBranch) {
52396
52410
  const branchName = `squad/instance-${instanceId.slice(0, 8)}`;
52397
52411
  try {
52398
- const { exec: exec8 } = await import("node:child_process");
52399
- const { promisify: promisify8 } = await import("node:util");
52400
- const execAsync8 = promisify8(exec8);
52401
- await execAsync8(`git fetch origin && git pull origin ${baseBranch}`, {
52412
+ const { exec: exec9 } = await import("node:child_process");
52413
+ const { promisify: promisify9 } = await import("node:util");
52414
+ const execAsync9 = promisify9(exec9);
52415
+ await execAsync9(`git fetch origin && git pull origin ${baseBranch}`, {
52402
52416
  cwd: repoPath,
52403
52417
  maxBuffer: 10 * 1024 * 1024
52404
52418
  });
@@ -54266,7 +54280,7 @@ var require_sonic_boom = __commonJS({
54266
54280
  if (!(this instanceof SonicBoom)) {
54267
54281
  return new SonicBoom(opts);
54268
54282
  }
54269
- let { fd, dest, minLength, maxLength, maxWrite, periodicFlush, sync, append = true, mkdir: mkdir10, retryEAGAIN, fsync, contentMode, mode } = opts || {};
54283
+ let { fd, dest, minLength, maxLength, maxWrite, periodicFlush, sync, append = true, mkdir: mkdir11, retryEAGAIN, fsync, contentMode, mode } = opts || {};
54270
54284
  fd = fd || dest;
54271
54285
  this._len = 0;
54272
54286
  this.fd = -1;
@@ -54291,7 +54305,7 @@ var require_sonic_boom = __commonJS({
54291
54305
  this.append = append || false;
54292
54306
  this.mode = mode;
54293
54307
  this.retryEAGAIN = retryEAGAIN || (() => true);
54294
- this.mkdir = mkdir10 || false;
54308
+ this.mkdir = mkdir11 || false;
54295
54309
  let fsWriteSync;
54296
54310
  let fsWrite;
54297
54311
  if (contentMode === kContentModeBuffer) {
@@ -55009,7 +55023,7 @@ var require_thread_stream = __commonJS({
55009
55023
  var { version: version2 } = require_package();
55010
55024
  var { EventEmitter: EventEmitter2 } = __require("events");
55011
55025
  var { Worker } = __require("worker_threads");
55012
- var { join: join16 } = __require("path");
55026
+ var { join: join17 } = __require("path");
55013
55027
  var { pathToFileURL: pathToFileURL2 } = __require("url");
55014
55028
  var { wait } = require_wait();
55015
55029
  var {
@@ -55052,7 +55066,7 @@ var require_thread_stream = __commonJS({
55052
55066
  function createWorker(stream, opts) {
55053
55067
  const { filename, workerData } = opts;
55054
55068
  const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
55055
- const toExecute = bundlerOverrides["thread-stream-worker"] || join16(__dirname, "lib", "worker.js");
55069
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join17(__dirname, "lib", "worker.js");
55056
55070
  const worker = new Worker(toExecute, {
55057
55071
  ...opts.workerOpts,
55058
55072
  trackUnmanagedFds: false,
@@ -55455,7 +55469,7 @@ var require_transport = __commonJS({
55455
55469
  "use strict";
55456
55470
  var { createRequire } = __require("module");
55457
55471
  var getCallers = require_caller();
55458
- var { join: join16, isAbsolute: isAbsolute2, sep } = __require("node:path");
55472
+ var { join: join17, isAbsolute: isAbsolute2, sep } = __require("node:path");
55459
55473
  var sleep = require_atomic_sleep();
55460
55474
  var onExit = require_on_exit_leak_free();
55461
55475
  var ThreadStream = require_thread_stream();
@@ -55518,7 +55532,7 @@ var require_transport = __commonJS({
55518
55532
  throw new Error("only one of target or targets can be specified");
55519
55533
  }
55520
55534
  if (targets) {
55521
- target = bundlerOverrides["pino-worker"] || join16(__dirname, "worker.js");
55535
+ target = bundlerOverrides["pino-worker"] || join17(__dirname, "worker.js");
55522
55536
  options2.targets = targets.filter((dest) => dest.target).map((dest) => {
55523
55537
  return {
55524
55538
  ...dest,
@@ -55536,7 +55550,7 @@ var require_transport = __commonJS({
55536
55550
  });
55537
55551
  });
55538
55552
  } else if (pipeline) {
55539
- target = bundlerOverrides["pino-worker"] || join16(__dirname, "worker.js");
55553
+ target = bundlerOverrides["pino-worker"] || join17(__dirname, "worker.js");
55540
55554
  options2.pipelines = [pipeline.map((dest) => {
55541
55555
  return {
55542
55556
  ...dest,
@@ -55558,7 +55572,7 @@ var require_transport = __commonJS({
55558
55572
  return origin;
55559
55573
  }
55560
55574
  if (origin === "pino/file") {
55561
- return join16(__dirname, "..", "file.js");
55575
+ return join17(__dirname, "..", "file.js");
55562
55576
  }
55563
55577
  let fixTarget2;
55564
55578
  for (const filePath of callers) {
@@ -56547,7 +56561,7 @@ var require_safe_stable_stringify = __commonJS({
56547
56561
  return circularValue;
56548
56562
  }
56549
56563
  let res = "";
56550
- let join16 = ",";
56564
+ let join17 = ",";
56551
56565
  const originalIndentation = indentation;
56552
56566
  if (Array.isArray(value)) {
56553
56567
  if (value.length === 0) {
@@ -56561,7 +56575,7 @@ var require_safe_stable_stringify = __commonJS({
56561
56575
  indentation += spacer;
56562
56576
  res += `
56563
56577
  ${indentation}`;
56564
- join16 = `,
56578
+ join17 = `,
56565
56579
  ${indentation}`;
56566
56580
  }
56567
56581
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -56569,13 +56583,13 @@ ${indentation}`;
56569
56583
  for (; i < maximumValuesToStringify - 1; i++) {
56570
56584
  const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
56571
56585
  res += tmp2 !== void 0 ? tmp2 : "null";
56572
- res += join16;
56586
+ res += join17;
56573
56587
  }
56574
56588
  const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
56575
56589
  res += tmp !== void 0 ? tmp : "null";
56576
56590
  if (value.length - 1 > maximumBreadth) {
56577
56591
  const removedKeys = value.length - maximumBreadth - 1;
56578
- res += `${join16}"... ${getItemCount(removedKeys)} not stringified"`;
56592
+ res += `${join17}"... ${getItemCount(removedKeys)} not stringified"`;
56579
56593
  }
56580
56594
  if (spacer !== "") {
56581
56595
  res += `
@@ -56596,7 +56610,7 @@ ${originalIndentation}`;
56596
56610
  let separator = "";
56597
56611
  if (spacer !== "") {
56598
56612
  indentation += spacer;
56599
- join16 = `,
56613
+ join17 = `,
56600
56614
  ${indentation}`;
56601
56615
  whitespace = " ";
56602
56616
  }
@@ -56610,13 +56624,13 @@ ${indentation}`;
56610
56624
  const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
56611
56625
  if (tmp !== void 0) {
56612
56626
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
56613
- separator = join16;
56627
+ separator = join17;
56614
56628
  }
56615
56629
  }
56616
56630
  if (keyLength > maximumBreadth) {
56617
56631
  const removedKeys = keyLength - maximumBreadth;
56618
56632
  res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
56619
- separator = join16;
56633
+ separator = join17;
56620
56634
  }
56621
56635
  if (spacer !== "" && separator.length > 1) {
56622
56636
  res = `
@@ -56657,7 +56671,7 @@ ${originalIndentation}`;
56657
56671
  }
56658
56672
  const originalIndentation = indentation;
56659
56673
  let res = "";
56660
- let join16 = ",";
56674
+ let join17 = ",";
56661
56675
  if (Array.isArray(value)) {
56662
56676
  if (value.length === 0) {
56663
56677
  return "[]";
@@ -56670,7 +56684,7 @@ ${originalIndentation}`;
56670
56684
  indentation += spacer;
56671
56685
  res += `
56672
56686
  ${indentation}`;
56673
- join16 = `,
56687
+ join17 = `,
56674
56688
  ${indentation}`;
56675
56689
  }
56676
56690
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -56678,13 +56692,13 @@ ${indentation}`;
56678
56692
  for (; i < maximumValuesToStringify - 1; i++) {
56679
56693
  const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
56680
56694
  res += tmp2 !== void 0 ? tmp2 : "null";
56681
- res += join16;
56695
+ res += join17;
56682
56696
  }
56683
56697
  const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
56684
56698
  res += tmp !== void 0 ? tmp : "null";
56685
56699
  if (value.length - 1 > maximumBreadth) {
56686
56700
  const removedKeys = value.length - maximumBreadth - 1;
56687
- res += `${join16}"... ${getItemCount(removedKeys)} not stringified"`;
56701
+ res += `${join17}"... ${getItemCount(removedKeys)} not stringified"`;
56688
56702
  }
56689
56703
  if (spacer !== "") {
56690
56704
  res += `
@@ -56697,7 +56711,7 @@ ${originalIndentation}`;
56697
56711
  let whitespace = "";
56698
56712
  if (spacer !== "") {
56699
56713
  indentation += spacer;
56700
- join16 = `,
56714
+ join17 = `,
56701
56715
  ${indentation}`;
56702
56716
  whitespace = " ";
56703
56717
  }
@@ -56706,7 +56720,7 @@ ${indentation}`;
56706
56720
  const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
56707
56721
  if (tmp !== void 0) {
56708
56722
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
56709
- separator = join16;
56723
+ separator = join17;
56710
56724
  }
56711
56725
  }
56712
56726
  if (spacer !== "" && separator.length > 1) {
@@ -56764,20 +56778,20 @@ ${originalIndentation}`;
56764
56778
  indentation += spacer;
56765
56779
  let res2 = `
56766
56780
  ${indentation}`;
56767
- const join17 = `,
56781
+ const join18 = `,
56768
56782
  ${indentation}`;
56769
56783
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
56770
56784
  let i = 0;
56771
56785
  for (; i < maximumValuesToStringify - 1; i++) {
56772
56786
  const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
56773
56787
  res2 += tmp2 !== void 0 ? tmp2 : "null";
56774
- res2 += join17;
56788
+ res2 += join18;
56775
56789
  }
56776
56790
  const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
56777
56791
  res2 += tmp !== void 0 ? tmp : "null";
56778
56792
  if (value.length - 1 > maximumBreadth) {
56779
56793
  const removedKeys = value.length - maximumBreadth - 1;
56780
- res2 += `${join17}"... ${getItemCount(removedKeys)} not stringified"`;
56794
+ res2 += `${join18}"... ${getItemCount(removedKeys)} not stringified"`;
56781
56795
  }
56782
56796
  res2 += `
56783
56797
  ${originalIndentation}`;
@@ -56793,16 +56807,16 @@ ${originalIndentation}`;
56793
56807
  return '"[Object]"';
56794
56808
  }
56795
56809
  indentation += spacer;
56796
- const join16 = `,
56810
+ const join17 = `,
56797
56811
  ${indentation}`;
56798
56812
  let res = "";
56799
56813
  let separator = "";
56800
56814
  let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
56801
56815
  if (isTypedArrayWithEntries(value)) {
56802
- res += stringifyTypedArray(value, join16, maximumBreadth);
56816
+ res += stringifyTypedArray(value, join17, maximumBreadth);
56803
56817
  keys = keys.slice(value.length);
56804
56818
  maximumPropertiesToStringify -= value.length;
56805
- separator = join16;
56819
+ separator = join17;
56806
56820
  }
56807
56821
  if (deterministic) {
56808
56822
  keys = sort(keys, comparator);
@@ -56813,13 +56827,13 @@ ${indentation}`;
56813
56827
  const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
56814
56828
  if (tmp !== void 0) {
56815
56829
  res += `${separator}${strEscape(key2)}: ${tmp}`;
56816
- separator = join16;
56830
+ separator = join17;
56817
56831
  }
56818
56832
  }
56819
56833
  if (keyLength > maximumBreadth) {
56820
56834
  const removedKeys = keyLength - maximumBreadth;
56821
56835
  res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
56822
- separator = join16;
56836
+ separator = join17;
56823
56837
  }
56824
56838
  if (separator !== "") {
56825
56839
  res = `
@@ -69429,7 +69443,8 @@ function mergeUsage(target, usage) {
69429
69443
  target.models.push(usage.model);
69430
69444
  }
69431
69445
  }
69432
- async function persistUsage(member, usageEvents) {
69446
+ async function persistUsage(member, usageEvents, squadName) {
69447
+ const resolvedSquadName = squadName ?? (member.squadId ? (await getSquad(member.squadId))?.name : null) ?? null;
69433
69448
  for (const usage of usageEvents) {
69434
69449
  const model = usage.model;
69435
69450
  const pricing = await getModelPricing(model);
@@ -69442,7 +69457,9 @@ async function persistUsage(member, usageEvents) {
69442
69457
  ) : 0;
69443
69458
  await recordUsage({
69444
69459
  squadId: member.squadId,
69460
+ squadName: resolvedSquadName,
69445
69461
  agentId: member.id,
69462
+ agentName: member.name,
69446
69463
  model,
69447
69464
  inputTokens: usage.inputTokens ?? 0,
69448
69465
  outputTokens: usage.outputTokens ?? 0,
@@ -70368,7 +70385,11 @@ async function runGit2(command, cwd) {
70368
70385
  return stdout.trim();
70369
70386
  }
70370
70387
  async function resolveRepoPath(repoUrl, repoName) {
70388
+ const urlSegments = repoUrl.replace(/\.git$/i, "").split("/").filter(Boolean);
70389
+ const owner = urlSegments.at(-2) ?? "";
70390
+ const managedDir = owner && repoName ? join15(DATA_DIR, "repos", `${owner}--${repoName}`) : null;
70371
70391
  const candidates = [
70392
+ ...managedDir ? [managedDir] : [],
70372
70393
  process.cwd(),
70373
70394
  join15(process.cwd(), repoName),
70374
70395
  join15(process.cwd(), "repos", repoName),
@@ -70635,6 +70656,7 @@ var init_runner = __esm({
70635
70656
  "packages/daemon/src/execution/runner.ts"() {
70636
70657
  "use strict";
70637
70658
  init_dist();
70659
+ init_paths();
70638
70660
  init_event_bus();
70639
70661
  init_manager2();
70640
70662
  init_store2();
@@ -70886,6 +70908,18 @@ var init_hiring = __esm({
70886
70908
  });
70887
70909
 
70888
70910
  // packages/daemon/src/orchestrator/tools/squad.ts
70911
+ import { exec as exec8 } from "node:child_process";
70912
+ import { mkdir as mkdir10, readFile as readFile9, readdir as readdir6, stat as stat4 } from "node:fs/promises";
70913
+ import { join as join16 } from "node:path";
70914
+ import { promisify as promisify8 } from "node:util";
70915
+ async function pathExists2(path) {
70916
+ try {
70917
+ await stat4(path);
70918
+ return true;
70919
+ } catch {
70920
+ return false;
70921
+ }
70922
+ }
70889
70923
  function getDefaultSquadConfig(_config) {
70890
70924
  return {
70891
70925
  prMode: "draft-pr",
@@ -70905,58 +70939,94 @@ async function buildRepoAnalysis(repoUrl) {
70905
70939
  );
70906
70940
  return lines.join("\n");
70907
70941
  }
70908
- const headers = { Accept: "application/vnd.github+json" };
70909
- if (process.env.GITHUB_TOKEN) {
70910
- headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`;
70942
+ const repoDir = join16(DATA_DIR, "repos", `${owner}--${name}`);
70943
+ try {
70944
+ await mkdir10(join16(DATA_DIR, "repos"), { recursive: true });
70945
+ if (await pathExists2(join16(repoDir, ".git"))) {
70946
+ await execAsync8("git pull --ff-only", { cwd: repoDir, timeout: 3e4 }).catch(
70947
+ () => void 0
70948
+ );
70949
+ } else {
70950
+ await execAsync8(`git clone --depth 50 ${normalized} "${repoDir}"`, {
70951
+ timeout: 6e4
70952
+ });
70953
+ }
70954
+ } catch {
70955
+ lines.push("Unable to clone repository locally; falling back to basic analysis.");
70956
+ lines.push("Based on the repository name, propose roles that match common project patterns.");
70957
+ return lines.join("\n");
70911
70958
  }
70912
70959
  try {
70913
- const metaRes = await fetch(`https://api.github.com/repos/${owner}/${name}`, { headers });
70914
- if (metaRes.ok) {
70915
- const meta3 = await metaRes.json();
70916
- if (meta3.description) lines.push(`Description: ${meta3.description}`);
70917
- if (meta3.language) lines.push(`Primary language: ${meta3.language}`);
70918
- if (meta3.topics?.length) lines.push(`Topics: ${meta3.topics.join(", ")}`);
70919
- }
70920
- const treeRes = await fetch(
70921
- `https://api.github.com/repos/${owner}/${name}/git/trees/HEAD?recursive=false`,
70922
- { headers }
70923
- );
70924
- if (treeRes.ok) {
70925
- const tree = await treeRes.json();
70926
- const rootFiles = (tree.tree ?? []).filter((entry) => entry.type === "blob").map((entry) => entry.path);
70927
- const rootDirs = (tree.tree ?? []).filter((entry) => entry.type === "tree").map((entry) => entry.path);
70928
- if (rootFiles.length) lines.push(`Root files: ${rootFiles.join(", ")}`);
70929
- if (rootDirs.length) lines.push(`Root directories: ${rootDirs.join(", ")}`);
70930
- }
70931
- const manifests = [
70960
+ const rootEntries = await readdir6(repoDir, { withFileTypes: true });
70961
+ const rootFiles = rootEntries.filter((e) => e.isFile()).map((e) => e.name);
70962
+ const rootDirs = rootEntries.filter((e) => e.isDirectory() && e.name !== ".git").map((e) => e.name);
70963
+ if (rootFiles.length) lines.push(`Root files: ${rootFiles.join(", ")}`);
70964
+ if (rootDirs.length) lines.push(`Root directories: ${rootDirs.join(", ")}`);
70965
+ const manifestFiles = [
70932
70966
  "package.json",
70933
70967
  "Cargo.toml",
70934
70968
  "go.mod",
70935
70969
  "requirements.txt",
70936
- "pyproject.toml"
70970
+ "pyproject.toml",
70971
+ "Gemfile",
70972
+ "pom.xml",
70973
+ "build.gradle",
70974
+ "composer.json",
70975
+ "Makefile",
70976
+ "Dockerfile",
70977
+ "docker-compose.yml",
70978
+ "docker-compose.yaml",
70979
+ ".github/workflows"
70937
70980
  ];
70938
- for (const manifest of manifests) {
70981
+ for (const manifest of manifestFiles) {
70982
+ const fullPath = join16(repoDir, manifest);
70939
70983
  try {
70940
- const fileRes = await fetch(
70941
- `https://api.github.com/repos/${owner}/${name}/contents/${manifest}`,
70942
- { headers }
70943
- );
70944
- if (fileRes.ok) {
70945
- const file2 = await fileRes.json();
70946
- if (file2.content && file2.encoding === "base64") {
70947
- const decoded = Buffer.from(file2.content, "base64").toString("utf8");
70948
- lines.push(`
70984
+ const fileStat = await stat4(fullPath);
70985
+ if (fileStat.isFile()) {
70986
+ const content = await readFile9(fullPath, "utf8");
70987
+ lines.push(`
70949
70988
  --- ${manifest} ---
70950
- ${decoded.slice(0, 2e3)}`);
70951
- }
70989
+ ${content.slice(0, 3e3)}`);
70990
+ } else if (fileStat.isDirectory()) {
70991
+ const children = await readdir6(fullPath);
70992
+ lines.push(`
70993
+ --- ${manifest}/ ---
70994
+ ${children.join(", ")}`);
70952
70995
  }
70953
70996
  } catch {
70954
70997
  }
70955
70998
  }
70999
+ const srcDirs = rootDirs.filter(
71000
+ (d) => ["src", "lib", "app", "packages", "crates", "cmd", "internal"].includes(d)
71001
+ );
71002
+ for (const srcDir of srcDirs) {
71003
+ try {
71004
+ const srcEntries = await readdir6(join16(repoDir, srcDir), { withFileTypes: true });
71005
+ const srcFiles = srcEntries.filter((e) => e.isFile()).map((e) => e.name);
71006
+ const srcSubDirs = srcEntries.filter((e) => e.isDirectory()).map((e) => e.name);
71007
+ lines.push(`
71008
+ --- ${srcDir}/ ---`);
71009
+ if (srcSubDirs.length) lines.push(` Directories: ${srcSubDirs.join(", ")}`);
71010
+ if (srcFiles.length) lines.push(` Files: ${srcFiles.slice(0, 30).join(", ")}`);
71011
+ } catch {
71012
+ }
71013
+ }
71014
+ const readmeCandidates = ["README.md", "README.rst", "README.txt", "README"];
71015
+ for (const readme of readmeCandidates) {
71016
+ try {
71017
+ const content = await readFile9(join16(repoDir, readme), "utf8");
71018
+ lines.push(`
71019
+ --- ${readme} (excerpt) ---
71020
+ ${content.slice(0, 1500)}`);
71021
+ break;
71022
+ } catch {
71023
+ }
71024
+ }
70956
71025
  } catch {
71026
+ lines.push("Filesystem scan failed; using minimal info.");
70957
71027
  }
70958
71028
  lines.push(
70959
- "\nBased on the above repository structure, propose roles that match the project's actual technology stack."
71029
+ "\nBased on the above repository structure and contents, propose roles that match the project's actual technology stack and architecture."
70960
71030
  );
70961
71031
  return lines.join("\n");
70962
71032
  }
@@ -71079,17 +71149,19 @@ function createSquadToolExecutor(config2) {
71079
71149
  }
71080
71150
  };
71081
71151
  }
71082
- var hireSquadSchema, squadIdSchema, delegateToSquadSchema, squadToolDefinitions;
71152
+ var execAsync8, hireSquadSchema, squadIdSchema, delegateToSquadSchema, squadToolDefinitions;
71083
71153
  var init_squad2 = __esm({
71084
71154
  "packages/daemon/src/orchestrator/tools/squad.ts"() {
71085
71155
  "use strict";
71086
71156
  init_dist();
71157
+ init_paths();
71087
71158
  init_zod();
71088
71159
  init_instances2();
71089
71160
  init_runner();
71090
71161
  init_hiring();
71091
71162
  init_manager2();
71092
71163
  init_store2();
71164
+ execAsync8 = promisify8(exec8);
71093
71165
  hireSquadSchema = external_exports.object({
71094
71166
  repoUrl: external_exports.string().trim().min(1)
71095
71167
  });
@@ -85259,7 +85331,7 @@ var init_index = __esm({
85259
85331
  init_dist();
85260
85332
  init_paths();
85261
85333
  init_data_dir();
85262
- import { readFile as readFile9, writeFile as writeFile8 } from "node:fs/promises";
85334
+ import { readFile as readFile10, writeFile as writeFile8 } from "node:fs/promises";
85263
85335
  import { stdin as input, stdout as output } from "node:process";
85264
85336
  import { createInterface } from "node:readline/promises";
85265
85337
  function printHelp() {
@@ -85274,7 +85346,7 @@ Usage:
85274
85346
  }
85275
85347
  async function readExistingConfig() {
85276
85348
  try {
85277
- const existingConfig = await readFile9(CONFIG_PATH, "utf8");
85349
+ const existingConfig = await readFile10(CONFIG_PATH, "utf8");
85278
85350
  const parsedConfig = JSON.parse(existingConfig);
85279
85351
  if (parsedConfig === null || typeof parsedConfig !== "object" || Array.isArray(parsedConfig)) {
85280
85352
  throw new Error(`Invalid config file at ${CONFIG_PATH}: expected a JSON object`);