linguclaw 0.4.0

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 (168) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +161 -0
  3. package/dist/agent-system.d.ts +196 -0
  4. package/dist/agent-system.d.ts.map +1 -0
  5. package/dist/agent-system.js +738 -0
  6. package/dist/agent-system.js.map +1 -0
  7. package/dist/alphabeta.d.ts +54 -0
  8. package/dist/alphabeta.d.ts.map +1 -0
  9. package/dist/alphabeta.js +193 -0
  10. package/dist/alphabeta.js.map +1 -0
  11. package/dist/browser.d.ts +62 -0
  12. package/dist/browser.d.ts.map +1 -0
  13. package/dist/browser.js +224 -0
  14. package/dist/browser.js.map +1 -0
  15. package/dist/cli.d.ts +7 -0
  16. package/dist/cli.d.ts.map +1 -0
  17. package/dist/cli.js +565 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/code-parser.d.ts +39 -0
  20. package/dist/code-parser.d.ts.map +1 -0
  21. package/dist/code-parser.js +385 -0
  22. package/dist/code-parser.js.map +1 -0
  23. package/dist/config.d.ts +66 -0
  24. package/dist/config.d.ts.map +1 -0
  25. package/dist/config.js +232 -0
  26. package/dist/config.js.map +1 -0
  27. package/dist/core/engine.d.ts +359 -0
  28. package/dist/core/engine.d.ts.map +1 -0
  29. package/dist/core/engine.js +127 -0
  30. package/dist/core/engine.js.map +1 -0
  31. package/dist/daemon.d.ts +29 -0
  32. package/dist/daemon.d.ts.map +1 -0
  33. package/dist/daemon.js +212 -0
  34. package/dist/daemon.js.map +1 -0
  35. package/dist/email-receiver.d.ts +63 -0
  36. package/dist/email-receiver.d.ts.map +1 -0
  37. package/dist/email-receiver.js +553 -0
  38. package/dist/email-receiver.js.map +1 -0
  39. package/dist/git-integration.d.ts +180 -0
  40. package/dist/git-integration.d.ts.map +1 -0
  41. package/dist/git-integration.js +850 -0
  42. package/dist/git-integration.js.map +1 -0
  43. package/dist/inbox.d.ts +84 -0
  44. package/dist/inbox.d.ts.map +1 -0
  45. package/dist/inbox.js +198 -0
  46. package/dist/inbox.js.map +1 -0
  47. package/dist/index.d.ts +6 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +41 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/languages/cpp.d.ts +51 -0
  52. package/dist/languages/cpp.d.ts.map +1 -0
  53. package/dist/languages/cpp.js +930 -0
  54. package/dist/languages/cpp.js.map +1 -0
  55. package/dist/languages/csharp.d.ts +79 -0
  56. package/dist/languages/csharp.d.ts.map +1 -0
  57. package/dist/languages/csharp.js +1776 -0
  58. package/dist/languages/csharp.js.map +1 -0
  59. package/dist/languages/go.d.ts +50 -0
  60. package/dist/languages/go.d.ts.map +1 -0
  61. package/dist/languages/go.js +882 -0
  62. package/dist/languages/go.js.map +1 -0
  63. package/dist/languages/java.d.ts +47 -0
  64. package/dist/languages/java.d.ts.map +1 -0
  65. package/dist/languages/java.js +649 -0
  66. package/dist/languages/java.js.map +1 -0
  67. package/dist/languages/python.d.ts +47 -0
  68. package/dist/languages/python.d.ts.map +1 -0
  69. package/dist/languages/python.js +655 -0
  70. package/dist/languages/python.js.map +1 -0
  71. package/dist/languages/rust.d.ts +61 -0
  72. package/dist/languages/rust.d.ts.map +1 -0
  73. package/dist/languages/rust.js +1064 -0
  74. package/dist/languages/rust.js.map +1 -0
  75. package/dist/logger.d.ts +20 -0
  76. package/dist/logger.d.ts.map +1 -0
  77. package/dist/logger.js +133 -0
  78. package/dist/logger.js.map +1 -0
  79. package/dist/longterm-memory.d.ts +47 -0
  80. package/dist/longterm-memory.d.ts.map +1 -0
  81. package/dist/longterm-memory.js +300 -0
  82. package/dist/longterm-memory.js.map +1 -0
  83. package/dist/memory.d.ts +42 -0
  84. package/dist/memory.d.ts.map +1 -0
  85. package/dist/memory.js +274 -0
  86. package/dist/memory.js.map +1 -0
  87. package/dist/messaging.d.ts +103 -0
  88. package/dist/messaging.d.ts.map +1 -0
  89. package/dist/messaging.js +645 -0
  90. package/dist/messaging.js.map +1 -0
  91. package/dist/multi-provider.d.ts +69 -0
  92. package/dist/multi-provider.d.ts.map +1 -0
  93. package/dist/multi-provider.js +484 -0
  94. package/dist/multi-provider.js.map +1 -0
  95. package/dist/orchestrator.d.ts +65 -0
  96. package/dist/orchestrator.d.ts.map +1 -0
  97. package/dist/orchestrator.js +441 -0
  98. package/dist/orchestrator.js.map +1 -0
  99. package/dist/plugins.d.ts +52 -0
  100. package/dist/plugins.d.ts.map +1 -0
  101. package/dist/plugins.js +215 -0
  102. package/dist/plugins.js.map +1 -0
  103. package/dist/prism-orchestrator.d.ts +26 -0
  104. package/dist/prism-orchestrator.d.ts.map +1 -0
  105. package/dist/prism-orchestrator.js +191 -0
  106. package/dist/prism-orchestrator.js.map +1 -0
  107. package/dist/prism.d.ts +46 -0
  108. package/dist/prism.d.ts.map +1 -0
  109. package/dist/prism.js +188 -0
  110. package/dist/prism.js.map +1 -0
  111. package/dist/privacy.d.ts +23 -0
  112. package/dist/privacy.d.ts.map +1 -0
  113. package/dist/privacy.js +220 -0
  114. package/dist/privacy.js.map +1 -0
  115. package/dist/proactive.d.ts +30 -0
  116. package/dist/proactive.d.ts.map +1 -0
  117. package/dist/proactive.js +260 -0
  118. package/dist/proactive.js.map +1 -0
  119. package/dist/refactoring-engine.d.ts +100 -0
  120. package/dist/refactoring-engine.d.ts.map +1 -0
  121. package/dist/refactoring-engine.js +717 -0
  122. package/dist/refactoring-engine.js.map +1 -0
  123. package/dist/resilience.d.ts +43 -0
  124. package/dist/resilience.d.ts.map +1 -0
  125. package/dist/resilience.js +200 -0
  126. package/dist/resilience.js.map +1 -0
  127. package/dist/safety.d.ts +40 -0
  128. package/dist/safety.d.ts.map +1 -0
  129. package/dist/safety.js +133 -0
  130. package/dist/safety.js.map +1 -0
  131. package/dist/sandbox.d.ts +33 -0
  132. package/dist/sandbox.d.ts.map +1 -0
  133. package/dist/sandbox.js +173 -0
  134. package/dist/sandbox.js.map +1 -0
  135. package/dist/scheduler.d.ts +72 -0
  136. package/dist/scheduler.d.ts.map +1 -0
  137. package/dist/scheduler.js +374 -0
  138. package/dist/scheduler.js.map +1 -0
  139. package/dist/semantic-memory.d.ts +70 -0
  140. package/dist/semantic-memory.d.ts.map +1 -0
  141. package/dist/semantic-memory.js +430 -0
  142. package/dist/semantic-memory.js.map +1 -0
  143. package/dist/skills.d.ts +97 -0
  144. package/dist/skills.d.ts.map +1 -0
  145. package/dist/skills.js +575 -0
  146. package/dist/skills.js.map +1 -0
  147. package/dist/static/dashboard.html +853 -0
  148. package/dist/static/hub.html +772 -0
  149. package/dist/static/index.html +818 -0
  150. package/dist/static/logo.svg +24 -0
  151. package/dist/static/workflow-editor.html +913 -0
  152. package/dist/tools.d.ts +67 -0
  153. package/dist/tools.d.ts.map +1 -0
  154. package/dist/tools.js +303 -0
  155. package/dist/tools.js.map +1 -0
  156. package/dist/types.d.ts +295 -0
  157. package/dist/types.d.ts.map +1 -0
  158. package/dist/types.js +90 -0
  159. package/dist/types.js.map +1 -0
  160. package/dist/web.d.ts +76 -0
  161. package/dist/web.d.ts.map +1 -0
  162. package/dist/web.js +2139 -0
  163. package/dist/web.js.map +1 -0
  164. package/dist/workflow-engine.d.ts +114 -0
  165. package/dist/workflow-engine.d.ts.map +1 -0
  166. package/dist/workflow-engine.js +855 -0
  167. package/dist/workflow-engine.js.map +1 -0
  168. package/package.json +77 -0
@@ -0,0 +1,717 @@
1
+ "use strict";
2
+ /**
3
+ * Code Refactoring Engine for LinguClaw
4
+ * Automated code transformations and improvements
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.RefactoringEngine = void 0;
41
+ const fs = __importStar(require("fs"));
42
+ const logger_1 = require("./logger");
43
+ const logger = (0, logger_1.getLogger)();
44
+ // ============================================
45
+ // REFACTORING ENGINE
46
+ // ============================================
47
+ class RefactoringEngine {
48
+ operations = new Map();
49
+ appliedRefactorings = [];
50
+ constructor() {
51
+ this.registerDefaultOperations();
52
+ }
53
+ registerDefaultOperations() {
54
+ // Simplification refactorings
55
+ this.register({
56
+ id: 'remove-unused-imports',
57
+ name: 'Remove Unused Imports',
58
+ description: 'Removes import statements that are not used in the code',
59
+ category: 'simplification',
60
+ appliesTo: ['typescript', 'javascript', 'python', 'java', 'go', 'rust', 'csharp'],
61
+ canApply: (node) => this.hasUnusedImports(node),
62
+ apply: (node, source) => this.removeUnusedImports(node, source),
63
+ safety: 'safe',
64
+ breaking: false,
65
+ });
66
+ this.register({
67
+ id: 'simplify-boolean-expressions',
68
+ name: 'Simplify Boolean Expressions',
69
+ description: 'Simplifies redundant boolean expressions like `x == true` to `x`',
70
+ category: 'simplification',
71
+ appliesTo: ['typescript', 'javascript', 'python', 'java', 'csharp'],
72
+ canApply: (node) => this.hasRedundantBooleanExpressions(node),
73
+ apply: (node, source) => this.simplifyBooleanExpressions(node, source),
74
+ safety: 'safe',
75
+ breaking: false,
76
+ });
77
+ this.register({
78
+ id: 'remove-dead-code',
79
+ name: 'Remove Dead Code',
80
+ description: 'Removes unreachable code and unused variables',
81
+ category: 'simplification',
82
+ appliesTo: ['typescript', 'javascript', 'python', 'java', 'go', 'rust', 'csharp'],
83
+ canApply: (node) => this.hasDeadCode(node),
84
+ apply: (node, source) => this.removeDeadCode(node, source),
85
+ safety: 'requires-review',
86
+ breaking: false,
87
+ });
88
+ // Extraction refactorings
89
+ this.register({
90
+ id: 'extract-method',
91
+ name: 'Extract Method',
92
+ description: 'Extracts a block of code into a separate method/function',
93
+ category: 'extraction',
94
+ appliesTo: ['typescript', 'javascript', 'python', 'java', 'csharp'],
95
+ canApply: (node) => this.canExtractMethod(node),
96
+ apply: (node, source) => this.extractMethod(node, source),
97
+ safety: 'safe',
98
+ breaking: false,
99
+ });
100
+ this.register({
101
+ id: 'extract-variable',
102
+ name: 'Extract Variable',
103
+ description: 'Extracts a complex expression into a named variable',
104
+ category: 'extraction',
105
+ appliesTo: ['typescript', 'javascript', 'python', 'java', 'go', 'rust', 'csharp'],
106
+ canApply: (node) => this.canExtractVariable(node),
107
+ apply: (node, source) => this.extractVariable(node, source),
108
+ safety: 'safe',
109
+ breaking: false,
110
+ });
111
+ this.register({
112
+ id: 'extract-interface',
113
+ name: 'Extract Interface',
114
+ description: 'Creates an interface from a class public API',
115
+ category: 'extraction',
116
+ appliesTo: ['typescript', 'java', 'csharp'],
117
+ canApply: (node) => this.canExtractInterface(node),
118
+ apply: (node, source) => this.extractInterface(node, source),
119
+ safety: 'safe',
120
+ breaking: false,
121
+ });
122
+ // Modernization refactorings
123
+ this.register({
124
+ id: 'convert-to-arrow-functions',
125
+ name: 'Convert to Arrow Functions',
126
+ description: 'Converts traditional functions to arrow functions where appropriate',
127
+ category: 'modernization',
128
+ appliesTo: ['typescript', 'javascript'],
129
+ canApply: (node) => this.canConvertToArrowFunction(node),
130
+ apply: (node, source) => this.convertToArrowFunction(node, source),
131
+ safety: 'safe',
132
+ breaking: false,
133
+ });
134
+ this.register({
135
+ id: 'convert-to-template-literals',
136
+ name: 'Convert to Template Literals',
137
+ description: 'Converts string concatenation to template literals',
138
+ category: 'modernization',
139
+ appliesTo: ['typescript', 'javascript'],
140
+ canApply: (node) => this.hasStringConcatenation(node),
141
+ apply: (node, source) => this.convertToTemplateLiterals(node, source),
142
+ safety: 'safe',
143
+ breaking: false,
144
+ });
145
+ this.register({
146
+ id: 'convert-to-async-await',
147
+ name: 'Convert to Async/Await',
148
+ description: 'Converts Promise chains to async/await syntax',
149
+ category: 'modernization',
150
+ appliesTo: ['typescript', 'javascript', 'csharp'],
151
+ canApply: (node) => this.hasPromiseChains(node),
152
+ apply: (node, source) => this.convertToAsyncAwait(node, source),
153
+ safety: 'requires-review',
154
+ breaking: false,
155
+ });
156
+ this.register({
157
+ id: 'convert-to-optional-chaining',
158
+ name: 'Convert to Optional Chaining',
159
+ description: 'Converts nested property checks to optional chaining',
160
+ category: 'modernization',
161
+ appliesTo: ['typescript', 'javascript'],
162
+ canApply: (node) => this.hasNestedPropertyChecks(node),
163
+ apply: (node, source) => this.convertToOptionalChaining(node, source),
164
+ safety: 'safe',
165
+ breaking: false,
166
+ });
167
+ // Performance refactorings
168
+ this.register({
169
+ id: 'optimize-string-concatenation',
170
+ name: 'Optimize String Concatenation',
171
+ description: 'Uses StringBuilder/StringBuffer for concatenation in loops',
172
+ category: 'performance',
173
+ appliesTo: ['java', 'csharp', 'typescript', 'javascript'],
174
+ canApply: (node) => this.hasStringConcatInLoop(node),
175
+ apply: (node, source) => this.optimizeStringConcatenation(node, source),
176
+ safety: 'safe',
177
+ breaking: false,
178
+ });
179
+ this.register({
180
+ id: 'convert-to-linq',
181
+ name: 'Convert to LINQ/Stream',
182
+ description: 'Converts imperative loops to LINQ (C#) or Stream (Java)',
183
+ category: 'performance',
184
+ appliesTo: ['csharp', 'java'],
185
+ canApply: (node) => this.canConvertToLinq(node),
186
+ apply: (node, source) => this.convertToLinq(node, source),
187
+ safety: 'requires-review',
188
+ breaking: false,
189
+ });
190
+ // Readability refactorings
191
+ this.register({
192
+ id: 'rename-variable',
193
+ name: 'Rename Variable',
194
+ description: 'Renames variables to be more descriptive',
195
+ category: 'readability',
196
+ appliesTo: ['typescript', 'javascript', 'python', 'java', 'go', 'rust', 'csharp'],
197
+ canApply: (node) => this.hasPoorlyNamedVariables(node),
198
+ apply: (node, source) => this.renameVariables(node, source),
199
+ safety: 'requires-review',
200
+ breaking: false,
201
+ });
202
+ this.register({
203
+ id: 'add-type-annotations',
204
+ name: 'Add Type Annotations',
205
+ description: 'Adds explicit type annotations where they improve readability',
206
+ category: 'readability',
207
+ appliesTo: ['typescript', 'python', 'go', 'rust'],
208
+ canApply: (node) => this.missingTypeAnnotations(node),
209
+ apply: (node, source) => this.addTypeAnnotations(node, source),
210
+ safety: 'safe',
211
+ breaking: false,
212
+ });
213
+ this.register({
214
+ id: 'reorganize-class-members',
215
+ name: 'Reorganize Class Members',
216
+ description: 'Reorders class members by visibility and type',
217
+ category: 'reorganization',
218
+ appliesTo: ['typescript', 'java', 'csharp', 'python'],
219
+ canApply: (node) => this.hasUnorganizedMembers(node),
220
+ apply: (node, source) => this.reorganizeClassMembers(node, source),
221
+ safety: 'safe',
222
+ breaking: false,
223
+ });
224
+ }
225
+ register(operation) {
226
+ this.operations.set(operation.id, operation);
227
+ }
228
+ getAvailableOperations(language) {
229
+ return Array.from(this.operations.values())
230
+ .filter(op => op.appliesTo.includes(language));
231
+ }
232
+ analyzeForRefactoring(ast, language, source) {
233
+ const suggestions = [];
234
+ const operations = this.getAvailableOperations(language);
235
+ for (const op of operations) {
236
+ if (op.canApply(ast)) {
237
+ const result = op.apply(ast, source);
238
+ if (result.success && result.changes.length > 0) {
239
+ suggestions.push({
240
+ operation: op,
241
+ preview: result,
242
+ impact: this.calculateImpact(result),
243
+ });
244
+ }
245
+ }
246
+ }
247
+ return suggestions.sort((a, b) => b.impact - a.impact);
248
+ }
249
+ calculateImpact(result) {
250
+ let impact = 0;
251
+ // More changes = higher impact
252
+ impact += result.changes.length * 5;
253
+ // Fewer warnings = higher confidence
254
+ impact -= result.warnings.length * 2;
255
+ // No errors = good
256
+ if (result.errors.length === 0)
257
+ impact += 10;
258
+ return Math.max(0, impact);
259
+ }
260
+ async applyRefactoring(filePath, operationId, ast, dryRun = false) {
261
+ const operation = this.operations.get(operationId);
262
+ if (!operation) {
263
+ return {
264
+ success: false,
265
+ original: '',
266
+ transformed: '',
267
+ changes: [],
268
+ warnings: [],
269
+ errors: [`Operation ${operationId} not found`],
270
+ };
271
+ }
272
+ const source = fs.readFileSync(filePath, 'utf-8');
273
+ if (!operation.canApply(ast)) {
274
+ return {
275
+ success: false,
276
+ original: source,
277
+ transformed: source,
278
+ changes: [],
279
+ warnings: [],
280
+ errors: [`Operation ${operationId} cannot be applied to this code`],
281
+ };
282
+ }
283
+ const result = operation.apply(ast, source);
284
+ if (!dryRun && result.success) {
285
+ fs.writeFileSync(filePath, result.transformed);
286
+ this.appliedRefactorings.push(result);
287
+ logger.info(`Applied refactoring: ${operation.name} to ${filePath}`);
288
+ }
289
+ return result;
290
+ }
291
+ // ============================================
292
+ // REFACTORING IMPLEMENTATIONS
293
+ // ============================================
294
+ hasUnusedImports(node) {
295
+ // Simplified check - would need full symbol analysis
296
+ return node.children.some(c => c.type === 'ImportDeclaration');
297
+ }
298
+ removeUnusedImports(node, source) {
299
+ const changes = [];
300
+ const lines = source.split('\n');
301
+ const unusedImports = this.findUnusedImports(node, source);
302
+ for (const imp of unusedImports) {
303
+ const lineIndex = imp.location.startLine - 1;
304
+ changes.push({
305
+ type: 'delete',
306
+ startLine: imp.location.startLine,
307
+ startColumn: 0,
308
+ endLine: imp.location.endLine,
309
+ endColumn: lines[lineIndex]?.length || 0,
310
+ originalText: lines[lineIndex] || '',
311
+ newText: '',
312
+ description: 'Remove unused import',
313
+ });
314
+ }
315
+ return {
316
+ success: true,
317
+ original: source,
318
+ transformed: this.applyChanges(source, changes),
319
+ changes,
320
+ warnings: [],
321
+ errors: [],
322
+ };
323
+ }
324
+ findUnusedImports(node, source) {
325
+ const imports = node.children.filter(c => c.type === 'ImportDeclaration');
326
+ return imports.filter(imp => {
327
+ const names = imp.metadata.names || [];
328
+ return names.some((name) => !source.includes(name) || source.indexOf(name) === source.lastIndexOf(name));
329
+ });
330
+ }
331
+ hasRedundantBooleanExpressions(node) {
332
+ // Check for patterns like `x == true` or `x == false`
333
+ return /==\s*(true|false)|===\s*(true|false)/.test(JSON.stringify(node));
334
+ }
335
+ simplifyBooleanExpressions(node, source) {
336
+ const changes = [];
337
+ // Find all redundant boolean comparisons
338
+ const patterns = [
339
+ { regex: /([\w.]+)\s*===?\s*true/g, replacement: '$1', desc: 'Simplify `x === true` to `x`' },
340
+ { regex: /([\w.]+)\s*===?\s*false/g, replacement: '!$1', desc: 'Simplify `x === false` to `!x`' },
341
+ ];
342
+ const lines = source.split('\n');
343
+ for (let i = 0; i < lines.length; i++) {
344
+ for (const pattern of patterns) {
345
+ if (pattern.regex.test(lines[i])) {
346
+ const original = lines[i];
347
+ const transformed = lines[i].replace(pattern.regex, pattern.replacement);
348
+ if (original !== transformed) {
349
+ changes.push({
350
+ type: 'replace',
351
+ startLine: i + 1,
352
+ startColumn: 0,
353
+ endLine: i + 1,
354
+ endColumn: original.length,
355
+ originalText: original,
356
+ newText: transformed,
357
+ description: pattern.desc,
358
+ });
359
+ }
360
+ }
361
+ }
362
+ }
363
+ return {
364
+ success: true,
365
+ original: source,
366
+ transformed: this.applyChanges(source, changes),
367
+ changes,
368
+ warnings: [],
369
+ errors: [],
370
+ };
371
+ }
372
+ hasDeadCode(node) {
373
+ // Check for unreachable code or unused variables
374
+ return node.children.some(c => c.type === 'VariableDeclaration' && !c.metadata.isUsed ||
375
+ c.type === 'FunctionDeclaration' && !c.metadata.isCalled);
376
+ }
377
+ removeDeadCode(node, source) {
378
+ // Implementation would require full data flow analysis
379
+ return {
380
+ success: false,
381
+ original: source,
382
+ transformed: source,
383
+ changes: [],
384
+ warnings: ['Dead code removal requires comprehensive analysis'],
385
+ errors: [],
386
+ };
387
+ }
388
+ canExtractMethod(node) {
389
+ // Check if there's a code block that can be extracted
390
+ return node.children.some(c => c.type === 'BlockStatement' ||
391
+ c.type === 'MethodDeclaration' ||
392
+ c.type === 'FunctionDeclaration');
393
+ }
394
+ extractMethod(node, source) {
395
+ // Complex refactoring - would need full analysis
396
+ return {
397
+ success: false,
398
+ original: source,
399
+ transformed: source,
400
+ changes: [],
401
+ warnings: ['Method extraction requires selection of code block'],
402
+ errors: [],
403
+ };
404
+ }
405
+ canExtractVariable(node) {
406
+ // Check for complex expressions
407
+ return node.children.some(c => c.type === 'BinaryExpression' ||
408
+ c.type === 'CallExpression' ||
409
+ c.type === 'MemberExpression');
410
+ }
411
+ extractVariable(node, source) {
412
+ // Would need selection of specific expression
413
+ return {
414
+ success: false,
415
+ original: source,
416
+ transformed: source,
417
+ changes: [],
418
+ warnings: ['Variable extraction requires selection of expression'],
419
+ errors: [],
420
+ };
421
+ }
422
+ canExtractInterface(node) {
423
+ return node.type === 'ClassDeclaration' || node.type === 'ClassDefinition';
424
+ }
425
+ extractInterface(node, source) {
426
+ // Generate interface from class public methods
427
+ const className = node.metadata.name || 'Unknown';
428
+ const methods = node.children.filter(c => c.type === 'MethodDeclaration' &&
429
+ (c.metadata.isPublic || !c.metadata.isPrivate));
430
+ let interfaceCode = `interface I${className} {\n`;
431
+ for (const method of methods) {
432
+ const params = (method.metadata.parameters || []).join(', ');
433
+ interfaceCode += ` ${method.metadata.name}(${params}): ${method.metadata.returnType || 'void'};\n`;
434
+ }
435
+ interfaceCode += '}';
436
+ return {
437
+ success: true,
438
+ original: source,
439
+ transformed: source + '\n\n' + interfaceCode,
440
+ changes: [{
441
+ type: 'insert',
442
+ startLine: source.split('\n').length + 1,
443
+ startColumn: 0,
444
+ endLine: source.split('\n').length + 1,
445
+ endColumn: 0,
446
+ originalText: '',
447
+ newText: interfaceCode,
448
+ description: `Extract interface I${className}`,
449
+ }],
450
+ warnings: [],
451
+ errors: [],
452
+ };
453
+ }
454
+ canConvertToArrowFunction(node) {
455
+ return node.children.some(c => c.type === 'FunctionDeclaration' &&
456
+ !c.metadata.isGenerator &&
457
+ !c.metadata.isConstructor);
458
+ }
459
+ convertToArrowFunction(node, source) {
460
+ const changes = [];
461
+ const lines = source.split('\n');
462
+ for (const child of node.children) {
463
+ if (child.type === 'FunctionDeclaration' && child.metadata.name) {
464
+ const startLine = child.location.startLine - 1;
465
+ const original = lines[startLine];
466
+ // Simple transformation for demo
467
+ const arrowVersion = `const ${child.metadata.name} = ${original.replace('function ', '').replace(child.metadata.name, '')}`;
468
+ changes.push({
469
+ type: 'replace',
470
+ startLine: child.location.startLine,
471
+ startColumn: 0,
472
+ endLine: child.location.startLine,
473
+ endColumn: original.length,
474
+ originalText: original,
475
+ newText: arrowVersion,
476
+ description: 'Convert function to arrow function',
477
+ });
478
+ }
479
+ }
480
+ return {
481
+ success: changes.length > 0,
482
+ original: source,
483
+ transformed: this.applyChanges(source, changes),
484
+ changes,
485
+ warnings: [],
486
+ errors: [],
487
+ };
488
+ }
489
+ hasStringConcatenation(node) {
490
+ return /\+\s*['"]/.test(JSON.stringify(node)) || /['"]\s*\+/.test(JSON.stringify(node));
491
+ }
492
+ convertToTemplateLiterals(node, source) {
493
+ const changes = [];
494
+ const lines = source.split('\n');
495
+ for (let i = 0; i < lines.length; i++) {
496
+ const line = lines[i];
497
+ // Find string concatenation patterns
498
+ const concatPattern = /['"]([^'"]*)['"]\s*\+\s*(\w+)\s*\+\s*['"]([^'"]*)['"]/g;
499
+ if (concatPattern.test(line)) {
500
+ const transformed = line.replace(/['"]([^'"]*)['"]\s*\+\s*(\w+)\s*\+\s*['"]([^'"]*)['"]/g, '`$1${$2}$3`');
501
+ if (line !== transformed) {
502
+ changes.push({
503
+ type: 'replace',
504
+ startLine: i + 1,
505
+ startColumn: 0,
506
+ endLine: i + 1,
507
+ endColumn: line.length,
508
+ originalText: line,
509
+ newText: transformed,
510
+ description: 'Convert string concatenation to template literal',
511
+ });
512
+ }
513
+ }
514
+ }
515
+ return {
516
+ success: changes.length > 0,
517
+ original: source,
518
+ transformed: this.applyChanges(source, changes),
519
+ changes,
520
+ warnings: [],
521
+ errors: [],
522
+ };
523
+ }
524
+ hasPromiseChains(node) {
525
+ const str = JSON.stringify(node);
526
+ return new RegExp('\\.then\\s*\\(').test(str) || new RegExp('\\.catch\\s*\\(').test(str);
527
+ }
528
+ convertToAsyncAwait(node, source) {
529
+ // Complex transformation requiring full AST manipulation
530
+ return {
531
+ success: false,
532
+ original: source,
533
+ transformed: source,
534
+ changes: [],
535
+ warnings: ['Promise to async/await conversion requires full AST transformation'],
536
+ errors: [],
537
+ };
538
+ }
539
+ hasNestedPropertyChecks(node) {
540
+ return /&&\s*[\w.]+\s*!==\s*null/.test(JSON.stringify(node)) ||
541
+ /&&\s*[\w.]+\s*!==\s*undefined/.test(JSON.stringify(node));
542
+ }
543
+ convertToOptionalChaining(node, source) {
544
+ const changes = [];
545
+ const lines = source.split('\n');
546
+ for (let i = 0; i < lines.length; i++) {
547
+ const line = lines[i];
548
+ // Pattern: obj && obj.prop && obj.prop.nested
549
+ const pattern = /(\w+)\s*&&\s*\1\.(\w+)/g;
550
+ if (pattern.test(line)) {
551
+ const transformed = line.replace(/(\w+)\s*&&\s*\1\.(\w+)/g, '$1?.$2');
552
+ if (line !== transformed) {
553
+ changes.push({
554
+ type: 'replace',
555
+ startLine: i + 1,
556
+ startColumn: 0,
557
+ endLine: i + 1,
558
+ endColumn: line.length,
559
+ originalText: line,
560
+ newText: transformed,
561
+ description: 'Convert to optional chaining',
562
+ });
563
+ }
564
+ }
565
+ }
566
+ return {
567
+ success: changes.length > 0,
568
+ original: source,
569
+ transformed: this.applyChanges(source, changes),
570
+ changes,
571
+ warnings: [],
572
+ errors: [],
573
+ };
574
+ }
575
+ hasStringConcatInLoop(node) {
576
+ return /for|while/.test(JSON.stringify(node)) && /\+\s*['"]/.test(JSON.stringify(node));
577
+ }
578
+ optimizeStringConcatenation(node, source) {
579
+ return {
580
+ success: false,
581
+ original: source,
582
+ transformed: source,
583
+ changes: [],
584
+ warnings: ['String concatenation optimization requires context analysis'],
585
+ errors: [],
586
+ };
587
+ }
588
+ canConvertToLinq(node) {
589
+ return /for\s*\([^)]+\)\s*\{/.test(JSON.stringify(node)) &&
590
+ /Add|add/.test(JSON.stringify(node));
591
+ }
592
+ convertToLinq(node, source) {
593
+ return {
594
+ success: false,
595
+ original: source,
596
+ transformed: source,
597
+ changes: [],
598
+ warnings: ['LINQ conversion requires pattern matching on specific loop types'],
599
+ errors: [],
600
+ };
601
+ }
602
+ hasPoorlyNamedVariables(node) {
603
+ const badNames = ['x', 'y', 'z', 'a', 'b', 'c', 'i', 'j', 'k', 'temp', 'tmp', 'val', 'num'];
604
+ return node.children.some(c => badNames.includes(c.metadata.name) ||
605
+ c.metadata.name?.length === 1);
606
+ }
607
+ renameVariables(node, source) {
608
+ return {
609
+ success: false,
610
+ original: source,
611
+ transformed: source,
612
+ changes: [],
613
+ warnings: ['Variable renaming requires semantic analysis to suggest meaningful names'],
614
+ errors: [],
615
+ };
616
+ }
617
+ missingTypeAnnotations(node) {
618
+ return node.children.some(c => (c.type === 'VariableDeclaration' || c.type === 'FunctionDeclaration') &&
619
+ !c.metadata.type);
620
+ }
621
+ addTypeAnnotations(node, source) {
622
+ return {
623
+ success: false,
624
+ original: source,
625
+ transformed: source,
626
+ changes: [],
627
+ warnings: ['Type annotation addition requires type inference analysis'],
628
+ errors: [],
629
+ };
630
+ }
631
+ hasUnorganizedMembers(node) {
632
+ return node.type === 'ClassDeclaration' || node.type === 'ClassDefinition';
633
+ }
634
+ reorganizeClassMembers(node, source) {
635
+ return {
636
+ success: false,
637
+ original: source,
638
+ transformed: source,
639
+ changes: [],
640
+ warnings: ['Member reorganization requires full class structure analysis'],
641
+ errors: [],
642
+ };
643
+ }
644
+ applyChanges(source, changes) {
645
+ const lines = source.split('\n');
646
+ // Sort changes by line number (descending) to avoid index shifting
647
+ changes.sort((a, b) => b.startLine - a.startLine);
648
+ for (const change of changes) {
649
+ const lineIndex = change.startLine - 1;
650
+ if (change.type === 'delete') {
651
+ lines.splice(lineIndex, 1);
652
+ }
653
+ else if (change.type === 'replace') {
654
+ lines[lineIndex] = change.newText;
655
+ }
656
+ else if (change.type === 'insert') {
657
+ lines.splice(lineIndex, 0, change.newText);
658
+ }
659
+ }
660
+ return lines.join('\n');
661
+ }
662
+ // ============================================
663
+ // BATCH OPERATIONS
664
+ // ============================================
665
+ async batchRefactor(files, operationIds, dryRun = true) {
666
+ const results = [];
667
+ let totalChanges = 0;
668
+ let successCount = 0;
669
+ for (const file of files) {
670
+ const fileResults = [];
671
+ for (const opId of operationIds) {
672
+ // Parse file (simplified - would need actual parser)
673
+ const source = fs.readFileSync(file, 'utf-8');
674
+ const mockAST = {
675
+ type: 'Program',
676
+ id: file,
677
+ location: { file, startLine: 1, startColumn: 0, endLine: source.split('\n').length, endColumn: 0, byteOffset: 0 },
678
+ children: [],
679
+ metadata: {},
680
+ };
681
+ const result = await this.applyRefactoring(file, opId, mockAST, dryRun);
682
+ fileResults.push(result);
683
+ if (result.success) {
684
+ totalChanges += result.changes.length;
685
+ successCount++;
686
+ }
687
+ }
688
+ results.push({
689
+ file,
690
+ results: fileResults,
691
+ totalChanges: fileResults.reduce((sum, r) => sum + r.changes.length, 0),
692
+ });
693
+ }
694
+ return {
695
+ files: results,
696
+ totalFiles: files.length,
697
+ successfulRefactorings: successCount,
698
+ totalChanges,
699
+ dryRun,
700
+ };
701
+ }
702
+ getAppliedRefactorings() {
703
+ return this.appliedRefactorings;
704
+ }
705
+ undoLastRefactoring() {
706
+ const last = this.appliedRefactorings.pop();
707
+ if (last) {
708
+ // Would need to track original file states
709
+ logger.info('Undo functionality requires file state tracking');
710
+ return false;
711
+ }
712
+ return false;
713
+ }
714
+ }
715
+ exports.RefactoringEngine = RefactoringEngine;
716
+ exports.default = RefactoringEngine;
717
+ //# sourceMappingURL=refactoring-engine.js.map