ghcralph 0.1.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/LICENSE +21 -0
- package/README.md +327 -0
- package/bin/ghcralph.js +2 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +92 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/config.d.ts +8 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +118 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/index.d.ts +11 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +11 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +15 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +116 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/rollback.d.ts +8 -0
- package/dist/commands/rollback.d.ts.map +1 -0
- package/dist/commands/rollback.js +238 -0
- package/dist/commands/rollback.js.map +1 -0
- package/dist/commands/run.d.ts +28 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +407 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/status.d.ts +8 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +399 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/core/action-executor.d.ts +96 -0
- package/dist/core/action-executor.d.ts.map +1 -0
- package/dist/core/action-executor.js +289 -0
- package/dist/core/action-executor.js.map +1 -0
- package/dist/core/checkpoint-manager.d.ts +94 -0
- package/dist/core/checkpoint-manager.d.ts.map +1 -0
- package/dist/core/checkpoint-manager.js +236 -0
- package/dist/core/checkpoint-manager.js.map +1 -0
- package/dist/core/config-manager.d.ts +62 -0
- package/dist/core/config-manager.d.ts.map +1 -0
- package/dist/core/config-manager.js +184 -0
- package/dist/core/config-manager.js.map +1 -0
- package/dist/core/config-schema.d.ts +74 -0
- package/dist/core/config-schema.d.ts.map +1 -0
- package/dist/core/config-schema.js +84 -0
- package/dist/core/config-schema.js.map +1 -0
- package/dist/core/context-builder.d.ts +116 -0
- package/dist/core/context-builder.d.ts.map +1 -0
- package/dist/core/context-builder.js +388 -0
- package/dist/core/context-builder.js.map +1 -0
- package/dist/core/feedback-builder.d.ts +94 -0
- package/dist/core/feedback-builder.d.ts.map +1 -0
- package/dist/core/feedback-builder.js +226 -0
- package/dist/core/feedback-builder.js.map +1 -0
- package/dist/core/file-safeguard.d.ts +109 -0
- package/dist/core/file-safeguard.d.ts.map +1 -0
- package/dist/core/file-safeguard.js +200 -0
- package/dist/core/file-safeguard.js.map +1 -0
- package/dist/core/git-branch-manager.d.ts +122 -0
- package/dist/core/git-branch-manager.d.ts.map +1 -0
- package/dist/core/git-branch-manager.js +302 -0
- package/dist/core/git-branch-manager.js.map +1 -0
- package/dist/core/github-plan.d.ts +86 -0
- package/dist/core/github-plan.d.ts.map +1 -0
- package/dist/core/github-plan.js +333 -0
- package/dist/core/github-plan.js.map +1 -0
- package/dist/core/index.d.ts +43 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +26 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/local-markdown-plan.d.ts +65 -0
- package/dist/core/local-markdown-plan.d.ts.map +1 -0
- package/dist/core/local-markdown-plan.js +154 -0
- package/dist/core/local-markdown-plan.js.map +1 -0
- package/dist/core/loop-engine.d.ts +133 -0
- package/dist/core/loop-engine.d.ts.map +1 -0
- package/dist/core/loop-engine.js +420 -0
- package/dist/core/loop-engine.js.map +1 -0
- package/dist/core/loop-events.d.ts +48 -0
- package/dist/core/loop-events.d.ts.map +1 -0
- package/dist/core/loop-events.js +24 -0
- package/dist/core/loop-events.js.map +1 -0
- package/dist/core/loop-state.d.ts +51 -0
- package/dist/core/loop-state.d.ts.map +1 -0
- package/dist/core/loop-state.js +48 -0
- package/dist/core/loop-state.js.map +1 -0
- package/dist/core/markdown-parser.d.ts +51 -0
- package/dist/core/markdown-parser.d.ts.map +1 -0
- package/dist/core/markdown-parser.js +122 -0
- package/dist/core/markdown-parser.js.map +1 -0
- package/dist/core/plan-manager.d.ts +61 -0
- package/dist/core/plan-manager.d.ts.map +1 -0
- package/dist/core/plan-manager.js +7 -0
- package/dist/core/plan-manager.js.map +1 -0
- package/dist/core/progress-tracker.d.ts +74 -0
- package/dist/core/progress-tracker.d.ts.map +1 -0
- package/dist/core/progress-tracker.js +198 -0
- package/dist/core/progress-tracker.js.map +1 -0
- package/dist/core/prompt-examples.d.ts +52 -0
- package/dist/core/prompt-examples.d.ts.map +1 -0
- package/dist/core/prompt-examples.js +194 -0
- package/dist/core/prompt-examples.js.map +1 -0
- package/dist/core/response-parser.d.ts +90 -0
- package/dist/core/response-parser.d.ts.map +1 -0
- package/dist/core/response-parser.js +209 -0
- package/dist/core/response-parser.js.map +1 -0
- package/dist/core/verification-hooks.d.ts +103 -0
- package/dist/core/verification-hooks.d.ts.map +1 -0
- package/dist/core/verification-hooks.js +268 -0
- package/dist/core/verification-hooks.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/auth.d.ts +28 -0
- package/dist/integrations/auth.d.ts.map +1 -0
- package/dist/integrations/auth.js +76 -0
- package/dist/integrations/auth.js.map +1 -0
- package/dist/integrations/copilot-agent.d.ts +104 -0
- package/dist/integrations/copilot-agent.d.ts.map +1 -0
- package/dist/integrations/copilot-agent.js +235 -0
- package/dist/integrations/copilot-agent.js.map +1 -0
- package/dist/integrations/index.d.ts +18 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +14 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/mcp-tools.d.ts +129 -0
- package/dist/integrations/mcp-tools.d.ts.map +1 -0
- package/dist/integrations/mcp-tools.js +272 -0
- package/dist/integrations/mcp-tools.js.map +1 -0
- package/dist/integrations/tokens.d.ts +45 -0
- package/dist/integrations/tokens.d.ts.map +1 -0
- package/dist/integrations/tokens.js +50 -0
- package/dist/integrations/tokens.js.map +1 -0
- package/dist/types/index.d.ts +53 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/index.d.ts +23 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +37 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/output.d.ts +59 -0
- package/dist/utils/output.d.ts.map +1 -0
- package/dist/utils/output.js +96 -0
- package/dist/utils/output.js.map +1 -0
- package/dist/utils/paths.d.ts +34 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +67 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/shell.d.ts +26 -0
- package/dist/utils/shell.d.ts.map +1 -0
- package/dist/utils/shell.js +65 -0
- package/dist/utils/shell.js.map +1 -0
- package/dist/utils/validation.d.ts +27 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +43 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Action Executor
|
|
3
|
+
*
|
|
4
|
+
* Executes parsed actions from AI responses.
|
|
5
|
+
* This component bridges the gap between AI intent and filesystem reality.
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'node:fs/promises';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import { exec } from 'node:child_process';
|
|
10
|
+
import { promisify } from 'node:util';
|
|
11
|
+
import { debug, info, warn } from '../utils/index.js';
|
|
12
|
+
const execAsync = promisify(exec);
|
|
13
|
+
const DEFAULT_CONFIG = {
|
|
14
|
+
cwd: process.cwd(),
|
|
15
|
+
execute: true,
|
|
16
|
+
commandTimeout: 30000, // 30 seconds
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Action Executor class
|
|
20
|
+
*/
|
|
21
|
+
export class ActionExecutor {
|
|
22
|
+
config;
|
|
23
|
+
constructor(config = {}) {
|
|
24
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Execute all actions from a parsed response
|
|
28
|
+
*/
|
|
29
|
+
async executeAll(parseResult) {
|
|
30
|
+
const results = [];
|
|
31
|
+
let taskComplete = false;
|
|
32
|
+
let completionReason;
|
|
33
|
+
for (const action of parseResult.actions) {
|
|
34
|
+
const result = await this.executeAction(action);
|
|
35
|
+
results.push(result);
|
|
36
|
+
if (action.type === 'COMPLETE' && result.success) {
|
|
37
|
+
taskComplete = true;
|
|
38
|
+
completionReason = action.reason;
|
|
39
|
+
}
|
|
40
|
+
// Stop on first failure (except for COMPLETE which is informational)
|
|
41
|
+
if (!result.success && action.type !== 'COMPLETE') {
|
|
42
|
+
warn(`Action failed: ${result.error}`);
|
|
43
|
+
// Continue with remaining actions? For now, we'll continue
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const allSucceeded = results.every((r) => r.success);
|
|
47
|
+
const summary = this.buildSummary(results);
|
|
48
|
+
const executionResult = {
|
|
49
|
+
results,
|
|
50
|
+
allSucceeded,
|
|
51
|
+
taskComplete,
|
|
52
|
+
summary,
|
|
53
|
+
};
|
|
54
|
+
if (completionReason) {
|
|
55
|
+
executionResult.completionReason = completionReason;
|
|
56
|
+
}
|
|
57
|
+
return executionResult;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Execute a single action
|
|
61
|
+
*/
|
|
62
|
+
async executeAction(action) {
|
|
63
|
+
debug(`Executing action: ${action.type}`);
|
|
64
|
+
if (!this.config.execute) {
|
|
65
|
+
return {
|
|
66
|
+
action,
|
|
67
|
+
success: true,
|
|
68
|
+
message: `[DRY RUN] Would execute ${action.type}`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
switch (action.type) {
|
|
73
|
+
case 'CREATE':
|
|
74
|
+
return await this.executeCreate(action);
|
|
75
|
+
case 'EDIT':
|
|
76
|
+
return await this.executeEdit(action);
|
|
77
|
+
case 'DELETE':
|
|
78
|
+
return await this.executeDelete(action);
|
|
79
|
+
case 'EXECUTE':
|
|
80
|
+
return await this.executeCommand(action);
|
|
81
|
+
case 'COMPLETE':
|
|
82
|
+
return this.executeComplete(action);
|
|
83
|
+
default:
|
|
84
|
+
return {
|
|
85
|
+
action,
|
|
86
|
+
success: false,
|
|
87
|
+
message: `Unknown action type`,
|
|
88
|
+
error: `Unknown action type: ${action.type}`,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
94
|
+
return {
|
|
95
|
+
action,
|
|
96
|
+
success: false,
|
|
97
|
+
message: `Failed to execute ${action.type}`,
|
|
98
|
+
error: errorMsg,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Execute a CREATE action
|
|
104
|
+
*/
|
|
105
|
+
async executeCreate(action) {
|
|
106
|
+
const fullPath = path.resolve(this.config.cwd, action.path);
|
|
107
|
+
// Security: ensure path is within cwd
|
|
108
|
+
if (!fullPath.startsWith(this.config.cwd)) {
|
|
109
|
+
return {
|
|
110
|
+
action,
|
|
111
|
+
success: false,
|
|
112
|
+
message: `Cannot create file outside working directory`,
|
|
113
|
+
error: `Path escapes working directory: ${action.path}`,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// Create parent directories if needed
|
|
117
|
+
const dir = path.dirname(fullPath);
|
|
118
|
+
await fs.mkdir(dir, { recursive: true });
|
|
119
|
+
// Write the file
|
|
120
|
+
await fs.writeFile(fullPath, action.content, 'utf-8');
|
|
121
|
+
// Make executable if it's a script
|
|
122
|
+
if (action.path.endsWith('.sh') || action.content.startsWith('#!/')) {
|
|
123
|
+
await fs.chmod(fullPath, 0o755);
|
|
124
|
+
}
|
|
125
|
+
info(`Created: ${action.path}`);
|
|
126
|
+
return {
|
|
127
|
+
action,
|
|
128
|
+
success: true,
|
|
129
|
+
message: `Created ${action.path}`,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Execute an EDIT action
|
|
134
|
+
*/
|
|
135
|
+
async executeEdit(action) {
|
|
136
|
+
const fullPath = path.resolve(this.config.cwd, action.path);
|
|
137
|
+
// Security: ensure path is within cwd
|
|
138
|
+
if (!fullPath.startsWith(this.config.cwd)) {
|
|
139
|
+
return {
|
|
140
|
+
action,
|
|
141
|
+
success: false,
|
|
142
|
+
message: `Cannot edit file outside working directory`,
|
|
143
|
+
error: `Path escapes working directory: ${action.path}`,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
// Read current content
|
|
147
|
+
let content;
|
|
148
|
+
try {
|
|
149
|
+
content = await fs.readFile(fullPath, 'utf-8');
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return {
|
|
153
|
+
action,
|
|
154
|
+
success: false,
|
|
155
|
+
message: `File not found: ${action.path}`,
|
|
156
|
+
error: `Cannot edit non-existent file: ${action.path}`,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
// Find and replace the old content
|
|
160
|
+
if (!content.includes(action.oldContent)) {
|
|
161
|
+
return {
|
|
162
|
+
action,
|
|
163
|
+
success: false,
|
|
164
|
+
message: `Old content not found in ${action.path}`,
|
|
165
|
+
error: `The specified old content was not found in the file`,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
const newFileContent = content.replace(action.oldContent, action.newContent);
|
|
169
|
+
await fs.writeFile(fullPath, newFileContent, 'utf-8');
|
|
170
|
+
info(`Edited: ${action.path}`);
|
|
171
|
+
return {
|
|
172
|
+
action,
|
|
173
|
+
success: true,
|
|
174
|
+
message: `Edited ${action.path}`,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Execute a DELETE action
|
|
179
|
+
*/
|
|
180
|
+
async executeDelete(action) {
|
|
181
|
+
const fullPath = path.resolve(this.config.cwd, action.path);
|
|
182
|
+
// Security: ensure path is within cwd
|
|
183
|
+
if (!fullPath.startsWith(this.config.cwd)) {
|
|
184
|
+
return {
|
|
185
|
+
action,
|
|
186
|
+
success: false,
|
|
187
|
+
message: `Cannot delete file outside working directory`,
|
|
188
|
+
error: `Path escapes working directory: ${action.path}`,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
// Check file safeguard
|
|
192
|
+
if (this.config.fileSafeguard && !this.config.fileSafeguard.canDelete(action.path)) {
|
|
193
|
+
return {
|
|
194
|
+
action,
|
|
195
|
+
success: false,
|
|
196
|
+
message: `Cannot delete protected file: ${action.path}`,
|
|
197
|
+
error: `File is protected by safeguard (existed before session)`,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
// Check if file exists
|
|
201
|
+
try {
|
|
202
|
+
await fs.access(fullPath);
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
return {
|
|
206
|
+
action,
|
|
207
|
+
success: false,
|
|
208
|
+
message: `File not found: ${action.path}`,
|
|
209
|
+
error: `Cannot delete non-existent file`,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
await fs.unlink(fullPath);
|
|
213
|
+
info(`Deleted: ${action.path}`);
|
|
214
|
+
return {
|
|
215
|
+
action,
|
|
216
|
+
success: true,
|
|
217
|
+
message: `Deleted ${action.path}`,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Execute an EXECUTE action (shell command)
|
|
222
|
+
*/
|
|
223
|
+
async executeCommand(action) {
|
|
224
|
+
info(`Executing: ${action.command}`);
|
|
225
|
+
try {
|
|
226
|
+
const { stdout, stderr } = await execAsync(action.command, {
|
|
227
|
+
cwd: this.config.cwd,
|
|
228
|
+
timeout: this.config.commandTimeout,
|
|
229
|
+
maxBuffer: 1024 * 1024, // 1MB
|
|
230
|
+
});
|
|
231
|
+
const output = stdout + (stderr ? `\nSTDERR:\n${stderr}` : '');
|
|
232
|
+
return {
|
|
233
|
+
action,
|
|
234
|
+
success: true,
|
|
235
|
+
message: `Executed: ${action.command}`,
|
|
236
|
+
output: output.trim(),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
const execError = err;
|
|
241
|
+
const output = (execError.stdout ?? '') + (execError.stderr ? `\nSTDERR:\n${execError.stderr}` : '');
|
|
242
|
+
return {
|
|
243
|
+
action,
|
|
244
|
+
success: false,
|
|
245
|
+
message: `Command failed: ${action.command}`,
|
|
246
|
+
output: output.trim(),
|
|
247
|
+
error: execError.message ?? 'Command execution failed',
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Execute a COMPLETE action (just marks completion)
|
|
253
|
+
*/
|
|
254
|
+
executeComplete(action) {
|
|
255
|
+
info(`Task complete: ${action.reason}`);
|
|
256
|
+
return {
|
|
257
|
+
action,
|
|
258
|
+
success: true,
|
|
259
|
+
message: `Task marked complete: ${action.reason}`,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Build a human-readable summary of executed actions
|
|
264
|
+
*/
|
|
265
|
+
buildSummary(results) {
|
|
266
|
+
const parts = [];
|
|
267
|
+
const succeeded = results.filter((r) => r.success);
|
|
268
|
+
const failed = results.filter((r) => !r.success);
|
|
269
|
+
for (const result of succeeded) {
|
|
270
|
+
const icon = '✓';
|
|
271
|
+
parts.push(`${icon} ${result.message}`);
|
|
272
|
+
}
|
|
273
|
+
for (const result of failed) {
|
|
274
|
+
const icon = '✗';
|
|
275
|
+
parts.push(`${icon} ${result.message}: ${result.error}`);
|
|
276
|
+
}
|
|
277
|
+
if (parts.length === 0) {
|
|
278
|
+
return 'No actions executed';
|
|
279
|
+
}
|
|
280
|
+
return parts.join('\n');
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Create an action executor with custom configuration
|
|
285
|
+
*/
|
|
286
|
+
export function createActionExecutor(config) {
|
|
287
|
+
return new ActionExecutor(config);
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=action-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-executor.js","sourceRoot":"","sources":["../../src/core/action-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkpoint Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages automatic git commits after each loop iteration
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Checkpoint configuration
|
|
8
|
+
*/
|
|
9
|
+
export interface CheckpointConfig {
|
|
10
|
+
/** Whether to auto-commit after each iteration (default: true) */
|
|
11
|
+
autoCommit: boolean;
|
|
12
|
+
/** Prefix for commit messages (default: 'ghcralph:') */
|
|
13
|
+
messagePrefix: string;
|
|
14
|
+
/** Working directory */
|
|
15
|
+
cwd: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Checkpoint record
|
|
19
|
+
*/
|
|
20
|
+
export interface Checkpoint {
|
|
21
|
+
/** Iteration number */
|
|
22
|
+
iteration: number;
|
|
23
|
+
/** Commit hash */
|
|
24
|
+
commitHash: string;
|
|
25
|
+
/** Commit message */
|
|
26
|
+
message: string;
|
|
27
|
+
/** Files modified in this commit */
|
|
28
|
+
filesModified: string[];
|
|
29
|
+
/** Timestamp of the commit */
|
|
30
|
+
timestamp: Date;
|
|
31
|
+
/** Token usage for the iteration */
|
|
32
|
+
tokensUsed: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Checkpoint Manager class
|
|
36
|
+
*/
|
|
37
|
+
export declare class CheckpointManager {
|
|
38
|
+
private config;
|
|
39
|
+
private checkpoints;
|
|
40
|
+
constructor(config?: Partial<CheckpointConfig>);
|
|
41
|
+
/**
|
|
42
|
+
* Check if auto-commit is enabled
|
|
43
|
+
*/
|
|
44
|
+
isAutoCommitEnabled(): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Get all checkpoints
|
|
47
|
+
*/
|
|
48
|
+
getCheckpoints(): Checkpoint[];
|
|
49
|
+
/**
|
|
50
|
+
* Get the last checkpoint
|
|
51
|
+
*/
|
|
52
|
+
getLastCheckpoint(): Checkpoint | null;
|
|
53
|
+
/**
|
|
54
|
+
* Check if there are any modified files to commit
|
|
55
|
+
*/
|
|
56
|
+
hasChangesToCommit(): Promise<boolean>;
|
|
57
|
+
/**
|
|
58
|
+
* Get list of modified files
|
|
59
|
+
*/
|
|
60
|
+
getModifiedFiles(): Promise<string[]>;
|
|
61
|
+
/**
|
|
62
|
+
* Stage all modified files
|
|
63
|
+
*/
|
|
64
|
+
stageAllChanges(): Promise<boolean>;
|
|
65
|
+
/**
|
|
66
|
+
* Create a checkpoint commit
|
|
67
|
+
*/
|
|
68
|
+
createCheckpoint(iteration: number, summary: string, tokensUsed: number): Promise<Checkpoint | null>;
|
|
69
|
+
/**
|
|
70
|
+
* Rollback to a specific checkpoint
|
|
71
|
+
*/
|
|
72
|
+
rollbackTo(commitHash: string): Promise<boolean>;
|
|
73
|
+
/**
|
|
74
|
+
* Hard rollback to a specific checkpoint (discard changes)
|
|
75
|
+
*/
|
|
76
|
+
hardRollbackTo(commitHash: string): Promise<boolean>;
|
|
77
|
+
/**
|
|
78
|
+
* Rollback by N iterations
|
|
79
|
+
*/
|
|
80
|
+
rollbackIterations(count?: number): Promise<boolean>;
|
|
81
|
+
/**
|
|
82
|
+
* Get the initial commit hash before Ralph started
|
|
83
|
+
*/
|
|
84
|
+
getInitialCommit(): Promise<string | null>;
|
|
85
|
+
/**
|
|
86
|
+
* Rollback all Ralph changes (to state before Ralph started)
|
|
87
|
+
*/
|
|
88
|
+
rollbackAll(): Promise<boolean>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create a checkpoint manager with configuration
|
|
92
|
+
*/
|
|
93
|
+
export declare function createCheckpointManager(config?: Partial<CheckpointConfig>): CheckpointManager;
|
|
94
|
+
//# sourceMappingURL=checkpoint-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-manager.d.ts","sourceRoot":"","sources":["../../src/core/checkpoint-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,UAAU,EAAE,OAAO,CAAC;IACpB,wDAAwD;IACxD,aAAa,EAAE,MAAM,CAAC;IACtB,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAC;CACb;AAWD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,uBAAuB;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,8BAA8B;IAC9B,SAAS,EAAE,IAAI,CAAC;IAChB,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,WAAW,CAAoB;gBAE3B,MAAM,GAAE,OAAO,CAAC,gBAAgB,CAAM;IAIlD;;OAEG;IACH,mBAAmB,IAAI,OAAO;IAI9B;;OAEG;IACH,cAAc,IAAI,UAAU,EAAE;IAI9B;;OAEG;IACH,iBAAiB,IAAI,UAAU,GAAG,IAAI;IAQtC;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC;IAS5C;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAa3C;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAWzC;;OAEG;IACG,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAyD7B;;OAEG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYtD;;OAEG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW1D;;OAEG;IACG,kBAAkB,CAAC,KAAK,GAAE,MAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IA8B7D;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAgBhD;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;CAStC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,iBAAiB,CAE7F"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkpoint Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages automatic git commits after each loop iteration
|
|
5
|
+
*/
|
|
6
|
+
import { exec } from 'node:child_process';
|
|
7
|
+
import { promisify } from 'node:util';
|
|
8
|
+
import { debug, warn } from '../utils/index.js';
|
|
9
|
+
const execAsync = promisify(exec);
|
|
10
|
+
/**
|
|
11
|
+
* Default configuration
|
|
12
|
+
*/
|
|
13
|
+
const DEFAULT_CONFIG = {
|
|
14
|
+
autoCommit: true,
|
|
15
|
+
messagePrefix: 'ghcralph:',
|
|
16
|
+
cwd: process.cwd(),
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Checkpoint Manager class
|
|
20
|
+
*/
|
|
21
|
+
export class CheckpointManager {
|
|
22
|
+
config;
|
|
23
|
+
checkpoints = [];
|
|
24
|
+
constructor(config = {}) {
|
|
25
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Check if auto-commit is enabled
|
|
29
|
+
*/
|
|
30
|
+
isAutoCommitEnabled() {
|
|
31
|
+
return this.config.autoCommit;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get all checkpoints
|
|
35
|
+
*/
|
|
36
|
+
getCheckpoints() {
|
|
37
|
+
return [...this.checkpoints];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get the last checkpoint
|
|
41
|
+
*/
|
|
42
|
+
getLastCheckpoint() {
|
|
43
|
+
if (this.checkpoints.length === 0) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const last = this.checkpoints[this.checkpoints.length - 1];
|
|
47
|
+
return last ?? null;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Check if there are any modified files to commit
|
|
51
|
+
*/
|
|
52
|
+
async hasChangesToCommit() {
|
|
53
|
+
try {
|
|
54
|
+
const { stdout } = await execAsync('git status --porcelain', { cwd: this.config.cwd });
|
|
55
|
+
return stdout.trim().length > 0;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get list of modified files
|
|
63
|
+
*/
|
|
64
|
+
async getModifiedFiles() {
|
|
65
|
+
try {
|
|
66
|
+
const { stdout } = await execAsync('git status --porcelain', { cwd: this.config.cwd });
|
|
67
|
+
return stdout
|
|
68
|
+
.trim()
|
|
69
|
+
.split('\n')
|
|
70
|
+
.filter(Boolean)
|
|
71
|
+
.map(line => line.substring(3).trim());
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Stage all modified files
|
|
79
|
+
*/
|
|
80
|
+
async stageAllChanges() {
|
|
81
|
+
try {
|
|
82
|
+
await execAsync('git add -A', { cwd: this.config.cwd });
|
|
83
|
+
debug('Staged all changes');
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
warn('Failed to stage changes: ' + (err instanceof Error ? err.message : String(err)));
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Create a checkpoint commit
|
|
93
|
+
*/
|
|
94
|
+
async createCheckpoint(iteration, summary, tokensUsed) {
|
|
95
|
+
if (!this.config.autoCommit) {
|
|
96
|
+
debug('Auto-commit disabled, skipping checkpoint');
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
// Check if there are changes to commit
|
|
100
|
+
const hasChanges = await this.hasChangesToCommit();
|
|
101
|
+
if (!hasChanges) {
|
|
102
|
+
debug('No changes to commit for checkpoint');
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
// Get list of modified files before staging
|
|
106
|
+
const filesModified = await this.getModifiedFiles();
|
|
107
|
+
// Stage all changes
|
|
108
|
+
const staged = await this.stageAllChanges();
|
|
109
|
+
if (!staged) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
// Build commit message
|
|
113
|
+
const truncatedSummary = summary.length > 50
|
|
114
|
+
? summary.substring(0, 47) + '...'
|
|
115
|
+
: summary;
|
|
116
|
+
const message = `${this.config.messagePrefix} iteration ${iteration} - ${truncatedSummary}`;
|
|
117
|
+
const fullMessage = `${message}\n\nTokens used: ${tokensUsed}\nFiles modified: ${filesModified.length}`;
|
|
118
|
+
try {
|
|
119
|
+
// Create commit
|
|
120
|
+
await execAsync(`git commit -m "${fullMessage.replace(/"/g, '\\"')}"`, { cwd: this.config.cwd });
|
|
121
|
+
// Get commit hash
|
|
122
|
+
const { stdout } = await execAsync('git rev-parse HEAD', { cwd: this.config.cwd });
|
|
123
|
+
const commitHash = stdout.trim();
|
|
124
|
+
const checkpoint = {
|
|
125
|
+
iteration,
|
|
126
|
+
commitHash,
|
|
127
|
+
message,
|
|
128
|
+
filesModified,
|
|
129
|
+
timestamp: new Date(),
|
|
130
|
+
tokensUsed,
|
|
131
|
+
};
|
|
132
|
+
this.checkpoints.push(checkpoint);
|
|
133
|
+
debug(`Created checkpoint: ${commitHash.substring(0, 7)} - ${message}`);
|
|
134
|
+
return checkpoint;
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
warn('Failed to create checkpoint commit: ' + (err instanceof Error ? err.message : String(err)));
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Rollback to a specific checkpoint
|
|
143
|
+
*/
|
|
144
|
+
async rollbackTo(commitHash) {
|
|
145
|
+
try {
|
|
146
|
+
// Soft reset to keep changes in working directory for review
|
|
147
|
+
await execAsync(`git reset --soft "${commitHash}"`, { cwd: this.config.cwd });
|
|
148
|
+
debug(`Rolled back to ${commitHash.substring(0, 7)}`);
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
warn('Failed to rollback: ' + (err instanceof Error ? err.message : String(err)));
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Hard rollback to a specific checkpoint (discard changes)
|
|
158
|
+
*/
|
|
159
|
+
async hardRollbackTo(commitHash) {
|
|
160
|
+
try {
|
|
161
|
+
await execAsync(`git reset --hard "${commitHash}"`, { cwd: this.config.cwd });
|
|
162
|
+
debug(`Hard rolled back to ${commitHash.substring(0, 7)}`);
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
warn('Failed to hard rollback: ' + (err instanceof Error ? err.message : String(err)));
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Rollback by N iterations
|
|
172
|
+
*/
|
|
173
|
+
async rollbackIterations(count = 1) {
|
|
174
|
+
if (this.checkpoints.length < count) {
|
|
175
|
+
warn(`Cannot rollback ${count} iterations, only ${this.checkpoints.length} checkpoints available`);
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
// Get the checkpoint to rollback to
|
|
179
|
+
const targetIndex = this.checkpoints.length - count - 1;
|
|
180
|
+
if (targetIndex < 0) {
|
|
181
|
+
// Rollback before first checkpoint - get parent of first checkpoint
|
|
182
|
+
const firstCheckpoint = this.checkpoints[0];
|
|
183
|
+
if (!firstCheckpoint)
|
|
184
|
+
return false;
|
|
185
|
+
try {
|
|
186
|
+
const { stdout } = await execAsync(`git rev-parse "${firstCheckpoint.commitHash}^"`, { cwd: this.config.cwd });
|
|
187
|
+
const parentHash = stdout.trim();
|
|
188
|
+
return this.hardRollbackTo(parentHash);
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
warn('Cannot find parent commit for rollback');
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const targetCheckpoint = this.checkpoints[targetIndex];
|
|
196
|
+
if (!targetCheckpoint)
|
|
197
|
+
return false;
|
|
198
|
+
return this.hardRollbackTo(targetCheckpoint.commitHash);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Get the initial commit hash before Ralph started
|
|
202
|
+
*/
|
|
203
|
+
async getInitialCommit() {
|
|
204
|
+
if (this.checkpoints.length === 0) {
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
const firstCheckpoint = this.checkpoints[0];
|
|
208
|
+
if (!firstCheckpoint)
|
|
209
|
+
return null;
|
|
210
|
+
try {
|
|
211
|
+
const { stdout } = await execAsync(`git rev-parse "${firstCheckpoint.commitHash}^"`, { cwd: this.config.cwd });
|
|
212
|
+
return stdout.trim();
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Rollback all Ralph changes (to state before Ralph started)
|
|
220
|
+
*/
|
|
221
|
+
async rollbackAll() {
|
|
222
|
+
const initialCommit = await this.getInitialCommit();
|
|
223
|
+
if (!initialCommit) {
|
|
224
|
+
warn('No checkpoints to rollback');
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
return this.hardRollbackTo(initialCommit);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Create a checkpoint manager with configuration
|
|
232
|
+
*/
|
|
233
|
+
export function createCheckpointManager(config) {
|
|
234
|
+
return new CheckpointManager(config);
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=checkpoint-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-manager.js","sourceRoot":"","sources":["../../src/core/checkpoint-manager.ts"],"names":[],"mappings":"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"}
|