@posthog/agent 2.1.35 → 2.1.47

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.
@@ -1178,12 +1178,174 @@ import {
1178
1178
  import {
1179
1179
  query
1180
1180
  } from "@anthropic-ai/claude-agent-sdk";
1181
+
1182
+ // ../shared/dist/index.js
1183
+ var consoleLogger = {
1184
+ info: (_message, _data) => {
1185
+ },
1186
+ debug: (_message, _data) => {
1187
+ },
1188
+ error: (_message, _data) => {
1189
+ },
1190
+ warn: (_message, _data) => {
1191
+ }
1192
+ };
1193
+ var Saga = class {
1194
+ completedSteps = [];
1195
+ currentStepName = "unknown";
1196
+ stepTimings = [];
1197
+ log;
1198
+ constructor(logger) {
1199
+ this.log = logger ?? consoleLogger;
1200
+ }
1201
+ /**
1202
+ * Run the saga with the given input.
1203
+ * Returns a discriminated union result - either success with data or failure with error details.
1204
+ */
1205
+ async run(input) {
1206
+ this.completedSteps = [];
1207
+ this.currentStepName = "unknown";
1208
+ this.stepTimings = [];
1209
+ const sagaStart = performance.now();
1210
+ this.log.info("Starting saga", { sagaName: this.constructor.name });
1211
+ try {
1212
+ const result = await this.execute(input);
1213
+ const totalDuration = performance.now() - sagaStart;
1214
+ this.log.debug("Saga completed successfully", {
1215
+ sagaName: this.constructor.name,
1216
+ stepsCompleted: this.completedSteps.length,
1217
+ totalDurationMs: Math.round(totalDuration),
1218
+ stepTimings: this.stepTimings
1219
+ });
1220
+ return { success: true, data: result };
1221
+ } catch (error) {
1222
+ this.log.error("Saga failed, initiating rollback", {
1223
+ sagaName: this.constructor.name,
1224
+ failedStep: this.currentStepName,
1225
+ error: error instanceof Error ? error.message : String(error)
1226
+ });
1227
+ await this.rollback();
1228
+ return {
1229
+ success: false,
1230
+ error: error instanceof Error ? error.message : String(error),
1231
+ failedStep: this.currentStepName
1232
+ };
1233
+ }
1234
+ }
1235
+ /**
1236
+ * Execute a step with its rollback action.
1237
+ * If the step succeeds, its rollback action is stored for potential rollback.
1238
+ * The step name is automatically tracked for error reporting.
1239
+ *
1240
+ * @param config - Step configuration with name, execute, and rollback functions
1241
+ * @returns The result of the execute function
1242
+ * @throws Re-throws any error from the execute function (triggers rollback)
1243
+ */
1244
+ async step(config) {
1245
+ this.currentStepName = config.name;
1246
+ this.log.debug(`Executing step: ${config.name}`);
1247
+ const stepStart = performance.now();
1248
+ const result = await config.execute();
1249
+ const durationMs = Math.round(performance.now() - stepStart);
1250
+ this.stepTimings.push({ name: config.name, durationMs });
1251
+ this.log.debug(`Step completed: ${config.name}`, { durationMs });
1252
+ this.completedSteps.push({
1253
+ name: config.name,
1254
+ rollback: () => config.rollback(result)
1255
+ });
1256
+ return result;
1257
+ }
1258
+ /**
1259
+ * Execute a step that doesn't need rollback.
1260
+ * Useful for read-only operations or operations that are idempotent.
1261
+ * The step name is automatically tracked for error reporting.
1262
+ *
1263
+ * @param name - Step name for logging and error tracking
1264
+ * @param execute - The action to execute
1265
+ * @returns The result of the execute function
1266
+ */
1267
+ async readOnlyStep(name, execute) {
1268
+ this.currentStepName = name;
1269
+ this.log.debug(`Executing read-only step: ${name}`);
1270
+ const stepStart = performance.now();
1271
+ const result = await execute();
1272
+ const durationMs = Math.round(performance.now() - stepStart);
1273
+ this.stepTimings.push({ name, durationMs });
1274
+ this.log.debug(`Read-only step completed: ${name}`, { durationMs });
1275
+ return result;
1276
+ }
1277
+ /**
1278
+ * Roll back all completed steps in reverse order.
1279
+ * Rollback errors are logged but don't stop the rollback of other steps.
1280
+ */
1281
+ async rollback() {
1282
+ this.log.info("Rolling back saga", {
1283
+ stepsToRollback: this.completedSteps.length
1284
+ });
1285
+ const stepsReversed = [...this.completedSteps].reverse();
1286
+ for (const step of stepsReversed) {
1287
+ try {
1288
+ this.log.debug(`Rolling back step: ${step.name}`);
1289
+ await step.rollback();
1290
+ this.log.debug(`Step rolled back: ${step.name}`);
1291
+ } catch (error) {
1292
+ this.log.error(`Failed to rollback step: ${step.name}`, {
1293
+ error: error instanceof Error ? error.message : String(error)
1294
+ });
1295
+ }
1296
+ }
1297
+ this.log.info("Rollback completed", {
1298
+ stepsAttempted: this.completedSteps.length
1299
+ });
1300
+ }
1301
+ /**
1302
+ * Get the number of completed steps (useful for testing)
1303
+ */
1304
+ getCompletedStepCount() {
1305
+ return this.completedSteps.length;
1306
+ }
1307
+ };
1308
+ var NOOP_COLLECTOR = {
1309
+ time: (_label, fn) => fn(),
1310
+ timeSync: (_label, fn) => fn(),
1311
+ record: () => {
1312
+ },
1313
+ summarize: () => {
1314
+ }
1315
+ };
1316
+ function createTimingCollector(enabled, log) {
1317
+ if (!enabled) return NOOP_COLLECTOR;
1318
+ const steps = {};
1319
+ return {
1320
+ async time(label, fn) {
1321
+ const start = Date.now();
1322
+ const result = await fn();
1323
+ steps[label] = Date.now() - start;
1324
+ return result;
1325
+ },
1326
+ timeSync(label, fn) {
1327
+ const start = Date.now();
1328
+ const result = fn();
1329
+ steps[label] = Date.now() - start;
1330
+ return result;
1331
+ },
1332
+ record(label, ms) {
1333
+ steps[label] = ms;
1334
+ },
1335
+ summarize(label) {
1336
+ const total = Object.values(steps).reduce((a, b) => a + b, 0);
1337
+ log(`[timing] ${label}: ${total}ms`, steps);
1338
+ }
1339
+ };
1340
+ }
1341
+
1342
+ // src/adapters/claude/claude-agent.ts
1181
1343
  import { v7 as uuidv7 } from "uuid";
1182
1344
 
1183
1345
  // package.json
1184
1346
  var package_default = {
1185
1347
  name: "@posthog/agent",
1186
- version: "2.1.35",
1348
+ version: "2.1.47",
1187
1349
  repository: "https://github.com/PostHog/twig",
1188
1350
  description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
1189
1351
  exports: {
@@ -1314,11 +1476,16 @@ function unreachable(value, logger) {
1314
1476
  // src/gateway-models.ts
1315
1477
  var DEFAULT_GATEWAY_MODEL = "claude-opus-4-6";
1316
1478
  var BLOCKED_MODELS = /* @__PURE__ */ new Set(["gpt-5-mini", "openai/gpt-5-mini"]);
1479
+ var CACHE_TTL = 10 * 60 * 1e3;
1480
+ var gatewayModelsCache = null;
1317
1481
  async function fetchGatewayModels(options) {
1318
1482
  const gatewayUrl = options?.gatewayUrl ?? process.env.ANTHROPIC_BASE_URL;
1319
1483
  if (!gatewayUrl) {
1320
1484
  return [];
1321
1485
  }
1486
+ if (gatewayModelsCache && gatewayModelsCache.url === gatewayUrl && Date.now() < gatewayModelsCache.expiry) {
1487
+ return gatewayModelsCache.models;
1488
+ }
1322
1489
  const modelsUrl = `${gatewayUrl}/v1/models`;
1323
1490
  try {
1324
1491
  const response = await fetch(modelsUrl);
@@ -1326,8 +1493,13 @@ async function fetchGatewayModels(options) {
1326
1493
  return [];
1327
1494
  }
1328
1495
  const data = await response.json();
1329
- const models = data.data ?? [];
1330
- return models.filter((m) => !BLOCKED_MODELS.has(m.id));
1496
+ const models = (data.data ?? []).filter((m) => !BLOCKED_MODELS.has(m.id));
1497
+ gatewayModelsCache = {
1498
+ models,
1499
+ expiry: Date.now() + CACHE_TTL,
1500
+ url: gatewayUrl
1501
+ };
1502
+ return models;
1331
1503
  } catch {
1332
1504
  return [];
1333
1505
  }
@@ -3235,12 +3407,8 @@ function clearStatsigCache() {
3235
3407
  process.env.CLAUDE_CONFIG_DIR || path2.join(os2.homedir(), ".claude"),
3236
3408
  "statsig"
3237
3409
  );
3238
- try {
3239
- if (fs.existsSync(statsigPath)) {
3240
- fs.rmSync(statsigPath, { recursive: true, force: true });
3241
- }
3242
- } catch {
3243
- }
3410
+ fs.rm(statsigPath, { recursive: true, force: true }, () => {
3411
+ });
3244
3412
  }
3245
3413
 
3246
3414
  // src/adapters/claude/claude-agent.ts
@@ -3250,12 +3418,14 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3250
3418
  backgroundTerminals = {};
3251
3419
  clientCapabilities;
3252
3420
  logWriter;
3253
- processCallbacks;
3421
+ options;
3254
3422
  lastSentConfigOptions;
3255
- constructor(client, logWriter, processCallbacks) {
3423
+ debug;
3424
+ constructor(client, logWriter, options) {
3256
3425
  super(client);
3257
3426
  this.logWriter = logWriter;
3258
- this.processCallbacks = processCallbacks;
3427
+ this.options = options;
3428
+ this.debug = options?.debug ?? false;
3259
3429
  this.toolUseCache = {};
3260
3430
  this.logger = new Logger({ debug: true, prefix: "[ClaudeAcpAgent]" });
3261
3431
  }
@@ -3298,27 +3468,36 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3298
3468
  }
3299
3469
  async newSession(params) {
3300
3470
  this.checkAuthStatus();
3471
+ const tc = createTimingCollector(
3472
+ this.debug,
3473
+ (msg, data) => this.logger.info(msg, data)
3474
+ );
3301
3475
  const meta = params._meta;
3302
3476
  const sessionId = uuidv7();
3303
3477
  const permissionMode = meta?.permissionMode && TWIG_EXECUTION_MODES.includes(meta.permissionMode) ? meta.permissionMode : "default";
3304
- const mcpServers = parseMcpServers(params);
3305
- await fetchMcpToolMetadata(mcpServers, this.logger);
3306
- const options = buildSessionOptions({
3307
- cwd: params.cwd,
3308
- mcpServers,
3309
- permissionMode,
3310
- canUseTool: this.createCanUseTool(sessionId),
3311
- logger: this.logger,
3312
- systemPrompt: buildSystemPrompt(meta?.systemPrompt),
3313
- userProvidedOptions: meta?.claudeCode?.options,
3314
- sessionId,
3315
- isResume: false,
3316
- onModeChange: this.createOnModeChange(sessionId),
3317
- onProcessSpawned: this.processCallbacks?.onProcessSpawned,
3318
- onProcessExited: this.processCallbacks?.onProcessExited
3319
- });
3478
+ const mcpServers = tc.timeSync(
3479
+ "parseMcpServers",
3480
+ () => parseMcpServers(params)
3481
+ );
3482
+ const options = tc.timeSync(
3483
+ "buildSessionOptions",
3484
+ () => buildSessionOptions({
3485
+ cwd: params.cwd,
3486
+ mcpServers,
3487
+ permissionMode,
3488
+ canUseTool: this.createCanUseTool(sessionId),
3489
+ logger: this.logger,
3490
+ systemPrompt: buildSystemPrompt(meta?.systemPrompt),
3491
+ userProvidedOptions: meta?.claudeCode?.options,
3492
+ sessionId,
3493
+ isResume: false,
3494
+ onModeChange: this.createOnModeChange(sessionId),
3495
+ onProcessSpawned: this.options?.onProcessSpawned,
3496
+ onProcessExited: this.options?.onProcessExited
3497
+ })
3498
+ );
3320
3499
  const input = new Pushable();
3321
- const q = query({ prompt: input, options });
3500
+ const q = tc.timeSync("sdkQuery", () => query({ prompt: input, options }));
3322
3501
  const session = this.createSession(
3323
3502
  sessionId,
3324
3503
  q,
@@ -3330,28 +3509,40 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3330
3509
  session.taskRunId = meta?.taskRunId;
3331
3510
  this.registerPersistence(sessionId, meta);
3332
3511
  if (meta?.taskRunId) {
3333
- await this.client.extNotification("_posthog/sdk_session", {
3334
- taskRunId: meta.taskRunId,
3335
- sessionId,
3336
- adapter: "claude"
3337
- });
3512
+ await tc.time(
3513
+ "extNotification",
3514
+ () => this.client.extNotification("_posthog/sdk_session", {
3515
+ taskRunId: meta.taskRunId,
3516
+ sessionId,
3517
+ adapter: "claude"
3518
+ })
3519
+ );
3338
3520
  }
3339
- const modelOptions = await this.getModelConfigOptions();
3521
+ const modelOptions = await tc.time(
3522
+ "fetchModels",
3523
+ () => this.getModelConfigOptions()
3524
+ );
3525
+ this.deferBackgroundFetches(tc, q, sessionId, mcpServers);
3340
3526
  session.modelId = modelOptions.currentModelId;
3341
3527
  await this.trySetModel(q, modelOptions.currentModelId);
3342
- this.sendAvailableCommandsUpdate(
3343
- sessionId,
3344
- await getAvailableSlashCommands(q)
3528
+ const configOptions = await tc.time(
3529
+ "buildConfigOptions",
3530
+ () => this.buildConfigOptions(modelOptions)
3345
3531
  );
3532
+ tc.summarize("newSession");
3346
3533
  return {
3347
3534
  sessionId,
3348
- configOptions: await this.buildConfigOptions(modelOptions)
3535
+ configOptions
3349
3536
  };
3350
3537
  }
3351
3538
  async loadSession(params) {
3352
3539
  return this.resumeSession(params);
3353
3540
  }
3354
3541
  async resumeSession(params) {
3542
+ const tc = createTimingCollector(
3543
+ this.debug,
3544
+ (msg, data) => this.logger.info(msg, data)
3545
+ );
3355
3546
  const meta = params._meta;
3356
3547
  const sessionId = meta?.sessionId;
3357
3548
  if (!sessionId) {
@@ -3360,28 +3551,33 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3360
3551
  if (this.sessionId === sessionId) {
3361
3552
  return {};
3362
3553
  }
3363
- const mcpServers = parseMcpServers(params);
3364
- await fetchMcpToolMetadata(mcpServers, this.logger);
3554
+ const mcpServers = tc.timeSync(
3555
+ "parseMcpServers",
3556
+ () => parseMcpServers(params)
3557
+ );
3365
3558
  const permissionMode = meta?.permissionMode && TWIG_EXECUTION_MODES.includes(meta.permissionMode) ? meta.permissionMode : "default";
3366
- const { query: q, session } = await this.initializeQuery({
3367
- cwd: params.cwd,
3368
- permissionMode,
3369
- mcpServers,
3370
- systemPrompt: buildSystemPrompt(meta?.systemPrompt),
3371
- userProvidedOptions: meta?.claudeCode?.options,
3372
- sessionId,
3373
- isResume: true,
3374
- additionalDirectories: meta?.claudeCode?.options?.additionalDirectories
3375
- });
3559
+ const { query: q, session } = await tc.time(
3560
+ "initializeQuery",
3561
+ () => this.initializeQuery({
3562
+ cwd: params.cwd,
3563
+ permissionMode,
3564
+ mcpServers,
3565
+ systemPrompt: buildSystemPrompt(meta?.systemPrompt),
3566
+ userProvidedOptions: meta?.claudeCode?.options,
3567
+ sessionId,
3568
+ isResume: true,
3569
+ additionalDirectories: meta?.claudeCode?.options?.additionalDirectories
3570
+ })
3571
+ );
3376
3572
  session.taskRunId = meta?.taskRunId;
3377
3573
  this.registerPersistence(sessionId, meta);
3378
- this.sendAvailableCommandsUpdate(
3379
- sessionId,
3380
- await getAvailableSlashCommands(q)
3574
+ this.deferBackgroundFetches(tc, q, sessionId, mcpServers);
3575
+ const configOptions = await tc.time(
3576
+ "buildConfigOptions",
3577
+ () => this.buildConfigOptions()
3381
3578
  );
3382
- return {
3383
- configOptions: await this.buildConfigOptions()
3384
- };
3579
+ tc.summarize("resumeSession");
3580
+ return { configOptions };
3385
3581
  }
3386
3582
  async prompt(params) {
3387
3583
  this.session.cancelled = false;
@@ -3453,8 +3649,8 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3453
3649
  isResume: config.isResume,
3454
3650
  additionalDirectories: config.additionalDirectories,
3455
3651
  onModeChange: this.createOnModeChange(config.sessionId),
3456
- onProcessSpawned: this.processCallbacks?.onProcessSpawned,
3457
- onProcessExited: this.processCallbacks?.onProcessExited
3652
+ onProcessSpawned: this.options?.onProcessSpawned,
3653
+ onProcessExited: this.options?.onProcessExited
3458
3654
  });
3459
3655
  const q = query({ prompt: input, options });
3460
3656
  const abortController = options.abortController;
@@ -3564,6 +3760,23 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3564
3760
  await q.setModel(fallback);
3565
3761
  }
3566
3762
  }
3763
+ /**
3764
+ * Fire-and-forget: fetch slash commands and MCP tool metadata in parallel.
3765
+ * Both populate caches used later — neither is needed to return configOptions.
3766
+ */
3767
+ deferBackgroundFetches(tc, q, sessionId, mcpServers) {
3768
+ Promise.all([
3769
+ tc.time("slashCommands", () => getAvailableSlashCommands(q)),
3770
+ tc.time(
3771
+ "mcpMetadata",
3772
+ () => fetchMcpToolMetadata(mcpServers, this.logger)
3773
+ )
3774
+ ]).then(([slashCommands]) => {
3775
+ this.sendAvailableCommandsUpdate(sessionId, slashCommands);
3776
+ }).catch((err) => {
3777
+ this.logger.warn("Failed to fetch deferred session data", { err });
3778
+ });
3779
+ }
3567
3780
  registerPersistence(sessionId, meta) {
3568
3781
  const persistence = meta?.persistence;
3569
3782
  if (persistence && this.logWriter) {
@@ -3851,7 +4064,10 @@ function createClaudeConnection(config) {
3851
4064
  const agentStream = ndJsonStream(agentWritable, streams.agent.readable);
3852
4065
  let agent = null;
3853
4066
  const agentConnection = new AgentSideConnection((client) => {
3854
- agent = new ClaudeAcpAgent(client, logWriter, config.processCallbacks);
4067
+ agent = new ClaudeAcpAgent(client, logWriter, {
4068
+ ...config.processCallbacks,
4069
+ debug: config.debug
4070
+ });
3855
4071
  logger.info(`Created ${agent.adapterName} agent`);
3856
4072
  return agent;
3857
4073
  }, agentStream);
@@ -9231,136 +9447,9 @@ async function getHeadSha(baseDir, options) {
9231
9447
  }
9232
9448
 
9233
9449
  // src/sagas/apply-snapshot-saga.ts
9234
- import { mkdir as mkdir3, rm as rm2, writeFile as writeFile3 } from "fs/promises";
9450
+ import { mkdir as mkdir3, rm as rm3, writeFile as writeFile3 } from "fs/promises";
9235
9451
  import { join as join5 } from "path";
9236
9452
 
9237
- // ../shared/dist/index.js
9238
- var consoleLogger = {
9239
- info: (_message, _data) => {
9240
- },
9241
- debug: (_message, _data) => {
9242
- },
9243
- error: (_message, _data) => {
9244
- },
9245
- warn: (_message, _data) => {
9246
- }
9247
- };
9248
- var Saga = class {
9249
- completedSteps = [];
9250
- currentStepName = "unknown";
9251
- stepTimings = [];
9252
- log;
9253
- constructor(logger) {
9254
- this.log = logger ?? consoleLogger;
9255
- }
9256
- /**
9257
- * Run the saga with the given input.
9258
- * Returns a discriminated union result - either success with data or failure with error details.
9259
- */
9260
- async run(input) {
9261
- this.completedSteps = [];
9262
- this.currentStepName = "unknown";
9263
- this.stepTimings = [];
9264
- const sagaStart = performance.now();
9265
- this.log.info("Starting saga", { sagaName: this.constructor.name });
9266
- try {
9267
- const result = await this.execute(input);
9268
- const totalDuration = performance.now() - sagaStart;
9269
- this.log.debug("Saga completed successfully", {
9270
- sagaName: this.constructor.name,
9271
- stepsCompleted: this.completedSteps.length,
9272
- totalDurationMs: Math.round(totalDuration),
9273
- stepTimings: this.stepTimings
9274
- });
9275
- return { success: true, data: result };
9276
- } catch (error) {
9277
- this.log.error("Saga failed, initiating rollback", {
9278
- sagaName: this.constructor.name,
9279
- failedStep: this.currentStepName,
9280
- error: error instanceof Error ? error.message : String(error)
9281
- });
9282
- await this.rollback();
9283
- return {
9284
- success: false,
9285
- error: error instanceof Error ? error.message : String(error),
9286
- failedStep: this.currentStepName
9287
- };
9288
- }
9289
- }
9290
- /**
9291
- * Execute a step with its rollback action.
9292
- * If the step succeeds, its rollback action is stored for potential rollback.
9293
- * The step name is automatically tracked for error reporting.
9294
- *
9295
- * @param config - Step configuration with name, execute, and rollback functions
9296
- * @returns The result of the execute function
9297
- * @throws Re-throws any error from the execute function (triggers rollback)
9298
- */
9299
- async step(config) {
9300
- this.currentStepName = config.name;
9301
- this.log.debug(`Executing step: ${config.name}`);
9302
- const stepStart = performance.now();
9303
- const result = await config.execute();
9304
- const durationMs = Math.round(performance.now() - stepStart);
9305
- this.stepTimings.push({ name: config.name, durationMs });
9306
- this.log.debug(`Step completed: ${config.name}`, { durationMs });
9307
- this.completedSteps.push({
9308
- name: config.name,
9309
- rollback: () => config.rollback(result)
9310
- });
9311
- return result;
9312
- }
9313
- /**
9314
- * Execute a step that doesn't need rollback.
9315
- * Useful for read-only operations or operations that are idempotent.
9316
- * The step name is automatically tracked for error reporting.
9317
- *
9318
- * @param name - Step name for logging and error tracking
9319
- * @param execute - The action to execute
9320
- * @returns The result of the execute function
9321
- */
9322
- async readOnlyStep(name, execute) {
9323
- this.currentStepName = name;
9324
- this.log.debug(`Executing read-only step: ${name}`);
9325
- const stepStart = performance.now();
9326
- const result = await execute();
9327
- const durationMs = Math.round(performance.now() - stepStart);
9328
- this.stepTimings.push({ name, durationMs });
9329
- this.log.debug(`Read-only step completed: ${name}`, { durationMs });
9330
- return result;
9331
- }
9332
- /**
9333
- * Roll back all completed steps in reverse order.
9334
- * Rollback errors are logged but don't stop the rollback of other steps.
9335
- */
9336
- async rollback() {
9337
- this.log.info("Rolling back saga", {
9338
- stepsToRollback: this.completedSteps.length
9339
- });
9340
- const stepsReversed = [...this.completedSteps].reverse();
9341
- for (const step of stepsReversed) {
9342
- try {
9343
- this.log.debug(`Rolling back step: ${step.name}`);
9344
- await step.rollback();
9345
- this.log.debug(`Step rolled back: ${step.name}`);
9346
- } catch (error) {
9347
- this.log.error(`Failed to rollback step: ${step.name}`, {
9348
- error: error instanceof Error ? error.message : String(error)
9349
- });
9350
- }
9351
- }
9352
- this.log.info("Rollback completed", {
9353
- stepsAttempted: this.completedSteps.length
9354
- });
9355
- }
9356
- /**
9357
- * Get the number of completed steps (useful for testing)
9358
- */
9359
- getCompletedStepCount() {
9360
- return this.completedSteps.length;
9361
- }
9362
- };
9363
-
9364
9453
  // ../git/dist/sagas/tree.js
9365
9454
  import { existsSync as existsSync4 } from "fs";
9366
9455
  import * as fs5 from "fs/promises";
@@ -9672,7 +9761,7 @@ var ApplySnapshotSaga = class extends Saga {
9672
9761
  },
9673
9762
  rollback: async () => {
9674
9763
  if (this.archivePath) {
9675
- await rm2(this.archivePath, { force: true }).catch(() => {
9764
+ await rm3(this.archivePath, { force: true }).catch(() => {
9676
9765
  });
9677
9766
  }
9678
9767
  }
@@ -9688,7 +9777,7 @@ var ApplySnapshotSaga = class extends Saga {
9688
9777
  if (!applyResult.success) {
9689
9778
  throw new Error(`Failed to apply tree: ${applyResult.error}`);
9690
9779
  }
9691
- await rm2(this.archivePath, { force: true }).catch(() => {
9780
+ await rm3(this.archivePath, { force: true }).catch(() => {
9692
9781
  });
9693
9782
  this.log.info("Tree snapshot applied", {
9694
9783
  treeHash: snapshot.treeHash,
@@ -9701,7 +9790,7 @@ var ApplySnapshotSaga = class extends Saga {
9701
9790
 
9702
9791
  // src/sagas/capture-tree-saga.ts
9703
9792
  import { existsSync as existsSync5 } from "fs";
9704
- import { readFile as readFile3, rm as rm3 } from "fs/promises";
9793
+ import { readFile as readFile3, rm as rm4 } from "fs/promises";
9705
9794
  import { join as join6 } from "path";
9706
9795
  var CaptureTreeSaga2 = class extends Saga {
9707
9796
  async execute(input) {
@@ -9750,7 +9839,7 @@ var CaptureTreeSaga2 = class extends Saga {
9750
9839
  runId
9751
9840
  );
9752
9841
  } finally {
9753
- await rm3(createdArchivePath, { force: true }).catch(() => {
9842
+ await rm4(createdArchivePath, { force: true }).catch(() => {
9754
9843
  });
9755
9844
  }
9756
9845
  }
@@ -9794,7 +9883,7 @@ var CaptureTreeSaga2 = class extends Saga {
9794
9883
  return void 0;
9795
9884
  },
9796
9885
  rollback: async () => {
9797
- await rm3(archivePath, { force: true }).catch(() => {
9886
+ await rm4(archivePath, { force: true }).catch(() => {
9798
9887
  });
9799
9888
  }
9800
9889
  });