@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,6 +1,6 @@
1
- import { exec } from "node:child_process";
2
- import { promisify } from "node:util";
3
- import { Logger } from "./utils/logger.js";
1
+ import { exec } from 'child_process';
2
+ import { promisify } from 'util';
3
+ import { Logger } from './utils/logger.js';
4
4
 
5
5
  const execAsync = promisify(exec);
6
6
 
@@ -27,23 +27,20 @@ export class GitManager {
27
27
  this.repositoryPath = config.repositoryPath;
28
28
  this.authorName = config.authorName;
29
29
  this.authorEmail = config.authorEmail;
30
- this.logger =
31
- config.logger || new Logger({ debug: false, prefix: "[GitManager]" });
30
+ this.logger = config.logger || new Logger({ debug: false, prefix: '[GitManager]' });
32
31
  }
33
32
 
34
33
  private escapeShellArg(str: string): string {
35
34
  return str
36
- .replace(/\\/g, "\\\\")
35
+ .replace(/\\/g, '\\\\')
37
36
  .replace(/"/g, '\\"')
38
- .replace(/`/g, "\\`")
39
- .replace(/\$/g, "\\$");
37
+ .replace(/`/g, '\\`')
38
+ .replace(/\$/g, '\\$');
40
39
  }
41
40
 
42
41
  private async runGitCommand(command: string): Promise<string> {
43
42
  try {
44
- const { stdout } = await execAsync(
45
- `cd "${this.repositoryPath}" && git ${command}`,
46
- );
43
+ const { stdout } = await execAsync(`cd "${this.repositoryPath}" && git ${command}`);
47
44
  return stdout.trim();
48
45
  } catch (error) {
49
46
  throw new Error(`Git command failed: ${command}\n${error}`);
@@ -52,9 +49,7 @@ export class GitManager {
52
49
 
53
50
  private async runCommand(command: string): Promise<string> {
54
51
  try {
55
- const { stdout } = await execAsync(
56
- `cd "${this.repositoryPath}" && ${command}`,
57
- );
52
+ const { stdout } = await execAsync(`cd "${this.repositoryPath}" && ${command}`);
58
53
  return stdout.trim();
59
54
  } catch (error) {
60
55
  throw new Error(`Command failed: ${command}\n${error}`);
@@ -63,7 +58,7 @@ export class GitManager {
63
58
 
64
59
  async isGitRepository(): Promise<boolean> {
65
60
  try {
66
- await this.runGitCommand("rev-parse --git-dir");
61
+ await this.runGitCommand('rev-parse --git-dir');
67
62
  return true;
68
63
  } catch {
69
64
  return false;
@@ -71,26 +66,22 @@ export class GitManager {
71
66
  }
72
67
 
73
68
  async getCurrentBranch(): Promise<string> {
74
- return await this.runGitCommand("branch --show-current");
69
+ return await this.runGitCommand('branch --show-current');
75
70
  }
76
71
 
77
72
  async getDefaultBranch(): Promise<string> {
78
73
  try {
79
74
  // Try to get the default branch from remote
80
- const remoteBranch = await this.runGitCommand(
81
- "symbolic-ref refs/remotes/origin/HEAD",
82
- );
83
- return remoteBranch.replace("refs/remotes/origin/", "");
75
+ const remoteBranch = await this.runGitCommand('symbolic-ref refs/remotes/origin/HEAD');
76
+ return remoteBranch.replace('refs/remotes/origin/', '');
84
77
  } catch {
85
78
  // Fallback: check if main exists, otherwise use master
86
- if (await this.branchExists("main")) {
87
- return "main";
88
- } else if (await this.branchExists("master")) {
89
- return "master";
79
+ if (await this.branchExists('main')) {
80
+ return 'main';
81
+ } else if (await this.branchExists('master')) {
82
+ return 'master';
90
83
  } else {
91
- throw new Error(
92
- "Cannot determine default branch. No main or master branch found.",
93
- );
84
+ throw new Error('Cannot determine default branch. No main or master branch found.');
94
85
  }
95
86
  }
96
87
  }
@@ -105,7 +96,7 @@ export class GitManager {
105
96
  }
106
97
 
107
98
  async createBranch(branchName: string, baseBranch?: string): Promise<void> {
108
- const base = baseBranch || (await this.getCurrentBranch());
99
+ const base = baseBranch || await this.getCurrentBranch();
109
100
  await this.runGitCommand(`checkout -b ${branchName} ${base}`);
110
101
  }
111
102
 
@@ -118,31 +109,25 @@ export class GitManager {
118
109
  const defaultBranch = await this.getDefaultBranch();
119
110
 
120
111
  if (currentBranch === defaultBranch) {
121
- this.logger.debug("Already on default branch", { branch: defaultBranch });
112
+ this.logger.debug('Already on default branch', { branch: defaultBranch });
122
113
  return true;
123
114
  }
124
115
 
125
116
  if (await this.hasChanges()) {
126
- this.logger.warn("Skipping branch reset - uncommitted changes present", {
117
+ this.logger.warn('Skipping branch reset - uncommitted changes present', {
127
118
  currentBranch,
128
- defaultBranch,
119
+ defaultBranch
129
120
  });
130
121
  return false;
131
122
  }
132
123
 
133
124
  await this.switchToBranch(defaultBranch);
134
- this.logger.info("Reset to default branch", {
135
- from: currentBranch,
136
- to: defaultBranch,
137
- });
125
+ this.logger.info('Reset to default branch', { from: currentBranch, to: defaultBranch });
138
126
  return true;
139
127
  }
140
128
 
141
- async createOrSwitchToBranch(
142
- branchName: string,
143
- baseBranch?: string,
144
- ): Promise<void> {
145
- await this.ensureCleanWorkingDirectory("switching branches");
129
+ async createOrSwitchToBranch(branchName: string, baseBranch?: string): Promise<void> {
130
+ await this.ensureCleanWorkingDirectory('switching branches');
146
131
 
147
132
  const exists = await this.branchExists(branchName);
148
133
  if (exists) {
@@ -153,41 +138,38 @@ export class GitManager {
153
138
  }
154
139
 
155
140
  async addFiles(paths: string[]): Promise<void> {
156
- const pathList = paths.map((p) => `"${this.escapeShellArg(p)}"`).join(" ");
141
+ const pathList = paths.map(p => `"${this.escapeShellArg(p)}"`).join(' ');
157
142
  await this.runGitCommand(`add ${pathList}`);
158
143
  }
159
144
 
160
145
  async addAllPostHogFiles(): Promise<void> {
161
146
  try {
162
147
  // Use -A flag to add all changes (including new files) and ignore errors if directory is empty
163
- await this.runGitCommand("add -A .posthog/");
148
+ await this.runGitCommand('add -A .posthog/');
164
149
  } catch (error) {
165
150
  // If the directory doesn't exist or has no files, that's fine - just log and continue
166
- this.logger.debug("No PostHog files to add", { error });
151
+ this.logger.debug('No PostHog files to add', { error });
167
152
  }
168
153
  }
169
154
 
170
- async commitChanges(
171
- message: string,
172
- options?: {
173
- authorName?: string;
174
- authorEmail?: string;
175
- },
176
- ): Promise<string> {
155
+ async commitChanges(message: string, options?: {
156
+ authorName?: string;
157
+ authorEmail?: string;
158
+ }): Promise<string> {
177
159
  const command = this.buildCommitCommand(message, options);
178
160
  return await this.runGitCommand(command);
179
161
  }
180
162
 
181
163
  async hasChanges(): Promise<boolean> {
182
164
  try {
183
- const status = await this.runGitCommand("status --porcelain");
165
+ const status = await this.runGitCommand('status --porcelain');
184
166
  if (!status || status.trim().length === 0) {
185
167
  return false;
186
168
  }
187
169
 
188
- const lines = status.split("\n").filter((line) => {
170
+ const lines = status.split('\n').filter(line => {
189
171
  const trimmed = line.trim();
190
- return trimmed.length > 0 && !trimmed.includes(".posthog/");
172
+ return trimmed.length > 0 && !trimmed.includes('.posthog/');
191
173
  });
192
174
 
193
175
  return lines.length > 0;
@@ -198,7 +180,7 @@ export class GitManager {
198
180
 
199
181
  async hasStagedChanges(): Promise<boolean> {
200
182
  try {
201
- const status = await this.runGitCommand("diff --cached --name-only");
183
+ const status = await this.runGitCommand('diff --cached --name-only');
202
184
  return status.length > 0;
203
185
  } catch {
204
186
  return false;
@@ -208,14 +190,12 @@ export class GitManager {
208
190
  // Helper: Centralized safety check for uncommitted changes
209
191
  private async ensureCleanWorkingDirectory(operation: string): Promise<void> {
210
192
  if (await this.hasChanges()) {
211
- throw new Error(
212
- `Uncommitted changes detected. Please commit or stash changes before ${operation}.`,
213
- );
193
+ throw new Error(`Uncommitted changes detected. Please commit or stash changes before ${operation}.`);
214
194
  }
215
195
  }
216
196
 
217
197
  private async generateUniqueBranchName(baseName: string): Promise<string> {
218
- if (!(await this.branchExists(baseName))) {
198
+ if (!await this.branchExists(baseName)) {
219
199
  return baseName;
220
200
  }
221
201
 
@@ -233,25 +213,18 @@ export class GitManager {
233
213
  const currentBranch = await this.getCurrentBranch();
234
214
 
235
215
  if (currentBranch !== defaultBranch) {
236
- await this.ensureCleanWorkingDirectory("switching to default branch");
216
+ await this.ensureCleanWorkingDirectory('switching to default branch');
237
217
  await this.switchToBranch(defaultBranch);
238
218
  }
239
219
 
240
220
  return defaultBranch;
241
221
  }
242
222
 
243
- private buildCommitCommand(
244
- message: string,
245
- options?: {
246
- allowEmpty?: boolean;
247
- authorName?: string;
248
- authorEmail?: string;
249
- },
250
- ): string {
223
+ private buildCommitCommand(message: string, options?: { allowEmpty?: boolean; authorName?: string; authorEmail?: string }): string {
251
224
  let command = `commit -m "${this.escapeShellArg(message)}"`;
252
225
 
253
226
  if (options?.allowEmpty) {
254
- command += " --allow-empty";
227
+ command += ' --allow-empty';
255
228
  }
256
229
 
257
230
  const authorName = options?.authorName || this.authorName;
@@ -266,14 +239,14 @@ export class GitManager {
266
239
 
267
240
  async getRemoteUrl(): Promise<string | null> {
268
241
  try {
269
- return await this.runGitCommand("remote get-url origin");
242
+ return await this.runGitCommand('remote get-url origin');
270
243
  } catch {
271
244
  return null;
272
245
  }
273
246
  }
274
247
 
275
248
  async pushBranch(branchName: string, force: boolean = false): Promise<void> {
276
- const forceFlag = force ? "--force" : "";
249
+ const forceFlag = force ? '--force' : '';
277
250
  await this.runGitCommand(`push ${forceFlag} -u origin ${branchName}`);
278
251
  }
279
252
 
@@ -292,11 +265,11 @@ export class GitManager {
292
265
  push?: boolean;
293
266
  }) => Promise<{ commitCreated: boolean; pushedBranch: boolean }>;
294
267
  }> {
295
- const initialSha = await this.getCommitSha("HEAD");
268
+ const initialSha = await this.getCommitSha('HEAD');
296
269
 
297
270
  return {
298
271
  finalize: async (options) => {
299
- const currentSha = await this.getCommitSha("HEAD");
272
+ const currentSha = await this.getCommitSha('HEAD');
300
273
  const externalCommitsCreated = initialSha !== currentSha;
301
274
  const hasUncommittedChanges = await this.hasChanges();
302
275
 
@@ -309,7 +282,7 @@ export class GitManager {
309
282
 
310
283
  // Commit any remaining uncommitted changes
311
284
  if (hasUncommittedChanges) {
312
- await this.runGitCommand("add .");
285
+ await this.runGitCommand('add .');
313
286
  const hasStagedChanges = await this.hasStagedChanges();
314
287
 
315
288
  if (hasStagedChanges) {
@@ -324,13 +297,11 @@ export class GitManager {
324
297
  const currentBranch = await this.getCurrentBranch();
325
298
  await this.pushBranch(currentBranch);
326
299
  pushedBranch = true;
327
- this.logger.info("Pushed branch after operation", {
328
- branch: currentBranch,
329
- });
300
+ this.logger.info('Pushed branch after operation', { branch: currentBranch });
330
301
  }
331
302
 
332
303
  return { commitCreated, pushedBranch };
333
- },
304
+ }
334
305
  };
335
306
  }
336
307
 
@@ -340,10 +311,10 @@ export class GitManager {
340
311
  // Ensure we're on default branch before creating task branch
341
312
  const defaultBranch = await this.ensureOnDefaultBranch();
342
313
 
343
- this.logger.info("Creating task branch from default branch", {
314
+ this.logger.info('Creating task branch from default branch', {
344
315
  branchName,
345
316
  taskSlug,
346
- baseBranch: defaultBranch,
317
+ baseBranch: defaultBranch
347
318
  });
348
319
 
349
320
  await this.createOrSwitchToBranch(branchName, defaultBranch);
@@ -351,35 +322,26 @@ export class GitManager {
351
322
  return branchName;
352
323
  }
353
324
 
354
- async createTaskPlanningBranch(
355
- taskId: string,
356
- baseBranch?: string,
357
- ): Promise<string> {
325
+ async createTaskPlanningBranch(taskId: string, baseBranch?: string): Promise<string> {
358
326
  const baseName = `posthog/task-${taskId}-planning`;
359
327
  const branchName = await this.generateUniqueBranchName(baseName);
360
328
 
361
- this.logger.debug("Creating unique planning branch", {
362
- branchName,
363
- taskId,
364
- });
329
+ this.logger.debug('Creating unique planning branch', { branchName, taskId });
365
330
 
366
- const base = baseBranch || (await this.ensureOnDefaultBranch());
331
+ const base = baseBranch || await this.ensureOnDefaultBranch();
367
332
  await this.createBranch(branchName, base);
368
333
 
369
334
  return branchName;
370
335
  }
371
336
 
372
- async createTaskImplementationBranch(
373
- taskId: string,
374
- planningBranchName?: string,
375
- ): Promise<string> {
337
+ async createTaskImplementationBranch(taskId: string, planningBranchName?: string): Promise<string> {
376
338
  const baseName = `posthog/task-${taskId}-implementation`;
377
339
  const branchName = await this.generateUniqueBranchName(baseName);
378
340
 
379
- this.logger.debug("Creating unique implementation branch", {
341
+ this.logger.debug('Creating unique implementation branch', {
380
342
  branchName,
381
343
  taskId,
382
- currentBranch: await this.getCurrentBranch(),
344
+ currentBranch: await this.getCurrentBranch()
383
345
  });
384
346
 
385
347
  // Determine base branch: explicit param > current planning branch > default
@@ -387,24 +349,21 @@ export class GitManager {
387
349
 
388
350
  if (!baseBranch) {
389
351
  const currentBranch = await this.getCurrentBranch();
390
- if (currentBranch.includes("-planning")) {
352
+ if (currentBranch.includes('-planning')) {
391
353
  baseBranch = currentBranch;
392
- this.logger.debug("Using current planning branch", { baseBranch });
354
+ this.logger.debug('Using current planning branch', { baseBranch });
393
355
  } else {
394
356
  baseBranch = await this.ensureOnDefaultBranch();
395
- this.logger.debug("Using default branch", { baseBranch });
357
+ this.logger.debug('Using default branch', { baseBranch });
396
358
  }
397
359
  }
398
360
 
399
- this.logger.debug("Creating implementation branch from base", {
400
- baseBranch,
401
- branchName,
402
- });
361
+ this.logger.debug('Creating implementation branch from base', { baseBranch, branchName });
403
362
  await this.createBranch(branchName, baseBranch);
404
363
 
405
- this.logger.info("Implementation branch created", {
364
+ this.logger.info('Implementation branch created', {
406
365
  branchName,
407
- currentBranch: await this.getCurrentBranch(),
366
+ currentBranch: await this.getCurrentBranch()
408
367
  });
409
368
 
410
369
  return branchName;
@@ -412,16 +371,16 @@ export class GitManager {
412
371
 
413
372
  async commitPlan(taskId: string, taskTitle: string): Promise<string> {
414
373
  const currentBranch = await this.getCurrentBranch();
415
- this.logger.debug("Committing plan", { taskId, currentBranch });
374
+ this.logger.debug('Committing plan', { taskId, currentBranch });
416
375
 
417
376
  await this.addAllPostHogFiles();
418
377
 
419
378
  const hasChanges = await this.hasStagedChanges();
420
- this.logger.debug("Checking for staged changes", { hasChanges });
379
+ this.logger.debug('Checking for staged changes', { hasChanges });
421
380
 
422
381
  if (!hasChanges) {
423
- this.logger.info("No plan changes to commit", { taskId });
424
- return "No changes to commit";
382
+ this.logger.info('No plan changes to commit', { taskId });
383
+ return 'No changes to commit';
425
384
  }
426
385
 
427
386
  const message = `📋 Add plan for task: ${taskTitle}
@@ -433,21 +392,17 @@ This commit contains the implementation plan and supporting documentation
433
392
  for the task. Review the plan before proceeding with implementation.`;
434
393
 
435
394
  const result = await this.commitChanges(message);
436
- this.logger.info("Plan committed", { taskId, taskTitle });
395
+ this.logger.info('Plan committed', { taskId, taskTitle });
437
396
  return result;
438
397
  }
439
398
 
440
- async commitImplementation(
441
- taskId: string,
442
- taskTitle: string,
443
- planSummary?: string,
444
- ): Promise<string> {
445
- await this.runGitCommand("add .");
399
+ async commitImplementation(taskId: string, taskTitle: string, planSummary?: string): Promise<string> {
400
+ await this.runGitCommand('add .');
446
401
 
447
402
  const hasChanges = await this.hasStagedChanges();
448
403
  if (!hasChanges) {
449
- this.logger.warn("No implementation changes to commit", { taskId });
450
- return "No changes to commit";
404
+ this.logger.warn('No implementation changes to commit', { taskId });
405
+ return 'No changes to commit';
451
406
  }
452
407
 
453
408
  let message = `✨ Implement task: ${taskTitle}
@@ -462,15 +417,12 @@ Generated by PostHog Agent`;
462
417
  message += `\n\nThis commit implements the changes described in the task plan.`;
463
418
 
464
419
  const result = await this.commitChanges(message);
465
- this.logger.info("Implementation committed", { taskId, taskTitle });
420
+ this.logger.info('Implementation committed', { taskId, taskTitle });
466
421
  return result;
467
422
  }
468
423
 
469
- async deleteBranch(
470
- branchName: string,
471
- force: boolean = false,
472
- ): Promise<void> {
473
- const forceFlag = force ? "-D" : "-d";
424
+ async deleteBranch(branchName: string, force: boolean = false): Promise<void> {
425
+ const forceFlag = force ? '-D' : '-d';
474
426
  await this.runGitCommand(`branch ${forceFlag} ${branchName}`);
475
427
  }
476
428
 
@@ -485,15 +437,15 @@ Generated by PostHog Agent`;
485
437
  return {
486
438
  name: branchName,
487
439
  exists,
488
- isCurrentBranch: branchName === currentBranch,
440
+ isCurrentBranch: branchName === currentBranch
489
441
  };
490
442
  }
491
443
 
492
- async getCommitSha(ref: string = "HEAD"): Promise<string> {
444
+ async getCommitSha(ref: string = 'HEAD'): Promise<string> {
493
445
  return await this.runGitCommand(`rev-parse ${ref}`);
494
446
  }
495
447
 
496
- async getCommitMessage(ref: string = "HEAD"): Promise<string> {
448
+ async getCommitMessage(ref: string = 'HEAD'): Promise<string> {
497
449
  return await this.runGitCommand(`log -1 --pretty=%B ${ref}`);
498
450
  }
499
451
 
@@ -501,11 +453,11 @@ Generated by PostHog Agent`;
501
453
  branchName: string,
502
454
  title: string,
503
455
  body: string,
504
- baseBranch?: string,
456
+ baseBranch?: string
505
457
  ): Promise<string> {
506
458
  const currentBranch = await this.getCurrentBranch();
507
459
  if (currentBranch !== branchName) {
508
- await this.ensureCleanWorkingDirectory("creating PR");
460
+ await this.ensureCleanWorkingDirectory('creating PR');
509
461
  await this.switchToBranch(branchName);
510
462
  }
511
463
 
@@ -528,35 +480,30 @@ Generated by PostHog Agent`;
528
480
  async getTaskBranch(taskSlug: string): Promise<string | null> {
529
481
  try {
530
482
  // Get all branches matching the task slug pattern
531
- const branches = await this.runGitCommand("branch --list --all");
483
+ const branches = await this.runGitCommand('branch --list --all');
532
484
  const branchPattern = `posthog/task-${taskSlug}`;
533
-
485
+
534
486
  // Look for exact match or with counter suffix
535
- const lines = branches
536
- .split("\n")
537
- .map((l) => l.trim().replace(/^\*\s+/, ""));
487
+ const lines = branches.split('\n').map(l => l.trim().replace(/^\*\s+/, ''));
538
488
  for (const line of lines) {
539
- const cleanBranch = line.replace("remotes/origin/", "");
489
+ const cleanBranch = line.replace('remotes/origin/', '');
540
490
  if (cleanBranch.startsWith(branchPattern)) {
541
491
  return cleanBranch;
542
492
  }
543
493
  }
544
-
494
+
545
495
  return null;
546
496
  } catch (error) {
547
- this.logger.debug("Failed to get task branch", { taskSlug, error });
497
+ this.logger.debug('Failed to get task branch', { taskSlug, error });
548
498
  return null;
549
499
  }
550
500
  }
551
501
 
552
- async commitAndPush(
553
- message: string,
554
- options?: { allowEmpty?: boolean },
555
- ): Promise<void> {
502
+ async commitAndPush(message: string, options?: { allowEmpty?: boolean }): Promise<void> {
556
503
  const hasChanges = await this.hasStagedChanges();
557
504
 
558
505
  if (!hasChanges && !options?.allowEmpty) {
559
- this.logger.debug("No changes to commit, skipping");
506
+ this.logger.debug('No changes to commit, skipping');
560
507
  return;
561
508
  }
562
509
 
@@ -567,9 +514,6 @@ Generated by PostHog Agent`;
567
514
  const currentBranch = await this.getCurrentBranch();
568
515
  await this.pushBranch(currentBranch);
569
516
 
570
- this.logger.info("Committed and pushed changes", {
571
- branch: currentBranch,
572
- message,
573
- });
517
+ this.logger.info('Committed and pushed changes', { branch: currentBranch, message });
574
518
  }
575
519
  }