vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1642

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 (202) hide show
  1. package/README.md +240 -0
  2. package/package.json +10 -2
  3. package/src/agents/Agent.js +300 -0
  4. package/src/agents/AgentAdditionService.js +311 -0
  5. package/src/agents/AgentCheckService.js +690 -0
  6. package/src/agents/AgentInstallationService.js +140 -0
  7. package/src/agents/AgentSetupService.js +467 -0
  8. package/src/agents/AgentStatus.js +183 -0
  9. package/src/agents/AgentVerificationService.js +634 -0
  10. package/src/agents/ConfigurationSchemaValidator.js +543 -0
  11. package/src/agents/EnvironmentConfigurationManager.js +602 -0
  12. package/src/agents/InstallationErrorHandler.js +372 -0
  13. package/src/agents/InstallationLog.js +363 -0
  14. package/src/agents/InstallationMethod.js +510 -0
  15. package/src/agents/InstallationOrchestrator.js +352 -0
  16. package/src/agents/InstallationProgressReporter.js +372 -0
  17. package/src/agents/InstallationRetryManager.js +322 -0
  18. package/src/agents/InstallationType.js +254 -0
  19. package/src/agents/OperationTypes.js +310 -0
  20. package/src/agents/PerformanceMetricsCollector.js +493 -0
  21. package/src/agents/SecurityValidationService.js +534 -0
  22. package/src/agents/VerificationTest.js +354 -0
  23. package/src/agents/VerificationType.js +226 -0
  24. package/src/agents/WindowsPermissionHandler.js +518 -0
  25. package/src/agents/config/AgentConfigManager.js +393 -0
  26. package/src/agents/config/AgentDefaultsRegistry.js +373 -0
  27. package/src/agents/config/ConfigValidator.js +281 -0
  28. package/src/agents/discovery/AgentDiscoveryService.js +707 -0
  29. package/src/agents/logging/AgentLogger.js +511 -0
  30. package/src/agents/status/AgentStatusManager.js +481 -0
  31. package/src/agents/storage/FileManager.js +454 -0
  32. package/src/agents/verification/AgentCommunicationTester.js +474 -0
  33. package/src/agents/verification/BaseVerifier.js +430 -0
  34. package/src/agents/verification/CommandVerifier.js +480 -0
  35. package/src/agents/verification/FileOperationVerifier.js +453 -0
  36. package/src/agents/verification/ResultAnalyzer.js +707 -0
  37. package/src/agents/verification/TestRequirementManager.js +495 -0
  38. package/src/agents/verification/VerificationRunner.js +433 -0
  39. package/src/agents/windows/BaseWindowsInstaller.js +441 -0
  40. package/src/agents/windows/ChocolateyInstaller.js +509 -0
  41. package/src/agents/windows/DirectInstaller.js +443 -0
  42. package/src/agents/windows/InstallerFactory.js +391 -0
  43. package/src/agents/windows/NpmInstaller.js +505 -0
  44. package/src/agents/windows/PowerShellInstaller.js +458 -0
  45. package/src/agents/windows/WinGetInstaller.js +390 -0
  46. package/src/analysis/analysis-reporter.js +132 -0
  47. package/src/analysis/boundary-detector.js +712 -0
  48. package/src/analysis/categorizer.js +340 -0
  49. package/src/analysis/codebase-scanner.js +384 -0
  50. package/src/analysis/line-counter.js +513 -0
  51. package/src/analysis/priority-calculator.js +679 -0
  52. package/src/analysis/report/analysis-report.js +250 -0
  53. package/src/analysis/report/package-analyzer.js +278 -0
  54. package/src/analysis/report/recommendation-generator.js +382 -0
  55. package/src/analysis/report/statistics-generator.js +515 -0
  56. package/src/analysis/reports/analysis-report-model.js +101 -0
  57. package/src/analysis/reports/recommendation-generator.js +283 -0
  58. package/src/analysis/reports/report-generators.js +191 -0
  59. package/src/analysis/reports/statistics-calculator.js +231 -0
  60. package/src/analysis/reports/trend-analyzer.js +219 -0
  61. package/src/analysis/strategy-generator.js +814 -0
  62. package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
  63. package/src/config/refactoring-config.js +307 -0
  64. package/src/health-tracking/json-storage.js +38 -2
  65. package/src/ide-integration/applescript-manager-core.js +233 -0
  66. package/src/ide-integration/applescript-manager.cjs +357 -28
  67. package/src/ide-integration/applescript-manager.js +89 -3599
  68. package/src/ide-integration/cdp-manager.js +306 -0
  69. package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
  70. package/src/ide-integration/continuation-handler.js +337 -0
  71. package/src/ide-integration/ide-status-checker.js +292 -0
  72. package/src/ide-integration/macos-ide-manager.js +627 -0
  73. package/src/ide-integration/macos-text-sender.js +528 -0
  74. package/src/ide-integration/response-reader.js +548 -0
  75. package/src/ide-integration/windows-automation-manager.js +121 -0
  76. package/src/ide-integration/windows-ide-manager.js +373 -0
  77. package/src/index.cjs +25 -3
  78. package/src/index.js +15 -1
  79. package/src/llm/direct-llm-manager.cjs +90 -2
  80. package/src/models/compliance-report.js +538 -0
  81. package/src/models/file-analysis.js +681 -0
  82. package/src/models/refactoring-plan.js +770 -0
  83. package/src/monitoring/alert-system.js +834 -0
  84. package/src/monitoring/compliance-progress-tracker.js +437 -0
  85. package/src/monitoring/continuous-scan-notifications.js +661 -0
  86. package/src/monitoring/continuous-scanner.js +279 -0
  87. package/src/monitoring/file-monitor/file-analyzer.js +262 -0
  88. package/src/monitoring/file-monitor/file-monitor.js +237 -0
  89. package/src/monitoring/file-monitor/watcher.js +194 -0
  90. package/src/monitoring/file-monitor.js +17 -0
  91. package/src/monitoring/notification-manager.js +437 -0
  92. package/src/monitoring/scanner-core.js +368 -0
  93. package/src/monitoring/scanner-events.js +214 -0
  94. package/src/monitoring/violation-notification-system.js +515 -0
  95. package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
  96. package/src/refactoring/boundaries/extraction-result.js +285 -0
  97. package/src/refactoring/boundaries/extraction-strategies.js +392 -0
  98. package/src/refactoring/boundaries/module-boundary.js +209 -0
  99. package/src/refactoring/boundary/boundary-detector.js +741 -0
  100. package/src/refactoring/boundary/boundary-types.js +405 -0
  101. package/src/refactoring/boundary/extraction-strategies.js +554 -0
  102. package/src/refactoring/boundary-extraction-result.js +77 -0
  103. package/src/refactoring/boundary-extraction-strategies.js +330 -0
  104. package/src/refactoring/boundary-extractor.js +384 -0
  105. package/src/refactoring/boundary-types.js +46 -0
  106. package/src/refactoring/circular/circular-dependency.js +88 -0
  107. package/src/refactoring/circular/cycle-detection.js +147 -0
  108. package/src/refactoring/circular/dependency-node.js +82 -0
  109. package/src/refactoring/circular/dependency-result.js +107 -0
  110. package/src/refactoring/circular/dependency-types.js +58 -0
  111. package/src/refactoring/circular/graph-builder.js +213 -0
  112. package/src/refactoring/circular/resolution-strategy.js +72 -0
  113. package/src/refactoring/circular/strategy-generator.js +229 -0
  114. package/src/refactoring/circular-dependency-resolver-original.js +809 -0
  115. package/src/refactoring/circular-dependency-resolver.js +200 -0
  116. package/src/refactoring/code-mover.js +761 -0
  117. package/src/refactoring/file-splitter.js +696 -0
  118. package/src/refactoring/functionality-validator.js +816 -0
  119. package/src/refactoring/import-manager.js +774 -0
  120. package/src/refactoring/module-boundary.js +107 -0
  121. package/src/refactoring/refactoring-executor.js +672 -0
  122. package/src/refactoring/refactoring-rollback.js +614 -0
  123. package/src/refactoring/test-validator.js +631 -0
  124. package/src/requirement-management/default-requirement-manager.js +321 -0
  125. package/src/requirement-management/requirement-file-parser.js +159 -0
  126. package/src/requirement-management/requirement-sequencer.js +221 -0
  127. package/src/rui/commands/AgentCommandParser.js +600 -0
  128. package/src/rui/commands/AgentCommands.js +487 -0
  129. package/src/rui/commands/AgentResponseFormatter.js +832 -0
  130. package/src/scripts/verify-full-compliance.js +269 -0
  131. package/src/sync/sync-engine-core.js +1 -0
  132. package/src/sync/sync-engine-remote-handlers.js +135 -0
  133. package/src/task-generation/automated-task-generator.js +351 -0
  134. package/src/task-generation/prioritizer.js +287 -0
  135. package/src/task-generation/task-list-updater.js +215 -0
  136. package/src/task-generation/task-management-integration.js +480 -0
  137. package/src/task-generation/task-manager-integration.js +270 -0
  138. package/src/task-generation/violation-task-generator.js +474 -0
  139. package/src/task-management/continuous-scan-integration.js +342 -0
  140. package/src/timeout-management/index.js +12 -3
  141. package/src/timeout-management/response-time-tracker.js +167 -0
  142. package/src/timeout-management/timeout-calculator.js +159 -0
  143. package/src/timeout-management/timeout-config-manager.js +172 -0
  144. package/src/utils/ast-analyzer.js +417 -0
  145. package/src/utils/current-requirement-manager.js +276 -0
  146. package/src/utils/current-requirement-operations.js +472 -0
  147. package/src/utils/dependency-mapper.js +456 -0
  148. package/src/utils/download-with-progress.js +4 -2
  149. package/src/utils/electron-update-checker.js +4 -1
  150. package/src/utils/file-size-analyzer.js +272 -0
  151. package/src/utils/import-updater.js +280 -0
  152. package/src/utils/refactoring-tools.js +512 -0
  153. package/src/utils/report-generator.js +569 -0
  154. package/src/utils/reports/report-analysis.js +218 -0
  155. package/src/utils/reports/report-types.js +55 -0
  156. package/src/utils/reports/summary-generators.js +102 -0
  157. package/src/utils/requirement-file-management.js +157 -0
  158. package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
  159. package/src/utils/requirement-helpers/requirement-mover.js +414 -0
  160. package/src/utils/requirement-helpers/requirement-parser.js +326 -0
  161. package/src/utils/requirement-helpers/requirement-status.js +320 -0
  162. package/src/utils/requirement-helpers-new.js +55 -0
  163. package/src/utils/requirement-helpers-refactored.js +367 -0
  164. package/src/utils/requirement-helpers.js +291 -1191
  165. package/src/utils/requirement-movement-operations.js +450 -0
  166. package/src/utils/requirement-movement.js +312 -0
  167. package/src/utils/requirement-parsing-helpers.js +56 -0
  168. package/src/utils/requirement-statistics.js +200 -0
  169. package/src/utils/requirement-text-utils.js +58 -0
  170. package/src/utils/rollback/rollback-handlers.js +125 -0
  171. package/src/utils/rollback/rollback-operation.js +63 -0
  172. package/src/utils/rollback/rollback-recorder.js +166 -0
  173. package/src/utils/rollback/rollback-state-manager.js +175 -0
  174. package/src/utils/rollback/rollback-types.js +33 -0
  175. package/src/utils/rollback/rollback-utils.js +110 -0
  176. package/src/utils/rollback-manager-original.js +569 -0
  177. package/src/utils/rollback-manager.js +202 -0
  178. package/src/utils/smoke-test-cli.js +362 -0
  179. package/src/utils/smoke-test-gui.js +351 -0
  180. package/src/utils/smoke-test-orchestrator.js +321 -0
  181. package/src/utils/smoke-test-runner.js +60 -0
  182. package/src/utils/smoke-test-web.js +347 -0
  183. package/src/utils/specification-helpers.js +39 -13
  184. package/src/utils/specification-migration.js +97 -0
  185. package/src/utils/test-runner.js +579 -0
  186. package/src/utils/validation-framework.js +518 -0
  187. package/src/validation/compliance-analyzer.js +197 -0
  188. package/src/validation/compliance-report-generator.js +343 -0
  189. package/src/validation/compliance-reporter.js +711 -0
  190. package/src/validation/compliance-rules.js +127 -0
  191. package/src/validation/constitution-validator-new.js +196 -0
  192. package/src/validation/constitution-validator.js +17 -0
  193. package/src/validation/file-validators.js +170 -0
  194. package/src/validation/line-limit/file-analyzer.js +201 -0
  195. package/src/validation/line-limit/line-limit-validator.js +208 -0
  196. package/src/validation/line-limit/validation-result.js +144 -0
  197. package/src/validation/line-limit-core.js +225 -0
  198. package/src/validation/line-limit-reporter.js +134 -0
  199. package/src/validation/line-limit-result.js +125 -0
  200. package/src/validation/line-limit-validator.js +41 -0
  201. package/src/validation/metrics-calculator.js +660 -0
  202. package/src/sync/sync-engine-backup.js +0 -559
@@ -0,0 +1,741 @@
1
+ /**
2
+ * Boundary Detection Algorithms
3
+ */
4
+
5
+ const { BOUNDARY_TYPES, COHESION_LEVELS } = require('./boundary-types');
6
+
7
+ /**
8
+ * Boundary detector class
9
+ */
10
+ class BoundaryDetector {
11
+ constructor() {
12
+ this.patterns = this.initializePatterns();
13
+ }
14
+
15
+ /**
16
+ * Initialize detection patterns
17
+ * @returns {Object} Detection patterns
18
+ */
19
+ initializePatterns() {
20
+ return {
21
+ // Function patterns
22
+ function: {
23
+ declaration: /(?:function\s+(\w+)\s*\(|const\s+(\w+)\s*=\s*(?:async\s+)?(?:function|\([^)]*\)\s*=>)/g,
24
+ export: /(?:export\s+(?:default\s+)?(?:function|const|let|var)\s+(\w+))/g,
25
+ method: /(?:async\s+)?(\w+)\s*\([^)]*\)\s*{/g,
26
+ arrow: /(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?\([^)]*\)\s*=>/g
27
+ },
28
+
29
+ // Class patterns
30
+ class: {
31
+ declaration: /(?:class\s+(\w+)|export\s+(?:default\s+)?class\s+(\w+))/g,
32
+ method: /(?:async\s+)?(\w+)\s*\([^)]*\)\s*{/g,
33
+ property: /(\w+)\s*[=:]/g
34
+ },
35
+
36
+ // Object patterns
37
+ object: {
38
+ declaration: /(?:const|let|var)\s+(\w+)\s*=\s*{/g,
39
+ property: /(\w+)\s*:/g,
40
+ method: /(\w+)\s*\([^)]*\)\s*{/g
41
+ },
42
+
43
+ // Module patterns
44
+ module: {
45
+ export: /export\s+(?:\{([^}]+)\}|(?:default\s+)?(?:const|let|var|function|class)\s+(\w+))/g,
46
+ import: /import\s+(?:\{([^}]+)\}|(?:\*\s+as)?(\w+))/g
47
+ }
48
+ };
49
+ }
50
+
51
+ /**
52
+ * Detect boundaries in source code
53
+ * @param {string} sourceCode - Source code to analyze
54
+ * @param {string} filePath - File path
55
+ * @returns {Array} Array of detected boundaries
56
+ */
57
+ detectBoundaries(sourceCode, filePath) {
58
+ const lines = sourceCode.split('\n');
59
+ const boundaries = [];
60
+
61
+ // Detect function boundaries
62
+ boundaries.push(...this.detectFunctionBoundaries(lines, filePath));
63
+
64
+ // Detect class boundaries
65
+ boundaries.push(...this.detectClassBoundaries(lines, filePath));
66
+
67
+ // Detect object boundaries
68
+ boundaries.push(...this.detectObjectBoundaries(lines, filePath));
69
+
70
+ // Detect module boundaries
71
+ boundaries.push(...this.detectModuleBoundaries(lines, filePath));
72
+
73
+ // Detect utility boundaries
74
+ boundaries.push(...this.detectUtilityBoundaries(lines, filePath));
75
+
76
+ // Detect config boundaries
77
+ boundaries.push(...this.detectConfigBoundaries(lines, filePath));
78
+
79
+ // Detect constant boundaries
80
+ boundaries.push(...this.detectConstantBoundaries(lines, filePath));
81
+
82
+ return boundaries;
83
+ }
84
+
85
+ /**
86
+ * Detect function boundaries
87
+ * @param {Array} lines - Source code lines
88
+ * @param {string} filePath - File path
89
+ * @returns {Array} Array of function boundaries
90
+ */
91
+ detectFunctionBoundaries(lines, filePath) {
92
+ const boundaries = [];
93
+ const sourceCode = lines.join('\n');
94
+
95
+ // Find function declarations
96
+ const matches = [...sourceCode.matchAll(this.patterns.function.declaration)];
97
+
98
+ for (const match of matches) {
99
+ const functionName = match[1] || match[2];
100
+ if (functionName) {
101
+ const boundary = this.createBoundary(
102
+ BOUNDARY_TYPES.FUNCTION,
103
+ functionName,
104
+ lines,
105
+ filePath,
106
+ match.index
107
+ );
108
+
109
+ if (boundary) {
110
+ boundaries.push(boundary);
111
+ }
112
+ }
113
+ }
114
+
115
+ return boundaries;
116
+ }
117
+
118
+ /**
119
+ * Detect class boundaries
120
+ * @param {Array} lines - Source code lines
121
+ * @param {string} filePath - File path
122
+ * @returns {Array} Array of class boundaries
123
+ */
124
+ detectClassBoundaries(lines, filePath) {
125
+ const boundaries = [];
126
+ const sourceCode = lines.join('\n');
127
+
128
+ // Find class declarations
129
+ const matches = [...sourceCode.matchAll(this.patterns.class.declaration)];
130
+
131
+ for (const match of matches) {
132
+ const className = match[1] || match[2];
133
+ if (className) {
134
+ const boundary = this.createBoundary(
135
+ BOUNDARY_TYPES.CLASS,
136
+ className,
137
+ lines,
138
+ filePath,
139
+ match.index
140
+ );
141
+
142
+ if (boundary) {
143
+ boundaries.push(boundary);
144
+ }
145
+ }
146
+ }
147
+
148
+ return boundaries;
149
+ }
150
+
151
+ /**
152
+ * Detect object boundaries
153
+ * @param {Array} lines - Source code lines
154
+ * @param {string} filePath - File path
155
+ * @returns {Array} Array of object boundaries
156
+ */
157
+ detectObjectBoundaries(lines, filePath) {
158
+ const boundaries = [];
159
+ const sourceCode = lines.join('\n');
160
+
161
+ // Find object declarations
162
+ const matches = [...sourceCode.matchAll(this.patterns.object.declaration)];
163
+
164
+ for (const match of matches) {
165
+ const objectName = match[1];
166
+ if (objectName) {
167
+ const boundary = this.createBoundary(
168
+ BOUNDARY_TYPES.OBJECT,
169
+ objectName,
170
+ lines,
171
+ filePath,
172
+ match.index
173
+ );
174
+
175
+ if (boundary) {
176
+ boundaries.push(boundary);
177
+ }
178
+ }
179
+ }
180
+
181
+ return boundaries;
182
+ }
183
+
184
+ /**
185
+ * Detect module boundaries
186
+ * @param {Array} lines - Source code lines
187
+ * @param {string} filePath - File path
188
+ * @returns {Array} Array of module boundaries
189
+ */
190
+ detectModuleBoundaries(lines, filePath) {
191
+ const boundaries = [];
192
+ const sourceCode = lines.join('\n');
193
+
194
+ // Find export statements
195
+ const matches = [...sourceCode.matchAll(this.patterns.module.export)];
196
+
197
+ for (const match of matches) {
198
+ const exportNames = match[1] ? match[1].split(',').map(s => s.trim()) : [match[2]];
199
+
200
+ for (const exportName of exportNames) {
201
+ if (exportName && exportName !== 'default') {
202
+ const boundary = this.createBoundary(
203
+ BOUNDARY_TYPES.MODULE,
204
+ exportName,
205
+ lines,
206
+ filePath,
207
+ match.index
208
+ );
209
+
210
+ if (boundary) {
211
+ boundaries.push(boundary);
212
+ }
213
+ }
214
+ }
215
+ }
216
+
217
+ return boundaries;
218
+ }
219
+
220
+ /**
221
+ * Detect utility boundaries
222
+ * @param {Array} lines - Source code lines
223
+ * @param {string} filePath - File path
224
+ * @returns {Array} Array of utility boundaries
225
+ */
226
+ detectUtilityBoundaries(lines, filePath) {
227
+ const boundaries = [];
228
+
229
+ // Look for utility function patterns
230
+ for (let i = 0; i < lines.length; i++) {
231
+ const line = lines[i].trim();
232
+
233
+ // Helper function patterns
234
+ if (this.isUtilityFunction(line)) {
235
+ const functionName = this.extractUtilityFunctionName(line);
236
+ if (functionName) {
237
+ const boundary = this.createBoundary(
238
+ BOUNDARY_TYPES.UTILITY,
239
+ functionName,
240
+ lines,
241
+ filePath,
242
+ i
243
+ );
244
+
245
+ if (boundary) {
246
+ boundaries.push(boundary);
247
+ }
248
+ }
249
+ }
250
+ }
251
+
252
+ return boundaries;
253
+ }
254
+
255
+ /**
256
+ * Detect config boundaries
257
+ * @param {Array} lines - Source code lines
258
+ * @param {string} filePath - File path
259
+ * @returns {Array} Array of config boundaries
260
+ */
261
+ detectConfigBoundaries(lines, filePath) {
262
+ const boundaries = [];
263
+
264
+ // Look for config object patterns
265
+ for (let i = 0; i < lines.length; i++) {
266
+ const line = lines[i].trim();
267
+
268
+ // Config object patterns
269
+ if (this.isConfigObject(line)) {
270
+ const configName = this.extractConfigObjectName(line);
271
+ if (configName) {
272
+ const boundary = this.createBoundary(
273
+ BOUNDARY_TYPES.CONFIG,
274
+ configName,
275
+ lines,
276
+ filePath,
277
+ i
278
+ );
279
+
280
+ if (boundary) {
281
+ boundaries.push(boundary);
282
+ }
283
+ }
284
+ }
285
+ }
286
+
287
+ return boundaries;
288
+ }
289
+
290
+ /**
291
+ * Detect constant boundaries
292
+ * @param {Array} lines - Source code lines
293
+ * @param {string} filePath - File path
294
+ * @returns {Array} Array of constant boundaries
295
+ */
296
+ detectConstantBoundaries(lines, filePath) {
297
+ const boundaries = [];
298
+
299
+ // Look for constant patterns
300
+ for (let i = 0; i < lines.length; i++) {
301
+ const line = lines[i].trim();
302
+
303
+ // Constant patterns
304
+ if (this.isConstantDeclaration(line)) {
305
+ const constantName = this.extractConstantName(line);
306
+ if (constantName) {
307
+ const boundary = this.createBoundary(
308
+ BOUNDARY_TYPES.CONSTANT,
309
+ constantName,
310
+ lines,
311
+ filePath,
312
+ i
313
+ );
314
+
315
+ if (boundary) {
316
+ boundaries.push(boundary);
317
+ }
318
+ }
319
+ }
320
+ }
321
+
322
+ return boundaries;
323
+ }
324
+
325
+ /**
326
+ * Create boundary from detection
327
+ * @param {string} type - Boundary type
328
+ * @param {string} name - Boundary name
329
+ * @param {Array} lines - Source code lines
330
+ * @param {string} filePath - File path
331
+ * @param {number} startIndex - Start index in source
332
+ * @returns {Object|null} Boundary object or null
333
+ */
334
+ createBoundary(type, name, lines, filePath, startIndex) {
335
+ const { startLine, endLine } = this.findBoundaryExtent(lines, startIndex, type);
336
+
337
+ if (startLine === -1 || endLine === -1) {
338
+ return null;
339
+ }
340
+
341
+ const { ModuleBoundary } = require('./boundary-types');
342
+ const boundary = new ModuleBoundary(type, name, startLine + 1, endLine + 1, filePath);
343
+
344
+ // Analyze boundary properties
345
+ this.analyzeBoundary(boundary, lines, startLine, endLine);
346
+
347
+ return boundary;
348
+ }
349
+
350
+ /**
351
+ * Find the extent of a boundary
352
+ * @param {Array} lines - Source code lines
353
+ * @param {number} startIndex - Start index
354
+ * @param {string} type - Boundary type
355
+ * @returns {Object} Start and end line numbers
356
+ */
357
+ findBoundaryExtent(lines, startIndex, type) {
358
+ let startLine = -1;
359
+ let endLine = -1;
360
+ let braceCount = 0;
361
+ let inString = false;
362
+ let stringChar = null;
363
+
364
+ for (let i = startIndex; i < lines.length; i++) {
365
+ const line = lines[i];
366
+
367
+ // Track string literals
368
+ for (let j = 0; j < line.length; j++) {
369
+ const char = line[j];
370
+
371
+ if (!inString && (char === '"' || char === "'" || char === '`')) {
372
+ inString = true;
373
+ stringChar = char;
374
+ } else if (inString && char === stringChar) {
375
+ inString = false;
376
+ stringChar = null;
377
+ }
378
+ }
379
+
380
+ // Skip lines inside strings
381
+ if (inString) continue;
382
+
383
+ // Count braces for block detection
384
+ const openBraces = (line.match(/\{/g) || []).length;
385
+ const closeBraces = (line.match(/\}/g) || []).length;
386
+
387
+ braceCount += openBraces - closeBraces;
388
+
389
+ // Set start line on first detection
390
+ if (startLine === -1) {
391
+ startLine = i;
392
+ }
393
+
394
+ // End when braces are balanced and we're past the start
395
+ if (braceCount <= 0 && i > startIndex) {
396
+ endLine = i;
397
+ break;
398
+ }
399
+ }
400
+
401
+ return { startLine, endLine };
402
+ }
403
+
404
+ /**
405
+ * Analyze boundary properties
406
+ * @param {Object} boundary - Boundary object
407
+ * @param {Array} lines - Source code lines
408
+ * @param {number} startLine - Start line number
409
+ * @param {number} endLine - End line number
410
+ */
411
+ analyzeBoundary(boundary, lines, startLine, endLine) {
412
+ const boundaryLines = lines.slice(startLine, endLine + 1);
413
+ const sourceCode = boundaryLines.join('\n');
414
+
415
+ // Calculate complexity
416
+ const complexity = this.calculateComplexity(sourceCode);
417
+ boundary.setComplexity(complexity);
418
+
419
+ // Find dependencies
420
+ const dependencies = this.findDependencies(sourceCode);
421
+ for (const dep of dependencies) {
422
+ boundary.addDependency(dep);
423
+ }
424
+
425
+ // Find exports
426
+ const exports = this.findExports(sourceCode, boundary.type);
427
+ for (const exp of exports) {
428
+ boundary.addExport(exp);
429
+ }
430
+
431
+ // Calculate cohesion
432
+ const cohesion = this.calculateCohesion(boundary, boundaryLines);
433
+ boundary.setCohesion(cohesion);
434
+
435
+ // Determine extractability
436
+ const extractable = this.isExtractable(boundary, boundaryLines);
437
+ boundary.setExtractable(extractable);
438
+
439
+ // Set confidence based on analysis
440
+ const confidence = this.calculateConfidence(boundary);
441
+ boundary.setConfidence(confidence);
442
+ }
443
+
444
+ /**
445
+ * Calculate complexity score
446
+ * @param {string} sourceCode - Source code
447
+ * @returns {number} Complexity score
448
+ */
449
+ calculateComplexity(sourceCode) {
450
+ let complexity = 0;
451
+
452
+ // Cyclomatic complexity indicators
453
+ complexity += (sourceCode.match(/if\s*\(/g) || []).length * 1;
454
+ complexity += (sourceCode.match(/else\s+if/g) || []).length * 1;
455
+ complexity += (sourceCode.match(/while\s*\(/g) || []).length * 2;
456
+ complexity += (sourceCode.match(/for\s*\(/g) || []).length * 2;
457
+ complexity += (sourceCode.match(/switch\s*\(/g) || []).length * 2;
458
+ complexity += (sourceCode.match(/catch\s*\(/g) || []).length * 2;
459
+ complexity += (sourceCode.match(/&&/g) || []).length * 1;
460
+ complexity += (sourceCode.match(/\|\|/g) || []).length * 1;
461
+
462
+ // Nesting complexity
463
+ const maxNesting = this.calculateMaxNesting(sourceCode);
464
+ complexity += maxNesting * 2;
465
+
466
+ // Length complexity
467
+ const lineCount = sourceCode.split('\n').length;
468
+ if (lineCount > 50) complexity += 5;
469
+ if (lineCount > 100) complexity += 10;
470
+ if (lineCount > 200) complexity += 20;
471
+
472
+ return Math.min(100, complexity);
473
+ }
474
+
475
+ /**
476
+ * Calculate maximum nesting level
477
+ * @param {string} sourceCode - Source code
478
+ * @returns {number} Maximum nesting level
479
+ */
480
+ calculateMaxNesting(sourceCode) {
481
+ let maxNesting = 0;
482
+ let currentNesting = 0;
483
+ let inString = false;
484
+ let stringChar = null;
485
+
486
+ for (const char of sourceCode) {
487
+ if (!inString && (char === '"' || char === "'" || char === '`')) {
488
+ inString = true;
489
+ stringChar = char;
490
+ } else if (inString && char === stringChar) {
491
+ inString = false;
492
+ stringChar = null;
493
+ } else if (!inString) {
494
+ if (char === '{') {
495
+ currentNesting++;
496
+ maxNesting = Math.max(maxNesting, currentNesting);
497
+ } else if (char === '}') {
498
+ currentNesting--;
499
+ }
500
+ }
501
+ }
502
+
503
+ return maxNesting;
504
+ }
505
+
506
+ /**
507
+ * Find dependencies in boundary
508
+ * @param {string} sourceCode - Source code
509
+ * @returns {Array} Array of dependencies
510
+ */
511
+ findDependencies(sourceCode) {
512
+ const dependencies = [];
513
+
514
+ // Import statements
515
+ const importMatches = sourceCode.match(/import\s+.+from\s+['"]([^'"]+)['"]/g);
516
+ if (importMatches) {
517
+ for (const match of importMatches) {
518
+ dependencies.push(match[1]);
519
+ }
520
+ }
521
+
522
+ // Require statements
523
+ const requireMatches = sourceCode.match(/require\s*\(\s*['"]([^'"]+)['"]\s*\)/g);
524
+ if (requireMatches) {
525
+ for (const match of requireMatches) {
526
+ dependencies.push(match[1]);
527
+ }
528
+ }
529
+
530
+ return [...new Set(dependencies)];
531
+ }
532
+
533
+ /**
534
+ * Find exports in boundary
535
+ * @param {string} sourceCode - Source code
536
+ * @param {string} type - Boundary type
537
+ * @returns {Array} Array of exports
538
+ */
539
+ findExports(sourceCode, type) {
540
+ const exports = [];
541
+
542
+ if (type === BOUNDARY_TYPES.FUNCTION || type === BOUNDARY_TYPES.CLASS) {
543
+ // Look for explicit exports
544
+ const exportMatches = sourceCode.match(/export\s+(?:default\s+)?(?:\w+|\{[^}]+\})/g);
545
+ if (exportMatches) {
546
+ for (const match of exportMatches) {
547
+ const exportName = match.replace(/export\s+(?:default\s+)?/, '').trim();
548
+ if (exportName && exportName !== '{' && exportName !== '}') {
549
+ exports.push(exportName);
550
+ }
551
+ }
552
+ }
553
+ }
554
+
555
+ return exports;
556
+ }
557
+
558
+ /**
559
+ * Calculate cohesion level
560
+ * @param {Object} boundary - Boundary object
561
+ * @param {Array} lines - Boundary lines
562
+ * @returns {string} Cohesion level
563
+ */
564
+ calculateCohesion(boundary, lines) {
565
+ let cohesionScore = 0;
566
+
567
+ // Single responsibility (high cohesion)
568
+ if (boundary.type === BOUNDARY_TYPES.FUNCTION || boundary.type === BOUNDARY_TYPES.CLASS) {
569
+ cohesionScore += 40;
570
+ }
571
+
572
+ // Limited dependencies (medium cohesion)
573
+ if (boundary.dependencies.length <= 3) {
574
+ cohesionScore += 30;
575
+ } else if (boundary.dependencies.length <= 5) {
576
+ cohesionScore += 20;
577
+ } else {
578
+ cohesionScore += 10;
579
+ }
580
+
581
+ // Clear purpose (high cohesion)
582
+ if (this.hasClearPurpose(boundary, lines)) {
583
+ cohesionScore += 30;
584
+ }
585
+
586
+ // Convert to cohesion level
587
+ if (cohesionScore >= 80) return COHESION_LEVELS.HIGH;
588
+ if (cohesionScore >= 60) return COHESION_LEVELS.MEDIUM;
589
+ if (cohesionScore >= 40) return COHESION_LEVELS.LOW;
590
+ return COHESION_LEVELS.NONE;
591
+ }
592
+
593
+ /**
594
+ * Check if boundary has clear purpose
595
+ * @param {Object} boundary - Boundary object
596
+ * @param {Array} lines - Boundary lines
597
+ * @returns {boolean} Whether boundary has clear purpose
598
+ */
599
+ hasClearPurpose(boundary, lines) {
600
+ const sourceCode = lines.join('\n');
601
+
602
+ // Check for comments explaining purpose
603
+ const hasComments = /\/\*\*[\s\S]*?\*\/|\/\/.*/.test(sourceCode);
604
+
605
+ // Check for meaningful name
606
+ const hasMeaningfulName = boundary.name &&
607
+ boundary.name.length > 2 &&
608
+ !/^(temp|tmp|test|dummy|helper|util)/.test(boundary.name.toLowerCase());
609
+
610
+ // Check for implementation
611
+ const hasImplementation = sourceCode.includes('{') && sourceCode.includes('}');
612
+
613
+ return hasComments || hasMeaningfulName || hasImplementation;
614
+ }
615
+
616
+ /**
617
+ * Determine if boundary is extractable
618
+ * @param {Object} boundary - Boundary object
619
+ * @param {Array} lines - Boundary lines
620
+ * @returns {boolean} Whether boundary is extractable
621
+ */
622
+ isExtractable(boundary, lines) {
623
+ // Must have clear boundaries
624
+ if (boundary.lineCount < 5) return false;
625
+
626
+ // Must have reasonable cohesion
627
+ if (boundary.cohesion === COHESION_LEVELS.NONE) return false;
628
+
629
+ // Must not be too complex
630
+ if (boundary.complexity > 70) return false;
631
+
632
+ // Must have reasonable dependencies
633
+ if (boundary.dependencies.length > 10) return false;
634
+
635
+ return true;
636
+ }
637
+
638
+ /**
639
+ * Calculate confidence score
640
+ * @param {Object} boundary - Boundary object
641
+ * @returns {number} Confidence score (0-1)
642
+ */
643
+ calculateConfidence(boundary) {
644
+ let confidence = 0.5; // Base confidence
645
+
646
+ // Increase confidence for clear boundaries
647
+ if (boundary.lineCount >= 10 && boundary.lineCount <= 200) {
648
+ confidence += 0.2;
649
+ }
650
+
651
+ // Increase confidence for high cohesion
652
+ if (boundary.cohesion === COHESION_LEVELS.HIGH) {
653
+ confidence += 0.2;
654
+ } else if (boundary.cohesion === COHESION_LEVELS.MEDIUM) {
655
+ confidence += 0.1;
656
+ }
657
+
658
+ // Increase confidence for extractable boundaries
659
+ if (boundary.isExtractable()) {
660
+ confidence += 0.1;
661
+ }
662
+
663
+ return Math.min(1.0, confidence);
664
+ }
665
+
666
+ /**
667
+ * Check if line is a utility function
668
+ * @param {string} line - Code line
669
+ * @returns {boolean} Whether line is utility function
670
+ */
671
+ isUtilityFunction(line) {
672
+ const utilityPatterns = [
673
+ /(?:const|let|var)\s+\w+\s*=\s*\([^)]*\)\s*=>/,
674
+ /function\s+(?:is|has|get|set|calculate|compute|parse|format|validate|check)/,
675
+ /(?:is|has|get|set|calculate|compute|parse|format|validate|check)\w+\s*\(/
676
+ ];
677
+
678
+ return utilityPatterns.some(pattern => pattern.test(line));
679
+ }
680
+
681
+ /**
682
+ * Extract utility function name
683
+ * @param {string} line - Code line
684
+ * @returns {string|null} Function name
685
+ */
686
+ extractUtilityFunctionName(line) {
687
+ const match = line.match(/(?:const|let|var)\s+(\w+)\s*=|function\s+(\w+)/);
688
+ return match ? match[1] || match[2] : null;
689
+ }
690
+
691
+ /**
692
+ * Check if line is config object
693
+ * @param {string} line - Code line
694
+ * @returns {boolean} Whether line is config object
695
+ */
696
+ isConfigObject(line) {
697
+ const configPatterns = [
698
+ /(?:const|let|var)\s+\w*config\w*\s*=/,
699
+ /(?:const|let|var)\s+\w*Config\w*\s*=/,
700
+ /(?:const|let|var)\s+\w*Settings\w*\s*=/
701
+ ];
702
+
703
+ return configPatterns.some(pattern => pattern.test(line));
704
+ }
705
+
706
+ /**
707
+ * Extract config object name
708
+ * @param {string} line - Code line
709
+ * @returns {string|null} Config name
710
+ */
711
+ extractConfigObjectName(line) {
712
+ const match = line.match(/(?:const|let|var)\s+(\w*config\w*|\w*Config\w*|\w*Settings\w*)\s*=/);
713
+ return match ? match[1] : null;
714
+ }
715
+
716
+ /**
717
+ * Check if line is constant declaration
718
+ * @param {string} line - Code line
719
+ * @returns {boolean} Whether line is constant declaration
720
+ */
721
+ isConstantDeclaration(line) {
722
+ const constantPatterns = [
723
+ /const\s+[A-Z_][A-Z0-9_]*\s*=/,
724
+ /(?:const|let|var)\s+[A-Z_][A-Z0-9_]*\s*=/
725
+ ];
726
+
727
+ return constantPatterns.some(pattern => pattern.test(line));
728
+ }
729
+
730
+ /**
731
+ * Extract constant name
732
+ * @param {string} line - Code line
733
+ * @returns {string|null} Constant name
734
+ */
735
+ extractConstantName(line) {
736
+ const match = line.match(/(?:const|let|var)\s+([A-Z_][A-Z0-9_]*)\s*=/);
737
+ return match ? match[1] : null;
738
+ }
739
+ }
740
+
741
+ module.exports = BoundaryDetector;