@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
@@ -1,248 +1,216 @@
1
- import type { LocalArtifact } from "../../file-manager.js";
2
- import type { Task, TaskRunArtifact } from "../../types.js";
3
- import type { WorkflowStepRunner } from "../types.js";
4
- import { finalizeStepGitActions } from "../utils.js";
1
+ import type { LocalArtifact } from '../../file-manager.js';
2
+ import type { Task, TaskRunArtifact } from '../../types.js';
3
+ import type { WorkflowStepRunner } from '../types.js';
4
+ import { finalizeStepGitActions } from '../utils.js';
5
5
 
6
6
  const MAX_SNIPPET_LENGTH = 1200;
7
7
 
8
8
  export const finalizeStep: WorkflowStepRunner = async ({ step, context }) => {
9
- const {
10
- task,
11
- logger,
12
- fileManager,
13
- gitManager,
14
- posthogAPI,
15
- progressReporter,
16
- } = context;
17
-
18
- const stepLogger = logger.child("FinalizeStep");
19
- const artifacts = await fileManager.collectTaskArtifacts(task.id);
20
- let uploadedArtifacts: TaskRunArtifact[] | undefined;
21
-
22
- if (artifacts.length && posthogAPI && progressReporter.runId) {
23
- try {
24
- const payload = artifacts.map((artifact) => ({
25
- name: artifact.name,
26
- type: artifact.type,
27
- content: artifact.content,
28
- content_type: artifact.contentType,
29
- }));
30
- uploadedArtifacts = await posthogAPI.uploadTaskArtifacts(
31
- task.id,
32
- progressReporter.runId,
33
- payload,
34
- );
35
- stepLogger.info("Uploaded task artifacts to PostHog", {
36
- taskId: task.id,
37
- uploadedCount: uploadedArtifacts.length,
38
- });
39
- } catch (error) {
40
- stepLogger.warn("Failed to upload task artifacts", {
41
- taskId: task.id,
42
- error: error instanceof Error ? error.message : String(error),
43
- });
9
+ const {
10
+ task,
11
+ logger,
12
+ fileManager,
13
+ gitManager,
14
+ posthogAPI,
15
+ progressReporter,
16
+ } = context;
17
+
18
+ const stepLogger = logger.child('FinalizeStep');
19
+ const artifacts = await fileManager.collectTaskArtifacts(task.id);
20
+ let uploadedArtifacts: TaskRunArtifact[] | undefined;
21
+
22
+ if (artifacts.length && posthogAPI && progressReporter.runId) {
23
+ try {
24
+ const payload = artifacts.map((artifact) => ({
25
+ name: artifact.name,
26
+ type: artifact.type,
27
+ content: artifact.content,
28
+ content_type: artifact.contentType,
29
+ }));
30
+ uploadedArtifacts = await posthogAPI.uploadTaskArtifacts(task.id, progressReporter.runId, payload);
31
+ stepLogger.info('Uploaded task artifacts to PostHog', {
32
+ taskId: task.id,
33
+ uploadedCount: uploadedArtifacts.length,
34
+ });
35
+ } catch (error) {
36
+ stepLogger.warn('Failed to upload task artifacts', {
37
+ taskId: task.id,
38
+ error: error instanceof Error ? error.message : String(error),
39
+ });
40
+ }
41
+ } else {
42
+ stepLogger.debug('Skipping artifact upload', {
43
+ hasArtifacts: artifacts.length > 0,
44
+ hasPostHogApi: Boolean(posthogAPI),
45
+ runId: progressReporter.runId,
46
+ });
44
47
  }
45
- } else {
46
- stepLogger.debug("Skipping artifact upload", {
47
- hasArtifacts: artifacts.length > 0,
48
- hasPostHogApi: Boolean(posthogAPI),
49
- runId: progressReporter.runId,
48
+
49
+ const prBody = buildPullRequestBody(task, artifacts, uploadedArtifacts);
50
+ await fileManager.cleanupTaskDirectory(task.id);
51
+ await gitManager.addAllPostHogFiles();
52
+
53
+ // Commit the deletion of artifacts
54
+ await finalizeStepGitActions(context, step, {
55
+ commitMessage: `Cleanup task artifacts for ${task.title}`,
56
+ allowEmptyCommit: true
50
57
  });
51
- }
52
58
 
53
- const prBody = buildPullRequestBody(task, artifacts, uploadedArtifacts);
54
- await fileManager.cleanupTaskDirectory(task.id);
55
- await gitManager.addAllPostHogFiles();
59
+ context.stepResults[step.id] = {
60
+ prBody,
61
+ uploadedArtifacts,
62
+ artifactCount: artifacts.length,
63
+ };
56
64
 
57
- // Commit the deletion of artifacts
58
- await finalizeStepGitActions(context, step, {
59
- commitMessage: `Cleanup task artifacts for ${task.title}`,
60
- allowEmptyCommit: true,
61
- });
65
+ return { status: 'completed' };
66
+ };
62
67
 
63
- context.stepResults[step.id] = {
64
- prBody,
65
- uploadedArtifacts,
66
- artifactCount: artifacts.length,
67
- };
68
+ function buildPullRequestBody(task: Task, artifacts: LocalArtifact[], uploaded?: TaskRunArtifact[]): string {
69
+ const lines: string[] = [];
70
+ const taskSlug = (task as any).slug || task.id;
68
71
 
69
- return { status: "completed" };
70
- };
72
+ lines.push('## Task context');
73
+ lines.push(`- **Task**: ${taskSlug}`);
74
+ lines.push(`- **Title**: ${task.title}`);
75
+ lines.push(`- **Origin**: ${task.origin_product}`);
76
+
77
+ if (task.description) {
78
+ lines.push('');
79
+ lines.push('> ' + task.description.trim().split('\n').join('\n> '));
80
+ }
81
+
82
+ const usedFiles = new Set<string>();
83
+
84
+ const contextArtifact = artifacts.find((artifact) => artifact.name === 'context.md');
85
+ if (contextArtifact) {
86
+ lines.push('');
87
+ lines.push('### Task prompt');
88
+ lines.push(contextArtifact.content);
89
+ usedFiles.add(contextArtifact.name);
90
+ }
71
91
 
72
- function buildPullRequestBody(
73
- task: Task,
74
- artifacts: LocalArtifact[],
75
- uploaded?: TaskRunArtifact[],
76
- ): string {
77
- const lines: string[] = [];
78
- const taskSlug = (task as unknown as Record<string, unknown>).slug || task.id;
79
-
80
- lines.push("## Task context");
81
- lines.push(`- **Task**: ${taskSlug}`);
82
- lines.push(`- **Title**: ${task.title}`);
83
- lines.push(`- **Origin**: ${task.origin_product}`);
84
-
85
- if (task.description) {
86
- lines.push("");
87
- lines.push(`> ${task.description.trim().split("\n").join("\n> ")}`);
88
- }
89
-
90
- const usedFiles = new Set<string>();
91
-
92
- const contextArtifact = artifacts.find(
93
- (artifact) => artifact.name === "context.md",
94
- );
95
- if (contextArtifact) {
96
- lines.push("");
97
- lines.push("### Task prompt");
98
- lines.push(contextArtifact.content);
99
- usedFiles.add(contextArtifact.name);
100
- }
101
-
102
- const researchArtifact = artifacts.find(
103
- (artifact) => artifact.name === "research.json",
104
- );
105
- if (researchArtifact) {
106
- usedFiles.add(researchArtifact.name);
107
- const researchSection = formatResearchSection(researchArtifact.content);
108
- if (researchSection) {
109
- lines.push("");
110
- lines.push(researchSection);
92
+ const researchArtifact = artifacts.find((artifact) => artifact.name === 'research.json');
93
+ if (researchArtifact) {
94
+ usedFiles.add(researchArtifact.name);
95
+ const researchSection = formatResearchSection(researchArtifact.content);
96
+ if (researchSection) {
97
+ lines.push('');
98
+ lines.push(researchSection);
99
+ }
111
100
  }
112
- }
113
-
114
- const planArtifact = artifacts.find(
115
- (artifact) => artifact.name === "plan.md",
116
- );
117
- if (planArtifact) {
118
- lines.push("");
119
- lines.push("### Implementation plan");
120
- lines.push(planArtifact.content);
121
- usedFiles.add(planArtifact.name);
122
- }
123
-
124
- const todoArtifact = artifacts.find(
125
- (artifact) => artifact.name === "todos.json",
126
- );
127
- if (todoArtifact) {
128
- const summary = summarizeTodos(todoArtifact.content);
129
- if (summary) {
130
- lines.push("");
131
- lines.push("### Todo list");
132
- lines.push(summary);
101
+
102
+ const planArtifact = artifacts.find((artifact) => artifact.name === 'plan.md');
103
+ if (planArtifact) {
104
+ lines.push('');
105
+ lines.push('### Implementation plan');
106
+ lines.push(planArtifact.content);
107
+ usedFiles.add(planArtifact.name);
108
+ }
109
+
110
+ const todoArtifact = artifacts.find((artifact) => artifact.name === 'todos.json');
111
+ if (todoArtifact) {
112
+ const summary = summarizeTodos(todoArtifact.content);
113
+ if (summary) {
114
+ lines.push('');
115
+ lines.push('### Todo list');
116
+ lines.push(summary);
117
+ }
118
+ usedFiles.add(todoArtifact.name);
133
119
  }
134
- usedFiles.add(todoArtifact.name);
135
- }
136
-
137
- const remainingArtifacts = artifacts.filter(
138
- (artifact) => !usedFiles.has(artifact.name),
139
- );
140
- if (remainingArtifacts.length) {
141
- lines.push("");
142
- lines.push("### Additional artifacts");
143
- for (const artifact of remainingArtifacts) {
144
- lines.push(`#### ${artifact.name}`);
145
- lines.push(renderCodeFence(artifact.content));
120
+
121
+ const remainingArtifacts = artifacts.filter((artifact) => !usedFiles.has(artifact.name));
122
+ if (remainingArtifacts.length) {
123
+ lines.push('');
124
+ lines.push('### Additional artifacts');
125
+ for (const artifact of remainingArtifacts) {
126
+ lines.push(`#### ${artifact.name}`);
127
+ lines.push(renderCodeFence(artifact.content));
128
+ }
146
129
  }
147
- }
148
130
 
149
- const artifactList =
150
- uploaded ??
151
- artifacts.map((artifact) => ({
152
- name: artifact.name,
153
- type: artifact.type,
131
+ const artifactList = uploaded ?? artifacts.map((artifact) => ({
132
+ name: artifact.name,
133
+ type: artifact.type,
154
134
  }));
155
135
 
156
- if (artifactList.length) {
157
- lines.push("");
158
- lines.push("### Uploaded artifacts");
159
- for (const artifact of artifactList) {
160
- const rawStoragePath =
161
- "storage_path" in artifact
162
- ? (artifact as Record<string, unknown>).storage_path
163
- : undefined;
164
- const storagePath =
165
- typeof rawStoragePath === "string" ? rawStoragePath : undefined;
166
- const storage =
167
- storagePath && storagePath.trim().length > 0
168
- ? ` – \`${storagePath.trim()}\``
169
- : "";
170
- lines.push(`- ${artifact.name} (${artifact.type})${storage}`);
136
+ if (artifactList.length) {
137
+ lines.push('');
138
+ lines.push('### Uploaded artifacts');
139
+ for (const artifact of artifactList) {
140
+ const rawStoragePath = 'storage_path' in artifact ? (artifact as any).storage_path : undefined;
141
+ const storagePath = typeof rawStoragePath === 'string' ? rawStoragePath : undefined;
142
+ const storage = storagePath && storagePath.trim().length > 0 ? ` – \`${storagePath.trim()}\`` : '';
143
+ lines.push(`- ${artifact.name} (${artifact.type})${storage}`);
144
+ }
171
145
  }
172
- }
173
146
 
174
- return lines.join("\n\n");
147
+ return lines.join('\n\n');
175
148
  }
176
149
 
177
150
  function renderCodeFence(content: string): string {
178
- const snippet = truncate(content, MAX_SNIPPET_LENGTH);
179
- return ["```", snippet, "```"].join("\n");
151
+ const snippet = truncate(content, MAX_SNIPPET_LENGTH);
152
+ return ['```', snippet, '```'].join('\n');
180
153
  }
181
154
 
182
155
  function truncate(value: string, maxLength: number): string {
183
- if (value.length <= maxLength) {
184
- return value;
185
- }
186
- return `${value.slice(0, maxLength)}\n…`;
156
+ if (value.length <= maxLength) {
157
+ return value;
158
+ }
159
+ return `${value.slice(0, maxLength)}\n…`;
187
160
  }
188
161
 
189
162
  function formatResearchSection(content: string): string | null {
190
- try {
191
- const parsed = JSON.parse(content);
192
- const sections: string[] = [];
193
-
194
- if (parsed.context) {
195
- sections.push("### Research summary");
196
- sections.push(parsed.context);
197
- }
198
-
199
- if (parsed.questions?.length) {
200
- sections.push("");
201
- sections.push("### Questions needing answers");
202
- for (const question of parsed.questions) {
203
- sections.push(`- ${question.question ?? question}`);
204
- }
205
- }
206
-
207
- if (parsed.answers?.length) {
208
- sections.push("");
209
- sections.push("### Answers provided");
210
- for (const answer of parsed.answers) {
211
- const questionId = answer.questionId
212
- ? ` (Q: ${answer.questionId})`
213
- : "";
214
- sections.push(
215
- `- ${answer.selectedOption || answer.customInput || "answer"}${questionId}`,
216
- );
217
- }
163
+ try {
164
+ const parsed = JSON.parse(content);
165
+ const sections: string[] = [];
166
+
167
+ if (parsed.context) {
168
+ sections.push('### Research summary');
169
+ sections.push(parsed.context);
170
+ }
171
+
172
+ if (parsed.questions && parsed.questions.length) {
173
+ sections.push('');
174
+ sections.push('### Questions needing answers');
175
+ for (const question of parsed.questions) {
176
+ sections.push(`- ${question.question ?? question}`);
177
+ }
178
+ }
179
+
180
+ if (parsed.answers && parsed.answers.length) {
181
+ sections.push('');
182
+ sections.push('### Answers provided');
183
+ for (const answer of parsed.answers) {
184
+ const questionId = answer.questionId ? ` (Q: ${answer.questionId})` : '';
185
+ sections.push(`- ${answer.selectedOption || answer.customInput || 'answer'}${questionId}`);
186
+ }
187
+ }
188
+
189
+ return sections.length ? sections.join('\n') : null;
190
+ } catch {
191
+ return null;
218
192
  }
219
-
220
- return sections.length ? sections.join("\n") : null;
221
- } catch {
222
- return null;
223
- }
224
193
  }
225
194
 
226
195
  function summarizeTodos(content: string): string | null {
227
- try {
228
- const data = JSON.parse(content);
229
- const total = data?.metadata?.total ?? data?.items?.length;
230
- const completed =
231
- data?.metadata?.completed ??
232
- data?.items?.filter(
233
- (item: { status?: string }) => item.status === "completed",
234
- ).length;
235
-
236
- const lines = [`Progress: ${completed}/${total} completed`];
237
-
238
- if (data?.items?.length) {
239
- for (const item of data.items) {
240
- lines.push(`- [${item.status}] ${item.content}`);
241
- }
196
+ try {
197
+ const data = JSON.parse(content);
198
+ const total = data?.metadata?.total ?? data?.items?.length;
199
+ const completed = data?.metadata?.completed ?? data?.items?.filter((item: any) => item.status === 'completed').length;
200
+
201
+ const lines = [
202
+ `Progress: ${completed}/${total} completed`,
203
+ ];
204
+
205
+ if (data?.items?.length) {
206
+ for (const item of data.items) {
207
+ lines.push(`- [${item.status}] ${item.content}`);
208
+ }
209
+ }
210
+
211
+ return lines.join('\n');
212
+ } catch {
213
+ return null;
242
214
  }
243
-
244
- return lines.join("\n");
245
- } catch {
246
- return null;
247
- }
248
215
  }
216
+