codehere 0.2.2 → 0.3.0-rc.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.
- package/README.md +88 -68
- package/dist/domain/entities/task.js +4 -4
- package/dist/error-handler.js +4 -9
- package/dist/index.js +261 -1224
- package/dist/infrastructure/config/product-context.js +7 -6
- package/dist/infrastructure/hooks/claude-sdk-hook.js +348 -72
- package/dist/infrastructure/observability/execution-tracer.js +11 -6
- package/dist/infrastructure/orchestration/agent-adapter.js +13 -0
- package/dist/infrastructure/orchestration/agent-installer.js +101 -0
- package/dist/infrastructure/orchestration/agents-config-seed.js +56 -0
- package/dist/infrastructure/orchestration/aider-adapter.js +319 -0
- package/dist/infrastructure/orchestration/artifacts-extractor.js +175 -0
- package/dist/infrastructure/orchestration/claude-code-adapter.js +352 -0
- package/dist/infrastructure/orchestration/codex-adapter.js +310 -0
- package/dist/infrastructure/orchestration/conductor-adapter.js +340 -0
- package/dist/infrastructure/orchestration/generic-cli-adapter.js +553 -0
- package/dist/infrastructure/orchestration/opencode-adapter.js +275 -0
- package/dist/infrastructure/orchestration/progress-aggregator.js +189 -0
- package/dist/infrastructure/orchestration/readiness.js +106 -0
- package/dist/infrastructure/orchestration/session-manager.js +278 -0
- package/dist/infrastructure/orchestration/session-persistence.js +109 -0
- package/dist/infrastructure/protocols/mcp-helpers.js +10 -30
- package/dist/infrastructure/protocols/mcp-server-impl.js +359 -21
- package/dist/infrastructure/protocols/probe-port.js +36 -0
- package/dist/infrastructure/protocols/ui-page.js +1827 -0
- package/dist/infrastructure/security/file-collection.js +115 -0
- package/dist/infrastructure/security/trust-scorer.js +301 -56
- package/dist/infrastructure/storage/task-repository.js +8 -7
- package/dist/monitoring.js +9 -38
- package/dist/presentation/cli/commands/help-command.js +96 -139
- package/dist/presentation/cli/commands/hook-command.js +17 -24
- package/dist/presentation/cli/commands/report-command.js +59 -72
- package/dist/presentation/cli/commands/setup-command.js +4 -4
- package/dist/presentation/cli/commands/status-command.js +321 -30
- package/dist/presentation/cli/commands/trust-command.js +84 -72
- package/dist/presentation/cli/error-display.js +17 -21
- package/dist/presentation/cli/repl.js +474 -0
- package/dist/ui.js +11 -11
- package/package.json +24 -62
- package/dist/agents/base.js +0 -101
- package/dist/agents/orchestrator-model-driven.js +0 -141
- package/dist/agents/react-orchestrator-agent.js +0 -54
- package/dist/application/agents/execution-agent.js +0 -508
- package/dist/application/agents/multi-agent-orchestrator.js +0 -295
- package/dist/application/agents/planning-agent.js +0 -433
- package/dist/application/agents/validation-agent.js +0 -317
- package/dist/application/architectures/plan-and-act.js +0 -242
- package/dist/application/index.js +0 -12
- package/dist/application/services/agent-factory.js +0 -28
- package/dist/application/services/dependency-container.js +0 -596
- package/dist/application/services/git-context-service.js +0 -83
- package/dist/application/services/intelligent-router.js +0 -934
- package/dist/application/services/tool-executor-service.js +0 -94
- package/dist/application/use-cases/ask-question-use-case.js +0 -338
- package/dist/application/use-cases/edit-file-use-case.js +0 -830
- package/dist/application/use-cases/explain-file-use-case.js +0 -50
- package/dist/application/use-cases/index-codebase-use-case.js +0 -113
- package/dist/application/use-cases/planning-use-case.js +0 -276
- package/dist/application/use-cases/react-orchestration-use-case.js +0 -329
- package/dist/application/use-cases/reflexion-use-case.js +0 -30
- package/dist/application/workflows/deterministic-workflows.js +0 -189
- package/dist/ast-parser.js +0 -331
- package/dist/cache.js +0 -180
- package/dist/chat.js +0 -251
- package/dist/code-analysis.js +0 -327
- package/dist/context.js +0 -187
- package/dist/docs.js +0 -146
- package/dist/domain/entities/code-chunk.js +0 -6
- package/dist/domain/entities/decision.js +0 -9
- package/dist/domain/entities/edit.js +0 -6
- package/dist/domain/entities/knowledge-node.js +0 -9
- package/dist/domain/entities/knowledge-preservation.js +0 -10
- package/dist/domain/entities/memory.js +0 -6
- package/dist/domain/entities/pattern.js +0 -7
- package/dist/domain/entities/plan.js +0 -6
- package/dist/domain/entities/query.js +0 -6
- package/dist/domain/errors/embeddings-not-found-error.js +0 -13
- package/dist/domain/index.js +0 -19
- package/dist/domain/interfaces/ai-service.interface.js +0 -6
- package/dist/domain/interfaces/code-analyzer.interface.js +0 -6
- package/dist/domain/interfaces/decision-repository.interface.js +0 -9
- package/dist/domain/interfaces/embedding-repository.interface.js +0 -6
- package/dist/domain/interfaces/knowledge-graph-repository.interface.js +0 -9
- package/dist/domain/interfaces/knowledge-preservation-repository.interface.js +0 -8
- package/dist/domain/interfaces/memory-repository.interface.js +0 -6
- package/dist/domain/interfaces/pattern-repository.interface.js +0 -6
- package/dist/domain/interfaces/verification-service.interface.js +0 -6
- package/dist/domain/services/cross-team-pattern-sharing.js +0 -125
- package/dist/domain/services/decision-recorder.js +0 -223
- package/dist/domain/services/decision-retriever.js +0 -133
- package/dist/domain/services/environment-mode-manager.js +0 -22
- package/dist/domain/services/graded-memory-activation.js +0 -69
- package/dist/domain/services/knowledge-access.js +0 -132
- package/dist/domain/services/knowledge-extractor.js +0 -247
- package/dist/domain/services/knowledge-graph-builder.js +0 -268
- package/dist/domain/services/knowledge-graph-query.js +0 -187
- package/dist/domain/services/memory-retriever.js +0 -82
- package/dist/domain/services/memory-synthesizer.js +0 -91
- package/dist/domain/services/pattern-extractor.js +0 -442
- package/dist/domain/services/query-intent-classifier.js +0 -140
- package/dist/domain/services/react-loop.js +0 -186
- package/dist/domain/services/risk-tier-detector.js +0 -78
- package/dist/edit.js +0 -319
- package/dist/embed.js +0 -459
- package/dist/formatter.js +0 -168
- package/dist/git.js +0 -198
- package/dist/infrastructure/ai/cohere-ai-service.js +0 -607
- package/dist/infrastructure/ai/command-r-evaluation.js +0 -206
- package/dist/infrastructure/ai/model-config.js +0 -84
- package/dist/infrastructure/ai/provider-ai-service.js +0 -477
- package/dist/infrastructure/cache/embedding-cache.js +0 -175
- package/dist/infrastructure/cache/query-result-cache.js +0 -66
- package/dist/infrastructure/cache/response-cache.js +0 -48
- package/dist/infrastructure/cache/security-scan-cache.js +0 -47
- package/dist/infrastructure/chunking/ast-code-chunker.js +0 -19
- package/dist/infrastructure/chunking/code-aware-chunker.js +0 -397
- package/dist/infrastructure/context/context-compressor.js +0 -329
- package/dist/infrastructure/context/conversation-context.js +0 -128
- package/dist/infrastructure/context/session-manager.js +0 -94
- package/dist/infrastructure/cost/cost-tracker.js +0 -360
- package/dist/infrastructure/file-scanner/file-scanner.js +0 -106
- package/dist/infrastructure/governance/nist-ai-rmf.js +0 -292
- package/dist/infrastructure/governance/policy-as-code.js +0 -258
- package/dist/infrastructure/governance/prompt-to-code-lineage.js +0 -239
- package/dist/infrastructure/index.js +0 -7
- package/dist/infrastructure/observability/prompt-versioner.js +0 -145
- package/dist/infrastructure/protocols/a2a-metadata.js +0 -137
- package/dist/infrastructure/protocols/a2a-protocol.js +0 -314
- package/dist/infrastructure/protocols/mcp-oauth.js +0 -184
- package/dist/infrastructure/protocols/mcp-server.js +0 -333
- package/dist/infrastructure/protocols/streaming-handler.js +0 -103
- package/dist/infrastructure/providers/cohere-provider.js +0 -444
- package/dist/infrastructure/providers/fake-provider.js +0 -130
- package/dist/infrastructure/providers/local-llm-provider.js +0 -330
- package/dist/infrastructure/providers/model-config.types.js +0 -9
- package/dist/infrastructure/providers/model-provider.interface.js +0 -8
- package/dist/infrastructure/providers/openai-provider.js +0 -413
- package/dist/infrastructure/providers/openrouter-provider.js +0 -399
- package/dist/infrastructure/providers/operation-provider-resolver.js +0 -105
- package/dist/infrastructure/providers/provider-config-loader.js +0 -120
- package/dist/infrastructure/providers/provider-registry.js +0 -88
- package/dist/infrastructure/safety/pattern-detector.js +0 -133
- package/dist/infrastructure/security/ai-sast-scanner.js +0 -290
- package/dist/infrastructure/security/docker-sandbox.js +0 -178
- package/dist/infrastructure/security/enhanced-security-gate.js +0 -151
- package/dist/infrastructure/security/license-scanner.js +0 -167
- package/dist/infrastructure/security/provider-bias-detector.js +0 -164
- package/dist/infrastructure/security/sandbox-executor.js +0 -64
- package/dist/infrastructure/serialization/toon-serializer.js +0 -119
- package/dist/infrastructure/storage/memory-stream-service.js +0 -204
- package/dist/infrastructure/storage/plan-repository.js +0 -96
- package/dist/infrastructure/storage/sqlite-decision-repository.js +0 -232
- package/dist/infrastructure/storage/sqlite-embedding-repository.js +0 -311
- package/dist/infrastructure/storage/sqlite-knowledge-graph-repository.js +0 -417
- package/dist/infrastructure/storage/sqlite-knowledge-preservation-repository.js +0 -230
- package/dist/infrastructure/storage/sqlite-memory-repository.js +0 -229
- package/dist/infrastructure/storage/sqlite-pattern-repository.js +0 -249
- package/dist/infrastructure/storage/task-helpers.js +0 -197
- package/dist/infrastructure/telemetry/telemetry-service.js +0 -167
- package/dist/infrastructure/ux/appropriate-friction.js +0 -213
- package/dist/infrastructure/ux/bi-directional-learning.js +0 -337
- package/dist/infrastructure/ux/capability-boundaries.js +0 -42
- package/dist/infrastructure/ux/comprehensive-formatter.js +0 -117
- package/dist/infrastructure/ux/contextual-feature-discovery.js +0 -10
- package/dist/infrastructure/ux/expectation-management.js +0 -327
- package/dist/infrastructure/ux/feature-discovery.js +0 -14
- package/dist/infrastructure/ux/feedback-prompt.js +0 -45
- package/dist/infrastructure/ux/hitl-validation.js +0 -297
- package/dist/infrastructure/ux/progress-indicator.js +0 -116
- package/dist/infrastructure/ux/progressive-disclosure.js +0 -236
- package/dist/infrastructure/ux/review-checkpoint.js +0 -72
- package/dist/infrastructure/ux/staged-feature-intro.js +0 -24
- package/dist/infrastructure/ux/stream-markdown.js +0 -151
- package/dist/infrastructure/ux/syntax-highlighter.js +0 -91
- package/dist/infrastructure/ux/team-standards.js +0 -196
- package/dist/infrastructure/ux/transparency.js +0 -71
- package/dist/infrastructure/validation/agent-feedback.js +0 -55
- package/dist/infrastructure/validation/agent-validation-helper.js +0 -137
- package/dist/infrastructure/validation/review-handler.js +0 -40
- package/dist/infrastructure/validation/summary-aggregator.js +0 -70
- package/dist/infrastructure/validation/summary-extractor.js +0 -45
- package/dist/infrastructure/validation/trace-summary.js +0 -52
- package/dist/infrastructure/verification/verification-service.js +0 -47
- package/dist/infrastructure/xai/attention-visualizer.js +0 -172
- package/dist/infrastructure/xai/cot-visualizer.js +0 -283
- package/dist/infrastructure/xai/decision-tree-log.js +0 -212
- package/dist/infrastructure/xai/interactive-xai.js +0 -260
- package/dist/infrastructure/xai/uncertainty-quantifier.js +0 -198
- package/dist/intelligent-retrieval.js +0 -272
- package/dist/intent/classifier.js +0 -2
- package/dist/intent/context.js +0 -2
- package/dist/iterative-refinement.js +0 -189
- package/dist/learning.js +0 -232
- package/dist/log.js +0 -31
- package/dist/migrate.js +0 -133
- package/dist/parallel-processor.js +0 -534
- package/dist/planner.js +0 -198
- package/dist/policy.js +0 -26
- package/dist/presentation/cli/commands/ask-command.js +0 -314
- package/dist/presentation/cli/commands/cost-command.js +0 -191
- package/dist/presentation/cli/commands/decision-command.js +0 -207
- package/dist/presentation/cli/commands/docs-command.js +0 -25
- package/dist/presentation/cli/commands/fix-command.js +0 -53
- package/dist/presentation/cli/commands/knowledge-command.js +0 -129
- package/dist/presentation/cli/commands/learning-dashboard-command.js +0 -183
- package/dist/presentation/cli/commands/models-command.js +0 -194
- package/dist/presentation/cli/commands/orchestrate-command.js +0 -207
- package/dist/presentation/cli/commands/plan-command.js +0 -246
- package/dist/presentation/cli/commands/product-command.js +0 -199
- package/dist/presentation/cli/commands/react-command.js +0 -181
- package/dist/presentation/cli/commands/review-command.js +0 -154
- package/dist/presentation/cli/commands/run-command.js +0 -188
- package/dist/presentation/cli/commands/smart-command.js +0 -395
- package/dist/presentation/cli/commands/suggest-command.js +0 -138
- package/dist/presentation/cli/commands/trace-command.js +0 -129
- package/dist/presentation/cli/commands/undo-command.js +0 -150
- package/dist/query-optimizer.js +0 -205
- package/dist/refactor.js +0 -116
- package/dist/review.js +0 -206
- package/dist/search.js +0 -163
- package/dist/session.js +0 -704
- package/dist/task-verification.js +0 -336
- package/dist/testgen.js +0 -166
- package/dist/token-optimizer.js +0 -277
- package/dist/tools/bash.js +0 -213
- package/dist/tools/edit.js +0 -235
- package/dist/tools/executor.js +0 -153
- package/dist/tools/git-tool.js +0 -292
- package/dist/tools/parser.js +0 -158
- package/dist/tools/registry.js +0 -302
- package/dist/tools/search.js +0 -100
- package/dist/types.js +0 -2
- package/dist/utils/check-api-status.js +0 -100
- package/dist/utils/diff-parser.js +0 -162
- package/dist/verification/backup.js +0 -259
- package/dist/verification/compiler.js +0 -264
- package/dist/verification/index.js +0 -273
- package/dist/verification/test-runner.js +0 -379
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unified Verification Interface
|
|
3
|
-
* Provides a single entry point for all verification operations
|
|
4
|
-
*/
|
|
5
|
-
import { existsSync } from 'fs';
|
|
6
|
-
import { verifyCompilation } from './compiler.js';
|
|
7
|
-
import { runTests } from './test-runner.js';
|
|
8
|
-
import { backupFile, rollbackFile } from './backup.js';
|
|
9
|
-
/**
|
|
10
|
-
* Verify file after edit
|
|
11
|
-
*
|
|
12
|
-
* This function:
|
|
13
|
-
* 1. Creates a backup (if autoRollback is enabled)
|
|
14
|
-
* 2. Verifies compilation (if verifyCompilation is enabled)
|
|
15
|
-
* 3. Runs tests (if runTests is enabled)
|
|
16
|
-
* 4. Returns comprehensive result
|
|
17
|
-
*
|
|
18
|
-
* Use with applyEditWithVerification() for automatic rollback on failure
|
|
19
|
-
*/
|
|
20
|
-
export async function verifyFile(filepath, options = {}) {
|
|
21
|
-
const { verifyCompilation: shouldVerifyCompilation = true, runTests: shouldRunTests = true, autoRollback: shouldAutoRollback = true, compilationOptions = {}, testOptions = {}, } = options;
|
|
22
|
-
const result = {
|
|
23
|
-
success: false,
|
|
24
|
-
compiled: false,
|
|
25
|
-
testsPassed: false,
|
|
26
|
-
errors: [],
|
|
27
|
-
warnings: [],
|
|
28
|
-
rollbackRequired: false,
|
|
29
|
-
};
|
|
30
|
-
// Create backup if auto-rollback is enabled
|
|
31
|
-
let backupPath;
|
|
32
|
-
if (shouldAutoRollback) {
|
|
33
|
-
try {
|
|
34
|
-
backupPath = await backupFile(filepath);
|
|
35
|
-
result.backupPath = backupPath;
|
|
36
|
-
}
|
|
37
|
-
catch (error) {
|
|
38
|
-
result.warnings.push(`Failed to create backup: ${error instanceof Error ? error.message : String(error)}`);
|
|
39
|
-
// Don't fail verification if backup fails - just warn
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
// Step 1: Verify compilation
|
|
43
|
-
if (shouldVerifyCompilation) {
|
|
44
|
-
try {
|
|
45
|
-
const compilationResult = await verifyCompilation(filepath, undefined, compilationOptions);
|
|
46
|
-
result.compilationResult = compilationResult;
|
|
47
|
-
result.compiled = compilationResult.success;
|
|
48
|
-
if (!compilationResult.success) {
|
|
49
|
-
result.errors.push(...compilationResult.errors);
|
|
50
|
-
result.rollbackRequired = true;
|
|
51
|
-
}
|
|
52
|
-
result.warnings.push(...compilationResult.warnings);
|
|
53
|
-
// If compilation fails, stop here
|
|
54
|
-
if (!result.compiled) {
|
|
55
|
-
result.success = false;
|
|
56
|
-
return result;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
result.errors.push(`Compilation verification failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
61
|
-
result.rollbackRequired = true;
|
|
62
|
-
result.success = false;
|
|
63
|
-
return result;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
// Skip compilation check
|
|
68
|
-
result.compiled = true;
|
|
69
|
-
}
|
|
70
|
-
// Step 2: Run tests (only if compilation succeeded or was skipped)
|
|
71
|
-
if (shouldRunTests && result.compiled) {
|
|
72
|
-
try {
|
|
73
|
-
const testResult = await runTests(filepath, testOptions);
|
|
74
|
-
result.testResult = testResult;
|
|
75
|
-
result.testsPassed = testResult.success;
|
|
76
|
-
if (testResult.ran && !testResult.success) {
|
|
77
|
-
result.errors.push(...testResult.errors);
|
|
78
|
-
result.rollbackRequired = true;
|
|
79
|
-
}
|
|
80
|
-
if (testResult.ran) {
|
|
81
|
-
result.warnings.push(...testResult.warnings);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
catch (error) {
|
|
85
|
-
// Test execution failure is a warning, not an error
|
|
86
|
-
// (tests might not exist or framework might not be available)
|
|
87
|
-
result.warnings.push(`Test execution failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
88
|
-
result.testsPassed = true; // Don't fail if tests can't run
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
// Skip test check
|
|
93
|
-
result.testsPassed = true;
|
|
94
|
-
}
|
|
95
|
-
// Overall success: compilation passed AND (tests passed OR tests weren't run)
|
|
96
|
-
result.success = result.compiled && (result.testsPassed || !result.testResult?.ran);
|
|
97
|
-
return result;
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Apply edit with automatic verification and rollback
|
|
101
|
-
*
|
|
102
|
-
* This is the main function to use for safe code edits.
|
|
103
|
-
* It:
|
|
104
|
-
* 1. Creates backup
|
|
105
|
-
* 2. Applies edit (you provide the new content)
|
|
106
|
-
* 3. Verifies compilation and tests
|
|
107
|
-
* 4. Rolls back automatically on failure
|
|
108
|
-
*/
|
|
109
|
-
export async function applyEditWithVerification(filepath, newContent, options = {}) {
|
|
110
|
-
const { writeFileSync } = await import('fs');
|
|
111
|
-
const { readFileSync: readFile } = await import('fs');
|
|
112
|
-
// Read original content
|
|
113
|
-
const originalContent = existsSync(filepath)
|
|
114
|
-
? readFile(filepath, 'utf-8')
|
|
115
|
-
: '';
|
|
116
|
-
// Create backup
|
|
117
|
-
let backupPath;
|
|
118
|
-
try {
|
|
119
|
-
if (options.autoRollback !== false) {
|
|
120
|
-
backupPath = await backupFile(filepath);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
catch (error) {
|
|
124
|
-
return {
|
|
125
|
-
success: false,
|
|
126
|
-
verified: false,
|
|
127
|
-
result: {
|
|
128
|
-
success: false,
|
|
129
|
-
compiled: false,
|
|
130
|
-
testsPassed: false,
|
|
131
|
-
errors: [`Failed to create backup: ${error instanceof Error ? error.message : String(error)}`],
|
|
132
|
-
warnings: [],
|
|
133
|
-
rollbackRequired: true,
|
|
134
|
-
},
|
|
135
|
-
rolledBack: false,
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
// Write new content
|
|
139
|
-
try {
|
|
140
|
-
writeFileSync(filepath, newContent, 'utf-8');
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
return {
|
|
144
|
-
success: false,
|
|
145
|
-
verified: false,
|
|
146
|
-
result: {
|
|
147
|
-
success: false,
|
|
148
|
-
compiled: false,
|
|
149
|
-
testsPassed: false,
|
|
150
|
-
errors: [`Failed to write file: ${error instanceof Error ? error.message : String(error)}`],
|
|
151
|
-
warnings: [],
|
|
152
|
-
rollbackRequired: true,
|
|
153
|
-
},
|
|
154
|
-
rolledBack: false,
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
// Verify
|
|
158
|
-
try {
|
|
159
|
-
const verificationResult = await verifyFile(filepath, {
|
|
160
|
-
...options,
|
|
161
|
-
autoRollback: false, // Don't create another backup
|
|
162
|
-
});
|
|
163
|
-
// Rollback if verification failed
|
|
164
|
-
if (!verificationResult.success && options.autoRollback !== false) {
|
|
165
|
-
try {
|
|
166
|
-
await rollbackFile(filepath, backupPath);
|
|
167
|
-
return {
|
|
168
|
-
success: false,
|
|
169
|
-
verified: true,
|
|
170
|
-
result: verificationResult,
|
|
171
|
-
rolledBack: true,
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
catch (rollbackError) {
|
|
175
|
-
// Rollback failed - try to restore from original content
|
|
176
|
-
try {
|
|
177
|
-
writeFileSync(filepath, originalContent, 'utf-8');
|
|
178
|
-
return {
|
|
179
|
-
success: false,
|
|
180
|
-
verified: true,
|
|
181
|
-
result: {
|
|
182
|
-
...verificationResult,
|
|
183
|
-
errors: [
|
|
184
|
-
...verificationResult.errors,
|
|
185
|
-
`Rollback failed: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`,
|
|
186
|
-
],
|
|
187
|
-
},
|
|
188
|
-
rolledBack: true,
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
catch (restoreError) {
|
|
192
|
-
return {
|
|
193
|
-
success: false,
|
|
194
|
-
verified: true,
|
|
195
|
-
result: {
|
|
196
|
-
...verificationResult,
|
|
197
|
-
errors: [
|
|
198
|
-
...verificationResult.errors,
|
|
199
|
-
`Rollback and restore both failed. File may be in inconsistent state.`,
|
|
200
|
-
],
|
|
201
|
-
},
|
|
202
|
-
rolledBack: false, // Rollback failed
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
// Verification passed or rollback disabled
|
|
208
|
-
return {
|
|
209
|
-
success: verificationResult.success,
|
|
210
|
-
verified: true,
|
|
211
|
-
result: verificationResult,
|
|
212
|
-
rolledBack: false,
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
catch (error) {
|
|
216
|
-
// Verification threw an error - rollback
|
|
217
|
-
if (options.autoRollback !== false) {
|
|
218
|
-
try {
|
|
219
|
-
await rollbackFile(filepath, backupPath);
|
|
220
|
-
return {
|
|
221
|
-
success: false,
|
|
222
|
-
verified: false,
|
|
223
|
-
result: {
|
|
224
|
-
success: false,
|
|
225
|
-
compiled: false,
|
|
226
|
-
testsPassed: false,
|
|
227
|
-
errors: [`Verification failed: ${error instanceof Error ? error.message : String(error)}`],
|
|
228
|
-
warnings: [],
|
|
229
|
-
rollbackRequired: true,
|
|
230
|
-
},
|
|
231
|
-
rolledBack: true,
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
catch (rollbackError) {
|
|
235
|
-
// Rollback failed
|
|
236
|
-
writeFileSync(filepath, originalContent, 'utf-8');
|
|
237
|
-
return {
|
|
238
|
-
success: false,
|
|
239
|
-
verified: false,
|
|
240
|
-
result: {
|
|
241
|
-
success: false,
|
|
242
|
-
compiled: false,
|
|
243
|
-
testsPassed: false,
|
|
244
|
-
errors: [
|
|
245
|
-
`Verification failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
246
|
-
`Rollback failed: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`,
|
|
247
|
-
],
|
|
248
|
-
warnings: [],
|
|
249
|
-
rollbackRequired: true,
|
|
250
|
-
},
|
|
251
|
-
rolledBack: true, // Tried to rollback
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
return {
|
|
256
|
-
success: false,
|
|
257
|
-
verified: false,
|
|
258
|
-
result: {
|
|
259
|
-
success: false,
|
|
260
|
-
compiled: false,
|
|
261
|
-
testsPassed: false,
|
|
262
|
-
errors: [`Verification failed: ${error instanceof Error ? error.message : String(error)}`],
|
|
263
|
-
warnings: [],
|
|
264
|
-
rollbackRequired: true,
|
|
265
|
-
},
|
|
266
|
-
rolledBack: false,
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
export { verifyCompilation } from './compiler.js';
|
|
271
|
-
export { runTests, detectTestFramework } from './test-runner.js';
|
|
272
|
-
export { backupFile, rollbackFile, findLatestBackup, listBackups, deleteAllBackups } from './backup.js';
|
|
273
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,379 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test Execution Module
|
|
3
|
-
* Detects test frameworks and runs tests to verify code changes
|
|
4
|
-
*/
|
|
5
|
-
import { readFileSync, existsSync } from 'fs';
|
|
6
|
-
import { join, dirname } from 'path';
|
|
7
|
-
import { execSync } from 'child_process';
|
|
8
|
-
/**
|
|
9
|
-
* Verify tests pass for a given file
|
|
10
|
-
*/
|
|
11
|
-
export async function runTests(filepath, options = {}) {
|
|
12
|
-
try {
|
|
13
|
-
// Detect test framework
|
|
14
|
-
const framework = await detectTestFramework(filepath);
|
|
15
|
-
if (!framework || framework === 'unknown') {
|
|
16
|
-
return {
|
|
17
|
-
success: true,
|
|
18
|
-
ran: false,
|
|
19
|
-
errors: [],
|
|
20
|
-
warnings: ['No test framework detected. Skipping test verification.'],
|
|
21
|
-
framework: 'unknown',
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
// Find test files related to the changed file
|
|
25
|
-
const testFiles = findTestFiles(filepath, framework);
|
|
26
|
-
if (testFiles.length === 0) {
|
|
27
|
-
return {
|
|
28
|
-
success: true,
|
|
29
|
-
ran: false,
|
|
30
|
-
errors: [],
|
|
31
|
-
warnings: [`No test files found for ${filepath}. Skipping test verification.`],
|
|
32
|
-
framework,
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
// Run tests based on framework
|
|
36
|
-
switch (framework) {
|
|
37
|
-
case 'jest':
|
|
38
|
-
return await runJestTests(filepath, testFiles, options);
|
|
39
|
-
case 'mocha':
|
|
40
|
-
return await runMochaTests(filepath, testFiles, options);
|
|
41
|
-
case 'vitest':
|
|
42
|
-
return await runVitestTests(filepath, testFiles, options);
|
|
43
|
-
case 'tap':
|
|
44
|
-
return await runTapTests(filepath, testFiles, options);
|
|
45
|
-
case 'ava':
|
|
46
|
-
return await runAvaTests(filepath, testFiles, options);
|
|
47
|
-
default:
|
|
48
|
-
return {
|
|
49
|
-
success: true,
|
|
50
|
-
ran: false,
|
|
51
|
-
errors: [],
|
|
52
|
-
warnings: [`Test framework ${framework} not yet supported. Skipping test verification.`],
|
|
53
|
-
framework,
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
return {
|
|
59
|
-
success: false,
|
|
60
|
-
ran: true,
|
|
61
|
-
errors: [`Test execution failed: ${error instanceof Error ? error.message : String(error)}`],
|
|
62
|
-
warnings: [],
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Detect test framework in project
|
|
68
|
-
*/
|
|
69
|
-
export async function detectTestFramework(filepath) {
|
|
70
|
-
const projectDir = findProjectRoot(filepath);
|
|
71
|
-
if (!projectDir) {
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
// Check package.json scripts and dependencies
|
|
75
|
-
const packageJsonPath = join(projectDir, 'package.json');
|
|
76
|
-
if (existsSync(packageJsonPath)) {
|
|
77
|
-
try {
|
|
78
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
79
|
-
const deps = {
|
|
80
|
-
...packageJson.dependencies,
|
|
81
|
-
...packageJson.devDependencies,
|
|
82
|
-
};
|
|
83
|
-
const scripts = packageJson.scripts || {};
|
|
84
|
-
// Check for Jest
|
|
85
|
-
if (deps.jest ||
|
|
86
|
-
deps['@jest/globals'] ||
|
|
87
|
-
scripts.test?.includes('jest') ||
|
|
88
|
-
existsSync(join(projectDir, 'jest.config.js')) ||
|
|
89
|
-
existsSync(join(projectDir, 'jest.config.ts')) ||
|
|
90
|
-
existsSync(join(projectDir, 'jest.config.json'))) {
|
|
91
|
-
return 'jest';
|
|
92
|
-
}
|
|
93
|
-
// Check for Vitest
|
|
94
|
-
if (deps.vitest ||
|
|
95
|
-
scripts.test?.includes('vitest') ||
|
|
96
|
-
existsSync(join(projectDir, 'vitest.config.ts')) ||
|
|
97
|
-
existsSync(join(projectDir, 'vitest.config.js'))) {
|
|
98
|
-
return 'vitest';
|
|
99
|
-
}
|
|
100
|
-
// Check for Mocha
|
|
101
|
-
if (deps.mocha ||
|
|
102
|
-
scripts.test?.includes('mocha') ||
|
|
103
|
-
existsSync(join(projectDir, '.mocharc.js')) ||
|
|
104
|
-
existsSync(join(projectDir, '.mocharc.json'))) {
|
|
105
|
-
return 'mocha';
|
|
106
|
-
}
|
|
107
|
-
// Check for Tap
|
|
108
|
-
if (deps.tap || scripts.test?.includes('tap')) {
|
|
109
|
-
return 'tap';
|
|
110
|
-
}
|
|
111
|
-
// Check for Ava
|
|
112
|
-
if (deps.ava || scripts.test?.includes('ava')) {
|
|
113
|
-
return 'ava';
|
|
114
|
-
}
|
|
115
|
-
// Check script name
|
|
116
|
-
if (scripts.test) {
|
|
117
|
-
// Try to infer from test script
|
|
118
|
-
if (scripts.test.includes('jest'))
|
|
119
|
-
return 'jest';
|
|
120
|
-
if (scripts.test.includes('vitest'))
|
|
121
|
-
return 'vitest';
|
|
122
|
-
if (scripts.test.includes('mocha'))
|
|
123
|
-
return 'mocha';
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
catch (error) {
|
|
127
|
-
// Ignore package.json parsing errors
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
return null;
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Find test files related to a source file
|
|
134
|
-
*/
|
|
135
|
-
function findTestFiles(filepath, framework) {
|
|
136
|
-
const projectDir = findProjectRoot(filepath);
|
|
137
|
-
if (!projectDir) {
|
|
138
|
-
return [];
|
|
139
|
-
}
|
|
140
|
-
const dir = dirname(filepath);
|
|
141
|
-
const basename = filepath
|
|
142
|
-
.split('/')
|
|
143
|
-
.pop()
|
|
144
|
-
?.replace(/\.[^.]+$/, '') || '';
|
|
145
|
-
const ext = filepath.split('.').pop()?.toLowerCase() || '';
|
|
146
|
-
// Common test file patterns
|
|
147
|
-
const testPatterns = [
|
|
148
|
-
// Same directory
|
|
149
|
-
join(dir, `${basename}.test.${ext}`),
|
|
150
|
-
join(dir, `${basename}.spec.${ext}`),
|
|
151
|
-
join(dir, `${basename}.test.ts`), // TypeScript tests for JS files
|
|
152
|
-
join(dir, `${basename}.spec.ts`),
|
|
153
|
-
// Test directory
|
|
154
|
-
join(dir, '__tests__', `${basename}.${ext}`),
|
|
155
|
-
join(dir, '__tests__', `${basename}.test.${ext}`),
|
|
156
|
-
join(dir, '__tests__', `${basename}.spec.${ext}`),
|
|
157
|
-
// Parent test directory
|
|
158
|
-
join(dirname(dir), '__tests__', `${basename}.${ext}`),
|
|
159
|
-
join(dirname(dir), '__tests__', `${basename}.test.${ext}`),
|
|
160
|
-
join(dirname(dir), '__tests__', `${basename}.spec.${ext}`),
|
|
161
|
-
// Test subdirectory
|
|
162
|
-
join(dir, 'test', `${basename}.${ext}`),
|
|
163
|
-
join(dir, 'tests', `${basename}.${ext}`),
|
|
164
|
-
];
|
|
165
|
-
const testFiles = [];
|
|
166
|
-
for (const pattern of testPatterns) {
|
|
167
|
-
if (existsSync(pattern)) {
|
|
168
|
-
testFiles.push(pattern);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
return testFiles;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Run Jest tests
|
|
175
|
-
*/
|
|
176
|
-
async function runJestTests(filepath, testFiles, options = {}) {
|
|
177
|
-
const projectDir = findProjectRoot(filepath);
|
|
178
|
-
if (!projectDir) {
|
|
179
|
-
return {
|
|
180
|
-
success: false,
|
|
181
|
-
ran: false,
|
|
182
|
-
errors: ['Could not find project root'],
|
|
183
|
-
warnings: [],
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
try {
|
|
187
|
-
const timeout = options.timeout || 30000; // 30 seconds
|
|
188
|
-
// Build Jest command
|
|
189
|
-
let command = 'npx jest';
|
|
190
|
-
if (options.testFile) {
|
|
191
|
-
command += ` ${options.testFile}`;
|
|
192
|
-
}
|
|
193
|
-
else if (testFiles.length > 0) {
|
|
194
|
-
// Run specific test files
|
|
195
|
-
command += ` ${testFiles.join(' ')}`;
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
// Run all tests (fallback)
|
|
199
|
-
command += ' --findRelatedTests';
|
|
200
|
-
}
|
|
201
|
-
// Add flags for better output
|
|
202
|
-
command += ' --no-coverage --silent=false';
|
|
203
|
-
const output = execSync(command, {
|
|
204
|
-
cwd: projectDir,
|
|
205
|
-
encoding: 'utf-8',
|
|
206
|
-
stdio: 'pipe',
|
|
207
|
-
timeout,
|
|
208
|
-
});
|
|
209
|
-
// Parse Jest output
|
|
210
|
-
const passed = output.includes('PASS') ||
|
|
211
|
-
(output.includes('Test Suites:') && !output.includes('failed'));
|
|
212
|
-
return {
|
|
213
|
-
success: passed,
|
|
214
|
-
ran: true,
|
|
215
|
-
errors: passed ? [] : ['Tests failed'],
|
|
216
|
-
warnings: [],
|
|
217
|
-
output,
|
|
218
|
-
framework: 'jest',
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
catch (error) {
|
|
222
|
-
const output = error.stdout || error.stderr || error.message || '';
|
|
223
|
-
// Check if tests actually failed or if it's an execution error
|
|
224
|
-
const isTestFailure = output.includes('FAIL') || output.includes('Test Suites:');
|
|
225
|
-
return {
|
|
226
|
-
success: false,
|
|
227
|
-
ran: true,
|
|
228
|
-
errors: isTestFailure
|
|
229
|
-
? ['Tests failed', output.substring(0, 1000)]
|
|
230
|
-
: [`Test execution error: ${output.substring(0, 500)}`],
|
|
231
|
-
warnings: [],
|
|
232
|
-
output: String(output),
|
|
233
|
-
framework: 'jest',
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Run Mocha tests
|
|
239
|
-
*/
|
|
240
|
-
async function runMochaTests(filepath, testFiles, options = {}) {
|
|
241
|
-
const projectDir = findProjectRoot(filepath);
|
|
242
|
-
if (!projectDir) {
|
|
243
|
-
return {
|
|
244
|
-
success: false,
|
|
245
|
-
ran: false,
|
|
246
|
-
errors: ['Could not find project root'],
|
|
247
|
-
warnings: [],
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
try {
|
|
251
|
-
const timeout = options.timeout || 30000;
|
|
252
|
-
let command = 'npx mocha';
|
|
253
|
-
if (options.testFile) {
|
|
254
|
-
command += ` ${options.testFile}`;
|
|
255
|
-
}
|
|
256
|
-
else if (testFiles.length > 0) {
|
|
257
|
-
command += ` ${testFiles.join(' ')}`;
|
|
258
|
-
}
|
|
259
|
-
const output = execSync(command, {
|
|
260
|
-
cwd: projectDir,
|
|
261
|
-
encoding: 'utf-8',
|
|
262
|
-
stdio: 'pipe',
|
|
263
|
-
timeout,
|
|
264
|
-
});
|
|
265
|
-
const passed = output.includes('passing') && !output.includes('failing');
|
|
266
|
-
return {
|
|
267
|
-
success: passed,
|
|
268
|
-
ran: true,
|
|
269
|
-
errors: passed ? [] : ['Tests failed'],
|
|
270
|
-
warnings: [],
|
|
271
|
-
output,
|
|
272
|
-
framework: 'mocha',
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
catch (error) {
|
|
276
|
-
const output = error.stdout || error.stderr || error.message || '';
|
|
277
|
-
return {
|
|
278
|
-
success: false,
|
|
279
|
-
ran: true,
|
|
280
|
-
errors: [`Test execution failed: ${output.substring(0, 500)}`],
|
|
281
|
-
warnings: [],
|
|
282
|
-
output: String(output),
|
|
283
|
-
framework: 'mocha',
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Run Vitest tests
|
|
289
|
-
*/
|
|
290
|
-
async function runVitestTests(filepath, testFiles, options = {}) {
|
|
291
|
-
const projectDir = findProjectRoot(filepath);
|
|
292
|
-
if (!projectDir) {
|
|
293
|
-
return {
|
|
294
|
-
success: false,
|
|
295
|
-
ran: false,
|
|
296
|
-
errors: ['Could not find project root'],
|
|
297
|
-
warnings: [],
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
try {
|
|
301
|
-
const timeout = options.timeout || 30000;
|
|
302
|
-
let command = 'npx vitest run';
|
|
303
|
-
if (options.testFile) {
|
|
304
|
-
command += ` ${options.testFile}`;
|
|
305
|
-
}
|
|
306
|
-
else if (testFiles.length > 0) {
|
|
307
|
-
command += ` ${testFiles.join(' ')}`;
|
|
308
|
-
}
|
|
309
|
-
const output = execSync(command, {
|
|
310
|
-
cwd: projectDir,
|
|
311
|
-
encoding: 'utf-8',
|
|
312
|
-
stdio: 'pipe',
|
|
313
|
-
timeout,
|
|
314
|
-
});
|
|
315
|
-
const passed = output.includes('PASS') || output.includes('✓') && !output.includes('FAIL');
|
|
316
|
-
return {
|
|
317
|
-
success: passed,
|
|
318
|
-
ran: true,
|
|
319
|
-
errors: passed ? [] : ['Tests failed'],
|
|
320
|
-
warnings: [],
|
|
321
|
-
output,
|
|
322
|
-
framework: 'vitest',
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
catch (error) {
|
|
326
|
-
const output = error.stdout || error.stderr || error.message || '';
|
|
327
|
-
return {
|
|
328
|
-
success: false,
|
|
329
|
-
ran: true,
|
|
330
|
-
errors: [`Test execution failed: ${output.substring(0, 500)}`],
|
|
331
|
-
warnings: [],
|
|
332
|
-
output: String(output),
|
|
333
|
-
framework: 'vitest',
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Run Tap tests (placeholder)
|
|
339
|
-
*/
|
|
340
|
-
async function runTapTests(filepath, testFiles, options = {}) {
|
|
341
|
-
return {
|
|
342
|
-
success: true,
|
|
343
|
-
ran: false,
|
|
344
|
-
errors: [],
|
|
345
|
-
warnings: ['Tap test runner not yet implemented'],
|
|
346
|
-
framework: 'tap',
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
/**
|
|
350
|
-
* Run Ava tests (placeholder)
|
|
351
|
-
*/
|
|
352
|
-
async function runAvaTests(filepath, testFiles, options = {}) {
|
|
353
|
-
return {
|
|
354
|
-
success: true,
|
|
355
|
-
ran: false,
|
|
356
|
-
errors: [],
|
|
357
|
-
warnings: ['Ava test runner not yet implemented'],
|
|
358
|
-
framework: 'ava',
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
/**
|
|
362
|
-
* Find project root (where package.json is)
|
|
363
|
-
*/
|
|
364
|
-
function findProjectRoot(filepath) {
|
|
365
|
-
let currentDir = dirname(filepath);
|
|
366
|
-
const root = currentDir.split(/[/\\]/)[0];
|
|
367
|
-
while (currentDir !== root) {
|
|
368
|
-
if (existsSync(join(currentDir, 'package.json'))) {
|
|
369
|
-
return currentDir;
|
|
370
|
-
}
|
|
371
|
-
const parentDir = dirname(currentDir);
|
|
372
|
-
if (parentDir === currentDir) {
|
|
373
|
-
break;
|
|
374
|
-
}
|
|
375
|
-
currentDir = parentDir;
|
|
376
|
-
}
|
|
377
|
-
return null;
|
|
378
|
-
}
|
|
379
|
-
//# sourceMappingURL=test-runner.js.map
|