@posthog/agent 2.3.403 → 2.3.418

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.
@@ -3912,7 +3912,7 @@ function isSupportedReasoningEffort(adapter, modelId, value) {
3912
3912
  }
3913
3913
 
3914
3914
  // src/server/agent-server.ts
3915
- var import_promises5 = require("fs/promises");
3915
+ var import_promises6 = require("fs/promises");
3916
3916
  var import_node_path8 = require("path");
3917
3917
  var import_node_url2 = require("url");
3918
3918
  var import_sdk5 = require("@agentclientprotocol/sdk");
@@ -8266,12 +8266,12 @@ function isTaskError(result) {
8266
8266
  function getErrorMessage(result) {
8267
8267
  return Buffer.concat([...result.stdOut, ...result.stdErr]);
8268
8268
  }
8269
- function errorDetectionHandler(overwrite = false, isError = isTaskError, errorMessage = getErrorMessage) {
8269
+ function errorDetectionHandler(overwrite = false, isError = isTaskError, errorMessage2 = getErrorMessage) {
8270
8270
  return (error, result) => {
8271
8271
  if (!overwrite && error || !isError(result)) {
8272
8272
  return error;
8273
8273
  }
8274
- return errorMessage(result);
8274
+ return errorMessage2(result);
8275
8275
  };
8276
8276
  }
8277
8277
  function errorDetectionPlugin(config) {
@@ -8723,7 +8723,7 @@ var import_zod3 = require("zod");
8723
8723
  // package.json
8724
8724
  var package_default = {
8725
8725
  name: "@posthog/agent",
8726
- version: "2.3.403",
8726
+ version: "2.3.418",
8727
8727
  repository: "https://github.com/PostHog/code",
8728
8728
  description: "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
8729
8729
  exports: {
@@ -12906,6 +12906,8 @@ var ParseResult = class {
12906
12906
  return this.calls.filter((c) => CAPTURE_METHODS.has(c.method)).map((c) => ({
12907
12907
  name: c.key,
12908
12908
  line: c.line,
12909
+ keyStartCol: c.keyStartCol,
12910
+ keyEndCol: c.keyEndCol,
12909
12911
  dynamic: c.dynamic ?? false,
12910
12912
  viaWrapper: c.viaWrapper,
12911
12913
  inJsx: c.inJsx
@@ -12916,6 +12918,8 @@ var ParseResult = class {
12916
12918
  method: c.method,
12917
12919
  flagKey: c.key,
12918
12920
  line: c.line,
12921
+ keyStartCol: c.keyStartCol,
12922
+ keyEndCol: c.keyEndCol,
12919
12923
  viaWrapper: c.viaWrapper,
12920
12924
  inJsx: c.inJsx
12921
12925
  }));
@@ -13065,6 +13069,15 @@ var PostHogEnricher = class {
13065
13069
  settled[4]
13066
13070
  );
13067
13071
  }
13072
+ /**
13073
+ * Detect wrapper functions (functions that internally call a PostHog SDK
13074
+ * method) defined in the given source. Used by callers like `enrichSource`
13075
+ * to pick up same-file wrappers such as `track(...)` without threading
13076
+ * through filesystem I/O.
13077
+ */
13078
+ async findWrappersInSource(source, languageId) {
13079
+ return this.detector.findWrappers(source, languageId);
13080
+ }
13068
13081
  async parseFile(filePath) {
13069
13082
  const ext = path32.extname(filePath).toLowerCase();
13070
13083
  const languageId = EXT_TO_LANG_ID[ext];
@@ -13265,6 +13278,7 @@ async function withTimeout(operation, timeoutMs) {
13265
13278
  return Promise.race([operationPromise, timeoutPromise]);
13266
13279
  }
13267
13280
  var IS_ROOT = typeof process !== "undefined" && (process.geteuid?.() ?? process.getuid?.()) === 0;
13281
+ var ALLOW_BYPASS = !IS_ROOT || !!process.env.IS_SANDBOX;
13268
13282
  function unreachable(value, logger) {
13269
13283
  let valueAsString;
13270
13284
  try {
@@ -15056,7 +15070,6 @@ function normalizeAskUserQuestionInput(input) {
15056
15070
  }
15057
15071
 
15058
15072
  // src/execution-mode.ts
15059
- var ALLOW_BYPASS = !IS_ROOT;
15060
15073
  var availableModes = [
15061
15074
  {
15062
15075
  id: "default",
@@ -15099,7 +15112,7 @@ function isCodeExecutionMode(mode) {
15099
15112
  return CODE_EXECUTION_MODES.includes(mode);
15100
15113
  }
15101
15114
  function getAvailableModes() {
15102
- return IS_ROOT ? availableModes.filter((m) => m.id !== "bypassPermissions") : availableModes;
15115
+ return ALLOW_BYPASS ? availableModes : availableModes.filter((m) => m.id !== "bypassPermissions");
15103
15116
  }
15104
15117
  var CODEX_NATIVE_MODES = ["auto", "read-only", "full-access"];
15105
15118
  function isCodexNativeMode(mode) {
@@ -15232,10 +15245,9 @@ function buildPermissionOptions(toolName, toolInput, repoRoot, suggestions) {
15232
15245
  }
15233
15246
  return permissionOptions("Yes, always allow");
15234
15247
  }
15235
- var ALLOW_BYPASS2 = !IS_ROOT || !!process.env.IS_SANDBOX;
15236
15248
  function buildExitPlanModePermissionOptions() {
15237
15249
  const options = [];
15238
- if (ALLOW_BYPASS2) {
15250
+ if (ALLOW_BYPASS) {
15239
15251
  options.push({
15240
15252
  kind: "allow_always",
15241
15253
  name: "Yes, bypass all permissions",
@@ -15338,17 +15350,8 @@ async function requestPlanApproval(context, updatedInput) {
15338
15350
  });
15339
15351
  }
15340
15352
  async function applyPlanApproval(response, context, updatedInput) {
15341
- const { session } = context;
15342
15353
  if (response.outcome?.outcome === "selected" && (response.outcome.optionId === "auto" || response.outcome.optionId === "default" || response.outcome.optionId === "acceptEdits" || response.outcome.optionId === "bypassPermissions")) {
15343
- session.permissionMode = response.outcome.optionId;
15344
- await session.query.setPermissionMode(response.outcome.optionId);
15345
- await context.client.sessionUpdate({
15346
- sessionId: context.sessionId,
15347
- update: {
15348
- sessionUpdate: "current_mode_update",
15349
- currentModeId: response.outcome.optionId
15350
- }
15351
- });
15354
+ await context.applySessionMode(response.outcome.optionId);
15352
15355
  await context.updateConfigOption("mode", response.outcome.optionId);
15353
15356
  return {
15354
15357
  behavior: "allow",
@@ -15369,9 +15372,8 @@ async function applyPlanApproval(response, context, updatedInput) {
15369
15372
  return { behavior: "deny", message, interrupt: !feedback };
15370
15373
  }
15371
15374
  async function handleEnterPlanModeTool(context) {
15372
- const { session, toolInput } = context;
15373
- session.permissionMode = "plan";
15374
- await session.query.setPermissionMode("plan");
15375
+ const { toolInput } = context;
15376
+ await context.applySessionMode("plan");
15375
15377
  await context.updateConfigOption("mode", "plan");
15376
15378
  return {
15377
15379
  behavior: "allow",
@@ -15979,7 +15981,7 @@ function buildSessionOptions(params) {
15979
15981
  stderr: (err2) => params.logger.error(err2),
15980
15982
  cwd: params.cwd,
15981
15983
  includePartialMessages: true,
15982
- allowDangerouslySkipPermissions: !IS_ROOT,
15984
+ allowDangerouslySkipPermissions: !IS_ROOT || !!process.env.IS_SANDBOX,
15983
15985
  permissionMode: params.permissionMode,
15984
15986
  canUseTool: params.canUseTool,
15985
15987
  executable: "node",
@@ -17071,6 +17073,15 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
17071
17073
  configOptions: this.session.configOptions
17072
17074
  }
17073
17075
  });
17076
+ if (configId === "mode") {
17077
+ await this.client.sessionUpdate({
17078
+ sessionId: this.sessionId,
17079
+ update: {
17080
+ sessionUpdate: "current_mode_update",
17081
+ currentModeId: value
17082
+ }
17083
+ });
17084
+ }
17074
17085
  }
17075
17086
  async applySessionMode(modeId) {
17076
17087
  if (!CODE_EXECUTION_MODES.includes(modeId)) {
@@ -17293,6 +17304,7 @@ var ClaudeAcpAgent = class extends BaseAcpAgent {
17293
17304
  fileContentCache: this.fileContentCache,
17294
17305
  logger: this.logger,
17295
17306
  updateConfigOption: (configId, value) => this.updateConfigOption(configId, value),
17307
+ applySessionMode: (modeId) => this.applySessionMode(modeId),
17296
17308
  allowedDomains
17297
17309
  });
17298
17310
  }
@@ -18275,6 +18287,15 @@ var CodexAcpAgent = class extends BaseAcpAgent {
18275
18287
  if (response.configOptions) {
18276
18288
  this.sessionState.configOptions = response.configOptions;
18277
18289
  }
18290
+ if (params.configId === "mode" && typeof params.value === "string") {
18291
+ await this.client.sessionUpdate({
18292
+ sessionId: this.sessionId,
18293
+ update: {
18294
+ sessionUpdate: "current_mode_update",
18295
+ currentModeId: params.value
18296
+ }
18297
+ });
18298
+ }
18278
18299
  return response;
18279
18300
  }
18280
18301
  async authenticate(_params) {
@@ -19477,14 +19498,14 @@ var PostHogAPIClient = class {
19477
19498
  async apiRequest(endpoint, options = {}) {
19478
19499
  const response = await this.performRequestWithRetry(endpoint, options);
19479
19500
  if (!response.ok) {
19480
- let errorMessage;
19501
+ let errorMessage2;
19481
19502
  try {
19482
19503
  const errorResponse = await response.json();
19483
- errorMessage = `Failed request: [${response.status}] ${JSON.stringify(errorResponse)}`;
19504
+ errorMessage2 = `Failed request: [${response.status}] ${JSON.stringify(errorResponse)}`;
19484
19505
  } catch {
19485
- errorMessage = `Failed request: [${response.status}] ${response.statusText}`;
19506
+ errorMessage2 = `Failed request: [${response.status}] ${response.statusText}`;
19486
19507
  }
19487
- throw new Error(errorMessage);
19508
+ throw new Error(errorMessage2);
19488
19509
  }
19489
19510
  return response.json();
19490
19511
  }
@@ -20270,6 +20291,72 @@ var SessionLogWriter = class _SessionLogWriter {
20270
20291
  }
20271
20292
  };
20272
20293
 
20294
+ // src/server/agentsh-runtime.ts
20295
+ var import_node_child_process5 = require("child_process");
20296
+ var import_promises5 = require("fs/promises");
20297
+ var import_node_util2 = require("util");
20298
+ var AGENTSH_SESSION_ID_FILE = "/tmp/agentsh-session-id";
20299
+ var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process5.execFile);
20300
+ function errorMessage(error) {
20301
+ return error instanceof Error ? error.message : String(error);
20302
+ }
20303
+ function parseAgentshVersion(output) {
20304
+ const version = `${output.stdout}
20305
+ ${output.stderr}`.split("\n").map((line) => line.trim()).find(Boolean);
20306
+ return version ?? null;
20307
+ }
20308
+ async function getAgentshVersion() {
20309
+ const { stdout, stderr } = await execFileAsync2("agentsh", ["--version"], {
20310
+ timeout: 5e3
20311
+ });
20312
+ return { stdout, stderr };
20313
+ }
20314
+ async function resolveAgentshRuntimeInfo({
20315
+ sessionIdPath = AGENTSH_SESSION_ID_FILE,
20316
+ readSessionId = async (path16) => (0, import_promises5.readFile)(path16, "utf8"),
20317
+ getVersion = getAgentshVersion
20318
+ } = {}) {
20319
+ let sessionId;
20320
+ try {
20321
+ sessionId = (await readSessionId(sessionIdPath)).trim();
20322
+ } catch (error) {
20323
+ const code = error.code;
20324
+ if (code === "ENOENT") {
20325
+ return null;
20326
+ }
20327
+ throw error;
20328
+ }
20329
+ if (!sessionId) {
20330
+ return null;
20331
+ }
20332
+ try {
20333
+ const output = await getVersion();
20334
+ return {
20335
+ sessionId,
20336
+ version: parseAgentshVersion(output)
20337
+ };
20338
+ } catch (error) {
20339
+ return {
20340
+ sessionId,
20341
+ version: null,
20342
+ versionLookupError: errorMessage(error)
20343
+ };
20344
+ }
20345
+ }
20346
+ async function logAgentshRuntimeInfo(logger, options) {
20347
+ const agentsh = await resolveAgentshRuntimeInfo(options);
20348
+ if (!agentsh) {
20349
+ return;
20350
+ }
20351
+ logger.debug(`Agentsh session ID: ${agentsh.sessionId}`);
20352
+ logger.debug(`Agentsh hardening version: ${agentsh.version ?? "unknown"}`);
20353
+ if (agentsh.versionLookupError) {
20354
+ logger.debug(
20355
+ `Agentsh version lookup failed: ${agentsh.versionLookupError}`
20356
+ );
20357
+ }
20358
+ }
20359
+
20273
20360
  // src/server/cloud-prompt.ts
20274
20361
  function normalizeCloudPromptContent(content) {
20275
20362
  if (typeof content === "string") {
@@ -20592,7 +20679,7 @@ var AgentServer = class {
20592
20679
  return this.getRuntimeAdapter() === "codex" ? "auto" : "default";
20593
20680
  }
20594
20681
  shouldRelayPermissionToClient(mode) {
20595
- return mode === "default" || mode === "auto";
20682
+ return mode === "default" || mode === "auto" || mode === "read-only";
20596
20683
  }
20597
20684
  createApp() {
20598
20685
  const app = new import_hono.Hono();
@@ -21109,6 +21196,7 @@ var AgentServer = class {
21109
21196
  this.logger.debug(
21110
21197
  `Agent version: ${this.config.version ?? package_default.version}`
21111
21198
  );
21199
+ await logAgentshRuntimeInfo(this.logger);
21112
21200
  this.logger.debug(`Initial permission mode: ${initialPermissionMode}`);
21113
21201
  this.posthogAPI.updateTaskRun(payload.task_id, payload.run_id, {
21114
21202
  status: "in_progress"
@@ -21127,12 +21215,12 @@ var AgentServer = class {
21127
21215
  }
21128
21216
  classifyAndSignalFailure(payload, phase, error) {
21129
21217
  const { classification, message } = this.extractErrorClassification(error);
21130
- const errorMessage = classification === "upstream_stream_terminated" ? "Upstream LLM stream terminated" : classification === "upstream_connection_error" ? "Upstream LLM connection error" : message || "Agent error";
21218
+ const errorMessage2 = classification === "upstream_stream_terminated" ? "Upstream LLM stream terminated" : classification === "upstream_connection_error" ? "Upstream LLM connection error" : message || "Agent error";
21131
21219
  this.logger.error(`send_${phase}_task_message_failed`, {
21132
21220
  classification,
21133
21221
  message
21134
21222
  });
21135
- return this.signalTaskComplete(payload, "error", errorMessage);
21223
+ return this.signalTaskComplete(payload, "error", errorMessage2);
21136
21224
  }
21137
21225
  async sendInitialTaskMessage(payload, prefetchedRun) {
21138
21226
  if (!this.session) return;
@@ -21440,9 +21528,9 @@ Continue from where you left off. The user is waiting for your response.`
21440
21528
  runId,
21441
21529
  artifact.id ?? safeName
21442
21530
  );
21443
- await (0, import_promises5.mkdir)(artifactDir, { recursive: true });
21531
+ await (0, import_promises6.mkdir)(artifactDir, { recursive: true });
21444
21532
  const artifactPath = (0, import_node_path8.join)(artifactDir, safeName);
21445
- await (0, import_promises5.writeFile)(artifactPath, Buffer.from(data));
21533
+ await (0, import_promises6.writeFile)(artifactPath, Buffer.from(data));
21446
21534
  return resourceLink((0, import_node_url2.pathToFileURL)(artifactPath).toString(), artifact.name, {
21447
21535
  ...artifact.content_type ? { mimeType: artifact.content_type } : {},
21448
21536
  ...typeof artifact.size === "number" ? { size: artifact.size } : {}
@@ -21654,7 +21742,7 @@ ${attributionInstructions}
21654
21742
  });
21655
21743
  }
21656
21744
  }
21657
- async signalTaskComplete(payload, stopReason, errorMessage) {
21745
+ async signalTaskComplete(payload, stopReason, errorMessage2) {
21658
21746
  if (this.session?.payload.run_id === payload.run_id) {
21659
21747
  try {
21660
21748
  await this.session.logWriter.flush(payload.run_id, {
@@ -21678,7 +21766,7 @@ ${attributionInstructions}
21678
21766
  try {
21679
21767
  await this.posthogAPI.updateTaskRun(payload.task_id, payload.run_id, {
21680
21768
  status,
21681
- error_message: errorMessage ?? "Agent error"
21769
+ error_message: errorMessage2 ?? "Agent error"
21682
21770
  });
21683
21771
  this.logger.debug("Task completion signaled", { status, stopReason });
21684
21772
  } catch (error) {