@posthog/agent 2.0.0 → 2.0.2

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.
Files changed (131) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +221 -219
  3. package/dist/adapters/claude/conversion/tool-use-to-acp.d.ts +21 -0
  4. package/dist/adapters/claude/conversion/tool-use-to-acp.js +547 -0
  5. package/dist/adapters/claude/conversion/tool-use-to-acp.js.map +1 -0
  6. package/dist/adapters/claude/permissions/permission-options.d.ts +13 -0
  7. package/dist/adapters/claude/permissions/permission-options.js +117 -0
  8. package/dist/adapters/claude/permissions/permission-options.js.map +1 -0
  9. package/dist/adapters/claude/questions/utils.d.ts +132 -0
  10. package/dist/adapters/claude/questions/utils.js +63 -0
  11. package/dist/adapters/claude/questions/utils.js.map +1 -0
  12. package/dist/adapters/claude/tools.d.ts +18 -0
  13. package/dist/adapters/claude/tools.js +95 -0
  14. package/dist/adapters/claude/tools.js.map +1 -0
  15. package/dist/agent-DBQY1BfC.d.ts +123 -0
  16. package/dist/agent.d.ts +5 -0
  17. package/dist/agent.js +3656 -0
  18. package/dist/agent.js.map +1 -0
  19. package/dist/claude-cli/cli.js +3695 -2746
  20. package/dist/claude-cli/vendor/ripgrep/COPYING +3 -0
  21. package/dist/claude-cli/vendor/ripgrep/arm64-darwin/rg +0 -0
  22. package/dist/claude-cli/vendor/ripgrep/arm64-darwin/ripgrep.node +0 -0
  23. package/dist/claude-cli/vendor/ripgrep/arm64-linux/rg +0 -0
  24. package/dist/claude-cli/vendor/ripgrep/arm64-linux/ripgrep.node +0 -0
  25. package/dist/claude-cli/vendor/ripgrep/x64-darwin/rg +0 -0
  26. package/dist/claude-cli/vendor/ripgrep/x64-darwin/ripgrep.node +0 -0
  27. package/dist/claude-cli/vendor/ripgrep/x64-linux/rg +0 -0
  28. package/dist/claude-cli/vendor/ripgrep/x64-linux/ripgrep.node +0 -0
  29. package/dist/claude-cli/vendor/ripgrep/x64-win32/rg.exe +0 -0
  30. package/dist/claude-cli/vendor/ripgrep/x64-win32/ripgrep.node +0 -0
  31. package/dist/gateway-models.d.ts +24 -0
  32. package/dist/gateway-models.js +93 -0
  33. package/dist/gateway-models.js.map +1 -0
  34. package/dist/index.d.ts +170 -1157
  35. package/dist/index.js +9373 -5135
  36. package/dist/index.js.map +1 -1
  37. package/dist/logger-DDBiMOOD.d.ts +24 -0
  38. package/dist/posthog-api.d.ts +40 -0
  39. package/dist/posthog-api.js +175 -0
  40. package/dist/posthog-api.js.map +1 -0
  41. package/dist/server/agent-server.d.ts +41 -0
  42. package/dist/server/agent-server.js +10503 -0
  43. package/dist/server/agent-server.js.map +1 -0
  44. package/dist/server/bin.d.ts +1 -0
  45. package/dist/server/bin.js +10558 -0
  46. package/dist/server/bin.js.map +1 -0
  47. package/dist/types.d.ts +129 -0
  48. package/dist/types.js +1 -0
  49. package/dist/types.js.map +1 -0
  50. package/package.json +65 -13
  51. package/src/acp-extensions.ts +98 -16
  52. package/src/adapters/acp-connection.ts +494 -0
  53. package/src/adapters/base-acp-agent.ts +150 -0
  54. package/src/adapters/claude/claude-agent.ts +596 -0
  55. package/src/adapters/claude/conversion/acp-to-sdk.ts +102 -0
  56. package/src/adapters/claude/conversion/sdk-to-acp.ts +571 -0
  57. package/src/adapters/claude/conversion/tool-use-to-acp.ts +618 -0
  58. package/src/adapters/claude/hooks.ts +64 -0
  59. package/src/adapters/claude/mcp/tool-metadata.ts +102 -0
  60. package/src/adapters/claude/permissions/permission-handlers.ts +433 -0
  61. package/src/adapters/claude/permissions/permission-options.ts +103 -0
  62. package/src/adapters/claude/plan/utils.ts +56 -0
  63. package/src/adapters/claude/questions/utils.ts +92 -0
  64. package/src/adapters/claude/session/commands.ts +38 -0
  65. package/src/adapters/claude/session/mcp-config.ts +37 -0
  66. package/src/adapters/claude/session/models.ts +12 -0
  67. package/src/adapters/claude/session/options.ts +236 -0
  68. package/src/adapters/claude/tool-meta.ts +143 -0
  69. package/src/adapters/claude/tools.ts +53 -688
  70. package/src/adapters/claude/types.ts +61 -0
  71. package/src/adapters/codex/spawn.ts +130 -0
  72. package/src/agent.ts +96 -587
  73. package/src/execution-mode.ts +43 -0
  74. package/src/gateway-models.ts +135 -0
  75. package/src/index.ts +79 -0
  76. package/src/otel-log-writer.test.ts +105 -0
  77. package/src/otel-log-writer.ts +94 -0
  78. package/src/posthog-api.ts +75 -235
  79. package/src/resume.ts +115 -0
  80. package/src/sagas/apply-snapshot-saga.test.ts +690 -0
  81. package/src/sagas/apply-snapshot-saga.ts +88 -0
  82. package/src/sagas/capture-tree-saga.test.ts +892 -0
  83. package/src/sagas/capture-tree-saga.ts +141 -0
  84. package/src/sagas/resume-saga.test.ts +558 -0
  85. package/src/sagas/resume-saga.ts +332 -0
  86. package/src/sagas/test-fixtures.ts +250 -0
  87. package/src/server/agent-server.test.ts +220 -0
  88. package/src/server/agent-server.ts +748 -0
  89. package/src/server/bin.ts +88 -0
  90. package/src/server/jwt.ts +65 -0
  91. package/src/server/schemas.ts +47 -0
  92. package/src/server/types.ts +13 -0
  93. package/src/server/utils/retry.test.ts +122 -0
  94. package/src/server/utils/retry.ts +61 -0
  95. package/src/server/utils/sse-parser.test.ts +93 -0
  96. package/src/server/utils/sse-parser.ts +46 -0
  97. package/src/session-log-writer.test.ts +140 -0
  98. package/src/session-log-writer.ts +137 -0
  99. package/src/test/assertions.ts +114 -0
  100. package/src/test/controllers/sse-controller.ts +107 -0
  101. package/src/test/fixtures/api.ts +111 -0
  102. package/src/test/fixtures/config.ts +33 -0
  103. package/src/test/fixtures/notifications.ts +92 -0
  104. package/src/test/mocks/claude-sdk.ts +251 -0
  105. package/src/test/mocks/msw-handlers.ts +48 -0
  106. package/src/test/setup.ts +114 -0
  107. package/src/test/wait.ts +41 -0
  108. package/src/tree-tracker.ts +173 -0
  109. package/src/types.ts +54 -137
  110. package/src/utils/acp-content.ts +58 -0
  111. package/src/utils/async-mutex.test.ts +104 -0
  112. package/src/utils/async-mutex.ts +31 -0
  113. package/src/utils/common.ts +15 -0
  114. package/src/utils/gateway.ts +9 -6
  115. package/src/utils/logger.ts +0 -30
  116. package/src/utils/streams.ts +220 -0
  117. package/CLAUDE.md +0 -331
  118. package/src/adapters/claude/claude.ts +0 -1947
  119. package/src/adapters/claude/mcp-server.ts +0 -810
  120. package/src/adapters/claude/utils.ts +0 -267
  121. package/src/adapters/connection.ts +0 -95
  122. package/src/file-manager.ts +0 -273
  123. package/src/git-manager.ts +0 -577
  124. package/src/schemas.ts +0 -241
  125. package/src/session-store.ts +0 -259
  126. package/src/task-manager.ts +0 -163
  127. package/src/todo-manager.ts +0 -180
  128. package/src/tools/registry.ts +0 -134
  129. package/src/tools/types.ts +0 -133
  130. package/src/utils/tapped-stream.ts +0 -60
  131. package/src/worktree-manager.ts +0 -974
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Stored custom notification following ACP extensibility model.
3
+ * Custom notifications use underscore-prefixed methods (e.g., `_posthog/phase_start`).
4
+ * See: https://agentclientprotocol.com/docs/extensibility
5
+ */
6
+ interface StoredNotification {
7
+ type: "notification";
8
+ /** When this notification was stored */
9
+ timestamp: string;
10
+ /** JSON-RPC 2.0 notification (no id field = notification, not request) */
11
+ notification: {
12
+ jsonrpc: "2.0";
13
+ method: string;
14
+ params?: Record<string, unknown>;
15
+ };
16
+ }
17
+ /**
18
+ * Type alias for stored log entries.
19
+ */
20
+ type StoredEntry = StoredNotification;
21
+ interface Task {
22
+ id: string;
23
+ task_number?: number;
24
+ slug?: string;
25
+ title: string;
26
+ description: string;
27
+ origin_product: "error_tracking" | "eval_clusters" | "user_created" | "support_queue" | "session_summaries";
28
+ github_integration?: number | null;
29
+ repository: string;
30
+ json_schema?: Record<string, unknown> | null;
31
+ created_at: string;
32
+ updated_at: string;
33
+ created_by?: {
34
+ id: number;
35
+ uuid: string;
36
+ distinct_id: string;
37
+ first_name: string;
38
+ email: string;
39
+ };
40
+ latest_run?: TaskRun;
41
+ }
42
+ type ArtifactType = "plan" | "context" | "reference" | "output" | "artifact" | "tree_snapshot";
43
+ interface TaskRunArtifact {
44
+ name: string;
45
+ type: ArtifactType;
46
+ size?: number;
47
+ content_type?: string;
48
+ storage_path?: string;
49
+ uploaded_at?: string;
50
+ }
51
+ type TaskRunStatus = "not_started" | "queued" | "in_progress" | "completed" | "failed" | "cancelled";
52
+ type TaskRunEnvironment = "local" | "cloud";
53
+ interface TaskRun {
54
+ id: string;
55
+ task: string;
56
+ team: number;
57
+ branch: string | null;
58
+ stage: string | null;
59
+ environment: TaskRunEnvironment;
60
+ status: TaskRunStatus;
61
+ log_url: string;
62
+ error_message: string | null;
63
+ output: Record<string, unknown> | null;
64
+ state: Record<string, unknown>;
65
+ artifacts?: TaskRunArtifact[];
66
+ created_at: string;
67
+ updated_at: string;
68
+ completed_at: string | null;
69
+ }
70
+ interface ProcessSpawnedCallback {
71
+ onProcessSpawned?: (info: {
72
+ pid: number;
73
+ command: string;
74
+ sessionId?: string;
75
+ }) => void;
76
+ onProcessExited?: (pid: number) => void;
77
+ }
78
+ interface TaskExecutionOptions {
79
+ repositoryPath?: string;
80
+ adapter?: "claude" | "codex";
81
+ model?: string;
82
+ codexBinaryPath?: string;
83
+ processCallbacks?: ProcessSpawnedCallback;
84
+ }
85
+ type LogLevel = "debug" | "info" | "warn" | "error";
86
+ type OnLogCallback = (level: LogLevel, scope: string, message: string, data?: unknown) => void;
87
+ interface PostHogAPIConfig {
88
+ apiUrl: string;
89
+ getApiKey: () => string;
90
+ projectId: number;
91
+ }
92
+ interface OtelTransportConfig {
93
+ /** PostHog ingest host, e.g., "https://us.i.posthog.com" */
94
+ host: string;
95
+ /** Project API key */
96
+ apiKey: string;
97
+ /** Override the logs endpoint path (default: /i/v1/logs) */
98
+ logsPath?: string;
99
+ }
100
+ interface AgentConfig {
101
+ posthog?: PostHogAPIConfig;
102
+ /** OTEL transport config for shipping logs to PostHog Logs */
103
+ otelTransport?: OtelTransportConfig;
104
+ debug?: boolean;
105
+ onLog?: OnLogCallback;
106
+ }
107
+ interface DeviceInfo {
108
+ type: "local" | "cloud";
109
+ name?: string;
110
+ }
111
+ type AgentMode = "interactive" | "background";
112
+ type FileStatus = "A" | "M" | "D";
113
+ interface FileChange {
114
+ path: string;
115
+ status: FileStatus;
116
+ }
117
+ interface TreeSnapshot {
118
+ treeHash: string;
119
+ baseCommit: string | null;
120
+ archiveUrl?: string;
121
+ changes: FileChange[];
122
+ timestamp: string;
123
+ interrupted?: boolean;
124
+ }
125
+ interface TreeSnapshotEvent extends TreeSnapshot {
126
+ device?: DeviceInfo;
127
+ }
128
+
129
+ export type { AgentConfig, AgentMode, ArtifactType, DeviceInfo, FileChange, FileStatus, LogLevel, OnLogCallback, OtelTransportConfig, PostHogAPIConfig, ProcessSpawnedCallback, StoredEntry, StoredNotification, Task, TaskExecutionOptions, TaskRun, TaskRunArtifact, TaskRunEnvironment, TaskRunStatus, TreeSnapshot, TreeSnapshotEvent };
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,18 +1,53 @@
1
1
  {
2
2
  "name": "@posthog/agent",
3
- "version": "2.0.0",
4
- "repository": "https://github.com/PostHog/array",
3
+ "version": "2.0.2",
4
+ "repository": "https://github.com/PostHog/twig",
5
5
  "description": "TypeScript agent framework wrapping Claude Agent SDK with Git-based task execution for PostHog",
6
- "main": "./dist/index.js",
7
- "module": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
9
6
  "exports": {
10
7
  ".": {
11
8
  "types": "./dist/index.d.ts",
12
- "import": "./dist/index.js",
13
- "require": "./dist/index.js"
9
+ "import": "./dist/index.js"
10
+ },
11
+ "./agent": {
12
+ "types": "./dist/agent.d.ts",
13
+ "import": "./dist/agent.js"
14
+ },
15
+ "./gateway-models": {
16
+ "types": "./dist/gateway-models.d.ts",
17
+ "import": "./dist/gateway-models.js"
18
+ },
19
+ "./posthog-api": {
20
+ "types": "./dist/posthog-api.d.ts",
21
+ "import": "./dist/posthog-api.js"
22
+ },
23
+ "./types": {
24
+ "types": "./dist/types.d.ts",
25
+ "import": "./dist/types.js"
26
+ },
27
+ "./adapters/claude/questions/utils": {
28
+ "types": "./dist/adapters/claude/questions/utils.d.ts",
29
+ "import": "./dist/adapters/claude/questions/utils.js"
30
+ },
31
+ "./adapters/claude/permissions/permission-options": {
32
+ "types": "./dist/adapters/claude/permissions/permission-options.d.ts",
33
+ "import": "./dist/adapters/claude/permissions/permission-options.js"
34
+ },
35
+ "./adapters/claude/tools": {
36
+ "types": "./dist/adapters/claude/tools.d.ts",
37
+ "import": "./dist/adapters/claude/tools.js"
38
+ },
39
+ "./adapters/claude/conversion/tool-use-to-acp": {
40
+ "types": "./dist/adapters/claude/conversion/tool-use-to-acp.d.ts",
41
+ "import": "./dist/adapters/claude/conversion/tool-use-to-acp.js"
42
+ },
43
+ "./server": {
44
+ "types": "./dist/server/agent-server.d.ts",
45
+ "import": "./dist/server/agent-server.js"
14
46
  }
15
47
  },
48
+ "bin": {
49
+ "agent-server": "./dist/server/bin.js"
50
+ },
16
51
  "type": "module",
17
52
  "keywords": [
18
53
  "posthog",
@@ -30,18 +65,34 @@
30
65
  "devDependencies": {
31
66
  "@changesets/cli": "^2.27.8",
32
67
  "@types/bun": "latest",
68
+ "@types/tar": "^6.1.13",
33
69
  "minimatch": "^10.0.3",
70
+ "msw": "^2.12.7",
34
71
  "tsup": "^8.5.1",
35
72
  "tsx": "^4.20.6",
36
- "typescript": "^5.5.0"
73
+ "typescript": "^5.5.0",
74
+ "vitest": "^2.1.8",
75
+ "@twig/git": "1.0.0",
76
+ "@posthog/shared": "1.0.0"
37
77
  },
38
78
  "dependencies": {
39
- "@agentclientprotocol/sdk": "^0.5.1",
40
- "@anthropic-ai/claude-agent-sdk": "^0.1.55",
79
+ "@opentelemetry/api-logs": "^0.208.0",
80
+ "@opentelemetry/exporter-logs-otlp-http": "^0.208.0",
81
+ "@opentelemetry/resources": "^2.0.0",
82
+ "@opentelemetry/sdk-logs": "^0.208.0",
83
+ "@opentelemetry/semantic-conventions": "^1.28.0",
84
+ "@agentclientprotocol/sdk": "^0.14.0",
85
+ "@anthropic-ai/claude-agent-sdk": "0.2.12",
41
86
  "@anthropic-ai/sdk": "^0.71.0",
42
- "@modelcontextprotocol/sdk": "^1.23.0",
87
+ "@hono/node-server": "^1.19.9",
88
+ "@modelcontextprotocol/sdk": "^1.25.3",
89
+ "@types/jsonwebtoken": "^9.0.10",
90
+ "commander": "^14.0.2",
43
91
  "diff": "^8.0.2",
44
92
  "dotenv": "^17.2.3",
93
+ "hono": "^4.11.7",
94
+ "jsonwebtoken": "^9.0.2",
95
+ "tar": "^7.5.0",
45
96
  "uuid": "13.0.0",
46
97
  "yoga-wasm-web": "^0.3.3",
47
98
  "zod": "^3.24.1"
@@ -58,7 +109,8 @@
58
109
  "scripts": {
59
110
  "build": "tsup",
60
111
  "dev": "tsup --watch",
61
- "typecheck": "pnpm exec tsc --noEmit",
62
- "example": "tsx example.ts"
112
+ "test": "vitest run",
113
+ "test:watch": "vitest",
114
+ "typecheck": "pnpm exec tsc --noEmit"
63
115
  }
64
116
  }
@@ -5,6 +5,10 @@
5
5
  * - Custom notification methods are prefixed with `_posthog/`
6
6
  * - Custom data can be attached via `_meta` fields
7
7
  *
8
+ * Note: When using `extNotification()` from the ACP SDK, it automatically
9
+ * adds an extra underscore prefix (e.g., `_posthog/tree_snapshot` becomes
10
+ * `__posthog/tree_snapshot` in the log). Code that reads logs should handle both.
11
+ *
8
12
  * See: https://agentclientprotocol.com/docs/extensibility
9
13
  */
10
14
 
@@ -13,23 +17,57 @@
13
17
  * Used with AgentSideConnection.extNotification() or Client.extNotification()
14
18
  */
15
19
  export const POSTHOG_NOTIFICATIONS = {
16
- /** Git branch was created */
20
+ /** Git branch was created for a task */
17
21
  BRANCH_CREATED: "_posthog/branch_created",
18
- /** Task run has started */
22
+
23
+ /** Task run has started execution */
19
24
  RUN_STARTED: "_posthog/run_started",
20
- /** Task has completed */
25
+
26
+ /** Task has completed (success or failure) */
21
27
  TASK_COMPLETE: "_posthog/task_complete",
28
+
22
29
  /** Error occurred during task execution */
23
30
  ERROR: "_posthog/error",
24
- /** Console/log output */
31
+
32
+ /** Console/log output from the agent */
25
33
  CONSOLE: "_posthog/console",
26
- /** SDK session ID notification (for resumption) */
34
+
35
+ /** Maps taskRunId to agent's sessionId and adapter type (for resumption) */
27
36
  SDK_SESSION: "_posthog/sdk_session",
37
+
38
+ /** Tree state snapshot captured (git tree hash + file archive) */
39
+ TREE_SNAPSHOT: "_posthog/tree_snapshot",
40
+
41
+ /** Agent mode changed (interactive/background) */
42
+ MODE_CHANGE: "_posthog/mode_change",
43
+
44
+ /** Request to resume a session from previous state */
45
+ SESSION_RESUME: "_posthog/session/resume",
46
+
47
+ /** User message sent from client to agent */
48
+ USER_MESSAGE: "_posthog/user_message",
49
+
50
+ /** Request to cancel current operation */
51
+ CANCEL: "_posthog/cancel",
52
+
53
+ /** Request to close the session */
54
+ CLOSE: "_posthog/close",
55
+
56
+ /** Agent status update (thinking, working, etc.) */
57
+ STATUS: "_posthog/status",
58
+
59
+ /** Task-level notification (progress, milestones) */
60
+ TASK_NOTIFICATION: "_posthog/task_notification",
61
+
62
+ /** Marks a boundary for log compaction */
63
+ COMPACT_BOUNDARY: "_posthog/compact_boundary",
28
64
  } as const;
29
65
 
30
66
  export type PostHogNotificationType =
31
67
  (typeof POSTHOG_NOTIFICATIONS)[keyof typeof POSTHOG_NOTIFICATIONS];
32
68
 
69
+ // --- Payload types for each notification ---
70
+
33
71
  export interface BranchCreatedPayload {
34
72
  branch: string;
35
73
  }
@@ -40,9 +78,6 @@ export interface RunStartedPayload {
40
78
  taskId?: string;
41
79
  }
42
80
 
43
- /**
44
- * Payload for task complete notification
45
- */
46
81
  export interface TaskCompletePayload {
47
82
  sessionId: string;
48
83
  taskId: string;
@@ -54,21 +89,61 @@ export interface ErrorNotificationPayload {
54
89
  error?: unknown;
55
90
  }
56
91
 
57
- /**
58
- * Console output for a session
59
- */
60
92
  export interface ConsoleNotificationPayload {
61
93
  sessionId: string;
62
94
  level: "debug" | "info" | "warn" | "error";
63
95
  message: string;
64
96
  }
65
97
 
66
- /**
67
- * Maps a session ID to a SDKs session ID
68
- */
69
98
  export interface SdkSessionPayload {
99
+ taskRunId: string;
100
+ sessionId: string;
101
+ adapter: "claude" | "codex";
102
+ }
103
+
104
+ export interface TreeSnapshotPayload {
105
+ treeHash: string;
106
+ baseCommit: string | null;
107
+ archiveUrl?: string;
108
+ changes: Array<{ path: string; status: "A" | "M" | "D" }>;
109
+ timestamp: string;
110
+ interrupted?: boolean;
111
+ device?: {
112
+ type: "local" | "cloud";
113
+ name?: string;
114
+ };
115
+ }
116
+
117
+ export interface ModeChangePayload {
118
+ mode: "interactive" | "background";
119
+ previous_mode: "interactive" | "background";
120
+ }
121
+
122
+ export interface SessionResumePayload {
123
+ sessionId: string;
124
+ fromSnapshot?: string;
125
+ }
126
+
127
+ export interface UserMessagePayload {
128
+ content: string;
129
+ }
130
+
131
+ export interface StatusPayload {
132
+ sessionId: string;
133
+ status: string;
134
+ message?: string;
135
+ }
136
+
137
+ export interface TaskNotificationPayload {
138
+ sessionId: string;
139
+ type: string;
140
+ message?: string;
141
+ data?: Record<string, unknown>;
142
+ }
143
+
144
+ export interface CompactBoundaryPayload {
70
145
  sessionId: string;
71
- sdkSessionId: string;
146
+ timestamp: string;
72
147
  }
73
148
 
74
149
  export type PostHogNotificationPayload =
@@ -77,4 +152,11 @@ export type PostHogNotificationPayload =
77
152
  | TaskCompletePayload
78
153
  | ErrorNotificationPayload
79
154
  | ConsoleNotificationPayload
80
- | SdkSessionPayload;
155
+ | SdkSessionPayload
156
+ | TreeSnapshotPayload
157
+ | ModeChangePayload
158
+ | SessionResumePayload
159
+ | UserMessagePayload
160
+ | StatusPayload
161
+ | TaskNotificationPayload
162
+ | CompactBoundaryPayload;