@posthog/agent 1.24.0 → 1.24.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 (116) hide show
  1. package/LICENSE +33 -0
  2. package/dist/index.d.ts +11 -11
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +3 -3
  5. package/dist/src/adapters/claude/claude-adapter.d.ts +3 -3
  6. package/dist/src/adapters/claude/claude-adapter.d.ts.map +1 -1
  7. package/dist/src/adapters/claude/claude-adapter.js +111 -156
  8. package/dist/src/adapters/claude/claude-adapter.js.map +1 -1
  9. package/dist/src/adapters/claude/tool-mapper.d.ts +1 -1
  10. package/dist/src/adapters/claude/tool-mapper.d.ts.map +1 -1
  11. package/dist/src/adapters/claude/tool-mapper.js.map +1 -1
  12. package/dist/src/adapters/types.d.ts +1 -1
  13. package/dist/src/adapters/types.d.ts.map +1 -1
  14. package/dist/src/agent.d.ts +7 -7
  15. package/dist/src/agent.d.ts.map +1 -1
  16. package/dist/src/agent.js +85 -143
  17. package/dist/src/agent.js.map +1 -1
  18. package/dist/src/agents/execution.js.map +1 -1
  19. package/dist/src/agents/planning.js.map +1 -1
  20. package/dist/src/agents/research.js.map +1 -1
  21. package/dist/src/file-manager.d.ts +4 -4
  22. package/dist/src/file-manager.d.ts.map +1 -1
  23. package/dist/src/file-manager.js +58 -59
  24. package/dist/src/file-manager.js.map +1 -1
  25. package/dist/src/git-manager.d.ts +1 -1
  26. package/dist/src/git-manager.d.ts.map +1 -1
  27. package/dist/src/git-manager.js +70 -87
  28. package/dist/src/git-manager.js.map +1 -1
  29. package/dist/src/posthog-api.d.ts +3 -2
  30. package/dist/src/posthog-api.d.ts.map +1 -1
  31. package/dist/src/posthog-api.js +22 -22
  32. package/dist/src/posthog-api.js.map +1 -1
  33. package/dist/src/prompt-builder.d.ts +3 -3
  34. package/dist/src/prompt-builder.d.ts.map +1 -1
  35. package/dist/src/prompt-builder.js +93 -123
  36. package/dist/src/prompt-builder.js.map +1 -1
  37. package/dist/src/task-manager.d.ts +4 -4
  38. package/dist/src/task-manager.d.ts.map +1 -1
  39. package/dist/src/task-manager.js +18 -19
  40. package/dist/src/task-manager.js.map +1 -1
  41. package/dist/src/task-progress-reporter.d.ts +4 -3
  42. package/dist/src/task-progress-reporter.d.ts.map +1 -1
  43. package/dist/src/task-progress-reporter.js +54 -59
  44. package/dist/src/task-progress-reporter.js.map +1 -1
  45. package/dist/src/template-manager.d.ts +1 -1
  46. package/dist/src/template-manager.d.ts.map +1 -1
  47. package/dist/src/template-manager.js +28 -30
  48. package/dist/src/template-manager.js.map +1 -1
  49. package/dist/src/todo-manager.d.ts +3 -3
  50. package/dist/src/todo-manager.d.ts.map +1 -1
  51. package/dist/src/todo-manager.js +24 -29
  52. package/dist/src/todo-manager.js.map +1 -1
  53. package/dist/src/tools/registry.d.ts +1 -1
  54. package/dist/src/tools/registry.js +60 -60
  55. package/dist/src/tools/registry.js.map +1 -1
  56. package/dist/src/tools/types.d.ts +31 -31
  57. package/dist/src/types.d.ts +33 -33
  58. package/dist/src/types.d.ts.map +1 -1
  59. package/dist/src/types.js.map +1 -1
  60. package/dist/src/utils/logger.d.ts +4 -4
  61. package/dist/src/utils/logger.d.ts.map +1 -1
  62. package/dist/src/utils/logger.js +8 -8
  63. package/dist/src/utils/logger.js.map +1 -1
  64. package/dist/src/workflow/config.d.ts +1 -1
  65. package/dist/src/workflow/config.d.ts.map +1 -1
  66. package/dist/src/workflow/config.js +18 -18
  67. package/dist/src/workflow/config.js.map +1 -1
  68. package/dist/src/workflow/steps/build.d.ts +1 -1
  69. package/dist/src/workflow/steps/build.d.ts.map +1 -1
  70. package/dist/src/workflow/steps/build.js +38 -46
  71. package/dist/src/workflow/steps/build.js.map +1 -1
  72. package/dist/src/workflow/steps/finalize.d.ts +1 -1
  73. package/dist/src/workflow/steps/finalize.d.ts.map +1 -1
  74. package/dist/src/workflow/steps/finalize.js +48 -54
  75. package/dist/src/workflow/steps/finalize.js.map +1 -1
  76. package/dist/src/workflow/steps/plan.d.ts +1 -1
  77. package/dist/src/workflow/steps/plan.d.ts.map +1 -1
  78. package/dist/src/workflow/steps/plan.js +46 -58
  79. package/dist/src/workflow/steps/plan.js.map +1 -1
  80. package/dist/src/workflow/steps/research.d.ts +1 -1
  81. package/dist/src/workflow/steps/research.d.ts.map +1 -1
  82. package/dist/src/workflow/steps/research.js +56 -68
  83. package/dist/src/workflow/steps/research.js.map +1 -1
  84. package/dist/src/workflow/types.d.ts +12 -12
  85. package/dist/src/workflow/types.d.ts.map +1 -1
  86. package/dist/src/workflow/utils.d.ts +1 -1
  87. package/dist/src/workflow/utils.d.ts.map +1 -1
  88. package/dist/src/workflow/utils.js +4 -7
  89. package/dist/src/workflow/utils.js.map +1 -1
  90. package/package.json +6 -6
  91. package/src/adapters/claude/claude-adapter.ts +168 -220
  92. package/src/adapters/claude/tool-mapper.ts +2 -2
  93. package/src/adapters/types.ts +1 -1
  94. package/src/agent.ts +444 -579
  95. package/src/agents/execution.ts +1 -1
  96. package/src/agents/planning.ts +1 -1
  97. package/src/agents/research.ts +1 -0
  98. package/src/file-manager.ts +63 -64
  99. package/src/git-manager.ts +88 -144
  100. package/src/posthog-api.ts +82 -122
  101. package/src/prompt-builder.ts +135 -180
  102. package/src/task-manager.ts +30 -38
  103. package/src/task-progress-reporter.ts +59 -70
  104. package/src/template-manager.ts +45 -98
  105. package/src/todo-manager.ts +30 -35
  106. package/src/tools/registry.ts +62 -62
  107. package/src/tools/types.ts +36 -36
  108. package/src/types.ts +71 -93
  109. package/src/utils/logger.ts +56 -62
  110. package/src/workflow/config.ts +48 -48
  111. package/src/workflow/steps/build.ts +113 -122
  112. package/src/workflow/steps/finalize.ts +182 -214
  113. package/src/workflow/steps/plan.ts +131 -151
  114. package/src/workflow/steps/research.ts +186 -205
  115. package/src/workflow/types.ts +36 -38
  116. package/src/workflow/utils.ts +34 -37
package/src/agent.ts CHANGED
@@ -1,403 +1,322 @@
1
1
  import { query } from "@anthropic-ai/claude-agent-sdk";
2
- import { ClaudeAdapter } from "./adapters/claude/claude-adapter.js";
3
- import type { ProviderAdapter } from "./adapters/types.js";
4
- import { PostHogFileManager } from "./file-manager.js";
5
- import { GitManager } from "./git-manager.js";
6
- import { PostHogAPIClient } from "./posthog-api.js";
7
- import { PromptBuilder } from "./prompt-builder.js";
8
- import { TaskManager } from "./task-manager.js";
9
- import { TaskProgressReporter } from "./task-progress-reporter.js";
10
- import { TemplateManager } from "./template-manager.js";
11
- import type {
12
- AgentConfig,
13
- CanUseTool,
14
- ExecutionResult,
15
- Task,
16
- } from "./types.js";
17
- import { Logger } from "./utils/logger.js";
18
- import { TASK_WORKFLOW } from "./workflow/config.js";
19
- import type { WorkflowRuntime } from "./workflow/types.js";
2
+ import type { Task, ExecutionResult, AgentConfig, CanUseTool } from './types.js';
3
+ import { TaskManager } from './task-manager.js';
4
+ import { PostHogAPIClient } from './posthog-api.js';
5
+ import { PostHogFileManager } from './file-manager.js';
6
+ import { GitManager } from './git-manager.js';
7
+ import { TemplateManager } from './template-manager.js';
8
+ import { ClaudeAdapter } from './adapters/claude/claude-adapter.js';
9
+ import type { ProviderAdapter } from './adapters/types.js';
10
+ import { Logger } from './utils/logger.js';
11
+ import { PromptBuilder } from './prompt-builder.js';
12
+ import { TaskProgressReporter } from './task-progress-reporter.js';
13
+ import { TASK_WORKFLOW } from './workflow/config.js';
14
+ import type { WorkflowRuntime } from './workflow/types.js';
20
15
 
21
16
  export class Agent {
22
- private workingDirectory: string;
23
- private onEvent?: (event: any) => void;
24
- private taskManager: TaskManager;
25
- private posthogAPI?: PostHogAPIClient;
26
- private fileManager: PostHogFileManager;
27
- private gitManager: GitManager;
28
- private templateManager: TemplateManager;
29
- private adapter: ProviderAdapter;
30
- private logger: Logger;
31
- private progressReporter: TaskProgressReporter;
32
- private promptBuilder: PromptBuilder;
33
- private mcpServers?: Record<string, any>;
34
- private canUseTool?: CanUseTool;
35
- public debug: boolean;
36
-
37
- constructor(config: AgentConfig) {
38
- this.workingDirectory = config.workingDirectory || process.cwd();
39
- this.onEvent = config.onEvent;
40
- this.canUseTool = config.canUseTool;
41
- this.debug = config.debug || false;
42
-
43
- // Build default PostHog MCP server configuration
44
- const posthogMcpUrl =
45
- config.posthogMcpUrl ||
46
- process.env.POSTHOG_MCP_URL ||
47
- "https://mcp.posthog.com/mcp";
48
-
49
- // Add auth if API key provided
50
- const headers: Record<string, string> = {};
51
- if (config.posthogApiKey) {
52
- headers.Authorization = `Bearer ${config.posthogApiKey}`;
53
- }
17
+ private workingDirectory: string;
18
+ private onEvent?: (event: any) => void;
19
+ private taskManager: TaskManager;
20
+ private posthogAPI?: PostHogAPIClient;
21
+ private fileManager: PostHogFileManager;
22
+ private gitManager: GitManager;
23
+ private templateManager: TemplateManager;
24
+ private adapter: ProviderAdapter;
25
+ private logger: Logger;
26
+ private progressReporter: TaskProgressReporter;
27
+ private promptBuilder: PromptBuilder;
28
+ private mcpServers?: Record<string, any>;
29
+ private canUseTool?: CanUseTool;
30
+ public debug: boolean;
31
+
32
+ constructor(config: AgentConfig) {
33
+ this.workingDirectory = config.workingDirectory || process.cwd();
34
+ this.onEvent = config.onEvent;
35
+ this.canUseTool = config.canUseTool;
36
+ this.debug = config.debug || false;
37
+
38
+ // Build default PostHog MCP server configuration
39
+ const posthogMcpUrl = config.posthogMcpUrl
40
+ || process.env.POSTHOG_MCP_URL
41
+ || 'https://mcp.posthog.com/mcp';
42
+
43
+ // Add auth if API key provided
44
+ const headers: Record<string, string> = {};
45
+ if (config.posthogApiKey) {
46
+ headers['Authorization'] = `Bearer ${config.posthogApiKey}`;
47
+ }
48
+
49
+ const defaultMcpServers = {
50
+ posthog: {
51
+ type: 'http' as const,
52
+ url: posthogMcpUrl,
53
+ ...(Object.keys(headers).length > 0 ? { headers } : {}),
54
+ }
55
+ };
56
+
57
+ // Merge default PostHog MCP with user-provided servers (user config takes precedence)
58
+ this.mcpServers = {
59
+ ...defaultMcpServers,
60
+ ...config.mcpServers
61
+ };
62
+ this.logger = new Logger({ debug: this.debug, prefix: '[PostHog Agent]' });
63
+ this.taskManager = new TaskManager();
64
+ // Hardcode Claude adapter for now - extensible for other providers later
65
+ this.adapter = new ClaudeAdapter();
66
+
67
+ this.fileManager = new PostHogFileManager(
68
+ this.workingDirectory,
69
+ this.logger.child('FileManager')
70
+ );
71
+ this.gitManager = new GitManager({
72
+ repositoryPath: this.workingDirectory,
73
+ logger: this.logger.child('GitManager')
74
+ // TODO: Add author config from environment or config
75
+ });
76
+ this.templateManager = new TemplateManager();
77
+
78
+ if (config.posthogApiUrl && config.posthogApiKey) {
79
+ this.posthogAPI = new PostHogAPIClient({
80
+ apiUrl: config.posthogApiUrl,
81
+ apiKey: config.posthogApiKey,
82
+ projectId: config.posthogProjectId,
83
+ });
84
+ }
54
85
 
55
- const defaultMcpServers = {
56
- posthog: {
57
- type: "http" as const,
58
- url: posthogMcpUrl,
59
- ...(Object.keys(headers).length > 0 ? { headers } : {}),
60
- },
61
- };
62
-
63
- // Merge default PostHog MCP with user-provided servers (user config takes precedence)
64
- this.mcpServers = {
65
- ...defaultMcpServers,
66
- ...config.mcpServers,
67
- };
68
- this.logger = new Logger({ debug: this.debug, prefix: "[PostHog Agent]" });
69
- this.taskManager = new TaskManager();
70
- // Hardcode Claude adapter for now - extensible for other providers later
71
- this.adapter = new ClaudeAdapter();
72
-
73
- this.fileManager = new PostHogFileManager(
74
- this.workingDirectory,
75
- this.logger.child("FileManager"),
76
- );
77
- this.gitManager = new GitManager({
78
- repositoryPath: this.workingDirectory,
79
- logger: this.logger.child("GitManager"),
80
- // TODO: Add author config from environment or config
81
- });
82
- this.templateManager = new TemplateManager();
83
-
84
- if (config.posthogApiUrl && config.posthogApiKey) {
85
- this.posthogAPI = new PostHogAPIClient({
86
- apiUrl: config.posthogApiUrl,
87
- apiKey: config.posthogApiKey,
88
- projectId: config.posthogProjectId,
89
- });
86
+ this.promptBuilder = new PromptBuilder({
87
+ getTaskFiles: (taskId: string) => this.getTaskFiles(taskId),
88
+ generatePlanTemplate: (vars) => this.templateManager.generatePlan(vars),
89
+ posthogClient: this.posthogAPI,
90
+ logger: this.logger.child('PromptBuilder')
91
+ });
92
+ this.progressReporter = new TaskProgressReporter(this.posthogAPI, this.logger);
90
93
  }
91
94
 
92
- this.promptBuilder = new PromptBuilder({
93
- getTaskFiles: (taskId: string) => this.getTaskFiles(taskId),
94
- generatePlanTemplate: (vars) => this.templateManager.generatePlan(vars),
95
- posthogClient: this.posthogAPI,
96
- logger: this.logger.child("PromptBuilder"),
97
- });
98
- this.progressReporter = new TaskProgressReporter(
99
- this.posthogAPI,
100
- this.logger,
101
- );
102
- }
103
-
104
- /**
105
- * Enable or disable debug logging
106
- */
107
- setDebug(enabled: boolean) {
108
- this.debug = enabled;
109
- this.logger.setDebug(enabled);
110
- }
111
-
112
- /**
113
- * Configure LLM gateway environment variables for Claude Code CLI
114
- */
115
- private async _configureLlmGateway(): Promise<void> {
116
- if (!this.posthogAPI) {
117
- return;
95
+ /**
96
+ * Enable or disable debug logging
97
+ */
98
+ setDebug(enabled: boolean) {
99
+ this.debug = enabled;
100
+ this.logger.setDebug(enabled);
118
101
  }
119
102
 
120
- try {
121
- const gatewayUrl = this.posthogAPI.getLlmGatewayUrl();
122
- const apiKey = this.posthogAPI.getApiKey();
103
+ /**
104
+ * Configure LLM gateway environment variables for Claude Code CLI
105
+ */
106
+ private async _configureLlmGateway(): Promise<void> {
107
+ if (!this.posthogAPI) {
108
+ return;
109
+ }
110
+
111
+ try {
112
+ const gatewayUrl = this.posthogAPI.getLlmGatewayUrl();
113
+ const apiKey = this.posthogAPI.getApiKey();
123
114
 
124
- process.env.ANTHROPIC_BASE_URL = gatewayUrl;
125
- process.env.ANTHROPIC_AUTH_TOKEN = apiKey;
126
- this.ensureOpenAIGatewayEnv(gatewayUrl, apiKey);
115
+ process.env.ANTHROPIC_BASE_URL = gatewayUrl;
116
+ process.env.ANTHROPIC_AUTH_TOKEN = apiKey;
117
+ this.ensureOpenAIGatewayEnv(gatewayUrl, apiKey);
127
118
 
128
- this.logger.debug("Configured LLM gateway", { gatewayUrl });
129
- } catch (error) {
130
- this.logger.error("Failed to configure LLM gateway", error);
131
- throw error;
119
+ this.logger.debug('Configured LLM gateway', { gatewayUrl });
120
+ } catch (error) {
121
+ this.logger.error('Failed to configure LLM gateway', error);
122
+ throw error;
123
+ }
124
+ }
125
+
126
+ // Adaptive task execution orchestrated via workflow steps
127
+ async runTask(taskOrId: Task | string, options: import('./types.js').TaskExecutionOptions = {}): Promise<void> {
128
+ await this._configureLlmGateway();
129
+
130
+ const task = typeof taskOrId === 'string' ? await this.fetchTask(taskOrId) : taskOrId;
131
+ const cwd = options.repositoryPath || this.workingDirectory;
132
+ const isCloudMode = options.isCloudMode ?? false;
133
+ const taskSlug = (task as any).slug || task.id;
134
+
135
+ this.logger.info('Starting adaptive task execution', { taskId: task.id, taskSlug, isCloudMode });
136
+
137
+ // Initialize progress reporter for task run tracking (needed for PR attachment)
138
+ await this.progressReporter.start(task.id, { totalSteps: TASK_WORKFLOW.length });
139
+ this.emitEvent(this.adapter.createStatusEvent('run_started', { runId: this.progressReporter.runId }));
140
+
141
+ await this.prepareTaskBranch(taskSlug, isCloudMode);
142
+
143
+ let taskError: Error | undefined;
144
+ try {
145
+ const workflowContext: WorkflowRuntime = {
146
+ task,
147
+ taskSlug,
148
+ cwd,
149
+ isCloudMode,
150
+ options,
151
+ logger: this.logger,
152
+ fileManager: this.fileManager,
153
+ gitManager: this.gitManager,
154
+ promptBuilder: this.promptBuilder,
155
+ progressReporter: this.progressReporter,
156
+ adapter: this.adapter,
157
+ mcpServers: this.mcpServers,
158
+ posthogAPI: this.posthogAPI,
159
+ emitEvent: (event: any) => this.emitEvent(event),
160
+ stepResults: {},
161
+ };
162
+
163
+ for (const step of TASK_WORKFLOW) {
164
+ const result = await step.run({ step, context: workflowContext });
165
+ if (result.halt) {
166
+ return;
167
+ }
168
+ }
169
+
170
+ const shouldCreatePR = options.createPR ?? isCloudMode;
171
+ if (shouldCreatePR) {
172
+ await this.ensurePullRequest(task, workflowContext.stepResults);
173
+ }
174
+
175
+ this.logger.info('Task execution complete', { taskId: task.id });
176
+ this.emitEvent(this.adapter.createStatusEvent('task_complete', { taskId: task.id }));
177
+ } catch (error) {
178
+ taskError = error instanceof Error ? error : new Error(String(error));
179
+ this.logger.error('Task execution failed', { taskId: task.id, error: taskError.message });
180
+ } finally {
181
+ if (taskError) {
182
+ await this.progressReporter.fail(taskError);
183
+ throw taskError;
184
+ } else {
185
+ await this.progressReporter.complete();
186
+ }
187
+ }
132
188
  }
133
- }
134
-
135
- // Adaptive task execution orchestrated via workflow steps
136
- async runTask(
137
- taskOrId: Task | string,
138
- options: import("./types.js").TaskExecutionOptions = {},
139
- ): Promise<void> {
140
- await this._configureLlmGateway();
141
-
142
- const task =
143
- typeof taskOrId === "string" ? await this.fetchTask(taskOrId) : taskOrId;
144
- const cwd = options.repositoryPath || this.workingDirectory;
145
- const isCloudMode = options.isCloudMode ?? false;
146
- const taskSlug = (task as any).slug || task.id;
147
-
148
- this.logger.info("Starting adaptive task execution", {
149
- taskId: task.id,
150
- taskSlug,
151
- isCloudMode,
152
- });
153
-
154
- // Initialize progress reporter for task run tracking (needed for PR attachment)
155
- await this.progressReporter.start(task.id, {
156
- totalSteps: TASK_WORKFLOW.length,
157
- });
158
- this.emitEvent(
159
- this.adapter.createStatusEvent("run_started", {
160
- runId: this.progressReporter.runId,
161
- }),
162
- );
163
-
164
- await this.prepareTaskBranch(taskSlug, isCloudMode);
165
-
166
- let taskError: Error | undefined;
167
- try {
168
- const workflowContext: WorkflowRuntime = {
169
- task,
170
- taskSlug,
171
- cwd,
172
- isCloudMode,
173
- options,
174
- logger: this.logger,
175
- fileManager: this.fileManager,
176
- gitManager: this.gitManager,
177
- promptBuilder: this.promptBuilder,
178
- progressReporter: this.progressReporter,
179
- adapter: this.adapter,
180
- mcpServers: this.mcpServers,
181
- posthogAPI: this.posthogAPI,
182
- emitEvent: (event: any) => this.emitEvent(event),
183
- stepResults: {},
184
- };
185
-
186
- for (const step of TASK_WORKFLOW) {
187
- const result = await step.run({ step, context: workflowContext });
188
- if (result.halt) {
189
- return;
189
+
190
+ // Direct prompt execution - still supported for low-level usage
191
+ async run(prompt: string, options: { repositoryPath?: string; permissionMode?: import('./types.js').PermissionMode; queryOverrides?: Record<string, any>; canUseTool?: CanUseTool } = {}): Promise<ExecutionResult> {
192
+ await this._configureLlmGateway();
193
+ const baseOptions: Record<string, any> = {
194
+ model: "claude-sonnet-4-5-20250929",
195
+ cwd: options.repositoryPath || this.workingDirectory,
196
+ permissionMode: (options.permissionMode as any) || "default",
197
+ settingSources: ["local"],
198
+ mcpServers: this.mcpServers,
199
+ };
200
+
201
+ // Add canUseTool hook if provided (options take precedence over instance config)
202
+ const canUseTool = options.canUseTool || this.canUseTool;
203
+ if (canUseTool) {
204
+ baseOptions.canUseTool = canUseTool;
205
+ }
206
+
207
+ const response = query({
208
+ prompt,
209
+ options: { ...baseOptions, ...(options.queryOverrides || {}) },
210
+ });
211
+
212
+ const results = [];
213
+ for await (const message of response) {
214
+ this.logger.debug('Received message in direct run', message);
215
+ // Emit raw SDK event
216
+ this.emitEvent(this.adapter.createRawSDKEvent(message));
217
+ const transformedEvents = this.adapter.transform(message);
218
+ for (const event of transformedEvents) {
219
+ this.emitEvent(event);
220
+ }
221
+ results.push(message);
190
222
  }
191
- }
192
-
193
- const shouldCreatePR = options.createPR ?? isCloudMode;
194
- if (shouldCreatePR) {
195
- await this.ensurePullRequest(task, workflowContext.stepResults);
196
- }
197
-
198
- this.logger.info("Task execution complete", { taskId: task.id });
199
- this.emitEvent(
200
- this.adapter.createStatusEvent("task_complete", { taskId: task.id }),
201
- );
202
- } catch (error) {
203
- taskError = error instanceof Error ? error : new Error(String(error));
204
- this.logger.error("Task execution failed", {
205
- taskId: task.id,
206
- error: taskError.message,
207
- });
208
- } finally {
209
- if (taskError) {
210
- await this.progressReporter.fail(taskError);
211
- // biome-ignore lint/correctness/noUnsafeFinally: we actually want to throw the error
212
- throw taskError;
213
- } else {
214
- await this.progressReporter.complete();
215
- }
223
+
224
+ return { results };
216
225
  }
217
- }
218
-
219
- // Direct prompt execution - still supported for low-level usage
220
- async run(
221
- prompt: string,
222
- options: {
223
- repositoryPath?: string;
224
- permissionMode?: import("./types.js").PermissionMode;
225
- queryOverrides?: Record<string, any>;
226
- canUseTool?: CanUseTool;
227
- } = {},
228
- ): Promise<ExecutionResult> {
229
- await this._configureLlmGateway();
230
- const baseOptions: Record<string, any> = {
231
- model: "claude-sonnet-4-5-20250929",
232
- cwd: options.repositoryPath || this.workingDirectory,
233
- permissionMode: (options.permissionMode as any) || "default",
234
- settingSources: ["local"],
235
- mcpServers: this.mcpServers,
236
- };
237
-
238
- // Add canUseTool hook if provided (options take precedence over instance config)
239
- const canUseTool = options.canUseTool || this.canUseTool;
240
- if (canUseTool) {
241
- baseOptions.canUseTool = canUseTool;
226
+
227
+ // PostHog task operations
228
+ async fetchTask(taskId: string): Promise<Task> {
229
+ this.logger.debug('Fetching task from PostHog', { taskId });
230
+ if (!this.posthogAPI) {
231
+ const error = new Error('PostHog API not configured. Provide posthogApiUrl and posthogApiKey in constructor.');
232
+ this.logger.error('PostHog API not configured', error);
233
+ throw error;
234
+ }
235
+ return this.posthogAPI.fetchTask(taskId);
242
236
  }
243
237
 
244
- const response = query({
245
- prompt,
246
- options: { ...baseOptions, ...(options.queryOverrides || {}) },
247
- });
248
-
249
- const results = [];
250
- try {
251
- for await (const message of response) {
252
- this.logger.debug("Received message in direct run", message);
253
- // Emit raw SDK event
254
- this.emitEvent(this.adapter.createRawSDKEvent(message));
255
- const transformedEvents = this.adapter.transform(message);
256
- for (const event of transformedEvents) {
257
- this.emitEvent(event);
238
+ getPostHogClient(): PostHogAPIClient | undefined {
239
+ return this.posthogAPI;
240
+ }
241
+
242
+ async listTasks(filters?: {
243
+ repository?: string;
244
+ organization?: string;
245
+ origin_product?: string;
246
+ }): Promise<Task[]> {
247
+ if (!this.posthogAPI) {
248
+ throw new Error('PostHog API not configured. Provide posthogApiUrl and posthogApiKey in constructor.');
258
249
  }
259
- results.push(message);
260
- }
261
- } catch (error) {
262
- this.logger.error("Error during direct run", error);
263
- throw error;
250
+ return this.posthogAPI.listTasks(filters);
251
+ }
252
+
253
+ // File system operations for task artifacts
254
+ async writeTaskFile(taskId: string, fileName: string, content: string, type: 'plan' | 'context' | 'reference' | 'output' = 'reference'): Promise<void> {
255
+ this.logger.debug('Writing task file', { taskId, fileName, type, contentLength: content.length });
256
+ await this.fileManager.writeTaskFile(taskId, { name: fileName, content, type });
257
+ }
258
+
259
+ async readTaskFile(taskId: string, fileName: string): Promise<string | null> {
260
+ this.logger.debug('Reading task file', { taskId, fileName });
261
+ return await this.fileManager.readTaskFile(taskId, fileName);
262
+ }
263
+
264
+ async getTaskFiles(taskId: string): Promise<any[]> {
265
+ this.logger.debug('Getting task files', { taskId });
266
+ const files = await this.fileManager.getTaskFiles(taskId);
267
+ this.logger.debug('Found task files', { taskId, fileCount: files.length });
268
+ return files;
269
+ }
270
+
271
+ async writePlan(taskId: string, plan: string): Promise<void> {
272
+ this.logger.info('Writing plan', { taskId, planLength: plan.length });
273
+ await this.fileManager.writePlan(taskId, plan);
274
+ }
275
+
276
+ async readPlan(taskId: string): Promise<string | null> {
277
+ this.logger.debug('Reading plan', { taskId });
278
+ return await this.fileManager.readPlan(taskId);
264
279
  }
265
280
 
266
- return { results };
267
- }
268
-
269
- // PostHog task operations
270
- async fetchTask(taskId: string): Promise<Task> {
271
- this.logger.debug("Fetching task from PostHog", { taskId });
272
- if (!this.posthogAPI) {
273
- const error = new Error(
274
- "PostHog API not configured. Provide posthogApiUrl and posthogApiKey in constructor.",
275
- );
276
- this.logger.error("PostHog API not configured", error);
277
- throw error;
281
+ // Git operations for task execution
282
+ async createPlanningBranch(taskId: string): Promise<string> {
283
+ this.logger.info('Creating planning branch', { taskId });
284
+ const branchName = await this.gitManager.createTaskPlanningBranch(taskId);
285
+ this.logger.debug('Planning branch created', { taskId, branchName });
286
+ return branchName;
287
+ }
288
+
289
+ async commitPlan(taskId: string, taskTitle: string): Promise<string> {
290
+ this.logger.info('Committing plan', { taskId, taskTitle });
291
+ const commitHash = await this.gitManager.commitPlan(taskId, taskTitle);
292
+ this.logger.debug('Plan committed', { taskId, commitHash });
293
+ return commitHash;
278
294
  }
279
- return this.posthogAPI.fetchTask(taskId);
280
- }
281
-
282
- getPostHogClient(): PostHogAPIClient | undefined {
283
- return this.posthogAPI;
284
- }
285
-
286
- async listTasks(filters?: {
287
- repository?: string;
288
- organization?: string;
289
- origin_product?: string;
290
- }): Promise<Task[]> {
291
- if (!this.posthogAPI) {
292
- throw new Error(
293
- "PostHog API not configured. Provide posthogApiUrl and posthogApiKey in constructor.",
294
- );
295
+
296
+ async createImplementationBranch(taskId: string, planningBranchName?: string): Promise<string> {
297
+ this.logger.info('Creating implementation branch', { taskId, fromBranch: planningBranchName });
298
+ const branchName = await this.gitManager.createTaskImplementationBranch(taskId, planningBranchName);
299
+ this.logger.debug('Implementation branch created', { taskId, branchName });
300
+ return branchName;
295
301
  }
296
- return this.posthogAPI.listTasks(filters);
297
- }
298
-
299
- // File system operations for task artifacts
300
- async writeTaskFile(
301
- taskId: string,
302
- fileName: string,
303
- content: string,
304
- type: "plan" | "context" | "reference" | "output" = "reference",
305
- ): Promise<void> {
306
- this.logger.debug("Writing task file", {
307
- taskId,
308
- fileName,
309
- type,
310
- contentLength: content.length,
311
- });
312
- await this.fileManager.writeTaskFile(taskId, {
313
- name: fileName,
314
- content,
315
- type,
316
- });
317
- }
318
-
319
- async readTaskFile(taskId: string, fileName: string): Promise<string | null> {
320
- this.logger.debug("Reading task file", { taskId, fileName });
321
- return await this.fileManager.readTaskFile(taskId, fileName);
322
- }
323
-
324
- async getTaskFiles(taskId: string): Promise<any[]> {
325
- this.logger.debug("Getting task files", { taskId });
326
- const files = await this.fileManager.getTaskFiles(taskId);
327
- this.logger.debug("Found task files", { taskId, fileCount: files.length });
328
- return files;
329
- }
330
-
331
- async writePlan(taskId: string, plan: string): Promise<void> {
332
- this.logger.info("Writing plan", { taskId, planLength: plan.length });
333
- await this.fileManager.writePlan(taskId, plan);
334
- }
335
-
336
- async readPlan(taskId: string): Promise<string | null> {
337
- this.logger.debug("Reading plan", { taskId });
338
- return await this.fileManager.readPlan(taskId);
339
- }
340
-
341
- // Git operations for task execution
342
- async createPlanningBranch(taskId: string): Promise<string> {
343
- this.logger.info("Creating planning branch", { taskId });
344
- const branchName = await this.gitManager.createTaskPlanningBranch(taskId);
345
- this.logger.debug("Planning branch created", { taskId, branchName });
346
- return branchName;
347
- }
348
-
349
- async commitPlan(taskId: string, taskTitle: string): Promise<string> {
350
- this.logger.info("Committing plan", { taskId, taskTitle });
351
- const commitHash = await this.gitManager.commitPlan(taskId, taskTitle);
352
- this.logger.debug("Plan committed", { taskId, commitHash });
353
- return commitHash;
354
- }
355
-
356
- async createImplementationBranch(
357
- taskId: string,
358
- planningBranchName?: string,
359
- ): Promise<string> {
360
- this.logger.info("Creating implementation branch", {
361
- taskId,
362
- fromBranch: planningBranchName,
363
- });
364
- const branchName = await this.gitManager.createTaskImplementationBranch(
365
- taskId,
366
- planningBranchName,
367
- );
368
- this.logger.debug("Implementation branch created", { taskId, branchName });
369
- return branchName;
370
- }
371
-
372
- async commitImplementation(
373
- taskId: string,
374
- taskTitle: string,
375
- planSummary?: string,
376
- ): Promise<string> {
377
- this.logger.info("Committing implementation", { taskId, taskTitle });
378
- const commitHash = await this.gitManager.commitImplementation(
379
- taskId,
380
- taskTitle,
381
- planSummary,
382
- );
383
- this.logger.debug("Implementation committed", { taskId, commitHash });
384
- return commitHash;
385
- }
386
-
387
- async createPullRequest(
388
- taskId: string,
389
- branchName: string,
390
- taskTitle: string,
391
- taskDescription: string,
392
- customBody?: string,
393
- ): Promise<string> {
394
- this.logger.info("Creating pull request", {
395
- taskId,
396
- branchName,
397
- taskTitle,
398
- });
399
-
400
- const defaultBody = `## Task Details
302
+
303
+ async commitImplementation(taskId: string, taskTitle: string, planSummary?: string): Promise<string> {
304
+ this.logger.info('Committing implementation', { taskId, taskTitle });
305
+ const commitHash = await this.gitManager.commitImplementation(taskId, taskTitle, planSummary);
306
+ this.logger.debug('Implementation committed', { taskId, commitHash });
307
+ return commitHash;
308
+ }
309
+
310
+ async createPullRequest(
311
+ taskId: string,
312
+ branchName: string,
313
+ taskTitle: string,
314
+ taskDescription: string,
315
+ customBody?: string
316
+ ): Promise<string> {
317
+ this.logger.info('Creating pull request', { taskId, branchName, taskTitle });
318
+
319
+ const defaultBody = `## Task Details
401
320
  **Task ID**: ${taskId}
402
321
  **Description**: ${taskDescription}
403
322
 
@@ -405,225 +324,171 @@ export class Agent {
405
324
  This PR implements the changes described in the task.
406
325
 
407
326
  Generated by PostHog Agent`;
408
- const prBody = customBody || defaultBody;
409
-
410
- const prUrl = await this.gitManager.createPullRequest(
411
- branchName,
412
- taskTitle,
413
- prBody,
414
- );
415
-
416
- this.logger.info("Pull request created", { taskId, prUrl });
417
- return prUrl;
418
- }
419
-
420
- async attachPullRequestToTask(
421
- taskId: string,
422
- prUrl: string,
423
- branchName?: string,
424
- ): Promise<void> {
425
- this.logger.info("Attaching PR to task run", { taskId, prUrl, branchName });
426
-
427
- if (!this.posthogAPI || !this.progressReporter.runId) {
428
- const error = new Error(
429
- "PostHog API not configured or no active run. Cannot attach PR to task.",
430
- );
431
- this.logger.error("PostHog API not configured", error);
432
- throw error;
433
- }
327
+ const prBody = customBody || defaultBody;
434
328
 
435
- const updates: any = {
436
- output: { pr_url: prUrl },
437
- };
438
- if (branchName) {
439
- updates.branch = branchName;
440
- }
329
+ const prUrl = await this.gitManager.createPullRequest(
330
+ branchName,
331
+ taskTitle,
332
+ prBody
333
+ );
441
334
 
442
- await this.posthogAPI.updateTaskRun(
443
- taskId,
444
- this.progressReporter.runId,
445
- updates,
446
- );
447
- this.logger.debug("PR attached to task run", {
448
- taskId,
449
- runId: this.progressReporter.runId,
450
- prUrl,
451
- });
452
- }
453
-
454
- async updateTaskBranch(taskId: string, branchName: string): Promise<void> {
455
- this.logger.info("Updating task run branch", { taskId, branchName });
456
-
457
- if (!this.posthogAPI || !this.progressReporter.runId) {
458
- const error = new Error(
459
- "PostHog API not configured or no active run. Cannot update branch.",
460
- );
461
- this.logger.error("PostHog API not configured", error);
462
- throw error;
335
+ this.logger.info('Pull request created', { taskId, prUrl });
336
+ return prUrl;
463
337
  }
464
338
 
465
- await this.posthogAPI.updateTaskRun(taskId, this.progressReporter.runId, {
466
- branch: branchName,
467
- });
468
- this.logger.debug("Task run branch updated", {
469
- taskId,
470
- runId: this.progressReporter.runId,
471
- branchName,
472
- });
473
- }
474
-
475
- // Execution management
476
- cancelTask(taskId: string): void {
477
- // Find the execution for this task and cancel it
478
- for (const [executionId, execution] of this.taskManager.executionStates) {
479
- if (execution.taskId === taskId && execution.status === "running") {
480
- this.taskManager.cancelExecution(executionId);
481
- break;
482
- }
483
- }
484
- }
485
-
486
- getTaskExecutionStatus(taskId: string): string | null {
487
- // Find the execution for this task
488
- for (const execution of this.taskManager.executionStates.values()) {
489
- if (execution.taskId === taskId) {
490
- return execution.status;
491
- }
492
- }
493
- return null;
494
- }
495
-
496
- private async prepareTaskBranch(
497
- taskSlug: string,
498
- isCloudMode: boolean,
499
- ): Promise<void> {
500
- if (await this.gitManager.hasChanges()) {
501
- throw new Error(
502
- "Cannot start task with uncommitted changes. Please commit or stash your changes first.",
503
- );
504
- }
505
-
506
- await this.gitManager.resetToDefaultBranchIfNeeded();
339
+ async attachPullRequestToTask(taskId: string, prUrl: string, branchName?: string): Promise<void> {
340
+ this.logger.info('Attaching PR to task run', { taskId, prUrl, branchName });
507
341
 
508
- const existingBranch = await this.gitManager.getTaskBranch(taskSlug);
509
- if (!existingBranch) {
510
- const branchName = await this.gitManager.createTaskBranch(taskSlug);
511
- this.emitEvent(
512
- this.adapter.createStatusEvent("branch_created", {
513
- branch: branchName,
514
- }),
515
- );
516
-
517
- await this.gitManager.addAllPostHogFiles();
342
+ if (!this.posthogAPI || !this.progressReporter.runId) {
343
+ const error = new Error('PostHog API not configured or no active run. Cannot attach PR to task.');
344
+ this.logger.error('PostHog API not configured', error);
345
+ throw error;
346
+ }
518
347
 
519
- // Only commit if there are changes or we're in cloud mode
520
- if (isCloudMode) {
521
- await this.gitManager.commitAndPush(`Initialize task ${taskSlug}`, {
522
- allowEmpty: true,
523
- });
524
- } else {
525
- // Check if there are any changes before committing
526
- const hasChanges = await this.gitManager.hasStagedChanges();
527
- if (hasChanges) {
528
- await this.gitManager.commitChanges(`Initialize task ${taskSlug}`);
348
+ const updates: any = {
349
+ output: { pr_url: prUrl }
350
+ };
351
+ if (branchName) {
352
+ updates.branch = branchName;
529
353
  }
530
- }
531
- } else {
532
- this.logger.info("Switching to existing task branch", {
533
- branch: existingBranch,
534
- });
535
- await this.gitManager.switchToBranch(existingBranch);
354
+
355
+ await this.posthogAPI.updateTaskRun(taskId, this.progressReporter.runId, updates);
356
+ this.logger.debug('PR attached to task run', { taskId, runId: this.progressReporter.runId, prUrl });
536
357
  }
537
- }
538
358
 
539
- private ensureOpenAIGatewayEnv(gatewayUrl?: string, token?: string): void {
540
- const resolvedGatewayUrl = gatewayUrl || process.env.ANTHROPIC_BASE_URL;
541
- const resolvedToken = token || process.env.ANTHROPIC_AUTH_TOKEN;
359
+ async updateTaskBranch(taskId: string, branchName: string): Promise<void> {
360
+ this.logger.info('Updating task run branch', { taskId, branchName });
542
361
 
543
- if (resolvedGatewayUrl) {
544
- process.env.OPENAI_BASE_URL = resolvedGatewayUrl;
362
+ if (!this.posthogAPI || !this.progressReporter.runId) {
363
+ const error = new Error('PostHog API not configured or no active run. Cannot update branch.');
364
+ this.logger.error('PostHog API not configured', error);
365
+ throw error;
366
+ }
367
+
368
+ await this.posthogAPI.updateTaskRun(taskId, this.progressReporter.runId, { branch: branchName });
369
+ this.logger.debug('Task run branch updated', { taskId, runId: this.progressReporter.runId, branchName });
545
370
  }
546
371
 
547
- if (resolvedToken) {
548
- process.env.OPENAI_API_KEY = resolvedToken;
372
+ // Execution management
373
+ cancelTask(taskId: string): void {
374
+ // Find the execution for this task and cancel it
375
+ for (const [executionId, execution] of this.taskManager['executionStates']) {
376
+ if (execution.taskId === taskId && execution.status === 'running') {
377
+ this.taskManager.cancelExecution(executionId);
378
+ break;
379
+ }
380
+ }
549
381
  }
550
- }
551
-
552
- private async ensurePullRequest(
553
- task: Task,
554
- stepResults: Record<string, any>,
555
- ): Promise<void> {
556
- const latestRun = task.latest_run;
557
- const existingPr =
558
- latestRun?.output && typeof latestRun.output === "object"
559
- ? (latestRun.output as any).pr_url
560
- : null;
561
-
562
- if (existingPr) {
563
- this.logger.info("PR already exists, skipping creation", {
564
- taskId: task.id,
565
- prUrl: existingPr,
566
- });
567
- return;
382
+
383
+ getTaskExecutionStatus(taskId: string): string | null {
384
+ // Find the execution for this task
385
+ for (const execution of this.taskManager['executionStates'].values()) {
386
+ if (execution.taskId === taskId) {
387
+ return execution.status;
388
+ }
389
+ }
390
+ return null;
568
391
  }
569
392
 
570
- const buildResult = stepResults.build;
571
- if (!buildResult?.commitCreated) {
572
- this.logger.warn(
573
- "Build step did not produce a commit; skipping PR creation",
574
- { taskId: task.id },
575
- );
576
- return;
393
+ private async prepareTaskBranch(taskSlug: string, isCloudMode: boolean): Promise<void> {
394
+ if (await this.gitManager.hasChanges()) {
395
+ throw new Error('Cannot start task with uncommitted changes. Please commit or stash your changes first.');
396
+ }
397
+
398
+ await this.gitManager.resetToDefaultBranchIfNeeded();
399
+
400
+ const existingBranch = await this.gitManager.getTaskBranch(taskSlug);
401
+ if (!existingBranch) {
402
+ const branchName = await this.gitManager.createTaskBranch(taskSlug);
403
+ this.emitEvent(this.adapter.createStatusEvent('branch_created', { branch: branchName }));
404
+
405
+ await this.gitManager.addAllPostHogFiles();
406
+
407
+ // Only commit if there are changes or we're in cloud mode
408
+ if (isCloudMode) {
409
+ await this.gitManager.commitAndPush(`Initialize task ${taskSlug}`, { allowEmpty: true });
410
+ } else {
411
+ // Check if there are any changes before committing
412
+ const hasChanges = await this.gitManager.hasStagedChanges();
413
+ if (hasChanges) {
414
+ await this.gitManager.commitChanges(`Initialize task ${taskSlug}`);
415
+ }
416
+ }
417
+ } else {
418
+ this.logger.info('Switching to existing task branch', { branch: existingBranch });
419
+ await this.gitManager.switchToBranch(existingBranch);
420
+ }
577
421
  }
578
422
 
579
- const branchName = await this.gitManager.getCurrentBranch();
580
- const finalizeResult = stepResults.finalize;
581
- const prBody = finalizeResult?.prBody;
582
-
583
- const prUrl = await this.createPullRequest(
584
- task.id,
585
- branchName,
586
- task.title,
587
- task.description ?? "",
588
- prBody,
589
- );
590
-
591
- this.emitEvent(this.adapter.createStatusEvent("pr_created", { prUrl }));
592
-
593
- try {
594
- await this.attachPullRequestToTask(task.id, prUrl, branchName);
595
- this.logger.info("PR attached to task successfully", {
596
- taskId: task.id,
597
- prUrl,
598
- });
599
- } catch (error) {
600
- this.logger.warn("Could not attach PR to task", {
601
- error: error instanceof Error ? error.message : String(error),
602
- });
423
+ private ensureOpenAIGatewayEnv(gatewayUrl?: string, token?: string): void {
424
+ const resolvedGatewayUrl = gatewayUrl || process.env.ANTHROPIC_BASE_URL;
425
+ const resolvedToken = token || process.env.ANTHROPIC_AUTH_TOKEN;
426
+
427
+ if (resolvedGatewayUrl) {
428
+ process.env.OPENAI_BASE_URL = resolvedGatewayUrl;
429
+ }
430
+
431
+ if (resolvedToken) {
432
+ process.env.OPENAI_API_KEY = resolvedToken;
433
+ }
603
434
  }
604
- }
605
435
 
606
- private emitEvent(event: any): void {
607
- if (this.debug && event.type !== "token") {
608
- // Log all events except tokens (too verbose)
609
- this.logger.debug("Emitting event", { type: event.type, ts: event.ts });
436
+ private async ensurePullRequest(task: Task, stepResults: Record<string, any>): Promise<void> {
437
+ const latestRun = task.latest_run;
438
+ const existingPr =
439
+ latestRun?.output && typeof latestRun.output === 'object'
440
+ ? (latestRun.output as any).pr_url
441
+ : null;
442
+
443
+ if (existingPr) {
444
+ this.logger.info('PR already exists, skipping creation', { taskId: task.id, prUrl: existingPr });
445
+ return;
446
+ }
447
+
448
+ const buildResult = stepResults['build'];
449
+ if (!buildResult?.commitCreated) {
450
+ this.logger.warn('Build step did not produce a commit; skipping PR creation', { taskId: task.id });
451
+ return;
452
+ }
453
+
454
+ const branchName = await this.gitManager.getCurrentBranch();
455
+ const finalizeResult = stepResults['finalize'];
456
+ const prBody = finalizeResult?.prBody;
457
+
458
+ const prUrl = await this.createPullRequest(
459
+ task.id,
460
+ branchName,
461
+ task.title,
462
+ task.description ?? '',
463
+ prBody
464
+ );
465
+
466
+ this.emitEvent(this.adapter.createStatusEvent('pr_created', { prUrl }));
467
+
468
+ try {
469
+ await this.attachPullRequestToTask(task.id, prUrl, branchName);
470
+ this.logger.info('PR attached to task successfully', { taskId: task.id, prUrl });
471
+ } catch (error) {
472
+ this.logger.warn('Could not attach PR to task', {
473
+ error: error instanceof Error ? error.message : String(error),
474
+ });
475
+ }
610
476
  }
611
- const persistPromise = this.progressReporter.recordEvent(event);
612
- if (persistPromise && typeof persistPromise.then === "function") {
613
- persistPromise.catch((error: Error) =>
614
- this.logger.debug("Failed to persist agent event", {
615
- message: error.message,
616
- }),
617
- );
477
+
478
+ private emitEvent(event: any): void {
479
+ if (this.debug && event.type !== 'token') {
480
+ // Log all events except tokens (too verbose)
481
+ this.logger.debug('Emitting event', { type: event.type, ts: event.ts });
482
+ }
483
+ const persistPromise = this.progressReporter.recordEvent(event);
484
+ if (persistPromise && typeof persistPromise.then === 'function') {
485
+ persistPromise.catch((error: Error) =>
486
+ this.logger.debug('Failed to persist agent event', { message: error.message })
487
+ );
488
+ }
489
+ this.onEvent?.(event);
618
490
  }
619
- this.onEvent?.(event);
620
- }
621
491
  }
622
492
 
623
- export type {
624
- AgentConfig,
625
- ExecutionResult,
626
- SupportingFile,
627
- Task,
628
- } from "./types.js";
629
- export { PermissionMode } from "./types.js";
493
+ export { PermissionMode } from './types.js';
494
+ export type { Task, SupportingFile, ExecutionResult, AgentConfig } from './types.js';