codehere 0.2.1 → 0.3.0-rc.1

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 (235) hide show
  1. package/README.md +88 -68
  2. package/dist/domain/entities/task.js +4 -4
  3. package/dist/error-handler.js +4 -9
  4. package/dist/index.js +253 -1219
  5. package/dist/infrastructure/config/product-context.js +7 -6
  6. package/dist/infrastructure/hooks/claude-sdk-hook.js +335 -63
  7. package/dist/infrastructure/observability/execution-tracer.js +11 -6
  8. package/dist/infrastructure/orchestration/agent-adapter.js +13 -0
  9. package/dist/infrastructure/orchestration/agent-installer.js +101 -0
  10. package/dist/infrastructure/orchestration/agents-config-seed.js +56 -0
  11. package/dist/infrastructure/orchestration/aider-adapter.js +319 -0
  12. package/dist/infrastructure/orchestration/artifacts-extractor.js +175 -0
  13. package/dist/infrastructure/orchestration/claude-code-adapter.js +352 -0
  14. package/dist/infrastructure/orchestration/codex-adapter.js +310 -0
  15. package/dist/infrastructure/orchestration/generic-cli-adapter.js +553 -0
  16. package/dist/infrastructure/orchestration/opencode-adapter.js +275 -0
  17. package/dist/infrastructure/orchestration/progress-aggregator.js +189 -0
  18. package/dist/infrastructure/orchestration/readiness.js +106 -0
  19. package/dist/infrastructure/orchestration/session-manager.js +272 -0
  20. package/dist/infrastructure/orchestration/session-persistence.js +109 -0
  21. package/dist/infrastructure/protocols/mcp-helpers.js +10 -30
  22. package/dist/infrastructure/protocols/mcp-server-impl.js +359 -21
  23. package/dist/infrastructure/protocols/ui-page.js +1827 -0
  24. package/dist/infrastructure/security/file-collection.js +115 -0
  25. package/dist/infrastructure/security/trust-scorer.js +301 -56
  26. package/dist/infrastructure/storage/task-repository.js +8 -7
  27. package/dist/monitoring.js +10 -49
  28. package/dist/presentation/cli/commands/help-command.js +96 -139
  29. package/dist/presentation/cli/commands/hook-command.js +17 -24
  30. package/dist/presentation/cli/commands/report-command.js +59 -72
  31. package/dist/presentation/cli/commands/setup-command.js +4 -4
  32. package/dist/presentation/cli/commands/status-command.js +334 -43
  33. package/dist/presentation/cli/commands/trust-command.js +115 -99
  34. package/dist/presentation/cli/error-display.js +17 -21
  35. package/dist/ui.js +17 -12
  36. package/package.json +35 -67
  37. package/dist/agents/base.js +0 -101
  38. package/dist/agents/orchestrator-model-driven.js +0 -141
  39. package/dist/agents/react-orchestrator-agent.js +0 -54
  40. package/dist/application/agents/execution-agent.js +0 -508
  41. package/dist/application/agents/multi-agent-orchestrator.js +0 -295
  42. package/dist/application/agents/planning-agent.js +0 -433
  43. package/dist/application/agents/validation-agent.js +0 -317
  44. package/dist/application/architectures/plan-and-act.js +0 -242
  45. package/dist/application/index.js +0 -12
  46. package/dist/application/services/agent-factory.js +0 -28
  47. package/dist/application/services/dependency-container.js +0 -596
  48. package/dist/application/services/git-context-service.js +0 -83
  49. package/dist/application/services/intelligent-router.js +0 -934
  50. package/dist/application/services/tool-executor-service.js +0 -94
  51. package/dist/application/use-cases/ask-question-use-case.js +0 -338
  52. package/dist/application/use-cases/edit-file-use-case.js +0 -830
  53. package/dist/application/use-cases/explain-file-use-case.js +0 -50
  54. package/dist/application/use-cases/index-codebase-use-case.js +0 -113
  55. package/dist/application/use-cases/planning-use-case.js +0 -276
  56. package/dist/application/use-cases/react-orchestration-use-case.js +0 -329
  57. package/dist/application/use-cases/reflexion-use-case.js +0 -30
  58. package/dist/application/workflows/deterministic-workflows.js +0 -189
  59. package/dist/ast-parser.js +0 -331
  60. package/dist/cache.js +0 -180
  61. package/dist/chat.js +0 -251
  62. package/dist/code-analysis.js +0 -327
  63. package/dist/context.js +0 -187
  64. package/dist/docs.js +0 -146
  65. package/dist/domain/entities/code-chunk.js +0 -6
  66. package/dist/domain/entities/decision.js +0 -9
  67. package/dist/domain/entities/edit.js +0 -6
  68. package/dist/domain/entities/knowledge-node.js +0 -9
  69. package/dist/domain/entities/knowledge-preservation.js +0 -10
  70. package/dist/domain/entities/memory.js +0 -6
  71. package/dist/domain/entities/pattern.js +0 -7
  72. package/dist/domain/entities/plan.js +0 -6
  73. package/dist/domain/entities/query.js +0 -6
  74. package/dist/domain/errors/embeddings-not-found-error.js +0 -13
  75. package/dist/domain/index.js +0 -19
  76. package/dist/domain/interfaces/ai-service.interface.js +0 -6
  77. package/dist/domain/interfaces/code-analyzer.interface.js +0 -6
  78. package/dist/domain/interfaces/decision-repository.interface.js +0 -9
  79. package/dist/domain/interfaces/embedding-repository.interface.js +0 -6
  80. package/dist/domain/interfaces/knowledge-graph-repository.interface.js +0 -9
  81. package/dist/domain/interfaces/knowledge-preservation-repository.interface.js +0 -8
  82. package/dist/domain/interfaces/memory-repository.interface.js +0 -6
  83. package/dist/domain/interfaces/pattern-repository.interface.js +0 -6
  84. package/dist/domain/interfaces/verification-service.interface.js +0 -6
  85. package/dist/domain/services/cross-team-pattern-sharing.js +0 -125
  86. package/dist/domain/services/decision-recorder.js +0 -223
  87. package/dist/domain/services/decision-retriever.js +0 -133
  88. package/dist/domain/services/environment-mode-manager.js +0 -22
  89. package/dist/domain/services/graded-memory-activation.js +0 -69
  90. package/dist/domain/services/knowledge-access.js +0 -132
  91. package/dist/domain/services/knowledge-extractor.js +0 -247
  92. package/dist/domain/services/knowledge-graph-builder.js +0 -268
  93. package/dist/domain/services/knowledge-graph-query.js +0 -187
  94. package/dist/domain/services/memory-retriever.js +0 -82
  95. package/dist/domain/services/memory-synthesizer.js +0 -91
  96. package/dist/domain/services/pattern-extractor.js +0 -442
  97. package/dist/domain/services/query-intent-classifier.js +0 -140
  98. package/dist/domain/services/react-loop.js +0 -186
  99. package/dist/domain/services/risk-tier-detector.js +0 -78
  100. package/dist/edit.js +0 -319
  101. package/dist/embed.js +0 -459
  102. package/dist/formatter.js +0 -168
  103. package/dist/git.js +0 -198
  104. package/dist/infrastructure/ai/cohere-ai-service.js +0 -607
  105. package/dist/infrastructure/ai/command-r-evaluation.js +0 -206
  106. package/dist/infrastructure/ai/model-config.js +0 -84
  107. package/dist/infrastructure/ai/provider-ai-service.js +0 -477
  108. package/dist/infrastructure/cache/embedding-cache.js +0 -175
  109. package/dist/infrastructure/cache/query-result-cache.js +0 -66
  110. package/dist/infrastructure/cache/response-cache.js +0 -48
  111. package/dist/infrastructure/cache/security-scan-cache.js +0 -47
  112. package/dist/infrastructure/chunking/ast-code-chunker.js +0 -19
  113. package/dist/infrastructure/chunking/code-aware-chunker.js +0 -397
  114. package/dist/infrastructure/context/context-compressor.js +0 -329
  115. package/dist/infrastructure/context/conversation-context.js +0 -128
  116. package/dist/infrastructure/context/session-manager.js +0 -94
  117. package/dist/infrastructure/cost/cost-tracker.js +0 -360
  118. package/dist/infrastructure/file-scanner/file-scanner.js +0 -106
  119. package/dist/infrastructure/governance/nist-ai-rmf.js +0 -292
  120. package/dist/infrastructure/governance/policy-as-code.js +0 -258
  121. package/dist/infrastructure/governance/prompt-to-code-lineage.js +0 -239
  122. package/dist/infrastructure/index.js +0 -7
  123. package/dist/infrastructure/observability/prompt-versioner.js +0 -145
  124. package/dist/infrastructure/protocols/a2a-metadata.js +0 -137
  125. package/dist/infrastructure/protocols/a2a-protocol.js +0 -314
  126. package/dist/infrastructure/protocols/mcp-oauth.js +0 -184
  127. package/dist/infrastructure/protocols/mcp-server.js +0 -333
  128. package/dist/infrastructure/protocols/streaming-handler.js +0 -103
  129. package/dist/infrastructure/providers/cohere-provider.js +0 -444
  130. package/dist/infrastructure/providers/fake-provider.js +0 -130
  131. package/dist/infrastructure/providers/local-llm-provider.js +0 -330
  132. package/dist/infrastructure/providers/model-config.types.js +0 -9
  133. package/dist/infrastructure/providers/model-provider.interface.js +0 -8
  134. package/dist/infrastructure/providers/openai-provider.js +0 -413
  135. package/dist/infrastructure/providers/openrouter-provider.js +0 -399
  136. package/dist/infrastructure/providers/operation-provider-resolver.js +0 -105
  137. package/dist/infrastructure/providers/provider-config-loader.js +0 -120
  138. package/dist/infrastructure/providers/provider-registry.js +0 -88
  139. package/dist/infrastructure/safety/pattern-detector.js +0 -133
  140. package/dist/infrastructure/security/ai-sast-scanner.js +0 -290
  141. package/dist/infrastructure/security/docker-sandbox.js +0 -178
  142. package/dist/infrastructure/security/enhanced-security-gate.js +0 -151
  143. package/dist/infrastructure/security/license-scanner.js +0 -167
  144. package/dist/infrastructure/security/provider-bias-detector.js +0 -164
  145. package/dist/infrastructure/security/sandbox-executor.js +0 -64
  146. package/dist/infrastructure/serialization/toon-serializer.js +0 -119
  147. package/dist/infrastructure/storage/memory-stream-service.js +0 -204
  148. package/dist/infrastructure/storage/plan-repository.js +0 -96
  149. package/dist/infrastructure/storage/sqlite-decision-repository.js +0 -232
  150. package/dist/infrastructure/storage/sqlite-embedding-repository.js +0 -311
  151. package/dist/infrastructure/storage/sqlite-knowledge-graph-repository.js +0 -417
  152. package/dist/infrastructure/storage/sqlite-knowledge-preservation-repository.js +0 -230
  153. package/dist/infrastructure/storage/sqlite-memory-repository.js +0 -229
  154. package/dist/infrastructure/storage/sqlite-pattern-repository.js +0 -249
  155. package/dist/infrastructure/storage/task-helpers.js +0 -197
  156. package/dist/infrastructure/telemetry/telemetry-service.js +0 -167
  157. package/dist/infrastructure/ux/appropriate-friction.js +0 -213
  158. package/dist/infrastructure/ux/bi-directional-learning.js +0 -337
  159. package/dist/infrastructure/ux/capability-boundaries.js +0 -42
  160. package/dist/infrastructure/ux/comprehensive-formatter.js +0 -117
  161. package/dist/infrastructure/ux/contextual-feature-discovery.js +0 -10
  162. package/dist/infrastructure/ux/expectation-management.js +0 -327
  163. package/dist/infrastructure/ux/feature-discovery.js +0 -14
  164. package/dist/infrastructure/ux/feedback-prompt.js +0 -45
  165. package/dist/infrastructure/ux/hitl-validation.js +0 -297
  166. package/dist/infrastructure/ux/progress-indicator.js +0 -116
  167. package/dist/infrastructure/ux/progressive-disclosure.js +0 -236
  168. package/dist/infrastructure/ux/review-checkpoint.js +0 -72
  169. package/dist/infrastructure/ux/staged-feature-intro.js +0 -24
  170. package/dist/infrastructure/ux/stream-markdown.js +0 -151
  171. package/dist/infrastructure/ux/syntax-highlighter.js +0 -91
  172. package/dist/infrastructure/ux/team-standards.js +0 -196
  173. package/dist/infrastructure/ux/transparency.js +0 -71
  174. package/dist/infrastructure/validation/agent-feedback.js +0 -55
  175. package/dist/infrastructure/validation/agent-validation-helper.js +0 -137
  176. package/dist/infrastructure/validation/review-handler.js +0 -40
  177. package/dist/infrastructure/validation/summary-aggregator.js +0 -70
  178. package/dist/infrastructure/validation/summary-extractor.js +0 -45
  179. package/dist/infrastructure/validation/trace-summary.js +0 -52
  180. package/dist/infrastructure/verification/verification-service.js +0 -47
  181. package/dist/infrastructure/xai/attention-visualizer.js +0 -172
  182. package/dist/infrastructure/xai/cot-visualizer.js +0 -283
  183. package/dist/infrastructure/xai/decision-tree-log.js +0 -212
  184. package/dist/infrastructure/xai/interactive-xai.js +0 -260
  185. package/dist/infrastructure/xai/uncertainty-quantifier.js +0 -198
  186. package/dist/intelligent-retrieval.js +0 -272
  187. package/dist/intent/classifier.js +0 -2
  188. package/dist/intent/context.js +0 -2
  189. package/dist/iterative-refinement.js +0 -189
  190. package/dist/learning.js +0 -232
  191. package/dist/log.js +0 -31
  192. package/dist/migrate.js +0 -133
  193. package/dist/parallel-processor.js +0 -530
  194. package/dist/planner.js +0 -198
  195. package/dist/policy.js +0 -26
  196. package/dist/presentation/cli/commands/ask-command.js +0 -314
  197. package/dist/presentation/cli/commands/cost-command.js +0 -191
  198. package/dist/presentation/cli/commands/decision-command.js +0 -207
  199. package/dist/presentation/cli/commands/docs-command.js +0 -25
  200. package/dist/presentation/cli/commands/fix-command.js +0 -53
  201. package/dist/presentation/cli/commands/knowledge-command.js +0 -129
  202. package/dist/presentation/cli/commands/learning-dashboard-command.js +0 -183
  203. package/dist/presentation/cli/commands/models-command.js +0 -194
  204. package/dist/presentation/cli/commands/orchestrate-command.js +0 -207
  205. package/dist/presentation/cli/commands/plan-command.js +0 -246
  206. package/dist/presentation/cli/commands/product-command.js +0 -199
  207. package/dist/presentation/cli/commands/react-command.js +0 -181
  208. package/dist/presentation/cli/commands/review-command.js +0 -154
  209. package/dist/presentation/cli/commands/run-command.js +0 -188
  210. package/dist/presentation/cli/commands/smart-command.js +0 -395
  211. package/dist/presentation/cli/commands/suggest-command.js +0 -138
  212. package/dist/presentation/cli/commands/trace-command.js +0 -129
  213. package/dist/presentation/cli/commands/undo-command.js +0 -150
  214. package/dist/query-optimizer.js +0 -205
  215. package/dist/refactor.js +0 -116
  216. package/dist/review.js +0 -206
  217. package/dist/search.js +0 -163
  218. package/dist/session.js +0 -652
  219. package/dist/task-verification.js +0 -336
  220. package/dist/testgen.js +0 -166
  221. package/dist/token-optimizer.js +0 -277
  222. package/dist/tools/bash.js +0 -213
  223. package/dist/tools/edit.js +0 -235
  224. package/dist/tools/executor.js +0 -153
  225. package/dist/tools/git-tool.js +0 -292
  226. package/dist/tools/parser.js +0 -158
  227. package/dist/tools/registry.js +0 -302
  228. package/dist/tools/search.js +0 -100
  229. package/dist/types.js +0 -2
  230. package/dist/utils/check-api-status.js +0 -100
  231. package/dist/utils/diff-parser.js +0 -162
  232. package/dist/verification/backup.js +0 -259
  233. package/dist/verification/compiler.js +0 -264
  234. package/dist/verification/index.js +0 -273
  235. package/dist/verification/test-runner.js +0 -379
@@ -1,162 +0,0 @@
1
- /**
2
- * Unified Diff Parser
3
- * Parses and applies unified diff patches to file content
4
- *
5
- * Handles standard unified diff format:
6
- * --- a/filepath
7
- * +++ b/filepath
8
- * @@ -start,count +start,count @@
9
- * -old line (remove)
10
- * +new line (add)
11
- * context line (keep)
12
- */
13
- /**
14
- * Apply a unified diff to file content
15
- */
16
- export function applyUnifiedDiff(originalContent, diff) {
17
- if (!diff || !diff.trim()) {
18
- return originalContent;
19
- }
20
- // Clean diff - remove any markdown formatting
21
- let cleanDiff = diff.trim();
22
- // Extract the actual diff lines
23
- const diffLines = cleanDiff.split('\n');
24
- const originalLines = originalContent.split('\n');
25
- const result = [];
26
- let originalIndex = 0; // Current position in original file
27
- let inHunk = false;
28
- let hunkStartLine = 0; // Line number where hunk starts (1-based from diff)
29
- let hunkOldLineCount = 0; // Number of old lines in this hunk
30
- let hunkOldLinesProcessed = 0; // How many old lines we've processed
31
- for (let i = 0; i < diffLines.length; i++) {
32
- const line = diffLines[i];
33
- // Skip header lines
34
- if (line.startsWith('---') || line.startsWith('+++')) {
35
- continue;
36
- }
37
- // Parse hunk header: @@ -start,count +start,count @@
38
- const hunkMatch = line.match(/^@@\s+-(\d+)(?:,(\d+))?\s+\+(\d+)(?:,(\d+))?\s+@@/);
39
- if (hunkMatch) {
40
- // Finish previous hunk
41
- if (inHunk) {
42
- // Make sure we've processed all old lines from previous hunk
43
- while (hunkOldLinesProcessed < hunkOldLineCount && originalIndex < originalLines.length) {
44
- originalIndex++;
45
- hunkOldLinesProcessed++;
46
- }
47
- }
48
- // Start new hunk
49
- inHunk = true;
50
- hunkStartLine = parseInt(hunkMatch[1], 10); // 1-based line number
51
- hunkOldLineCount = parseInt(hunkMatch[2] || '0', 10);
52
- hunkOldLinesProcessed = 0;
53
- // Copy all lines from original up to (but not including) the hunk start
54
- // hunkStartLine is 1-based, originalIndex is 0-based
55
- while (originalIndex < hunkStartLine - 1 && originalIndex < originalLines.length) {
56
- result.push(originalLines[originalIndex]);
57
- originalIndex++;
58
- }
59
- continue;
60
- }
61
- if (!inHunk) {
62
- continue; // Skip lines outside hunks
63
- }
64
- // Process hunk content
65
- if (line.startsWith('-')) {
66
- // Remove line: skip this line from original
67
- if (originalIndex < originalLines.length) {
68
- originalIndex++;
69
- hunkOldLinesProcessed++;
70
- }
71
- }
72
- else if (line.startsWith('+')) {
73
- // Add line: add new line to result
74
- result.push(line.substring(1));
75
- // Don't increment originalIndex or hunkOldLinesProcessed for additions
76
- }
77
- else if (line.startsWith(' ')) {
78
- // Context line: keep from original
79
- if (originalIndex < originalLines.length) {
80
- result.push(originalLines[originalIndex]);
81
- originalIndex++;
82
- hunkOldLinesProcessed++;
83
- }
84
- }
85
- else if (line.trim() === '') {
86
- // Empty line - preserve if it's part of the diff structure
87
- // But don't add it if we're in the middle of processing
88
- if (hunkOldLinesProcessed < hunkOldLineCount) {
89
- // This might be a continuation, skip it
90
- continue;
91
- }
92
- }
93
- // Check if hunk is complete
94
- if (hunkOldLinesProcessed >= hunkOldLineCount) {
95
- inHunk = false;
96
- }
97
- }
98
- // Copy all remaining lines from original
99
- while (originalIndex < originalLines.length) {
100
- result.push(originalLines[originalIndex]);
101
- originalIndex++;
102
- }
103
- return result.join('\n');
104
- }
105
- /**
106
- * Fallback: Try multiple strategies to apply the edit
107
- * Now optimized for complete file content (preferred) or unified diff
108
- */
109
- export function applyEditFallback(originalContent, diff) {
110
- if (!diff || !diff.trim()) {
111
- return originalContent;
112
- }
113
- // Clean the diff
114
- let cleanDiff = diff.trim();
115
- // Strategy 1: Extract from markdown code blocks
116
- const codeBlockMatch = cleanDiff.match(/```(?:\w+)?\n([\s\S]*?)\n```/);
117
- if (codeBlockMatch) {
118
- cleanDiff = codeBlockMatch[1].trim();
119
- }
120
- // Strategy 2: Check if it's a complete file (no diff markers)
121
- const hasDiffMarkers = cleanDiff.includes('---') || cleanDiff.includes('+++') || cleanDiff.includes('@@');
122
- // If no diff markers and substantial content, treat as complete file
123
- if (!hasDiffMarkers) {
124
- // Verify it looks like code (has common patterns)
125
- const looksLikeCode = cleanDiff.includes('function') ||
126
- cleanDiff.includes('class') ||
127
- cleanDiff.includes('import') ||
128
- cleanDiff.includes('export') ||
129
- cleanDiff.includes('const') ||
130
- cleanDiff.includes('async');
131
- if (looksLikeCode && cleanDiff.length > 100) {
132
- // Likely complete file content
133
- return cleanDiff;
134
- }
135
- }
136
- // Strategy 3: Try unified diff parsing if it has diff markers
137
- if (hasDiffMarkers) {
138
- try {
139
- const result = applyUnifiedDiff(originalContent, cleanDiff);
140
- // Basic sanity check
141
- if (result && result.length > 0 && result !== originalContent) {
142
- // Verify it's not just the diff itself
143
- if (!result.startsWith('---') && !result.startsWith('+++')) {
144
- return result;
145
- }
146
- }
147
- }
148
- catch (error) {
149
- if (process.env.CODEHERE_DEBUG === '1')
150
- console.warn('[DiffParser] Unified diff parsing failed:', error);
151
- }
152
- }
153
- // Strategy 4: Last resort - if it's substantial content, use it
154
- if (cleanDiff.length > 200 && !cleanDiff.startsWith('---') && !cleanDiff.startsWith('+++')) {
155
- return cleanDiff;
156
- }
157
- // Strategy 5: If all else fails, return original (safer than broken code)
158
- if (process.env.CODEHERE_DEBUG === '1')
159
- console.warn('[DiffParser] Could not parse diff, returning original content');
160
- return originalContent;
161
- }
162
- //# sourceMappingURL=diff-parser.js.map
@@ -1,259 +0,0 @@
1
- /**
2
- * File Backup and Rollback Module
3
- * Creates backups before edits and enables rollback on verification failure
4
- */
5
- import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync, readdirSync, statSync } from 'fs';
6
- import { join, dirname, basename } from 'path';
7
- import { executionTracer } from '../infrastructure/observability/execution-tracer.js';
8
- const BACKUP_DIR = '.codehere/backups';
9
- const MAX_BACKUPS = 5; // Keep last 5 backups per file
10
- /**
11
- * Create backup of file before editing
12
- */
13
- export async function backupFile(filepath) {
14
- try {
15
- // Read original file
16
- if (!existsSync(filepath)) {
17
- throw new Error(`File not found: ${filepath}`);
18
- }
19
- const originalContent = readFileSync(filepath, 'utf-8');
20
- // Create backup directory
21
- const projectDir = findProjectRoot(filepath) || dirname(filepath);
22
- const backupDir = join(projectDir, BACKUP_DIR);
23
- if (!existsSync(backupDir)) {
24
- mkdirSync(backupDir, { recursive: true });
25
- }
26
- // Generate backup filename with timestamp
27
- const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
28
- const filename = basename(filepath);
29
- const backupPath = join(backupDir, `${filename}.${timestamp}.backup`);
30
- // Write backup
31
- writeFileSync(backupPath, originalContent, 'utf-8');
32
- // Link backup to current run for traceability
33
- const runId = executionTracer.getCurrentRunId();
34
- if (runId) {
35
- executionTracer.trace({
36
- operationType: 'file_operation',
37
- operationName: 'backup',
38
- input: { filepath },
39
- output: { backupPath },
40
- metadata: {
41
- runId,
42
- filepath,
43
- timestamp: new Date().toISOString(),
44
- },
45
- });
46
- }
47
- // Clean up old backups for this file
48
- await cleanupOldBackups(backupDir, filename);
49
- return backupPath;
50
- }
51
- catch (error) {
52
- throw new Error(`Failed to create backup: ${error instanceof Error ? error.message : String(error)}`);
53
- }
54
- }
55
- /**
56
- * Restore file from backup
57
- */
58
- export async function rollbackFile(filepath, backupPath) {
59
- try {
60
- // If no backup path provided, find most recent backup
61
- if (!backupPath) {
62
- const latestBackup = await findLatestBackup(filepath);
63
- if (!latestBackup) {
64
- throw new Error(`No backup found for file: ${filepath}`);
65
- }
66
- backupPath = latestBackup;
67
- }
68
- // Verify backup exists
69
- if (!existsSync(backupPath)) {
70
- throw new Error(`Backup file not found: ${backupPath}`);
71
- }
72
- // Read backup content
73
- const backupContent = readFileSync(backupPath, 'utf-8');
74
- // Restore original file
75
- writeFileSync(filepath, backupContent, 'utf-8');
76
- // Trace rollback operation
77
- const runId = executionTracer.getCurrentRunId();
78
- if (runId) {
79
- executionTracer.trace({
80
- operationType: 'file_operation',
81
- operationName: 'rollback',
82
- input: { filepath, backupPath },
83
- output: { restored: true },
84
- metadata: {
85
- runId,
86
- filepath,
87
- backupPath,
88
- timestamp: new Date().toISOString(),
89
- },
90
- });
91
- }
92
- }
93
- catch (error) {
94
- throw new Error(`Failed to rollback file: ${error instanceof Error ? error.message : String(error)}`);
95
- }
96
- }
97
- /**
98
- * Find latest backup for a file
99
- */
100
- export async function findLatestBackup(filepath) {
101
- try {
102
- const projectDir = findProjectRoot(filepath) || dirname(filepath);
103
- const backupDir = join(projectDir, BACKUP_DIR);
104
- if (!existsSync(backupDir)) {
105
- return null;
106
- }
107
- const filename = basename(filepath);
108
- const files = readdirSync(backupDir)
109
- .filter(file => file.startsWith(`${filename}.`) && file.endsWith('.backup'))
110
- .map(file => join(backupDir, file))
111
- .filter(file => existsSync(file));
112
- if (files.length === 0) {
113
- return null;
114
- }
115
- // Sort by modification time (newest first)
116
- files.sort((a, b) => {
117
- const statA = statSync(a);
118
- const statB = statSync(b);
119
- return statB.mtime.getTime() - statA.mtime.getTime();
120
- });
121
- return files[0]; // Return most recent backup
122
- }
123
- catch (error) {
124
- return null;
125
- }
126
- }
127
- /**
128
- * List all backups for a file
129
- */
130
- export async function listBackups(filepath) {
131
- try {
132
- const projectDir = findProjectRoot(filepath) || dirname(filepath);
133
- const backupDir = join(projectDir, BACKUP_DIR);
134
- if (!existsSync(backupDir)) {
135
- return [];
136
- }
137
- const filename = basename(filepath);
138
- const files = readdirSync(backupDir)
139
- .filter(file => file.startsWith(`${filename}.`) && file.endsWith('.backup'))
140
- .map(file => {
141
- const backupPath = join(backupDir, file);
142
- if (!existsSync(backupPath)) {
143
- return null;
144
- }
145
- const stat = statSync(backupPath);
146
- const timestampMatch = file.match(/\.([^.]+)\.backup$/);
147
- let timestamp;
148
- if (timestampMatch) {
149
- // Timestamp format: 2025-12-02T00-10-46-506Z (dashes instead of colons)
150
- // Convert to ISO format: 2025-12-02T00:10:46.506Z
151
- const timestampStr = timestampMatch[1];
152
- // Replace dashes with colons, but keep date part dashes
153
- // Format: YYYY-MM-DDTHH-MM-SS-MMMZ
154
- // Convert: YYYY-MM-DDTHH:MM:SS.MMMZ
155
- const isoStr = timestampStr
156
- .replace(/T(\d{2})-(\d{2})-(\d{2})-(\d{3})Z$/, 'T$1:$2:$3.$4Z');
157
- try {
158
- timestamp = new Date(isoStr);
159
- // Validate date
160
- if (isNaN(timestamp.getTime())) {
161
- timestamp = stat.mtime; // Fallback to file mtime
162
- }
163
- }
164
- catch {
165
- timestamp = stat.mtime; // Fallback to file mtime
166
- }
167
- }
168
- else {
169
- timestamp = stat.mtime;
170
- }
171
- return {
172
- backupPath,
173
- originalPath: filepath,
174
- timestamp,
175
- };
176
- })
177
- .filter((info) => info !== null);
178
- // Sort by timestamp (newest first)
179
- files.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
180
- return files;
181
- }
182
- catch (error) {
183
- return [];
184
- }
185
- }
186
- /**
187
- * Clean up old backups (keep only MAX_BACKUPS most recent)
188
- */
189
- async function cleanupOldBackups(backupDir, filename) {
190
- try {
191
- const files = readdirSync(backupDir)
192
- .filter(file => file.startsWith(`${filename}.`) && file.endsWith('.backup'))
193
- .map(file => join(backupDir, file))
194
- .filter(file => existsSync(file));
195
- if (files.length <= MAX_BACKUPS) {
196
- return; // No cleanup needed
197
- }
198
- // Sort by modification time (oldest first)
199
- files.sort((a, b) => {
200
- const statA = statSync(a);
201
- const statB = statSync(b);
202
- return statA.mtime.getTime() - statB.mtime.getTime();
203
- });
204
- // Delete oldest backups
205
- const toDelete = files.slice(0, files.length - MAX_BACKUPS);
206
- for (const file of toDelete) {
207
- try {
208
- unlinkSync(file);
209
- }
210
- catch {
211
- // Ignore deletion errors
212
- }
213
- }
214
- }
215
- catch (error) {
216
- // Ignore cleanup errors - don't fail if cleanup fails
217
- }
218
- }
219
- /**
220
- * Delete all backups for a file
221
- */
222
- export async function deleteAllBackups(filepath) {
223
- try {
224
- const backups = await listBackups(filepath);
225
- for (const backup of backups) {
226
- try {
227
- if (existsSync(backup.backupPath)) {
228
- unlinkSync(backup.backupPath);
229
- }
230
- }
231
- catch {
232
- // Ignore deletion errors
233
- }
234
- }
235
- }
236
- catch (error) {
237
- // Ignore cleanup errors
238
- }
239
- }
240
- /**
241
- * Find project root (where package.json or .git is)
242
- */
243
- function findProjectRoot(filepath) {
244
- let currentDir = dirname(filepath);
245
- const root = currentDir.split(/[/\\]/)[0];
246
- while (currentDir !== root) {
247
- if (existsSync(join(currentDir, 'package.json')) ||
248
- existsSync(join(currentDir, '.git'))) {
249
- return currentDir;
250
- }
251
- const parentDir = dirname(currentDir);
252
- if (parentDir === currentDir) {
253
- break;
254
- }
255
- currentDir = parentDir;
256
- }
257
- return null;
258
- }
259
- //# sourceMappingURL=backup.js.map
@@ -1,264 +0,0 @@
1
- /**
2
- * Compilation Verification Module
3
- * Verifies TypeScript and JavaScript code compiles/syntax checks correctly
4
- */
5
- import { readFileSync, existsSync } from 'fs';
6
- import { join, dirname, extname } from 'path';
7
- import { execSync } from 'child_process';
8
- import { mkdirSync, writeFileSync, unlinkSync } from 'fs';
9
- import { tmpdir } from 'os';
10
- /**
11
- * Verify code compilation based on file type
12
- */
13
- export async function verifyCompilation(filepath, code, options = {}) {
14
- const ext = extname(filepath).toLowerCase();
15
- // Use provided code or read from file
16
- const codeToCheck = code || (existsSync(filepath) ? readFileSync(filepath, 'utf-8') : '');
17
- if (!codeToCheck) {
18
- return {
19
- success: false,
20
- errors: ['No code provided and file does not exist'],
21
- warnings: [],
22
- };
23
- }
24
- // Route to appropriate verifier
25
- if (ext === '.ts' || ext === '.tsx') {
26
- return await verifyTypeScriptCompilation(filepath, codeToCheck, options);
27
- }
28
- else if (ext === '.js' || ext === '.jsx') {
29
- return await verifyJavaScriptSyntax(filepath, codeToCheck, options);
30
- }
31
- // Unknown file type - skip verification
32
- return {
33
- success: true,
34
- errors: [],
35
- warnings: [`Unknown file type ${ext}, skipping compilation check`],
36
- };
37
- }
38
- /**
39
- * Verify TypeScript compilation
40
- */
41
- async function verifyTypeScriptCompilation(filepath, code, options = {}) {
42
- const errors = [];
43
- const warnings = [];
44
- const timeout = options.timeout || 30000; // 30 seconds default
45
- const skipLibCheck = options.skipLibCheck !== false; // Default to true
46
- try {
47
- // Create temporary file for checking
48
- const tmpDir = join(tmpdir(), 'codehere-verification');
49
- if (!existsSync(tmpDir)) {
50
- mkdirSync(tmpDir, { recursive: true });
51
- }
52
- const tmpFile = join(tmpDir, `check-${Date.now()}.ts`);
53
- writeFileSync(tmpFile, code, 'utf-8');
54
- try {
55
- // Build tsc command
56
- const tscArgs = [
57
- '--noEmit',
58
- skipLibCheck ? '--skipLibCheck' : '',
59
- '--strict',
60
- `"${tmpFile}"`,
61
- ].filter(Boolean).join(' ');
62
- // Try to find tsconfig.json in project root
63
- const projectDir = findProjectRoot(filepath);
64
- const hasTsConfig = projectDir && (existsSync(join(projectDir, 'tsconfig.json')) ||
65
- existsSync(join(projectDir, 'tsconfig.base.json')));
66
- let command;
67
- if (hasTsConfig && projectDir) {
68
- // Use project tsconfig.json
69
- command = `cd "${projectDir}" && npx tsc ${tscArgs}`;
70
- }
71
- else {
72
- // Use standalone file check
73
- command = `npx tsc ${tscArgs}`;
74
- }
75
- const result = execSync(command, {
76
- encoding: 'utf-8',
77
- stdio: 'pipe',
78
- timeout,
79
- cwd: projectDir || dirname(filepath),
80
- });
81
- // If execution succeeded with no output, compilation passed
82
- if (!result || result.trim().length === 0) {
83
- return { success: true, errors: [], warnings: [] };
84
- }
85
- // Parse output for errors and warnings (enhanced pattern detection)
86
- const lines = result.split('\n');
87
- for (const line of lines) {
88
- const trimmedLine = line.trim();
89
- // Enhanced error detection patterns
90
- if (trimmedLine.includes('error TS') ||
91
- trimmedLine.match(/error\s+TS\d+/i) ||
92
- trimmedLine.includes('Cannot find') ||
93
- trimmedLine.includes('is not defined') ||
94
- trimmedLine.includes('has no exported member') ||
95
- trimmedLine.includes('Property') && trimmedLine.includes('does not exist') ||
96
- trimmedLine.includes('Type') && trimmedLine.includes('is not assignable')) {
97
- errors.push(trimmedLine);
98
- }
99
- else if (trimmedLine.includes('warning TS') || trimmedLine.match(/warning\s+TS\d+/i)) {
100
- warnings.push(trimmedLine);
101
- }
102
- }
103
- return {
104
- success: errors.length === 0,
105
- errors,
106
- warnings,
107
- output: result,
108
- };
109
- }
110
- finally {
111
- // Clean up temp file
112
- try {
113
- if (existsSync(tmpFile)) {
114
- unlinkSync(tmpFile);
115
- }
116
- }
117
- catch {
118
- // Ignore cleanup errors
119
- }
120
- }
121
- }
122
- catch (error) {
123
- // execSync throws on non-zero exit code
124
- const output = error.stdout || error.stderr || error.message || '';
125
- const errorOutput = String(output);
126
- // Parse error output (enhanced pattern detection)
127
- const lines = errorOutput.split('\n');
128
- for (const line of lines) {
129
- const trimmedLine = line.trim();
130
- // Enhanced error detection patterns
131
- if (trimmedLine.includes('error TS') ||
132
- trimmedLine.match(/error\s+TS\d+/i) ||
133
- trimmedLine.includes('Cannot find') ||
134
- trimmedLine.includes('is not defined') ||
135
- trimmedLine.includes('has no exported member') ||
136
- trimmedLine.includes('Property') && trimmedLine.includes('does not exist') ||
137
- trimmedLine.includes('Type') && trimmedLine.includes('is not assignable') ||
138
- trimmedLine.includes('Module') && trimmedLine.includes('has no exported member')) {
139
- errors.push(trimmedLine);
140
- }
141
- else if (trimmedLine.includes('warning TS') || trimmedLine.match(/warning\s+TS\d+/i)) {
142
- warnings.push(trimmedLine);
143
- }
144
- }
145
- // If no structured errors found, try to extract meaningful error patterns
146
- if (errors.length === 0) {
147
- // Look for common error patterns in output
148
- const errorPatterns = [
149
- /(?:error|Error)[:\s]+(.+)/i,
150
- /(?:failed|Failed)[:\s]+(.+)/i,
151
- /(?:cannot|Cannot)[:\s]+(.+)/i,
152
- /(?:undefined|Undefined)[:\s]+(.+)/i,
153
- ];
154
- let foundError = false;
155
- for (const pattern of errorPatterns) {
156
- const match = errorOutput.match(pattern);
157
- if (match && match[1]) {
158
- errors.push(`TypeScript compilation error: ${match[1].trim().substring(0, 200)}`);
159
- foundError = true;
160
- break;
161
- }
162
- }
163
- if (!foundError) {
164
- errors.push(`TypeScript compilation failed: ${errorOutput.substring(0, 500)}`);
165
- }
166
- }
167
- // Check for timeout
168
- if (error.signal === 'SIGTERM' || errorOutput.includes('timeout')) {
169
- errors.push('Compilation check timed out');
170
- }
171
- // Check if tsc is available
172
- if (errorOutput.includes('command not found') || errorOutput.includes('Cannot find module')) {
173
- warnings.push('TypeScript compiler (tsc) not found. Install it with: npm install -D typescript');
174
- // Don't fail if tsc is not installed - this is a warning, not an error
175
- return {
176
- success: true, // Allow to proceed if compiler not available
177
- errors: [],
178
- warnings: ['TypeScript compiler not available, skipping compilation check'],
179
- };
180
- }
181
- return {
182
- success: false,
183
- errors,
184
- warnings,
185
- output: errorOutput,
186
- };
187
- }
188
- }
189
- /**
190
- * Verify JavaScript syntax
191
- */
192
- async function verifyJavaScriptSyntax(filepath, code, options = {}) {
193
- const errors = [];
194
- const warnings = [];
195
- try {
196
- // Syntax check: write to temp file and use node --check (parse-only, no execution)
197
- const tmpFile = join(tmpdir(), `codehere-syntax-${Date.now()}.js`);
198
- try {
199
- writeFileSync(tmpFile, code, 'utf-8');
200
- execSync(`node --check "${tmpFile}"`, { stdio: 'pipe' });
201
- }
202
- catch (parseError) {
203
- const errorMsg = parseError instanceof Error ? parseError.message : String(parseError);
204
- const lineMatch = errorMsg.match(/line (\d+)/i) || errorMsg.match(/:(\d+):/);
205
- const lineNum = lineMatch ? lineMatch[1] : '?';
206
- errors.push(`Syntax error at line ${lineNum}: ${errorMsg}`);
207
- return { success: false, errors, warnings };
208
- }
209
- finally {
210
- try {
211
- unlinkSync(tmpFile);
212
- }
213
- catch { /* ignore */ }
214
- }
215
- // Additional check: Try to parse as ES module
216
- // This catches import/export syntax errors
217
- try {
218
- // Create temporary file and try to load it as module
219
- // This is a lightweight check
220
- if (code.includes('import ') || code.includes('export ')) {
221
- // For ES modules, we'd need more sophisticated checking
222
- // For now, syntax check is sufficient
223
- }
224
- }
225
- catch (moduleError) {
226
- warnings.push(`Module syntax warning: ${moduleError instanceof Error ? moduleError.message : String(moduleError)}`);
227
- }
228
- return {
229
- success: true,
230
- errors: [],
231
- warnings,
232
- };
233
- }
234
- catch (error) {
235
- errors.push(`JavaScript syntax check failed: ${error instanceof Error ? error.message : String(error)}`);
236
- return {
237
- success: false,
238
- errors,
239
- warnings,
240
- };
241
- }
242
- }
243
- /**
244
- * Find project root (where package.json or tsconfig.json is)
245
- */
246
- function findProjectRoot(filepath) {
247
- let currentDir = dirname(filepath);
248
- const root = currentDir.split(/[/\\]/)[0]; // Get filesystem root
249
- // Walk up directory tree
250
- while (currentDir !== root) {
251
- if (existsSync(join(currentDir, 'package.json')) ||
252
- existsSync(join(currentDir, 'tsconfig.json')) ||
253
- existsSync(join(currentDir, 'tsconfig.base.json'))) {
254
- return currentDir;
255
- }
256
- const parentDir = dirname(currentDir);
257
- if (parentDir === currentDir) {
258
- break; // Reached root
259
- }
260
- currentDir = parentDir;
261
- }
262
- return null;
263
- }
264
- //# sourceMappingURL=compiler.js.map