@posthog/agent 1.22.0 → 1.24.0

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 (118) hide show
  1. package/CLAUDE.md +3 -3
  2. package/README.md +3 -3
  3. package/dist/index.d.ts +11 -11
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +3 -3
  6. package/dist/src/adapters/claude/claude-adapter.d.ts +3 -3
  7. package/dist/src/adapters/claude/claude-adapter.d.ts.map +1 -1
  8. package/dist/src/adapters/claude/claude-adapter.js +156 -111
  9. package/dist/src/adapters/claude/claude-adapter.js.map +1 -1
  10. package/dist/src/adapters/claude/tool-mapper.d.ts +1 -1
  11. package/dist/src/adapters/claude/tool-mapper.d.ts.map +1 -1
  12. package/dist/src/adapters/claude/tool-mapper.js.map +1 -1
  13. package/dist/src/adapters/types.d.ts +1 -1
  14. package/dist/src/adapters/types.d.ts.map +1 -1
  15. package/dist/src/agent.d.ts +7 -7
  16. package/dist/src/agent.d.ts.map +1 -1
  17. package/dist/src/agent.js +143 -85
  18. package/dist/src/agent.js.map +1 -1
  19. package/dist/src/agents/execution.js.map +1 -1
  20. package/dist/src/agents/planning.js.map +1 -1
  21. package/dist/src/agents/research.js.map +1 -1
  22. package/dist/src/file-manager.d.ts +4 -4
  23. package/dist/src/file-manager.d.ts.map +1 -1
  24. package/dist/src/file-manager.js +59 -58
  25. package/dist/src/file-manager.js.map +1 -1
  26. package/dist/src/git-manager.d.ts +1 -1
  27. package/dist/src/git-manager.d.ts.map +1 -1
  28. package/dist/src/git-manager.js +93 -69
  29. package/dist/src/git-manager.js.map +1 -1
  30. package/dist/src/posthog-api.d.ts +2 -3
  31. package/dist/src/posthog-api.d.ts.map +1 -1
  32. package/dist/src/posthog-api.js +22 -22
  33. package/dist/src/posthog-api.js.map +1 -1
  34. package/dist/src/prompt-builder.d.ts +3 -3
  35. package/dist/src/prompt-builder.d.ts.map +1 -1
  36. package/dist/src/prompt-builder.js +123 -93
  37. package/dist/src/prompt-builder.js.map +1 -1
  38. package/dist/src/task-manager.d.ts +4 -4
  39. package/dist/src/task-manager.d.ts.map +1 -1
  40. package/dist/src/task-manager.js +19 -18
  41. package/dist/src/task-manager.js.map +1 -1
  42. package/dist/src/task-progress-reporter.d.ts +3 -4
  43. package/dist/src/task-progress-reporter.d.ts.map +1 -1
  44. package/dist/src/task-progress-reporter.js +59 -54
  45. package/dist/src/task-progress-reporter.js.map +1 -1
  46. package/dist/src/template-manager.d.ts +1 -1
  47. package/dist/src/template-manager.d.ts.map +1 -1
  48. package/dist/src/template-manager.js +30 -28
  49. package/dist/src/template-manager.js.map +1 -1
  50. package/dist/src/todo-manager.d.ts +3 -3
  51. package/dist/src/todo-manager.d.ts.map +1 -1
  52. package/dist/src/todo-manager.js +29 -24
  53. package/dist/src/todo-manager.js.map +1 -1
  54. package/dist/src/tools/registry.d.ts +1 -1
  55. package/dist/src/tools/registry.js +60 -60
  56. package/dist/src/tools/registry.js.map +1 -1
  57. package/dist/src/tools/types.d.ts +31 -31
  58. package/dist/src/types.d.ts +33 -33
  59. package/dist/src/types.d.ts.map +1 -1
  60. package/dist/src/types.js.map +1 -1
  61. package/dist/src/utils/logger.d.ts +4 -4
  62. package/dist/src/utils/logger.d.ts.map +1 -1
  63. package/dist/src/utils/logger.js +8 -8
  64. package/dist/src/utils/logger.js.map +1 -1
  65. package/dist/src/workflow/config.d.ts +1 -1
  66. package/dist/src/workflow/config.d.ts.map +1 -1
  67. package/dist/src/workflow/config.js +18 -18
  68. package/dist/src/workflow/config.js.map +1 -1
  69. package/dist/src/workflow/steps/build.d.ts +1 -1
  70. package/dist/src/workflow/steps/build.d.ts.map +1 -1
  71. package/dist/src/workflow/steps/build.js +46 -38
  72. package/dist/src/workflow/steps/build.js.map +1 -1
  73. package/dist/src/workflow/steps/finalize.d.ts +1 -1
  74. package/dist/src/workflow/steps/finalize.d.ts.map +1 -1
  75. package/dist/src/workflow/steps/finalize.js +54 -48
  76. package/dist/src/workflow/steps/finalize.js.map +1 -1
  77. package/dist/src/workflow/steps/plan.d.ts +1 -1
  78. package/dist/src/workflow/steps/plan.d.ts.map +1 -1
  79. package/dist/src/workflow/steps/plan.js +58 -46
  80. package/dist/src/workflow/steps/plan.js.map +1 -1
  81. package/dist/src/workflow/steps/research.d.ts +1 -1
  82. package/dist/src/workflow/steps/research.d.ts.map +1 -1
  83. package/dist/src/workflow/steps/research.js +68 -56
  84. package/dist/src/workflow/steps/research.js.map +1 -1
  85. package/dist/src/workflow/types.d.ts +12 -12
  86. package/dist/src/workflow/types.d.ts.map +1 -1
  87. package/dist/src/workflow/utils.d.ts +1 -1
  88. package/dist/src/workflow/utils.d.ts.map +1 -1
  89. package/dist/src/workflow/utils.js +7 -4
  90. package/dist/src/workflow/utils.js.map +1 -1
  91. package/package.json +8 -8
  92. package/src/adapters/claude/claude-adapter.ts +220 -168
  93. package/src/adapters/claude/tool-mapper.ts +2 -2
  94. package/src/adapters/types.ts +1 -1
  95. package/src/agent.ts +579 -444
  96. package/src/agents/execution.ts +1 -1
  97. package/src/agents/planning.ts +1 -1
  98. package/src/agents/research.ts +0 -1
  99. package/src/file-manager.ts +64 -63
  100. package/src/git-manager.ts +152 -87
  101. package/src/posthog-api.ts +122 -82
  102. package/src/prompt-builder.ts +180 -135
  103. package/src/task-manager.ts +38 -30
  104. package/src/task-progress-reporter.ts +70 -59
  105. package/src/template-manager.ts +98 -45
  106. package/src/todo-manager.ts +35 -30
  107. package/src/tools/registry.ts +62 -62
  108. package/src/tools/types.ts +36 -36
  109. package/src/types.ts +93 -71
  110. package/src/utils/logger.ts +62 -56
  111. package/src/workflow/config.ts +48 -48
  112. package/src/workflow/steps/build.ts +122 -113
  113. package/src/workflow/steps/finalize.ts +214 -182
  114. package/src/workflow/steps/plan.ts +151 -131
  115. package/src/workflow/steps/research.ts +205 -186
  116. package/src/workflow/types.ts +38 -36
  117. package/src/workflow/utils.ts +37 -34
  118. package/LICENSE +0 -33
@@ -1,142 +1,162 @@
1
- import { query } from '@anthropic-ai/claude-agent-sdk';
2
- import { PLANNING_SYSTEM_PROMPT } from '../../agents/planning.js';
3
- import type { WorkflowStepRunner } from '../types.js';
4
- import { finalizeStepGitActions } from '../utils.js';
5
- import { TodoManager } from '../../todo-manager.js';
1
+ import { query } from "@anthropic-ai/claude-agent-sdk";
2
+ import { PLANNING_SYSTEM_PROMPT } from "../../agents/planning.js";
3
+ import { TodoManager } from "../../todo-manager.js";
4
+ import type { WorkflowStepRunner } from "../types.js";
5
+ import { finalizeStepGitActions } from "../utils.js";
6
6
 
7
7
  export const planStep: WorkflowStepRunner = async ({ step, context }) => {
8
- const {
9
- task,
10
- cwd,
11
- isCloudMode,
12
- options,
13
- logger,
14
- fileManager,
15
- gitManager,
16
- promptBuilder,
17
- adapter,
18
- mcpServers,
19
- emitEvent,
20
- } = context;
21
-
22
- const stepLogger = logger.child('PlanStep');
23
-
24
- const existingPlan = await fileManager.readPlan(task.id);
25
- if (existingPlan) {
26
- stepLogger.info('Plan already exists, skipping step', { taskId: task.id });
27
- return { status: 'skipped' };
8
+ const {
9
+ task,
10
+ cwd,
11
+ isCloudMode,
12
+ options,
13
+ logger,
14
+ fileManager,
15
+ gitManager,
16
+ promptBuilder,
17
+ adapter,
18
+ mcpServers,
19
+ emitEvent,
20
+ } = context;
21
+
22
+ const stepLogger = logger.child("PlanStep");
23
+
24
+ const existingPlan = await fileManager.readPlan(task.id);
25
+ if (existingPlan) {
26
+ stepLogger.info("Plan already exists, skipping step", { taskId: task.id });
27
+ return { status: "skipped" };
28
+ }
29
+
30
+ const researchData = await fileManager.readResearch(task.id);
31
+ if (researchData?.questions && !researchData.answered) {
32
+ stepLogger.info("Waiting for answered research questions", {
33
+ taskId: task.id,
34
+ });
35
+ emitEvent(
36
+ adapter.createStatusEvent("phase_complete", {
37
+ phase: "research_questions",
38
+ }),
39
+ );
40
+ return { status: "skipped", halt: true };
41
+ }
42
+
43
+ stepLogger.info("Starting planning phase", { taskId: task.id });
44
+ emitEvent(adapter.createStatusEvent("phase_start", { phase: "planning" }));
45
+ let researchContext = "";
46
+ if (researchData) {
47
+ researchContext += `## Research Context\n\n${researchData.context}\n\n`;
48
+ if (researchData.keyFiles.length > 0) {
49
+ researchContext += `**Key Files:**\n${researchData.keyFiles.map((f) => `- ${f}`).join("\n")}\n\n`;
28
50
  }
29
-
30
- const researchData = await fileManager.readResearch(task.id);
31
- if (researchData?.questions && !researchData.answered) {
32
- stepLogger.info('Waiting for answered research questions', { taskId: task.id });
33
- emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'research_questions' }));
34
- return { status: 'skipped', halt: true };
51
+ if (researchData.blockers && researchData.blockers.length > 0) {
52
+ researchContext += `**Considerations:**\n${researchData.blockers.map((b) => `- ${b}`).join("\n")}\n\n`;
35
53
  }
36
54
 
37
- stepLogger.info('Starting planning phase', { taskId: task.id });
38
- emitEvent(adapter.createStatusEvent('phase_start', { phase: 'planning' }));
39
- let researchContext = '';
40
- if (researchData) {
41
- researchContext += `## Research Context\n\n${researchData.context}\n\n`;
42
- if (researchData.keyFiles.length > 0) {
43
- researchContext += `**Key Files:**\n${researchData.keyFiles.map(f => `- ${f}`).join('\n')}\n\n`;
44
- }
45
- if (researchData.blockers && researchData.blockers.length > 0) {
46
- researchContext += `**Considerations:**\n${researchData.blockers.map(b => `- ${b}`).join('\n')}\n\n`;
47
- }
48
-
49
- // Add answered questions if they exist
50
- if (researchData.questions && researchData.answers && researchData.answered) {
51
- researchContext += `## Implementation Decisions\n\n`;
52
- for (const question of researchData.questions) {
53
- const answer = researchData.answers.find(
54
- (a) => a.questionId === question.id
55
- );
56
-
57
- researchContext += `### ${question.question}\n\n`;
58
- if (answer) {
59
- researchContext += `**Selected:** ${answer.selectedOption}\n`;
60
- if (answer.customInput) {
61
- researchContext += `**Details:** ${answer.customInput}\n`;
62
- }
63
- } else {
64
- researchContext += `**Selected:** Not answered\n`;
65
- }
66
- researchContext += `\n`;
67
- }
55
+ // Add answered questions if they exist
56
+ if (
57
+ researchData.questions &&
58
+ researchData.answers &&
59
+ researchData.answered
60
+ ) {
61
+ researchContext += `## Implementation Decisions\n\n`;
62
+ for (const question of researchData.questions) {
63
+ const answer = researchData.answers.find(
64
+ (a) => a.questionId === question.id,
65
+ );
66
+
67
+ researchContext += `### ${question.question}\n\n`;
68
+ if (answer) {
69
+ researchContext += `**Selected:** ${answer.selectedOption}\n`;
70
+ if (answer.customInput) {
71
+ researchContext += `**Details:** ${answer.customInput}\n`;
72
+ }
73
+ } else {
74
+ researchContext += `**Selected:** Not answered\n`;
68
75
  }
76
+ researchContext += `\n`;
77
+ }
69
78
  }
70
-
71
- const planningPrompt = await promptBuilder.buildPlanningPrompt(task, cwd);
72
- const fullPrompt = `${PLANNING_SYSTEM_PROMPT}\n\n${planningPrompt}\n\n${researchContext}`;
73
-
74
- const baseOptions: Record<string, any> = {
75
- model: step.model,
76
- cwd,
77
- permissionMode: 'plan',
78
- settingSources: ['local'],
79
- mcpServers,
80
- // Allow research tools: read-only operations, web search, MCP resources, and ExitPlanMode
81
- allowedTools: [
82
- 'Read',
83
- 'Glob',
84
- 'Grep',
85
- 'WebFetch',
86
- 'WebSearch',
87
- 'ListMcpResources',
88
- 'ReadMcpResource',
89
- 'ExitPlanMode',
90
- 'TodoWrite',
91
- 'BashOutput',
92
- ],
93
- };
94
-
95
- const response = query({
96
- prompt: fullPrompt,
97
- options: { ...baseOptions, ...(options.queryOverrides || {}) },
98
- });
99
-
100
- const todoManager = new TodoManager(fileManager, stepLogger);
101
-
102
- let planContent = '';
79
+ }
80
+
81
+ const planningPrompt = await promptBuilder.buildPlanningPrompt(task, cwd);
82
+ const fullPrompt = `${PLANNING_SYSTEM_PROMPT}\n\n${planningPrompt}\n\n${researchContext}`;
83
+
84
+ const baseOptions: Record<string, unknown> = {
85
+ model: step.model,
86
+ cwd,
87
+ permissionMode: "plan",
88
+ settingSources: ["local"],
89
+ mcpServers,
90
+ // Allow research tools: read-only operations, web search, MCP resources, and ExitPlanMode
91
+ allowedTools: [
92
+ "Read",
93
+ "Glob",
94
+ "Grep",
95
+ "WebFetch",
96
+ "WebSearch",
97
+ "ListMcpResources",
98
+ "ReadMcpResource",
99
+ "ExitPlanMode",
100
+ "TodoWrite",
101
+ "BashOutput",
102
+ ],
103
+ };
104
+
105
+ const response = query({
106
+ prompt: fullPrompt,
107
+ options: { ...baseOptions, ...(options.queryOverrides || {}) },
108
+ });
109
+
110
+ const todoManager = new TodoManager(fileManager, stepLogger);
111
+
112
+ let planContent = "";
113
+ try {
103
114
  for await (const message of response) {
104
- emitEvent(adapter.createRawSDKEvent(message));
105
- const transformedEvents = adapter.transform(message);
106
- for (const event of transformedEvents) {
107
- emitEvent(event);
108
- }
109
-
110
- const todoList = await todoManager.checkAndPersistFromMessage(message, task.id);
111
- if (todoList) {
112
- emitEvent(adapter.createArtifactEvent('todos', todoList));
113
- }
114
-
115
- // Extract text content for plan
116
- if (message.type === 'assistant' && message.message?.content) {
117
- for (const block of message.message.content) {
118
- if (block.type === 'text' && block.text) {
119
- planContent += `${block.text}\n`;
120
- }
121
- }
115
+ emitEvent(adapter.createRawSDKEvent(message));
116
+ const transformedEvents = adapter.transform(message);
117
+ for (const event of transformedEvents) {
118
+ emitEvent(event);
119
+ }
120
+
121
+ const todoList = await todoManager.checkAndPersistFromMessage(
122
+ message,
123
+ task.id,
124
+ );
125
+ if (todoList) {
126
+ emitEvent(adapter.createArtifactEvent("todos", todoList));
127
+ }
128
+
129
+ // Extract text content for plan
130
+ if (message.type === "assistant" && message.message?.content) {
131
+ for (const block of message.message.content) {
132
+ if (block.type === "text" && block.text) {
133
+ planContent += `${block.text}\n`;
134
+ }
122
135
  }
136
+ }
123
137
  }
124
-
125
- if (planContent.trim()) {
126
- await fileManager.writePlan(task.id, planContent.trim());
127
- stepLogger.info('Plan completed', { taskId: task.id });
128
- }
129
-
130
- await gitManager.addAllPostHogFiles();
131
- await finalizeStepGitActions(context, step, {
132
- commitMessage: `Planning phase for ${task.title}`,
133
- });
134
-
135
- if (!isCloudMode) {
136
- emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'planning' }));
137
- return { status: 'completed', halt: true };
138
- }
139
-
140
- emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'planning' }));
141
- return { status: 'completed' };
138
+ } catch (error) {
139
+ stepLogger.error("Error during plan step query", error);
140
+ throw error;
141
+ }
142
+
143
+ if (planContent.trim()) {
144
+ await fileManager.writePlan(task.id, planContent.trim());
145
+ stepLogger.info("Plan completed", { taskId: task.id });
146
+ }
147
+
148
+ await gitManager.addAllPostHogFiles();
149
+ await finalizeStepGitActions(context, step, {
150
+ commitMessage: `Planning phase for ${task.title}`,
151
+ });
152
+
153
+ if (!isCloudMode) {
154
+ emitEvent(
155
+ adapter.createStatusEvent("phase_complete", { phase: "planning" }),
156
+ );
157
+ return { status: "completed", halt: true };
158
+ }
159
+
160
+ emitEvent(adapter.createStatusEvent("phase_complete", { phase: "planning" }));
161
+ return { status: "completed" };
142
162
  };