@stackmemoryai/stackmemory 0.3.9 → 0.3.10

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.
Files changed (40) hide show
  1. package/README.md +53 -0
  2. package/dist/agents/core/agent-task-manager.js +12 -1
  3. package/dist/agents/core/agent-task-manager.js.map +3 -3
  4. package/dist/agents/testing-agent.js +610 -0
  5. package/dist/agents/testing-agent.js.map +7 -0
  6. package/dist/cli/claude-sm.js +2 -2
  7. package/dist/cli/claude-sm.js.map +2 -2
  8. package/dist/cli/codex-sm.js +2 -2
  9. package/dist/cli/codex-sm.js.map +2 -2
  10. package/dist/cli/commands/handoff.js +65 -18
  11. package/dist/cli/commands/handoff.js.map +3 -3
  12. package/dist/cli/commands/onboard.js +3 -3
  13. package/dist/cli/commands/onboard.js.map +2 -2
  14. package/dist/cli/commands/quality.js +2 -2
  15. package/dist/cli/commands/quality.js.map +2 -2
  16. package/dist/cli/commands/skills.js +113 -28
  17. package/dist/cli/commands/skills.js.map +2 -2
  18. package/dist/cli/commands/test.js +282 -0
  19. package/dist/cli/commands/test.js.map +7 -0
  20. package/dist/cli/commands/worktree.js +28 -10
  21. package/dist/cli/commands/worktree.js.map +2 -2
  22. package/dist/cli/index.js +2 -0
  23. package/dist/cli/index.js.map +2 -2
  24. package/dist/core/config/config-manager.js +26 -0
  25. package/dist/core/config/config-manager.js.map +3 -3
  26. package/dist/core/context/frame-manager.js +139 -0
  27. package/dist/core/context/frame-manager.js.map +2 -2
  28. package/dist/core/context/refactored-frame-manager.js +180 -1
  29. package/dist/core/context/refactored-frame-manager.js.map +2 -2
  30. package/dist/core/utils/update-checker.js +2 -2
  31. package/dist/core/utils/update-checker.js.map +2 -2
  32. package/dist/integrations/claude-code/subagent-client-stub.js +16 -0
  33. package/dist/integrations/claude-code/subagent-client-stub.js.map +7 -0
  34. package/dist/skills/claude-skills.js +97 -3
  35. package/dist/skills/claude-skills.js.map +2 -2
  36. package/dist/skills/security-secrets-scanner.js +21 -6
  37. package/dist/skills/security-secrets-scanner.js.map +2 -2
  38. package/dist/skills/unified-rlm-orchestrator.js +400 -0
  39. package/dist/skills/unified-rlm-orchestrator.js.map +7 -0
  40. package/package.json +3 -2
@@ -0,0 +1,610 @@
1
+ import * as ts from "typescript";
2
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
3
+ import { dirname, join, basename } from "path";
4
+ import { execSync } from "child_process";
5
+ import { glob } from "glob";
6
+ import { logger } from "../core/monitoring/logger.js";
7
+ class TestingAgent {
8
+ projectRoot;
9
+ testDir;
10
+ mockDir;
11
+ fixtureDir;
12
+ constructor(projectRoot = process.cwd()) {
13
+ this.projectRoot = projectRoot;
14
+ this.testDir = join(projectRoot, "src", "__tests__");
15
+ this.mockDir = join(projectRoot, "src", "__mocks__");
16
+ this.fixtureDir = join(projectRoot, "src", "__fixtures__");
17
+ }
18
+ /**
19
+ * Analyze code coverage from existing reports
20
+ */
21
+ async analyzeCodeCoverage(targetPath) {
22
+ const coveragePath = join(
23
+ this.projectRoot,
24
+ "coverage",
25
+ "coverage-final.json"
26
+ );
27
+ if (!existsSync(coveragePath)) {
28
+ try {
29
+ execSync("npm run test -- --coverage --silent", {
30
+ cwd: this.projectRoot,
31
+ stdio: "pipe"
32
+ });
33
+ } catch (error) {
34
+ logger.warn("Coverage generation failed", { error });
35
+ }
36
+ }
37
+ if (existsSync(coveragePath)) {
38
+ const coverage = JSON.parse(
39
+ readFileSync(coveragePath, "utf-8")
40
+ );
41
+ const fileCoverage = coverage[targetPath] || {};
42
+ return {
43
+ filePath: targetPath,
44
+ lines: this.calculateCoverage(
45
+ fileCoverage.s || {}
46
+ ),
47
+ branches: this.calculateCoverage(
48
+ fileCoverage.b || {}
49
+ ),
50
+ functions: this.calculateCoverage(
51
+ fileCoverage.f || {}
52
+ ),
53
+ uncoveredLines: this.findUncoveredLines(
54
+ fileCoverage.statementMap || {},
55
+ fileCoverage.s || {}
56
+ )
57
+ };
58
+ }
59
+ return {
60
+ filePath: targetPath,
61
+ lines: { total: 0, covered: 0, percentage: 0 },
62
+ branches: { total: 0, covered: 0, percentage: 0 },
63
+ functions: { total: 0, covered: 0, percentage: 0 },
64
+ uncoveredLines: []
65
+ };
66
+ }
67
+ /**
68
+ * Generate unit tests for a function or module
69
+ */
70
+ async generateUnitTests(targetPath) {
71
+ const sourceCode = readFileSync(targetPath, "utf-8");
72
+ const sourceFile = ts.createSourceFile(
73
+ targetPath,
74
+ sourceCode,
75
+ ts.ScriptTarget.Latest,
76
+ true
77
+ );
78
+ const functions = this.extractFunctions(sourceFile);
79
+ const classes = this.extractClasses(sourceFile);
80
+ const tests = [];
81
+ for (const func of functions) {
82
+ tests.push(...this.generateFunctionTests(func));
83
+ }
84
+ for (const cls of classes) {
85
+ tests.push(...this.generateClassTests(cls));
86
+ }
87
+ const testSuite = {
88
+ filePath: this.getTestPath(targetPath),
89
+ targetPath,
90
+ describe: this.getModuleName(targetPath),
91
+ imports: this.generateImports(targetPath, sourceFile),
92
+ beforeEach: this.generateBeforeEach(classes),
93
+ afterEach: this.generateAfterEach(classes),
94
+ tests
95
+ };
96
+ return testSuite;
97
+ }
98
+ /**
99
+ * Generate integration tests for a module
100
+ */
101
+ async generateIntegrationTests(modulePath) {
102
+ const moduleFiles = glob.sync(join(modulePath, "**/*.ts"), {
103
+ ignore: ["**/*.test.ts", "**/*.spec.ts", "**/node_modules/**"]
104
+ });
105
+ const tests = [];
106
+ const dependencies = /* @__PURE__ */ new Set();
107
+ for (const file of moduleFiles) {
108
+ const sourceCode = readFileSync(file, "utf-8");
109
+ const sourceFile = ts.createSourceFile(
110
+ file,
111
+ sourceCode,
112
+ ts.ScriptTarget.Latest,
113
+ true
114
+ );
115
+ this.findDependencies(sourceFile, dependencies);
116
+ }
117
+ tests.push(
118
+ ...this.generateModuleIntegrationTests(
119
+ modulePath,
120
+ Array.from(dependencies)
121
+ )
122
+ );
123
+ const testSuite = {
124
+ filePath: this.getIntegrationTestPath(modulePath),
125
+ targetPath: modulePath,
126
+ describe: `${basename(modulePath)} Integration`,
127
+ imports: this.generateIntegrationImports(modulePath, dependencies),
128
+ beforeEach: this.generateIntegrationSetup(dependencies),
129
+ afterEach: this.generateIntegrationCleanup(),
130
+ tests
131
+ };
132
+ return testSuite;
133
+ }
134
+ /**
135
+ * Generate edge case tests for a function
136
+ */
137
+ async generateEdgeCaseTests(targetPath, functionName) {
138
+ const sourceCode = readFileSync(targetPath, "utf-8");
139
+ const sourceFile = ts.createSourceFile(
140
+ targetPath,
141
+ sourceCode,
142
+ ts.ScriptTarget.Latest,
143
+ true
144
+ );
145
+ const func = this.findFunction(sourceFile, functionName);
146
+ if (!func) {
147
+ throw new Error(`Function ${functionName} not found in ${targetPath}`);
148
+ }
149
+ return this.generateFunctionEdgeCases(func);
150
+ }
151
+ /**
152
+ * Execute tests and return results
153
+ */
154
+ async executeTests(pattern) {
155
+ try {
156
+ const output = execSync(`npm run test -- ${pattern} --reporter=json`, {
157
+ cwd: this.projectRoot,
158
+ encoding: "utf-8",
159
+ stdio: "pipe"
160
+ });
161
+ const results = JSON.parse(output);
162
+ return {
163
+ passed: results.numPassedTests || 0,
164
+ failed: results.numFailedTests || 0,
165
+ skipped: results.numPendingTests || 0,
166
+ duration: results.duration || 0,
167
+ failures: this.extractFailures(results)
168
+ };
169
+ } catch (error) {
170
+ return {
171
+ passed: 0,
172
+ failed: 1,
173
+ skipped: 0,
174
+ duration: 0,
175
+ failures: [{ test: "Test execution", error: error.message }]
176
+ };
177
+ }
178
+ }
179
+ /**
180
+ * Generate mock data for testing
181
+ */
182
+ generateMockData(schema) {
183
+ const mockType = this.inferTypeFromSchema(schema);
184
+ const mockValue = this.generateMockValue(mockType, schema);
185
+ return {
186
+ name: schema.name || "mockData",
187
+ type: mockType,
188
+ value: mockValue,
189
+ implementation: this.generateMockImplementation(schema)
190
+ };
191
+ }
192
+ /**
193
+ * Create test fixtures
194
+ */
195
+ createTestFixtures(componentName) {
196
+ const fixtures = [];
197
+ fixtures.push({
198
+ name: `${componentName}DefaultProps`,
199
+ data: this.generateDefaultProps(),
200
+ setup: this.generateFixtureSetup(componentName),
201
+ teardown: this.generateFixtureTeardown(componentName)
202
+ });
203
+ fixtures.push({
204
+ name: `${componentName}EdgeCaseProps`,
205
+ data: this.generateEdgeCaseProps()
206
+ });
207
+ fixtures.push({
208
+ name: `${componentName}TestData`,
209
+ data: this.generateTestData()
210
+ });
211
+ return fixtures;
212
+ }
213
+ /**
214
+ * Benchmark performance of a function
215
+ */
216
+ async benchmarkPerformance(targetPath, functionName) {
217
+ const benchmarkCode = this.generateBenchmarkCode(targetPath, functionName);
218
+ const benchmarkFile = join(
219
+ this.testDir,
220
+ "benchmarks",
221
+ `${functionName}.bench.ts`
222
+ );
223
+ const benchDir = dirname(benchmarkFile);
224
+ if (!existsSync(benchDir)) {
225
+ mkdirSync(benchDir, { recursive: true });
226
+ }
227
+ writeFileSync(benchmarkFile, benchmarkCode);
228
+ try {
229
+ const output = execSync(
230
+ `npx vitest bench ${benchmarkFile} --reporter=json`,
231
+ {
232
+ cwd: this.projectRoot,
233
+ encoding: "utf-8",
234
+ stdio: "pipe"
235
+ }
236
+ );
237
+ const results = JSON.parse(output);
238
+ return this.parseBenchmarkResults(results, functionName);
239
+ } catch (error) {
240
+ logger.error("Benchmark failed", { error });
241
+ return {
242
+ function: functionName,
243
+ averageTime: 0,
244
+ minTime: 0,
245
+ maxTime: 0,
246
+ iterations: 0,
247
+ memoryUsage: 0
248
+ };
249
+ }
250
+ }
251
+ /**
252
+ * Save generated test suite to file
253
+ */
254
+ async saveTestSuite(suite) {
255
+ const testCode = this.generateTestCode(suite);
256
+ const testDir = dirname(suite.filePath);
257
+ if (!existsSync(testDir)) {
258
+ mkdirSync(testDir, { recursive: true });
259
+ }
260
+ writeFileSync(suite.filePath, testCode);
261
+ logger.info("Test suite saved", { path: suite.filePath });
262
+ }
263
+ // Private helper methods
264
+ extractFunctions(sourceFile) {
265
+ const functions = [];
266
+ const visit = (node) => {
267
+ if (ts.isFunctionDeclaration(node) && node.name) {
268
+ functions.push(node);
269
+ }
270
+ ts.forEachChild(node, visit);
271
+ };
272
+ visit(sourceFile);
273
+ return functions;
274
+ }
275
+ extractClasses(sourceFile) {
276
+ const classes = [];
277
+ const visit = (node) => {
278
+ if (ts.isClassDeclaration(node) && node.name) {
279
+ classes.push(node);
280
+ }
281
+ ts.forEachChild(node, visit);
282
+ };
283
+ visit(sourceFile);
284
+ return classes;
285
+ }
286
+ generateFunctionTests(func) {
287
+ const tests = [];
288
+ const funcName = func.name?.getText() || "unknown";
289
+ tests.push({
290
+ name: `should execute ${funcName} successfully with valid input`,
291
+ description: `Test normal execution of ${funcName}`,
292
+ action: `const result = ${funcName}();`,
293
+ assertion: "expect(result).toBeDefined();"
294
+ });
295
+ return tests;
296
+ }
297
+ generateClassTests(cls) {
298
+ const tests = [];
299
+ const className = cls.name?.getText() || "UnknownClass";
300
+ tests.push({
301
+ name: `should create instance of ${className}`,
302
+ description: `Test ${className} instantiation`,
303
+ action: `const instance = new ${className}()`,
304
+ assertion: `expect(instance).toBeInstanceOf(${className})`
305
+ });
306
+ return tests;
307
+ }
308
+ generateFunctionEdgeCases(_func) {
309
+ return [];
310
+ }
311
+ generateTestCode(suite) {
312
+ const imports = suite.imports.join("\n");
313
+ const tests = suite.tests.map((test) => this.formatTestCase(test)).join("\n\n ");
314
+ return `/**
315
+ * Generated test suite for ${suite.targetPath}
316
+ * Generated by TestingAgent
317
+ */
318
+
319
+ ${imports}
320
+
321
+ describe('${suite.describe}', () => {
322
+ ${suite.beforeEach ? ` beforeEach(() => {
323
+ ${suite.beforeEach}
324
+ });
325
+ ` : ""}
326
+ ${suite.afterEach ? ` afterEach(() => {
327
+ ${suite.afterEach}
328
+ });
329
+ ` : ""}
330
+ ${tests}
331
+ });
332
+ `;
333
+ }
334
+ formatTestCase(test) {
335
+ return `it('${test.name}', () => {
336
+ ${test.setup ? ` // Arrange
337
+ ${test.setup}
338
+ ` : ""}
339
+ // Act
340
+ ${test.action}
341
+
342
+ // Assert
343
+ ${test.assertion}
344
+ ${test.cleanup ? `
345
+ // Cleanup
346
+ ${test.cleanup}` : ""}
347
+ })`;
348
+ }
349
+ generateImports(targetPath, sourceFile) {
350
+ const imports = [
351
+ `import { describe, it, expect, beforeEach, afterEach } from 'vitest';`
352
+ ];
353
+ const relativePath = this.getRelativePath(
354
+ this.getTestPath(targetPath),
355
+ targetPath
356
+ );
357
+ const exportedNames = this.getExportedNames(sourceFile);
358
+ if (exportedNames.length > 0) {
359
+ imports.push(
360
+ `import { ${exportedNames.join(", ")} } from '${relativePath}';`
361
+ );
362
+ }
363
+ return imports;
364
+ }
365
+ getExportedNames(sourceFile) {
366
+ const exports = [];
367
+ const visit = (node) => {
368
+ if (ts.isFunctionDeclaration(node) && node.name && this.isExported(node)) {
369
+ exports.push(node.name.getText());
370
+ }
371
+ if (ts.isClassDeclaration(node) && node.name && this.isExported(node)) {
372
+ exports.push(node.name.getText());
373
+ }
374
+ ts.forEachChild(node, visit);
375
+ };
376
+ visit(sourceFile);
377
+ return exports;
378
+ }
379
+ isExported(node) {
380
+ return node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) || false;
381
+ }
382
+ getTestPath(targetPath) {
383
+ const relativePath = targetPath.replace(this.projectRoot, "");
384
+ const pathParts = relativePath.split("/");
385
+ const fileName = pathParts.pop();
386
+ const testFileName = fileName?.replace(".ts", ".test.ts");
387
+ return join(
388
+ this.projectRoot,
389
+ "src",
390
+ "__tests__",
391
+ ...pathParts.slice(2),
392
+ testFileName || ""
393
+ );
394
+ }
395
+ getIntegrationTestPath(modulePath) {
396
+ const moduleName = basename(modulePath);
397
+ return join(
398
+ this.testDir,
399
+ "integration",
400
+ `${moduleName}.integration.test.ts`
401
+ );
402
+ }
403
+ getModuleName(targetPath) {
404
+ const fileName = basename(targetPath);
405
+ return fileName.replace(/\.(ts|js)$/, "");
406
+ }
407
+ getRelativePath(from, to) {
408
+ const fromParts = from.split("/");
409
+ const toParts = to.split("/");
410
+ let i = 0;
411
+ while (i < fromParts.length && i < toParts.length && fromParts[i] === toParts[i]) {
412
+ i++;
413
+ }
414
+ const upCount = fromParts.length - i - 1;
415
+ const ups = Array(upCount).fill("..");
416
+ const downs = toParts.slice(i);
417
+ const relativePath = [...ups, ...downs].join("/");
418
+ return relativePath.replace(/\.ts$/, ".js");
419
+ }
420
+ calculateCoverage(coverageData) {
421
+ const values = Object.values(coverageData);
422
+ const total = values.length;
423
+ const covered = values.filter((v) => v > 0).length;
424
+ const percentage = total > 0 ? covered / total * 100 : 0;
425
+ return { total, covered, percentage: Math.round(percentage) };
426
+ }
427
+ findUncoveredLines(statementMap, statements) {
428
+ const uncovered = [];
429
+ Object.entries(statements).forEach(([key, value]) => {
430
+ if (value === 0 && statementMap[key]) {
431
+ const loc = statementMap[key].start;
432
+ uncovered.push(loc.line);
433
+ }
434
+ });
435
+ return uncovered;
436
+ }
437
+ extractFailures(results) {
438
+ const failures = [];
439
+ if (results.testResults) {
440
+ const testResults = results.testResults;
441
+ testResults.forEach((suite) => {
442
+ suite.assertionResults?.forEach((test) => {
443
+ if (test.status === "failed") {
444
+ failures.push({
445
+ test: test.title,
446
+ error: test.failureMessages?.join("\n") || "Unknown error"
447
+ });
448
+ }
449
+ });
450
+ });
451
+ }
452
+ return failures;
453
+ }
454
+ // Mock and fixture generation helpers
455
+ generateMockImplementation(schema) {
456
+ return `export const mock${schema.name || "Data"} = {
457
+ ${this.generateMockProperties(schema)}
458
+ };`;
459
+ }
460
+ generateMockProperties(schema) {
461
+ if (!schema.properties) return "";
462
+ const properties = schema.properties;
463
+ return Object.entries(properties).map(([key, value]) => {
464
+ return `${key}: ${this.generateMockValue(value.type, value)}`;
465
+ }).join(",\n ");
466
+ }
467
+ generateMockValue(type, _schema) {
468
+ switch (type) {
469
+ case "string":
470
+ return `'mock-value'`;
471
+ case "number":
472
+ return `${Math.floor(Math.random() * 100)}`;
473
+ case "boolean":
474
+ return "true";
475
+ case "array":
476
+ return "[]";
477
+ case "object":
478
+ return "{}";
479
+ default:
480
+ return "null";
481
+ }
482
+ }
483
+ inferTypeFromSchema(schema) {
484
+ if (typeof schema === "object" && schema !== null && "type" in schema) {
485
+ return schema.type;
486
+ }
487
+ if (Array.isArray(schema)) return "array";
488
+ if (typeof schema === "object") return "object";
489
+ return typeof schema;
490
+ }
491
+ findDependencies(sourceFile, dependencies) {
492
+ const visit = (node) => {
493
+ if (ts.isImportDeclaration(node)) {
494
+ const moduleSpecifier = node.moduleSpecifier;
495
+ if (ts.isStringLiteral(moduleSpecifier)) {
496
+ dependencies.add(moduleSpecifier.text);
497
+ }
498
+ }
499
+ ts.forEachChild(node, visit);
500
+ };
501
+ visit(sourceFile);
502
+ }
503
+ generateModuleIntegrationTests(modulePath, _dependencies) {
504
+ const tests = [];
505
+ const moduleName = basename(modulePath);
506
+ tests.push({
507
+ name: `should initialize ${moduleName} module`,
508
+ description: `Test module initialization`,
509
+ action: `const module = await import('${modulePath}');`,
510
+ assertion: `expect(module).toBeDefined();`,
511
+ isAsync: true
512
+ });
513
+ return tests;
514
+ }
515
+ generateIntegrationImports(modulePath, dependencies) {
516
+ const imports = [
517
+ `import { describe, it, expect, beforeEach, afterEach } from 'vitest';`
518
+ ];
519
+ dependencies.forEach((dep) => {
520
+ if (!dep.startsWith(".")) {
521
+ const importName = dep.replace(/[^a-zA-Z]/g, "");
522
+ imports.push(`import * as ${importName} from '${dep}';`);
523
+ }
524
+ });
525
+ return imports;
526
+ }
527
+ generateIntegrationSetup(_dependencies) {
528
+ return "const testContext = {};";
529
+ }
530
+ generateIntegrationCleanup() {
531
+ return "// Reset any global state";
532
+ }
533
+ generateBeforeEach(classes) {
534
+ if (classes.length === 0) return void 0;
535
+ return "// Setup test environment";
536
+ }
537
+ generateAfterEach(classes) {
538
+ if (classes.length === 0) return void 0;
539
+ return "// Cleanup test environment";
540
+ }
541
+ findFunction(sourceFile, functionName) {
542
+ let result;
543
+ const visit = (node) => {
544
+ if (ts.isFunctionDeclaration(node) && node.name?.getText() === functionName) {
545
+ result = node;
546
+ }
547
+ if (!result) {
548
+ ts.forEachChild(node, visit);
549
+ }
550
+ };
551
+ visit(sourceFile);
552
+ return result;
553
+ }
554
+ generateDefaultProps() {
555
+ return {
556
+ id: "test-id",
557
+ className: "test-class",
558
+ children: "Test Content"
559
+ };
560
+ }
561
+ generateEdgeCaseProps() {
562
+ return {
563
+ id: "",
564
+ className: null,
565
+ children: void 0
566
+ };
567
+ }
568
+ generateTestData() {
569
+ return {
570
+ items: [
571
+ { id: 1, name: "Item 1" },
572
+ { id: 2, name: "Item 2" }
573
+ ],
574
+ config: {
575
+ enabled: true,
576
+ limit: 10
577
+ }
578
+ };
579
+ }
580
+ generateFixtureSetup(componentName) {
581
+ return `// Setup ${componentName} fixture`;
582
+ }
583
+ generateFixtureTeardown(componentName) {
584
+ return `// Teardown ${componentName} fixture`;
585
+ }
586
+ generateBenchmarkCode(targetPath, functionName) {
587
+ return `import { bench, describe } from 'vitest';
588
+ import { ${functionName} } from '${targetPath}';
589
+
590
+ describe('${functionName} performance', () => {
591
+ bench('${functionName} execution time', () => {
592
+ ${functionName}();
593
+ });
594
+ });`;
595
+ }
596
+ parseBenchmarkResults(results, functionName) {
597
+ return {
598
+ function: functionName,
599
+ averageTime: results.mean || 0,
600
+ minTime: results.min || 0,
601
+ maxTime: results.max || 0,
602
+ iterations: results.samples || 0,
603
+ memoryUsage: results.memory || 0
604
+ };
605
+ }
606
+ }
607
+ export {
608
+ TestingAgent
609
+ };
610
+ //# sourceMappingURL=testing-agent.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/agents/testing-agent.ts"],
4
+ "sourcesContent": ["/**\n * Testing Agent - Automated Test Generation and Execution\n * Analyzes code to generate comprehensive test suites\n */\n\nimport * as ts from 'typescript';\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';\nimport { dirname, join, basename } from 'path';\nimport { execSync } from 'child_process';\nimport { glob } from 'glob';\nimport { logger } from '../core/monitoring/logger.js';\n\ninterface TestCase {\n name: string;\n description: string;\n setup?: string;\n action: string;\n assertion: string;\n cleanup?: string;\n isAsync?: boolean;\n}\n\ninterface TestSuite {\n filePath: string;\n targetPath: string;\n describe: string;\n imports: string[];\n beforeEach?: string;\n afterEach?: string;\n tests: TestCase[];\n}\n\ninterface CoverageReport {\n filePath: string;\n lines: { total: number; covered: number; percentage: number };\n branches: { total: number; covered: number; percentage: number };\n functions: { total: number; covered: number; percentage: number };\n uncoveredLines: number[];\n}\n\ninterface TestResults {\n passed: number;\n failed: number;\n skipped: number;\n duration: number;\n failures: Array<{ test: string; error: string }>;\n}\n\ninterface MockData {\n name: string;\n type: string;\n value: unknown;\n implementation?: string;\n}\n\ninterface Fixture {\n name: string;\n data: unknown;\n setup?: string;\n teardown?: string;\n}\n\ninterface PerfReport {\n function: string;\n averageTime: number;\n minTime: number;\n maxTime: number;\n iterations: number;\n memoryUsage: number;\n}\n\nexport class TestingAgent {\n private readonly projectRoot: string;\n private readonly testDir: string;\n private readonly mockDir: string;\n private readonly fixtureDir: string;\n\n constructor(projectRoot = process.cwd()) {\n this.projectRoot = projectRoot;\n this.testDir = join(projectRoot, 'src', '__tests__');\n this.mockDir = join(projectRoot, 'src', '__mocks__');\n this.fixtureDir = join(projectRoot, 'src', '__fixtures__');\n }\n\n /**\n * Analyze code coverage from existing reports\n */\n public async analyzeCodeCoverage(\n targetPath: string\n ): Promise<CoverageReport> {\n const coveragePath = join(\n this.projectRoot,\n 'coverage',\n 'coverage-final.json'\n );\n\n if (!existsSync(coveragePath)) {\n // Run coverage first\n try {\n execSync('npm run test -- --coverage --silent', {\n cwd: this.projectRoot,\n stdio: 'pipe',\n });\n } catch (error) {\n logger.warn('Coverage generation failed', { error });\n }\n }\n\n // Parse coverage report\n if (existsSync(coveragePath)) {\n const coverage = JSON.parse(\n readFileSync(coveragePath, 'utf-8')\n ) as Record<string, unknown>;\n const fileCoverage =\n (coverage[targetPath] as Record<string, unknown>) || {};\n\n return {\n filePath: targetPath,\n lines: this.calculateCoverage(\n (fileCoverage.s as Record<string, number>) || {}\n ),\n branches: this.calculateCoverage(\n (fileCoverage.b as Record<string, number>) || {}\n ),\n functions: this.calculateCoverage(\n (fileCoverage.f as Record<string, number>) || {}\n ),\n uncoveredLines: this.findUncoveredLines(\n (fileCoverage.statementMap as Record<string, unknown>) || {},\n (fileCoverage.s as Record<string, number>) || {}\n ),\n };\n }\n\n // Default report if no coverage data\n return {\n filePath: targetPath,\n lines: { total: 0, covered: 0, percentage: 0 },\n branches: { total: 0, covered: 0, percentage: 0 },\n functions: { total: 0, covered: 0, percentage: 0 },\n uncoveredLines: [],\n };\n }\n\n /**\n * Generate unit tests for a function or module\n */\n public async generateUnitTests(targetPath: string): Promise<TestSuite> {\n const sourceCode = readFileSync(targetPath, 'utf-8');\n const sourceFile = ts.createSourceFile(\n targetPath,\n sourceCode,\n ts.ScriptTarget.Latest,\n true\n );\n\n const functions = this.extractFunctions(sourceFile);\n const classes = this.extractClasses(sourceFile);\n const tests: TestCase[] = [];\n\n // Generate tests for functions\n for (const func of functions) {\n tests.push(...this.generateFunctionTests(func));\n }\n\n // Generate tests for classes\n for (const cls of classes) {\n tests.push(...this.generateClassTests(cls));\n }\n\n // Create test suite\n const testSuite: TestSuite = {\n filePath: this.getTestPath(targetPath),\n targetPath,\n describe: this.getModuleName(targetPath),\n imports: this.generateImports(targetPath, sourceFile),\n beforeEach: this.generateBeforeEach(classes),\n afterEach: this.generateAfterEach(classes),\n tests,\n };\n\n return testSuite;\n }\n\n /**\n * Generate integration tests for a module\n */\n public async generateIntegrationTests(\n modulePath: string\n ): Promise<TestSuite> {\n const moduleFiles = glob.sync(join(modulePath, '**/*.ts'), {\n ignore: ['**/*.test.ts', '**/*.spec.ts', '**/node_modules/**'],\n });\n\n const tests: TestCase[] = [];\n const dependencies = new Set<string>();\n\n // Analyze module interactions\n for (const file of moduleFiles) {\n const sourceCode = readFileSync(file, 'utf-8');\n const sourceFile = ts.createSourceFile(\n file,\n sourceCode,\n ts.ScriptTarget.Latest,\n true\n );\n\n // Find external dependencies\n this.findDependencies(sourceFile, dependencies);\n }\n\n // Generate integration test cases\n tests.push(\n ...this.generateModuleIntegrationTests(\n modulePath,\n Array.from(dependencies)\n )\n );\n\n const testSuite: TestSuite = {\n filePath: this.getIntegrationTestPath(modulePath),\n targetPath: modulePath,\n describe: `${basename(modulePath)} Integration`,\n imports: this.generateIntegrationImports(modulePath, dependencies),\n beforeEach: this.generateIntegrationSetup(dependencies),\n afterEach: this.generateIntegrationCleanup(),\n tests,\n };\n\n return testSuite;\n }\n\n /**\n * Generate edge case tests for a function\n */\n public async generateEdgeCaseTests(\n targetPath: string,\n functionName: string\n ): Promise<TestCase[]> {\n const sourceCode = readFileSync(targetPath, 'utf-8');\n const sourceFile = ts.createSourceFile(\n targetPath,\n sourceCode,\n ts.ScriptTarget.Latest,\n true\n );\n\n const func = this.findFunction(sourceFile, functionName);\n if (!func) {\n throw new Error(`Function ${functionName} not found in ${targetPath}`);\n }\n\n return this.generateFunctionEdgeCases(func);\n }\n\n /**\n * Execute tests and return results\n */\n public async executeTests(pattern: string): Promise<TestResults> {\n try {\n const output = execSync(`npm run test -- ${pattern} --reporter=json`, {\n cwd: this.projectRoot,\n encoding: 'utf-8',\n stdio: 'pipe',\n });\n\n const results = JSON.parse(output) as Record<string, unknown>;\n return {\n passed: (results.numPassedTests as number) || 0,\n failed: (results.numFailedTests as number) || 0,\n skipped: (results.numPendingTests as number) || 0,\n duration: (results.duration as number) || 0,\n failures: this.extractFailures(results),\n };\n } catch (error: unknown) {\n // Parse error output\n return {\n passed: 0,\n failed: 1,\n skipped: 0,\n duration: 0,\n failures: [{ test: 'Test execution', error: (error as Error).message }],\n };\n }\n }\n\n /**\n * Generate mock data for testing\n */\n public generateMockData(schema: Record<string, unknown>): MockData {\n const mockType = this.inferTypeFromSchema(schema);\n const mockValue = this.generateMockValue(mockType, schema);\n\n return {\n name: (schema.name as string) || 'mockData',\n type: mockType,\n value: mockValue,\n implementation: this.generateMockImplementation(schema),\n };\n }\n\n /**\n * Create test fixtures\n */\n public createTestFixtures(componentName: string): Fixture[] {\n const fixtures: Fixture[] = [];\n\n // Generate common fixtures\n fixtures.push({\n name: `${componentName}DefaultProps`,\n data: this.generateDefaultProps(),\n setup: this.generateFixtureSetup(componentName),\n teardown: this.generateFixtureTeardown(componentName),\n });\n\n fixtures.push({\n name: `${componentName}EdgeCaseProps`,\n data: this.generateEdgeCaseProps(),\n });\n\n fixtures.push({\n name: `${componentName}TestData`,\n data: this.generateTestData(),\n });\n\n return fixtures;\n }\n\n /**\n * Benchmark performance of a function\n */\n public async benchmarkPerformance(\n targetPath: string,\n functionName: string\n ): Promise<PerfReport> {\n const benchmarkCode = this.generateBenchmarkCode(targetPath, functionName);\n const benchmarkFile = join(\n this.testDir,\n 'benchmarks',\n `${functionName}.bench.ts`\n );\n\n // Ensure directory exists\n const benchDir = dirname(benchmarkFile);\n if (!existsSync(benchDir)) {\n mkdirSync(benchDir, { recursive: true });\n }\n\n // Write benchmark file\n writeFileSync(benchmarkFile, benchmarkCode);\n\n // Run benchmark\n try {\n const output = execSync(\n `npx vitest bench ${benchmarkFile} --reporter=json`,\n {\n cwd: this.projectRoot,\n encoding: 'utf-8',\n stdio: 'pipe',\n }\n );\n\n const results = JSON.parse(output) as Record<string, unknown>;\n return this.parseBenchmarkResults(results, functionName);\n } catch (error) {\n logger.error('Benchmark failed', { error });\n return {\n function: functionName,\n averageTime: 0,\n minTime: 0,\n maxTime: 0,\n iterations: 0,\n memoryUsage: 0,\n };\n }\n }\n\n /**\n * Save generated test suite to file\n */\n public async saveTestSuite(suite: TestSuite): Promise<void> {\n const testCode = this.generateTestCode(suite);\n const testDir = dirname(suite.filePath);\n\n // Ensure directory exists\n if (!existsSync(testDir)) {\n mkdirSync(testDir, { recursive: true });\n }\n\n writeFileSync(suite.filePath, testCode);\n logger.info('Test suite saved', { path: suite.filePath });\n }\n\n // Private helper methods\n\n private extractFunctions(\n sourceFile: ts.SourceFile\n ): ts.FunctionDeclaration[] {\n const functions: ts.FunctionDeclaration[] = [];\n\n const visit = (node: ts.Node) => {\n if (ts.isFunctionDeclaration(node) && node.name) {\n functions.push(node);\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return functions;\n }\n\n private extractClasses(sourceFile: ts.SourceFile): ts.ClassDeclaration[] {\n const classes: ts.ClassDeclaration[] = [];\n\n const visit = (node: ts.Node) => {\n if (ts.isClassDeclaration(node) && node.name) {\n classes.push(node);\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return classes;\n }\n\n private generateFunctionTests(func: ts.FunctionDeclaration): TestCase[] {\n const tests: TestCase[] = [];\n const funcName = func.name?.getText() || 'unknown';\n\n // Happy path test\n tests.push({\n name: `should execute ${funcName} successfully with valid input`,\n description: `Test normal execution of ${funcName}`,\n action: `const result = ${funcName}();`,\n assertion: 'expect(result).toBeDefined();',\n });\n\n return tests;\n }\n\n private generateClassTests(cls: ts.ClassDeclaration): TestCase[] {\n const tests: TestCase[] = [];\n const className = cls.name?.getText() || 'UnknownClass';\n\n // Constructor test\n tests.push({\n name: `should create instance of ${className}`,\n description: `Test ${className} instantiation`,\n action: `const instance = new ${className}()`,\n assertion: `expect(instance).toBeInstanceOf(${className})`,\n });\n\n return tests;\n }\n\n private generateFunctionEdgeCases(_func: ts.FunctionDeclaration): TestCase[] {\n return [];\n }\n\n private generateTestCode(suite: TestSuite): string {\n const imports = suite.imports.join('\\n');\n const tests = suite.tests\n .map((test) => this.formatTestCase(test))\n .join('\\n\\n ');\n\n return `/**\n * Generated test suite for ${suite.targetPath}\n * Generated by TestingAgent\n */\n\n${imports}\n\ndescribe('${suite.describe}', () => {\n${suite.beforeEach ? ` beforeEach(() => {\\n ${suite.beforeEach}\\n });\\n` : ''}\n${suite.afterEach ? ` afterEach(() => {\\n ${suite.afterEach}\\n });\\n` : ''}\n ${tests}\n});\n`;\n }\n\n private formatTestCase(test: TestCase): string {\n return `it('${test.name}', () => {\n${test.setup ? ` // Arrange\\n ${test.setup}\\n` : ''}\n // Act\n ${test.action}\n\n // Assert\n ${test.assertion}\n${test.cleanup ? `\\n // Cleanup\\n ${test.cleanup}` : ''}\n })`;\n }\n\n private generateImports(\n targetPath: string,\n sourceFile: ts.SourceFile\n ): string[] {\n const imports: string[] = [\n `import { describe, it, expect, beforeEach, afterEach } from 'vitest';`,\n ];\n\n // Import the module being tested\n const relativePath = this.getRelativePath(\n this.getTestPath(targetPath),\n targetPath\n );\n const exportedNames = this.getExportedNames(sourceFile);\n if (exportedNames.length > 0) {\n imports.push(\n `import { ${exportedNames.join(', ')} } from '${relativePath}';`\n );\n }\n\n return imports;\n }\n\n private getExportedNames(sourceFile: ts.SourceFile): string[] {\n const exports: string[] = [];\n\n const visit = (node: ts.Node) => {\n if (\n ts.isFunctionDeclaration(node) &&\n node.name &&\n this.isExported(node)\n ) {\n exports.push(node.name.getText());\n }\n if (ts.isClassDeclaration(node) && node.name && this.isExported(node)) {\n exports.push(node.name.getText());\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return exports;\n }\n\n private isExported(node: ts.Node): boolean {\n return (\n node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ||\n false\n );\n }\n\n private getTestPath(targetPath: string): string {\n const relativePath = targetPath.replace(this.projectRoot, '');\n const pathParts = relativePath.split('/');\n const fileName = pathParts.pop();\n const testFileName = fileName?.replace('.ts', '.test.ts');\n\n return join(\n this.projectRoot,\n 'src',\n '__tests__',\n ...pathParts.slice(2),\n testFileName || ''\n );\n }\n\n private getIntegrationTestPath(modulePath: string): string {\n const moduleName = basename(modulePath);\n return join(\n this.testDir,\n 'integration',\n `${moduleName}.integration.test.ts`\n );\n }\n\n private getModuleName(targetPath: string): string {\n const fileName = basename(targetPath);\n return fileName.replace(/\\.(ts|js)$/, '');\n }\n\n private getRelativePath(from: string, to: string): string {\n const fromParts = from.split('/');\n const toParts = to.split('/');\n\n // Find common base\n let i = 0;\n while (\n i < fromParts.length &&\n i < toParts.length &&\n fromParts[i] === toParts[i]\n ) {\n i++;\n }\n\n // Generate relative path\n const upCount = fromParts.length - i - 1;\n const ups = Array(upCount).fill('..');\n const downs = toParts.slice(i);\n\n const relativePath = [...ups, ...downs].join('/');\n return relativePath.replace(/\\.ts$/, '.js');\n }\n\n private calculateCoverage(coverageData: Record<string, number>): {\n total: number;\n covered: number;\n percentage: number;\n } {\n const values = Object.values(coverageData);\n const total = values.length;\n const covered = values.filter((v) => v > 0).length;\n const percentage = total > 0 ? (covered / total) * 100 : 0;\n\n return { total, covered, percentage: Math.round(percentage) };\n }\n\n private findUncoveredLines(\n statementMap: Record<string, unknown>,\n statements: Record<string, number>\n ): number[] {\n const uncovered: number[] = [];\n\n Object.entries(statements).forEach(([key, value]) => {\n if (value === 0 && statementMap[key]) {\n const loc = (statementMap[key] as { start: { line: number } }).start;\n uncovered.push(loc.line);\n }\n });\n\n return uncovered;\n }\n\n private extractFailures(\n results: Record<string, unknown>\n ): Array<{ test: string; error: string }> {\n const failures: Array<{ test: string; error: string }> = [];\n\n if (results.testResults) {\n const testResults = results.testResults as Array<{\n assertionResults?: Array<{\n status: string;\n title: string;\n failureMessages?: string[];\n }>;\n }>;\n testResults.forEach((suite) => {\n suite.assertionResults?.forEach((test) => {\n if (test.status === 'failed') {\n failures.push({\n test: test.title,\n error: test.failureMessages?.join('\\n') || 'Unknown error',\n });\n }\n });\n });\n }\n\n return failures;\n }\n\n // Mock and fixture generation helpers\n private generateMockImplementation(schema: Record<string, unknown>): string {\n return `export const mock${(schema.name as string) || 'Data'} = {\n ${this.generateMockProperties(schema)}\n};`;\n }\n\n private generateMockProperties(schema: Record<string, unknown>): string {\n if (!schema.properties) return '';\n\n const properties = schema.properties as Record<string, { type: string }>;\n return Object.entries(properties)\n .map(([key, value]) => {\n return `${key}: ${this.generateMockValue(value.type, value)}`;\n })\n .join(',\\n ');\n }\n\n private generateMockValue(type: string, _schema: unknown): string {\n switch (type) {\n case 'string':\n return `'mock-value'`;\n case 'number':\n return `${Math.floor(Math.random() * 100)}`;\n case 'boolean':\n return 'true';\n case 'array':\n return '[]';\n case 'object':\n return '{}';\n default:\n return 'null';\n }\n }\n\n private inferTypeFromSchema(schema: unknown): string {\n if (typeof schema === 'object' && schema !== null && 'type' in schema) {\n return (schema as { type: string }).type;\n }\n if (Array.isArray(schema)) return 'array';\n if (typeof schema === 'object') return 'object';\n return typeof schema;\n }\n\n private findDependencies(\n sourceFile: ts.SourceFile,\n dependencies: Set<string>\n ): void {\n const visit = (node: ts.Node) => {\n if (ts.isImportDeclaration(node)) {\n const moduleSpecifier = node.moduleSpecifier;\n if (ts.isStringLiteral(moduleSpecifier)) {\n dependencies.add(moduleSpecifier.text);\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n }\n\n private generateModuleIntegrationTests(\n modulePath: string,\n _dependencies: string[]\n ): TestCase[] {\n const tests: TestCase[] = [];\n const moduleName = basename(modulePath);\n\n tests.push({\n name: `should initialize ${moduleName} module`,\n description: `Test module initialization`,\n action: `const module = await import('${modulePath}');`,\n assertion: `expect(module).toBeDefined();`,\n isAsync: true,\n });\n\n return tests;\n }\n\n private generateIntegrationImports(\n modulePath: string,\n dependencies: Set<string>\n ): string[] {\n const imports = [\n `import { describe, it, expect, beforeEach, afterEach } from 'vitest';`,\n ];\n\n // Add dependency imports\n dependencies.forEach((dep) => {\n if (!dep.startsWith('.')) {\n const importName = dep.replace(/[^a-zA-Z]/g, '');\n imports.push(`import * as ${importName} from '${dep}';`);\n }\n });\n\n return imports;\n }\n\n private generateIntegrationSetup(_dependencies: Set<string>): string {\n return 'const testContext = {};';\n }\n\n private generateIntegrationCleanup(): string {\n return '// Reset any global state';\n }\n\n private generateBeforeEach(\n classes: ts.ClassDeclaration[]\n ): string | undefined {\n if (classes.length === 0) return undefined;\n return '// Setup test environment';\n }\n\n private generateAfterEach(\n classes: ts.ClassDeclaration[]\n ): string | undefined {\n if (classes.length === 0) return undefined;\n return '// Cleanup test environment';\n }\n\n private findFunction(\n sourceFile: ts.SourceFile,\n functionName: string\n ): ts.FunctionDeclaration | undefined {\n let result: ts.FunctionDeclaration | undefined;\n\n const visit = (node: ts.Node) => {\n if (\n ts.isFunctionDeclaration(node) &&\n node.name?.getText() === functionName\n ) {\n result = node;\n }\n if (!result) {\n ts.forEachChild(node, visit);\n }\n };\n\n visit(sourceFile);\n return result;\n }\n\n private generateDefaultProps(): Record<string, unknown> {\n return {\n id: 'test-id',\n className: 'test-class',\n children: 'Test Content',\n };\n }\n\n private generateEdgeCaseProps(): Record<string, unknown> {\n return {\n id: '',\n className: null,\n children: undefined,\n };\n }\n\n private generateTestData(): Record<string, unknown> {\n return {\n items: [\n { id: 1, name: 'Item 1' },\n { id: 2, name: 'Item 2' },\n ],\n config: {\n enabled: true,\n limit: 10,\n },\n };\n }\n\n private generateFixtureSetup(componentName: string): string {\n return `// Setup ${componentName} fixture`;\n }\n\n private generateFixtureTeardown(componentName: string): string {\n return `// Teardown ${componentName} fixture`;\n }\n\n private generateBenchmarkCode(\n targetPath: string,\n functionName: string\n ): string {\n return `import { bench, describe } from 'vitest';\nimport { ${functionName} } from '${targetPath}';\n\ndescribe('${functionName} performance', () => {\n bench('${functionName} execution time', () => {\n ${functionName}();\n });\n});`;\n }\n\n private parseBenchmarkResults(\n results: Record<string, unknown>,\n functionName: string\n ): PerfReport {\n return {\n function: functionName,\n averageTime: (results.mean as number) || 0,\n minTime: (results.min as number) || 0,\n maxTime: (results.max as number) || 0,\n iterations: (results.samples as number) || 0,\n memoryUsage: (results.memory as number) || 0,\n };\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }