@posthog/agent 1.30.0 → 2.0.1

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 (144) 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 +172 -1203
  35. package/dist/index.js +3704 -6826
  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 +4451 -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 +4507 -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 +66 -14
  51. package/src/acp-extensions.ts +93 -61
  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 -611
  70. package/src/adapters/claude/types.ts +61 -0
  71. package/src/adapters/codex/spawn.ts +130 -0
  72. package/src/agent.ts +97 -734
  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 +51 -154
  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/dist/templates/plan-template.md +0 -41
  119. package/src/adapters/claude/claude.ts +0 -1543
  120. package/src/adapters/claude/mcp-server.ts +0 -810
  121. package/src/adapters/claude/utils.ts +0 -267
  122. package/src/agents/execution.ts +0 -37
  123. package/src/agents/planning.ts +0 -60
  124. package/src/agents/research.ts +0 -160
  125. package/src/file-manager.ts +0 -306
  126. package/src/git-manager.ts +0 -577
  127. package/src/prompt-builder.ts +0 -499
  128. package/src/schemas.ts +0 -241
  129. package/src/session-store.ts +0 -259
  130. package/src/task-manager.ts +0 -163
  131. package/src/template-manager.ts +0 -236
  132. package/src/templates/plan-template.md +0 -41
  133. package/src/todo-manager.ts +0 -180
  134. package/src/tools/registry.ts +0 -129
  135. package/src/tools/types.ts +0 -127
  136. package/src/utils/tapped-stream.ts +0 -60
  137. package/src/workflow/config.ts +0 -53
  138. package/src/workflow/steps/build.ts +0 -135
  139. package/src/workflow/steps/finalize.ts +0 -241
  140. package/src/workflow/steps/plan.ts +0 -167
  141. package/src/workflow/steps/research.ts +0 -223
  142. package/src/workflow/types.ts +0 -62
  143. package/src/workflow/utils.ts +0 -53
  144. package/src/worktree-manager.ts +0 -928
@@ -0,0 +1,220 @@
1
+ import jwt from "jsonwebtoken";
2
+ import { type SetupServerApi, setupServer } from "msw/node";
3
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
4
+ import { createTestRepo, type TestRepo } from "../test/fixtures/api.js";
5
+ import { createPostHogHandlers } from "../test/mocks/msw-handlers.js";
6
+ import { AgentServer } from "./agent-server.js";
7
+ import { type JwtPayload, SANDBOX_CONNECTION_AUDIENCE } from "./jwt.js";
8
+
9
+ function createTestJwt(
10
+ payload: JwtPayload,
11
+ privateKey: string,
12
+ expiresInSeconds = 3600,
13
+ ): string {
14
+ return jwt.sign(
15
+ { ...payload, aud: SANDBOX_CONNECTION_AUDIENCE },
16
+ privateKey,
17
+ {
18
+ algorithm: "RS256",
19
+ expiresIn: expiresInSeconds,
20
+ },
21
+ );
22
+ }
23
+
24
+ // Test RSA key pair (2048-bit, for testing only)
25
+ const TEST_PRIVATE_KEY = `-----BEGIN PRIVATE KEY-----
26
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDqh94SYMFsvG4C
27
+ Co9BSGjtPr2/OxzuNGr41O4+AMkDQRd9pKO49DhTA4VzwnOvrH8y4eI9N8OQne7B
28
+ wpdoouSn4DoDAS/b3SUfij/RoFUSyZiTQoWz0H6o2Vuufiz0Hf+BzlZEVnhSQ1ru
29
+ vqSf+4l8cWgeMXaFXgdD5kQ8GjvR5uqKxvO2Env1hMJRKeOOEGgCep/0c6SkMUTX
30
+ SeC+VjypVg9+8yPxtIpOQ7XKv+7e/PA0ilqehRQh4fo9BAWjUW1+HnbtsjJAjjfv
31
+ ngzIjpajuQVyMi7G79v8OvijhLMJjJBh3TdbVIfi+RkVj/H94UUfKWRfJA0eLykA
32
+ VvTiFf0nAgMBAAECggEABkLBQWFW2IXBNAm/IEGEF408uH2l/I/mqSTaBUq1EwKq
33
+ U17RRg8y77hg2CHBP9fNf3i7NuIltNcaeA6vRwpOK1MXiVv/QJHLO2fP41Mx4jIC
34
+ gi/c7NtsfiprQaG5pnykhP0SnXlndd65bzUkpOasmWdXnbK5VL8ZV40uliInJafE
35
+ 1Eo9qSYCJxHmivU/4AbiBgygOAo1QIiuuUHcx0YGknLrBaMQETuvWJGE3lxVQ30/
36
+ EuRyA3r6BwN2T0z47PZBzvCpg/C1KeoYuKSMwMyEXfl+a8NclqdROkVaenmZpvVH
37
+ 0lAvFDuPrBSDmU4XJbKCEfwfHjRkiWAFaTrKntGQtQKBgQD/ILoK4U9DkJoKTYvY
38
+ 9lX7dg6wNO8jGLHNufU8tHhU+QnBMH3hBXrAtIKQ1sGs+D5rq/O7o0Balmct9vwb
39
+ CQZ1EpPfa83Thsv6Skd7lWK0JF7g2vVk8kT4nY/eqkgZUWgkfdMp+OMg2drYiIE8
40
+ u+sRPTCdq4Tv5miRg0OToX2H/QKBgQDrVR2GXm6ZUyFbCy8A0kttXP1YyXqDVq7p
41
+ L4kqyUq43hmbjzIRM4YDN3EvgZvVf6eub6L/3HfKvWD/OvEhHovTvHb9jkwZ3FO+
42
+ YQllB/ccAWJs/Dw5jLAsX9O+eIe4lfwROib3vYLnDTAmrXD5VL35R5F0MsdRoxk5
43
+ lTCq1sYI8wKBgGA9ZjDIgXAJUjJkwkZb1l9/T1clALiKjjf+2AXIRkQ3lXhs5G9H
44
+ 8+BRt5cPjAvFsTZIrS6xDIufhNiP/NXt96OeGG4FaqVKihOmhYSW+57cwXWs4zjr
45
+ Mx1dwnHKZlw2m0R4unlwy60OwUFBbQ8ODER6gqZXl1Qv5G5Px+Qe3Q25AoGAUl+s
46
+ wgfz9r9egZvcjBEQTeuq0pVTyP1ipET7YnqrKSK1G/p3sAW09xNFDzfy8DyK2UhC
47
+ agUl+VVoym47UTh8AVWK4R4aDUNOHOmifDbZjHf/l96CxjI0yJOSbq2J9FarsOwG
48
+ D9nKJE49eIxlayD6jnM6us27bxwEDF/odSRQlXkCgYEAxn9l/5kewWkeEA0Afe1c
49
+ Uf+mepHBLw1Pbg5GJYIZPC6e5+wRNvtFjM5J6h5LVhyb7AjKeLBTeohoBKEfUyUO
50
+ rl/ql9qDIh5lJFn3uNh7+r7tmG21Zl2pyh+O8GljjZ25mYhdiwl0uqzVZaINe2Wa
51
+ vbMnD1ZQKgL8LHgb02cbTsc=
52
+ -----END PRIVATE KEY-----`;
53
+
54
+ const TEST_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
55
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6ofeEmDBbLxuAgqPQUho
56
+ 7T69vzsc7jRq+NTuPgDJA0EXfaSjuPQ4UwOFc8Jzr6x/MuHiPTfDkJ3uwcKXaKLk
57
+ p+A6AwEv290lH4o/0aBVEsmYk0KFs9B+qNlbrn4s9B3/gc5WRFZ4UkNa7r6kn/uJ
58
+ fHFoHjF2hV4HQ+ZEPBo70ebqisbzthJ79YTCUSnjjhBoAnqf9HOkpDFE10ngvlY8
59
+ qVYPfvMj8bSKTkO1yr/u3vzwNIpanoUUIeH6PQQFo1Ftfh527bIyQI43754MyI6W
60
+ o7kFcjIuxu/b/Dr4o4SzCYyQYd03W1SH4vkZFY/x/eFFHylkXyQNHi8pAFb04hX9
61
+ JwIDAQAB
62
+ -----END PUBLIC KEY-----`;
63
+
64
+ describe("AgentServer HTTP Mode", () => {
65
+ let repo: TestRepo;
66
+ let server: AgentServer;
67
+ let mswServer: SetupServerApi;
68
+ let appendLogCalls: unknown[][];
69
+ const port = 3099;
70
+
71
+ beforeEach(async () => {
72
+ repo = await createTestRepo("agent-server-http");
73
+ appendLogCalls = [];
74
+ mswServer = setupServer(
75
+ ...createPostHogHandlers({
76
+ baseUrl: "http://localhost:8000",
77
+ onAppendLog: (entries) => appendLogCalls.push(entries),
78
+ }),
79
+ );
80
+ mswServer.listen({ onUnhandledRequest: "bypass" });
81
+ });
82
+
83
+ afterEach(async () => {
84
+ if (server) {
85
+ await server.stop();
86
+ }
87
+ mswServer.close();
88
+ await repo.cleanup();
89
+ });
90
+
91
+ const createServer = () => {
92
+ server = new AgentServer({
93
+ port,
94
+ jwtPublicKey: TEST_PUBLIC_KEY,
95
+ repositoryPath: repo.path,
96
+ apiUrl: "http://localhost:8000",
97
+ apiKey: "test-api-key",
98
+ projectId: 1,
99
+ mode: "interactive",
100
+ taskId: "test-task-id",
101
+ runId: "test-run-id",
102
+ });
103
+ return server;
104
+ };
105
+
106
+ const createToken = (overrides = {}) => {
107
+ return createTestJwt(
108
+ {
109
+ run_id: "test-run-id",
110
+ task_id: "test-task-id",
111
+ team_id: 1,
112
+ user_id: 1,
113
+ distinct_id: "test-distinct-id",
114
+ mode: "interactive",
115
+ ...overrides,
116
+ },
117
+ TEST_PRIVATE_KEY,
118
+ );
119
+ };
120
+
121
+ describe("GET /health", () => {
122
+ it("returns ok status with active session", async () => {
123
+ await createServer().start();
124
+
125
+ const response = await fetch(`http://localhost:${port}/health`);
126
+ const body = await response.json();
127
+
128
+ expect(response.status).toBe(200);
129
+ expect(body).toEqual({ status: "ok", hasSession: true });
130
+ });
131
+ });
132
+
133
+ describe("GET /events", () => {
134
+ it("returns 401 without authorization header", async () => {
135
+ await createServer().start();
136
+
137
+ const response = await fetch(`http://localhost:${port}/events`);
138
+ const body = await response.json();
139
+
140
+ expect(response.status).toBe(401);
141
+ expect(body.error).toBe("Missing authorization header");
142
+ });
143
+
144
+ it("returns 401 with invalid token", async () => {
145
+ await createServer().start();
146
+
147
+ const response = await fetch(`http://localhost:${port}/events`, {
148
+ headers: { Authorization: "Bearer invalid-token" },
149
+ });
150
+ const body = await response.json();
151
+
152
+ expect(response.status).toBe(401);
153
+ expect(body.code).toBe("invalid_signature");
154
+ });
155
+
156
+ it("accepts valid JWT and returns SSE stream", async () => {
157
+ await createServer().start();
158
+ const token = createToken();
159
+
160
+ const response = await fetch(`http://localhost:${port}/events`, {
161
+ headers: { Authorization: `Bearer ${token}` },
162
+ });
163
+
164
+ expect(response.status).toBe(200);
165
+ expect(response.headers.get("content-type")).toBe("text/event-stream");
166
+ });
167
+ });
168
+
169
+ describe("POST /command", () => {
170
+ it("returns 401 without authorization", async () => {
171
+ await createServer().start();
172
+
173
+ const response = await fetch(`http://localhost:${port}/command`, {
174
+ method: "POST",
175
+ headers: { "Content-Type": "application/json" },
176
+ body: JSON.stringify({
177
+ jsonrpc: "2.0",
178
+ method: "user_message",
179
+ params: { content: "test" },
180
+ }),
181
+ });
182
+
183
+ expect(response.status).toBe(401);
184
+ });
185
+
186
+ it("returns 400 when run_id does not match active session", async () => {
187
+ await createServer().start();
188
+ const token = createToken({ run_id: "different-run-id" });
189
+
190
+ const response = await fetch(`http://localhost:${port}/command`, {
191
+ method: "POST",
192
+ headers: {
193
+ Authorization: `Bearer ${token}`,
194
+ "Content-Type": "application/json",
195
+ },
196
+ body: JSON.stringify({
197
+ jsonrpc: "2.0",
198
+ method: "user_message",
199
+ params: { content: "test" },
200
+ }),
201
+ });
202
+
203
+ expect(response.status).toBe(400);
204
+ const body = await response.json();
205
+ expect(body.error).toBe("No active session for this run");
206
+ });
207
+ });
208
+
209
+ describe("404 handling", () => {
210
+ it("returns 404 for unknown routes", async () => {
211
+ await createServer().start();
212
+
213
+ const response = await fetch(`http://localhost:${port}/unknown`);
214
+ const body = await response.json();
215
+
216
+ expect(response.status).toBe(404);
217
+ expect(body.error).toBe("Not found");
218
+ });
219
+ });
220
+ });