scai 0.1.108 → 0.1.110
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/dist/CHANGELOG.md +24 -1
- package/dist/__tests__/example.test.js +10 -0
- package/dist/agent/agentManager.js +14 -2
- package/dist/agent/workflowManager.js +5 -0
- package/dist/commands/DaemonCmd.js +3 -1
- package/dist/config.js +13 -8
- package/dist/context.js +36 -10
- package/dist/daemon/daemonBatch.js +68 -14
- package/dist/daemon/daemonWorker.js +19 -2
- package/dist/db/functionExtractors/extractFromJs.js +96 -16
- package/dist/db/functionExtractors/extractFromTs.js +73 -16
- package/dist/db/functionExtractors/index.js +34 -33
- package/dist/db/functionIndex.js +1 -1
- package/dist/db/schema.js +51 -5
- package/dist/index.js +5 -9
- package/dist/modelSetup.js +17 -20
- package/dist/pipeline/modules/cleanGeneratedTestsModule.js +17 -6
- package/dist/pipeline/modules/cleanupModule.js +32 -13
- package/dist/pipeline/modules/kgModule.js +55 -0
- package/dist/pipeline/modules/repairTestsModule.js +40 -0
- package/dist/pipeline/modules/runTestsModule.js +37 -0
- package/dist/pipeline/registry/moduleRegistry.js +17 -0
- package/dist/scripts/dbcheck.js +98 -0
- package/dist/utils/log.js +1 -1
- package/package.json +2 -2
- package/dist/jest.config.js +0 -11
- package/dist/jest.setup.js +0 -14
- package/dist/utils/runTests.js +0 -11
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
import path from "path";
|
|
3
|
+
export const runTestsModule = {
|
|
4
|
+
name: "runTestsModule",
|
|
5
|
+
description: "Runs generated Jest tests with safety checks for a single file",
|
|
6
|
+
async run(input) {
|
|
7
|
+
const { filepath } = input;
|
|
8
|
+
if (!filepath) {
|
|
9
|
+
throw new Error("No filepath provided to runTestsModule.");
|
|
10
|
+
}
|
|
11
|
+
const absoluteFilePath = path.resolve(filepath);
|
|
12
|
+
try {
|
|
13
|
+
// Step 1: TypeScript syntax check for this file only using tsconfig.test.json
|
|
14
|
+
// Step 1: TypeScript syntax check for this file only
|
|
15
|
+
execSync(`npx tsc --noEmit --project tsconfig.test.json`, { stdio: "inherit" });
|
|
16
|
+
// Step 2: Dry-run Jest for this file only
|
|
17
|
+
execSync(`npx jest --config ${path.resolve("jest.config.ts")} --dryRun ${absoluteFilePath}`, { stdio: "inherit" });
|
|
18
|
+
// Step 3: Full Jest run for this file only
|
|
19
|
+
execSync(`npx jest --config ${path.resolve("jest.config.ts")} ${absoluteFilePath}`, { stdio: "inherit" });
|
|
20
|
+
return {
|
|
21
|
+
content: "✅ Tests ran successfully",
|
|
22
|
+
filepath,
|
|
23
|
+
mode: "skip",
|
|
24
|
+
summary: "All tests passed successfully."
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
const errorMessage = error?.message || String(error);
|
|
29
|
+
return {
|
|
30
|
+
content: `❌ Test run failed:\n${errorMessage}`,
|
|
31
|
+
filepath,
|
|
32
|
+
mode: "skip",
|
|
33
|
+
summary: errorMessage // provides failure context for repair
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
@@ -6,6 +6,8 @@ import { commitSuggesterModule } from '../modules/commitSuggesterModule.js';
|
|
|
6
6
|
import { changelogModule } from '../modules/changeLogModule.js';
|
|
7
7
|
import { cleanGeneratedTestsModule } from '../modules/cleanGeneratedTestsModule.js';
|
|
8
8
|
import { preserveCodeModule } from '../modules/preserveCodeModule.js';
|
|
9
|
+
import { runTestsModule } from '../modules/runTestsModule.js';
|
|
10
|
+
import { repairTestsModule } from '../modules/repairTestsModule.js';
|
|
9
11
|
// Built-in modules with metadata
|
|
10
12
|
export const builtInModules = {
|
|
11
13
|
comments: {
|
|
@@ -38,6 +40,21 @@ export const builtInModules = {
|
|
|
38
40
|
...cleanGeneratedTestsModule,
|
|
39
41
|
group: 'testing',
|
|
40
42
|
},
|
|
43
|
+
runTests: {
|
|
44
|
+
...runTestsModule,
|
|
45
|
+
group: 'testing',
|
|
46
|
+
dependencies: {
|
|
47
|
+
before: ['tests'], // must exist after tests are generated
|
|
48
|
+
after: ['cleanTests'], // run after cleaning
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
repairTests: {
|
|
52
|
+
...repairTestsModule,
|
|
53
|
+
group: 'testing',
|
|
54
|
+
dependencies: {
|
|
55
|
+
after: ['runTests'], // repair runs after tests have been executed
|
|
56
|
+
},
|
|
57
|
+
},
|
|
41
58
|
suggest: {
|
|
42
59
|
...commitSuggesterModule,
|
|
43
60
|
group: 'git',
|
package/dist/scripts/dbcheck.js
CHANGED
|
@@ -224,3 +224,101 @@ const functionRows = db.prepare(`
|
|
|
224
224
|
LIMIT 50
|
|
225
225
|
`).all();
|
|
226
226
|
console.table(functionRows);
|
|
227
|
+
// === Class Table Stats ===
|
|
228
|
+
console.log('\n📊 Stats for Table: classes');
|
|
229
|
+
console.log('-------------------------------------------');
|
|
230
|
+
try {
|
|
231
|
+
const classCount = db.prepare(`SELECT COUNT(*) AS count FROM classes`).get().count;
|
|
232
|
+
const distinctClassFiles = db.prepare(`SELECT COUNT(DISTINCT file_id) AS count FROM classes`).get().count;
|
|
233
|
+
console.log(`🏷 Total classes: ${classCount}`);
|
|
234
|
+
console.log(`📂 Distinct files: ${distinctClassFiles}`);
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
console.error('❌ Error accessing classes table:', err.message);
|
|
238
|
+
}
|
|
239
|
+
// === Example Classes ===
|
|
240
|
+
console.log('\n🧪 Example extracted classes:');
|
|
241
|
+
try {
|
|
242
|
+
const sampleClasses = db.prepare(`
|
|
243
|
+
SELECT id, name, file_id, start_line, end_line, substr(content, 1, 100) || '...' AS short_body
|
|
244
|
+
FROM classes
|
|
245
|
+
ORDER BY id DESC
|
|
246
|
+
LIMIT 5
|
|
247
|
+
`).all();
|
|
248
|
+
sampleClasses.forEach(cls => {
|
|
249
|
+
console.log(`🏷 ID: ${cls.id}`);
|
|
250
|
+
console.log(` Name: ${cls.name}`);
|
|
251
|
+
console.log(` File: ${cls.file_id}`);
|
|
252
|
+
console.log(` Lines: ${cls.start_line}-${cls.end_line}`);
|
|
253
|
+
console.log(` Body: ${cls.short_body}\n`);
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
catch (err) {
|
|
257
|
+
console.error('❌ Error printing class examples:', err.message);
|
|
258
|
+
}
|
|
259
|
+
// === Edge Table Stats ===
|
|
260
|
+
console.log('\n📊 Stats for Table: edges');
|
|
261
|
+
console.log('-------------------------------------------');
|
|
262
|
+
try {
|
|
263
|
+
const edgeCount = db.prepare(`SELECT COUNT(*) AS count FROM edges`).get().count;
|
|
264
|
+
const distinctRelations = db.prepare(`SELECT COUNT(DISTINCT relation) AS count FROM edges`).get().count;
|
|
265
|
+
console.log(`🔗 Total edges: ${edgeCount}`);
|
|
266
|
+
console.log(`🧩 Distinct relations: ${distinctRelations}`);
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
console.error('❌ Error accessing edges table:', err.message);
|
|
270
|
+
}
|
|
271
|
+
// === Example Edges ===
|
|
272
|
+
console.log('\n🧪 Example edges:');
|
|
273
|
+
try {
|
|
274
|
+
const sampleEdges = db.prepare(`
|
|
275
|
+
SELECT id, source_id, target_id, relation
|
|
276
|
+
FROM edges
|
|
277
|
+
ORDER BY id DESC
|
|
278
|
+
LIMIT 10
|
|
279
|
+
`).all();
|
|
280
|
+
sampleEdges.forEach(e => {
|
|
281
|
+
console.log(`🔗 Edge ${e.id}: ${e.source_id} -[${e.relation}]-> ${e.target_id}`);
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
catch (err) {
|
|
285
|
+
console.error('❌ Error printing edge examples:', err.message);
|
|
286
|
+
}
|
|
287
|
+
// === Tags Master Stats ===
|
|
288
|
+
console.log('\n📊 Stats for Table: tags_master');
|
|
289
|
+
console.log('-------------------------------------------');
|
|
290
|
+
try {
|
|
291
|
+
const tagCount = db.prepare(`SELECT COUNT(*) AS count FROM tags_master`).get().count;
|
|
292
|
+
console.log(`🏷 Total tags: ${tagCount}`);
|
|
293
|
+
const sampleTags = db.prepare(`
|
|
294
|
+
SELECT id, name
|
|
295
|
+
FROM tags_master
|
|
296
|
+
ORDER BY id DESC
|
|
297
|
+
LIMIT 5
|
|
298
|
+
`).all();
|
|
299
|
+
sampleTags.forEach(tag => {
|
|
300
|
+
console.log(`🏷 Tag ${tag.id}: ${tag.name}`);
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
catch (err) {
|
|
304
|
+
console.error('❌ Error accessing tags_master table:', err.message);
|
|
305
|
+
}
|
|
306
|
+
// === Entity Tags Stats ===
|
|
307
|
+
console.log('\n📊 Stats for Table: entity_tags');
|
|
308
|
+
console.log('-------------------------------------------');
|
|
309
|
+
try {
|
|
310
|
+
const entityTagCount = db.prepare(`SELECT COUNT(*) AS count FROM entity_tags`).get().count;
|
|
311
|
+
console.log(`🔗 Total entity-tags: ${entityTagCount}`);
|
|
312
|
+
const sampleEntityTags = db.prepare(`
|
|
313
|
+
SELECT id, entity_type, entity_id, tag_id
|
|
314
|
+
FROM entity_tags
|
|
315
|
+
ORDER BY id DESC
|
|
316
|
+
LIMIT 10
|
|
317
|
+
`).all();
|
|
318
|
+
sampleEntityTags.forEach(et => {
|
|
319
|
+
console.log(`🔗 EntityTag ${et.id}: ${et.entity_type} ${et.entity_id} -> tag ${et.tag_id}`);
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
catch (err) {
|
|
323
|
+
console.error('❌ Error accessing entity_tags table:', err.message);
|
|
324
|
+
}
|
package/dist/utils/log.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { LOG_PATH } from "../constants.js";
|
|
1
2
|
import fs from 'fs';
|
|
2
|
-
import { LOG_PATH } from '../constants.js';
|
|
3
3
|
export function log(...args) {
|
|
4
4
|
const timestamp = new Date().toISOString();
|
|
5
5
|
const message = args.map(arg => typeof arg === 'string' ? arg : JSON.stringify(arg, null, 2)).join(' ');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scai",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.110",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"scai": "./dist/index.js"
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"workflow"
|
|
35
35
|
],
|
|
36
36
|
"scripts": {
|
|
37
|
-
"build": "rm -rfd dist && tsc && git add .",
|
|
37
|
+
"build": "rm -rfd dist && tsc && chmod +x dist/index.js && git add .",
|
|
38
38
|
"start": "node dist/index.js"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
package/dist/jest.config.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
const config = {
|
|
2
|
-
preset: 'ts-jest',
|
|
3
|
-
testEnvironment: 'node',
|
|
4
|
-
setupFilesAfterEnv: ['./jest.setup.ts'],
|
|
5
|
-
transform: {
|
|
6
|
-
'^.+\\.ts$': 'ts-jest',
|
|
7
|
-
},
|
|
8
|
-
moduleFileExtensions: ['ts', 'js', 'json', 'node'],
|
|
9
|
-
testPathIgnorePatterns: ['/node_modules/', '/dist/'],
|
|
10
|
-
};
|
|
11
|
-
export default config;
|
package/dist/jest.setup.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { jest } from '@jest/globals';
|
|
2
|
-
// jest.setup.ts
|
|
3
|
-
// Mock the global fetch function in Jest for Node.js 18+
|
|
4
|
-
global.fetch = jest.fn(() => Promise.resolve({
|
|
5
|
-
json: () => Promise.resolve({ response: 'Mocked Commit Message' }),
|
|
6
|
-
ok: true,
|
|
7
|
-
status: 200,
|
|
8
|
-
statusText: 'OK',
|
|
9
|
-
headers: new Headers(),
|
|
10
|
-
redirected: false,
|
|
11
|
-
type: 'default',
|
|
12
|
-
url: 'https://mocked-url.com',
|
|
13
|
-
}) // Type assertion for `Response` object
|
|
14
|
-
);
|
package/dist/utils/runTests.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { execSync } from 'child_process';
|
|
2
|
-
export function runJestTest(testFile) {
|
|
3
|
-
try {
|
|
4
|
-
execSync(`npx jest ${testFile} --silent`, { stdio: 'inherit' });
|
|
5
|
-
return true;
|
|
6
|
-
}
|
|
7
|
-
catch (err) {
|
|
8
|
-
console.error(`❌ Tests failed for ${testFile}`);
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
}
|