vibecodingmachine-core 2026.2.26-1739 → 2026.3.9-850

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 (192) hide show
  1. package/package.json +1 -1
  2. package/src/agents/AgentCheckDiscoveryService.js +180 -0
  3. package/src/agents/AgentCheckService.js +18 -261
  4. package/src/agents/AgentCheckStatisticsService.js +195 -0
  5. package/src/agents/EnvironmentConfigurationManager.js +31 -380
  6. package/src/agents/InstallationType.js +19 -6
  7. package/src/agents/SimpleAgentCheckService.js +472 -0
  8. package/src/agents/config-managers/ConfigUtils.js +72 -0
  9. package/src/agents/config-managers/DefaultConfig.js +58 -0
  10. package/src/agents/config-managers/EnvVarLoader.js +66 -0
  11. package/src/agents/config-managers/FileConfigLoader.js +124 -0
  12. package/src/agents/config-managers/TypeConverters.js +61 -0
  13. package/src/agents/config-managers/VariableMappings.js +92 -0
  14. package/src/agents/discovery/AgentDiscoveryService-refactored.js +272 -0
  15. package/src/agents/discovery/AgentDiscoveryService.js +29 -403
  16. package/src/agents/discovery/agent-validator.js +262 -0
  17. package/src/agents/discovery/discovery-results.js +176 -0
  18. package/src/agents/discovery/discovery-scanner.js +268 -0
  19. package/src/agents/discovery/discovery-utils.js +161 -0
  20. package/src/agents/discovery/executable-analyzer.js +290 -0
  21. package/src/agents/discovery/history-manager.js +310 -0
  22. package/src/agents/verification/ResultAnalyzer-refactored.js +341 -0
  23. package/src/agents/verification/ResultAnalyzer.js +30 -431
  24. package/src/agents/verification/analysis-utils.js +310 -0
  25. package/src/agents/verification/batch-analyzer.js +440 -0
  26. package/src/agents/verification/pattern-recognizer.js +369 -0
  27. package/src/agents/verification/report-generator.js +320 -0
  28. package/src/agents/verification/test-analyzer.js +290 -0
  29. package/src/agents/windows/InstallerFactory.js +4 -0
  30. package/src/agents/windows/VSCodeExtensionInstaller.js +404 -0
  31. package/src/analysis/analysis-engine.js +314 -0
  32. package/src/analysis/ast-analyzer.js +342 -0
  33. package/src/analysis/boundary-detector-refactored.js +378 -0
  34. package/src/analysis/boundary-detector.js +200 -603
  35. package/src/analysis/boundary-scanner.js +609 -0
  36. package/src/analysis/boundary-types.js +118 -0
  37. package/src/analysis/boundary-utils.js +293 -0
  38. package/src/analysis/deadline-priority-calculator.js +18 -0
  39. package/src/analysis/detection-methods.js +347 -0
  40. package/src/analysis/importance-priority-calculator.js +18 -0
  41. package/src/analysis/priority/factor-calculators.js +204 -0
  42. package/src/analysis/priority/factor-helpers.js +71 -0
  43. package/src/analysis/priority/priority-constants.js +73 -0
  44. package/src/analysis/priority/priority-factor-calculators.js +301 -0
  45. package/src/analysis/priority/reasons-generator.js +44 -0
  46. package/src/analysis/priority-calculator.js +15 -580
  47. package/src/analysis/strategy-generator.js +16 -66
  48. package/src/analysis/type-priority-calculator.js +18 -0
  49. package/src/analysis/urgency-priority-calculator.js +18 -0
  50. package/src/auto-mode/AutoModeBusinessLogic.js +2 -40
  51. package/src/commands/disable-requirement.js +60 -0
  52. package/src/commands/disable-spec.js +60 -0
  53. package/src/commands/enable-requirement.js +60 -0
  54. package/src/commands/enable-spec.js +60 -0
  55. package/src/commands/registry.js +1 -6
  56. package/src/commands/requirements.js +8 -2
  57. package/src/ide-integration/applescript-manager.cjs +9 -24
  58. package/src/ide-integration/cdp-handlers/chat-reader.js +44 -0
  59. package/src/ide-integration/cdp-handlers/connection-handler.js +88 -0
  60. package/src/ide-integration/cdp-handlers/continuation-handler.js +314 -0
  61. package/src/ide-integration/cdp-handlers/message-submitter.js +75 -0
  62. package/src/ide-integration/cdp-handlers/text-sender.js +138 -0
  63. package/src/ide-integration/cdp-manager.js +28 -573
  64. package/src/ide-integration/claude-code-cli-manager.cjs +48 -12
  65. package/src/ide-integration/ide-openers/claude-opener.js +171 -0
  66. package/src/ide-integration/ide-openers/cursor-opener.js +53 -0
  67. package/src/ide-integration/ide-openers/other-ides-opener.js +230 -0
  68. package/src/ide-integration/ide-openers/vscode-opener.js +147 -0
  69. package/src/ide-integration/macos-ide-manager.js +20 -582
  70. package/src/ide-integration/macos-quota-checker.js +164 -0
  71. package/src/ide-integration/macos-text-sender.js +19 -38
  72. package/src/ide-integration/provider-manager.cjs +52 -7
  73. package/src/index.cjs +6 -0
  74. package/src/index.js +10 -0
  75. package/src/llm/direct-llm-manager.cjs +501 -0
  76. package/src/localization/translations/en-part1.js +363 -0
  77. package/src/localization/translations/en-part2.js +320 -0
  78. package/src/localization/translations/en.js +4 -687
  79. package/src/localization/translations/es-part1.js +363 -0
  80. package/src/localization/translations/es-part2.js +320 -0
  81. package/src/localization/translations/es.js +4 -688
  82. package/src/models/file-analysis-collection.js +139 -0
  83. package/src/models/file-analysis-metrics.js +50 -0
  84. package/src/models/file-analysis.js +15 -262
  85. package/src/models/plan-manager.js +410 -0
  86. package/src/models/refactoring-models.js +380 -0
  87. package/src/models/refactoring-plan-refactored.js +81 -0
  88. package/src/models/refactoring-plan.js +2 -663
  89. package/src/monitoring/alert-system.js +4 -45
  90. package/src/monitoring/continuous-scan-notifications.js +37 -191
  91. package/src/monitoring/notification-handlers/base-handler.js +58 -0
  92. package/src/monitoring/notification-handlers/error-handler.js +36 -0
  93. package/src/monitoring/notification-handlers/index.js +21 -0
  94. package/src/monitoring/notification-handlers/new-violation-handler.js +91 -0
  95. package/src/monitoring/notification-handlers/progress-handler.js +48 -0
  96. package/src/monitoring/notification-handlers/resolved-violation-handler.js +54 -0
  97. package/src/monitoring/notification-handlers/threshold-handler.js +36 -0
  98. package/src/provider-registry.js +8 -0
  99. package/src/refactoring/boundary/boundary-detector-refactored.js +58 -0
  100. package/src/refactoring/boundary/boundary-detector.js +26 -596
  101. package/src/refactoring/boundary/detectors/boundary-analyzers.js +281 -0
  102. package/src/refactoring/boundary/detectors/boundary-core.js +167 -0
  103. package/src/refactoring/boundary/detectors/class-detector.js +247 -0
  104. package/src/refactoring/boundary/detectors/config-detector.js +270 -0
  105. package/src/refactoring/boundary/detectors/constant-detector.js +269 -0
  106. package/src/refactoring/boundary/detectors/function-detector.js +248 -0
  107. package/src/refactoring/boundary/detectors/module-detector.js +249 -0
  108. package/src/refactoring/boundary/detectors/object-detector.js +247 -0
  109. package/src/refactoring/boundary/detectors/type-detectors.js +338 -0
  110. package/src/refactoring/boundary/detectors/utility-detector.js +270 -0
  111. package/src/refactoring/circular-dependency-resolver-original.js +16 -76
  112. package/src/refactoring/code-mover-refactored.js +309 -0
  113. package/src/refactoring/code-mover.js +48 -355
  114. package/src/refactoring/execution-status.js +18 -0
  115. package/src/refactoring/execution-strategies.js +172 -0
  116. package/src/refactoring/file-splitter-core.js +568 -0
  117. package/src/refactoring/file-splitter-types.js +136 -0
  118. package/src/refactoring/file-splitter.js +2 -682
  119. package/src/refactoring/functionality-validator.js +11 -51
  120. package/src/refactoring/import-manager-refactored.js +385 -0
  121. package/src/refactoring/import-manager.js +112 -487
  122. package/src/refactoring/import-models.js +189 -0
  123. package/src/refactoring/import-parser.js +306 -0
  124. package/src/refactoring/move-executor.js +431 -0
  125. package/src/refactoring/move-utils.js +368 -0
  126. package/src/refactoring/operation-executor.js +76 -0
  127. package/src/refactoring/plan-creator.js +36 -0
  128. package/src/refactoring/plan-executor.js +143 -0
  129. package/src/refactoring/plan-validator.js +68 -0
  130. package/src/refactoring/refactoring-executor-result.js +70 -0
  131. package/src/refactoring/refactoring-executor.js +34 -569
  132. package/src/refactoring/refactoring-operation.js +94 -0
  133. package/src/refactoring/refactoring-plan.js +69 -0
  134. package/src/refactoring/refactoring-rollback.js +22 -527
  135. package/src/refactoring/rollback-handlers/RollbackExecutor.js +107 -0
  136. package/src/refactoring/rollback-handlers/RollbackManager.js +265 -0
  137. package/src/refactoring/rollback-handlers/RollbackOperation.js +105 -0
  138. package/src/refactoring/rollback-handlers/RollbackResult.js +109 -0
  139. package/src/refactoring/rollback-handlers/RollbackStatistics.js +77 -0
  140. package/src/refactoring/test-validator.js +32 -448
  141. package/src/refactoring/validation/baseline-runner.js +71 -0
  142. package/src/refactoring/validation/report-generator.js +136 -0
  143. package/src/refactoring/validation/result-comparator.js +92 -0
  144. package/src/refactoring/validation/test-suite.js +59 -0
  145. package/src/refactoring/validation/test-validation-result.js +83 -0
  146. package/src/refactoring/validation/validation-runner.js +95 -0
  147. package/src/refactoring/validation/validation-status.js +18 -0
  148. package/src/rui/commands/AgentCommandParser.js +60 -369
  149. package/src/rui/commands/AgentResponseFormatter.js +7 -47
  150. package/src/rui/commands/parsers/CommandMapper.js +148 -0
  151. package/src/rui/commands/parsers/CommandValidator.js +228 -0
  152. package/src/rui/commands/parsers/ComponentExtractor.js +100 -0
  153. package/src/rui/commands/parsers/TokenParser.js +69 -0
  154. package/src/rui/commands/parsers/tokenizer.js +153 -0
  155. package/src/utils/current-requirement-operations.js +50 -1
  156. package/src/utils/report-generator.js +18 -514
  157. package/src/utils/report-generators/analysis-generator.js +115 -0
  158. package/src/utils/report-generators/base-generator.js +141 -0
  159. package/src/utils/report-generators/compliance-generator.js +41 -0
  160. package/src/utils/report-generators/format-handlers.js +185 -0
  161. package/src/utils/report-generators/refactoring-generator.js +46 -0
  162. package/src/utils/report-generators/validation-generator.js +63 -0
  163. package/src/utils/requirement-enable-disable.js +265 -0
  164. package/src/utils/requirement-helpers/requirement-file-ops.js +69 -1
  165. package/src/utils/requirement-helpers/requirement-mover.js +88 -1
  166. package/src/utils/requirement-helpers.js +5 -2
  167. package/src/utils/smoke-test-cli.js +45 -8
  168. package/src/utils/specification-enable-disable.js +122 -0
  169. package/src/utils/specification-helpers.js +30 -4
  170. package/src/utils/specification-migration.js +5 -5
  171. package/src/utils/test-comparator.js +118 -0
  172. package/src/utils/test-config.js +54 -0
  173. package/src/utils/test-executor.js +133 -0
  174. package/src/utils/test-parser.js +215 -0
  175. package/src/utils/test-runner-baseline.js +63 -0
  176. package/src/utils/test-runner-core.js +98 -0
  177. package/src/utils/test-runner-report.js +39 -0
  178. package/src/utils/test-runner-validation.js +71 -0
  179. package/src/utils/test-runner.js +11 -535
  180. package/src/validation/comparison-analyzer.js +333 -0
  181. package/src/validation/compliance-reporter-new.js +282 -0
  182. package/src/validation/compliance-reporter-refactored.js +344 -0
  183. package/src/validation/compliance-reporter.js +278 -591
  184. package/src/validation/compliance-utils.js +278 -0
  185. package/src/validation/html-generator.js +446 -0
  186. package/src/validation/metrics/category-calculator.js +137 -0
  187. package/src/validation/metrics/metrics-helpers.js +155 -0
  188. package/src/validation/metrics/overview-calculator.js +85 -0
  189. package/src/validation/metrics/overview-metrics.js +41 -0
  190. package/src/validation/metrics/quality-calculator.js +166 -0
  191. package/src/validation/metrics/size-calculator.js +69 -0
  192. package/src/validation/metrics-calculator.js +27 -551
@@ -0,0 +1,609 @@
1
+ /**
2
+ * Boundary Scanner
3
+ *
4
+ * Scans source code to detect logical boundaries.
5
+ */
6
+
7
+ const { BOUNDARY_TYPES, createBoundary, validateBoundary } = require('./boundary-utils');
8
+
9
+ /**
10
+ * Boundary Scanner class
11
+ */
12
+ class BoundaryScanner {
13
+ constructor(options = {}) {
14
+ this.options = {
15
+ includeComments: options.includeComments !== false,
16
+ includeImports: options.includeImports !== false,
17
+ includeExports: options.includeExports !== false,
18
+ minBoundarySize: options.minBoundarySize || 5,
19
+ ...options
20
+ };
21
+ }
22
+
23
+ /**
24
+ * Scan file for boundaries
25
+ * @param {string} content - File content
26
+ * @param {string} filePath - File path
27
+ * @returns {Object} - Scan result
28
+ */
29
+ scanFile(content, filePath) {
30
+ const lines = content.split('\n');
31
+ const boundaries = [];
32
+
33
+ // Scan for different boundary types
34
+ boundaries.push(...this.scanFunctions(lines));
35
+ boundaries.push(...this.scanClasses(lines));
36
+ boundaries.push(...this.scanModules(lines));
37
+ boundaries.push(...this.scanBlocks(lines));
38
+
39
+ if (this.options.includeComments) {
40
+ boundaries.push(...this.scanComments(lines));
41
+ }
42
+
43
+ if (this.options.includeImports) {
44
+ boundaries.push(...this.scanImports(lines));
45
+ }
46
+
47
+ if (this.options.includeExports) {
48
+ boundaries.push(...this.scanExports(lines));
49
+ }
50
+
51
+ // Filter and validate boundaries
52
+ const validBoundaries = boundaries
53
+ .filter(b => b.size >= this.options.minBoundarySize)
54
+ .map(b => {
55
+ b.complexity = this.calculateBoundaryComplexity(b, lines);
56
+ return b;
57
+ })
58
+ .filter(b => validateBoundary(b).isValid);
59
+
60
+ return {
61
+ filePath,
62
+ boundaries: validBoundaries,
63
+ metadata: this.generateScanMetadata(validBoundaries, lines)
64
+ };
65
+ }
66
+
67
+ /**
68
+ * Scan for functions
69
+ * @param {Array} lines - File lines
70
+ * @returns {Array} - Function boundaries
71
+ */
72
+ scanFunctions(lines) {
73
+ const functions = [];
74
+ const functionPatterns = [
75
+ /^(\s*)function\s+(\w+)\s*\(/,
76
+ /^(\s*)(async\s+)?function\s+(\w+)\s*\(/,
77
+ /^(\s*)(\w+)\s*:\s*function\s*\(/,
78
+ /^(\s*)(const|let|var)\s+(\w+)\s*=\s*(async\s+)?function\s*\(/,
79
+ /^(\s*)(\w+)\s*\([^)]*\)\s*{/,
80
+ /^(\s*)=>\s*{/
81
+ ];
82
+
83
+ lines.forEach((line, index) => {
84
+ functionPatterns.forEach(pattern => {
85
+ const match = line.match(pattern);
86
+ if (match) {
87
+ const indent = match[1] || '';
88
+ const name = match[match.length - 1] || 'anonymous';
89
+ const start = index + 1;
90
+ const end = this.findFunctionEnd(lines, index);
91
+
92
+ if (end > start) {
93
+ functions.push(createBoundary(
94
+ BOUNDARY_TYPES.FUNCTION,
95
+ start,
96
+ end,
97
+ name,
98
+ {
99
+ indent: indent.length,
100
+ isAsync: line.includes('async'),
101
+ isArrow: line.includes('=>')
102
+ }
103
+ ));
104
+ }
105
+ }
106
+ });
107
+ });
108
+
109
+ return functions;
110
+ }
111
+
112
+ /**
113
+ * Scan for classes
114
+ * @param {Array} lines - File lines
115
+ * @returns {Array} - Class boundaries
116
+ */
117
+ scanClasses(lines) {
118
+ const classes = [];
119
+ const classPatterns = [
120
+ /^(\s*)class\s+(\w+)/,
121
+ /^(\s*)class\s+(\w+)\s+extends\s+(\w+)/,
122
+ /^(\s*)export\s+class\s+(\w+)/,
123
+ /^(\s*)export\s+default\s+class\s+(\w+)/
124
+ ];
125
+
126
+ lines.forEach((line, index) => {
127
+ classPatterns.forEach(pattern => {
128
+ const match = line.match(pattern);
129
+ if (match) {
130
+ const indent = match[1] || '';
131
+ const name = match[2] || 'anonymous';
132
+ const parent = match[3] || null;
133
+ const start = index + 1;
134
+ const end = this.findClassEnd(lines, index);
135
+
136
+ if (end > start) {
137
+ classes.push(createBoundary(
138
+ BOUNDARY_TYPES.CLASS,
139
+ start,
140
+ end,
141
+ name,
142
+ {
143
+ indent: indent.length,
144
+ parent,
145
+ isExport: line.includes('export')
146
+ }
147
+ ));
148
+ }
149
+ }
150
+ });
151
+ });
152
+
153
+ return classes;
154
+ }
155
+
156
+ /**
157
+ * Scan for modules
158
+ * @param {Array} lines - File lines
159
+ * @returns {Array} - Module boundaries
160
+ */
161
+ scanModules(lines) {
162
+ const modules = [];
163
+ const modulePatterns = [
164
+ /^(\s*)module\.exports\s*=\s*{/,
165
+ /^(\s*)exports\.(\w+)\s*=/,
166
+ /^(\s*)export\s*{/,
167
+ /^(\s*)export\s+default\s*{/
168
+ ];
169
+
170
+ lines.forEach((line, index) => {
171
+ modulePatterns.forEach(pattern => {
172
+ if (pattern.test(line)) {
173
+ const indent = line.match(/^(\s*)/)[1] || '';
174
+ const start = index + 1;
175
+ const end = this.findModuleEnd(lines, index);
176
+
177
+ if (end > start) {
178
+ modules.push(createBoundary(
179
+ BOUNDARY_TYPES.MODULE,
180
+ start,
181
+ end,
182
+ `module_${index}`,
183
+ {
184
+ indent: indent.length,
185
+ type: line.includes('default') ? 'default' : 'named'
186
+ }
187
+ ));
188
+ }
189
+ }
190
+ });
191
+ });
192
+
193
+ return modules;
194
+ }
195
+
196
+ /**
197
+ * Scan for blocks
198
+ * @param {Array} lines - File lines
199
+ * @returns {Array} - Block boundaries
200
+ */
201
+ scanBlocks(lines) {
202
+ const blocks = [];
203
+ const blockPatterns = [
204
+ /^(\s*)if\s*\(/,
205
+ /^(\s*)for\s*\(/,
206
+ /^(\s*)while\s*\(/,
207
+ /^(\s*)switch\s*\(/,
208
+ /^(\s*)try\s*{/,
209
+ /^(\s*)catch\s*\(/,
210
+ /^(\s*)finally\s*{/
211
+ ];
212
+
213
+ lines.forEach((line, index) => {
214
+ blockPatterns.forEach(pattern => {
215
+ if (pattern.test(line)) {
216
+ const indent = line.match(/^(\s*)/)[1] || '';
217
+ const type = pattern.source.replace(/\\s\*/g, '').replace(/[()]/g, '');
218
+ const start = index + 1;
219
+ const end = this.findBlockEnd(lines, index);
220
+
221
+ if (end > start) {
222
+ blocks.push(createBoundary(
223
+ BOUNDARY_TYPES.BLOCK,
224
+ start,
225
+ end,
226
+ `${type}_${index}`,
227
+ {
228
+ indent: indent.length,
229
+ blockType: type
230
+ }
231
+ ));
232
+ }
233
+ }
234
+ });
235
+ });
236
+
237
+ return blocks;
238
+ }
239
+
240
+ /**
241
+ * Scan for comments
242
+ * @param {Array} lines - File lines
243
+ * @returns {Array} - Comment boundaries
244
+ */
245
+ scanComments(lines) {
246
+ const comments = [];
247
+ const commentPatterns = [
248
+ /\/\*\*/,
249
+ /\*\//,
250
+ /\/\//,
251
+ /\/\*/,
252
+ /\*\//
253
+ ];
254
+
255
+ let inComment = false;
256
+ let commentStart = 0;
257
+ let commentType = null;
258
+
259
+ lines.forEach((line, index) => {
260
+ if (!inComment) {
261
+ // Check for comment start
262
+ if (line.includes('/*')) {
263
+ inComment = true;
264
+ commentStart = index + 1;
265
+ commentType = 'block';
266
+ } else if (line.includes('//')) {
267
+ comments.push(createBoundary(
268
+ BOUNDARY_TYPES.COMMENT,
269
+ index + 1,
270
+ index + 1,
271
+ `line_comment_${index}`,
272
+ {
273
+ type: 'line',
274
+ content: line
275
+ }
276
+ ));
277
+ }
278
+ } else {
279
+ // Check for comment end
280
+ if (commentType === 'block' && line.includes('*/')) {
281
+ comments.push(createBoundary(
282
+ BOUNDARY_TYPES.COMMENT,
283
+ commentStart,
284
+ index + 1,
285
+ `block_comment_${commentStart}`,
286
+ {
287
+ type: 'block',
288
+ content: lines.slice(commentStart - 1, index + 1).join('\n')
289
+ }
290
+ ));
291
+ inComment = false;
292
+ commentType = null;
293
+ }
294
+ }
295
+ });
296
+
297
+ return comments;
298
+ }
299
+
300
+ /**
301
+ * Scan for imports
302
+ * @param {Array} lines - File lines
303
+ * @returns {Array} - Import boundaries
304
+ */
305
+ scanImports(lines) {
306
+ const imports = [];
307
+ const importPatterns = [
308
+ /^(\s*)import\s+.*\s+from\s+['"][^'"]+['"]/, // ES6 imports
309
+ /^(\s*)const\s+.*=\s*require\(['"][^'"]+['"]/, // CommonJS imports
310
+ /^(\s*)import\s+['"][^'"]+['"]/, // Default imports
311
+ /^(\s*)require\(['"][^'"]+['"]/
312
+ ];
313
+
314
+ lines.forEach((line, index) => {
315
+ importPatterns.forEach(pattern => {
316
+ if (pattern.test(line)) {
317
+ const indent = line.match(/^(\s*)/)[1] || '';
318
+ const moduleName = this.extractModuleName(line);
319
+
320
+ imports.push(createBoundary(
321
+ BOUNDARY_TYPES.IMPORT,
322
+ index + 1,
323
+ index + 1,
324
+ `import_${moduleName}`,
325
+ {
326
+ indent: indent.length,
327
+ module: moduleName,
328
+ type: line.includes('import') ? 'es6' : 'commonjs'
329
+ }
330
+ ));
331
+ }
332
+ });
333
+ });
334
+
335
+ return imports;
336
+ }
337
+
338
+ /**
339
+ * Scan for exports
340
+ * @param {Array} lines - File lines
341
+ * @returns {Array} - Export boundaries
342
+ */
343
+ scanExports(lines) {
344
+ const exports = [];
345
+ const exportPatterns = [
346
+ /^(\s*)export\s+(default\s+)?\w+/,
347
+ /^(\s*)module\.exports\s*=\s*\w+/,
348
+ /^(\s*)exports\.\w+\s*=/,
349
+ /^(\s*)export\s*{/
350
+ ];
351
+
352
+ lines.forEach((line, index) => {
353
+ exportPatterns.forEach(pattern => {
354
+ if (pattern.test(line)) {
355
+ const indent = line.match(/^(\s*)/)[1] || '';
356
+ const exportName = this.extractExportName(line);
357
+
358
+ exports.push(createBoundary(
359
+ BOUNDARY_TYPES.EXPORT,
360
+ index + 1,
361
+ index + 1,
362
+ `export_${exportName}`,
363
+ {
364
+ indent: indent.length,
365
+ name: exportName,
366
+ type: line.includes('default') ? 'default' : 'named'
367
+ }
368
+ ));
369
+ }
370
+ });
371
+ });
372
+
373
+ return exports;
374
+ }
375
+
376
+ /**
377
+ * Find function end
378
+ * @param {Array} lines - File lines
379
+ * @param {number} startIndex - Start index
380
+ * @returns {number} - End line number
381
+ */
382
+ findFunctionEnd(lines, startIndex) {
383
+ let braceCount = 0;
384
+ let inFunction = false;
385
+
386
+ for (let i = startIndex; i < lines.length; i++) {
387
+ const line = lines[i];
388
+
389
+ if (line.includes('{')) {
390
+ braceCount += (line.match(/{/g) || []).length;
391
+ inFunction = true;
392
+ }
393
+
394
+ if (line.includes('}')) {
395
+ braceCount -= (line.match(/}/g) || []).length;
396
+ }
397
+
398
+ if (inFunction && braceCount === 0) {
399
+ return i + 1;
400
+ }
401
+ }
402
+
403
+ return lines.length;
404
+ }
405
+
406
+ /**
407
+ * Find class end
408
+ * @param {Array} lines - File lines
409
+ * @param {number} startIndex - Start index
410
+ * @returns {number} - End line number
411
+ */
412
+ findClassEnd(lines, startIndex) {
413
+ let braceCount = 0;
414
+ let inClass = false;
415
+
416
+ for (let i = startIndex; i < lines.length; i++) {
417
+ const line = lines[i];
418
+
419
+ if (line.includes('{')) {
420
+ braceCount += (line.match(/{/g) || []).length;
421
+ inClass = true;
422
+ }
423
+
424
+ if (line.includes('}')) {
425
+ braceCount -= (line.match(/}/g) || []).length;
426
+ }
427
+
428
+ if (inClass && braceCount === 0) {
429
+ return i + 1;
430
+ }
431
+ }
432
+
433
+ return lines.length;
434
+ }
435
+
436
+ /**
437
+ * Find module end
438
+ * @param {Array} lines - File lines
439
+ * @param {number} startIndex - Start index
440
+ * @returns {number} - End line number
441
+ */
442
+ findModuleEnd(lines, startIndex) {
443
+ // Module typically ends at end of file or next export/module
444
+ for (let i = startIndex + 1; i < lines.length; i++) {
445
+ const line = lines[i];
446
+ if (/^\s*(export|module\.exports)/.test(line)) {
447
+ return i;
448
+ }
449
+ }
450
+
451
+ return lines.length;
452
+ }
453
+
454
+ /**
455
+ * Find block end
456
+ * @param {Array} lines - File lines
457
+ * @param {number} startIndex - Start index
458
+ * @returns {number} - End line number
459
+ */
460
+ findBlockEnd(lines, startIndex) {
461
+ let braceCount = 0;
462
+ let inBlock = false;
463
+
464
+ for (let i = startIndex; i < lines.length; i++) {
465
+ const line = lines[i];
466
+
467
+ if (line.includes('{')) {
468
+ braceCount += (line.match(/{/g) || []).length;
469
+ inBlock = true;
470
+ }
471
+
472
+ if (line.includes('}')) {
473
+ braceCount -= (line.match(/}/g) || []).length;
474
+ }
475
+
476
+ if (inBlock && braceCount === 0) {
477
+ return i + 1;
478
+ }
479
+ }
480
+
481
+ return lines.length;
482
+ }
483
+
484
+ /**
485
+ * Extract module name from import line
486
+ * @param {string} line - Import line
487
+ * @returns {string} - Module name
488
+ */
489
+ extractModuleName(line) {
490
+ const match = line.match(/(?:from\s+|require\()['"]([^'"]+)['"]/);
491
+ return match ? match[1] : 'unknown';
492
+ }
493
+
494
+ /**
495
+ * Extract export name from export line
496
+ * @param {string} line - Export line
497
+ * @returns {string} - Export name
498
+ */
499
+ extractExportName(line) {
500
+ const match = line.match(/(?:export\s+(?:default\s+)?|module\.exports\s*=|exports\.)(\w+)/);
501
+ return match ? match[1] : 'unknown';
502
+ }
503
+
504
+ /**
505
+ * Calculate boundary complexity
506
+ * @param {Object} boundary - Boundary object
507
+ * @param {Array} lines - File lines
508
+ * @returns {number} - Complexity score
509
+ */
510
+ calculateBoundaryComplexity(boundary, lines) {
511
+ const boundaryLines = lines.slice(boundary.start - 1, boundary.end);
512
+ let complexity = 1;
513
+
514
+ // Count control structures
515
+ const controlStructures = ['if', 'for', 'while', 'switch', 'try', 'catch'];
516
+ boundaryLines.forEach(line => {
517
+ controlStructures.forEach(struct => {
518
+ if (new RegExp(`\\b${struct}\\b`).test(line)) {
519
+ complexity += 0.5;
520
+ }
521
+ });
522
+ });
523
+
524
+ // Count nested structures
525
+ const maxNesting = this.calculateMaxNesting(boundaryLines);
526
+ complexity += maxNesting * 0.3;
527
+
528
+ return Math.round(complexity);
529
+ }
530
+
531
+ /**
532
+ * Calculate maximum nesting level
533
+ * @param {Array} lines - Boundary lines
534
+ * @returns {number} - Maximum nesting level
535
+ */
536
+ calculateMaxNesting(lines) {
537
+ let maxNesting = 0;
538
+ let currentNesting = 0;
539
+
540
+ lines.forEach(line => {
541
+ const opens = (line.match(/{/g) || []).length;
542
+ const closes = (line.match(/}/g) || []).length;
543
+
544
+ currentNesting += opens - closes;
545
+ maxNesting = Math.max(maxNesting, currentNesting);
546
+ });
547
+
548
+ return maxNesting;
549
+ }
550
+
551
+ /**
552
+ * Generate scan metadata
553
+ * @param {Array} boundaries - Detected boundaries
554
+ * @param {Array} lines - File lines
555
+ * @returns {Object} - Scan metadata
556
+ */
557
+ generateScanMetadata(boundaries, lines) {
558
+ const byType = {};
559
+ boundaries.forEach(boundary => {
560
+ byType[boundary.type] = (byType[boundary.type] || 0) + 1;
561
+ });
562
+
563
+ return {
564
+ totalLines: lines.length,
565
+ totalBoundaries: boundaries.length,
566
+ byType,
567
+ averageBoundarySize: boundaries.length > 0 ?
568
+ boundaries.reduce((sum, b) => sum + b.size, 0) / boundaries.length : 0,
569
+ scanOptions: this.options
570
+ };
571
+ }
572
+
573
+ /**
574
+ * Get scanner information
575
+ * @returns {Object} - Scanner info
576
+ */
577
+ getScannerInfo() {
578
+ return {
579
+ supportedTypes: Object.values(BOUNDARY_TYPES),
580
+ defaultOptions: this.options,
581
+ features: [
582
+ 'function detection',
583
+ 'class detection',
584
+ 'module detection',
585
+ 'block detection',
586
+ 'comment detection',
587
+ 'import/export detection'
588
+ ],
589
+ version: '1.0.0'
590
+ };
591
+ }
592
+
593
+ /**
594
+ * Create scanner with default configuration
595
+ * @param {Object} config - Configuration overrides
596
+ * @returns {BoundaryScanner} - Scanner instance
597
+ */
598
+ static createDefault(config = {}) {
599
+ return new BoundaryScanner({
600
+ includeComments: true,
601
+ includeImports: true,
602
+ includeExports: true,
603
+ minBoundarySize: 5,
604
+ ...config
605
+ });
606
+ }
607
+ }
608
+
609
+ module.exports = BoundaryScanner;
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Boundary Detection - Types
3
+ *
4
+ * Contains boundary detection types and result classes.
5
+ */
6
+
7
+ /**
8
+ * Boundary types
9
+ */
10
+ const BOUNDARY_TYPES = {
11
+ FUNCTION: 'function',
12
+ CLASS: 'class',
13
+ MODULE: 'module',
14
+ BLOCK: 'block',
15
+ IMPORT: 'import',
16
+ EXPORT: 'export',
17
+ COMMENT: 'comment',
18
+ UTILITY: 'utility',
19
+ CONSTANT: 'constant'
20
+ };
21
+
22
+ /**
23
+ * Boundary detection result class
24
+ */
25
+ class BoundaryDetectionResult {
26
+ constructor(filePath) {
27
+ this.filePath = filePath;
28
+ this.boundaries = [];
29
+ this.metadata = {
30
+ totalBoundaries: 0,
31
+ byType: {},
32
+ complexity: 'unknown',
33
+ cohesion: 'unknown',
34
+ coupling: 'unknown'
35
+ };
36
+ }
37
+
38
+ addBoundary(boundary) {
39
+ this.boundaries.push(boundary);
40
+ this.metadata.totalBoundaries++;
41
+
42
+ if (!this.metadata.byType[boundary.type]) {
43
+ this.metadata.byType[boundary.type] = 0;
44
+ }
45
+ this.metadata.byType[boundary.type]++;
46
+ }
47
+
48
+ getBoundariesByType(type) {
49
+ return this.boundaries.filter(b => b.type === type);
50
+ }
51
+
52
+ getLargestBoundaries(count = 5) {
53
+ return this.boundaries
54
+ .sort((a, b) => b.lineCount - a.lineCount)
55
+ .slice(0, count);
56
+ }
57
+
58
+ getRefactoringCandidates() {
59
+ return this.boundaries.filter(b =>
60
+ b.lineCount > 50 && // Reasonable size
61
+ (b.type === BOUNDARY_TYPES.FUNCTION || b.type === BOUNDARY_TYPES.CLASS)
62
+ );
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Boundary class
68
+ */
69
+ class Boundary {
70
+ constructor(type, startLine, endLine, name = '') {
71
+ this.type = type;
72
+ this.startLine = startLine;
73
+ this.endLine = endLine;
74
+ this.name = name;
75
+ this.lineCount = endLine - startLine + 1;
76
+ this.complexity = 0;
77
+ this.dependencies = [];
78
+ this.exports = [];
79
+ this.comments = [];
80
+ this.metadata = {};
81
+ }
82
+
83
+ addDependency(dependency) {
84
+ this.dependencies.push(dependency);
85
+ }
86
+
87
+ addExport(exportName) {
88
+ this.exports.push(exportName);
89
+ }
90
+
91
+ addComment(comment) {
92
+ this.comments.push(comment);
93
+ }
94
+
95
+ setComplexity(complexity) {
96
+ this.complexity = complexity;
97
+ }
98
+
99
+ getSummary() {
100
+ return {
101
+ type: this.type,
102
+ name: this.name,
103
+ startLine: this.startLine,
104
+ endLine: this.endLine,
105
+ lineCount: this.lineCount,
106
+ complexity: this.complexity,
107
+ dependencyCount: this.dependencies.length,
108
+ exportCount: this.exports.length,
109
+ commentCount: this.comments.length
110
+ };
111
+ }
112
+ }
113
+
114
+ module.exports = {
115
+ BOUNDARY_TYPES,
116
+ BoundaryDetectionResult,
117
+ Boundary
118
+ };