codeep 1.0.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 +201 -0
- package/README.md +576 -0
- package/dist/api/index.d.ts +8 -0
- package/dist/api/index.js +421 -0
- package/dist/app.d.ts +2 -0
- package/dist/app.js +1406 -0
- package/dist/components/AgentProgress.d.ts +33 -0
- package/dist/components/AgentProgress.js +97 -0
- package/dist/components/Export.d.ts +8 -0
- package/dist/components/Export.js +27 -0
- package/dist/components/Help.d.ts +2 -0
- package/dist/components/Help.js +3 -0
- package/dist/components/Input.d.ts +9 -0
- package/dist/components/Input.js +89 -0
- package/dist/components/Loading.d.ts +9 -0
- package/dist/components/Loading.js +31 -0
- package/dist/components/Login.d.ts +7 -0
- package/dist/components/Login.js +77 -0
- package/dist/components/Logo.d.ts +8 -0
- package/dist/components/Logo.js +89 -0
- package/dist/components/LogoutPicker.d.ts +8 -0
- package/dist/components/LogoutPicker.js +61 -0
- package/dist/components/Message.d.ts +10 -0
- package/dist/components/Message.js +234 -0
- package/dist/components/MessageList.d.ts +10 -0
- package/dist/components/MessageList.js +8 -0
- package/dist/components/ProjectPermission.d.ts +7 -0
- package/dist/components/ProjectPermission.js +52 -0
- package/dist/components/Search.d.ts +10 -0
- package/dist/components/Search.js +30 -0
- package/dist/components/SessionPicker.d.ts +9 -0
- package/dist/components/SessionPicker.js +88 -0
- package/dist/components/Sessions.d.ts +12 -0
- package/dist/components/Sessions.js +102 -0
- package/dist/components/Settings.d.ts +7 -0
- package/dist/components/Settings.js +162 -0
- package/dist/components/Status.d.ts +2 -0
- package/dist/components/Status.js +12 -0
- package/dist/config/config.test.d.ts +1 -0
- package/dist/config/config.test.js +157 -0
- package/dist/config/index.d.ts +121 -0
- package/dist/config/index.js +555 -0
- package/dist/config/providers.d.ts +43 -0
- package/dist/config/providers.js +82 -0
- package/dist/config/providers.test.d.ts +1 -0
- package/dist/config/providers.test.js +132 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +38 -0
- package/dist/utils/agent.d.ts +37 -0
- package/dist/utils/agent.js +627 -0
- package/dist/utils/codeReview.d.ts +36 -0
- package/dist/utils/codeReview.js +390 -0
- package/dist/utils/context.d.ts +49 -0
- package/dist/utils/context.js +216 -0
- package/dist/utils/diffPreview.d.ts +57 -0
- package/dist/utils/diffPreview.js +335 -0
- package/dist/utils/export.d.ts +19 -0
- package/dist/utils/export.js +94 -0
- package/dist/utils/git.d.ts +85 -0
- package/dist/utils/git.js +399 -0
- package/dist/utils/git.test.d.ts +1 -0
- package/dist/utils/git.test.js +193 -0
- package/dist/utils/history.d.ts +93 -0
- package/dist/utils/history.js +348 -0
- package/dist/utils/interactive.d.ts +34 -0
- package/dist/utils/interactive.js +206 -0
- package/dist/utils/keychain.d.ts +17 -0
- package/dist/utils/keychain.js +160 -0
- package/dist/utils/learning.d.ts +89 -0
- package/dist/utils/learning.js +330 -0
- package/dist/utils/logger.d.ts +33 -0
- package/dist/utils/logger.js +130 -0
- package/dist/utils/project.d.ts +86 -0
- package/dist/utils/project.js +415 -0
- package/dist/utils/project.test.d.ts +1 -0
- package/dist/utils/project.test.js +212 -0
- package/dist/utils/ratelimit.d.ts +26 -0
- package/dist/utils/ratelimit.js +132 -0
- package/dist/utils/ratelimit.test.d.ts +1 -0
- package/dist/utils/ratelimit.test.js +131 -0
- package/dist/utils/retry.d.ts +28 -0
- package/dist/utils/retry.js +109 -0
- package/dist/utils/retry.test.d.ts +1 -0
- package/dist/utils/retry.test.js +163 -0
- package/dist/utils/search.d.ts +11 -0
- package/dist/utils/search.js +29 -0
- package/dist/utils/shell.d.ts +45 -0
- package/dist/utils/shell.js +242 -0
- package/dist/utils/skills.d.ts +144 -0
- package/dist/utils/skills.js +1137 -0
- package/dist/utils/smartContext.d.ts +29 -0
- package/dist/utils/smartContext.js +441 -0
- package/dist/utils/tools.d.ts +224 -0
- package/dist/utils/tools.js +731 -0
- package/dist/utils/update.d.ts +22 -0
- package/dist/utils/update.js +128 -0
- package/dist/utils/validation.d.ts +28 -0
- package/dist/utils/validation.js +141 -0
- package/dist/utils/validation.test.d.ts +1 -0
- package/dist/utils/validation.test.js +164 -0
- package/dist/utils/verify.d.ts +78 -0
- package/dist/utils/verify.js +464 -0
- package/package.json +68 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diff Preview - show changes before applying them
|
|
3
|
+
*/
|
|
4
|
+
export interface FileDiff {
|
|
5
|
+
path: string;
|
|
6
|
+
type: 'create' | 'modify' | 'delete';
|
|
7
|
+
oldContent?: string;
|
|
8
|
+
newContent?: string;
|
|
9
|
+
hunks: DiffHunk[];
|
|
10
|
+
}
|
|
11
|
+
export interface DiffHunk {
|
|
12
|
+
oldStart: number;
|
|
13
|
+
oldLines: number;
|
|
14
|
+
newStart: number;
|
|
15
|
+
newLines: number;
|
|
16
|
+
lines: DiffLine[];
|
|
17
|
+
}
|
|
18
|
+
export interface DiffLine {
|
|
19
|
+
type: 'context' | 'add' | 'remove';
|
|
20
|
+
content: string;
|
|
21
|
+
oldLineNum?: number;
|
|
22
|
+
newLineNum?: number;
|
|
23
|
+
}
|
|
24
|
+
export interface DiffPreviewResult {
|
|
25
|
+
files: FileDiff[];
|
|
26
|
+
totalAdditions: number;
|
|
27
|
+
totalDeletions: number;
|
|
28
|
+
totalFiles: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Generate diff between old and new content
|
|
32
|
+
*/
|
|
33
|
+
export declare function generateDiff(oldContent: string, newContent: string, contextLines?: number): DiffHunk[];
|
|
34
|
+
/**
|
|
35
|
+
* Create file diff for a write operation
|
|
36
|
+
*/
|
|
37
|
+
export declare function createFileDiff(path: string, newContent: string, projectRoot: string): FileDiff;
|
|
38
|
+
/**
|
|
39
|
+
* Create file diff for an edit operation
|
|
40
|
+
*/
|
|
41
|
+
export declare function createEditDiff(path: string, oldText: string, newText: string, projectRoot: string): FileDiff | null;
|
|
42
|
+
/**
|
|
43
|
+
* Create file diff for a delete operation
|
|
44
|
+
*/
|
|
45
|
+
export declare function createDeleteDiff(path: string, projectRoot: string): FileDiff | null;
|
|
46
|
+
/**
|
|
47
|
+
* Format diff for terminal display
|
|
48
|
+
*/
|
|
49
|
+
export declare function formatDiffForDisplay(diff: FileDiff): string;
|
|
50
|
+
/**
|
|
51
|
+
* Format multiple diffs
|
|
52
|
+
*/
|
|
53
|
+
export declare function formatDiffPreview(diffs: FileDiff[]): string;
|
|
54
|
+
/**
|
|
55
|
+
* Calculate diff statistics
|
|
56
|
+
*/
|
|
57
|
+
export declare function getDiffStats(diffs: FileDiff[]): DiffPreviewResult;
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diff Preview - show changes before applying them
|
|
3
|
+
*/
|
|
4
|
+
import { existsSync, readFileSync } from 'fs';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
/**
|
|
7
|
+
* Generate diff between old and new content
|
|
8
|
+
*/
|
|
9
|
+
export function generateDiff(oldContent, newContent, contextLines = 3) {
|
|
10
|
+
const oldLines = oldContent.split('\n');
|
|
11
|
+
const newLines = newContent.split('\n');
|
|
12
|
+
const hunks = [];
|
|
13
|
+
// Simple diff algorithm (Myers-like)
|
|
14
|
+
const lcs = longestCommonSubsequence(oldLines, newLines);
|
|
15
|
+
let oldIdx = 0;
|
|
16
|
+
let newIdx = 0;
|
|
17
|
+
let currentHunk = null;
|
|
18
|
+
let pendingContext = [];
|
|
19
|
+
for (const [oldMatch, newMatch] of lcs) {
|
|
20
|
+
// Handle deletions
|
|
21
|
+
while (oldIdx < oldMatch) {
|
|
22
|
+
if (!currentHunk) {
|
|
23
|
+
currentHunk = createHunk(oldIdx, newIdx);
|
|
24
|
+
// Add leading context
|
|
25
|
+
for (let i = Math.max(0, oldIdx - contextLines); i < oldIdx; i++) {
|
|
26
|
+
currentHunk.lines.push({
|
|
27
|
+
type: 'context',
|
|
28
|
+
content: oldLines[i],
|
|
29
|
+
oldLineNum: i + 1,
|
|
30
|
+
newLineNum: newIdx - (oldIdx - i) + 1,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
currentHunk.lines.push({
|
|
35
|
+
type: 'remove',
|
|
36
|
+
content: oldLines[oldIdx],
|
|
37
|
+
oldLineNum: oldIdx + 1,
|
|
38
|
+
});
|
|
39
|
+
oldIdx++;
|
|
40
|
+
}
|
|
41
|
+
// Handle additions
|
|
42
|
+
while (newIdx < newMatch) {
|
|
43
|
+
if (!currentHunk) {
|
|
44
|
+
currentHunk = createHunk(oldIdx, newIdx);
|
|
45
|
+
// Add leading context
|
|
46
|
+
for (let i = Math.max(0, oldIdx - contextLines); i < oldIdx; i++) {
|
|
47
|
+
currentHunk.lines.push({
|
|
48
|
+
type: 'context',
|
|
49
|
+
content: oldLines[i],
|
|
50
|
+
oldLineNum: i + 1,
|
|
51
|
+
newLineNum: newIdx - (oldIdx - i) + 1,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
currentHunk.lines.push({
|
|
56
|
+
type: 'add',
|
|
57
|
+
content: newLines[newIdx],
|
|
58
|
+
newLineNum: newIdx + 1,
|
|
59
|
+
});
|
|
60
|
+
newIdx++;
|
|
61
|
+
}
|
|
62
|
+
// Handle match
|
|
63
|
+
if (oldIdx < oldLines.length && newIdx < newLines.length) {
|
|
64
|
+
if (currentHunk) {
|
|
65
|
+
// Add trailing context
|
|
66
|
+
for (let i = 0; i < contextLines && oldIdx + i < oldLines.length; i++) {
|
|
67
|
+
currentHunk.lines.push({
|
|
68
|
+
type: 'context',
|
|
69
|
+
content: oldLines[oldIdx + i],
|
|
70
|
+
oldLineNum: oldIdx + i + 1,
|
|
71
|
+
newLineNum: newIdx + i + 1,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
// Finalize hunk
|
|
75
|
+
finalizeHunk(currentHunk);
|
|
76
|
+
hunks.push(currentHunk);
|
|
77
|
+
currentHunk = null;
|
|
78
|
+
}
|
|
79
|
+
oldIdx++;
|
|
80
|
+
newIdx++;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Handle remaining deletions
|
|
84
|
+
while (oldIdx < oldLines.length) {
|
|
85
|
+
if (!currentHunk) {
|
|
86
|
+
currentHunk = createHunk(oldIdx, newIdx);
|
|
87
|
+
}
|
|
88
|
+
currentHunk.lines.push({
|
|
89
|
+
type: 'remove',
|
|
90
|
+
content: oldLines[oldIdx],
|
|
91
|
+
oldLineNum: oldIdx + 1,
|
|
92
|
+
});
|
|
93
|
+
oldIdx++;
|
|
94
|
+
}
|
|
95
|
+
// Handle remaining additions
|
|
96
|
+
while (newIdx < newLines.length) {
|
|
97
|
+
if (!currentHunk) {
|
|
98
|
+
currentHunk = createHunk(oldIdx, newIdx);
|
|
99
|
+
}
|
|
100
|
+
currentHunk.lines.push({
|
|
101
|
+
type: 'add',
|
|
102
|
+
content: newLines[newIdx],
|
|
103
|
+
newLineNum: newIdx + 1,
|
|
104
|
+
});
|
|
105
|
+
newIdx++;
|
|
106
|
+
}
|
|
107
|
+
// Finalize last hunk
|
|
108
|
+
if (currentHunk) {
|
|
109
|
+
finalizeHunk(currentHunk);
|
|
110
|
+
hunks.push(currentHunk);
|
|
111
|
+
}
|
|
112
|
+
return hunks;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Create a new hunk
|
|
116
|
+
*/
|
|
117
|
+
function createHunk(oldStart, newStart) {
|
|
118
|
+
return {
|
|
119
|
+
oldStart: oldStart + 1,
|
|
120
|
+
oldLines: 0,
|
|
121
|
+
newStart: newStart + 1,
|
|
122
|
+
newLines: 0,
|
|
123
|
+
lines: [],
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Finalize hunk by counting lines
|
|
128
|
+
*/
|
|
129
|
+
function finalizeHunk(hunk) {
|
|
130
|
+
hunk.oldLines = hunk.lines.filter(l => l.type !== 'add').length;
|
|
131
|
+
hunk.newLines = hunk.lines.filter(l => l.type !== 'remove').length;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Simple LCS algorithm for diff
|
|
135
|
+
*/
|
|
136
|
+
function longestCommonSubsequence(old, newArr) {
|
|
137
|
+
const result = [];
|
|
138
|
+
let oldIdx = 0;
|
|
139
|
+
let newIdx = 0;
|
|
140
|
+
while (oldIdx < old.length && newIdx < newArr.length) {
|
|
141
|
+
if (old[oldIdx] === newArr[newIdx]) {
|
|
142
|
+
result.push([oldIdx, newIdx]);
|
|
143
|
+
oldIdx++;
|
|
144
|
+
newIdx++;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
// Try to find match
|
|
148
|
+
let foundOld = -1;
|
|
149
|
+
let foundNew = -1;
|
|
150
|
+
// Look ahead in new array
|
|
151
|
+
for (let i = newIdx + 1; i < Math.min(newIdx + 10, newArr.length); i++) {
|
|
152
|
+
if (old[oldIdx] === newArr[i]) {
|
|
153
|
+
foundNew = i;
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Look ahead in old array
|
|
158
|
+
for (let i = oldIdx + 1; i < Math.min(oldIdx + 10, old.length); i++) {
|
|
159
|
+
if (old[i] === newArr[newIdx]) {
|
|
160
|
+
foundOld = i;
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (foundNew !== -1 && (foundOld === -1 || foundNew - newIdx < foundOld - oldIdx)) {
|
|
165
|
+
newIdx = foundNew;
|
|
166
|
+
}
|
|
167
|
+
else if (foundOld !== -1) {
|
|
168
|
+
oldIdx = foundOld;
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
oldIdx++;
|
|
172
|
+
newIdx++;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// Add end markers
|
|
177
|
+
result.push([old.length, newArr.length]);
|
|
178
|
+
return result;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Create file diff for a write operation
|
|
182
|
+
*/
|
|
183
|
+
export function createFileDiff(path, newContent, projectRoot) {
|
|
184
|
+
const fullPath = join(projectRoot, path);
|
|
185
|
+
const exists = existsSync(fullPath);
|
|
186
|
+
let oldContent = '';
|
|
187
|
+
let type = 'create';
|
|
188
|
+
if (exists) {
|
|
189
|
+
try {
|
|
190
|
+
oldContent = readFileSync(fullPath, 'utf-8');
|
|
191
|
+
type = 'modify';
|
|
192
|
+
}
|
|
193
|
+
catch { }
|
|
194
|
+
}
|
|
195
|
+
const hunks = generateDiff(oldContent, newContent);
|
|
196
|
+
return {
|
|
197
|
+
path,
|
|
198
|
+
type,
|
|
199
|
+
oldContent: exists ? oldContent : undefined,
|
|
200
|
+
newContent,
|
|
201
|
+
hunks,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Create file diff for an edit operation
|
|
206
|
+
*/
|
|
207
|
+
export function createEditDiff(path, oldText, newText, projectRoot) {
|
|
208
|
+
const fullPath = join(projectRoot, path);
|
|
209
|
+
if (!existsSync(fullPath)) {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
try {
|
|
213
|
+
const content = readFileSync(fullPath, 'utf-8');
|
|
214
|
+
if (!content.includes(oldText)) {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
const newContent = content.replace(oldText, newText);
|
|
218
|
+
const hunks = generateDiff(content, newContent);
|
|
219
|
+
return {
|
|
220
|
+
path,
|
|
221
|
+
type: 'modify',
|
|
222
|
+
oldContent: content,
|
|
223
|
+
newContent,
|
|
224
|
+
hunks,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Create file diff for a delete operation
|
|
233
|
+
*/
|
|
234
|
+
export function createDeleteDiff(path, projectRoot) {
|
|
235
|
+
const fullPath = join(projectRoot, path);
|
|
236
|
+
if (!existsSync(fullPath)) {
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
try {
|
|
240
|
+
const content = readFileSync(fullPath, 'utf-8');
|
|
241
|
+
const hunks = generateDiff(content, '');
|
|
242
|
+
return {
|
|
243
|
+
path,
|
|
244
|
+
type: 'delete',
|
|
245
|
+
oldContent: content,
|
|
246
|
+
hunks,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Format diff for terminal display
|
|
255
|
+
*/
|
|
256
|
+
export function formatDiffForDisplay(diff) {
|
|
257
|
+
const lines = [];
|
|
258
|
+
// Header
|
|
259
|
+
if (diff.type === 'create') {
|
|
260
|
+
lines.push(`+++ NEW FILE: ${diff.path}`);
|
|
261
|
+
}
|
|
262
|
+
else if (diff.type === 'delete') {
|
|
263
|
+
lines.push(`--- DELETE FILE: ${diff.path}`);
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
lines.push(`--- a/${diff.path}`);
|
|
267
|
+
lines.push(`+++ b/${diff.path}`);
|
|
268
|
+
}
|
|
269
|
+
// Hunks
|
|
270
|
+
for (const hunk of diff.hunks) {
|
|
271
|
+
lines.push(`@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`);
|
|
272
|
+
for (const line of hunk.lines) {
|
|
273
|
+
if (line.type === 'add') {
|
|
274
|
+
lines.push(`+ ${line.content}`);
|
|
275
|
+
}
|
|
276
|
+
else if (line.type === 'remove') {
|
|
277
|
+
lines.push(`- ${line.content}`);
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
lines.push(` ${line.content}`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return lines.join('\n');
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Format multiple diffs
|
|
288
|
+
*/
|
|
289
|
+
export function formatDiffPreview(diffs) {
|
|
290
|
+
const lines = ['## Diff Preview', ''];
|
|
291
|
+
let totalAdditions = 0;
|
|
292
|
+
let totalDeletions = 0;
|
|
293
|
+
for (const diff of diffs) {
|
|
294
|
+
for (const hunk of diff.hunks) {
|
|
295
|
+
for (const line of hunk.lines) {
|
|
296
|
+
if (line.type === 'add')
|
|
297
|
+
totalAdditions++;
|
|
298
|
+
if (line.type === 'remove')
|
|
299
|
+
totalDeletions++;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
lines.push(`Files: ${diffs.length} | +${totalAdditions} -${totalDeletions}`);
|
|
304
|
+
lines.push('');
|
|
305
|
+
for (const diff of diffs) {
|
|
306
|
+
lines.push('```diff');
|
|
307
|
+
lines.push(formatDiffForDisplay(diff));
|
|
308
|
+
lines.push('```');
|
|
309
|
+
lines.push('');
|
|
310
|
+
}
|
|
311
|
+
return lines.join('\n');
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Calculate diff statistics
|
|
315
|
+
*/
|
|
316
|
+
export function getDiffStats(diffs) {
|
|
317
|
+
let totalAdditions = 0;
|
|
318
|
+
let totalDeletions = 0;
|
|
319
|
+
for (const diff of diffs) {
|
|
320
|
+
for (const hunk of diff.hunks) {
|
|
321
|
+
for (const line of hunk.lines) {
|
|
322
|
+
if (line.type === 'add')
|
|
323
|
+
totalAdditions++;
|
|
324
|
+
if (line.type === 'remove')
|
|
325
|
+
totalDeletions++;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return {
|
|
330
|
+
files: diffs,
|
|
331
|
+
totalAdditions,
|
|
332
|
+
totalDeletions,
|
|
333
|
+
totalFiles: diffs.length,
|
|
334
|
+
};
|
|
335
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Message } from '../config';
|
|
2
|
+
export type ExportFormat = 'md' | 'json' | 'txt';
|
|
3
|
+
export interface ExportOptions {
|
|
4
|
+
format: ExportFormat;
|
|
5
|
+
sessionName?: string;
|
|
6
|
+
timestamp?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Export messages to specified format
|
|
10
|
+
*/
|
|
11
|
+
export declare function exportMessages(messages: Message[], options: ExportOptions): string;
|
|
12
|
+
/**
|
|
13
|
+
* Save exported content to file
|
|
14
|
+
*/
|
|
15
|
+
export declare function saveExport(content: string, format: ExportFormat, outputPath: string, sessionName?: string): {
|
|
16
|
+
success: boolean;
|
|
17
|
+
filePath: string;
|
|
18
|
+
error?: string;
|
|
19
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { writeFileSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Export messages to Markdown format
|
|
5
|
+
*/
|
|
6
|
+
function exportToMarkdown(messages, sessionName) {
|
|
7
|
+
const timestamp = new Date().toLocaleString('hr-HR');
|
|
8
|
+
let markdown = `# Codeep Chat Export\n\n`;
|
|
9
|
+
if (sessionName) {
|
|
10
|
+
markdown += `**Session:** ${sessionName}\n`;
|
|
11
|
+
}
|
|
12
|
+
markdown += `**Exported:** ${timestamp}\n\n`;
|
|
13
|
+
markdown += `---\n\n`;
|
|
14
|
+
messages.forEach((message, index) => {
|
|
15
|
+
const role = message.role === 'user' ? '👤 User' : '🤖 Assistant';
|
|
16
|
+
markdown += `## ${role}\n\n`;
|
|
17
|
+
markdown += `${message.content}\n\n`;
|
|
18
|
+
if (index < messages.length - 1) {
|
|
19
|
+
markdown += `---\n\n`;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
return markdown;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Export messages to JSON format
|
|
26
|
+
*/
|
|
27
|
+
function exportToJson(messages, sessionName) {
|
|
28
|
+
const exportData = {
|
|
29
|
+
session: sessionName || 'Unnamed',
|
|
30
|
+
exportedAt: new Date().toISOString(),
|
|
31
|
+
messageCount: messages.length,
|
|
32
|
+
messages: messages,
|
|
33
|
+
};
|
|
34
|
+
return JSON.stringify(exportData, null, 2);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Export messages to plain text format
|
|
38
|
+
*/
|
|
39
|
+
function exportToText(messages, sessionName) {
|
|
40
|
+
const timestamp = new Date().toLocaleString('hr-HR');
|
|
41
|
+
let text = `Codeep Chat Export\n`;
|
|
42
|
+
text += `===================\n\n`;
|
|
43
|
+
if (sessionName) {
|
|
44
|
+
text += `Session: ${sessionName}\n`;
|
|
45
|
+
}
|
|
46
|
+
text += `Exported: ${timestamp}\n`;
|
|
47
|
+
text += `Messages: ${messages.length}\n\n`;
|
|
48
|
+
text += `===================\n\n`;
|
|
49
|
+
messages.forEach((message, index) => {
|
|
50
|
+
const role = message.role === 'user' ? 'USER' : 'ASSISTANT';
|
|
51
|
+
text += `[${role}]\n`;
|
|
52
|
+
text += `${message.content}\n\n`;
|
|
53
|
+
if (index < messages.length - 1) {
|
|
54
|
+
text += `---\n\n`;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return text;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Export messages to specified format
|
|
61
|
+
*/
|
|
62
|
+
export function exportMessages(messages, options) {
|
|
63
|
+
switch (options.format) {
|
|
64
|
+
case 'md':
|
|
65
|
+
return exportToMarkdown(messages, options.sessionName);
|
|
66
|
+
case 'json':
|
|
67
|
+
return exportToJson(messages, options.sessionName);
|
|
68
|
+
case 'txt':
|
|
69
|
+
return exportToText(messages, options.sessionName);
|
|
70
|
+
default:
|
|
71
|
+
throw new Error(`Unknown export format: ${options.format}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Save exported content to file
|
|
76
|
+
*/
|
|
77
|
+
export function saveExport(content, format, outputPath, sessionName) {
|
|
78
|
+
try {
|
|
79
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
|
|
80
|
+
const fileName = sessionName
|
|
81
|
+
? `${sessionName}-${timestamp}.${format}`
|
|
82
|
+
: `chat-export-${timestamp}.${format}`;
|
|
83
|
+
const filePath = join(outputPath, fileName);
|
|
84
|
+
writeFileSync(filePath, content, 'utf-8');
|
|
85
|
+
return { success: true, filePath };
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
return {
|
|
89
|
+
success: false,
|
|
90
|
+
filePath: '',
|
|
91
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { ActionLog } from './tools';
|
|
2
|
+
export interface GitStatus {
|
|
3
|
+
isRepo: boolean;
|
|
4
|
+
branch?: string;
|
|
5
|
+
hasChanges?: boolean;
|
|
6
|
+
ahead?: number;
|
|
7
|
+
behind?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface GitDiffResult {
|
|
10
|
+
success: boolean;
|
|
11
|
+
diff: string;
|
|
12
|
+
error?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface GitCommitResult {
|
|
15
|
+
success: boolean;
|
|
16
|
+
hash?: string;
|
|
17
|
+
error?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Check if current directory is a git repository
|
|
21
|
+
*/
|
|
22
|
+
export declare function isGitRepository(cwd?: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Get current git status
|
|
25
|
+
*/
|
|
26
|
+
export declare function getGitStatus(cwd?: string): GitStatus;
|
|
27
|
+
/**
|
|
28
|
+
* Get git diff (staged or unstaged)
|
|
29
|
+
*/
|
|
30
|
+
export declare function getGitDiff(staged?: boolean, cwd?: string): GitDiffResult;
|
|
31
|
+
/**
|
|
32
|
+
* Get list of changed files
|
|
33
|
+
*/
|
|
34
|
+
export declare function getChangedFiles(cwd?: string): string[];
|
|
35
|
+
/**
|
|
36
|
+
* Generate commit message suggestion based on diff
|
|
37
|
+
*/
|
|
38
|
+
export declare function suggestCommitMessage(diff: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Create a commit with the given message
|
|
41
|
+
*/
|
|
42
|
+
export declare function createCommit(message: string, cwd?: string): GitCommitResult;
|
|
43
|
+
/**
|
|
44
|
+
* Stage all changes
|
|
45
|
+
*/
|
|
46
|
+
export declare function stageAll(cwd?: string): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Format git diff for display
|
|
49
|
+
*/
|
|
50
|
+
export declare function formatDiffForDisplay(diff: string, maxLines?: number): string;
|
|
51
|
+
/**
|
|
52
|
+
* Create a new branch
|
|
53
|
+
*/
|
|
54
|
+
export declare function createBranch(branchName: string, cwd?: string): {
|
|
55
|
+
success: boolean;
|
|
56
|
+
error?: string;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Switch to a branch
|
|
60
|
+
*/
|
|
61
|
+
export declare function switchBranch(branchName: string, cwd?: string): {
|
|
62
|
+
success: boolean;
|
|
63
|
+
error?: string;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Generate a commit message based on agent actions
|
|
67
|
+
*/
|
|
68
|
+
export declare function generateCommitMessage(prompt: string, actions: ActionLog[]): string;
|
|
69
|
+
/**
|
|
70
|
+
* Auto-commit agent changes
|
|
71
|
+
*/
|
|
72
|
+
export declare function autoCommitAgentChanges(prompt: string, actions: ActionLog[], cwd?: string): GitCommitResult;
|
|
73
|
+
/**
|
|
74
|
+
* Generate branch name from prompt
|
|
75
|
+
*/
|
|
76
|
+
export declare function generateBranchName(prompt: string): string;
|
|
77
|
+
/**
|
|
78
|
+
* Create branch and commit agent changes
|
|
79
|
+
*/
|
|
80
|
+
export declare function createBranchAndCommit(prompt: string, actions: ActionLog[], cwd?: string): {
|
|
81
|
+
success: boolean;
|
|
82
|
+
branch?: string;
|
|
83
|
+
hash?: string;
|
|
84
|
+
error?: string;
|
|
85
|
+
};
|