@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.
@@ -1170,174 +1170,12 @@ var os3 = __toESM(require("os"), 1);
1170
1170
  var path3 = __toESM(require("path"), 1);
1171
1171
  var import_sdk2 = require("@agentclientprotocol/sdk");
1172
1172
  var import_claude_agent_sdk = require("@anthropic-ai/claude-agent-sdk");
1173
-
1174
- // ../shared/dist/index.js
1175
- var consoleLogger = {
1176
- info: (_message, _data) => {
1177
- },
1178
- debug: (_message, _data) => {
1179
- },
1180
- error: (_message, _data) => {
1181
- },
1182
- warn: (_message, _data) => {
1183
- }
1184
- };
1185
- var Saga = class {
1186
- completedSteps = [];
1187
- currentStepName = "unknown";
1188
- stepTimings = [];
1189
- log;
1190
- constructor(logger) {
1191
- this.log = logger ?? consoleLogger;
1192
- }
1193
- /**
1194
- * Run the saga with the given input.
1195
- * Returns a discriminated union result - either success with data or failure with error details.
1196
- */
1197
- async run(input) {
1198
- this.completedSteps = [];
1199
- this.currentStepName = "unknown";
1200
- this.stepTimings = [];
1201
- const sagaStart = performance.now();
1202
- this.log.info("Starting saga", { sagaName: this.constructor.name });
1203
- try {
1204
- const result = await this.execute(input);
1205
- const totalDuration = performance.now() - sagaStart;
1206
- this.log.debug("Saga completed successfully", {
1207
- sagaName: this.constructor.name,
1208
- stepsCompleted: this.completedSteps.length,
1209
- totalDurationMs: Math.round(totalDuration),
1210
- stepTimings: this.stepTimings
1211
- });
1212
- return { success: true, data: result };
1213
- } catch (error) {
1214
- this.log.error("Saga failed, initiating rollback", {
1215
- sagaName: this.constructor.name,
1216
- failedStep: this.currentStepName,
1217
- error: error instanceof Error ? error.message : String(error)
1218
- });
1219
- await this.rollback();
1220
- return {
1221
- success: false,
1222
- error: error instanceof Error ? error.message : String(error),
1223
- failedStep: this.currentStepName
1224
- };
1225
- }
1226
- }
1227
- /**
1228
- * Execute a step with its rollback action.
1229
- * If the step succeeds, its rollback action is stored for potential rollback.
1230
- * The step name is automatically tracked for error reporting.
1231
- *
1232
- * @param config - Step configuration with name, execute, and rollback functions
1233
- * @returns The result of the execute function
1234
- * @throws Re-throws any error from the execute function (triggers rollback)
1235
- */
1236
- async step(config) {
1237
- this.currentStepName = config.name;
1238
- this.log.debug(`Executing step: ${config.name}`);
1239
- const stepStart = performance.now();
1240
- const result = await config.execute();
1241
- const durationMs = Math.round(performance.now() - stepStart);
1242
- this.stepTimings.push({ name: config.name, durationMs });
1243
- this.log.debug(`Step completed: ${config.name}`, { durationMs });
1244
- this.completedSteps.push({
1245
- name: config.name,
1246
- rollback: () => config.rollback(result)
1247
- });
1248
- return result;
1249
- }
1250
- /**
1251
- * Execute a step that doesn't need rollback.
1252
- * Useful for read-only operations or operations that are idempotent.
1253
- * The step name is automatically tracked for error reporting.
1254
- *
1255
- * @param name - Step name for logging and error tracking
1256
- * @param execute - The action to execute
1257
- * @returns The result of the execute function
1258
- */
1259
- async readOnlyStep(name, execute) {
1260
- this.currentStepName = name;
1261
- this.log.debug(`Executing read-only step: ${name}`);
1262
- const stepStart = performance.now();
1263
- const result = await execute();
1264
- const durationMs = Math.round(performance.now() - stepStart);
1265
- this.stepTimings.push({ name, durationMs });
1266
- this.log.debug(`Read-only step completed: ${name}`, { durationMs });
1267
- return result;
1268
- }
1269
- /**
1270
- * Roll back all completed steps in reverse order.
1271
- * Rollback errors are logged but don't stop the rollback of other steps.
1272
- */
1273
- async rollback() {
1274
- this.log.info("Rolling back saga", {
1275
- stepsToRollback: this.completedSteps.length
1276
- });
1277
- const stepsReversed = [...this.completedSteps].reverse();
1278
- for (const step of stepsReversed) {
1279
- try {
1280
- this.log.debug(`Rolling back step: ${step.name}`);
1281
- await step.rollback();
1282
- this.log.debug(`Step rolled back: ${step.name}`);
1283
- } catch (error) {
1284
- this.log.error(`Failed to rollback step: ${step.name}`, {
1285
- error: error instanceof Error ? error.message : String(error)
1286
- });
1287
- }
1288
- }
1289
- this.log.info("Rollback completed", {
1290
- stepsAttempted: this.completedSteps.length
1291
- });
1292
- }
1293
- /**
1294
- * Get the number of completed steps (useful for testing)
1295
- */
1296
- getCompletedStepCount() {
1297
- return this.completedSteps.length;
1298
- }
1299
- };
1300
- var NOOP_COLLECTOR = {
1301
- time: (_label, fn) => fn(),
1302
- timeSync: (_label, fn) => fn(),
1303
- record: () => {
1304
- },
1305
- summarize: () => {
1306
- }
1307
- };
1308
- function createTimingCollector(enabled, log) {
1309
- if (!enabled) return NOOP_COLLECTOR;
1310
- const steps = {};
1311
- return {
1312
- async time(label, fn) {
1313
- const start = Date.now();
1314
- const result = await fn();
1315
- steps[label] = Date.now() - start;
1316
- return result;
1317
- },
1318
- timeSync(label, fn) {
1319
- const start = Date.now();
1320
- const result = fn();
1321
- steps[label] = Date.now() - start;
1322
- return result;
1323
- },
1324
- record(label, ms) {
1325
- steps[label] = ms;
1326
- },
1327
- summarize(label) {
1328
- const total = Object.values(steps).reduce((a, b) => a + b, 0);
1329
- log(`[timing] ${label}: ${total}ms`, steps);
1330
- }
1331
- };
1332
- }
1333
-
1334
- // src/adapters/claude/claude-agent.ts
1335
1173
  var import_uuid = require("uuid");
1336
1174
 
1337
1175
  // package.json
1338
1176
  var package_default = {
1339
1177
  name: "@posthog/agent",
1340
- version: "2.1.47",
1178
+ version: "2.1.48",
1341
1179
  repository: "https://github.com/PostHog/twig",
1342
1180
  description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
1343
1181
  exports: {
@@ -3412,12 +3250,10 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3412
3250
  logWriter;
3413
3251
  options;
3414
3252
  lastSentConfigOptions;
3415
- debug;
3416
3253
  constructor(client, logWriter, options) {
3417
3254
  super(client);
3418
3255
  this.logWriter = logWriter;
3419
3256
  this.options = options;
3420
- this.debug = options?.debug ?? false;
3421
3257
  this.toolUseCache = {};
3422
3258
  this.logger = new Logger({ debug: true, prefix: "[ClaudeAcpAgent]" });
3423
3259
  }
@@ -3460,36 +3296,26 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3460
3296
  }
3461
3297
  async newSession(params) {
3462
3298
  this.checkAuthStatus();
3463
- const tc = createTimingCollector(
3464
- this.debug,
3465
- (msg, data) => this.logger.info(msg, data)
3466
- );
3467
3299
  const meta = params._meta;
3468
3300
  const sessionId = (0, import_uuid.v7)();
3469
3301
  const permissionMode = meta?.permissionMode && TWIG_EXECUTION_MODES.includes(meta.permissionMode) ? meta.permissionMode : "default";
3470
- const mcpServers = tc.timeSync(
3471
- "parseMcpServers",
3472
- () => parseMcpServers(params)
3473
- );
3474
- const options = tc.timeSync(
3475
- "buildSessionOptions",
3476
- () => buildSessionOptions({
3477
- cwd: params.cwd,
3478
- mcpServers,
3479
- permissionMode,
3480
- canUseTool: this.createCanUseTool(sessionId),
3481
- logger: this.logger,
3482
- systemPrompt: buildSystemPrompt(meta?.systemPrompt),
3483
- userProvidedOptions: meta?.claudeCode?.options,
3484
- sessionId,
3485
- isResume: false,
3486
- onModeChange: this.createOnModeChange(sessionId),
3487
- onProcessSpawned: this.options?.onProcessSpawned,
3488
- onProcessExited: this.options?.onProcessExited
3489
- })
3490
- );
3302
+ const mcpServers = parseMcpServers(params);
3303
+ const options = buildSessionOptions({
3304
+ cwd: params.cwd,
3305
+ mcpServers,
3306
+ permissionMode,
3307
+ canUseTool: this.createCanUseTool(sessionId),
3308
+ logger: this.logger,
3309
+ systemPrompt: buildSystemPrompt(meta?.systemPrompt),
3310
+ userProvidedOptions: meta?.claudeCode?.options,
3311
+ sessionId,
3312
+ isResume: false,
3313
+ onModeChange: this.createOnModeChange(sessionId),
3314
+ onProcessSpawned: this.options?.onProcessSpawned,
3315
+ onProcessExited: this.options?.onProcessExited
3316
+ });
3491
3317
  const input = new Pushable();
3492
- const q = tc.timeSync("sdkQuery", () => (0, import_claude_agent_sdk.query)({ prompt: input, options }));
3318
+ const q = (0, import_claude_agent_sdk.query)({ prompt: input, options });
3493
3319
  const session = this.createSession(
3494
3320
  sessionId,
3495
3321
  q,
@@ -3501,27 +3327,17 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3501
3327
  session.taskRunId = meta?.taskRunId;
3502
3328
  this.registerPersistence(sessionId, meta);
3503
3329
  if (meta?.taskRunId) {
3504
- await tc.time(
3505
- "extNotification",
3506
- () => this.client.extNotification("_posthog/sdk_session", {
3507
- taskRunId: meta.taskRunId,
3508
- sessionId,
3509
- adapter: "claude"
3510
- })
3511
- );
3330
+ await this.client.extNotification("_posthog/sdk_session", {
3331
+ taskRunId: meta.taskRunId,
3332
+ sessionId,
3333
+ adapter: "claude"
3334
+ });
3512
3335
  }
3513
- const modelOptions = await tc.time(
3514
- "fetchModels",
3515
- () => this.getModelConfigOptions()
3516
- );
3517
- this.deferBackgroundFetches(tc, q, sessionId, mcpServers);
3336
+ const modelOptions = await this.getModelConfigOptions();
3337
+ this.deferBackgroundFetches(q, sessionId, mcpServers);
3518
3338
  session.modelId = modelOptions.currentModelId;
3519
3339
  await this.trySetModel(q, modelOptions.currentModelId);
3520
- const configOptions = await tc.time(
3521
- "buildConfigOptions",
3522
- () => this.buildConfigOptions(modelOptions)
3523
- );
3524
- tc.summarize("newSession");
3340
+ const configOptions = await this.buildConfigOptions(modelOptions);
3525
3341
  return {
3526
3342
  sessionId,
3527
3343
  configOptions
@@ -3531,10 +3347,6 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3531
3347
  return this.resumeSession(params);
3532
3348
  }
3533
3349
  async resumeSession(params) {
3534
- const tc = createTimingCollector(
3535
- this.debug,
3536
- (msg, data) => this.logger.info(msg, data)
3537
- );
3538
3350
  const meta = params._meta;
3539
3351
  const sessionId = meta?.sessionId;
3540
3352
  if (!sessionId) {
@@ -3543,32 +3355,22 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3543
3355
  if (this.sessionId === sessionId) {
3544
3356
  return {};
3545
3357
  }
3546
- const mcpServers = tc.timeSync(
3547
- "parseMcpServers",
3548
- () => parseMcpServers(params)
3549
- );
3358
+ const mcpServers = parseMcpServers(params);
3550
3359
  const permissionMode = meta?.permissionMode && TWIG_EXECUTION_MODES.includes(meta.permissionMode) ? meta.permissionMode : "default";
3551
- const { query: q, session } = await tc.time(
3552
- "initializeQuery",
3553
- () => this.initializeQuery({
3554
- cwd: params.cwd,
3555
- permissionMode,
3556
- mcpServers,
3557
- systemPrompt: buildSystemPrompt(meta?.systemPrompt),
3558
- userProvidedOptions: meta?.claudeCode?.options,
3559
- sessionId,
3560
- isResume: true,
3561
- additionalDirectories: meta?.claudeCode?.options?.additionalDirectories
3562
- })
3563
- );
3360
+ const { query: q, session } = await this.initializeQuery({
3361
+ cwd: params.cwd,
3362
+ permissionMode,
3363
+ mcpServers,
3364
+ systemPrompt: buildSystemPrompt(meta?.systemPrompt),
3365
+ userProvidedOptions: meta?.claudeCode?.options,
3366
+ sessionId,
3367
+ isResume: true,
3368
+ additionalDirectories: meta?.claudeCode?.options?.additionalDirectories
3369
+ });
3564
3370
  session.taskRunId = meta?.taskRunId;
3565
3371
  this.registerPersistence(sessionId, meta);
3566
- this.deferBackgroundFetches(tc, q, sessionId, mcpServers);
3567
- const configOptions = await tc.time(
3568
- "buildConfigOptions",
3569
- () => this.buildConfigOptions()
3570
- );
3571
- tc.summarize("resumeSession");
3372
+ this.deferBackgroundFetches(q, sessionId, mcpServers);
3373
+ const configOptions = await this.buildConfigOptions();
3572
3374
  return { configOptions };
3573
3375
  }
3574
3376
  async prompt(params) {
@@ -3756,13 +3558,10 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
3756
3558
  * Fire-and-forget: fetch slash commands and MCP tool metadata in parallel.
3757
3559
  * Both populate caches used later — neither is needed to return configOptions.
3758
3560
  */
3759
- deferBackgroundFetches(tc, q, sessionId, mcpServers) {
3561
+ deferBackgroundFetches(q, sessionId, mcpServers) {
3760
3562
  Promise.all([
3761
- tc.time("slashCommands", () => getAvailableSlashCommands(q)),
3762
- tc.time(
3763
- "mcpMetadata",
3764
- () => fetchMcpToolMetadata(mcpServers, this.logger)
3765
- )
3563
+ getAvailableSlashCommands(q),
3564
+ fetchMcpToolMetadata(mcpServers, this.logger)
3766
3565
  ]).then(([slashCommands]) => {
3767
3566
  this.sendAvailableCommandsUpdate(sessionId, slashCommands);
3768
3567
  }).catch((err) => {
@@ -4056,10 +3855,7 @@ function createClaudeConnection(config) {
4056
3855
  const agentStream = (0, import_sdk3.ndJsonStream)(agentWritable, streams.agent.readable);
4057
3856
  let agent = null;
4058
3857
  const agentConnection = new import_sdk3.AgentSideConnection((client) => {
4059
- agent = new ClaudeAcpAgent(client, logWriter, {
4060
- ...config.processCallbacks,
4061
- debug: config.debug
4062
- });
3858
+ agent = new ClaudeAcpAgent(client, logWriter, config.processCallbacks);
4063
3859
  logger.info(`Created ${agent.adapterName} agent`);
4064
3860
  return agent;
4065
3861
  }, agentStream);
@@ -9442,6 +9238,133 @@ async function getHeadSha(baseDir, options) {
9442
9238
  var import_promises2 = require("fs/promises");
9443
9239
  var import_node_path3 = require("path");
9444
9240
 
9241
+ // ../shared/dist/index.js
9242
+ var consoleLogger = {
9243
+ info: (_message, _data) => {
9244
+ },
9245
+ debug: (_message, _data) => {
9246
+ },
9247
+ error: (_message, _data) => {
9248
+ },
9249
+ warn: (_message, _data) => {
9250
+ }
9251
+ };
9252
+ var Saga = class {
9253
+ completedSteps = [];
9254
+ currentStepName = "unknown";
9255
+ stepTimings = [];
9256
+ log;
9257
+ constructor(logger) {
9258
+ this.log = logger ?? consoleLogger;
9259
+ }
9260
+ /**
9261
+ * Run the saga with the given input.
9262
+ * Returns a discriminated union result - either success with data or failure with error details.
9263
+ */
9264
+ async run(input) {
9265
+ this.completedSteps = [];
9266
+ this.currentStepName = "unknown";
9267
+ this.stepTimings = [];
9268
+ const sagaStart = performance.now();
9269
+ this.log.info("Starting saga", { sagaName: this.constructor.name });
9270
+ try {
9271
+ const result = await this.execute(input);
9272
+ const totalDuration = performance.now() - sagaStart;
9273
+ this.log.debug("Saga completed successfully", {
9274
+ sagaName: this.constructor.name,
9275
+ stepsCompleted: this.completedSteps.length,
9276
+ totalDurationMs: Math.round(totalDuration),
9277
+ stepTimings: this.stepTimings
9278
+ });
9279
+ return { success: true, data: result };
9280
+ } catch (error) {
9281
+ this.log.error("Saga failed, initiating rollback", {
9282
+ sagaName: this.constructor.name,
9283
+ failedStep: this.currentStepName,
9284
+ error: error instanceof Error ? error.message : String(error)
9285
+ });
9286
+ await this.rollback();
9287
+ return {
9288
+ success: false,
9289
+ error: error instanceof Error ? error.message : String(error),
9290
+ failedStep: this.currentStepName
9291
+ };
9292
+ }
9293
+ }
9294
+ /**
9295
+ * Execute a step with its rollback action.
9296
+ * If the step succeeds, its rollback action is stored for potential rollback.
9297
+ * The step name is automatically tracked for error reporting.
9298
+ *
9299
+ * @param config - Step configuration with name, execute, and rollback functions
9300
+ * @returns The result of the execute function
9301
+ * @throws Re-throws any error from the execute function (triggers rollback)
9302
+ */
9303
+ async step(config) {
9304
+ this.currentStepName = config.name;
9305
+ this.log.debug(`Executing step: ${config.name}`);
9306
+ const stepStart = performance.now();
9307
+ const result = await config.execute();
9308
+ const durationMs = Math.round(performance.now() - stepStart);
9309
+ this.stepTimings.push({ name: config.name, durationMs });
9310
+ this.log.debug(`Step completed: ${config.name}`, { durationMs });
9311
+ this.completedSteps.push({
9312
+ name: config.name,
9313
+ rollback: () => config.rollback(result)
9314
+ });
9315
+ return result;
9316
+ }
9317
+ /**
9318
+ * Execute a step that doesn't need rollback.
9319
+ * Useful for read-only operations or operations that are idempotent.
9320
+ * The step name is automatically tracked for error reporting.
9321
+ *
9322
+ * @param name - Step name for logging and error tracking
9323
+ * @param execute - The action to execute
9324
+ * @returns The result of the execute function
9325
+ */
9326
+ async readOnlyStep(name, execute) {
9327
+ this.currentStepName = name;
9328
+ this.log.debug(`Executing read-only step: ${name}`);
9329
+ const stepStart = performance.now();
9330
+ const result = await execute();
9331
+ const durationMs = Math.round(performance.now() - stepStart);
9332
+ this.stepTimings.push({ name, durationMs });
9333
+ this.log.debug(`Read-only step completed: ${name}`, { durationMs });
9334
+ return result;
9335
+ }
9336
+ /**
9337
+ * Roll back all completed steps in reverse order.
9338
+ * Rollback errors are logged but don't stop the rollback of other steps.
9339
+ */
9340
+ async rollback() {
9341
+ this.log.info("Rolling back saga", {
9342
+ stepsToRollback: this.completedSteps.length
9343
+ });
9344
+ const stepsReversed = [...this.completedSteps].reverse();
9345
+ for (const step of stepsReversed) {
9346
+ try {
9347
+ this.log.debug(`Rolling back step: ${step.name}`);
9348
+ await step.rollback();
9349
+ this.log.debug(`Step rolled back: ${step.name}`);
9350
+ } catch (error) {
9351
+ this.log.error(`Failed to rollback step: ${step.name}`, {
9352
+ error: error instanceof Error ? error.message : String(error)
9353
+ });
9354
+ }
9355
+ }
9356
+ this.log.info("Rollback completed", {
9357
+ stepsAttempted: this.completedSteps.length
9358
+ });
9359
+ }
9360
+ /**
9361
+ * Get the number of completed steps (useful for testing)
9362
+ */
9363
+ getCompletedStepCount() {
9364
+ return this.completedSteps.length;
9365
+ }
9366
+ };
9367
+
9445
9368
  // ../git/dist/sagas/tree.js
9446
9369
  var import_node_fs2 = require("fs");
9447
9370
  var fs5 = __toESM(require("fs/promises"), 1);