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