@posthog/agent 2.1.148 → 2.1.150

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.
@@ -904,7 +904,7 @@ var import_hono = require("hono");
904
904
  // package.json
905
905
  var package_default = {
906
906
  name: "@posthog/agent",
907
- version: "2.1.148",
907
+ version: "2.1.150",
908
908
  repository: "https://github.com/PostHog/twig",
909
909
  description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
910
910
  exports: {
@@ -3416,7 +3416,7 @@ function getAbortController(userProvidedController) {
3416
3416
  }
3417
3417
  return controller;
3418
3418
  }
3419
- function buildSpawnWrapper(sessionId, onProcessSpawned, onProcessExited) {
3419
+ function buildSpawnWrapper(sessionId, onProcessSpawned, onProcessExited, logger) {
3420
3420
  return (spawnOpts) => {
3421
3421
  const child = (0, import_node_child_process.spawn)(spawnOpts.command, spawnOpts.args, {
3422
3422
  cwd: spawnOpts.cwd,
@@ -3430,6 +3430,12 @@ function buildSpawnWrapper(sessionId, onProcessSpawned, onProcessExited) {
3430
3430
  sessionId
3431
3431
  });
3432
3432
  }
3433
+ child.stderr?.on("data", (data) => {
3434
+ const msg = data.toString().trim();
3435
+ if (msg && logger) {
3436
+ logger.debug(`[claude-code:${child.pid}] stderr: ${msg}`);
3437
+ }
3438
+ });
3433
3439
  if (onProcessExited) {
3434
3440
  child.on("exit", () => {
3435
3441
  if (child.pid) {
@@ -3521,7 +3527,8 @@ function buildSessionOptions(params) {
3521
3527
  spawnClaudeCodeProcess: buildSpawnWrapper(
3522
3528
  params.sessionId,
3523
3529
  params.onProcessSpawned,
3524
- params.onProcessExited
3530
+ params.onProcessExited,
3531
+ params.logger
3525
3532
  )
3526
3533
  }
3527
3534
  };
@@ -4524,7 +4531,7 @@ function spawnCodexProcess(options) {
4524
4531
  detached: process.platform !== "win32"
4525
4532
  });
4526
4533
  child.stderr?.on("data", (data) => {
4527
- logger.debug("codex-acp stderr:", data.toString());
4534
+ logger.warn("codex-acp stderr:", data.toString());
4528
4535
  });
4529
4536
  child.on("error", (err) => {
4530
4537
  logger.error("codex-acp process error:", err);
@@ -5087,12 +5094,14 @@ var PostHogAPIClient = class {
5087
5094
 
5088
5095
  // src/session-log-writer.ts
5089
5096
  var import_node_fs2 = __toESM(require("fs"), 1);
5097
+ var import_promises = __toESM(require("fs/promises"), 1);
5090
5098
  var import_node_path2 = __toESM(require("path"), 1);
5091
5099
  var SessionLogWriter = class _SessionLogWriter {
5092
5100
  static FLUSH_DEBOUNCE_MS = 500;
5093
5101
  static FLUSH_MAX_INTERVAL_MS = 5e3;
5094
5102
  static MAX_FLUSH_RETRIES = 10;
5095
5103
  static MAX_RETRY_DELAY_MS = 3e4;
5104
+ static SESSIONS_MAX_AGE_MS = 30 * 24 * 60 * 60 * 1e3;
5096
5105
  posthogAPI;
5097
5106
  pendingEntries = /* @__PURE__ */ new Map();
5098
5107
  flushTimeouts = /* @__PURE__ */ new Map();
@@ -5229,10 +5238,16 @@ var SessionLogWriter = class _SessionLogWriter {
5229
5238
  );
5230
5239
  this.retryCounts.set(sessionId, 0);
5231
5240
  } else {
5232
- this.logger.error(
5233
- `Failed to persist session logs (attempt ${retryCount}/${_SessionLogWriter.MAX_FLUSH_RETRIES}):`,
5234
- error
5235
- );
5241
+ if (retryCount === 1) {
5242
+ this.logger.warn(
5243
+ `Failed to persist session logs, will retry (up to ${_SessionLogWriter.MAX_FLUSH_RETRIES} attempts)`,
5244
+ {
5245
+ taskId: session.context.taskId,
5246
+ runId: session.context.runId,
5247
+ error: error instanceof Error ? error.message : String(error)
5248
+ }
5249
+ );
5250
+ }
5236
5251
  const currentPending = this.pendingEntries.get(sessionId) ?? [];
5237
5252
  this.pendingEntries.set(sessionId, [...pending, ...currentPending]);
5238
5253
  this.scheduleFlush(sessionId);
@@ -5346,6 +5361,27 @@ var SessionLogWriter = class _SessionLogWriter {
5346
5361
  });
5347
5362
  }
5348
5363
  }
5364
+ static async cleanupOldSessions(localCachePath) {
5365
+ const sessionsDir = import_node_path2.default.join(localCachePath, "sessions");
5366
+ let deleted = 0;
5367
+ try {
5368
+ const entries = await import_promises.default.readdir(sessionsDir);
5369
+ const now = Date.now();
5370
+ for (const entry of entries) {
5371
+ const entryPath = import_node_path2.default.join(sessionsDir, entry);
5372
+ try {
5373
+ const stats = await import_promises.default.stat(entryPath);
5374
+ if (stats.isDirectory() && now - stats.birthtimeMs > _SessionLogWriter.SESSIONS_MAX_AGE_MS) {
5375
+ await import_promises.default.rm(entryPath, { recursive: true, force: true });
5376
+ deleted++;
5377
+ }
5378
+ } catch {
5379
+ }
5380
+ }
5381
+ } catch {
5382
+ }
5383
+ return deleted;
5384
+ }
5349
5385
  };
5350
5386
 
5351
5387
  // ../git/dist/queries.js
@@ -9913,7 +9949,7 @@ function createGitClient(baseDir, options) {
9913
9949
 
9914
9950
  // ../git/dist/lock-detector.js
9915
9951
  var import_node_child_process3 = require("child_process");
9916
- var import_promises = __toESM(require("fs/promises"), 1);
9952
+ var import_promises2 = __toESM(require("fs/promises"), 1);
9917
9953
  var import_node_path4 = __toESM(require("path"), 1);
9918
9954
  var import_node_util = require("util");
9919
9955
  var execFileAsync = (0, import_node_util.promisify)(import_node_child_process3.execFile);
@@ -9928,7 +9964,7 @@ async function getIndexLockPath(repoPath) {
9928
9964
  async function getLockInfo(repoPath) {
9929
9965
  const lockPath = await getIndexLockPath(repoPath);
9930
9966
  try {
9931
- const stat = await import_promises.default.stat(lockPath);
9967
+ const stat = await import_promises2.default.stat(lockPath);
9932
9968
  return {
9933
9969
  path: lockPath,
9934
9970
  ageMs: Date.now() - stat.mtimeMs
@@ -9939,7 +9975,7 @@ async function getLockInfo(repoPath) {
9939
9975
  }
9940
9976
  async function removeLock(repoPath) {
9941
9977
  const lockPath = await getIndexLockPath(repoPath);
9942
- await import_promises.default.rm(lockPath, { force: true });
9978
+ await import_promises2.default.rm(lockPath, { force: true });
9943
9979
  }
9944
9980
  async function isLocked(repoPath) {
9945
9981
  return await getLockInfo(repoPath) !== null;
@@ -10105,7 +10141,7 @@ async function getHeadSha(baseDir, options) {
10105
10141
  }
10106
10142
 
10107
10143
  // src/sagas/apply-snapshot-saga.ts
10108
- var import_promises2 = require("fs/promises");
10144
+ var import_promises3 = require("fs/promises");
10109
10145
  var import_node_path5 = require("path");
10110
10146
 
10111
10147
  // ../shared/dist/index.js
@@ -10136,12 +10172,12 @@ var Saga = class {
10136
10172
  this.currentStepName = "unknown";
10137
10173
  this.stepTimings = [];
10138
10174
  const sagaStart = performance.now();
10139
- this.log.info("Starting saga", { sagaName: this.constructor.name });
10175
+ this.log.info("Starting saga", { sagaName: this.sagaName });
10140
10176
  try {
10141
10177
  const result = await this.execute(input);
10142
10178
  const totalDuration = performance.now() - sagaStart;
10143
10179
  this.log.debug("Saga completed successfully", {
10144
- sagaName: this.constructor.name,
10180
+ sagaName: this.sagaName,
10145
10181
  stepsCompleted: this.completedSteps.length,
10146
10182
  totalDurationMs: Math.round(totalDuration),
10147
10183
  stepTimings: this.stepTimings
@@ -10149,7 +10185,7 @@ var Saga = class {
10149
10185
  return { success: true, data: result };
10150
10186
  } catch (error) {
10151
10187
  this.log.error("Saga failed, initiating rollback", {
10152
- sagaName: this.constructor.name,
10188
+ sagaName: this.sagaName,
10153
10189
  failedStep: this.currentStepName,
10154
10190
  error: error instanceof Error ? error.message : String(error)
10155
10191
  });
@@ -10261,6 +10297,7 @@ var GitSaga = class extends Saga {
10261
10297
 
10262
10298
  // ../git/dist/sagas/tree.js
10263
10299
  var CaptureTreeSaga = class extends GitSaga {
10300
+ sagaName = "CaptureTreeSaga";
10264
10301
  tempIndexPath = null;
10265
10302
  async executeGitOperations(input) {
10266
10303
  const { baseDir, lastTreeHash, archivePath, signal } = input;
@@ -10381,6 +10418,7 @@ var CaptureTreeSaga = class extends GitSaga {
10381
10418
  }
10382
10419
  };
10383
10420
  var ApplyTreeSaga = class extends GitSaga {
10421
+ sagaName = "ApplyTreeSaga";
10384
10422
  originalHead = null;
10385
10423
  originalBranch = null;
10386
10424
  extractedFiles = [];
@@ -10515,6 +10553,7 @@ var ApplyTreeSaga = class extends GitSaga {
10515
10553
 
10516
10554
  // src/sagas/apply-snapshot-saga.ts
10517
10555
  var ApplySnapshotSaga = class extends Saga {
10556
+ sagaName = "ApplySnapshotSaga";
10518
10557
  archivePath = null;
10519
10558
  async execute(input) {
10520
10559
  const { snapshot, repositoryPath, apiClient, taskId, runId } = input;
@@ -10525,7 +10564,7 @@ var ApplySnapshotSaga = class extends Saga {
10525
10564
  const archiveUrl = snapshot.archiveUrl;
10526
10565
  await this.step({
10527
10566
  name: "create_tmp_dir",
10528
- execute: () => (0, import_promises2.mkdir)(tmpDir, { recursive: true }),
10567
+ execute: () => (0, import_promises3.mkdir)(tmpDir, { recursive: true }),
10529
10568
  rollback: async () => {
10530
10569
  }
10531
10570
  });
@@ -10544,11 +10583,11 @@ var ApplySnapshotSaga = class extends Saga {
10544
10583
  }
10545
10584
  const base64Content = Buffer.from(arrayBuffer).toString("utf-8");
10546
10585
  const binaryContent = Buffer.from(base64Content, "base64");
10547
- await (0, import_promises2.writeFile)(archivePath, binaryContent);
10586
+ await (0, import_promises3.writeFile)(archivePath, binaryContent);
10548
10587
  },
10549
10588
  rollback: async () => {
10550
10589
  if (this.archivePath) {
10551
- await (0, import_promises2.rm)(this.archivePath, { force: true }).catch(() => {
10590
+ await (0, import_promises3.rm)(this.archivePath, { force: true }).catch(() => {
10552
10591
  });
10553
10592
  }
10554
10593
  }
@@ -10564,7 +10603,7 @@ var ApplySnapshotSaga = class extends Saga {
10564
10603
  if (!applyResult.success) {
10565
10604
  throw new Error(`Failed to apply tree: ${applyResult.error}`);
10566
10605
  }
10567
- await (0, import_promises2.rm)(this.archivePath, { force: true }).catch(() => {
10606
+ await (0, import_promises3.rm)(this.archivePath, { force: true }).catch(() => {
10568
10607
  });
10569
10608
  this.log.info("Tree snapshot applied", {
10570
10609
  treeHash: snapshot.treeHash,
@@ -10577,9 +10616,10 @@ var ApplySnapshotSaga = class extends Saga {
10577
10616
 
10578
10617
  // src/sagas/capture-tree-saga.ts
10579
10618
  var import_node_fs4 = require("fs");
10580
- var import_promises3 = require("fs/promises");
10619
+ var import_promises4 = require("fs/promises");
10581
10620
  var import_node_path6 = require("path");
10582
10621
  var CaptureTreeSaga2 = class extends Saga {
10622
+ sagaName = "CaptureTreeSaga";
10583
10623
  async execute(input) {
10584
10624
  const {
10585
10625
  repositoryPath,
@@ -10626,7 +10666,7 @@ var CaptureTreeSaga2 = class extends Saga {
10626
10666
  runId
10627
10667
  );
10628
10668
  } finally {
10629
- await (0, import_promises3.rm)(createdArchivePath, { force: true }).catch(() => {
10669
+ await (0, import_promises4.rm)(createdArchivePath, { force: true }).catch(() => {
10630
10670
  });
10631
10671
  }
10632
10672
  }
@@ -10650,7 +10690,7 @@ var CaptureTreeSaga2 = class extends Saga {
10650
10690
  const archiveUrl = await this.step({
10651
10691
  name: "upload_archive",
10652
10692
  execute: async () => {
10653
- const archiveContent = await (0, import_promises3.readFile)(archivePath);
10693
+ const archiveContent = await (0, import_promises4.readFile)(archivePath);
10654
10694
  const base64Content = archiveContent.toString("base64");
10655
10695
  const artifacts = await apiClient.uploadTaskArtifacts(taskId, runId, [
10656
10696
  {
@@ -10670,7 +10710,7 @@ var CaptureTreeSaga2 = class extends Saga {
10670
10710
  return void 0;
10671
10711
  },
10672
10712
  rollback: async () => {
10673
- await (0, import_promises3.rm)(archivePath, { force: true }).catch(() => {
10713
+ await (0, import_promises4.rm)(archivePath, { force: true }).catch(() => {
10674
10714
  });
10675
10715
  }
10676
10716
  });