@defai.digital/ax-cli 3.4.5 → 3.5.2

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 (211) hide show
  1. package/LICENSE +2 -6
  2. package/README.md +91 -3
  3. package/dist/analyzers/ast/parser.d.ts +59 -0
  4. package/dist/analyzers/ast/parser.js +293 -0
  5. package/dist/analyzers/ast/parser.js.map +1 -0
  6. package/dist/analyzers/ast/types.d.ts +107 -0
  7. package/dist/analyzers/ast/types.js +7 -0
  8. package/dist/analyzers/ast/types.js.map +1 -0
  9. package/dist/analyzers/code-smells/base-smell-detector.d.ts +30 -0
  10. package/dist/analyzers/code-smells/base-smell-detector.js +44 -0
  11. package/dist/analyzers/code-smells/base-smell-detector.js.map +1 -0
  12. package/dist/analyzers/code-smells/code-smell-analyzer.d.ts +30 -0
  13. package/dist/analyzers/code-smells/code-smell-analyzer.js +167 -0
  14. package/dist/analyzers/code-smells/code-smell-analyzer.js.map +1 -0
  15. package/dist/analyzers/code-smells/detectors/data-clumps-detector.d.ts +11 -0
  16. package/dist/analyzers/code-smells/detectors/data-clumps-detector.js +66 -0
  17. package/dist/analyzers/code-smells/detectors/data-clumps-detector.js.map +1 -0
  18. package/dist/analyzers/code-smells/detectors/dead-code-detector.d.ts +11 -0
  19. package/dist/analyzers/code-smells/detectors/dead-code-detector.js +53 -0
  20. package/dist/analyzers/code-smells/detectors/dead-code-detector.js.map +1 -0
  21. package/dist/analyzers/code-smells/detectors/duplicate-code-detector.d.ts +11 -0
  22. package/dist/analyzers/code-smells/detectors/duplicate-code-detector.js +51 -0
  23. package/dist/analyzers/code-smells/detectors/duplicate-code-detector.js.map +1 -0
  24. package/dist/analyzers/code-smells/detectors/feature-envy-detector.d.ts +11 -0
  25. package/dist/analyzers/code-smells/detectors/feature-envy-detector.js +64 -0
  26. package/dist/analyzers/code-smells/detectors/feature-envy-detector.js.map +1 -0
  27. package/dist/analyzers/code-smells/detectors/inappropriate-intimacy-detector.d.ts +11 -0
  28. package/dist/analyzers/code-smells/detectors/inappropriate-intimacy-detector.js +56 -0
  29. package/dist/analyzers/code-smells/detectors/inappropriate-intimacy-detector.js.map +1 -0
  30. package/dist/analyzers/code-smells/detectors/large-class-detector.d.ts +13 -0
  31. package/dist/analyzers/code-smells/detectors/large-class-detector.js +58 -0
  32. package/dist/analyzers/code-smells/detectors/large-class-detector.js.map +1 -0
  33. package/dist/analyzers/code-smells/detectors/long-method-detector.d.ts +12 -0
  34. package/dist/analyzers/code-smells/detectors/long-method-detector.js +52 -0
  35. package/dist/analyzers/code-smells/detectors/long-method-detector.js.map +1 -0
  36. package/dist/analyzers/code-smells/detectors/long-parameter-list-detector.d.ts +12 -0
  37. package/dist/analyzers/code-smells/detectors/long-parameter-list-detector.js +50 -0
  38. package/dist/analyzers/code-smells/detectors/long-parameter-list-detector.js.map +1 -0
  39. package/dist/analyzers/code-smells/detectors/magic-numbers-detector.d.ts +12 -0
  40. package/dist/analyzers/code-smells/detectors/magic-numbers-detector.js +54 -0
  41. package/dist/analyzers/code-smells/detectors/magic-numbers-detector.js.map +1 -0
  42. package/dist/analyzers/code-smells/detectors/nested-conditionals-detector.d.ts +13 -0
  43. package/dist/analyzers/code-smells/detectors/nested-conditionals-detector.js +71 -0
  44. package/dist/analyzers/code-smells/detectors/nested-conditionals-detector.js.map +1 -0
  45. package/dist/analyzers/code-smells/index.d.ts +16 -0
  46. package/dist/analyzers/code-smells/index.js +19 -0
  47. package/dist/analyzers/code-smells/index.js.map +1 -0
  48. package/dist/analyzers/code-smells/types.d.ts +82 -0
  49. package/dist/analyzers/code-smells/types.js +30 -0
  50. package/dist/analyzers/code-smells/types.js.map +1 -0
  51. package/dist/analyzers/dependency/circular-detector.d.ts +17 -0
  52. package/dist/analyzers/dependency/circular-detector.js +71 -0
  53. package/dist/analyzers/dependency/circular-detector.js.map +1 -0
  54. package/dist/analyzers/dependency/coupling-calculator.d.ts +24 -0
  55. package/dist/analyzers/dependency/coupling-calculator.js +86 -0
  56. package/dist/analyzers/dependency/coupling-calculator.js.map +1 -0
  57. package/dist/analyzers/dependency/dependency-analyzer.d.ts +40 -0
  58. package/dist/analyzers/dependency/dependency-analyzer.js +214 -0
  59. package/dist/analyzers/dependency/dependency-analyzer.js.map +1 -0
  60. package/dist/analyzers/dependency/dependency-graph.d.ts +57 -0
  61. package/dist/analyzers/dependency/dependency-graph.js +186 -0
  62. package/dist/analyzers/dependency/dependency-graph.js.map +1 -0
  63. package/dist/analyzers/dependency/index.d.ts +8 -0
  64. package/dist/analyzers/dependency/index.js +8 -0
  65. package/dist/analyzers/dependency/index.js.map +1 -0
  66. package/dist/analyzers/dependency/types.d.ts +105 -0
  67. package/dist/analyzers/dependency/types.js +5 -0
  68. package/dist/analyzers/dependency/types.js.map +1 -0
  69. package/dist/analyzers/git/churn-calculator.d.ts +34 -0
  70. package/dist/analyzers/git/churn-calculator.js +214 -0
  71. package/dist/analyzers/git/churn-calculator.js.map +1 -0
  72. package/dist/analyzers/git/git-analyzer.d.ts +19 -0
  73. package/dist/analyzers/git/git-analyzer.js +71 -0
  74. package/dist/analyzers/git/git-analyzer.js.map +1 -0
  75. package/dist/analyzers/git/hotspot-detector.d.ts +34 -0
  76. package/dist/analyzers/git/hotspot-detector.js +170 -0
  77. package/dist/analyzers/git/hotspot-detector.js.map +1 -0
  78. package/dist/analyzers/git/index.d.ts +7 -0
  79. package/dist/analyzers/git/index.js +7 -0
  80. package/dist/analyzers/git/index.js.map +1 -0
  81. package/dist/analyzers/git/types.d.ts +88 -0
  82. package/dist/analyzers/git/types.js +5 -0
  83. package/dist/analyzers/git/types.js.map +1 -0
  84. package/dist/analyzers/metrics/halstead-calculator.d.ts +30 -0
  85. package/dist/analyzers/metrics/halstead-calculator.js +150 -0
  86. package/dist/analyzers/metrics/halstead-calculator.js.map +1 -0
  87. package/dist/analyzers/metrics/index.d.ts +9 -0
  88. package/dist/analyzers/metrics/index.js +9 -0
  89. package/dist/analyzers/metrics/index.js.map +1 -0
  90. package/dist/analyzers/metrics/maintainability-calculator.d.ts +17 -0
  91. package/dist/analyzers/metrics/maintainability-calculator.js +46 -0
  92. package/dist/analyzers/metrics/maintainability-calculator.js.map +1 -0
  93. package/dist/analyzers/metrics/metrics-analyzer.d.ts +32 -0
  94. package/dist/analyzers/metrics/metrics-analyzer.js +140 -0
  95. package/dist/analyzers/metrics/metrics-analyzer.js.map +1 -0
  96. package/dist/analyzers/metrics/types.d.ts +67 -0
  97. package/dist/analyzers/metrics/types.js +5 -0
  98. package/dist/analyzers/metrics/types.js.map +1 -0
  99. package/dist/analyzers/security/base-detector.d.ts +58 -0
  100. package/dist/analyzers/security/base-detector.js +104 -0
  101. package/dist/analyzers/security/base-detector.js.map +1 -0
  102. package/dist/analyzers/security/detectors/command-injection-detector.d.ts +12 -0
  103. package/dist/analyzers/security/detectors/command-injection-detector.js +84 -0
  104. package/dist/analyzers/security/detectors/command-injection-detector.js.map +1 -0
  105. package/dist/analyzers/security/detectors/hardcoded-secrets-detector.d.ts +16 -0
  106. package/dist/analyzers/security/detectors/hardcoded-secrets-detector.js +140 -0
  107. package/dist/analyzers/security/detectors/hardcoded-secrets-detector.js.map +1 -0
  108. package/dist/analyzers/security/detectors/insecure-deserialization-detector.d.ts +12 -0
  109. package/dist/analyzers/security/detectors/insecure-deserialization-detector.js +109 -0
  110. package/dist/analyzers/security/detectors/insecure-deserialization-detector.js.map +1 -0
  111. package/dist/analyzers/security/detectors/insecure-random-detector.d.ts +12 -0
  112. package/dist/analyzers/security/detectors/insecure-random-detector.js +61 -0
  113. package/dist/analyzers/security/detectors/insecure-random-detector.js.map +1 -0
  114. package/dist/analyzers/security/detectors/path-traversal-detector.d.ts +12 -0
  115. package/dist/analyzers/security/detectors/path-traversal-detector.js +82 -0
  116. package/dist/analyzers/security/detectors/path-traversal-detector.js.map +1 -0
  117. package/dist/analyzers/security/detectors/sql-injection-detector.d.ts +12 -0
  118. package/dist/analyzers/security/detectors/sql-injection-detector.js +88 -0
  119. package/dist/analyzers/security/detectors/sql-injection-detector.js.map +1 -0
  120. package/dist/analyzers/security/detectors/weak-crypto-detector.d.ts +12 -0
  121. package/dist/analyzers/security/detectors/weak-crypto-detector.js +104 -0
  122. package/dist/analyzers/security/detectors/weak-crypto-detector.js.map +1 -0
  123. package/dist/analyzers/security/detectors/xss-detector.d.ts +12 -0
  124. package/dist/analyzers/security/detectors/xss-detector.js +90 -0
  125. package/dist/analyzers/security/detectors/xss-detector.js.map +1 -0
  126. package/dist/analyzers/security/index.d.ts +16 -0
  127. package/dist/analyzers/security/index.js +18 -0
  128. package/dist/analyzers/security/index.js.map +1 -0
  129. package/dist/analyzers/security/security-analyzer.d.ts +38 -0
  130. package/dist/analyzers/security/security-analyzer.js +215 -0
  131. package/dist/analyzers/security/security-analyzer.js.map +1 -0
  132. package/dist/analyzers/security/types.d.ts +95 -0
  133. package/dist/analyzers/security/types.js +7 -0
  134. package/dist/analyzers/security/types.js.map +1 -0
  135. package/dist/commands/memory.js +1 -1
  136. package/dist/commands/memory.js.map +1 -1
  137. package/dist/commands/setup.js +6 -1
  138. package/dist/commands/setup.js.map +1 -1
  139. package/dist/hooks/use-enhanced-input.d.ts +0 -1
  140. package/dist/hooks/use-enhanced-input.js.map +1 -1
  141. package/dist/mcp/health.js +4 -2
  142. package/dist/mcp/health.js.map +1 -1
  143. package/dist/mcp/validation.js +12 -6
  144. package/dist/mcp/validation.js.map +1 -1
  145. package/dist/tools/analysis-tools.d.ts +73 -0
  146. package/dist/tools/analysis-tools.js +422 -0
  147. package/dist/tools/analysis-tools.js.map +1 -0
  148. package/dist/tools/bash.js +2 -1
  149. package/dist/tools/bash.js.map +1 -1
  150. package/dist/ui/components/chat-history.js +1 -1
  151. package/dist/ui/components/chat-history.js.map +1 -1
  152. package/dist/ui/components/chat-interface.js +3 -2
  153. package/dist/ui/components/chat-interface.js.map +1 -1
  154. package/dist/ui/components/confirmation-dialog.js +1 -1
  155. package/dist/ui/components/confirmation-dialog.js.map +1 -1
  156. package/dist/ui/components/welcome-panel.js +1 -1
  157. package/dist/ui/components/welcome-panel.js.map +1 -1
  158. package/dist/ui/hooks/use-chat-reducer.d.ts +61 -0
  159. package/dist/ui/hooks/use-chat-reducer.js +118 -0
  160. package/dist/ui/hooks/use-chat-reducer.js.map +1 -0
  161. package/dist/ui/hooks/use-enhanced-input.d.ts +40 -0
  162. package/dist/ui/hooks/use-enhanced-input.js +254 -0
  163. package/dist/ui/hooks/use-enhanced-input.js.map +1 -0
  164. package/dist/ui/hooks/use-input-handler.d.ts +46 -0
  165. package/dist/ui/hooks/use-input-handler.js +1434 -0
  166. package/dist/ui/hooks/use-input-handler.js.map +1 -0
  167. package/dist/ui/hooks/use-input-history.d.ts +9 -0
  168. package/dist/ui/hooks/use-input-history.js +117 -0
  169. package/dist/ui/hooks/use-input-history.js.map +1 -0
  170. package/dist/utils/config-loader.js +3 -3
  171. package/dist/utils/config-loader.js.map +1 -1
  172. package/dist/utils/parallel-analyzer.js +7 -11
  173. package/dist/utils/parallel-analyzer.js.map +1 -1
  174. package/dist/utils/paste-collapse.d.ts +46 -0
  175. package/dist/utils/paste-collapse.js +77 -0
  176. package/dist/utils/paste-collapse.js.map +1 -0
  177. package/dist/utils/settings-manager.js +16 -2
  178. package/dist/utils/settings-manager.js.map +1 -1
  179. package/dist/utils/streaming-analyzer.js +9 -21
  180. package/dist/utils/streaming-analyzer.js.map +1 -1
  181. package/package.json +5 -5
  182. package/vitest.config.ts +1 -0
  183. package/dist/commands/weather.d.ts +0 -8
  184. package/dist/commands/weather.js +0 -160
  185. package/dist/commands/weather.js.map +0 -1
  186. package/dist/grok/client.d.ts +0 -144
  187. package/dist/grok/client.js +0 -237
  188. package/dist/grok/client.js.map +0 -1
  189. package/dist/grok/tools.d.ts +0 -8
  190. package/dist/grok/tools.js +0 -318
  191. package/dist/grok/tools.js.map +0 -1
  192. package/dist/grok/types.d.ts +0 -291
  193. package/dist/grok/types.js +0 -127
  194. package/dist/grok/types.js.map +0 -1
  195. package/dist/tools/morph-editor.d.ts +0 -36
  196. package/dist/tools/morph-editor.js +0 -308
  197. package/dist/tools/morph-editor.js.map +0 -1
  198. package/dist/ui/components/session-recovery.d.ts +0 -12
  199. package/dist/ui/components/session-recovery.js +0 -93
  200. package/dist/ui/components/session-recovery.js.map +0 -1
  201. package/dist/utils/model-config.d.ts +0 -28
  202. package/dist/utils/model-config.js +0 -43
  203. package/dist/utils/model-config.js.map +0 -1
  204. package/dist/utils/tool-helpers.d.ts +0 -25
  205. package/dist/utils/tool-helpers.js +0 -79
  206. package/dist/utils/tool-helpers.js.map +0 -1
  207. /package/{automatosx.config.json → ax.config.json} +0 -0
  208. /package/{config → config-defaults}/messages.yaml +0 -0
  209. /package/{config → config-defaults}/models.yaml +0 -0
  210. /package/{config → config-defaults}/prompts.yaml +0 -0
  211. /package/{config → config-defaults}/settings.yaml +0 -0
package/LICENSE CHANGED
@@ -1,12 +1,8 @@
1
1
  MIT License
2
2
 
3
- This software is based on grok-cli (MIT License)
4
- Copyright (c) 2023 GrokCLI Authors https://github.com/superagent-ai/grok-cli
5
-
6
- Modifications Copyright (c) 2025 DEFAI Private Limited
3
+ Copyright (c) 2025 DEFAI Private Limited
7
4
  Licensed under the MIT License https://github.com/defai-digital/ax-cli
8
5
 
9
-
10
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
11
7
  of this software and associated documentation files (the "Software"), to deal
12
8
  in the Software without restriction, including without limitation the rights
@@ -14,7 +10,7 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
10
  copies of the Software, and to permit persons to whom the Software is
15
11
  furnished to do so, subject to the following conditions:
16
12
 
17
- The above copyright notice and this permission statement shall be included in all
13
+ The above copyright notice and this permission notice shall be included in all
18
14
  copies or substantial portions of the Software.
19
15
 
20
16
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # AX CLI - Enterprise-Class GLM AI CLI
2
2
 
3
- [![Tests](https://img.shields.io/badge/tests-562%20passing-brightgreen?style=flat-square)](https://github.com/defai-digital/ax-cli/actions/workflows/test.yml)
4
- [![Coverage](https://img.shields.io/badge/coverage-98.29%25-brightgreen?style=flat-square)](https://github.com/defai-digital/ax-cli)
5
3
  [![npm](https://img.shields.io/npm/dt/@defai.digital/ax-cli?style=flat-square&logo=npm&label=downloads)](https://npm-stat.com/charts.html?package=%40defai.digital%2Fax-cli)
6
- [![Node.js Version](https://img.shields.io/badge/node-%3E%3D24.0.0-blue?style=flat-square)](https://nodejs.org/)
4
+ [![Tests](https://img.shields.io/badge/tests-1017%20passing-brightgreen?style=flat-square)](https://github.com/defai-digital/ax-cli/actions/workflows/test.yml)
5
+ [![Coverage](https://img.shields.io/badge/coverage-98%2B%25-brightgreen?style=flat-square)](https://github.com/defai-digital/ax-cli)
7
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.9%2B-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)
7
+ [![Node.js Version](https://img.shields.io/badge/node-%3E%3D24.0.0-blue?style=flat-square)](https://nodejs.org/)
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)
9
9
  [![macOS](https://img.shields.io/badge/macOS-26-blue?style=flat-square&logo=apple)](https://www.apple.com/macos/)
10
10
  [![Windows](https://img.shields.io/badge/Windows-11-blue?style=flat-square&logo=windows)](https://www.microsoft.com/windows/)
@@ -82,6 +82,13 @@ ax-cli
82
82
  - Support for technical docs, code examples, news, and general queries
83
83
  - Configurable search depth and freshness filters
84
84
  - **🔄 Auto-Update**: Built-in update checker and installer
85
+ - **📊 Advanced Code Analysis** (NEW in v2.4.0): Professional-grade static analysis tools
86
+ - **Dependency Analyzer**: Detect circular dependencies, calculate coupling metrics, identify orphan and hub files
87
+ - **Code Smell Detector**: Find 10+ anti-patterns (long methods, large classes, duplicates, dead code, etc.)
88
+ - **Hotspot Analyzer**: Identify frequently changing, complex code using git history analysis
89
+ - **Metrics Calculator**: Cyclomatic complexity, Halstead metrics, Maintainability Index (MI)
90
+ - **Security Scanner**: Detect SQL injection, XSS, path traversal, hardcoded secrets, and more
91
+ - **[Complete Guide](docs/analysis-tools.md)** and **[API Documentation](docs/api/analyzers.md)**
85
92
 
86
93
  ### Max Tokens Configuration
87
94
 
@@ -350,6 +357,60 @@ ax-cli usage reset
350
357
 
351
358
  [CLI Reference →](docs/cli-reference.md) | [Usage Guide →](docs/usage.md)
352
359
 
360
+ ## 📋 Working with Large Content
361
+
362
+ When working with large amounts of text (logs, code files, documentation), use **file-based workflows** instead of pasting directly into the terminal.
363
+
364
+ ### ⚠️ Terminal Paste Limitations
365
+
366
+ **Avoid pasting large content directly** into the interactive terminal:
367
+
368
+ - ❌ **DON'T**: Paste large code files, logs, or documents (>2000 characters)
369
+ - ⚠️ Some terminals may have paste limitations
370
+ - ⚠️ Character counter shows visual warning: Gray (0-999) → Cyan (1000-1599) → Yellow (1600-1999) → **Red (2000+)**
371
+
372
+ ### ✅ Recommended Approaches
373
+
374
+ **Option 1: File Reference (Interactive Mode)**
375
+ ```bash
376
+ # Save your content to a file first
377
+ cat > context.txt
378
+ # (paste content, then Ctrl+D)
379
+
380
+ # Then use memory commands
381
+ ax-cli
382
+ > /memory add context.txt
383
+ > analyze the content I just added
384
+ ```
385
+
386
+ **Option 2: Headless Mode with File Input**
387
+ ```bash
388
+ # Direct file processing
389
+ ax-cli --prompt "analyze this: $(cat large-file.txt)"
390
+
391
+ # Or use the --file flag
392
+ ax-cli --file path/to/code.ts --prompt "review this code"
393
+ ```
394
+
395
+ **Option 3: Use `/memory` Commands**
396
+ ```bash
397
+ # In interactive mode
398
+ > /memory add src/
399
+ > /memory add logs/error.log
400
+ > analyze the errors in the log file
401
+ ```
402
+
403
+ ### Character Count Guide
404
+
405
+ The interactive terminal shows a character counter `[count/2000]` with color-coded warnings:
406
+
407
+ | Color | Range | Recommendation |
408
+ |-------|-------|----------------|
409
+ | **Gray** | 0-999 | ✅ Optimal length |
410
+ | **Cyan** | 1000-1599 | ⚠️ Getting long |
411
+ | **Yellow** | 1600-1999 | ⚠️ Consider using files |
412
+ | **Red** | 2000+ | ❌ Use file-based workflow |
413
+
353
414
  ## 🏥 Health Check & Diagnostics (NEW)
354
415
 
355
416
  Run comprehensive diagnostics to verify your AX CLI configuration:
@@ -679,6 +740,33 @@ AX CLI implements enterprise-grade architecture with:
679
740
  - [Development](docs/development.md) - Development and contribution guide
680
741
  - [Troubleshooting](docs/troubleshooting.md) - Common issues and solutions
681
742
 
743
+ ## 📋 Changelog
744
+
745
+ ### v3.5.2 (2025-11-22)
746
+
747
+ **Bug Fixes - Resource Leak Prevention:**
748
+ - Fixed uncleaned nested timeout in bash tool that held process references after exit
749
+ - Fixed uncleaned timeout in MCP URL validation causing 3-second memory leaks
750
+ - Added `.unref()` to background cleanup timers to prevent GC blocking
751
+ - Added try-finally blocks for guaranteed timeout cleanup in error scenarios
752
+
753
+ **Bug Fixes - Platform Compatibility:**
754
+ - Fixed Windows home directory bug in command history (used `os.homedir()` instead of `"~"` fallback)
755
+
756
+ **Code Quality:**
757
+ - Comprehensive resource leak analysis across 78+ potential issues
758
+ - Improved timeout cleanup patterns following Node.js best practices
759
+ - Enhanced memory management for better garbage collection
760
+
761
+ ### v3.5.0
762
+
763
+ **Features:**
764
+ - Multi-phase task planner with automatic complexity detection
765
+ - Enhanced MCP integration with production-ready templates
766
+ - Project memory system with intelligent context caching
767
+ - Web search capabilities with Tavily AI and Brave Search
768
+ - Advanced code analysis tools (dependency, security, metrics)
769
+
682
770
  ## 📄 License
683
771
 
684
772
  MIT License - see [LICENSE](LICENSE) for details
@@ -0,0 +1,59 @@
1
+ /**
2
+ * AST Parser
3
+ *
4
+ * Provides TypeScript/JavaScript AST parsing using ts-morph
5
+ */
6
+ import { SourceFile } from 'ts-morph';
7
+ import type { FileASTInfo } from './types.js';
8
+ export declare class ASTParser {
9
+ private project;
10
+ constructor();
11
+ /**
12
+ * Parse a TypeScript/JavaScript file
13
+ */
14
+ parseFile(filePath: string): FileASTInfo;
15
+ /**
16
+ * Parse file content directly
17
+ */
18
+ parseContent(content: string, filePath?: string): FileASTInfo;
19
+ /**
20
+ * Extract all functions from source file
21
+ */
22
+ private extractFunctions;
23
+ /**
24
+ * Extract all classes from source file
25
+ */
26
+ private extractClasses;
27
+ /**
28
+ * Extract methods from a class
29
+ */
30
+ private extractMethods;
31
+ /**
32
+ * Extract properties from a class
33
+ */
34
+ private extractProperties;
35
+ /**
36
+ * Extract parameters from a function or method
37
+ */
38
+ private extractParameters;
39
+ /**
40
+ * Extract imports from source file
41
+ */
42
+ private extractImports;
43
+ /**
44
+ * Extract exports from source file
45
+ */
46
+ private extractExports;
47
+ /**
48
+ * Calculate cyclomatic complexity (simplified)
49
+ */
50
+ private calculateCyclomaticComplexity;
51
+ /**
52
+ * Get raw source file for advanced operations
53
+ */
54
+ getSourceFile(filePath: string): SourceFile;
55
+ /**
56
+ * Clear project cache
57
+ */
58
+ clear(): void;
59
+ }
@@ -0,0 +1,293 @@
1
+ /**
2
+ * AST Parser
3
+ *
4
+ * Provides TypeScript/JavaScript AST parsing using ts-morph
5
+ */
6
+ import { Project, ScriptTarget, ModuleKind, SyntaxKind } from 'ts-morph';
7
+ export class ASTParser {
8
+ project;
9
+ constructor() {
10
+ this.project = new Project({
11
+ compilerOptions: {
12
+ target: ScriptTarget.Latest,
13
+ module: ModuleKind.CommonJS,
14
+ allowJs: true,
15
+ skipLibCheck: true,
16
+ },
17
+ skipAddingFilesFromTsConfig: true,
18
+ });
19
+ }
20
+ /**
21
+ * Parse a TypeScript/JavaScript file
22
+ */
23
+ parseFile(filePath) {
24
+ const sourceFile = this.project.addSourceFileAtPath(filePath);
25
+ try {
26
+ const functions = this.extractFunctions(sourceFile);
27
+ const classes = this.extractClasses(sourceFile);
28
+ const imports = this.extractImports(sourceFile);
29
+ const exports = this.extractExports(sourceFile);
30
+ return Object.freeze({
31
+ filePath,
32
+ functions: Object.freeze(functions),
33
+ classes: Object.freeze(classes),
34
+ imports: Object.freeze(imports),
35
+ exports: Object.freeze(exports),
36
+ totalLines: sourceFile.getEndLineNumber(),
37
+ });
38
+ }
39
+ finally {
40
+ // Clean up to prevent memory leaks
41
+ this.project.removeSourceFile(sourceFile);
42
+ }
43
+ }
44
+ /**
45
+ * Parse file content directly
46
+ */
47
+ parseContent(content, filePath = 'temp.ts') {
48
+ const sourceFile = this.project.createSourceFile(filePath, content, { overwrite: true });
49
+ try {
50
+ const functions = this.extractFunctions(sourceFile);
51
+ const classes = this.extractClasses(sourceFile);
52
+ const imports = this.extractImports(sourceFile);
53
+ const exports = this.extractExports(sourceFile);
54
+ return Object.freeze({
55
+ filePath,
56
+ functions: Object.freeze(functions),
57
+ classes: Object.freeze(classes),
58
+ imports: Object.freeze(imports),
59
+ exports: Object.freeze(exports),
60
+ totalLines: sourceFile.getEndLineNumber(),
61
+ });
62
+ }
63
+ finally {
64
+ this.project.removeSourceFile(sourceFile);
65
+ }
66
+ }
67
+ /**
68
+ * Extract all functions from source file
69
+ */
70
+ extractFunctions(sourceFile) {
71
+ const functions = [];
72
+ sourceFile.getFunctions().forEach(func => {
73
+ const name = func.getName() || '<anonymous>';
74
+ const parameters = this.extractParameters(func);
75
+ const startLine = func.getStartLineNumber();
76
+ const endLine = func.getEndLineNumber();
77
+ functions.push(Object.freeze({
78
+ name,
79
+ parameters: Object.freeze(parameters),
80
+ returnType: func.getReturnType().getText(),
81
+ startLine,
82
+ endLine,
83
+ complexity: this.calculateCyclomaticComplexity(func.getBody()?.getText() || ''),
84
+ length: endLine - startLine + 1,
85
+ isAsync: func.isAsync(),
86
+ isExported: func.isExported(),
87
+ }));
88
+ });
89
+ return functions;
90
+ }
91
+ /**
92
+ * Extract all classes from source file
93
+ */
94
+ extractClasses(sourceFile) {
95
+ const classes = [];
96
+ sourceFile.getClasses().forEach(cls => {
97
+ const name = cls.getName() || '<anonymous>';
98
+ const methods = this.extractMethods(cls);
99
+ const properties = this.extractProperties(cls);
100
+ const startLine = cls.getStartLineNumber();
101
+ const endLine = cls.getEndLineNumber();
102
+ classes.push(Object.freeze({
103
+ name,
104
+ methods: Object.freeze(methods),
105
+ properties: Object.freeze(properties),
106
+ startLine,
107
+ endLine,
108
+ length: endLine - startLine + 1,
109
+ isExported: cls.isExported(),
110
+ extendsClass: cls.getExtends()?.getText(),
111
+ implementsInterfaces: Object.freeze(cls.getImplements().map(i => i.getText())),
112
+ }));
113
+ });
114
+ return classes;
115
+ }
116
+ /**
117
+ * Extract methods from a class
118
+ */
119
+ extractMethods(cls) {
120
+ const methods = [];
121
+ cls.getMethods().forEach((method) => {
122
+ const name = method.getName();
123
+ const parameters = this.extractParameters(method);
124
+ const startLine = method.getStartLineNumber();
125
+ const endLine = method.getEndLineNumber();
126
+ // Determine visibility
127
+ let visibility = 'public';
128
+ if (method.hasModifier(SyntaxKind.PrivateKeyword)) {
129
+ visibility = 'private';
130
+ }
131
+ else if (method.hasModifier(SyntaxKind.ProtectedKeyword)) {
132
+ visibility = 'protected';
133
+ }
134
+ methods.push(Object.freeze({
135
+ name,
136
+ parameters: Object.freeze(parameters),
137
+ returnType: method.getReturnType().getText(),
138
+ visibility,
139
+ isStatic: method.isStatic(),
140
+ isAsync: method.isAsync(),
141
+ complexity: this.calculateCyclomaticComplexity(method.getBody()?.getText() || ''),
142
+ length: endLine - startLine + 1,
143
+ startLine,
144
+ endLine,
145
+ }));
146
+ });
147
+ return methods;
148
+ }
149
+ /**
150
+ * Extract properties from a class
151
+ */
152
+ extractProperties(cls) {
153
+ const properties = [];
154
+ cls.getProperties().forEach((prop) => {
155
+ const name = prop.getName();
156
+ // Determine visibility
157
+ let visibility = 'public';
158
+ if (prop.hasModifier(SyntaxKind.PrivateKeyword)) {
159
+ visibility = 'private';
160
+ }
161
+ else if (prop.hasModifier(SyntaxKind.ProtectedKeyword)) {
162
+ visibility = 'protected';
163
+ }
164
+ properties.push(Object.freeze({
165
+ name,
166
+ type: prop.getType().getText(),
167
+ visibility,
168
+ isReadonly: prop.isReadonly(),
169
+ isStatic: prop.isStatic(),
170
+ hasInitializer: prop.hasInitializer(),
171
+ }));
172
+ });
173
+ return properties;
174
+ }
175
+ /**
176
+ * Extract parameters from a function or method
177
+ */
178
+ extractParameters(func) {
179
+ const parameters = [];
180
+ func.getParameters().forEach((param) => {
181
+ parameters.push(Object.freeze({
182
+ name: param.getName(),
183
+ type: param.getType().getText(),
184
+ isOptional: param.isOptional(),
185
+ hasDefault: param.hasInitializer(),
186
+ }));
187
+ });
188
+ return parameters;
189
+ }
190
+ /**
191
+ * Extract imports from source file
192
+ */
193
+ extractImports(sourceFile) {
194
+ const imports = [];
195
+ sourceFile.getImportDeclarations().forEach(imp => {
196
+ const moduleSpecifier = imp.getModuleSpecifierValue();
197
+ const namedImports = imp.getNamedImports().map(n => n.getName());
198
+ const defaultImport = imp.getDefaultImport()?.getText();
199
+ const namespaceImport = imp.getNamespaceImport()?.getText();
200
+ // Determine if external (starts with letter, not './' or '../')
201
+ const isExternal = !moduleSpecifier.startsWith('.') && !moduleSpecifier.startsWith('/');
202
+ // Check if type-only import
203
+ const isTypeOnly = imp.isTypeOnly();
204
+ imports.push(Object.freeze({
205
+ moduleSpecifier,
206
+ namedImports: Object.freeze(namedImports),
207
+ defaultImport,
208
+ namespaceImport,
209
+ isExternal,
210
+ isTypeOnly,
211
+ }));
212
+ });
213
+ return imports;
214
+ }
215
+ /**
216
+ * Extract exports from source file
217
+ */
218
+ extractExports(sourceFile) {
219
+ const exports = [];
220
+ // Named exports
221
+ sourceFile.getExportDeclarations().forEach(exp => {
222
+ exp.getNamedExports().forEach(named => {
223
+ exports.push(Object.freeze({
224
+ name: named.getName(),
225
+ isDefault: false,
226
+ type: 'variable',
227
+ }));
228
+ });
229
+ });
230
+ // Exported functions
231
+ sourceFile.getFunctions().forEach(func => {
232
+ if (func.isExported()) {
233
+ exports.push(Object.freeze({
234
+ name: func.getName() || '<anonymous>',
235
+ isDefault: func.isDefaultExport(),
236
+ type: 'function',
237
+ }));
238
+ }
239
+ });
240
+ // Exported classes
241
+ sourceFile.getClasses().forEach(cls => {
242
+ if (cls.isExported()) {
243
+ exports.push(Object.freeze({
244
+ name: cls.getName() || '<anonymous>',
245
+ isDefault: cls.isDefaultExport(),
246
+ type: 'class',
247
+ }));
248
+ }
249
+ });
250
+ return exports;
251
+ }
252
+ /**
253
+ * Calculate cyclomatic complexity (simplified)
254
+ */
255
+ calculateCyclomaticComplexity(code) {
256
+ let complexity = 1;
257
+ // Count decision points
258
+ const patterns = [
259
+ /\bif\b/g,
260
+ /\belse\s+if\b/g,
261
+ /\bfor\b/g,
262
+ /\bwhile\b/g,
263
+ /\bcase\b/g,
264
+ /\bcatch\b/g,
265
+ /&&/g,
266
+ /\|\|/g,
267
+ /\?/g,
268
+ ];
269
+ for (const pattern of patterns) {
270
+ const matches = code.match(pattern);
271
+ if (matches) {
272
+ complexity += matches.length;
273
+ }
274
+ }
275
+ return complexity;
276
+ }
277
+ /**
278
+ * Get raw source file for advanced operations
279
+ */
280
+ getSourceFile(filePath) {
281
+ return this.project.addSourceFileAtPath(filePath);
282
+ }
283
+ /**
284
+ * Clear project cache
285
+ */
286
+ clear() {
287
+ const sourceFiles = this.project.getSourceFiles();
288
+ for (const sourceFile of sourceFiles) {
289
+ this.project.removeSourceFile(sourceFile);
290
+ }
291
+ }
292
+ }
293
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../src/analyzers/ast/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * AST Parser Types
3
+ *
4
+ * Type definitions for AST-based analysis
5
+ */
6
+ import type { SourceFile, FunctionDeclaration, ClassDeclaration, MethodDeclaration, ImportDeclaration, ExportDeclaration } from 'ts-morph';
7
+ /**
8
+ * Function information extracted from AST
9
+ */
10
+ export interface FunctionInfo {
11
+ readonly name: string;
12
+ readonly parameters: ReadonlyArray<ParameterInfo>;
13
+ readonly returnType?: string;
14
+ readonly startLine: number;
15
+ readonly endLine: number;
16
+ readonly complexity: number;
17
+ readonly length: number;
18
+ readonly isAsync: boolean;
19
+ readonly isExported: boolean;
20
+ }
21
+ /**
22
+ * Parameter information
23
+ */
24
+ export interface ParameterInfo {
25
+ readonly name: string;
26
+ readonly type?: string;
27
+ readonly isOptional: boolean;
28
+ readonly hasDefault: boolean;
29
+ }
30
+ /**
31
+ * Class information extracted from AST
32
+ */
33
+ export interface ClassInfo {
34
+ readonly name: string;
35
+ readonly methods: ReadonlyArray<MethodInfo>;
36
+ readonly properties: ReadonlyArray<PropertyInfo>;
37
+ readonly startLine: number;
38
+ readonly endLine: number;
39
+ readonly length: number;
40
+ readonly isExported: boolean;
41
+ readonly extendsClass?: string;
42
+ readonly implementsInterfaces: ReadonlyArray<string>;
43
+ }
44
+ /**
45
+ * Method information
46
+ */
47
+ export interface MethodInfo {
48
+ readonly name: string;
49
+ readonly parameters: ReadonlyArray<ParameterInfo>;
50
+ readonly returnType?: string;
51
+ readonly visibility: 'public' | 'private' | 'protected';
52
+ readonly isStatic: boolean;
53
+ readonly isAsync: boolean;
54
+ readonly complexity: number;
55
+ readonly length: number;
56
+ readonly startLine: number;
57
+ readonly endLine: number;
58
+ }
59
+ /**
60
+ * Property information
61
+ */
62
+ export interface PropertyInfo {
63
+ readonly name: string;
64
+ readonly type?: string;
65
+ readonly visibility: 'public' | 'private' | 'protected';
66
+ readonly isReadonly: boolean;
67
+ readonly isStatic: boolean;
68
+ readonly hasInitializer: boolean;
69
+ }
70
+ /**
71
+ * Import information
72
+ */
73
+ export interface ImportInfo {
74
+ readonly moduleSpecifier: string;
75
+ readonly namedImports: ReadonlyArray<string>;
76
+ readonly defaultImport?: string;
77
+ readonly namespaceImport?: string;
78
+ readonly isExternal: boolean;
79
+ readonly isTypeOnly: boolean;
80
+ }
81
+ /**
82
+ * Export information
83
+ */
84
+ export interface ExportInfo {
85
+ readonly name: string;
86
+ readonly isDefault: boolean;
87
+ readonly type: 'function' | 'class' | 'variable' | 'type';
88
+ }
89
+ /**
90
+ * File AST information
91
+ */
92
+ export interface FileASTInfo {
93
+ readonly filePath: string;
94
+ readonly functions: ReadonlyArray<FunctionInfo>;
95
+ readonly classes: ReadonlyArray<ClassInfo>;
96
+ readonly imports: ReadonlyArray<ImportInfo>;
97
+ readonly exports: ReadonlyArray<ExportInfo>;
98
+ readonly totalLines: number;
99
+ }
100
+ /**
101
+ * AST node visitor callback
102
+ */
103
+ export type NodeVisitor<T> = (node: T) => void | boolean;
104
+ /**
105
+ * Re-export ts-morph types for convenience
106
+ */
107
+ export type { SourceFile, FunctionDeclaration, ClassDeclaration, MethodDeclaration, ImportDeclaration, ExportDeclaration };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * AST Parser Types
3
+ *
4
+ * Type definitions for AST-based analysis
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/analyzers/ast/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Base Smell Detector
3
+ *
4
+ * Abstract base class for all smell detectors
5
+ */
6
+ import { ASTParser } from '../ast/parser.js';
7
+ import type { SmellDetector, CodeSmell, SmellType, DetectorConfig } from './types.js';
8
+ import { SmellSeverity } from './types.js';
9
+ export declare abstract class BaseSmellDetector implements SmellDetector {
10
+ readonly type: SmellType;
11
+ readonly config: DetectorConfig;
12
+ protected astParser: ASTParser;
13
+ constructor(type: SmellType, config: DetectorConfig);
14
+ /**
15
+ * Detect smells in a file
16
+ */
17
+ abstract detect(filePath: string): Promise<CodeSmell[]>;
18
+ /**
19
+ * Check if detector is enabled
20
+ */
21
+ protected isEnabled(): boolean;
22
+ /**
23
+ * Get threshold value
24
+ */
25
+ protected getThreshold(key: string, defaultValue: number): number;
26
+ /**
27
+ * Create a code smell object
28
+ */
29
+ protected createSmell(filePath: string, startLine: number, endLine: number, message: string, suggestion: string, severity: SmellSeverity, metadata?: Record<string, unknown>): CodeSmell;
30
+ }