@posthog/agent 2.1.47 → 2.1.48

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,174 +1178,12 @@ 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
1343
1181
  import { v7 as uuidv7 } from "uuid";
1344
1182
 
1345
1183
  // package.json
1346
1184
  var package_default = {
1347
1185
  name: "@posthog/agent",
1348
- version: "2.1.47",
1186
+ version: "2.1.48",
1349
1187
  repository: "https://github.com/PostHog/twig",
1350
1188
  description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
1351
1189
  exports: {
@@ -3420,12 +3258,10 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3420
3258
  logWriter;
3421
3259
  options;
3422
3260
  lastSentConfigOptions;
3423
- debug;
3424
3261
  constructor(client, logWriter, options) {
3425
3262
  super(client);
3426
3263
  this.logWriter = logWriter;
3427
3264
  this.options = options;
3428
- this.debug = options?.debug ?? false;
3429
3265
  this.toolUseCache = {};
3430
3266
  this.logger = new Logger({ debug: true, prefix: "[ClaudeAcpAgent]" });
3431
3267
  }
@@ -3468,36 +3304,26 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3468
3304
  }
3469
3305
  async newSession(params) {
3470
3306
  this.checkAuthStatus();
3471
- const tc = createTimingCollector(
3472
- this.debug,
3473
- (msg, data) => this.logger.info(msg, data)
3474
- );
3475
3307
  const meta = params._meta;
3476
3308
  const sessionId = uuidv7();
3477
3309
  const permissionMode = meta?.permissionMode && TWIG_EXECUTION_MODES.includes(meta.permissionMode) ? meta.permissionMode : "default";
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
- );
3310
+ const mcpServers = parseMcpServers(params);
3311
+ const options = buildSessionOptions({
3312
+ cwd: params.cwd,
3313
+ mcpServers,
3314
+ permissionMode,
3315
+ canUseTool: this.createCanUseTool(sessionId),
3316
+ logger: this.logger,
3317
+ systemPrompt: buildSystemPrompt(meta?.systemPrompt),
3318
+ userProvidedOptions: meta?.claudeCode?.options,
3319
+ sessionId,
3320
+ isResume: false,
3321
+ onModeChange: this.createOnModeChange(sessionId),
3322
+ onProcessSpawned: this.options?.onProcessSpawned,
3323
+ onProcessExited: this.options?.onProcessExited
3324
+ });
3499
3325
  const input = new Pushable();
3500
- const q = tc.timeSync("sdkQuery", () => query({ prompt: input, options }));
3326
+ const q = query({ prompt: input, options });
3501
3327
  const session = this.createSession(
3502
3328
  sessionId,
3503
3329
  q,
@@ -3509,27 +3335,17 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3509
3335
  session.taskRunId = meta?.taskRunId;
3510
3336
  this.registerPersistence(sessionId, meta);
3511
3337
  if (meta?.taskRunId) {
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
+ await this.client.extNotification("_posthog/sdk_session", {
3339
+ taskRunId: meta.taskRunId,
3340
+ sessionId,
3341
+ adapter: "claude"
3342
+ });
3520
3343
  }
3521
- const modelOptions = await tc.time(
3522
- "fetchModels",
3523
- () => this.getModelConfigOptions()
3524
- );
3525
- this.deferBackgroundFetches(tc, q, sessionId, mcpServers);
3344
+ const modelOptions = await this.getModelConfigOptions();
3345
+ this.deferBackgroundFetches(q, sessionId, mcpServers);
3526
3346
  session.modelId = modelOptions.currentModelId;
3527
3347
  await this.trySetModel(q, modelOptions.currentModelId);
3528
- const configOptions = await tc.time(
3529
- "buildConfigOptions",
3530
- () => this.buildConfigOptions(modelOptions)
3531
- );
3532
- tc.summarize("newSession");
3348
+ const configOptions = await this.buildConfigOptions(modelOptions);
3533
3349
  return {
3534
3350
  sessionId,
3535
3351
  configOptions
@@ -3539,10 +3355,6 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3539
3355
  return this.resumeSession(params);
3540
3356
  }
3541
3357
  async resumeSession(params) {
3542
- const tc = createTimingCollector(
3543
- this.debug,
3544
- (msg, data) => this.logger.info(msg, data)
3545
- );
3546
3358
  const meta = params._meta;
3547
3359
  const sessionId = meta?.sessionId;
3548
3360
  if (!sessionId) {
@@ -3551,32 +3363,22 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3551
3363
  if (this.sessionId === sessionId) {
3552
3364
  return {};
3553
3365
  }
3554
- const mcpServers = tc.timeSync(
3555
- "parseMcpServers",
3556
- () => parseMcpServers(params)
3557
- );
3366
+ const mcpServers = parseMcpServers(params);
3558
3367
  const permissionMode = meta?.permissionMode && TWIG_EXECUTION_MODES.includes(meta.permissionMode) ? meta.permissionMode : "default";
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
- );
3368
+ const { query: q, session } = await this.initializeQuery({
3369
+ cwd: params.cwd,
3370
+ permissionMode,
3371
+ mcpServers,
3372
+ systemPrompt: buildSystemPrompt(meta?.systemPrompt),
3373
+ userProvidedOptions: meta?.claudeCode?.options,
3374
+ sessionId,
3375
+ isResume: true,
3376
+ additionalDirectories: meta?.claudeCode?.options?.additionalDirectories
3377
+ });
3572
3378
  session.taskRunId = meta?.taskRunId;
3573
3379
  this.registerPersistence(sessionId, meta);
3574
- this.deferBackgroundFetches(tc, q, sessionId, mcpServers);
3575
- const configOptions = await tc.time(
3576
- "buildConfigOptions",
3577
- () => this.buildConfigOptions()
3578
- );
3579
- tc.summarize("resumeSession");
3380
+ this.deferBackgroundFetches(q, sessionId, mcpServers);
3381
+ const configOptions = await this.buildConfigOptions();
3580
3382
  return { configOptions };
3581
3383
  }
3582
3384
  async prompt(params) {
@@ -3764,13 +3566,10 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3764
3566
  * Fire-and-forget: fetch slash commands and MCP tool metadata in parallel.
3765
3567
  * Both populate caches used later — neither is needed to return configOptions.
3766
3568
  */
3767
- deferBackgroundFetches(tc, q, sessionId, mcpServers) {
3569
+ deferBackgroundFetches(q, sessionId, mcpServers) {
3768
3570
  Promise.all([
3769
- tc.time("slashCommands", () => getAvailableSlashCommands(q)),
3770
- tc.time(
3771
- "mcpMetadata",
3772
- () => fetchMcpToolMetadata(mcpServers, this.logger)
3773
- )
3571
+ getAvailableSlashCommands(q),
3572
+ fetchMcpToolMetadata(mcpServers, this.logger)
3774
3573
  ]).then(([slashCommands]) => {
3775
3574
  this.sendAvailableCommandsUpdate(sessionId, slashCommands);
3776
3575
  }).catch((err) => {
@@ -4064,10 +3863,7 @@ function createClaudeConnection(config) {
4064
3863
  const agentStream = ndJsonStream(agentWritable, streams.agent.readable);
4065
3864
  let agent = null;
4066
3865
  const agentConnection = new AgentSideConnection((client) => {
4067
- agent = new ClaudeAcpAgent(client, logWriter, {
4068
- ...config.processCallbacks,
4069
- debug: config.debug
4070
- });
3866
+ agent = new ClaudeAcpAgent(client, logWriter, config.processCallbacks);
4071
3867
  logger.info(`Created ${agent.adapterName} agent`);
4072
3868
  return agent;
4073
3869
  }, agentStream);
@@ -9450,6 +9246,133 @@ async function getHeadSha(baseDir, options) {
9450
9246
  import { mkdir as mkdir3, rm as rm3, writeFile as writeFile3 } from "fs/promises";
9451
9247
  import { join as join5 } from "path";
9452
9248
 
9249
+ // ../shared/dist/index.js
9250
+ var consoleLogger = {
9251
+ info: (_message, _data) => {
9252
+ },
9253
+ debug: (_message, _data) => {
9254
+ },
9255
+ error: (_message, _data) => {
9256
+ },
9257
+ warn: (_message, _data) => {
9258
+ }
9259
+ };
9260
+ var Saga = class {
9261
+ completedSteps = [];
9262
+ currentStepName = "unknown";
9263
+ stepTimings = [];
9264
+ log;
9265
+ constructor(logger) {
9266
+ this.log = logger ?? consoleLogger;
9267
+ }
9268
+ /**
9269
+ * Run the saga with the given input.
9270
+ * Returns a discriminated union result - either success with data or failure with error details.
9271
+ */
9272
+ async run(input) {
9273
+ this.completedSteps = [];
9274
+ this.currentStepName = "unknown";
9275
+ this.stepTimings = [];
9276
+ const sagaStart = performance.now();
9277
+ this.log.info("Starting saga", { sagaName: this.constructor.name });
9278
+ try {
9279
+ const result = await this.execute(input);
9280
+ const totalDuration = performance.now() - sagaStart;
9281
+ this.log.debug("Saga completed successfully", {
9282
+ sagaName: this.constructor.name,
9283
+ stepsCompleted: this.completedSteps.length,
9284
+ totalDurationMs: Math.round(totalDuration),
9285
+ stepTimings: this.stepTimings
9286
+ });
9287
+ return { success: true, data: result };
9288
+ } catch (error) {
9289
+ this.log.error("Saga failed, initiating rollback", {
9290
+ sagaName: this.constructor.name,
9291
+ failedStep: this.currentStepName,
9292
+ error: error instanceof Error ? error.message : String(error)
9293
+ });
9294
+ await this.rollback();
9295
+ return {
9296
+ success: false,
9297
+ error: error instanceof Error ? error.message : String(error),
9298
+ failedStep: this.currentStepName
9299
+ };
9300
+ }
9301
+ }
9302
+ /**
9303
+ * Execute a step with its rollback action.
9304
+ * If the step succeeds, its rollback action is stored for potential rollback.
9305
+ * The step name is automatically tracked for error reporting.
9306
+ *
9307
+ * @param config - Step configuration with name, execute, and rollback functions
9308
+ * @returns The result of the execute function
9309
+ * @throws Re-throws any error from the execute function (triggers rollback)
9310
+ */
9311
+ async step(config) {
9312
+ this.currentStepName = config.name;
9313
+ this.log.debug(`Executing step: ${config.name}`);
9314
+ const stepStart = performance.now();
9315
+ const result = await config.execute();
9316
+ const durationMs = Math.round(performance.now() - stepStart);
9317
+ this.stepTimings.push({ name: config.name, durationMs });
9318
+ this.log.debug(`Step completed: ${config.name}`, { durationMs });
9319
+ this.completedSteps.push({
9320
+ name: config.name,
9321
+ rollback: () => config.rollback(result)
9322
+ });
9323
+ return result;
9324
+ }
9325
+ /**
9326
+ * Execute a step that doesn't need rollback.
9327
+ * Useful for read-only operations or operations that are idempotent.
9328
+ * The step name is automatically tracked for error reporting.
9329
+ *
9330
+ * @param name - Step name for logging and error tracking
9331
+ * @param execute - The action to execute
9332
+ * @returns The result of the execute function
9333
+ */
9334
+ async readOnlyStep(name, execute) {
9335
+ this.currentStepName = name;
9336
+ this.log.debug(`Executing read-only step: ${name}`);
9337
+ const stepStart = performance.now();
9338
+ const result = await execute();
9339
+ const durationMs = Math.round(performance.now() - stepStart);
9340
+ this.stepTimings.push({ name, durationMs });
9341
+ this.log.debug(`Read-only step completed: ${name}`, { durationMs });
9342
+ return result;
9343
+ }
9344
+ /**
9345
+ * Roll back all completed steps in reverse order.
9346
+ * Rollback errors are logged but don't stop the rollback of other steps.
9347
+ */
9348
+ async rollback() {
9349
+ this.log.info("Rolling back saga", {
9350
+ stepsToRollback: this.completedSteps.length
9351
+ });
9352
+ const stepsReversed = [...this.completedSteps].reverse();
9353
+ for (const step of stepsReversed) {
9354
+ try {
9355
+ this.log.debug(`Rolling back step: ${step.name}`);
9356
+ await step.rollback();
9357
+ this.log.debug(`Step rolled back: ${step.name}`);
9358
+ } catch (error) {
9359
+ this.log.error(`Failed to rollback step: ${step.name}`, {
9360
+ error: error instanceof Error ? error.message : String(error)
9361
+ });
9362
+ }
9363
+ }
9364
+ this.log.info("Rollback completed", {
9365
+ stepsAttempted: this.completedSteps.length
9366
+ });
9367
+ }
9368
+ /**
9369
+ * Get the number of completed steps (useful for testing)
9370
+ */
9371
+ getCompletedStepCount() {
9372
+ return this.completedSteps.length;
9373
+ }
9374
+ };
9375
+
9453
9376
  // ../git/dist/sagas/tree.js
9454
9377
  import { existsSync as existsSync4 } from "fs";
9455
9378
  import * as fs5 from "fs/promises";