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.
Files changed (238) 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 +261 -1224
  5. package/dist/infrastructure/config/product-context.js +7 -6
  6. package/dist/infrastructure/hooks/claude-sdk-hook.js +348 -72
  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/conductor-adapter.js +340 -0
  16. package/dist/infrastructure/orchestration/generic-cli-adapter.js +553 -0
  17. package/dist/infrastructure/orchestration/opencode-adapter.js +275 -0
  18. package/dist/infrastructure/orchestration/progress-aggregator.js +189 -0
  19. package/dist/infrastructure/orchestration/readiness.js +106 -0
  20. package/dist/infrastructure/orchestration/session-manager.js +278 -0
  21. package/dist/infrastructure/orchestration/session-persistence.js +109 -0
  22. package/dist/infrastructure/protocols/mcp-helpers.js +10 -30
  23. package/dist/infrastructure/protocols/mcp-server-impl.js +359 -21
  24. package/dist/infrastructure/protocols/probe-port.js +36 -0
  25. package/dist/infrastructure/protocols/ui-page.js +1827 -0
  26. package/dist/infrastructure/security/file-collection.js +115 -0
  27. package/dist/infrastructure/security/trust-scorer.js +301 -56
  28. package/dist/infrastructure/storage/task-repository.js +8 -7
  29. package/dist/monitoring.js +9 -38
  30. package/dist/presentation/cli/commands/help-command.js +96 -139
  31. package/dist/presentation/cli/commands/hook-command.js +17 -24
  32. package/dist/presentation/cli/commands/report-command.js +59 -72
  33. package/dist/presentation/cli/commands/setup-command.js +4 -4
  34. package/dist/presentation/cli/commands/status-command.js +321 -30
  35. package/dist/presentation/cli/commands/trust-command.js +84 -72
  36. package/dist/presentation/cli/error-display.js +17 -21
  37. package/dist/presentation/cli/repl.js +474 -0
  38. package/dist/ui.js +11 -11
  39. package/package.json +24 -62
  40. package/dist/agents/base.js +0 -101
  41. package/dist/agents/orchestrator-model-driven.js +0 -141
  42. package/dist/agents/react-orchestrator-agent.js +0 -54
  43. package/dist/application/agents/execution-agent.js +0 -508
  44. package/dist/application/agents/multi-agent-orchestrator.js +0 -295
  45. package/dist/application/agents/planning-agent.js +0 -433
  46. package/dist/application/agents/validation-agent.js +0 -317
  47. package/dist/application/architectures/plan-and-act.js +0 -242
  48. package/dist/application/index.js +0 -12
  49. package/dist/application/services/agent-factory.js +0 -28
  50. package/dist/application/services/dependency-container.js +0 -596
  51. package/dist/application/services/git-context-service.js +0 -83
  52. package/dist/application/services/intelligent-router.js +0 -934
  53. package/dist/application/services/tool-executor-service.js +0 -94
  54. package/dist/application/use-cases/ask-question-use-case.js +0 -338
  55. package/dist/application/use-cases/edit-file-use-case.js +0 -830
  56. package/dist/application/use-cases/explain-file-use-case.js +0 -50
  57. package/dist/application/use-cases/index-codebase-use-case.js +0 -113
  58. package/dist/application/use-cases/planning-use-case.js +0 -276
  59. package/dist/application/use-cases/react-orchestration-use-case.js +0 -329
  60. package/dist/application/use-cases/reflexion-use-case.js +0 -30
  61. package/dist/application/workflows/deterministic-workflows.js +0 -189
  62. package/dist/ast-parser.js +0 -331
  63. package/dist/cache.js +0 -180
  64. package/dist/chat.js +0 -251
  65. package/dist/code-analysis.js +0 -327
  66. package/dist/context.js +0 -187
  67. package/dist/docs.js +0 -146
  68. package/dist/domain/entities/code-chunk.js +0 -6
  69. package/dist/domain/entities/decision.js +0 -9
  70. package/dist/domain/entities/edit.js +0 -6
  71. package/dist/domain/entities/knowledge-node.js +0 -9
  72. package/dist/domain/entities/knowledge-preservation.js +0 -10
  73. package/dist/domain/entities/memory.js +0 -6
  74. package/dist/domain/entities/pattern.js +0 -7
  75. package/dist/domain/entities/plan.js +0 -6
  76. package/dist/domain/entities/query.js +0 -6
  77. package/dist/domain/errors/embeddings-not-found-error.js +0 -13
  78. package/dist/domain/index.js +0 -19
  79. package/dist/domain/interfaces/ai-service.interface.js +0 -6
  80. package/dist/domain/interfaces/code-analyzer.interface.js +0 -6
  81. package/dist/domain/interfaces/decision-repository.interface.js +0 -9
  82. package/dist/domain/interfaces/embedding-repository.interface.js +0 -6
  83. package/dist/domain/interfaces/knowledge-graph-repository.interface.js +0 -9
  84. package/dist/domain/interfaces/knowledge-preservation-repository.interface.js +0 -8
  85. package/dist/domain/interfaces/memory-repository.interface.js +0 -6
  86. package/dist/domain/interfaces/pattern-repository.interface.js +0 -6
  87. package/dist/domain/interfaces/verification-service.interface.js +0 -6
  88. package/dist/domain/services/cross-team-pattern-sharing.js +0 -125
  89. package/dist/domain/services/decision-recorder.js +0 -223
  90. package/dist/domain/services/decision-retriever.js +0 -133
  91. package/dist/domain/services/environment-mode-manager.js +0 -22
  92. package/dist/domain/services/graded-memory-activation.js +0 -69
  93. package/dist/domain/services/knowledge-access.js +0 -132
  94. package/dist/domain/services/knowledge-extractor.js +0 -247
  95. package/dist/domain/services/knowledge-graph-builder.js +0 -268
  96. package/dist/domain/services/knowledge-graph-query.js +0 -187
  97. package/dist/domain/services/memory-retriever.js +0 -82
  98. package/dist/domain/services/memory-synthesizer.js +0 -91
  99. package/dist/domain/services/pattern-extractor.js +0 -442
  100. package/dist/domain/services/query-intent-classifier.js +0 -140
  101. package/dist/domain/services/react-loop.js +0 -186
  102. package/dist/domain/services/risk-tier-detector.js +0 -78
  103. package/dist/edit.js +0 -319
  104. package/dist/embed.js +0 -459
  105. package/dist/formatter.js +0 -168
  106. package/dist/git.js +0 -198
  107. package/dist/infrastructure/ai/cohere-ai-service.js +0 -607
  108. package/dist/infrastructure/ai/command-r-evaluation.js +0 -206
  109. package/dist/infrastructure/ai/model-config.js +0 -84
  110. package/dist/infrastructure/ai/provider-ai-service.js +0 -477
  111. package/dist/infrastructure/cache/embedding-cache.js +0 -175
  112. package/dist/infrastructure/cache/query-result-cache.js +0 -66
  113. package/dist/infrastructure/cache/response-cache.js +0 -48
  114. package/dist/infrastructure/cache/security-scan-cache.js +0 -47
  115. package/dist/infrastructure/chunking/ast-code-chunker.js +0 -19
  116. package/dist/infrastructure/chunking/code-aware-chunker.js +0 -397
  117. package/dist/infrastructure/context/context-compressor.js +0 -329
  118. package/dist/infrastructure/context/conversation-context.js +0 -128
  119. package/dist/infrastructure/context/session-manager.js +0 -94
  120. package/dist/infrastructure/cost/cost-tracker.js +0 -360
  121. package/dist/infrastructure/file-scanner/file-scanner.js +0 -106
  122. package/dist/infrastructure/governance/nist-ai-rmf.js +0 -292
  123. package/dist/infrastructure/governance/policy-as-code.js +0 -258
  124. package/dist/infrastructure/governance/prompt-to-code-lineage.js +0 -239
  125. package/dist/infrastructure/index.js +0 -7
  126. package/dist/infrastructure/observability/prompt-versioner.js +0 -145
  127. package/dist/infrastructure/protocols/a2a-metadata.js +0 -137
  128. package/dist/infrastructure/protocols/a2a-protocol.js +0 -314
  129. package/dist/infrastructure/protocols/mcp-oauth.js +0 -184
  130. package/dist/infrastructure/protocols/mcp-server.js +0 -333
  131. package/dist/infrastructure/protocols/streaming-handler.js +0 -103
  132. package/dist/infrastructure/providers/cohere-provider.js +0 -444
  133. package/dist/infrastructure/providers/fake-provider.js +0 -130
  134. package/dist/infrastructure/providers/local-llm-provider.js +0 -330
  135. package/dist/infrastructure/providers/model-config.types.js +0 -9
  136. package/dist/infrastructure/providers/model-provider.interface.js +0 -8
  137. package/dist/infrastructure/providers/openai-provider.js +0 -413
  138. package/dist/infrastructure/providers/openrouter-provider.js +0 -399
  139. package/dist/infrastructure/providers/operation-provider-resolver.js +0 -105
  140. package/dist/infrastructure/providers/provider-config-loader.js +0 -120
  141. package/dist/infrastructure/providers/provider-registry.js +0 -88
  142. package/dist/infrastructure/safety/pattern-detector.js +0 -133
  143. package/dist/infrastructure/security/ai-sast-scanner.js +0 -290
  144. package/dist/infrastructure/security/docker-sandbox.js +0 -178
  145. package/dist/infrastructure/security/enhanced-security-gate.js +0 -151
  146. package/dist/infrastructure/security/license-scanner.js +0 -167
  147. package/dist/infrastructure/security/provider-bias-detector.js +0 -164
  148. package/dist/infrastructure/security/sandbox-executor.js +0 -64
  149. package/dist/infrastructure/serialization/toon-serializer.js +0 -119
  150. package/dist/infrastructure/storage/memory-stream-service.js +0 -204
  151. package/dist/infrastructure/storage/plan-repository.js +0 -96
  152. package/dist/infrastructure/storage/sqlite-decision-repository.js +0 -232
  153. package/dist/infrastructure/storage/sqlite-embedding-repository.js +0 -311
  154. package/dist/infrastructure/storage/sqlite-knowledge-graph-repository.js +0 -417
  155. package/dist/infrastructure/storage/sqlite-knowledge-preservation-repository.js +0 -230
  156. package/dist/infrastructure/storage/sqlite-memory-repository.js +0 -229
  157. package/dist/infrastructure/storage/sqlite-pattern-repository.js +0 -249
  158. package/dist/infrastructure/storage/task-helpers.js +0 -197
  159. package/dist/infrastructure/telemetry/telemetry-service.js +0 -167
  160. package/dist/infrastructure/ux/appropriate-friction.js +0 -213
  161. package/dist/infrastructure/ux/bi-directional-learning.js +0 -337
  162. package/dist/infrastructure/ux/capability-boundaries.js +0 -42
  163. package/dist/infrastructure/ux/comprehensive-formatter.js +0 -117
  164. package/dist/infrastructure/ux/contextual-feature-discovery.js +0 -10
  165. package/dist/infrastructure/ux/expectation-management.js +0 -327
  166. package/dist/infrastructure/ux/feature-discovery.js +0 -14
  167. package/dist/infrastructure/ux/feedback-prompt.js +0 -45
  168. package/dist/infrastructure/ux/hitl-validation.js +0 -297
  169. package/dist/infrastructure/ux/progress-indicator.js +0 -116
  170. package/dist/infrastructure/ux/progressive-disclosure.js +0 -236
  171. package/dist/infrastructure/ux/review-checkpoint.js +0 -72
  172. package/dist/infrastructure/ux/staged-feature-intro.js +0 -24
  173. package/dist/infrastructure/ux/stream-markdown.js +0 -151
  174. package/dist/infrastructure/ux/syntax-highlighter.js +0 -91
  175. package/dist/infrastructure/ux/team-standards.js +0 -196
  176. package/dist/infrastructure/ux/transparency.js +0 -71
  177. package/dist/infrastructure/validation/agent-feedback.js +0 -55
  178. package/dist/infrastructure/validation/agent-validation-helper.js +0 -137
  179. package/dist/infrastructure/validation/review-handler.js +0 -40
  180. package/dist/infrastructure/validation/summary-aggregator.js +0 -70
  181. package/dist/infrastructure/validation/summary-extractor.js +0 -45
  182. package/dist/infrastructure/validation/trace-summary.js +0 -52
  183. package/dist/infrastructure/verification/verification-service.js +0 -47
  184. package/dist/infrastructure/xai/attention-visualizer.js +0 -172
  185. package/dist/infrastructure/xai/cot-visualizer.js +0 -283
  186. package/dist/infrastructure/xai/decision-tree-log.js +0 -212
  187. package/dist/infrastructure/xai/interactive-xai.js +0 -260
  188. package/dist/infrastructure/xai/uncertainty-quantifier.js +0 -198
  189. package/dist/intelligent-retrieval.js +0 -272
  190. package/dist/intent/classifier.js +0 -2
  191. package/dist/intent/context.js +0 -2
  192. package/dist/iterative-refinement.js +0 -189
  193. package/dist/learning.js +0 -232
  194. package/dist/log.js +0 -31
  195. package/dist/migrate.js +0 -133
  196. package/dist/parallel-processor.js +0 -534
  197. package/dist/planner.js +0 -198
  198. package/dist/policy.js +0 -26
  199. package/dist/presentation/cli/commands/ask-command.js +0 -314
  200. package/dist/presentation/cli/commands/cost-command.js +0 -191
  201. package/dist/presentation/cli/commands/decision-command.js +0 -207
  202. package/dist/presentation/cli/commands/docs-command.js +0 -25
  203. package/dist/presentation/cli/commands/fix-command.js +0 -53
  204. package/dist/presentation/cli/commands/knowledge-command.js +0 -129
  205. package/dist/presentation/cli/commands/learning-dashboard-command.js +0 -183
  206. package/dist/presentation/cli/commands/models-command.js +0 -194
  207. package/dist/presentation/cli/commands/orchestrate-command.js +0 -207
  208. package/dist/presentation/cli/commands/plan-command.js +0 -246
  209. package/dist/presentation/cli/commands/product-command.js +0 -199
  210. package/dist/presentation/cli/commands/react-command.js +0 -181
  211. package/dist/presentation/cli/commands/review-command.js +0 -154
  212. package/dist/presentation/cli/commands/run-command.js +0 -188
  213. package/dist/presentation/cli/commands/smart-command.js +0 -395
  214. package/dist/presentation/cli/commands/suggest-command.js +0 -138
  215. package/dist/presentation/cli/commands/trace-command.js +0 -129
  216. package/dist/presentation/cli/commands/undo-command.js +0 -150
  217. package/dist/query-optimizer.js +0 -205
  218. package/dist/refactor.js +0 -116
  219. package/dist/review.js +0 -206
  220. package/dist/search.js +0 -163
  221. package/dist/session.js +0 -704
  222. package/dist/task-verification.js +0 -336
  223. package/dist/testgen.js +0 -166
  224. package/dist/token-optimizer.js +0 -277
  225. package/dist/tools/bash.js +0 -213
  226. package/dist/tools/edit.js +0 -235
  227. package/dist/tools/executor.js +0 -153
  228. package/dist/tools/git-tool.js +0 -292
  229. package/dist/tools/parser.js +0 -158
  230. package/dist/tools/registry.js +0 -302
  231. package/dist/tools/search.js +0 -100
  232. package/dist/types.js +0 -2
  233. package/dist/utils/check-api-status.js +0 -100
  234. package/dist/utils/diff-parser.js +0 -162
  235. package/dist/verification/backup.js +0 -259
  236. package/dist/verification/compiler.js +0 -264
  237. package/dist/verification/index.js +0 -273
  238. 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