@posthog/agent 2.3.406 → 2.3.425

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/agent",
3
- "version": "2.3.406",
3
+ "version": "2.3.425",
4
4
  "repository": "https://github.com/PostHog/code",
5
5
  "description": "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
6
6
  "exports": {
@@ -103,8 +103,8 @@
103
103
  "typescript": "^5.5.0",
104
104
  "vitest": "^2.1.8",
105
105
  "@posthog/shared": "1.0.0",
106
- "@posthog/git": "1.0.0",
107
- "@posthog/enricher": "1.0.0"
106
+ "@posthog/enricher": "1.0.0",
107
+ "@posthog/git": "1.0.0"
108
108
  },
109
109
  "dependencies": {
110
110
  "@agentclientprotocol/sdk": "0.19.0",
@@ -48,6 +48,7 @@ import { resourceLink } from "../utils/acp-content";
48
48
  import { AsyncMutex } from "../utils/async-mutex";
49
49
  import { getLlmGatewayUrl } from "../utils/gateway";
50
50
  import { Logger } from "../utils/logger";
51
+ import { logAgentshRuntimeInfo } from "./agentsh-runtime";
51
52
  import {
52
53
  normalizeCloudPromptContent,
53
54
  promptBlocksToText,
@@ -954,6 +955,7 @@ export class AgentServer {
954
955
  this.logger.debug(
955
956
  `Agent version: ${this.config.version ?? packageJson.version}`,
956
957
  );
958
+ await logAgentshRuntimeInfo(this.logger);
957
959
  this.logger.debug(`Initial permission mode: ${initialPermissionMode}`);
958
960
 
959
961
  // Signal in_progress so the UI can start polling for updates
@@ -0,0 +1,107 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import {
3
+ logAgentshRuntimeInfo,
4
+ resolveAgentshRuntimeInfo,
5
+ } from "./agentsh-runtime";
6
+
7
+ describe("agentsh runtime detection", () => {
8
+ it("returns null when no agentsh session marker exists", async () => {
9
+ const getVersion = vi.fn();
10
+ const result = await resolveAgentshRuntimeInfo({
11
+ readSessionId: async () => {
12
+ const error = new Error("missing") as NodeJS.ErrnoException;
13
+ error.code = "ENOENT";
14
+ throw error;
15
+ },
16
+ getVersion,
17
+ });
18
+
19
+ expect(result).toBeNull();
20
+ expect(getVersion).not.toHaveBeenCalled();
21
+ });
22
+
23
+ it("rethrows unexpected session marker read errors", async () => {
24
+ const error = new Error("permission denied") as NodeJS.ErrnoException;
25
+ error.code = "EACCES";
26
+
27
+ await expect(
28
+ resolveAgentshRuntimeInfo({
29
+ readSessionId: async () => {
30
+ throw error;
31
+ },
32
+ }),
33
+ ).rejects.toBe(error);
34
+ });
35
+
36
+ it.each([
37
+ {
38
+ name: "returns the agentsh session id and version",
39
+ getVersion: async () => ({
40
+ stdout: "agentsh version 0.18.3\n",
41
+ stderr: "",
42
+ }),
43
+ expected: {
44
+ sessionId: "session-123",
45
+ version: "agentsh version 0.18.3",
46
+ },
47
+ },
48
+ {
49
+ name: "keeps the agentsh signal when version lookup fails",
50
+ getVersion: async () => {
51
+ throw new Error("agentsh not found");
52
+ },
53
+ expected: {
54
+ sessionId: "session-123",
55
+ version: null,
56
+ versionLookupError: "agentsh not found",
57
+ },
58
+ },
59
+ ])("$name", async ({ getVersion, expected }) => {
60
+ const result = await resolveAgentshRuntimeInfo({
61
+ readSessionId: async () => "session-123\n",
62
+ getVersion,
63
+ });
64
+
65
+ expect(result).toEqual(expected);
66
+ });
67
+
68
+ it("logs session id and version details", async () => {
69
+ const logger = { debug: vi.fn() };
70
+
71
+ await logAgentshRuntimeInfo(logger, {
72
+ readSessionId: async () => "session-123\n",
73
+ getVersion: async () => ({
74
+ stdout: "agentsh version 0.18.3\n",
75
+ stderr: "",
76
+ }),
77
+ });
78
+
79
+ expect(logger.debug).toHaveBeenCalledWith(
80
+ "Agentsh session ID: session-123",
81
+ );
82
+ expect(logger.debug).toHaveBeenCalledWith(
83
+ "Agentsh hardening version: agentsh version 0.18.3",
84
+ );
85
+ });
86
+
87
+ it("logs version lookup failures", async () => {
88
+ const logger = { debug: vi.fn() };
89
+
90
+ await logAgentshRuntimeInfo(logger, {
91
+ readSessionId: async () => "session-123\n",
92
+ getVersion: async () => {
93
+ throw new Error("agentsh not found");
94
+ },
95
+ });
96
+
97
+ expect(logger.debug).toHaveBeenCalledWith(
98
+ "Agentsh session ID: session-123",
99
+ );
100
+ expect(logger.debug).toHaveBeenCalledWith(
101
+ "Agentsh hardening version: unknown",
102
+ );
103
+ expect(logger.debug).toHaveBeenCalledWith(
104
+ "Agentsh version lookup failed: agentsh not found",
105
+ );
106
+ });
107
+ });
@@ -0,0 +1,97 @@
1
+ import { execFile } from "node:child_process";
2
+ import { readFile } from "node:fs/promises";
3
+ import { promisify } from "node:util";
4
+ import type { Logger } from "../utils/logger";
5
+
6
+ export const AGENTSH_SESSION_ID_FILE = "/tmp/agentsh-session-id";
7
+
8
+ const execFileAsync = promisify(execFile);
9
+
10
+ interface AgentshVersionOutput {
11
+ stdout: string;
12
+ stderr: string;
13
+ }
14
+
15
+ interface ResolveAgentshRuntimeInfoOptions {
16
+ sessionIdPath?: string;
17
+ readSessionId?: (path: string) => Promise<string>;
18
+ getVersion?: () => Promise<AgentshVersionOutput>;
19
+ }
20
+
21
+ export interface AgentshRuntimeInfo {
22
+ sessionId: string;
23
+ version: string | null;
24
+ versionLookupError?: string;
25
+ }
26
+
27
+ function errorMessage(error: unknown): string {
28
+ return error instanceof Error ? error.message : String(error);
29
+ }
30
+
31
+ function parseAgentshVersion(output: AgentshVersionOutput): string | null {
32
+ const version = `${output.stdout}\n${output.stderr}`
33
+ .split("\n")
34
+ .map((line) => line.trim())
35
+ .find(Boolean);
36
+ return version ?? null;
37
+ }
38
+
39
+ async function getAgentshVersion(): Promise<AgentshVersionOutput> {
40
+ const { stdout, stderr } = await execFileAsync("agentsh", ["--version"], {
41
+ timeout: 5_000,
42
+ });
43
+ return { stdout, stderr };
44
+ }
45
+
46
+ export async function resolveAgentshRuntimeInfo({
47
+ sessionIdPath = AGENTSH_SESSION_ID_FILE,
48
+ readSessionId = async (path: string) => readFile(path, "utf8"),
49
+ getVersion = getAgentshVersion,
50
+ }: ResolveAgentshRuntimeInfoOptions = {}): Promise<AgentshRuntimeInfo | null> {
51
+ let sessionId: string;
52
+ try {
53
+ sessionId = (await readSessionId(sessionIdPath)).trim();
54
+ } catch (error) {
55
+ const code = (error as NodeJS.ErrnoException).code;
56
+ if (code === "ENOENT") {
57
+ return null;
58
+ }
59
+ throw error;
60
+ }
61
+
62
+ if (!sessionId) {
63
+ return null;
64
+ }
65
+
66
+ try {
67
+ const output = await getVersion();
68
+ return {
69
+ sessionId,
70
+ version: parseAgentshVersion(output),
71
+ };
72
+ } catch (error) {
73
+ return {
74
+ sessionId,
75
+ version: null,
76
+ versionLookupError: errorMessage(error),
77
+ };
78
+ }
79
+ }
80
+
81
+ export async function logAgentshRuntimeInfo(
82
+ logger: Pick<Logger, "debug">,
83
+ options?: ResolveAgentshRuntimeInfoOptions,
84
+ ): Promise<void> {
85
+ const agentsh = await resolveAgentshRuntimeInfo(options);
86
+ if (!agentsh) {
87
+ return;
88
+ }
89
+
90
+ logger.debug(`Agentsh session ID: ${agentsh.sessionId}`);
91
+ logger.debug(`Agentsh hardening version: ${agentsh.version ?? "unknown"}`);
92
+ if (agentsh.versionLookupError) {
93
+ logger.debug(
94
+ `Agentsh version lookup failed: ${agentsh.versionLookupError}`,
95
+ );
96
+ }
97
+ }