@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.
- package/LICENSE +1 -1
- package/README.md +221 -219
- package/dist/adapters/claude/conversion/tool-use-to-acp.d.ts +21 -0
- package/dist/adapters/claude/conversion/tool-use-to-acp.js +547 -0
- package/dist/adapters/claude/conversion/tool-use-to-acp.js.map +1 -0
- package/dist/adapters/claude/permissions/permission-options.d.ts +13 -0
- package/dist/adapters/claude/permissions/permission-options.js +117 -0
- package/dist/adapters/claude/permissions/permission-options.js.map +1 -0
- package/dist/adapters/claude/questions/utils.d.ts +132 -0
- package/dist/adapters/claude/questions/utils.js +63 -0
- package/dist/adapters/claude/questions/utils.js.map +1 -0
- package/dist/adapters/claude/tools.d.ts +18 -0
- package/dist/adapters/claude/tools.js +95 -0
- package/dist/adapters/claude/tools.js.map +1 -0
- package/dist/agent-DBQY1BfC.d.ts +123 -0
- package/dist/agent.d.ts +5 -0
- package/dist/agent.js +3656 -0
- package/dist/agent.js.map +1 -0
- package/dist/claude-cli/cli.js +3695 -2746
- package/dist/claude-cli/vendor/ripgrep/COPYING +3 -0
- package/dist/claude-cli/vendor/ripgrep/arm64-darwin/rg +0 -0
- package/dist/claude-cli/vendor/ripgrep/arm64-darwin/ripgrep.node +0 -0
- package/dist/claude-cli/vendor/ripgrep/arm64-linux/rg +0 -0
- package/dist/claude-cli/vendor/ripgrep/arm64-linux/ripgrep.node +0 -0
- package/dist/claude-cli/vendor/ripgrep/x64-darwin/rg +0 -0
- package/dist/claude-cli/vendor/ripgrep/x64-darwin/ripgrep.node +0 -0
- package/dist/claude-cli/vendor/ripgrep/x64-linux/rg +0 -0
- package/dist/claude-cli/vendor/ripgrep/x64-linux/ripgrep.node +0 -0
- package/dist/claude-cli/vendor/ripgrep/x64-win32/rg.exe +0 -0
- package/dist/claude-cli/vendor/ripgrep/x64-win32/ripgrep.node +0 -0
- package/dist/gateway-models.d.ts +24 -0
- package/dist/gateway-models.js +93 -0
- package/dist/gateway-models.js.map +1 -0
- package/dist/index.d.ts +172 -1203
- package/dist/index.js +3704 -6826
- package/dist/index.js.map +1 -1
- package/dist/logger-DDBiMOOD.d.ts +24 -0
- package/dist/posthog-api.d.ts +40 -0
- package/dist/posthog-api.js +175 -0
- package/dist/posthog-api.js.map +1 -0
- package/dist/server/agent-server.d.ts +41 -0
- package/dist/server/agent-server.js +4451 -0
- package/dist/server/agent-server.js.map +1 -0
- package/dist/server/bin.d.ts +1 -0
- package/dist/server/bin.js +4507 -0
- package/dist/server/bin.js.map +1 -0
- package/dist/types.d.ts +129 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/package.json +66 -14
- package/src/acp-extensions.ts +93 -61
- package/src/adapters/acp-connection.ts +494 -0
- package/src/adapters/base-acp-agent.ts +150 -0
- package/src/adapters/claude/claude-agent.ts +596 -0
- package/src/adapters/claude/conversion/acp-to-sdk.ts +102 -0
- package/src/adapters/claude/conversion/sdk-to-acp.ts +571 -0
- package/src/adapters/claude/conversion/tool-use-to-acp.ts +618 -0
- package/src/adapters/claude/hooks.ts +64 -0
- package/src/adapters/claude/mcp/tool-metadata.ts +102 -0
- package/src/adapters/claude/permissions/permission-handlers.ts +433 -0
- package/src/adapters/claude/permissions/permission-options.ts +103 -0
- package/src/adapters/claude/plan/utils.ts +56 -0
- package/src/adapters/claude/questions/utils.ts +92 -0
- package/src/adapters/claude/session/commands.ts +38 -0
- package/src/adapters/claude/session/mcp-config.ts +37 -0
- package/src/adapters/claude/session/models.ts +12 -0
- package/src/adapters/claude/session/options.ts +236 -0
- package/src/adapters/claude/tool-meta.ts +143 -0
- package/src/adapters/claude/tools.ts +53 -611
- package/src/adapters/claude/types.ts +61 -0
- package/src/adapters/codex/spawn.ts +130 -0
- package/src/agent.ts +97 -734
- package/src/execution-mode.ts +43 -0
- package/src/gateway-models.ts +135 -0
- package/src/index.ts +79 -0
- package/src/otel-log-writer.test.ts +105 -0
- package/src/otel-log-writer.ts +94 -0
- package/src/posthog-api.ts +75 -235
- package/src/resume.ts +115 -0
- package/src/sagas/apply-snapshot-saga.test.ts +690 -0
- package/src/sagas/apply-snapshot-saga.ts +88 -0
- package/src/sagas/capture-tree-saga.test.ts +892 -0
- package/src/sagas/capture-tree-saga.ts +141 -0
- package/src/sagas/resume-saga.test.ts +558 -0
- package/src/sagas/resume-saga.ts +332 -0
- package/src/sagas/test-fixtures.ts +250 -0
- package/src/server/agent-server.test.ts +220 -0
- package/src/server/agent-server.ts +748 -0
- package/src/server/bin.ts +88 -0
- package/src/server/jwt.ts +65 -0
- package/src/server/schemas.ts +47 -0
- package/src/server/types.ts +13 -0
- package/src/server/utils/retry.test.ts +122 -0
- package/src/server/utils/retry.ts +61 -0
- package/src/server/utils/sse-parser.test.ts +93 -0
- package/src/server/utils/sse-parser.ts +46 -0
- package/src/session-log-writer.test.ts +140 -0
- package/src/session-log-writer.ts +137 -0
- package/src/test/assertions.ts +114 -0
- package/src/test/controllers/sse-controller.ts +107 -0
- package/src/test/fixtures/api.ts +111 -0
- package/src/test/fixtures/config.ts +33 -0
- package/src/test/fixtures/notifications.ts +92 -0
- package/src/test/mocks/claude-sdk.ts +251 -0
- package/src/test/mocks/msw-handlers.ts +48 -0
- package/src/test/setup.ts +114 -0
- package/src/test/wait.ts +41 -0
- package/src/tree-tracker.ts +173 -0
- package/src/types.ts +51 -154
- package/src/utils/acp-content.ts +58 -0
- package/src/utils/async-mutex.test.ts +104 -0
- package/src/utils/async-mutex.ts +31 -0
- package/src/utils/common.ts +15 -0
- package/src/utils/gateway.ts +9 -6
- package/src/utils/logger.ts +0 -30
- package/src/utils/streams.ts +220 -0
- package/CLAUDE.md +0 -331
- package/dist/templates/plan-template.md +0 -41
- package/src/adapters/claude/claude.ts +0 -1543
- package/src/adapters/claude/mcp-server.ts +0 -810
- package/src/adapters/claude/utils.ts +0 -267
- package/src/agents/execution.ts +0 -37
- package/src/agents/planning.ts +0 -60
- package/src/agents/research.ts +0 -160
- package/src/file-manager.ts +0 -306
- package/src/git-manager.ts +0 -577
- package/src/prompt-builder.ts +0 -499
- package/src/schemas.ts +0 -241
- package/src/session-store.ts +0 -259
- package/src/task-manager.ts +0 -163
- package/src/template-manager.ts +0 -236
- package/src/templates/plan-template.md +0 -41
- package/src/todo-manager.ts +0 -180
- package/src/tools/registry.ts +0 -129
- package/src/tools/types.ts +0 -127
- package/src/utils/tapped-stream.ts +0 -60
- package/src/workflow/config.ts +0 -53
- package/src/workflow/steps/build.ts +0 -135
- package/src/workflow/steps/finalize.ts +0 -241
- package/src/workflow/steps/plan.ts +0 -167
- package/src/workflow/steps/research.ts +0 -223
- package/src/workflow/types.ts +0 -62
- package/src/workflow/utils.ts +0 -53
- 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
|
+
});
|