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,464 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-verification module for agent
|
|
3
|
+
* Runs build/test and analyzes errors for auto-fixing
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync, readFileSync } from 'fs';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
import { executeCommand } from './shell';
|
|
8
|
+
const DEFAULT_OPTIONS = {
|
|
9
|
+
runBuild: true,
|
|
10
|
+
runTest: true,
|
|
11
|
+
runLint: false,
|
|
12
|
+
runTypecheck: true,
|
|
13
|
+
timeout: 120000, // 2 minutes
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Detect project type and available scripts
|
|
17
|
+
*/
|
|
18
|
+
export function detectProjectScripts(projectRoot) {
|
|
19
|
+
const result = {
|
|
20
|
+
packageManager: 'npm',
|
|
21
|
+
};
|
|
22
|
+
// Detect package manager
|
|
23
|
+
if (existsSync(join(projectRoot, 'bun.lockb'))) {
|
|
24
|
+
result.packageManager = 'bun';
|
|
25
|
+
}
|
|
26
|
+
else if (existsSync(join(projectRoot, 'pnpm-lock.yaml'))) {
|
|
27
|
+
result.packageManager = 'pnpm';
|
|
28
|
+
}
|
|
29
|
+
else if (existsSync(join(projectRoot, 'yarn.lock'))) {
|
|
30
|
+
result.packageManager = 'yarn';
|
|
31
|
+
}
|
|
32
|
+
// Check package.json for scripts
|
|
33
|
+
const packageJsonPath = join(projectRoot, 'package.json');
|
|
34
|
+
if (existsSync(packageJsonPath)) {
|
|
35
|
+
try {
|
|
36
|
+
const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
37
|
+
const scripts = pkg.scripts || {};
|
|
38
|
+
// Build command
|
|
39
|
+
if (scripts.build) {
|
|
40
|
+
result.build = 'build';
|
|
41
|
+
}
|
|
42
|
+
else if (scripts.compile) {
|
|
43
|
+
result.build = 'compile';
|
|
44
|
+
}
|
|
45
|
+
// Test command
|
|
46
|
+
if (scripts.test) {
|
|
47
|
+
result.test = 'test';
|
|
48
|
+
}
|
|
49
|
+
else if (scripts.spec) {
|
|
50
|
+
result.test = 'spec';
|
|
51
|
+
}
|
|
52
|
+
// Lint command
|
|
53
|
+
if (scripts.lint) {
|
|
54
|
+
result.lint = 'lint';
|
|
55
|
+
}
|
|
56
|
+
else if (scripts.eslint) {
|
|
57
|
+
result.lint = 'eslint';
|
|
58
|
+
}
|
|
59
|
+
// Typecheck command
|
|
60
|
+
if (scripts.typecheck) {
|
|
61
|
+
result.typecheck = 'typecheck';
|
|
62
|
+
}
|
|
63
|
+
else if (scripts['type-check']) {
|
|
64
|
+
result.typecheck = 'type-check';
|
|
65
|
+
}
|
|
66
|
+
else if (scripts.tsc) {
|
|
67
|
+
result.typecheck = 'tsc';
|
|
68
|
+
}
|
|
69
|
+
else if (existsSync(join(projectRoot, 'tsconfig.json'))) {
|
|
70
|
+
// TypeScript project without explicit typecheck script
|
|
71
|
+
result.typecheck = '__tsc_direct__';
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Ignore parse errors
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Python project
|
|
79
|
+
const requirementsPath = join(projectRoot, 'requirements.txt');
|
|
80
|
+
const pyprojectPath = join(projectRoot, 'pyproject.toml');
|
|
81
|
+
if (existsSync(requirementsPath) || existsSync(pyprojectPath)) {
|
|
82
|
+
if (existsSync(join(projectRoot, 'pytest.ini')) || existsSync(join(projectRoot, 'tests'))) {
|
|
83
|
+
result.test = '__pytest__';
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Go project
|
|
87
|
+
if (existsSync(join(projectRoot, 'go.mod'))) {
|
|
88
|
+
result.build = '__go_build__';
|
|
89
|
+
result.test = '__go_test__';
|
|
90
|
+
}
|
|
91
|
+
// Rust project
|
|
92
|
+
if (existsSync(join(projectRoot, 'Cargo.toml'))) {
|
|
93
|
+
result.build = '__cargo_build__';
|
|
94
|
+
result.test = '__cargo_test__';
|
|
95
|
+
}
|
|
96
|
+
// PHP project (Composer)
|
|
97
|
+
if (existsSync(join(projectRoot, 'composer.json'))) {
|
|
98
|
+
try {
|
|
99
|
+
const composer = JSON.parse(readFileSync(join(projectRoot, 'composer.json'), 'utf-8'));
|
|
100
|
+
const scripts = composer.scripts || {};
|
|
101
|
+
if (scripts.test) {
|
|
102
|
+
result.test = '__composer_test__';
|
|
103
|
+
}
|
|
104
|
+
else if (existsSync(join(projectRoot, 'phpunit.xml')) || existsSync(join(projectRoot, 'phpunit.xml.dist'))) {
|
|
105
|
+
result.test = '__phpunit__';
|
|
106
|
+
}
|
|
107
|
+
if (scripts.build) {
|
|
108
|
+
result.build = '__composer_build__';
|
|
109
|
+
}
|
|
110
|
+
// PHP syntax check
|
|
111
|
+
result.typecheck = '__php_lint__';
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// Ignore parse errors
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Laravel project
|
|
118
|
+
if (existsSync(join(projectRoot, 'artisan'))) {
|
|
119
|
+
result.test = '__artisan_test__';
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Run a verification command
|
|
125
|
+
*/
|
|
126
|
+
function runVerifyCommand(type, command, args, projectRoot, timeout) {
|
|
127
|
+
const startTime = Date.now();
|
|
128
|
+
const result = executeCommand(command, args, {
|
|
129
|
+
cwd: projectRoot,
|
|
130
|
+
projectRoot,
|
|
131
|
+
timeout,
|
|
132
|
+
});
|
|
133
|
+
const duration = Date.now() - startTime;
|
|
134
|
+
const output = result.stdout + '\n' + result.stderr;
|
|
135
|
+
// Parse errors from output
|
|
136
|
+
const errors = parseErrors(output, type);
|
|
137
|
+
return {
|
|
138
|
+
success: result.success,
|
|
139
|
+
type,
|
|
140
|
+
command: `${command} ${args.join(' ')}`,
|
|
141
|
+
output: output.trim(),
|
|
142
|
+
errors,
|
|
143
|
+
duration,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Parse errors from command output
|
|
148
|
+
*/
|
|
149
|
+
function parseErrors(output, type) {
|
|
150
|
+
const errors = [];
|
|
151
|
+
const lines = output.split('\n');
|
|
152
|
+
for (const line of lines) {
|
|
153
|
+
// TypeScript/TSC errors: src/file.ts(10,5): error TS2345: ...
|
|
154
|
+
const tsMatch = line.match(/^(.+?)\((\d+),(\d+)\):\s*(error|warning)\s+(TS\d+):\s*(.+)$/);
|
|
155
|
+
if (tsMatch) {
|
|
156
|
+
errors.push({
|
|
157
|
+
file: tsMatch[1],
|
|
158
|
+
line: parseInt(tsMatch[2]),
|
|
159
|
+
column: parseInt(tsMatch[3]),
|
|
160
|
+
severity: tsMatch[4],
|
|
161
|
+
code: tsMatch[5],
|
|
162
|
+
message: tsMatch[6],
|
|
163
|
+
});
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
// ESLint/Prettier: /path/to/file.ts:10:5: error ...
|
|
167
|
+
const eslintMatch = line.match(/^(.+?):(\d+):(\d+):\s*(error|warning)\s+(.+)$/);
|
|
168
|
+
if (eslintMatch) {
|
|
169
|
+
errors.push({
|
|
170
|
+
file: eslintMatch[1],
|
|
171
|
+
line: parseInt(eslintMatch[2]),
|
|
172
|
+
column: parseInt(eslintMatch[3]),
|
|
173
|
+
severity: eslintMatch[4],
|
|
174
|
+
message: eslintMatch[5],
|
|
175
|
+
});
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
// Jest/Vitest: FAIL src/file.test.ts
|
|
179
|
+
const jestFailMatch = line.match(/^\s*FAIL\s+(.+)$/);
|
|
180
|
+
if (jestFailMatch) {
|
|
181
|
+
errors.push({
|
|
182
|
+
file: jestFailMatch[1],
|
|
183
|
+
severity: 'error',
|
|
184
|
+
message: 'Test file failed',
|
|
185
|
+
});
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
// Generic error with file:line
|
|
189
|
+
const genericMatch = line.match(/^(.+?):(\d+):\s*(.+error.+)$/i);
|
|
190
|
+
if (genericMatch) {
|
|
191
|
+
errors.push({
|
|
192
|
+
file: genericMatch[1],
|
|
193
|
+
line: parseInt(genericMatch[2]),
|
|
194
|
+
severity: 'error',
|
|
195
|
+
message: genericMatch[3],
|
|
196
|
+
});
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
// Go errors: file.go:10:5: ...
|
|
200
|
+
const goMatch = line.match(/^(.+\.go):(\d+):(\d+):\s*(.+)$/);
|
|
201
|
+
if (goMatch) {
|
|
202
|
+
errors.push({
|
|
203
|
+
file: goMatch[1],
|
|
204
|
+
line: parseInt(goMatch[2]),
|
|
205
|
+
column: parseInt(goMatch[3]),
|
|
206
|
+
severity: 'error',
|
|
207
|
+
message: goMatch[4],
|
|
208
|
+
});
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
// Rust errors: error[E0001]: ... --> src/main.rs:10:5
|
|
212
|
+
const rustMatch = line.match(/^\s*-->\s*(.+?):(\d+):(\d+)$/);
|
|
213
|
+
if (rustMatch) {
|
|
214
|
+
errors.push({
|
|
215
|
+
file: rustMatch[1],
|
|
216
|
+
line: parseInt(rustMatch[2]),
|
|
217
|
+
column: parseInt(rustMatch[3]),
|
|
218
|
+
severity: 'error',
|
|
219
|
+
message: 'Rust compilation error',
|
|
220
|
+
});
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
// PHP errors: PHP Parse error: ... in /path/file.php on line 10
|
|
224
|
+
const phpMatch = line.match(/PHP\s+(Parse error|Fatal error|Warning):\s*(.+?)\s+in\s+(.+?)\s+on line\s+(\d+)/i);
|
|
225
|
+
if (phpMatch) {
|
|
226
|
+
errors.push({
|
|
227
|
+
file: phpMatch[3],
|
|
228
|
+
line: parseInt(phpMatch[4]),
|
|
229
|
+
severity: phpMatch[1].toLowerCase().includes('warning') ? 'warning' : 'error',
|
|
230
|
+
message: phpMatch[2],
|
|
231
|
+
});
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
// PHPUnit errors: 1) TestClass::testMethod
|
|
235
|
+
const phpunitMatch = line.match(/^\d+\)\s+(.+)::(.+)$/);
|
|
236
|
+
if (phpunitMatch) {
|
|
237
|
+
errors.push({
|
|
238
|
+
severity: 'error',
|
|
239
|
+
message: `Test failed: ${phpunitMatch[1]}::${phpunitMatch[2]}`,
|
|
240
|
+
});
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return errors;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Run build verification
|
|
248
|
+
*/
|
|
249
|
+
export function runBuildVerification(projectRoot, timeout = 120000) {
|
|
250
|
+
const scripts = detectProjectScripts(projectRoot);
|
|
251
|
+
if (!scripts.build) {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
let command;
|
|
255
|
+
let args;
|
|
256
|
+
if (scripts.build === '__go_build__') {
|
|
257
|
+
command = 'go';
|
|
258
|
+
args = ['build', './...'];
|
|
259
|
+
}
|
|
260
|
+
else if (scripts.build === '__cargo_build__') {
|
|
261
|
+
command = 'cargo';
|
|
262
|
+
args = ['build'];
|
|
263
|
+
}
|
|
264
|
+
else if (scripts.build === '__composer_build__') {
|
|
265
|
+
command = 'composer';
|
|
266
|
+
args = ['run', 'build'];
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
command = scripts.packageManager;
|
|
270
|
+
args = ['run', scripts.build];
|
|
271
|
+
}
|
|
272
|
+
return runVerifyCommand('build', command, args, projectRoot, timeout);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Run test verification
|
|
276
|
+
*/
|
|
277
|
+
export function runTestVerification(projectRoot, timeout = 120000) {
|
|
278
|
+
const scripts = detectProjectScripts(projectRoot);
|
|
279
|
+
if (!scripts.test) {
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
let command;
|
|
283
|
+
let args;
|
|
284
|
+
if (scripts.test === '__pytest__') {
|
|
285
|
+
command = 'pytest';
|
|
286
|
+
args = ['-v'];
|
|
287
|
+
}
|
|
288
|
+
else if (scripts.test === '__go_test__') {
|
|
289
|
+
command = 'go';
|
|
290
|
+
args = ['test', './...'];
|
|
291
|
+
}
|
|
292
|
+
else if (scripts.test === '__cargo_test__') {
|
|
293
|
+
command = 'cargo';
|
|
294
|
+
args = ['test'];
|
|
295
|
+
}
|
|
296
|
+
else if (scripts.test === '__phpunit__') {
|
|
297
|
+
command = './vendor/bin/phpunit';
|
|
298
|
+
args = [];
|
|
299
|
+
}
|
|
300
|
+
else if (scripts.test === '__composer_test__') {
|
|
301
|
+
command = 'composer';
|
|
302
|
+
args = ['run', 'test'];
|
|
303
|
+
}
|
|
304
|
+
else if (scripts.test === '__artisan_test__') {
|
|
305
|
+
command = 'php';
|
|
306
|
+
args = ['artisan', 'test'];
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
command = scripts.packageManager;
|
|
310
|
+
args = ['run', scripts.test];
|
|
311
|
+
}
|
|
312
|
+
return runVerifyCommand('test', command, args, projectRoot, timeout);
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Run TypeScript type checking
|
|
316
|
+
*/
|
|
317
|
+
export function runTypecheckVerification(projectRoot, timeout = 60000) {
|
|
318
|
+
const scripts = detectProjectScripts(projectRoot);
|
|
319
|
+
if (!scripts.typecheck) {
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
let command;
|
|
323
|
+
let args;
|
|
324
|
+
if (scripts.typecheck === '__tsc_direct__') {
|
|
325
|
+
command = 'npx';
|
|
326
|
+
args = ['tsc', '--noEmit'];
|
|
327
|
+
}
|
|
328
|
+
else if (scripts.typecheck === '__php_lint__') {
|
|
329
|
+
// PHP syntax check on all PHP files
|
|
330
|
+
command = 'find';
|
|
331
|
+
args = ['.', '-name', '*.php', '-not', '-path', './vendor/*', '-exec', 'php', '-l', '{}', ';'];
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
command = scripts.packageManager;
|
|
335
|
+
args = ['run', scripts.typecheck];
|
|
336
|
+
}
|
|
337
|
+
return runVerifyCommand('typecheck', command, args, projectRoot, timeout);
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Run lint verification
|
|
341
|
+
*/
|
|
342
|
+
export function runLintVerification(projectRoot, timeout = 60000) {
|
|
343
|
+
const scripts = detectProjectScripts(projectRoot);
|
|
344
|
+
if (!scripts.lint) {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
const command = scripts.packageManager;
|
|
348
|
+
const args = ['run', scripts.lint];
|
|
349
|
+
return runVerifyCommand('lint', command, args, projectRoot, timeout);
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Run all verifications
|
|
353
|
+
*/
|
|
354
|
+
export function runAllVerifications(projectRoot, options = {}) {
|
|
355
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
356
|
+
const results = [];
|
|
357
|
+
// Run typecheck first (fastest feedback)
|
|
358
|
+
if (opts.runTypecheck) {
|
|
359
|
+
const result = runTypecheckVerification(projectRoot, opts.timeout);
|
|
360
|
+
if (result)
|
|
361
|
+
results.push(result);
|
|
362
|
+
}
|
|
363
|
+
// Run build
|
|
364
|
+
if (opts.runBuild) {
|
|
365
|
+
const result = runBuildVerification(projectRoot, opts.timeout);
|
|
366
|
+
if (result)
|
|
367
|
+
results.push(result);
|
|
368
|
+
}
|
|
369
|
+
// Run lint
|
|
370
|
+
if (opts.runLint) {
|
|
371
|
+
const result = runLintVerification(projectRoot, opts.timeout);
|
|
372
|
+
if (result)
|
|
373
|
+
results.push(result);
|
|
374
|
+
}
|
|
375
|
+
// Run tests last (slowest)
|
|
376
|
+
if (opts.runTest) {
|
|
377
|
+
const result = runTestVerification(projectRoot, opts.timeout);
|
|
378
|
+
if (result)
|
|
379
|
+
results.push(result);
|
|
380
|
+
}
|
|
381
|
+
return results;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Format verification results for display
|
|
385
|
+
*/
|
|
386
|
+
export function formatVerifyResults(results) {
|
|
387
|
+
const lines = [];
|
|
388
|
+
for (const result of results) {
|
|
389
|
+
const status = result.success ? '✓' : '✗';
|
|
390
|
+
const duration = `${(result.duration / 1000).toFixed(1)}s`;
|
|
391
|
+
lines.push(`${status} ${result.type}: ${result.command} (${duration})`);
|
|
392
|
+
if (!result.success && result.errors.length > 0) {
|
|
393
|
+
const errorCount = result.errors.filter(e => e.severity === 'error').length;
|
|
394
|
+
const warnCount = result.errors.filter(e => e.severity === 'warning').length;
|
|
395
|
+
lines.push(` ${errorCount} error(s), ${warnCount} warning(s)`);
|
|
396
|
+
// Show first few errors
|
|
397
|
+
for (const error of result.errors.slice(0, 5)) {
|
|
398
|
+
const loc = error.file ? `${error.file}:${error.line || '?'}` : '';
|
|
399
|
+
lines.push(` - ${loc}: ${error.message}`);
|
|
400
|
+
}
|
|
401
|
+
if (result.errors.length > 5) {
|
|
402
|
+
lines.push(` ... and ${result.errors.length - 5} more`);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return lines.join('\n');
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Format errors for agent to fix
|
|
410
|
+
*/
|
|
411
|
+
export function formatErrorsForAgent(results) {
|
|
412
|
+
const failedResults = results.filter(r => !r.success);
|
|
413
|
+
if (failedResults.length === 0) {
|
|
414
|
+
return '';
|
|
415
|
+
}
|
|
416
|
+
const lines = ['## Verification Errors - Please Fix:', ''];
|
|
417
|
+
for (const result of failedResults) {
|
|
418
|
+
lines.push(`### ${result.type.toUpperCase()} Failed`);
|
|
419
|
+
lines.push(`Command: ${result.command}`);
|
|
420
|
+
lines.push('');
|
|
421
|
+
if (result.errors.length > 0) {
|
|
422
|
+
lines.push('Errors:');
|
|
423
|
+
for (const error of result.errors) {
|
|
424
|
+
const loc = error.file
|
|
425
|
+
? `${error.file}${error.line ? `:${error.line}` : ''}${error.column ? `:${error.column}` : ''}`
|
|
426
|
+
: 'unknown';
|
|
427
|
+
lines.push(`- [${loc}] ${error.message}${error.code ? ` (${error.code})` : ''}`);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
// No parsed errors, show raw output
|
|
432
|
+
lines.push('Output:');
|
|
433
|
+
lines.push('```');
|
|
434
|
+
lines.push(result.output.slice(0, 2000));
|
|
435
|
+
if (result.output.length > 2000) {
|
|
436
|
+
lines.push('... (truncated)');
|
|
437
|
+
}
|
|
438
|
+
lines.push('```');
|
|
439
|
+
}
|
|
440
|
+
lines.push('');
|
|
441
|
+
}
|
|
442
|
+
lines.push('Please fix these errors and try again.');
|
|
443
|
+
return lines.join('\n');
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Check if any verification failed
|
|
447
|
+
*/
|
|
448
|
+
export function hasVerificationErrors(results) {
|
|
449
|
+
return results.some(r => !r.success);
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Get summary of verification
|
|
453
|
+
*/
|
|
454
|
+
export function getVerificationSummary(results) {
|
|
455
|
+
const passed = results.filter(r => r.success).length;
|
|
456
|
+
const failed = results.filter(r => !r.success).length;
|
|
457
|
+
const errors = results.reduce((sum, r) => sum + r.errors.filter(e => e.severity === 'error').length, 0);
|
|
458
|
+
return {
|
|
459
|
+
passed,
|
|
460
|
+
failed,
|
|
461
|
+
total: results.length,
|
|
462
|
+
errors,
|
|
463
|
+
};
|
|
464
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "codeep",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "AI-powered coding assistant built for the terminal. Multiple LLM providers, project-aware context, and a seamless development workflow.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"codeep": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"dev": "node --import tsx src/index.tsx",
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"build:binary": "npm run build && pkg dist/index.js --targets node18-macos-arm64,node18-macos-x64,node18-linux-x64 --output bin/codeep",
|
|
15
|
+
"test": "vitest run",
|
|
16
|
+
"test:watch": "vitest",
|
|
17
|
+
"test:coverage": "vitest run --coverage"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/VladoIvankovic/Codeep.git"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"ai",
|
|
25
|
+
"cli",
|
|
26
|
+
"tui",
|
|
27
|
+
"glm",
|
|
28
|
+
"z.ai",
|
|
29
|
+
"coding",
|
|
30
|
+
"assistant"
|
|
31
|
+
],
|
|
32
|
+
"author": "Vlado Ivankovic",
|
|
33
|
+
"license": "Apache-2.0",
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/VladoIvankovic/Codeep/issues"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://codeep.dev",
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"clipboardy": "^4.0.0",
|
|
40
|
+
"conf": "^12.0.0",
|
|
41
|
+
"ink": "^4.4.1",
|
|
42
|
+
"ink-spinner": "^5.0.0",
|
|
43
|
+
"ink-text-input": "^5.0.1",
|
|
44
|
+
"keytar": "^7.9.0",
|
|
45
|
+
"open": "^10.0.0",
|
|
46
|
+
"react": "^18.2.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/node": "^20.10.0",
|
|
50
|
+
"@types/react": "^18.2.0",
|
|
51
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
52
|
+
"pkg": "^5.8.1",
|
|
53
|
+
"tsx": "^4.7.0",
|
|
54
|
+
"typescript": "^5.3.0",
|
|
55
|
+
"vitest": "^4.0.18"
|
|
56
|
+
},
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=18.0.0"
|
|
59
|
+
},
|
|
60
|
+
"files": [
|
|
61
|
+
"dist/**/*",
|
|
62
|
+
"README.md",
|
|
63
|
+
"LICENSE"
|
|
64
|
+
],
|
|
65
|
+
"publishConfig": {
|
|
66
|
+
"access": "public"
|
|
67
|
+
}
|
|
68
|
+
}
|