agent-ide 0.1.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 (436) hide show
  1. package/README.md +678 -0
  2. package/bin/agent-ide.js +19 -0
  3. package/bin/mcp-server.js +20 -0
  4. package/dist/application/events/event-bus.d.ts +107 -0
  5. package/dist/application/events/event-bus.d.ts.map +1 -0
  6. package/dist/application/events/event-bus.js +364 -0
  7. package/dist/application/events/event-bus.js.map +1 -0
  8. package/dist/application/events/event-types.d.ts +195 -0
  9. package/dist/application/events/event-types.d.ts.map +1 -0
  10. package/dist/application/events/event-types.js +36 -0
  11. package/dist/application/events/event-types.js.map +1 -0
  12. package/dist/application/events/index.d.ts +6 -0
  13. package/dist/application/events/index.d.ts.map +1 -0
  14. package/dist/application/events/index.js +6 -0
  15. package/dist/application/events/index.js.map +1 -0
  16. package/dist/application/index.d.ts +85 -0
  17. package/dist/application/index.d.ts.map +1 -0
  18. package/dist/application/index.js +138 -0
  19. package/dist/application/index.js.map +1 -0
  20. package/dist/application/services/cache-coordinator.service.d.ts +69 -0
  21. package/dist/application/services/cache-coordinator.service.d.ts.map +1 -0
  22. package/dist/application/services/cache-coordinator.service.js +251 -0
  23. package/dist/application/services/cache-coordinator.service.js.map +1 -0
  24. package/dist/application/services/error-handler.service.d.ts +56 -0
  25. package/dist/application/services/error-handler.service.d.ts.map +1 -0
  26. package/dist/application/services/error-handler.service.js +273 -0
  27. package/dist/application/services/error-handler.service.js.map +1 -0
  28. package/dist/application/services/index.d.ts +8 -0
  29. package/dist/application/services/index.d.ts.map +1 -0
  30. package/dist/application/services/index.js +8 -0
  31. package/dist/application/services/index.js.map +1 -0
  32. package/dist/application/services/module-coordinator.service.d.ts +70 -0
  33. package/dist/application/services/module-coordinator.service.d.ts.map +1 -0
  34. package/dist/application/services/module-coordinator.service.js +418 -0
  35. package/dist/application/services/module-coordinator.service.js.map +1 -0
  36. package/dist/application/services/session-manager.service.d.ts +86 -0
  37. package/dist/application/services/session-manager.service.d.ts.map +1 -0
  38. package/dist/application/services/session-manager.service.js +318 -0
  39. package/dist/application/services/session-manager.service.js.map +1 -0
  40. package/dist/application/services/workflow-engine.service.d.ts +76 -0
  41. package/dist/application/services/workflow-engine.service.d.ts.map +1 -0
  42. package/dist/application/services/workflow-engine.service.js +405 -0
  43. package/dist/application/services/workflow-engine.service.js.map +1 -0
  44. package/dist/application/state/application-state.d.ts +164 -0
  45. package/dist/application/state/application-state.d.ts.map +1 -0
  46. package/dist/application/state/application-state.js +290 -0
  47. package/dist/application/state/application-state.js.map +1 -0
  48. package/dist/application/state/index.d.ts +15 -0
  49. package/dist/application/state/index.d.ts.map +1 -0
  50. package/dist/application/state/index.js +15 -0
  51. package/dist/application/state/index.js.map +1 -0
  52. package/dist/application/state/session-state.d.ts +114 -0
  53. package/dist/application/state/session-state.d.ts.map +1 -0
  54. package/dist/application/state/session-state.js +188 -0
  55. package/dist/application/state/session-state.js.map +1 -0
  56. package/dist/application/state/state-manager.d.ts +122 -0
  57. package/dist/application/state/state-manager.d.ts.map +1 -0
  58. package/dist/application/state/state-manager.js +234 -0
  59. package/dist/application/state/state-manager.js.map +1 -0
  60. package/dist/application/types.d.ts +280 -0
  61. package/dist/application/types.d.ts.map +1 -0
  62. package/dist/application/types.js +13 -0
  63. package/dist/application/types.js.map +1 -0
  64. package/dist/application/workflows/analysis-workflow.d.ts +239 -0
  65. package/dist/application/workflows/analysis-workflow.d.ts.map +1 -0
  66. package/dist/application/workflows/analysis-workflow.js +395 -0
  67. package/dist/application/workflows/analysis-workflow.js.map +1 -0
  68. package/dist/application/workflows/base-workflow.d.ts +108 -0
  69. package/dist/application/workflows/base-workflow.d.ts.map +1 -0
  70. package/dist/application/workflows/base-workflow.js +236 -0
  71. package/dist/application/workflows/base-workflow.js.map +1 -0
  72. package/dist/application/workflows/index.d.ts +115 -0
  73. package/dist/application/workflows/index.d.ts.map +1 -0
  74. package/dist/application/workflows/index.js +218 -0
  75. package/dist/application/workflows/index.js.map +1 -0
  76. package/dist/application/workflows/refactor-workflow.d.ts +107 -0
  77. package/dist/application/workflows/refactor-workflow.d.ts.map +1 -0
  78. package/dist/application/workflows/refactor-workflow.js +310 -0
  79. package/dist/application/workflows/refactor-workflow.js.map +1 -0
  80. package/dist/core/analysis/complexity-analyzer.d.ts +81 -0
  81. package/dist/core/analysis/complexity-analyzer.d.ts.map +1 -0
  82. package/dist/core/analysis/complexity-analyzer.js +254 -0
  83. package/dist/core/analysis/complexity-analyzer.js.map +1 -0
  84. package/dist/core/analysis/dead-code-detector.d.ts +123 -0
  85. package/dist/core/analysis/dead-code-detector.d.ts.map +1 -0
  86. package/dist/core/analysis/dead-code-detector.js +275 -0
  87. package/dist/core/analysis/dead-code-detector.js.map +1 -0
  88. package/dist/core/analysis/duplication-detector.d.ts +150 -0
  89. package/dist/core/analysis/duplication-detector.d.ts.map +1 -0
  90. package/dist/core/analysis/duplication-detector.js +433 -0
  91. package/dist/core/analysis/duplication-detector.js.map +1 -0
  92. package/dist/core/analysis/index.d.ts +9 -0
  93. package/dist/core/analysis/index.d.ts.map +1 -0
  94. package/dist/core/analysis/index.js +13 -0
  95. package/dist/core/analysis/index.js.map +1 -0
  96. package/dist/core/analysis/quality-metrics.d.ts +158 -0
  97. package/dist/core/analysis/quality-metrics.d.ts.map +1 -0
  98. package/dist/core/analysis/quality-metrics.js +442 -0
  99. package/dist/core/analysis/quality-metrics.js.map +1 -0
  100. package/dist/core/dependency/cycle-detector.d.ts +81 -0
  101. package/dist/core/dependency/cycle-detector.d.ts.map +1 -0
  102. package/dist/core/dependency/cycle-detector.js +300 -0
  103. package/dist/core/dependency/cycle-detector.js.map +1 -0
  104. package/dist/core/dependency/dependency-analyzer.d.ts +152 -0
  105. package/dist/core/dependency/dependency-analyzer.d.ts.map +1 -0
  106. package/dist/core/dependency/dependency-analyzer.js +458 -0
  107. package/dist/core/dependency/dependency-analyzer.js.map +1 -0
  108. package/dist/core/dependency/dependency-graph.d.ts +156 -0
  109. package/dist/core/dependency/dependency-graph.d.ts.map +1 -0
  110. package/dist/core/dependency/dependency-graph.js +371 -0
  111. package/dist/core/dependency/dependency-graph.js.map +1 -0
  112. package/dist/core/dependency/index.d.ts +27 -0
  113. package/dist/core/dependency/index.d.ts.map +1 -0
  114. package/dist/core/dependency/index.js +36 -0
  115. package/dist/core/dependency/index.js.map +1 -0
  116. package/dist/core/dependency/types.d.ts +168 -0
  117. package/dist/core/dependency/types.d.ts.map +1 -0
  118. package/dist/core/dependency/types.js +103 -0
  119. package/dist/core/dependency/types.js.map +1 -0
  120. package/dist/core/indexing/file-index.d.ts +117 -0
  121. package/dist/core/indexing/file-index.d.ts.map +1 -0
  122. package/dist/core/indexing/file-index.js +302 -0
  123. package/dist/core/indexing/file-index.js.map +1 -0
  124. package/dist/core/indexing/file-watcher.d.ts +110 -0
  125. package/dist/core/indexing/file-watcher.d.ts.map +1 -0
  126. package/dist/core/indexing/file-watcher.js +280 -0
  127. package/dist/core/indexing/file-watcher.js.map +1 -0
  128. package/dist/core/indexing/index-engine.d.ts +120 -0
  129. package/dist/core/indexing/index-engine.d.ts.map +1 -0
  130. package/dist/core/indexing/index-engine.js +445 -0
  131. package/dist/core/indexing/index-engine.js.map +1 -0
  132. package/dist/core/indexing/index.d.ts +25 -0
  133. package/dist/core/indexing/index.d.ts.map +1 -0
  134. package/dist/core/indexing/index.js +36 -0
  135. package/dist/core/indexing/index.js.map +1 -0
  136. package/dist/core/indexing/symbol-index.d.ts +107 -0
  137. package/dist/core/indexing/symbol-index.d.ts.map +1 -0
  138. package/dist/core/indexing/symbol-index.js +352 -0
  139. package/dist/core/indexing/symbol-index.js.map +1 -0
  140. package/dist/core/indexing/types.d.ts +222 -0
  141. package/dist/core/indexing/types.d.ts.map +1 -0
  142. package/dist/core/indexing/types.js +143 -0
  143. package/dist/core/indexing/types.js.map +1 -0
  144. package/dist/core/move/import-resolver.d.ts +54 -0
  145. package/dist/core/move/import-resolver.d.ts.map +1 -0
  146. package/dist/core/move/import-resolver.js +268 -0
  147. package/dist/core/move/import-resolver.js.map +1 -0
  148. package/dist/core/move/index.d.ts +10 -0
  149. package/dist/core/move/index.d.ts.map +1 -0
  150. package/dist/core/move/index.js +12 -0
  151. package/dist/core/move/index.js.map +1 -0
  152. package/dist/core/move/move-service.d.ts +67 -0
  153. package/dist/core/move/move-service.d.ts.map +1 -0
  154. package/dist/core/move/move-service.js +400 -0
  155. package/dist/core/move/move-service.js.map +1 -0
  156. package/dist/core/move/types.d.ts +266 -0
  157. package/dist/core/move/types.d.ts.map +1 -0
  158. package/dist/core/move/types.js +101 -0
  159. package/dist/core/move/types.js.map +1 -0
  160. package/dist/core/performance/analyzer.d.ts +62 -0
  161. package/dist/core/performance/analyzer.d.ts.map +1 -0
  162. package/dist/core/performance/analyzer.js +378 -0
  163. package/dist/core/performance/analyzer.js.map +1 -0
  164. package/dist/core/performance/cache-manager.d.ts +161 -0
  165. package/dist/core/performance/cache-manager.d.ts.map +1 -0
  166. package/dist/core/performance/cache-manager.js +375 -0
  167. package/dist/core/performance/cache-manager.js.map +1 -0
  168. package/dist/core/performance/index.d.ts +14 -0
  169. package/dist/core/performance/index.d.ts.map +1 -0
  170. package/dist/core/performance/index.js +17 -0
  171. package/dist/core/performance/index.js.map +1 -0
  172. package/dist/core/performance/interfaces.d.ts +188 -0
  173. package/dist/core/performance/interfaces.d.ts.map +1 -0
  174. package/dist/core/performance/interfaces.js +17 -0
  175. package/dist/core/performance/interfaces.js.map +1 -0
  176. package/dist/core/performance/memory-manager.d.ts +176 -0
  177. package/dist/core/performance/memory-manager.d.ts.map +1 -0
  178. package/dist/core/performance/memory-manager.js +364 -0
  179. package/dist/core/performance/memory-manager.js.map +1 -0
  180. package/dist/core/performance/monitor.d.ts +92 -0
  181. package/dist/core/performance/monitor.d.ts.map +1 -0
  182. package/dist/core/performance/monitor.js +228 -0
  183. package/dist/core/performance/monitor.js.map +1 -0
  184. package/dist/core/refactor/design-patterns.d.ts +178 -0
  185. package/dist/core/refactor/design-patterns.d.ts.map +1 -0
  186. package/dist/core/refactor/design-patterns.js +656 -0
  187. package/dist/core/refactor/design-patterns.js.map +1 -0
  188. package/dist/core/refactor/extract-function.d.ts +175 -0
  189. package/dist/core/refactor/extract-function.d.ts.map +1 -0
  190. package/dist/core/refactor/extract-function.js +478 -0
  191. package/dist/core/refactor/extract-function.js.map +1 -0
  192. package/dist/core/refactor/index.d.ts +8 -0
  193. package/dist/core/refactor/index.d.ts.map +1 -0
  194. package/dist/core/refactor/index.js +11 -0
  195. package/dist/core/refactor/index.js.map +1 -0
  196. package/dist/core/refactor/inline-function.d.ts +175 -0
  197. package/dist/core/refactor/inline-function.d.ts.map +1 -0
  198. package/dist/core/refactor/inline-function.js +425 -0
  199. package/dist/core/refactor/inline-function.js.map +1 -0
  200. package/dist/core/rename/index.d.ts +9 -0
  201. package/dist/core/rename/index.d.ts.map +1 -0
  202. package/dist/core/rename/index.js +13 -0
  203. package/dist/core/rename/index.js.map +1 -0
  204. package/dist/core/rename/reference-updater.d.ts +77 -0
  205. package/dist/core/rename/reference-updater.d.ts.map +1 -0
  206. package/dist/core/rename/reference-updater.js +400 -0
  207. package/dist/core/rename/reference-updater.js.map +1 -0
  208. package/dist/core/rename/rename-engine.d.ts +69 -0
  209. package/dist/core/rename/rename-engine.d.ts.map +1 -0
  210. package/dist/core/rename/rename-engine.js +350 -0
  211. package/dist/core/rename/rename-engine.js.map +1 -0
  212. package/dist/core/rename/scope-analyzer.d.ts +75 -0
  213. package/dist/core/rename/scope-analyzer.d.ts.map +1 -0
  214. package/dist/core/rename/scope-analyzer.js +269 -0
  215. package/dist/core/rename/scope-analyzer.js.map +1 -0
  216. package/dist/core/rename/types.d.ts +163 -0
  217. package/dist/core/rename/types.d.ts.map +1 -0
  218. package/dist/core/rename/types.js +80 -0
  219. package/dist/core/rename/types.js.map +1 -0
  220. package/dist/core/search/engines/text-engine.d.ts +52 -0
  221. package/dist/core/search/engines/text-engine.d.ts.map +1 -0
  222. package/dist/core/search/engines/text-engine.js +376 -0
  223. package/dist/core/search/engines/text-engine.js.map +1 -0
  224. package/dist/core/search/index.d.ts +10 -0
  225. package/dist/core/search/index.d.ts.map +1 -0
  226. package/dist/core/search/index.js +11 -0
  227. package/dist/core/search/index.js.map +1 -0
  228. package/dist/core/search/service.d.ts +105 -0
  229. package/dist/core/search/service.d.ts.map +1 -0
  230. package/dist/core/search/service.js +384 -0
  231. package/dist/core/search/service.js.map +1 -0
  232. package/dist/core/search/types.d.ts +357 -0
  233. package/dist/core/search/types.d.ts.map +1 -0
  234. package/dist/core/search/types.js +47 -0
  235. package/dist/core/search/types.js.map +1 -0
  236. package/dist/infrastructure/cache/cache-manager.d.ts +113 -0
  237. package/dist/infrastructure/cache/cache-manager.d.ts.map +1 -0
  238. package/dist/infrastructure/cache/cache-manager.js +279 -0
  239. package/dist/infrastructure/cache/cache-manager.js.map +1 -0
  240. package/dist/infrastructure/cache/index.d.ts +138 -0
  241. package/dist/infrastructure/cache/index.d.ts.map +1 -0
  242. package/dist/infrastructure/cache/index.js +266 -0
  243. package/dist/infrastructure/cache/index.js.map +1 -0
  244. package/dist/infrastructure/cache/memory-cache.d.ts +94 -0
  245. package/dist/infrastructure/cache/memory-cache.d.ts.map +1 -0
  246. package/dist/infrastructure/cache/memory-cache.js +327 -0
  247. package/dist/infrastructure/cache/memory-cache.js.map +1 -0
  248. package/dist/infrastructure/cache/strategies.d.ts +99 -0
  249. package/dist/infrastructure/cache/strategies.d.ts.map +1 -0
  250. package/dist/infrastructure/cache/strategies.js +230 -0
  251. package/dist/infrastructure/cache/strategies.js.map +1 -0
  252. package/dist/infrastructure/cache/types.d.ts +220 -0
  253. package/dist/infrastructure/cache/types.d.ts.map +1 -0
  254. package/dist/infrastructure/cache/types.js +42 -0
  255. package/dist/infrastructure/cache/types.js.map +1 -0
  256. package/dist/infrastructure/parser/base.d.ts +126 -0
  257. package/dist/infrastructure/parser/base.d.ts.map +1 -0
  258. package/dist/infrastructure/parser/base.js +269 -0
  259. package/dist/infrastructure/parser/base.js.map +1 -0
  260. package/dist/infrastructure/parser/factory.d.ts +141 -0
  261. package/dist/infrastructure/parser/factory.d.ts.map +1 -0
  262. package/dist/infrastructure/parser/factory.js +306 -0
  263. package/dist/infrastructure/parser/factory.js.map +1 -0
  264. package/dist/infrastructure/parser/index.d.ts +12 -0
  265. package/dist/infrastructure/parser/index.d.ts.map +1 -0
  266. package/dist/infrastructure/parser/index.js +12 -0
  267. package/dist/infrastructure/parser/index.js.map +1 -0
  268. package/dist/infrastructure/parser/interface.d.ts +108 -0
  269. package/dist/infrastructure/parser/interface.d.ts.map +1 -0
  270. package/dist/infrastructure/parser/interface.js +72 -0
  271. package/dist/infrastructure/parser/interface.js.map +1 -0
  272. package/dist/infrastructure/parser/registry.d.ts +141 -0
  273. package/dist/infrastructure/parser/registry.d.ts.map +1 -0
  274. package/dist/infrastructure/parser/registry.js +289 -0
  275. package/dist/infrastructure/parser/registry.js.map +1 -0
  276. package/dist/infrastructure/parser/types.d.ts +172 -0
  277. package/dist/infrastructure/parser/types.d.ts.map +1 -0
  278. package/dist/infrastructure/parser/types.js +147 -0
  279. package/dist/infrastructure/parser/types.js.map +1 -0
  280. package/dist/infrastructure/storage/file-system.d.ts +74 -0
  281. package/dist/infrastructure/storage/file-system.d.ts.map +1 -0
  282. package/dist/infrastructure/storage/file-system.js +334 -0
  283. package/dist/infrastructure/storage/file-system.js.map +1 -0
  284. package/dist/infrastructure/storage/file-watcher.d.ts +84 -0
  285. package/dist/infrastructure/storage/file-watcher.d.ts.map +1 -0
  286. package/dist/infrastructure/storage/file-watcher.js +249 -0
  287. package/dist/infrastructure/storage/file-watcher.js.map +1 -0
  288. package/dist/infrastructure/storage/index.d.ts +11 -0
  289. package/dist/infrastructure/storage/index.d.ts.map +1 -0
  290. package/dist/infrastructure/storage/index.js +16 -0
  291. package/dist/infrastructure/storage/index.js.map +1 -0
  292. package/dist/infrastructure/storage/path-utils.d.ts +96 -0
  293. package/dist/infrastructure/storage/path-utils.d.ts.map +1 -0
  294. package/dist/infrastructure/storage/path-utils.js +272 -0
  295. package/dist/infrastructure/storage/path-utils.js.map +1 -0
  296. package/dist/infrastructure/storage/types.d.ts +106 -0
  297. package/dist/infrastructure/storage/types.d.ts.map +1 -0
  298. package/dist/infrastructure/storage/types.js +53 -0
  299. package/dist/infrastructure/storage/types.js.map +1 -0
  300. package/dist/interfaces/cli/cli.d.ts +70 -0
  301. package/dist/interfaces/cli/cli.d.ts.map +1 -0
  302. package/dist/interfaces/cli/cli.js +1054 -0
  303. package/dist/interfaces/cli/cli.js.map +1 -0
  304. package/dist/interfaces/cli/index.d.ts +7 -0
  305. package/dist/interfaces/cli/index.d.ts.map +1 -0
  306. package/dist/interfaces/cli/index.js +22 -0
  307. package/dist/interfaces/cli/index.js.map +1 -0
  308. package/dist/interfaces/mcp/index.d.ts +7 -0
  309. package/dist/interfaces/mcp/index.d.ts.map +1 -0
  310. package/dist/interfaces/mcp/index.js +6 -0
  311. package/dist/interfaces/mcp/index.js.map +1 -0
  312. package/dist/interfaces/mcp/mcp-server.d.ts +34 -0
  313. package/dist/interfaces/mcp/mcp-server.d.ts.map +1 -0
  314. package/dist/interfaces/mcp/mcp-server.js +154 -0
  315. package/dist/interfaces/mcp/mcp-server.js.map +1 -0
  316. package/dist/interfaces/mcp/mcp.d.ts +44 -0
  317. package/dist/interfaces/mcp/mcp.d.ts.map +1 -0
  318. package/dist/interfaces/mcp/mcp.js +559 -0
  319. package/dist/interfaces/mcp/mcp.js.map +1 -0
  320. package/dist/plugins/javascript/index.d.ts +12 -0
  321. package/dist/plugins/javascript/index.d.ts.map +1 -0
  322. package/dist/plugins/javascript/index.js +16 -0
  323. package/dist/plugins/javascript/index.js.map +1 -0
  324. package/dist/plugins/javascript/parser.d.ts +81 -0
  325. package/dist/plugins/javascript/parser.d.ts.map +1 -0
  326. package/dist/plugins/javascript/parser.js +457 -0
  327. package/dist/plugins/javascript/parser.js.map +1 -0
  328. package/dist/plugins/javascript/types.d.ts +131 -0
  329. package/dist/plugins/javascript/types.d.ts.map +1 -0
  330. package/dist/plugins/javascript/types.js +366 -0
  331. package/dist/plugins/javascript/types.js.map +1 -0
  332. package/dist/plugins/swift/index.d.ts +11 -0
  333. package/dist/plugins/swift/index.d.ts.map +1 -0
  334. package/dist/plugins/swift/index.js +15 -0
  335. package/dist/plugins/swift/index.js.map +1 -0
  336. package/dist/plugins/swift/parser.d.ts +98 -0
  337. package/dist/plugins/swift/parser.d.ts.map +1 -0
  338. package/dist/plugins/swift/parser.js +612 -0
  339. package/dist/plugins/swift/parser.js.map +1 -0
  340. package/dist/plugins/swift/types.d.ts +196 -0
  341. package/dist/plugins/swift/types.d.ts.map +1 -0
  342. package/dist/plugins/swift/types.js +268 -0
  343. package/dist/plugins/swift/types.js.map +1 -0
  344. package/dist/plugins/typescript/dependency-analyzer.d.ts +78 -0
  345. package/dist/plugins/typescript/dependency-analyzer.d.ts.map +1 -0
  346. package/dist/plugins/typescript/dependency-analyzer.js +305 -0
  347. package/dist/plugins/typescript/dependency-analyzer.js.map +1 -0
  348. package/dist/plugins/typescript/index.d.ts +9 -0
  349. package/dist/plugins/typescript/index.d.ts.map +1 -0
  350. package/dist/plugins/typescript/index.js +8 -0
  351. package/dist/plugins/typescript/index.js.map +1 -0
  352. package/dist/plugins/typescript/parser.d.ts +117 -0
  353. package/dist/plugins/typescript/parser.d.ts.map +1 -0
  354. package/dist/plugins/typescript/parser.js +888 -0
  355. package/dist/plugins/typescript/parser.js.map +1 -0
  356. package/dist/plugins/typescript/symbol-extractor.d.ts +76 -0
  357. package/dist/plugins/typescript/symbol-extractor.d.ts.map +1 -0
  358. package/dist/plugins/typescript/symbol-extractor.js +339 -0
  359. package/dist/plugins/typescript/symbol-extractor.js.map +1 -0
  360. package/dist/plugins/typescript/types.d.ts +131 -0
  361. package/dist/plugins/typescript/types.d.ts.map +1 -0
  362. package/dist/plugins/typescript/types.js +331 -0
  363. package/dist/plugins/typescript/types.js.map +1 -0
  364. package/dist/shared/errors/base-error.d.ts +27 -0
  365. package/dist/shared/errors/base-error.d.ts.map +1 -0
  366. package/dist/shared/errors/base-error.js +58 -0
  367. package/dist/shared/errors/base-error.js.map +1 -0
  368. package/dist/shared/errors/config-error.d.ts +21 -0
  369. package/dist/shared/errors/config-error.d.ts.map +1 -0
  370. package/dist/shared/errors/config-error.js +34 -0
  371. package/dist/shared/errors/config-error.js.map +1 -0
  372. package/dist/shared/errors/file-error.d.ts +21 -0
  373. package/dist/shared/errors/file-error.d.ts.map +1 -0
  374. package/dist/shared/errors/file-error.js +34 -0
  375. package/dist/shared/errors/file-error.js.map +1 -0
  376. package/dist/shared/errors/index.d.ts +59 -0
  377. package/dist/shared/errors/index.d.ts.map +1 -0
  378. package/dist/shared/errors/index.js +114 -0
  379. package/dist/shared/errors/index.js.map +1 -0
  380. package/dist/shared/errors/parser-error.d.ts +72 -0
  381. package/dist/shared/errors/parser-error.d.ts.map +1 -0
  382. package/dist/shared/errors/parser-error.js +104 -0
  383. package/dist/shared/errors/parser-error.js.map +1 -0
  384. package/dist/shared/errors/validation-error.d.ts +21 -0
  385. package/dist/shared/errors/validation-error.d.ts.map +1 -0
  386. package/dist/shared/errors/validation-error.js +34 -0
  387. package/dist/shared/errors/validation-error.js.map +1 -0
  388. package/dist/shared/index.d.ts +11 -0
  389. package/dist/shared/index.d.ts.map +1 -0
  390. package/dist/shared/index.js +22 -0
  391. package/dist/shared/index.js.map +1 -0
  392. package/dist/shared/types/ast.d.ts +78 -0
  393. package/dist/shared/types/ast.d.ts.map +1 -0
  394. package/dist/shared/types/ast.js +215 -0
  395. package/dist/shared/types/ast.js.map +1 -0
  396. package/dist/shared/types/core.d.ts +65 -0
  397. package/dist/shared/types/core.d.ts.map +1 -0
  398. package/dist/shared/types/core.js +114 -0
  399. package/dist/shared/types/core.js.map +1 -0
  400. package/dist/shared/types/index.d.ts +11 -0
  401. package/dist/shared/types/index.d.ts.map +1 -0
  402. package/dist/shared/types/index.js +12 -0
  403. package/dist/shared/types/index.js.map +1 -0
  404. package/dist/shared/types/symbol.d.ts +119 -0
  405. package/dist/shared/types/symbol.d.ts.map +1 -0
  406. package/dist/shared/types/symbol.js +197 -0
  407. package/dist/shared/types/symbol.js.map +1 -0
  408. package/dist/shared/utils/array.d.ts +68 -0
  409. package/dist/shared/utils/array.d.ts.map +1 -0
  410. package/dist/shared/utils/array.js +165 -0
  411. package/dist/shared/utils/array.js.map +1 -0
  412. package/dist/shared/utils/async.d.ts +87 -0
  413. package/dist/shared/utils/async.d.ts.map +1 -0
  414. package/dist/shared/utils/async.js +185 -0
  415. package/dist/shared/utils/async.js.map +1 -0
  416. package/dist/shared/utils/index.d.ts +32 -0
  417. package/dist/shared/utils/index.d.ts.map +1 -0
  418. package/dist/shared/utils/index.js +37 -0
  419. package/dist/shared/utils/index.js.map +1 -0
  420. package/dist/shared/utils/memory-monitor.d.ts +83 -0
  421. package/dist/shared/utils/memory-monitor.d.ts.map +1 -0
  422. package/dist/shared/utils/memory-monitor.js +168 -0
  423. package/dist/shared/utils/memory-monitor.js.map +1 -0
  424. package/dist/shared/utils/object.d.ts +71 -0
  425. package/dist/shared/utils/object.d.ts.map +1 -0
  426. package/dist/shared/utils/object.js +284 -0
  427. package/dist/shared/utils/object.js.map +1 -0
  428. package/dist/shared/utils/path.d.ts +59 -0
  429. package/dist/shared/utils/path.d.ts.map +1 -0
  430. package/dist/shared/utils/path.js +201 -0
  431. package/dist/shared/utils/path.js.map +1 -0
  432. package/dist/shared/utils/string.d.ts +74 -0
  433. package/dist/shared/utils/string.d.ts.map +1 -0
  434. package/dist/shared/utils/string.js +201 -0
  435. package/dist/shared/utils/string.js.map +1 -0
  436. package/package.json +81 -0
@@ -0,0 +1,1054 @@
1
+ /**
2
+ * CLI 介面實作
3
+ * 提供命令列介面來操作 Agent IDE 功能
4
+ */
5
+ import { Command } from 'commander';
6
+ import { IndexEngine } from '../../core/indexing/index-engine.js';
7
+ import { DependencyAnalyzer } from '../../core/dependency/dependency-analyzer.js';
8
+ import { RenameEngine } from '../../core/rename/rename-engine.js';
9
+ import { ReferenceUpdater } from '../../core/rename/reference-updater.js';
10
+ import { MoveService } from '../../core/move/index.js';
11
+ import { SearchService } from '../../core/search/service.js';
12
+ import { createIndexConfig } from '../../core/indexing/types.js';
13
+ import { ParserRegistry } from '../../infrastructure/parser/registry.js';
14
+ import { TypeScriptParser } from '../../plugins/typescript/parser.js';
15
+ import { JavaScriptParser } from '../../plugins/javascript/parser.js';
16
+ import { ComplexityAnalyzer } from '../../core/analysis/complexity-analyzer.js';
17
+ import { DeadCodeDetector } from '../../core/analysis/dead-code-detector.js';
18
+ import * as fs from 'fs/promises';
19
+ import * as path from 'path';
20
+ export class AgentIdeCLI {
21
+ program;
22
+ indexEngine;
23
+ dependencyAnalyzer;
24
+ renameEngine;
25
+ importResolver;
26
+ moveService;
27
+ searchService;
28
+ constructor() {
29
+ this.program = new Command();
30
+ this.setupCommands();
31
+ this.initializeParsers();
32
+ }
33
+ /**
34
+ * 執行 CLI 程式
35
+ */
36
+ async run(argv) {
37
+ await this.program.parseAsync(argv);
38
+ }
39
+ initializeParsers() {
40
+ try {
41
+ const registry = ParserRegistry.getInstance();
42
+ // 檢查 registry 是否可用
43
+ if (!registry) {
44
+ console.debug('Parser registry not available');
45
+ return;
46
+ }
47
+ // 在測試環境中,檢查是否已經有測試 Parser 註冊
48
+ if (process.env.NODE_ENV === 'test') {
49
+ // 如果所有測試 Parser 都已經註冊,就不需要重複註冊
50
+ const tsParser = registry.getParserByName('typescript');
51
+ const jsParser = registry.getParserByName('javascript');
52
+ if (tsParser && jsParser) {
53
+ return;
54
+ }
55
+ }
56
+ // 嘗試註冊內建的 TypeScript Parser
57
+ try {
58
+ const tsParser = new TypeScriptParser();
59
+ if (!registry.getParserByName('typescript')) {
60
+ registry.register(tsParser);
61
+ }
62
+ }
63
+ catch (tsError) {
64
+ // 如果 TypeScript Parser 載入失敗,記錄錯誤
65
+ console.debug('TypeScript parser loading failed:', tsError);
66
+ console.debug('TypeScript Parser initialization warning:', tsError);
67
+ }
68
+ // 嘗試註冊內建的 JavaScript Parser
69
+ try {
70
+ const jsParser = new JavaScriptParser();
71
+ if (!registry.getParserByName('javascript')) {
72
+ registry.register(jsParser);
73
+ }
74
+ }
75
+ catch (jsError) {
76
+ // 如果 JavaScript Parser 載入失敗,記錄錯誤
77
+ console.debug('JavaScript parser loading failed:', jsError);
78
+ console.debug('JavaScript Parser initialization warning:', jsError);
79
+ }
80
+ }
81
+ catch (error) {
82
+ // 靜默處理初始化錯誤,避免影響 CLI 啟動
83
+ console.debug('Parser initialization warning:', error);
84
+ }
85
+ }
86
+ setupCommands() {
87
+ this.program
88
+ .name('agent-ide')
89
+ .description('程式碼智能工具集 for AI Agents')
90
+ .version('0.1.0');
91
+ this.setupIndexCommand();
92
+ this.setupRenameCommand();
93
+ this.setupRefactorCommand();
94
+ this.setupMoveCommand();
95
+ this.setupSearchCommand();
96
+ this.setupAnalyzeCommand();
97
+ this.setupDepsCommand();
98
+ this.setupPluginsCommand();
99
+ }
100
+ setupIndexCommand() {
101
+ this.program
102
+ .command('index')
103
+ .description('建立或更新程式碼索引')
104
+ .option('-p, --path <path>', '專案路徑', process.cwd())
105
+ .option('-u, --update', '增量更新索引')
106
+ .option('-e, --extensions <exts>', '包含的檔案副檔名', '.ts,.js,.tsx,.jsx')
107
+ .option('-x, --exclude <patterns>', '排除模式', 'node_modules/**,*.test.*')
108
+ .action(async (options) => {
109
+ await this.handleIndexCommand(options);
110
+ });
111
+ }
112
+ setupRenameCommand() {
113
+ this.program
114
+ .command('rename')
115
+ .description('重新命名程式碼元素')
116
+ .option('-t, --type <type>', '符號類型 (variable|function|class|interface)', 'variable')
117
+ .option('-s, --symbol <name>', '要重新命名的符號')
118
+ .option('-f, --from <name>', '原始名稱(--symbol 的別名)')
119
+ .option('-n, --new-name <name>', '新名稱')
120
+ .option('-o, --to <name>', '新名稱(--new-name 的別名)')
121
+ .option('-p, --path <path>', '檔案或目錄路徑', '.')
122
+ .option('--preview', '預覽變更而不執行')
123
+ .action(async (options) => {
124
+ await this.handleRenameCommand(options);
125
+ });
126
+ }
127
+ setupRefactorCommand() {
128
+ this.program
129
+ .command('refactor <action>')
130
+ .description('重構程式碼 (extract-function | inline-function)')
131
+ .option('-f, --file <file>', '檔案路徑')
132
+ .option('-s, --start-line <line>', '起始行號')
133
+ .option('-e, --end-line <line>', '結束行號')
134
+ .option('-n, --function-name <name>', '函式名稱')
135
+ .option('-p, --path <path>', '專案路徑', '.')
136
+ .option('--preview', '預覽變更而不執行')
137
+ .action(async (action, options) => {
138
+ await this.handleRefactorCommand(action, options);
139
+ });
140
+ }
141
+ setupMoveCommand() {
142
+ this.program
143
+ .command('move')
144
+ .description('移動檔案或目錄')
145
+ .argument('<source>', '來源路徑')
146
+ .argument('<target>', '目標路徑')
147
+ .option('--update-imports', '自動更新 import 路徑', true)
148
+ .option('--preview', '預覽變更而不執行')
149
+ .action(async (source, target, options) => {
150
+ await this.handleMoveCommand(source, target, options);
151
+ });
152
+ }
153
+ setupSearchCommand() {
154
+ this.program
155
+ .command('search')
156
+ .description('搜尋程式碼')
157
+ .argument('<query>', '搜尋查詢')
158
+ .option('-t, --type <type>', '搜尋類型 (text|regex|fuzzy)', 'text')
159
+ .option('-p, --path <path>', '搜尋路徑', '.')
160
+ .option('-e, --extensions <exts>', '檔案副檔名', '.ts,.js,.tsx,.jsx')
161
+ .option('-l, --limit <num>', '結果數量限制', '50')
162
+ .option('-c, --context <lines>', '上下文行數', '2')
163
+ .option('--case-sensitive', '大小寫敏感')
164
+ .option('--whole-word', '全字匹配')
165
+ .option('--multiline', '多行匹配')
166
+ .option('--include <patterns>', '包含模式')
167
+ .option('--exclude <patterns>', '排除模式', 'node_modules/**,*.test.*')
168
+ .option('--format <format>', '輸出格式 (list|json|minimal)', 'list')
169
+ .action(async (query, options) => {
170
+ await this.handleSearchCommand(query, options);
171
+ });
172
+ }
173
+ setupAnalyzeCommand() {
174
+ this.program
175
+ .command('analyze [type]')
176
+ .description('分析程式碼品質')
177
+ .option('-p, --path <path>', '分析路徑', '.')
178
+ .option('--pattern <pattern>', '分析模式')
179
+ .option('--format <format>', '輸出格式 (json|table|summary)', 'summary')
180
+ .action(async (type, options) => {
181
+ await this.handleAnalyzeCommand(type, options);
182
+ });
183
+ }
184
+ setupDepsCommand() {
185
+ this.program
186
+ .command('deps')
187
+ .description('分析依賴關係')
188
+ .option('-p, --path <path>', '分析路徑', '.')
189
+ .option('-t, --type <type>', '分析類型 (graph|cycles|impact)')
190
+ .option('-f, --file <file>', '特定檔案分析')
191
+ .option('--format <format>', '輸出格式 (json|dot|summary)', 'summary')
192
+ .action(async (options) => {
193
+ await this.handleDepsCommand(options);
194
+ });
195
+ }
196
+ setupPluginsCommand() {
197
+ const pluginsCmd = this.program
198
+ .command('plugins')
199
+ .description('管理 Parser 插件');
200
+ pluginsCmd
201
+ .command('list')
202
+ .option('--enabled', '只顯示啟用的插件')
203
+ .option('--disabled', '只顯示停用的插件')
204
+ .description('列出所有插件')
205
+ .action(async (options) => {
206
+ await this.handlePluginsListCommand(options);
207
+ });
208
+ pluginsCmd
209
+ .command('info <plugin>')
210
+ .description('顯示插件資訊')
211
+ .action(async (pluginName) => {
212
+ await this.handlePluginInfoCommand(pluginName);
213
+ });
214
+ }
215
+ // Command handlers
216
+ async handleIndexCommand(options) {
217
+ console.log('🔍 開始建立程式碼索引...');
218
+ try {
219
+ const config = createIndexConfig(options.path, {
220
+ includeExtensions: options.extensions.split(','),
221
+ excludePatterns: options.exclude.split(',')
222
+ });
223
+ this.indexEngine = new IndexEngine(config);
224
+ if (options.update) {
225
+ // TODO: 實作增量更新
226
+ console.log('📝 執行增量索引更新...');
227
+ }
228
+ else {
229
+ await this.indexEngine.indexProject(options.path);
230
+ }
231
+ const stats = await this.indexEngine.getStats();
232
+ console.log('✅ 索引完成!');
233
+ console.log(`📊 統計: ${stats.totalFiles} 檔案, ${stats.totalSymbols} 符號`);
234
+ }
235
+ catch (error) {
236
+ console.error('❌ 索引失敗:', error instanceof Error ? error.message : error);
237
+ if (process.env.NODE_ENV !== 'test') {
238
+ process.exit(1);
239
+ }
240
+ }
241
+ }
242
+ async handleRenameCommand(options) {
243
+ // 支援多種參數名稱
244
+ const from = options.symbol || options.from;
245
+ const to = options.newName || options.to;
246
+ if (!from || !to) {
247
+ console.error('❌ 必須指定符號名稱和新名稱');
248
+ console.error(' 使用方式: agent-ide rename --symbol <name> --new-name <name>');
249
+ if (process.env.NODE_ENV !== 'test') {
250
+ process.exit(1);
251
+ }
252
+ return;
253
+ }
254
+ console.log(`🔄 重新命名 ${from} → ${to}`);
255
+ try {
256
+ const workspacePath = options.path || process.cwd();
257
+ // 初始化索引引擎(每次都重新索引以確保資料是最新的)
258
+ const config = createIndexConfig(workspacePath, {
259
+ includeExtensions: ['.ts', '.tsx', '.js', '.jsx'],
260
+ excludePatterns: ['node_modules/**', '*.test.*']
261
+ });
262
+ this.indexEngine = new IndexEngine(config);
263
+ await this.indexEngine.indexProject(workspacePath);
264
+ // 初始化重新命名引擎
265
+ if (!this.renameEngine) {
266
+ this.renameEngine = new RenameEngine();
267
+ }
268
+ // 1. 查找符號
269
+ console.log(`🔍 查找符號 "${from}"...`);
270
+ const searchResults = await this.indexEngine.findSymbol(from);
271
+ if (searchResults.length === 0) {
272
+ console.log(`❌ 找不到符號 "${from}"`);
273
+ if (process.env.NODE_ENV !== 'test') {
274
+ process.exit(1);
275
+ }
276
+ return;
277
+ }
278
+ if (searchResults.length > 1) {
279
+ console.log('⚠️ 找到多個符號,使用第一個:');
280
+ searchResults.forEach((result, index) => {
281
+ console.log(` ${index + 1}. ${result.symbol.name} 在 ${result.symbol.location.filePath}:${result.symbol.location.range.start.line}`);
282
+ });
283
+ }
284
+ const targetSymbol = searchResults[0].symbol;
285
+ // 2. 預覽變更
286
+ if (options.preview) {
287
+ console.log('🔍 預覽變更...');
288
+ try {
289
+ // 確保有有效的檔案路徑
290
+ let filePaths;
291
+ if (targetSymbol.location && targetSymbol.location.filePath) {
292
+ filePaths = [targetSymbol.location.filePath];
293
+ }
294
+ else {
295
+ // 如果沒有 location,使用所有已索引的檔案
296
+ const allFiles = this.indexEngine.getAllIndexedFiles();
297
+ filePaths = allFiles.map(f => f.filePath);
298
+ if (filePaths.length === 0) {
299
+ filePaths = [options.path || process.cwd()];
300
+ }
301
+ }
302
+ const preview = await this.renameEngine.previewRename({
303
+ symbol: targetSymbol,
304
+ newName: to,
305
+ filePaths
306
+ });
307
+ console.log('📝 預計變更:');
308
+ console.log(` 檔案數: ${preview.affectedFiles.length}`);
309
+ console.log(` 操作數: ${preview.operations.length}`);
310
+ if (preview.conflicts.length > 0) {
311
+ console.log('⚠️ 發現衝突:');
312
+ preview.conflicts.forEach(conflict => {
313
+ console.log(` - ${conflict.message}`);
314
+ });
315
+ }
316
+ preview.operations.forEach(op => {
317
+ console.log(` ${op.filePath}: "${op.oldText}" → "${op.newText}"`);
318
+ });
319
+ console.log('✅ 預覽完成');
320
+ return;
321
+ }
322
+ catch (previewError) {
323
+ console.error('❌ 預覽失敗:', previewError instanceof Error ? previewError.message : previewError);
324
+ if (process.env.NODE_ENV !== 'test') {
325
+ process.exit(1);
326
+ }
327
+ }
328
+ }
329
+ // 3. 執行重新命名(處理跨檔案引用)
330
+ console.log('✏️ 執行重新命名...');
331
+ // 使用 ReferenceUpdater 來處理跨檔案引用
332
+ const referenceUpdater = new ReferenceUpdater();
333
+ const allProjectFiles = await this.getAllProjectFiles(options.path);
334
+ const updateResult = await referenceUpdater.updateCrossFileReferences(targetSymbol, to, allProjectFiles);
335
+ if (updateResult.success) {
336
+ console.log('✅ 重新命名成功!');
337
+ console.log(`📊 統計: ${updateResult.updatedFiles.length} 檔案, ${updateResult.updatedFiles.reduce((sum, f) => sum + f.changes.length, 0)} 變更`);
338
+ updateResult.updatedFiles.forEach(file => {
339
+ file.changes.forEach(change => {
340
+ console.log(` ✓ ${file.filePath}: "${change.oldText}" → "${change.newText}"`);
341
+ });
342
+ });
343
+ }
344
+ else {
345
+ console.error('❌ 重新命名失敗:');
346
+ updateResult.errors?.forEach(error => {
347
+ console.error(` - ${error}`);
348
+ });
349
+ if (process.env.NODE_ENV !== 'test') {
350
+ process.exit(1);
351
+ }
352
+ }
353
+ }
354
+ catch (error) {
355
+ console.error('❌ 重新命名失敗:', error instanceof Error ? error.message : error);
356
+ if (process.env.NODE_ENV !== 'test') {
357
+ process.exit(1);
358
+ }
359
+ }
360
+ }
361
+ async handleRefactorCommand(action, options) {
362
+ if (!options.file) {
363
+ console.error('❌ 必須指定 --file 參數');
364
+ if (process.env.NODE_ENV !== 'test') {
365
+ process.exit(1);
366
+ }
367
+ return;
368
+ }
369
+ console.log(`🔧 重構: ${action}`);
370
+ try {
371
+ const filePath = path.resolve(options.file);
372
+ if (action === 'extract-function') {
373
+ if (!options.startLine || !options.endLine || !options.functionName) {
374
+ console.error('❌ extract-function 需要 --start-line, --end-line 和 --function-name 參數');
375
+ if (process.env.NODE_ENV !== 'test') {
376
+ process.exit(1);
377
+ }
378
+ return;
379
+ }
380
+ // 讀取檔案內容
381
+ const fs = await import('fs/promises');
382
+ const code = await fs.readFile(filePath, 'utf-8');
383
+ // 建立範圍
384
+ const range = {
385
+ start: { line: parseInt(options.startLine), column: 0 },
386
+ end: { line: parseInt(options.endLine), column: 0 }
387
+ };
388
+ // 初始化 FunctionExtractor
389
+ const { FunctionExtractor } = await import('../../core/refactor/extract-function.js');
390
+ const extractor = new FunctionExtractor();
391
+ // 執行提取
392
+ const result = await extractor.extract(code, range, {
393
+ functionName: options.functionName,
394
+ generateComments: true,
395
+ preserveFormatting: true,
396
+ validateExtraction: true
397
+ });
398
+ if (result.success) {
399
+ // 套用編輯
400
+ let modifiedCode = code;
401
+ result.edits.forEach(edit => {
402
+ modifiedCode = this.applyCodeEdit(modifiedCode, edit);
403
+ });
404
+ // 提取函式簽名(從修改後的程式碼中)
405
+ const functionSignatureMatch = modifiedCode.match(new RegExp(`(async\\s+)?function\\s+${result.functionName}\\s*\\([^)]*\\)`));
406
+ const functionSignature = functionSignatureMatch ? functionSignatureMatch[0] : `function ${result.functionName}`;
407
+ console.log('✅ 重構完成');
408
+ console.log(`📝 提取的函式: ${functionSignature}`);
409
+ console.log(functionSignature);
410
+ if (!options.preview) {
411
+ // 寫入檔案
412
+ await fs.writeFile(filePath, modifiedCode, 'utf-8');
413
+ console.log(`✓ 已更新 ${filePath}`);
414
+ }
415
+ else {
416
+ console.log('\n🔍 預覽模式 - 未寫入檔案');
417
+ console.log(`📊 參數: ${result.parameters.map(p => p.name).join(', ')}`);
418
+ }
419
+ }
420
+ else {
421
+ console.error('❌ 重構失敗:', result.errors.join(', '));
422
+ if (process.env.NODE_ENV !== 'test') {
423
+ process.exit(1);
424
+ }
425
+ }
426
+ }
427
+ else if (action === 'inline-function') {
428
+ console.error('❌ inline-function 尚未實作');
429
+ if (process.env.NODE_ENV !== 'test') {
430
+ process.exit(1);
431
+ }
432
+ }
433
+ else {
434
+ console.error(`❌ 未知的重構操作: ${action}`);
435
+ if (process.env.NODE_ENV !== 'test') {
436
+ process.exit(1);
437
+ }
438
+ }
439
+ }
440
+ catch (error) {
441
+ console.error('❌ 重構失敗:', error instanceof Error ? error.message : error);
442
+ if (process.env.NODE_ENV !== 'test') {
443
+ process.exit(1);
444
+ }
445
+ }
446
+ }
447
+ async handleMoveCommand(source, target, options) {
448
+ console.log(`📦 移動 ${source} → ${target}`);
449
+ try {
450
+ // 檢查源檔案是否存在
451
+ const sourceExists = await this.fileExists(source);
452
+ if (!sourceExists) {
453
+ console.log(`❌ 移動失敗: 源檔案不存在 "${source}"`);
454
+ if (process.env.NODE_ENV !== 'test') {
455
+ process.exit(1);
456
+ }
457
+ }
458
+ // 初始化移動服務
459
+ if (!this.moveService) {
460
+ this.moveService = new MoveService({
461
+ pathAliases: {},
462
+ supportedExtensions: ['.ts', '.tsx', '.js', '.jsx', '.vue'],
463
+ includeNodeModules: false
464
+ });
465
+ }
466
+ const moveOperation = {
467
+ source: path.resolve(source),
468
+ target: path.resolve(target),
469
+ updateImports: options.updateImports
470
+ };
471
+ const moveOptions = {
472
+ preview: options.preview,
473
+ projectRoot: process.cwd()
474
+ };
475
+ // 執行移動操作
476
+ const result = await this.moveService.moveFile(moveOperation, moveOptions);
477
+ if (result.success) {
478
+ if (options.preview) {
479
+ console.log('🔍 預覽移動操作:');
480
+ }
481
+ else {
482
+ console.log('✅ 移動成功!');
483
+ }
484
+ console.log(`📊 統計: ${result.pathUpdates.length} 個 import 需要更新`);
485
+ if (result.pathUpdates.length > 0) {
486
+ console.log('📝 影響的檔案:');
487
+ const fileGroups = new Map();
488
+ result.pathUpdates.forEach(update => {
489
+ if (!fileGroups.has(update.filePath)) {
490
+ fileGroups.set(update.filePath, []);
491
+ }
492
+ fileGroups.get(update.filePath).push(update);
493
+ });
494
+ for (const [filePath, updates] of fileGroups) {
495
+ console.log(` 📄 ${path.relative(process.cwd(), filePath)}:`);
496
+ updates.forEach(update => {
497
+ console.log(` 第 ${update.line} 行: "${path.basename(source)}" → "${path.basename(target)}"`);
498
+ });
499
+ }
500
+ }
501
+ }
502
+ else {
503
+ console.error('❌ 移動失敗:', result.error);
504
+ if (process.env.NODE_ENV !== 'test') {
505
+ process.exit(1);
506
+ }
507
+ }
508
+ }
509
+ catch (error) {
510
+ console.error('❌ 移動失敗:', error instanceof Error ? error.message : error);
511
+ if (process.env.NODE_ENV !== 'test') {
512
+ process.exit(1);
513
+ }
514
+ }
515
+ }
516
+ async handleSearchCommand(query, options) {
517
+ const isMinimalOrJson = options.format === 'minimal' || options.format === 'json';
518
+ if (!isMinimalOrJson) {
519
+ console.log(`🔍 搜尋: "${query}"`);
520
+ }
521
+ try {
522
+ // 初始化搜尋服務
523
+ if (!this.searchService) {
524
+ this.searchService = new SearchService();
525
+ }
526
+ // 建構搜尋選項
527
+ const searchOptions = this.buildSearchOptions(options);
528
+ // 根據搜尋類型建立查詢
529
+ const searchQuery = {
530
+ type: 'text',
531
+ query,
532
+ options: searchOptions
533
+ };
534
+ // 執行搜尋
535
+ const startTime = Date.now();
536
+ const result = await this.searchService.searchText(searchQuery);
537
+ const searchTime = Date.now() - startTime;
538
+ // 顯示結果
539
+ if (result.matches.length === 0) {
540
+ if (!isMinimalOrJson) {
541
+ console.log('📝 沒有找到匹配結果');
542
+ }
543
+ else if (options.format === 'json') {
544
+ // JSON 格式輸出空結果
545
+ console.log(JSON.stringify({ results: [] }, null, 2));
546
+ }
547
+ return;
548
+ }
549
+ if (!isMinimalOrJson) {
550
+ console.log(`✅ 找到 ${result.matches.length} 個結果 (${searchTime}ms)`);
551
+ if (result.truncated) {
552
+ console.log(`⚠️ 結果已截斷,顯示前 ${options.limit} 個結果`);
553
+ }
554
+ }
555
+ // 格式化輸出
556
+ this.formatSearchResults(result, options);
557
+ }
558
+ catch (error) {
559
+ if (isMinimalOrJson) {
560
+ // 對於 minimal 和 json 格式,輸出空結果或錯誤
561
+ if (options.format === 'json') {
562
+ console.log(JSON.stringify({ matches: [], error: error instanceof Error ? error.message : String(error) }));
563
+ }
564
+ else {
565
+ console.error(`Error: ${error instanceof Error ? error.message : error}`);
566
+ }
567
+ }
568
+ else {
569
+ console.error('❌ 搜尋失敗:', error instanceof Error ? error.message : error);
570
+ }
571
+ // 測試環境不 exit
572
+ if (process.env.NODE_ENV !== 'test') {
573
+ if (process.env.NODE_ENV !== 'test') {
574
+ process.exit(1);
575
+ }
576
+ }
577
+ }
578
+ }
579
+ /**
580
+ * 建構搜尋選項
581
+ */
582
+ buildSearchOptions(options) {
583
+ const includeFiles = options.include ? options.include.split(',') : undefined;
584
+ const excludeFiles = options.exclude ? options.exclude.split(',') : undefined;
585
+ return {
586
+ scope: {
587
+ type: 'directory',
588
+ path: path.resolve(options.path),
589
+ recursive: true
590
+ },
591
+ maxResults: parseInt(options.limit),
592
+ caseSensitive: options.caseSensitive || false,
593
+ wholeWord: options.wholeWord || false,
594
+ regex: options.type === 'regex',
595
+ fuzzy: options.type === 'fuzzy',
596
+ multiline: options.multiline || false,
597
+ showContext: options.context > 0,
598
+ contextLines: parseInt(options.context),
599
+ includeFiles,
600
+ excludeFiles,
601
+ timeout: 30000
602
+ };
603
+ }
604
+ /**
605
+ * 格式化搜尋結果輸出
606
+ */
607
+ formatSearchResults(result, options) {
608
+ switch (options.format) {
609
+ case 'json':
610
+ // 測試期望的格式是 { results: [...] } 而不是 { matches: [...] }
611
+ // 將絕對路徑轉換為相對路徑
612
+ const resultsWithRelativePaths = result.matches.map((match) => ({
613
+ ...match,
614
+ file: this.formatFilePath(match.file)
615
+ }));
616
+ console.log(JSON.stringify({ results: resultsWithRelativePaths }, null, 2));
617
+ break;
618
+ case 'minimal':
619
+ // AI Agent 友善的最小輸出
620
+ result.matches.forEach((match) => {
621
+ console.log(`${match.file}:${match.line}:${match.column}:${match.content.trim()}`);
622
+ });
623
+ break;
624
+ case 'list':
625
+ default:
626
+ result.matches.forEach((match, index) => {
627
+ console.log(`\n${index + 1}. ${this.formatFilePath(match.file)}:${match.line}:${match.column}`);
628
+ console.log(` ${this.highlightMatch(match.content, options.query)}`);
629
+ // 顯示上下文
630
+ if (options.context > 0 && match.context) {
631
+ if (match.context.before.length > 0) {
632
+ match.context.before.forEach((line, i) => {
633
+ const lineNum = match.line - match.context.before.length + i;
634
+ console.log(` ${lineNum.toString().padStart(3, ' ')}: ${line}`);
635
+ });
636
+ }
637
+ console.log(`>> ${match.line.toString().padStart(3, ' ')}: ${this.highlightMatch(match.content, options.query)}`);
638
+ if (match.context.after.length > 0) {
639
+ match.context.after.forEach((line, i) => {
640
+ const lineNum = match.line + i + 1;
641
+ console.log(` ${lineNum.toString().padStart(3, ' ')}: ${line}`);
642
+ });
643
+ }
644
+ }
645
+ });
646
+ break;
647
+ }
648
+ }
649
+ /**
650
+ * 格式化檔案路徑(顯示相對路徑)
651
+ */
652
+ formatFilePath(filePath) {
653
+ const cwd = process.cwd();
654
+ const relativePath = path.relative(cwd, filePath);
655
+ return relativePath.startsWith('..') ? filePath : relativePath;
656
+ }
657
+ /**
658
+ * 高亮匹配內容
659
+ */
660
+ highlightMatch(text, query) {
661
+ if (!text || !query) {
662
+ return text;
663
+ }
664
+ // 簡單的高亮實作
665
+ try {
666
+ const regex = new RegExp(query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'gi');
667
+ return text.replace(regex, `[${query}]`);
668
+ }
669
+ catch {
670
+ return text;
671
+ }
672
+ }
673
+ async handleAnalyzeCommand(type, options) {
674
+ const analyzeType = type || 'complexity';
675
+ if (options.format !== 'json') {
676
+ console.log('📊 分析程式碼品質...');
677
+ }
678
+ try {
679
+ const analyzePath = options.path || process.cwd();
680
+ // 根據分析類型執行對應分析
681
+ if (analyzeType === 'complexity') {
682
+ const analyzer = new ComplexityAnalyzer();
683
+ // 獲取需要分析的檔案列表
684
+ const files = await this.getAllProjectFiles(analyzePath);
685
+ const results = await analyzer.analyzeFiles(files);
686
+ // 計算統計資訊
687
+ const complexities = results.map(r => r.complexity.cyclomaticComplexity);
688
+ const averageComplexity = complexities.length > 0
689
+ ? complexities.reduce((sum, c) => sum + c, 0) / complexities.length
690
+ : 0;
691
+ const maxComplexity = complexities.length > 0
692
+ ? Math.max(...complexities)
693
+ : 0;
694
+ if (options.format === 'json') {
695
+ console.log(JSON.stringify({
696
+ files: results.map(r => ({
697
+ path: r.file,
698
+ complexity: r.complexity.cyclomaticComplexity,
699
+ cognitiveComplexity: r.complexity.cognitiveComplexity,
700
+ evaluation: r.complexity.evaluation
701
+ })),
702
+ summary: {
703
+ averageComplexity,
704
+ maxComplexity,
705
+ totalFiles: results.length
706
+ }
707
+ }, null, 2));
708
+ }
709
+ else {
710
+ console.log('✅ 複雜度分析完成!');
711
+ console.log(`📊 統計: ${results.length} 個檔案`);
712
+ console.log(` 平均複雜度: ${averageComplexity.toFixed(2)}`);
713
+ console.log(` 最高複雜度: ${maxComplexity}`);
714
+ }
715
+ }
716
+ else if (analyzeType === 'dead-code') {
717
+ const detector = new DeadCodeDetector();
718
+ // 獲取需要分析的檔案列表
719
+ const files = await this.getAllProjectFiles(analyzePath);
720
+ const results = await detector.detectInFiles(files);
721
+ // 統計結果
722
+ const allDeadCode = results.flatMap(r => r.deadCode);
723
+ const deadFunctions = allDeadCode.filter(d => d.type === 'function');
724
+ const deadVariables = allDeadCode.filter(d => d.type === 'variable');
725
+ if (options.format === 'json') {
726
+ console.log(JSON.stringify({
727
+ files: results.map(r => ({
728
+ path: r.file,
729
+ deadCode: r.deadCode
730
+ })),
731
+ deadFunctions: allDeadCode.filter(d => d.type === 'function'),
732
+ deadVariables: allDeadCode.filter(d => d.type === 'variable'),
733
+ summary: {
734
+ totalDeadFunctions: deadFunctions.length,
735
+ totalDeadVariables: deadVariables.length,
736
+ totalDeadCode: allDeadCode.length
737
+ }
738
+ }, null, 2));
739
+ }
740
+ else {
741
+ console.log('✅ 死代碼檢測完成!');
742
+ console.log('📊 發現:');
743
+ console.log(` 未使用函式: ${deadFunctions.length} 個`);
744
+ console.log(` 未使用變數: ${deadVariables.length} 個`);
745
+ }
746
+ }
747
+ else if (analyzeType === 'best-practices') {
748
+ // 檢查最佳實踐
749
+ const files = await this.getAllProjectFiles(analyzePath);
750
+ const issues = [];
751
+ const recommendations = [];
752
+ // 檢查 ES Module 使用情況
753
+ const hasEsmImports = files.some(async (file) => {
754
+ const content = await fs.readFile(file, 'utf-8');
755
+ return content.includes('import ') && content.includes('from ');
756
+ });
757
+ if (hasEsmImports) {
758
+ recommendations.push({
759
+ type: 'es-modules',
760
+ status: 'good',
761
+ message: '專案使用 ES Module'
762
+ });
763
+ }
764
+ if (options.format === 'json') {
765
+ console.log(JSON.stringify({
766
+ issues,
767
+ recommendations
768
+ }, null, 2));
769
+ }
770
+ else {
771
+ console.log('✅ 最佳實踐檢查完成!');
772
+ console.log(`📊 建議數: ${recommendations.length}`);
773
+ }
774
+ }
775
+ else if (analyzeType === 'patterns') {
776
+ // 檢測程式碼模式
777
+ const files = await this.getAllProjectFiles(analyzePath);
778
+ const patterns = [];
779
+ let asyncFunctionCount = 0;
780
+ for (const file of files) {
781
+ const content = await fs.readFile(file, 'utf-8');
782
+ // 檢測 async 函式
783
+ if (content.includes('async ')) {
784
+ asyncFunctionCount++;
785
+ if (!patterns.includes('async-functions')) {
786
+ patterns.push('async-functions');
787
+ }
788
+ }
789
+ // 檢測 Promise 使用
790
+ if (content.includes('Promise') || content.includes('.then(')) {
791
+ if (!patterns.includes('promise-usage')) {
792
+ patterns.push('promise-usage');
793
+ }
794
+ }
795
+ // TypeScript 特定模式
796
+ if (file.endsWith('.ts') || file.endsWith('.tsx')) {
797
+ // 檢測 interface 使用
798
+ if (content.includes('interface ') && !patterns.includes('interface-usage')) {
799
+ patterns.push('interface-usage');
800
+ }
801
+ // 檢測泛型類型
802
+ if (content.match(/<[A-Z]\w*(\s*extends\s+\w+)?>/g) && !patterns.includes('generic-types')) {
803
+ patterns.push('generic-types');
804
+ }
805
+ // 檢測 enum 使用
806
+ if (content.includes('enum ') && !patterns.includes('enum-usage')) {
807
+ patterns.push('enum-usage');
808
+ }
809
+ }
810
+ }
811
+ if (options.format === 'json') {
812
+ console.log(JSON.stringify({
813
+ patterns,
814
+ statistics: {
815
+ asyncFunctions: asyncFunctionCount
816
+ }
817
+ }, null, 2));
818
+ }
819
+ else {
820
+ console.log('✅ 模式檢測完成!');
821
+ console.log(`📊 發現模式: ${patterns.join(', ')}`);
822
+ }
823
+ }
824
+ else {
825
+ throw new Error(`不支援的分析類型: ${analyzeType}`);
826
+ }
827
+ }
828
+ catch (error) {
829
+ if (options.format === 'json') {
830
+ console.log(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
831
+ }
832
+ else {
833
+ console.error('❌ 分析失敗:', error instanceof Error ? error.message : error);
834
+ }
835
+ if (process.env.NODE_ENV !== 'test') {
836
+ if (process.env.NODE_ENV !== 'test') {
837
+ process.exit(1);
838
+ }
839
+ }
840
+ }
841
+ }
842
+ async handleDepsCommand(options) {
843
+ if (options.format !== 'json') {
844
+ console.log('🕸️ 分析依賴關係...');
845
+ }
846
+ try {
847
+ const analyzePath = options.path || process.cwd();
848
+ // 初始化依賴分析器
849
+ if (!this.dependencyAnalyzer) {
850
+ this.dependencyAnalyzer = new DependencyAnalyzer();
851
+ }
852
+ // 分析專案依賴
853
+ const projectDeps = await this.dependencyAnalyzer.analyzeProject(analyzePath);
854
+ // 獲取統計資訊
855
+ const stats = this.dependencyAnalyzer.getStats();
856
+ // 使用 CycleDetector 檢測循環依賴
857
+ const cycleDetector = new (await import('../../core/dependency/cycle-detector.js')).CycleDetector();
858
+ const graph = await this.buildGraphFromProjectDeps(projectDeps);
859
+ const cycles = cycleDetector.detectCycles(graph);
860
+ // 輸出結果
861
+ if (options.format === 'json') {
862
+ // 建立 nodes 和 edges 格式(為了符合測試期望)
863
+ const nodes = graph.getAllNodes().map((nodeId) => ({
864
+ id: nodeId,
865
+ dependencies: graph.getDependencies(nodeId)
866
+ }));
867
+ const edges = [];
868
+ for (const nodeId of graph.getAllNodes()) {
869
+ for (const depId of graph.getDependencies(nodeId)) {
870
+ edges.push({ source: nodeId, target: depId });
871
+ }
872
+ }
873
+ // 根據 --file 選項決定輸出格式
874
+ if (options.file) {
875
+ // 單檔案依賴查詢模式
876
+ const targetFile = path.resolve(options.file);
877
+ const dependencies = {};
878
+ dependencies[options.file] = graph.getDependencies(targetFile);
879
+ console.log(JSON.stringify({
880
+ dependencies
881
+ }, null, 2));
882
+ }
883
+ else {
884
+ // 專案依賴圖模式
885
+ console.log(JSON.stringify({
886
+ nodes,
887
+ edges,
888
+ cycles: cycles.map(c => ({
889
+ cycle: c.cycle,
890
+ length: c.length,
891
+ severity: c.severity
892
+ })),
893
+ stats: {
894
+ totalFiles: stats.totalFiles,
895
+ totalDependencies: stats.totalDependencies,
896
+ averageDependenciesPerFile: stats.averageDependenciesPerFile,
897
+ maxDependenciesInFile: stats.maxDependenciesInFile,
898
+ circularDependencies: cycles.length,
899
+ orphanedFiles: stats.orphanedFiles
900
+ }
901
+ }, null, 2));
902
+ }
903
+ }
904
+ else {
905
+ console.log('✅ 依賴分析完成!');
906
+ console.log('📊 統計:');
907
+ console.log(` 總檔案數: ${stats.totalFiles}`);
908
+ console.log(` 總依賴數: ${stats.totalDependencies}`);
909
+ console.log(` 平均依賴數: ${stats.averageDependenciesPerFile.toFixed(2)}`);
910
+ console.log(` 最大依賴數: ${stats.maxDependenciesInFile}`);
911
+ if (cycles.length > 0) {
912
+ console.log(`⚠️ 發現 ${cycles.length} 個循環依賴:`);
913
+ cycles.forEach((cycle, index) => {
914
+ console.log(` ${index + 1}. ${cycle.cycle.join(' → ')} (長度: ${cycle.length}, 嚴重性: ${cycle.severity})`);
915
+ });
916
+ }
917
+ else {
918
+ console.log('✓ 無循環依賴');
919
+ }
920
+ if (stats.orphanedFiles > 0) {
921
+ console.log(`⚠️ 發現 ${stats.orphanedFiles} 個孤立檔案`);
922
+ }
923
+ }
924
+ }
925
+ catch (error) {
926
+ if (options.format === 'json') {
927
+ console.log(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
928
+ }
929
+ else {
930
+ console.error('❌ 依賴分析失敗:', error instanceof Error ? error.message : error);
931
+ }
932
+ if (process.env.NODE_ENV !== 'test') {
933
+ if (process.env.NODE_ENV !== 'test') {
934
+ process.exit(1);
935
+ }
936
+ }
937
+ }
938
+ }
939
+ /**
940
+ * 從專案依賴資訊建立依賴圖
941
+ */
942
+ async buildGraphFromProjectDeps(projectDeps) {
943
+ const { DependencyGraph } = await import('../../core/dependency/dependency-graph.js');
944
+ const graph = new DependencyGraph();
945
+ // 新增所有檔案節點及其依賴關係
946
+ for (const fileDep of projectDeps.fileDependencies) {
947
+ graph.addNode(fileDep.filePath);
948
+ for (const dep of fileDep.dependencies) {
949
+ graph.addDependency(fileDep.filePath, dep.path);
950
+ }
951
+ }
952
+ return graph;
953
+ }
954
+ async handlePluginsListCommand(options) {
955
+ console.log('🔌 插件列表:');
956
+ const registry = ParserRegistry.getInstance();
957
+ // 確保 registry 存在且有 listParsers 方法
958
+ if (!registry || typeof registry.listParsers !== 'function') {
959
+ console.log('📝 插件系統尚未初始化');
960
+ return;
961
+ }
962
+ const parsers = registry.listParsers();
963
+ if (!parsers || parsers.length === 0) {
964
+ console.log('📝 未找到已註冊的插件');
965
+ return;
966
+ }
967
+ console.table(parsers.map(p => ({
968
+ 名稱: p.name,
969
+ 版本: p.version,
970
+ 支援副檔名: p.supportedExtensions.join(', '),
971
+ 支援語言: p.supportedLanguages.join(', '),
972
+ 註冊時間: p.registeredAt.toLocaleString()
973
+ })));
974
+ }
975
+ async handlePluginInfoCommand(pluginName) {
976
+ const registry = ParserRegistry.getInstance();
977
+ // 確保 registry 存在且有 getParserByName 方法
978
+ if (!registry || typeof registry.getParserByName !== 'function') {
979
+ console.error('❌ 插件系統尚未初始化');
980
+ if (process.env.NODE_ENV !== 'test') {
981
+ process.exit(1);
982
+ }
983
+ }
984
+ const plugin = registry.getParserByName(pluginName);
985
+ if (!plugin) {
986
+ console.error(`❌ 找不到插件: ${pluginName}`);
987
+ if (process.env.NODE_ENV !== 'test') {
988
+ process.exit(1);
989
+ }
990
+ }
991
+ console.log(`🔌 插件資訊: ${pluginName}`);
992
+ // TODO: 顯示詳細插件資訊
993
+ }
994
+ /**
995
+ * 檢查檔案是否存在
996
+ */
997
+ async fileExists(filePath) {
998
+ try {
999
+ await fs.access(filePath);
1000
+ return true;
1001
+ }
1002
+ catch {
1003
+ return false;
1004
+ }
1005
+ }
1006
+ /**
1007
+ * 套用程式碼編輯
1008
+ */
1009
+ applyCodeEdit(code, edit) {
1010
+ const lines = code.split('\n');
1011
+ const startLine = edit.range.start.line - 1; // 轉為 0-based
1012
+ const endLine = edit.range.end.line - 1;
1013
+ // 取得編輯範圍前後的內容
1014
+ const before = lines.slice(0, startLine);
1015
+ const after = lines.slice(endLine + 1);
1016
+ // 組合新的內容
1017
+ return [...before, edit.newText, ...after].join('\n');
1018
+ }
1019
+ /**
1020
+ * 獲取專案中的所有檔案
1021
+ */
1022
+ async getAllProjectFiles(projectPath) {
1023
+ const files = [];
1024
+ const allowedExtensions = ['.ts', '.tsx', '.js', '.jsx'];
1025
+ const excludePatterns = ['node_modules', 'dist', '.git', 'coverage'];
1026
+ async function walkDir(dir) {
1027
+ try {
1028
+ const entries = await fs.readdir(dir, { withFileTypes: true });
1029
+ for (const entry of entries) {
1030
+ const fullPath = path.join(dir, entry.name);
1031
+ if (entry.isDirectory()) {
1032
+ // 跳過排除的目錄
1033
+ if (excludePatterns.some(pattern => entry.name.includes(pattern))) {
1034
+ continue;
1035
+ }
1036
+ await walkDir(fullPath);
1037
+ }
1038
+ else if (entry.isFile()) {
1039
+ // 只包含支援的副檔名
1040
+ if (allowedExtensions.some(ext => entry.name.endsWith(ext))) {
1041
+ files.push(fullPath);
1042
+ }
1043
+ }
1044
+ }
1045
+ }
1046
+ catch (error) {
1047
+ // 忽略無法存取的目錄
1048
+ }
1049
+ }
1050
+ await walkDir(projectPath);
1051
+ return files;
1052
+ }
1053
+ }
1054
+ //# sourceMappingURL=cli.js.map