@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
@@ -1,180 +0,0 @@
1
- import type { PostHogFileManager } from "./file-manager.js";
2
- import { Logger } from "./utils/logger.js";
3
-
4
- export interface TodoItem {
5
- content: string;
6
- status: "pending" | "in_progress" | "completed";
7
- activeForm: string;
8
- }
9
-
10
- export interface TodoList {
11
- items: TodoItem[];
12
- metadata: {
13
- total: number;
14
- pending: number;
15
- in_progress: number;
16
- completed: number;
17
- last_updated: string;
18
- };
19
- }
20
-
21
- export class TodoManager {
22
- private fileManager: PostHogFileManager;
23
- private logger: Logger;
24
-
25
- constructor(fileManager: PostHogFileManager, logger?: Logger) {
26
- this.fileManager = fileManager;
27
- this.logger =
28
- logger || new Logger({ debug: false, prefix: "[TodoManager]" });
29
- }
30
-
31
- async readTodos(taskId: string): Promise<TodoList | null> {
32
- try {
33
- const content = await this.fileManager.readTaskFile(taskId, "todos.json");
34
- if (!content) {
35
- return null;
36
- }
37
-
38
- const parsed = JSON.parse(content) as TodoList;
39
- this.logger.debug("Loaded todos", {
40
- taskId,
41
- total: parsed.metadata.total,
42
- pending: parsed.metadata.pending,
43
- in_progress: parsed.metadata.in_progress,
44
- completed: parsed.metadata.completed,
45
- });
46
-
47
- return parsed;
48
- } catch (error) {
49
- this.logger.debug("Failed to read todos.json", {
50
- taskId,
51
- error: error instanceof Error ? error.message : String(error),
52
- });
53
- return null;
54
- }
55
- }
56
-
57
- async writeTodos(taskId: string, todos: TodoList): Promise<void> {
58
- this.logger.debug("Writing todos", {
59
- taskId,
60
- total: todos.metadata.total,
61
- pending: todos.metadata.pending,
62
- in_progress: todos.metadata.in_progress,
63
- completed: todos.metadata.completed,
64
- });
65
-
66
- await this.fileManager.writeTaskFile(taskId, {
67
- name: "todos.json",
68
- content: JSON.stringify(todos, null, 2),
69
- type: "artifact",
70
- });
71
-
72
- this.logger.info("Todos saved", {
73
- taskId,
74
- total: todos.metadata.total,
75
- completed: todos.metadata.completed,
76
- });
77
- }
78
-
79
- parseTodoWriteInput(toolInput: Record<string, unknown>): TodoList {
80
- const items: TodoItem[] = [];
81
-
82
- if (toolInput.todos && Array.isArray(toolInput.todos)) {
83
- for (const todo of toolInput.todos) {
84
- items.push({
85
- content: todo.content || "",
86
- status: todo.status || "pending",
87
- activeForm: todo.activeForm || todo.content || "",
88
- });
89
- }
90
- }
91
-
92
- const metadata = this.calculateMetadata(items);
93
-
94
- return { items, metadata };
95
- }
96
-
97
- private calculateMetadata(items: TodoItem[]): TodoList["metadata"] {
98
- const total = items.length;
99
- const pending = items.filter((t) => t.status === "pending").length;
100
- const in_progress = items.filter((t) => t.status === "in_progress").length;
101
- const completed = items.filter((t) => t.status === "completed").length;
102
-
103
- return {
104
- total,
105
- pending,
106
- in_progress,
107
- completed,
108
- last_updated: new Date().toISOString(),
109
- };
110
- }
111
-
112
- async getTodoContext(taskId: string): Promise<string> {
113
- const todos = await this.readTodos(taskId);
114
- if (!todos || todos.items.length === 0) {
115
- return "";
116
- }
117
-
118
- const lines: string[] = ["## Previous Todo List\n"];
119
- lines.push("You previously created the following todo list:\n");
120
-
121
- for (const item of todos.items) {
122
- const statusIcon =
123
- item.status === "completed"
124
- ? "✓"
125
- : item.status === "in_progress"
126
- ? "▶"
127
- : "○";
128
- lines.push(`${statusIcon} [${item.status}] ${item.content}`);
129
- }
130
-
131
- lines.push(
132
- `\nProgress: ${todos.metadata.completed}/${todos.metadata.total} completed\n`,
133
- );
134
-
135
- return lines.join("\n");
136
- }
137
-
138
- // check for TodoWrite tool call and persist if found
139
- async checkAndPersistFromMessage(
140
- message: Record<string, unknown>,
141
- taskId: string,
142
- ): Promise<TodoList | null> {
143
- if (
144
- message.type !== "assistant" ||
145
- typeof message.message !== "object" ||
146
- !message.message ||
147
- !("content" in message.message) ||
148
- !Array.isArray(message.message.content)
149
- ) {
150
- return null;
151
- }
152
-
153
- for (const block of message.message.content) {
154
- if (block.type === "tool_use" && block.name === "TodoWrite") {
155
- try {
156
- this.logger.info("TodoWrite detected, persisting todos", { taskId });
157
-
158
- const todoList = this.parseTodoWriteInput(block.input);
159
- await this.writeTodos(taskId, todoList);
160
-
161
- this.logger.info("Persisted todos successfully", {
162
- taskId,
163
- total: todoList.metadata.total,
164
- completed: todoList.metadata.completed,
165
- });
166
-
167
- return todoList;
168
- } catch (error) {
169
- this.logger.error("Failed to persist todos", {
170
- taskId,
171
- error: error instanceof Error ? error.message : String(error),
172
- });
173
- return null;
174
- }
175
- }
176
- }
177
-
178
- return null;
179
- }
180
- }
@@ -1,134 +0,0 @@
1
- import type { Tool } from "./types.js";
2
-
3
- /**
4
- * Registry of all known tools with their metadata.
5
- * Maps tool names to their definitions.
6
- */
7
- const TOOL_DEFINITIONS: Record<string, Tool> = {
8
- // Filesystem tools
9
- Read: {
10
- name: "Read",
11
- category: "filesystem",
12
- description: "Read file contents from the filesystem",
13
- },
14
- Write: {
15
- name: "Write",
16
- category: "filesystem",
17
- description: "Write content to a file",
18
- },
19
- Edit: {
20
- name: "Edit",
21
- category: "filesystem",
22
- description: "Edit file with find and replace operations",
23
- },
24
- Glob: {
25
- name: "Glob",
26
- category: "filesystem",
27
- description: "Find files matching a pattern",
28
- },
29
- NotebookEdit: {
30
- name: "NotebookEdit",
31
- category: "filesystem",
32
- description: "Edit Jupyter notebook cells",
33
- },
34
-
35
- // Shell tools
36
- Bash: {
37
- name: "Bash",
38
- category: "shell",
39
- description: "Execute bash commands",
40
- },
41
- BashOutput: {
42
- name: "BashOutput",
43
- category: "shell",
44
- description: "Read output from a background bash process",
45
- },
46
- KillShell: {
47
- name: "KillShell",
48
- category: "shell",
49
- description: "Terminate a background bash process",
50
- },
51
-
52
- // Web tools
53
- WebFetch: {
54
- name: "WebFetch",
55
- category: "web",
56
- description: "Fetch content from a URL",
57
- },
58
- WebSearch: {
59
- name: "WebSearch",
60
- category: "web",
61
- description: "Search the web",
62
- },
63
-
64
- // Search tools
65
- Grep: {
66
- name: "Grep",
67
- category: "search",
68
- description: "Search file contents using patterns",
69
- },
70
-
71
- // Assistant tools
72
- Task: {
73
- name: "Task",
74
- category: "assistant",
75
- description: "Launch a specialized agent for a sub-task",
76
- },
77
- TodoWrite: {
78
- name: "TodoWrite",
79
- category: "assistant",
80
- description: "Manage task list and track progress",
81
- },
82
- ExitPlanMode: {
83
- name: "ExitPlanMode",
84
- category: "assistant",
85
- description: "Exit plan mode and present plan to user",
86
- },
87
- AskUserQuestion: {
88
- name: "AskUserQuestion",
89
- category: "assistant",
90
- description: "Ask the user a clarifying question with options",
91
- },
92
- SlashCommand: {
93
- name: "SlashCommand",
94
- category: "assistant",
95
- description: "Execute a slash command",
96
- },
97
- };
98
-
99
- /**
100
- * Tool registry for looking up tool definitions by name.
101
- * Provides metadata about tools for UI consumption.
102
- */
103
- export class ToolRegistry {
104
- /**
105
- * Get tool definition by name.
106
- * Returns undefined if tool is not recognized.
107
- */
108
- get(name: string): Tool | undefined {
109
- return TOOL_DEFINITIONS[name];
110
- }
111
-
112
- /**
113
- * Get all registered tools.
114
- */
115
- getAll(): Tool[] {
116
- return Object.values(TOOL_DEFINITIONS);
117
- }
118
-
119
- /**
120
- * Check if a tool name is registered.
121
- */
122
- has(name: string): boolean {
123
- return name in TOOL_DEFINITIONS;
124
- }
125
-
126
- /**
127
- * Get all tools in a specific category.
128
- */
129
- getByCategory(category: string): Tool[] {
130
- return Object.values(TOOL_DEFINITIONS).filter(
131
- (tool) => tool.category === category,
132
- );
133
- }
134
- }
@@ -1,133 +0,0 @@
1
- /**
2
- * Tool category classification for grouping related tools.
3
- * Makes it easier for UIs to filter and display tools by function.
4
- */
5
- export type ToolCategory =
6
- | "filesystem" // File operations: Read, Write, Edit, Glob, NotebookEdit
7
- | "shell" // Shell operations: Bash, BashOutput, KillShell
8
- | "web" // Web operations: WebFetch, WebSearch
9
- | "assistant" // Assistant operations: Task, TodoWrite, ExitPlanMode
10
- | "search" // Search operations: Grep
11
- | "unknown"; // Unknown or unrecognized tools
12
-
13
- /**
14
- * Base tool interface representing a tool that can be called by the agent.
15
- * Each tool has a name, category, and human-readable description.
16
- */
17
- export interface Tool {
18
- name: string;
19
- category: ToolCategory;
20
- description: string;
21
- }
22
-
23
- // Filesystem tools
24
-
25
- export interface ReadTool extends Tool {
26
- name: "Read";
27
- category: "filesystem";
28
- }
29
-
30
- export interface WriteTool extends Tool {
31
- name: "Write";
32
- category: "filesystem";
33
- }
34
-
35
- export interface EditTool extends Tool {
36
- name: "Edit";
37
- category: "filesystem";
38
- }
39
-
40
- export interface GlobTool extends Tool {
41
- name: "Glob";
42
- category: "filesystem";
43
- }
44
-
45
- export interface NotebookEditTool extends Tool {
46
- name: "NotebookEdit";
47
- category: "filesystem";
48
- }
49
-
50
- // Shell tools
51
-
52
- export interface BashTool extends Tool {
53
- name: "Bash";
54
- category: "shell";
55
- }
56
-
57
- export interface BashOutputTool extends Tool {
58
- name: "BashOutput";
59
- category: "shell";
60
- }
61
-
62
- export interface KillShellTool extends Tool {
63
- name: "KillShell";
64
- category: "shell";
65
- }
66
-
67
- // Web tools
68
-
69
- export interface WebFetchTool extends Tool {
70
- name: "WebFetch";
71
- category: "web";
72
- }
73
-
74
- export interface WebSearchTool extends Tool {
75
- name: "WebSearch";
76
- category: "web";
77
- }
78
-
79
- // Search tools
80
-
81
- export interface GrepTool extends Tool {
82
- name: "Grep";
83
- category: "search";
84
- }
85
-
86
- // Assistant tools
87
-
88
- export interface TaskTool extends Tool {
89
- name: "Task";
90
- category: "assistant";
91
- }
92
-
93
- export interface TodoWriteTool extends Tool {
94
- name: "TodoWrite";
95
- category: "assistant";
96
- }
97
-
98
- export interface ExitPlanModeTool extends Tool {
99
- name: "ExitPlanMode";
100
- category: "assistant";
101
- }
102
-
103
- export interface AskUserQuestionTool extends Tool {
104
- name: "AskUserQuestion";
105
- category: "assistant";
106
- }
107
-
108
- export interface SlashCommandTool extends Tool {
109
- name: "SlashCommand";
110
- category: "assistant";
111
- }
112
-
113
- /**
114
- * Union type of all known tool types.
115
- * Useful for discriminated unions and type narrowing.
116
- */
117
- export type KnownTool =
118
- | ReadTool
119
- | WriteTool
120
- | EditTool
121
- | GlobTool
122
- | NotebookEditTool
123
- | BashTool
124
- | BashOutputTool
125
- | KillShellTool
126
- | WebFetchTool
127
- | WebSearchTool
128
- | GrepTool
129
- | TaskTool
130
- | TodoWriteTool
131
- | ExitPlanModeTool
132
- | AskUserQuestionTool
133
- | SlashCommandTool;
@@ -1,60 +0,0 @@
1
- import type { Logger } from "./logger.js";
2
-
3
- type MessageCallback = (line: string) => void;
4
-
5
- export interface TappedStreamOptions {
6
- onMessage: MessageCallback;
7
- logger?: Logger;
8
- }
9
-
10
- /**
11
- * Creates a WritableStream wrapper that taps all newline-delimited messages,
12
- * forwarding each complete line for persistence.
13
- *
14
- * This aligns with ACP's transport model - all messages flow through
15
- * newline-delimited JSON-RPC streams, so we intercept at the transport layer
16
- * and persist everything.
17
- */
18
- export function createTappedWritableStream(
19
- underlying: WritableStream<Uint8Array>,
20
- options: TappedStreamOptions,
21
- ): WritableStream<Uint8Array> {
22
- const { onMessage, logger } = options;
23
- const decoder = new TextDecoder();
24
- let buffer = "";
25
- let _messageCount = 0;
26
-
27
- return new WritableStream({
28
- async write(chunk: Uint8Array) {
29
- // Decode and buffer
30
- buffer += decoder.decode(chunk, { stream: true });
31
-
32
- // Process complete lines (newline-delimited)
33
- const lines = buffer.split("\n");
34
- buffer = lines.pop() ?? "";
35
-
36
- for (const line of lines) {
37
- if (!line.trim()) continue;
38
- _messageCount++;
39
-
40
- onMessage(line);
41
- }
42
-
43
- // Forward to underlying stream
44
- const writer = underlying.getWriter();
45
- await writer.write(chunk);
46
- writer.releaseLock();
47
- },
48
- async close() {
49
- const writer = underlying.getWriter();
50
- await writer.close();
51
- writer.releaseLock();
52
- },
53
- async abort(reason: unknown) {
54
- logger?.warn("Tapped stream aborted", { reason });
55
- const writer = underlying.getWriter();
56
- await writer.abort(reason);
57
- writer.releaseLock();
58
- },
59
- });
60
- }