@defai.digital/ax-cli 4.4.6 → 4.4.10

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 (802) hide show
  1. package/bin/ax-cli +1 -5
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +158 -9
  4. package/dist/index.js.map +1 -1
  5. package/dist/setup.d.ts +27 -0
  6. package/dist/setup.d.ts.map +1 -0
  7. package/dist/setup.js +591 -0
  8. package/dist/setup.js.map +1 -0
  9. package/package.json +43 -135
  10. package/LICENSE +0 -22
  11. package/README.md +0 -387
  12. package/config-defaults/messages.yaml +0 -75
  13. package/config-defaults/models.yaml +0 -57
  14. package/config-defaults/prompts.yaml +0 -948
  15. package/config-defaults/settings.yaml +0 -157
  16. package/dist/agent/agent-executor.d.ts +0 -61
  17. package/dist/agent/agent-executor.js +0 -194
  18. package/dist/agent/agent-executor.js.map +0 -1
  19. package/dist/agent/agent-router.d.ts +0 -68
  20. package/dist/agent/agent-router.js +0 -242
  21. package/dist/agent/agent-router.js.map +0 -1
  22. package/dist/agent/context-manager.d.ts +0 -122
  23. package/dist/agent/context-manager.js +0 -406
  24. package/dist/agent/context-manager.js.map +0 -1
  25. package/dist/agent/core/index.d.ts +0 -8
  26. package/dist/agent/core/index.js +0 -9
  27. package/dist/agent/core/index.js.map +0 -1
  28. package/dist/agent/core/types.d.ts +0 -92
  29. package/dist/agent/core/types.js +0 -11
  30. package/dist/agent/core/types.js.map +0 -1
  31. package/dist/agent/dependency-resolver.d.ts +0 -90
  32. package/dist/agent/dependency-resolver.js +0 -366
  33. package/dist/agent/dependency-resolver.js.map +0 -1
  34. package/dist/agent/execution/index.d.ts +0 -9
  35. package/dist/agent/execution/index.js +0 -9
  36. package/dist/agent/execution/index.js.map +0 -1
  37. package/dist/agent/execution/tool-executor.d.ts +0 -93
  38. package/dist/agent/execution/tool-executor.js +0 -552
  39. package/dist/agent/execution/tool-executor.js.map +0 -1
  40. package/dist/agent/index.d.ts +0 -14
  41. package/dist/agent/index.js +0 -145
  42. package/dist/agent/index.js.map +0 -1
  43. package/dist/agent/llm-agent.d.ts +0 -368
  44. package/dist/agent/llm-agent.js +0 -1931
  45. package/dist/agent/llm-agent.js.map +0 -1
  46. package/dist/agent/loop-detector.d.ts +0 -72
  47. package/dist/agent/loop-detector.js +0 -335
  48. package/dist/agent/loop-detector.js.map +0 -1
  49. package/dist/agent/parallel-tools.d.ts +0 -69
  50. package/dist/agent/parallel-tools.js +0 -188
  51. package/dist/agent/parallel-tools.js.map +0 -1
  52. package/dist/agent/planning/index.d.ts +0 -9
  53. package/dist/agent/planning/index.js +0 -9
  54. package/dist/agent/planning/index.js.map +0 -1
  55. package/dist/agent/planning/plan-executor.d.ts +0 -79
  56. package/dist/agent/planning/plan-executor.js +0 -240
  57. package/dist/agent/planning/plan-executor.js.map +0 -1
  58. package/dist/agent/progress-tracker.d.ts +0 -94
  59. package/dist/agent/progress-tracker.js +0 -225
  60. package/dist/agent/progress-tracker.js.map +0 -1
  61. package/dist/agent/specialized/analysis-agent.d.ts +0 -11
  62. package/dist/agent/specialized/analysis-agent.js +0 -24
  63. package/dist/agent/specialized/analysis-agent.js.map +0 -1
  64. package/dist/agent/specialized/debug-agent.d.ts +0 -11
  65. package/dist/agent/specialized/debug-agent.js +0 -46
  66. package/dist/agent/specialized/debug-agent.js.map +0 -1
  67. package/dist/agent/specialized/documentation-agent.d.ts +0 -11
  68. package/dist/agent/specialized/documentation-agent.js +0 -24
  69. package/dist/agent/specialized/documentation-agent.js.map +0 -1
  70. package/dist/agent/specialized/index.d.ts +0 -11
  71. package/dist/agent/specialized/index.js +0 -12
  72. package/dist/agent/specialized/index.js.map +0 -1
  73. package/dist/agent/specialized/performance-agent.d.ts +0 -11
  74. package/dist/agent/specialized/performance-agent.js +0 -24
  75. package/dist/agent/specialized/performance-agent.js.map +0 -1
  76. package/dist/agent/specialized/refactoring-agent.d.ts +0 -11
  77. package/dist/agent/specialized/refactoring-agent.js +0 -24
  78. package/dist/agent/specialized/refactoring-agent.js.map +0 -1
  79. package/dist/agent/specialized/testing-agent.d.ts +0 -11
  80. package/dist/agent/specialized/testing-agent.js +0 -24
  81. package/dist/agent/specialized/testing-agent.js.map +0 -1
  82. package/dist/agent/status-reporter.d.ts +0 -114
  83. package/dist/agent/status-reporter.js +0 -335
  84. package/dist/agent/status-reporter.js.map +0 -1
  85. package/dist/agent/streaming/index.d.ts +0 -9
  86. package/dist/agent/streaming/index.js +0 -9
  87. package/dist/agent/streaming/index.js.map +0 -1
  88. package/dist/agent/streaming/stream-handler.d.ts +0 -62
  89. package/dist/agent/streaming/stream-handler.js +0 -217
  90. package/dist/agent/streaming/stream-handler.js.map +0 -1
  91. package/dist/agent/subagent-orchestrator.d.ts +0 -166
  92. package/dist/agent/subagent-orchestrator.js +0 -487
  93. package/dist/agent/subagent-orchestrator.js.map +0 -1
  94. package/dist/agent/subagent-types.d.ts +0 -261
  95. package/dist/agent/subagent-types.js +0 -257
  96. package/dist/agent/subagent-types.js.map +0 -1
  97. package/dist/agent/subagent.d.ts +0 -116
  98. package/dist/agent/subagent.js +0 -507
  99. package/dist/agent/subagent.js.map +0 -1
  100. package/dist/checkpoint/index.d.ts +0 -9
  101. package/dist/checkpoint/index.js +0 -11
  102. package/dist/checkpoint/index.js.map +0 -1
  103. package/dist/checkpoint/manager.d.ts +0 -101
  104. package/dist/checkpoint/manager.js +0 -407
  105. package/dist/checkpoint/manager.js.map +0 -1
  106. package/dist/checkpoint/storage.d.ts +0 -39
  107. package/dist/checkpoint/storage.js +0 -350
  108. package/dist/checkpoint/storage.js.map +0 -1
  109. package/dist/checkpoint/types.d.ts +0 -111
  110. package/dist/checkpoint/types.js +0 -17
  111. package/dist/checkpoint/types.js.map +0 -1
  112. package/dist/commands/cache.d.ts +0 -7
  113. package/dist/commands/cache.js +0 -284
  114. package/dist/commands/cache.js.map +0 -1
  115. package/dist/commands/custom-commands.d.ts +0 -77
  116. package/dist/commands/custom-commands.js +0 -251
  117. package/dist/commands/custom-commands.js.map +0 -1
  118. package/dist/commands/design.d.ts +0 -18
  119. package/dist/commands/design.js +0 -511
  120. package/dist/commands/design.js.map +0 -1
  121. package/dist/commands/doctor.d.ts +0 -6
  122. package/dist/commands/doctor.js +0 -773
  123. package/dist/commands/doctor.js.map +0 -1
  124. package/dist/commands/frontend.d.ts +0 -9
  125. package/dist/commands/frontend.js +0 -645
  126. package/dist/commands/frontend.js.map +0 -1
  127. package/dist/commands/init/wizard.d.ts +0 -55
  128. package/dist/commands/init/wizard.js +0 -189
  129. package/dist/commands/init/wizard.js.map +0 -1
  130. package/dist/commands/init.d.ts +0 -8
  131. package/dist/commands/init.js +0 -195
  132. package/dist/commands/init.js.map +0 -1
  133. package/dist/commands/mcp-migrate.d.ts +0 -9
  134. package/dist/commands/mcp-migrate.js +0 -175
  135. package/dist/commands/mcp-migrate.js.map +0 -1
  136. package/dist/commands/mcp.d.ts +0 -2
  137. package/dist/commands/mcp.js +0 -1292
  138. package/dist/commands/mcp.js.map +0 -1
  139. package/dist/commands/memory.d.ts +0 -6
  140. package/dist/commands/memory.js +0 -555
  141. package/dist/commands/memory.js.map +0 -1
  142. package/dist/commands/models.d.ts +0 -5
  143. package/dist/commands/models.js +0 -213
  144. package/dist/commands/models.js.map +0 -1
  145. package/dist/commands/plan.d.ts +0 -43
  146. package/dist/commands/plan.js +0 -362
  147. package/dist/commands/plan.js.map +0 -1
  148. package/dist/commands/rewind.d.ts +0 -19
  149. package/dist/commands/rewind.js +0 -221
  150. package/dist/commands/rewind.js.map +0 -1
  151. package/dist/commands/setup.d.ts +0 -14
  152. package/dist/commands/setup.js +0 -733
  153. package/dist/commands/setup.js.map +0 -1
  154. package/dist/commands/status.d.ts +0 -7
  155. package/dist/commands/status.js +0 -437
  156. package/dist/commands/status.js.map +0 -1
  157. package/dist/commands/templates.d.ts +0 -5
  158. package/dist/commands/templates.js +0 -245
  159. package/dist/commands/templates.js.map +0 -1
  160. package/dist/commands/update.d.ts +0 -49
  161. package/dist/commands/update.js +0 -366
  162. package/dist/commands/update.js.map +0 -1
  163. package/dist/commands/usage.d.ts +0 -8
  164. package/dist/commands/usage.js +0 -264
  165. package/dist/commands/usage.js.map +0 -1
  166. package/dist/commands/vscode.d.ts +0 -7
  167. package/dist/commands/vscode.js +0 -419
  168. package/dist/commands/vscode.js.map +0 -1
  169. package/dist/constants.d.ts +0 -236
  170. package/dist/constants.js +0 -288
  171. package/dist/constants.js.map +0 -1
  172. package/dist/design/figma-alias.d.ts +0 -170
  173. package/dist/design/figma-alias.js +0 -577
  174. package/dist/design/figma-alias.js.map +0 -1
  175. package/dist/design/figma-audit.d.ts +0 -40
  176. package/dist/design/figma-audit.js +0 -383
  177. package/dist/design/figma-audit.js.map +0 -1
  178. package/dist/design/figma-client.d.ts +0 -131
  179. package/dist/design/figma-client.js +0 -369
  180. package/dist/design/figma-client.js.map +0 -1
  181. package/dist/design/figma-map.d.ts +0 -29
  182. package/dist/design/figma-map.js +0 -346
  183. package/dist/design/figma-map.js.map +0 -1
  184. package/dist/design/figma-tokens.d.ts +0 -73
  185. package/dist/design/figma-tokens.js +0 -448
  186. package/dist/design/figma-tokens.js.map +0 -1
  187. package/dist/design/index.d.ts +0 -13
  188. package/dist/design/index.js +0 -20
  189. package/dist/design/index.js.map +0 -1
  190. package/dist/design/types.d.ts +0 -98
  191. package/dist/design/types.js +0 -9
  192. package/dist/design/types.js.map +0 -1
  193. package/dist/hooks/hook-runner.d.ts +0 -142
  194. package/dist/hooks/hook-runner.js +0 -436
  195. package/dist/hooks/hook-runner.js.map +0 -1
  196. package/dist/hooks/index.d.ts +0 -9
  197. package/dist/hooks/index.js +0 -10
  198. package/dist/hooks/index.js.map +0 -1
  199. package/dist/hooks/manager.d.ts +0 -84
  200. package/dist/hooks/manager.js +0 -348
  201. package/dist/hooks/manager.js.map +0 -1
  202. package/dist/hooks/types.d.ts +0 -134
  203. package/dist/hooks/types.js +0 -9
  204. package/dist/hooks/types.js.map +0 -1
  205. package/dist/index.d.ts +0 -2
  206. package/dist/ipc/index.d.ts +0 -9
  207. package/dist/ipc/index.js +0 -10
  208. package/dist/ipc/index.js.map +0 -1
  209. package/dist/ipc/vscode-client.d.ts +0 -200
  210. package/dist/ipc/vscode-client.js +0 -495
  211. package/dist/ipc/vscode-client.js.map +0 -1
  212. package/dist/llm/client.d.ts +0 -205
  213. package/dist/llm/client.js +0 -735
  214. package/dist/llm/client.js.map +0 -1
  215. package/dist/llm/tools.d.ts +0 -102
  216. package/dist/llm/tools.js +0 -275
  217. package/dist/llm/tools.js.map +0 -1
  218. package/dist/llm/types.d.ts +0 -428
  219. package/dist/llm/types.js +0 -194
  220. package/dist/llm/types.js.map +0 -1
  221. package/dist/mcp/automatosx-auto-discovery.d.ts +0 -66
  222. package/dist/mcp/automatosx-auto-discovery.js +0 -169
  223. package/dist/mcp/automatosx-auto-discovery.js.map +0 -1
  224. package/dist/mcp/automatosx-loader.d.ts +0 -99
  225. package/dist/mcp/automatosx-loader.js +0 -250
  226. package/dist/mcp/automatosx-loader.js.map +0 -1
  227. package/dist/mcp/cancellation.d.ts +0 -182
  228. package/dist/mcp/cancellation.js +0 -275
  229. package/dist/mcp/cancellation.js.map +0 -1
  230. package/dist/mcp/client-v2.d.ts +0 -500
  231. package/dist/mcp/client-v2.js +0 -1433
  232. package/dist/mcp/client-v2.js.map +0 -1
  233. package/dist/mcp/client.d.ts +0 -170
  234. package/dist/mcp/client.js +0 -232
  235. package/dist/mcp/client.js.map +0 -1
  236. package/dist/mcp/config-detector.d.ts +0 -90
  237. package/dist/mcp/config-detector.js +0 -250
  238. package/dist/mcp/config-detector.js.map +0 -1
  239. package/dist/mcp/config-migrator.d.ts +0 -68
  240. package/dist/mcp/config-migrator.js +0 -291
  241. package/dist/mcp/config-migrator.js.map +0 -1
  242. package/dist/mcp/config.d.ts +0 -24
  243. package/dist/mcp/config.js +0 -273
  244. package/dist/mcp/config.js.map +0 -1
  245. package/dist/mcp/constants.d.ts +0 -66
  246. package/dist/mcp/constants.js +0 -85
  247. package/dist/mcp/constants.js.map +0 -1
  248. package/dist/mcp/content-length-transport.d.ts +0 -106
  249. package/dist/mcp/content-length-transport.js +0 -413
  250. package/dist/mcp/content-length-transport.js.map +0 -1
  251. package/dist/mcp/debug.d.ts +0 -211
  252. package/dist/mcp/debug.js +0 -404
  253. package/dist/mcp/debug.js.map +0 -1
  254. package/dist/mcp/error-formatter.d.ts +0 -40
  255. package/dist/mcp/error-formatter.js +0 -207
  256. package/dist/mcp/error-formatter.js.map +0 -1
  257. package/dist/mcp/error-remediation.d.ts +0 -45
  258. package/dist/mcp/error-remediation.js +0 -291
  259. package/dist/mcp/error-remediation.js.map +0 -1
  260. package/dist/mcp/health.d.ts +0 -120
  261. package/dist/mcp/health.js +0 -267
  262. package/dist/mcp/health.js.map +0 -1
  263. package/dist/mcp/index.d.ts +0 -56
  264. package/dist/mcp/index.js +0 -89
  265. package/dist/mcp/index.js.map +0 -1
  266. package/dist/mcp/invariants.d.ts +0 -141
  267. package/dist/mcp/invariants.js +0 -243
  268. package/dist/mcp/invariants.js.map +0 -1
  269. package/dist/mcp/mutex-safe.d.ts +0 -151
  270. package/dist/mcp/mutex-safe.js +0 -260
  271. package/dist/mcp/mutex-safe.js.map +0 -1
  272. package/dist/mcp/progress.d.ts +0 -155
  273. package/dist/mcp/progress.js +0 -252
  274. package/dist/mcp/progress.js.map +0 -1
  275. package/dist/mcp/prompts.d.ts +0 -68
  276. package/dist/mcp/prompts.js +0 -129
  277. package/dist/mcp/prompts.js.map +0 -1
  278. package/dist/mcp/provider-mcp-loader.d.ts +0 -130
  279. package/dist/mcp/provider-mcp-loader.js +0 -292
  280. package/dist/mcp/provider-mcp-loader.js.map +0 -1
  281. package/dist/mcp/reconnection.d.ts +0 -101
  282. package/dist/mcp/reconnection.js +0 -253
  283. package/dist/mcp/reconnection.js.map +0 -1
  284. package/dist/mcp/registry.d.ts +0 -75
  285. package/dist/mcp/registry.js +0 -276
  286. package/dist/mcp/registry.js.map +0 -1
  287. package/dist/mcp/resources.d.ts +0 -58
  288. package/dist/mcp/resources.js +0 -144
  289. package/dist/mcp/resources.js.map +0 -1
  290. package/dist/mcp/schema-validator.d.ts +0 -82
  291. package/dist/mcp/schema-validator.js +0 -161
  292. package/dist/mcp/schema-validator.js.map +0 -1
  293. package/dist/mcp/ssrf-protection.d.ts +0 -86
  294. package/dist/mcp/ssrf-protection.js +0 -311
  295. package/dist/mcp/ssrf-protection.js.map +0 -1
  296. package/dist/mcp/subscriptions.d.ts +0 -168
  297. package/dist/mcp/subscriptions.js +0 -248
  298. package/dist/mcp/subscriptions.js.map +0 -1
  299. package/dist/mcp/templates.d.ts +0 -52
  300. package/dist/mcp/templates.js +0 -627
  301. package/dist/mcp/templates.js.map +0 -1
  302. package/dist/mcp/transports.d.ts +0 -80
  303. package/dist/mcp/transports.js +0 -237
  304. package/dist/mcp/transports.js.map +0 -1
  305. package/dist/mcp/type-safety.d.ts +0 -225
  306. package/dist/mcp/type-safety.js +0 -237
  307. package/dist/mcp/type-safety.js.map +0 -1
  308. package/dist/mcp/validation.d.ts +0 -29
  309. package/dist/mcp/validation.js +0 -339
  310. package/dist/mcp/validation.js.map +0 -1
  311. package/dist/mcp/zai-detector.d.ts +0 -63
  312. package/dist/mcp/zai-detector.js +0 -193
  313. package/dist/mcp/zai-detector.js.map +0 -1
  314. package/dist/mcp/zai-templates.d.ts +0 -90
  315. package/dist/mcp/zai-templates.js +0 -157
  316. package/dist/mcp/zai-templates.js.map +0 -1
  317. package/dist/memory/context-generator.d.ts +0 -84
  318. package/dist/memory/context-generator.js +0 -546
  319. package/dist/memory/context-generator.js.map +0 -1
  320. package/dist/memory/context-injector.d.ts +0 -97
  321. package/dist/memory/context-injector.js +0 -159
  322. package/dist/memory/context-injector.js.map +0 -1
  323. package/dist/memory/context-store.d.ts +0 -103
  324. package/dist/memory/context-store.js +0 -264
  325. package/dist/memory/context-store.js.map +0 -1
  326. package/dist/memory/index.d.ts +0 -43
  327. package/dist/memory/index.js +0 -49
  328. package/dist/memory/index.js.map +0 -1
  329. package/dist/memory/provider-context-store.d.ts +0 -127
  330. package/dist/memory/provider-context-store.js +0 -385
  331. package/dist/memory/provider-context-store.js.map +0 -1
  332. package/dist/memory/schemas.d.ts +0 -118
  333. package/dist/memory/schemas.js +0 -106
  334. package/dist/memory/schemas.js.map +0 -1
  335. package/dist/memory/stats-collector.d.ts +0 -73
  336. package/dist/memory/stats-collector.js +0 -170
  337. package/dist/memory/stats-collector.js.map +0 -1
  338. package/dist/memory/types.d.ts +0 -177
  339. package/dist/memory/types.js +0 -73
  340. package/dist/memory/types.js.map +0 -1
  341. package/dist/permissions/index.d.ts +0 -6
  342. package/dist/permissions/index.js +0 -7
  343. package/dist/permissions/index.js.map +0 -1
  344. package/dist/permissions/permission-manager.d.ts +0 -149
  345. package/dist/permissions/permission-manager.js +0 -410
  346. package/dist/permissions/permission-manager.js.map +0 -1
  347. package/dist/planner/dependency-resolver.d.ts +0 -72
  348. package/dist/planner/dependency-resolver.js +0 -272
  349. package/dist/planner/dependency-resolver.js.map +0 -1
  350. package/dist/planner/index.d.ts +0 -12
  351. package/dist/planner/index.js +0 -28
  352. package/dist/planner/index.js.map +0 -1
  353. package/dist/planner/plan-generator.d.ts +0 -74
  354. package/dist/planner/plan-generator.js +0 -244
  355. package/dist/planner/plan-generator.js.map +0 -1
  356. package/dist/planner/plan-storage.d.ts +0 -113
  357. package/dist/planner/plan-storage.js +0 -398
  358. package/dist/planner/plan-storage.js.map +0 -1
  359. package/dist/planner/prompts/planning-prompt.d.ts +0 -62
  360. package/dist/planner/prompts/planning-prompt.js +0 -414
  361. package/dist/planner/prompts/planning-prompt.js.map +0 -1
  362. package/dist/planner/task-planner.d.ts +0 -139
  363. package/dist/planner/task-planner.js +0 -532
  364. package/dist/planner/task-planner.js.map +0 -1
  365. package/dist/planner/token-estimator.d.ts +0 -63
  366. package/dist/planner/token-estimator.js +0 -295
  367. package/dist/planner/token-estimator.js.map +0 -1
  368. package/dist/planner/types.d.ts +0 -425
  369. package/dist/planner/types.js +0 -213
  370. package/dist/planner/types.js.map +0 -1
  371. package/dist/provider/config.d.ts +0 -227
  372. package/dist/provider/config.js +0 -430
  373. package/dist/provider/config.js.map +0 -1
  374. package/dist/schemas/api-schemas.d.ts +0 -45
  375. package/dist/schemas/api-schemas.js +0 -129
  376. package/dist/schemas/api-schemas.js.map +0 -1
  377. package/dist/schemas/confirmation-schemas.d.ts +0 -39
  378. package/dist/schemas/confirmation-schemas.js +0 -48
  379. package/dist/schemas/confirmation-schemas.js.map +0 -1
  380. package/dist/schemas/index-unified.d.ts +0 -12
  381. package/dist/schemas/index-unified.js +0 -17
  382. package/dist/schemas/index-unified.js.map +0 -1
  383. package/dist/schemas/index.d.ts +0 -83
  384. package/dist/schemas/index.js +0 -139
  385. package/dist/schemas/index.js.map +0 -1
  386. package/dist/schemas/settings-schemas.d.ts +0 -186
  387. package/dist/schemas/settings-schemas.js +0 -324
  388. package/dist/schemas/settings-schemas.js.map +0 -1
  389. package/dist/schemas/tool-schemas.d.ts +0 -127
  390. package/dist/schemas/tool-schemas.js +0 -84
  391. package/dist/schemas/tool-schemas.js.map +0 -1
  392. package/dist/schemas/yaml-schemas.d.ts +0 -231
  393. package/dist/schemas/yaml-schemas.js +0 -199
  394. package/dist/schemas/yaml-schemas.js.map +0 -1
  395. package/dist/sdk/errors.d.ts +0 -100
  396. package/dist/sdk/errors.js +0 -138
  397. package/dist/sdk/errors.js.map +0 -1
  398. package/dist/sdk/index.d.ts +0 -901
  399. package/dist/sdk/index.js +0 -1272
  400. package/dist/sdk/index.js.map +0 -1
  401. package/dist/sdk/progress-reporter.d.ts +0 -123
  402. package/dist/sdk/progress-reporter.js +0 -220
  403. package/dist/sdk/progress-reporter.js.map +0 -1
  404. package/dist/sdk/testing.d.ts +0 -427
  405. package/dist/sdk/testing.js +0 -725
  406. package/dist/sdk/testing.js.map +0 -1
  407. package/dist/sdk/tool-registry.d.ts +0 -194
  408. package/dist/sdk/tool-registry.js +0 -326
  409. package/dist/sdk/tool-registry.js.map +0 -1
  410. package/dist/sdk/types.d.ts +0 -53
  411. package/dist/sdk/types.js +0 -8
  412. package/dist/sdk/types.js.map +0 -1
  413. package/dist/sdk/unified-logger.d.ts +0 -173
  414. package/dist/sdk/unified-logger.js +0 -327
  415. package/dist/sdk/unified-logger.js.map +0 -1
  416. package/dist/sdk/version.d.ts +0 -163
  417. package/dist/sdk/version.js +0 -205
  418. package/dist/sdk/version.js.map +0 -1
  419. package/dist/tools/ask-user.d.ts +0 -126
  420. package/dist/tools/ask-user.js +0 -290
  421. package/dist/tools/ask-user.js.map +0 -1
  422. package/dist/tools/ax-agent.d.ts +0 -71
  423. package/dist/tools/ax-agent.js +0 -283
  424. package/dist/tools/ax-agent.js.map +0 -1
  425. package/dist/tools/bash-output.d.ts +0 -25
  426. package/dist/tools/bash-output.js +0 -146
  427. package/dist/tools/bash-output.js.map +0 -1
  428. package/dist/tools/bash.d.ts +0 -67
  429. package/dist/tools/bash.js +0 -522
  430. package/dist/tools/bash.js.map +0 -1
  431. package/dist/tools/confirmation-tool.d.ts +0 -16
  432. package/dist/tools/confirmation-tool.js +0 -76
  433. package/dist/tools/confirmation-tool.js.map +0 -1
  434. package/dist/tools/definitions/ask-user.d.ts +0 -8
  435. package/dist/tools/definitions/ask-user.js +0 -168
  436. package/dist/tools/definitions/ask-user.js.map +0 -1
  437. package/dist/tools/definitions/ax-agent.d.ts +0 -8
  438. package/dist/tools/definitions/ax-agent.js +0 -276
  439. package/dist/tools/definitions/ax-agent.js.map +0 -1
  440. package/dist/tools/definitions/bash-output.d.ts +0 -7
  441. package/dist/tools/definitions/bash-output.js +0 -78
  442. package/dist/tools/definitions/bash-output.js.map +0 -1
  443. package/dist/tools/definitions/bash.d.ts +0 -8
  444. package/dist/tools/definitions/bash.js +0 -152
  445. package/dist/tools/definitions/bash.js.map +0 -1
  446. package/dist/tools/definitions/create-file.d.ts +0 -7
  447. package/dist/tools/definitions/create-file.js +0 -129
  448. package/dist/tools/definitions/create-file.js.map +0 -1
  449. package/dist/tools/definitions/design.d.ts +0 -12
  450. package/dist/tools/definitions/design.js +0 -368
  451. package/dist/tools/definitions/design.js.map +0 -1
  452. package/dist/tools/definitions/index.d.ts +0 -49
  453. package/dist/tools/definitions/index.js +0 -87
  454. package/dist/tools/definitions/index.js.map +0 -1
  455. package/dist/tools/definitions/multi-edit.d.ts +0 -7
  456. package/dist/tools/definitions/multi-edit.js +0 -123
  457. package/dist/tools/definitions/multi-edit.js.map +0 -1
  458. package/dist/tools/definitions/search.d.ts +0 -7
  459. package/dist/tools/definitions/search.js +0 -159
  460. package/dist/tools/definitions/search.js.map +0 -1
  461. package/dist/tools/definitions/str-replace-editor.d.ts +0 -7
  462. package/dist/tools/definitions/str-replace-editor.js +0 -145
  463. package/dist/tools/definitions/str-replace-editor.js.map +0 -1
  464. package/dist/tools/definitions/todo.d.ts +0 -8
  465. package/dist/tools/definitions/todo.js +0 -261
  466. package/dist/tools/definitions/todo.js.map +0 -1
  467. package/dist/tools/definitions/view-file.d.ts +0 -7
  468. package/dist/tools/definitions/view-file.js +0 -111
  469. package/dist/tools/definitions/view-file.js.map +0 -1
  470. package/dist/tools/design-tool.d.ts +0 -68
  471. package/dist/tools/design-tool.js +0 -299
  472. package/dist/tools/design-tool.js.map +0 -1
  473. package/dist/tools/format-generators.d.ts +0 -62
  474. package/dist/tools/format-generators.js +0 -291
  475. package/dist/tools/format-generators.js.map +0 -1
  476. package/dist/tools/index.d.ts +0 -8
  477. package/dist/tools/index.js +0 -11
  478. package/dist/tools/index.js.map +0 -1
  479. package/dist/tools/priority-registry.d.ts +0 -124
  480. package/dist/tools/priority-registry.js +0 -401
  481. package/dist/tools/priority-registry.js.map +0 -1
  482. package/dist/tools/priority.d.ts +0 -158
  483. package/dist/tools/priority.js +0 -350
  484. package/dist/tools/priority.js.map +0 -1
  485. package/dist/tools/registry.d.ts +0 -146
  486. package/dist/tools/registry.js +0 -171
  487. package/dist/tools/registry.js.map +0 -1
  488. package/dist/tools/search.d.ts +0 -85
  489. package/dist/tools/search.js +0 -430
  490. package/dist/tools/search.js.map +0 -1
  491. package/dist/tools/text-editor.d.ts +0 -87
  492. package/dist/tools/text-editor.js +0 -1369
  493. package/dist/tools/text-editor.js.map +0 -1
  494. package/dist/tools/todo-tool.d.ts +0 -20
  495. package/dist/tools/todo-tool.js +0 -186
  496. package/dist/tools/todo-tool.js.map +0 -1
  497. package/dist/tools/types.d.ts +0 -175
  498. package/dist/tools/types.js +0 -11
  499. package/dist/tools/types.js.map +0 -1
  500. package/dist/types/index.d.ts +0 -30
  501. package/dist/types/index.js +0 -2
  502. package/dist/types/index.js.map +0 -1
  503. package/dist/types/project-analysis.d.ts +0 -84
  504. package/dist/types/project-analysis.js +0 -5
  505. package/dist/types/project-analysis.js.map +0 -1
  506. package/dist/types/template.d.ts +0 -53
  507. package/dist/types/template.js +0 -5
  508. package/dist/types/template.js.map +0 -1
  509. package/dist/ui/app.d.ts +0 -7
  510. package/dist/ui/app.js +0 -102
  511. package/dist/ui/app.js.map +0 -1
  512. package/dist/ui/components/api-key-input.d.ts +0 -7
  513. package/dist/ui/components/api-key-input.js +0 -92
  514. package/dist/ui/components/api-key-input.js.map +0 -1
  515. package/dist/ui/components/chat-history.d.ts +0 -12
  516. package/dist/ui/components/chat-history.js +0 -391
  517. package/dist/ui/components/chat-history.js.map +0 -1
  518. package/dist/ui/components/chat-input.d.ts +0 -13
  519. package/dist/ui/components/chat-input.js +0 -179
  520. package/dist/ui/components/chat-input.js.map +0 -1
  521. package/dist/ui/components/chat-interface.d.ts +0 -11
  522. package/dist/ui/components/chat-interface.js +0 -830
  523. package/dist/ui/components/chat-interface.js.map +0 -1
  524. package/dist/ui/components/collapsible-tool-result.d.ts +0 -42
  525. package/dist/ui/components/collapsible-tool-result.js +0 -216
  526. package/dist/ui/components/collapsible-tool-result.js.map +0 -1
  527. package/dist/ui/components/command-suggestions.d.ts +0 -29
  528. package/dist/ui/components/command-suggestions.js +0 -88
  529. package/dist/ui/components/command-suggestions.js.map +0 -1
  530. package/dist/ui/components/confirmation-dialog.d.ts +0 -11
  531. package/dist/ui/components/confirmation-dialog.js +0 -100
  532. package/dist/ui/components/confirmation-dialog.js.map +0 -1
  533. package/dist/ui/components/context-breakdown.d.ts +0 -23
  534. package/dist/ui/components/context-breakdown.js +0 -124
  535. package/dist/ui/components/context-breakdown.js.map +0 -1
  536. package/dist/ui/components/diff-renderer.d.ts +0 -13
  537. package/dist/ui/components/diff-renderer.js +0 -192
  538. package/dist/ui/components/diff-renderer.js.map +0 -1
  539. package/dist/ui/components/index.d.ts +0 -18
  540. package/dist/ui/components/index.js +0 -20
  541. package/dist/ui/components/index.js.map +0 -1
  542. package/dist/ui/components/keyboard-help.d.ts +0 -17
  543. package/dist/ui/components/keyboard-help.js +0 -122
  544. package/dist/ui/components/keyboard-help.js.map +0 -1
  545. package/dist/ui/components/keyboard-hints.d.ts +0 -35
  546. package/dist/ui/components/keyboard-hints.js +0 -142
  547. package/dist/ui/components/keyboard-hints.js.map +0 -1
  548. package/dist/ui/components/loading-spinner.d.ts +0 -9
  549. package/dist/ui/components/loading-spinner.js +0 -120
  550. package/dist/ui/components/loading-spinner.js.map +0 -1
  551. package/dist/ui/components/mcp-dashboard.d.ts +0 -15
  552. package/dist/ui/components/mcp-dashboard.js +0 -520
  553. package/dist/ui/components/mcp-dashboard.js.map +0 -1
  554. package/dist/ui/components/mcp-status.d.ts +0 -5
  555. package/dist/ui/components/mcp-status.js +0 -58
  556. package/dist/ui/components/mcp-status.js.map +0 -1
  557. package/dist/ui/components/model-selection.d.ts +0 -12
  558. package/dist/ui/components/model-selection.js +0 -17
  559. package/dist/ui/components/model-selection.js.map +0 -1
  560. package/dist/ui/components/phase-progress.d.ts +0 -21
  561. package/dist/ui/components/phase-progress.js +0 -185
  562. package/dist/ui/components/phase-progress.js.map +0 -1
  563. package/dist/ui/components/question-dialog.d.ts +0 -17
  564. package/dist/ui/components/question-dialog.js +0 -181
  565. package/dist/ui/components/question-dialog.js.map +0 -1
  566. package/dist/ui/components/quick-actions.d.ts +0 -12
  567. package/dist/ui/components/quick-actions.js +0 -171
  568. package/dist/ui/components/quick-actions.js.map +0 -1
  569. package/dist/ui/components/reasoning-display.d.ts +0 -36
  570. package/dist/ui/components/reasoning-display.js +0 -46
  571. package/dist/ui/components/reasoning-display.js.map +0 -1
  572. package/dist/ui/components/status-bar.d.ts +0 -47
  573. package/dist/ui/components/status-bar.js +0 -310
  574. package/dist/ui/components/status-bar.js.map +0 -1
  575. package/dist/ui/components/subagent-monitor.d.ts +0 -41
  576. package/dist/ui/components/subagent-monitor.js +0 -122
  577. package/dist/ui/components/subagent-monitor.js.map +0 -1
  578. package/dist/ui/components/toast-notification.d.ts +0 -197
  579. package/dist/ui/components/toast-notification.js +0 -190
  580. package/dist/ui/components/toast-notification.js.map +0 -1
  581. package/dist/ui/components/tool-group-display.d.ts +0 -19
  582. package/dist/ui/components/tool-group-display.js +0 -222
  583. package/dist/ui/components/tool-group-display.js.map +0 -1
  584. package/dist/ui/components/virtualized-chat-history.d.ts +0 -33
  585. package/dist/ui/components/virtualized-chat-history.js +0 -182
  586. package/dist/ui/components/virtualized-chat-history.js.map +0 -1
  587. package/dist/ui/components/welcome-panel.d.ts +0 -11
  588. package/dist/ui/components/welcome-panel.js +0 -225
  589. package/dist/ui/components/welcome-panel.js.map +0 -1
  590. package/dist/ui/hooks/use-chat-reducer.d.ts +0 -69
  591. package/dist/ui/hooks/use-chat-reducer.js +0 -118
  592. package/dist/ui/hooks/use-chat-reducer.js.map +0 -1
  593. package/dist/ui/hooks/use-enhanced-input.d.ts +0 -53
  594. package/dist/ui/hooks/use-enhanced-input.js +0 -1275
  595. package/dist/ui/hooks/use-enhanced-input.js.map +0 -1
  596. package/dist/ui/hooks/use-input-handler.d.ts +0 -79
  597. package/dist/ui/hooks/use-input-handler.js +0 -2251
  598. package/dist/ui/hooks/use-input-handler.js.map +0 -1
  599. package/dist/ui/hooks/use-input-history.d.ts +0 -9
  600. package/dist/ui/hooks/use-input-history.js +0 -168
  601. package/dist/ui/hooks/use-input-history.js.map +0 -1
  602. package/dist/ui/shared/max-sized-box.d.ts +0 -17
  603. package/dist/ui/shared/max-sized-box.js +0 -14
  604. package/dist/ui/shared/max-sized-box.js.map +0 -1
  605. package/dist/ui/themes/index.d.ts +0 -5
  606. package/dist/ui/themes/index.js +0 -5
  607. package/dist/ui/themes/index.js.map +0 -1
  608. package/dist/ui/themes/theme-registry.d.ts +0 -55
  609. package/dist/ui/themes/theme-registry.js +0 -202
  610. package/dist/ui/themes/theme-registry.js.map +0 -1
  611. package/dist/ui/utils/bracketed-paste-handler.d.ts +0 -97
  612. package/dist/ui/utils/bracketed-paste-handler.js +0 -322
  613. package/dist/ui/utils/bracketed-paste-handler.js.map +0 -1
  614. package/dist/ui/utils/change-summarizer.d.ts +0 -20
  615. package/dist/ui/utils/change-summarizer.js +0 -282
  616. package/dist/ui/utils/change-summarizer.js.map +0 -1
  617. package/dist/ui/utils/code-colorizer.d.ts +0 -9
  618. package/dist/ui/utils/code-colorizer.js +0 -13
  619. package/dist/ui/utils/code-colorizer.js.map +0 -1
  620. package/dist/ui/utils/colors.d.ts +0 -41
  621. package/dist/ui/utils/colors.js +0 -80
  622. package/dist/ui/utils/colors.js.map +0 -1
  623. package/dist/ui/utils/image-handler.d.ts +0 -29
  624. package/dist/ui/utils/image-handler.js +0 -129
  625. package/dist/ui/utils/image-handler.js.map +0 -1
  626. package/dist/ui/utils/markdown-renderer.d.ts +0 -4
  627. package/dist/ui/utils/markdown-renderer.js +0 -40
  628. package/dist/ui/utils/markdown-renderer.js.map +0 -1
  629. package/dist/ui/utils/semantic-action-detector.d.ts +0 -49
  630. package/dist/ui/utils/semantic-action-detector.js +0 -339
  631. package/dist/ui/utils/semantic-action-detector.js.map +0 -1
  632. package/dist/ui/utils/tool-grouper.d.ts +0 -94
  633. package/dist/ui/utils/tool-grouper.js +0 -618
  634. package/dist/ui/utils/tool-grouper.js.map +0 -1
  635. package/dist/utils/api-error.d.ts +0 -61
  636. package/dist/utils/api-error.js +0 -176
  637. package/dist/utils/api-error.js.map +0 -1
  638. package/dist/utils/audit-logger.d.ts +0 -206
  639. package/dist/utils/audit-logger.js +0 -286
  640. package/dist/utils/audit-logger.js.map +0 -1
  641. package/dist/utils/auto-accept-logger.d.ts +0 -175
  642. package/dist/utils/auto-accept-logger.js +0 -423
  643. package/dist/utils/auto-accept-logger.js.map +0 -1
  644. package/dist/utils/automatosx-detector.d.ts +0 -19
  645. package/dist/utils/automatosx-detector.js +0 -52
  646. package/dist/utils/automatosx-detector.js.map +0 -1
  647. package/dist/utils/background-task-manager.d.ts +0 -114
  648. package/dist/utils/background-task-manager.js +0 -470
  649. package/dist/utils/background-task-manager.js.map +0 -1
  650. package/dist/utils/cache.d.ts +0 -77
  651. package/dist/utils/cache.js +0 -180
  652. package/dist/utils/cache.js.map +0 -1
  653. package/dist/utils/command-security.d.ts +0 -85
  654. package/dist/utils/command-security.js +0 -210
  655. package/dist/utils/command-security.js.map +0 -1
  656. package/dist/utils/config-loader.d.ts +0 -190
  657. package/dist/utils/config-loader.js +0 -108
  658. package/dist/utils/config-loader.js.map +0 -1
  659. package/dist/utils/confirmation-service.d.ts +0 -51
  660. package/dist/utils/confirmation-service.js +0 -220
  661. package/dist/utils/confirmation-service.js.map +0 -1
  662. package/dist/utils/console-messenger.d.ts +0 -80
  663. package/dist/utils/console-messenger.js +0 -142
  664. package/dist/utils/console-messenger.js.map +0 -1
  665. package/dist/utils/custom-instructions.d.ts +0 -1
  666. package/dist/utils/custom-instructions.js +0 -24
  667. package/dist/utils/custom-instructions.js.map +0 -1
  668. package/dist/utils/encryption.d.ts +0 -86
  669. package/dist/utils/encryption.js +0 -236
  670. package/dist/utils/encryption.js.map +0 -1
  671. package/dist/utils/enhanced-error-messages.d.ts +0 -33
  672. package/dist/utils/enhanced-error-messages.js +0 -440
  673. package/dist/utils/enhanced-error-messages.js.map +0 -1
  674. package/dist/utils/error-handler.d.ts +0 -65
  675. package/dist/utils/error-handler.js +0 -148
  676. package/dist/utils/error-handler.js.map +0 -1
  677. package/dist/utils/error-translator.d.ts +0 -25
  678. package/dist/utils/error-translator.js +0 -203
  679. package/dist/utils/error-translator.js.map +0 -1
  680. package/dist/utils/external-editor.d.ts +0 -47
  681. package/dist/utils/external-editor.js +0 -179
  682. package/dist/utils/external-editor.js.map +0 -1
  683. package/dist/utils/file-cache.d.ts +0 -148
  684. package/dist/utils/file-cache.js +0 -413
  685. package/dist/utils/file-cache.js.map +0 -1
  686. package/dist/utils/file-lock.d.ts +0 -141
  687. package/dist/utils/file-lock.js +0 -554
  688. package/dist/utils/file-lock.js.map +0 -1
  689. package/dist/utils/file-mentions.d.ts +0 -68
  690. package/dist/utils/file-mentions.js +0 -225
  691. package/dist/utils/file-mentions.js.map +0 -1
  692. package/dist/utils/history-manager.d.ts +0 -52
  693. package/dist/utils/history-manager.js +0 -211
  694. package/dist/utils/history-manager.js.map +0 -1
  695. package/dist/utils/history-migration.d.ts +0 -9
  696. package/dist/utils/history-migration.js +0 -37
  697. package/dist/utils/history-migration.js.map +0 -1
  698. package/dist/utils/image-processor.d.ts +0 -33
  699. package/dist/utils/image-processor.js +0 -124
  700. package/dist/utils/image-processor.js.map +0 -1
  701. package/dist/utils/index.d.ts +0 -92
  702. package/dist/utils/index.js +0 -111
  703. package/dist/utils/index.js.map +0 -1
  704. package/dist/utils/init-previewer.d.ts +0 -56
  705. package/dist/utils/init-previewer.js +0 -239
  706. package/dist/utils/init-previewer.js.map +0 -1
  707. package/dist/utils/init-validator.d.ts +0 -65
  708. package/dist/utils/init-validator.js +0 -252
  709. package/dist/utils/init-validator.js.map +0 -1
  710. package/dist/utils/input-sanitizer.d.ts +0 -210
  711. package/dist/utils/input-sanitizer.js +0 -362
  712. package/dist/utils/input-sanitizer.js.map +0 -1
  713. package/dist/utils/instruction-generator.d.ts +0 -21
  714. package/dist/utils/instruction-generator.js +0 -233
  715. package/dist/utils/instruction-generator.js.map +0 -1
  716. package/dist/utils/json-utils.d.ts +0 -72
  717. package/dist/utils/json-utils.js +0 -226
  718. package/dist/utils/json-utils.js.map +0 -1
  719. package/dist/utils/llm-optimized-instruction-generator.d.ts +0 -36
  720. package/dist/utils/llm-optimized-instruction-generator.js +0 -365
  721. package/dist/utils/llm-optimized-instruction-generator.js.map +0 -1
  722. package/dist/utils/message-optimizer.d.ts +0 -100
  723. package/dist/utils/message-optimizer.js +0 -297
  724. package/dist/utils/message-optimizer.js.map +0 -1
  725. package/dist/utils/onboarding-manager.d.ts +0 -45
  726. package/dist/utils/onboarding-manager.js +0 -131
  727. package/dist/utils/onboarding-manager.js.map +0 -1
  728. package/dist/utils/parallel-analyzer.d.ts +0 -123
  729. package/dist/utils/parallel-analyzer.js +0 -241
  730. package/dist/utils/parallel-analyzer.js.map +0 -1
  731. package/dist/utils/paste-utils.d.ts +0 -99
  732. package/dist/utils/paste-utils.js +0 -295
  733. package/dist/utils/paste-utils.js.map +0 -1
  734. package/dist/utils/path-helpers.d.ts +0 -8
  735. package/dist/utils/path-helpers.js +0 -35
  736. package/dist/utils/path-helpers.js.map +0 -1
  737. package/dist/utils/path-security.d.ts +0 -92
  738. package/dist/utils/path-security.js +0 -300
  739. package/dist/utils/path-security.js.map +0 -1
  740. package/dist/utils/path-utils.d.ts +0 -83
  741. package/dist/utils/path-utils.js +0 -122
  742. package/dist/utils/path-utils.js.map +0 -1
  743. package/dist/utils/path-validator.d.ts +0 -66
  744. package/dist/utils/path-validator.js +0 -141
  745. package/dist/utils/path-validator.js.map +0 -1
  746. package/dist/utils/performance.d.ts +0 -74
  747. package/dist/utils/performance.js +0 -133
  748. package/dist/utils/performance.js.map +0 -1
  749. package/dist/utils/process-pool.d.ts +0 -109
  750. package/dist/utils/process-pool.js +0 -332
  751. package/dist/utils/process-pool.js.map +0 -1
  752. package/dist/utils/progress-tracker.d.ts +0 -51
  753. package/dist/utils/progress-tracker.js +0 -152
  754. package/dist/utils/progress-tracker.js.map +0 -1
  755. package/dist/utils/project-analyzer.d.ts +0 -49
  756. package/dist/utils/project-analyzer.js +0 -396
  757. package/dist/utils/project-analyzer.js.map +0 -1
  758. package/dist/utils/prompt-builder.d.ts +0 -14
  759. package/dist/utils/prompt-builder.js +0 -100
  760. package/dist/utils/prompt-builder.js.map +0 -1
  761. package/dist/utils/provider-context.d.ts +0 -243
  762. package/dist/utils/provider-context.js +0 -421
  763. package/dist/utils/provider-context.js.map +0 -1
  764. package/dist/utils/provider-file-cache.d.ts +0 -91
  765. package/dist/utils/provider-file-cache.js +0 -165
  766. package/dist/utils/provider-file-cache.js.map +0 -1
  767. package/dist/utils/provider-settings.d.ts +0 -181
  768. package/dist/utils/provider-settings.js +0 -450
  769. package/dist/utils/provider-settings.js.map +0 -1
  770. package/dist/utils/rate-limiter.d.ts +0 -222
  771. package/dist/utils/rate-limiter.js +0 -338
  772. package/dist/utils/rate-limiter.js.map +0 -1
  773. package/dist/utils/retry-helper.d.ts +0 -81
  774. package/dist/utils/retry-helper.js +0 -244
  775. package/dist/utils/retry-helper.js.map +0 -1
  776. package/dist/utils/safety-rules.d.ts +0 -64
  777. package/dist/utils/safety-rules.js +0 -225
  778. package/dist/utils/safety-rules.js.map +0 -1
  779. package/dist/utils/settings-manager.d.ts +0 -256
  780. package/dist/utils/settings-manager.js +0 -967
  781. package/dist/utils/settings-manager.js.map +0 -1
  782. package/dist/utils/setup-validator.d.ts +0 -47
  783. package/dist/utils/setup-validator.js +0 -304
  784. package/dist/utils/setup-validator.js.map +0 -1
  785. package/dist/utils/string-utils.d.ts +0 -19
  786. package/dist/utils/string-utils.js +0 -28
  787. package/dist/utils/string-utils.js.map +0 -1
  788. package/dist/utils/template-manager.d.ts +0 -62
  789. package/dist/utils/template-manager.js +0 -366
  790. package/dist/utils/template-manager.js.map +0 -1
  791. package/dist/utils/text-utils.d.ts +0 -82
  792. package/dist/utils/text-utils.js +0 -203
  793. package/dist/utils/text-utils.js.map +0 -1
  794. package/dist/utils/token-counter.d.ts +0 -76
  795. package/dist/utils/token-counter.js +0 -231
  796. package/dist/utils/token-counter.js.map +0 -1
  797. package/dist/utils/usage-tracker.d.ts +0 -78
  798. package/dist/utils/usage-tracker.js +0 -126
  799. package/dist/utils/usage-tracker.js.map +0 -1
  800. package/dist/utils/version.d.ts +0 -14
  801. package/dist/utils/version.js +0 -70
  802. package/dist/utils/version.js.map +0 -1
@@ -1,1369 +0,0 @@
1
- import fs from "fs-extra";
2
- import path from "path";
3
- import { writeFile as writeFilePromise } from "fs/promises";
4
- import { ConfirmationService } from "../utils/confirmation-service.js";
5
- import { validatePathSecure } from "../utils/path-security.js";
6
- import { getMessageOptimizer } from "../utils/message-optimizer.js";
7
- import { isDestructiveFileOperation } from "../utils/safety-rules.js";
8
- import { getAutoAcceptLogger } from "../utils/auto-accept-logger.js";
9
- import { getSettingsManager } from "../utils/settings-manager.js";
10
- import { ErrorCategory, createToolError } from "../utils/error-handler.js";
11
- import { getVSCodeIPCClient } from "../ipc/index.js";
12
- // Configuration constants
13
- const EDITOR_CONFIG = {
14
- /** Number of context lines to show in diffs */
15
- DIFF_CONTEXT_LINES: 3,
16
- /** Minimum similarity score for fuzzy line matching */
17
- LINE_SIMILARITY_THRESHOLD: 0.75,
18
- /** Minimum similarity score for block matching */
19
- BLOCK_SIMILARITY_THRESHOLD: 0.55,
20
- /** Minimum similarity for suggestions */
21
- SUGGESTION_SIMILARITY_THRESHOLD: 0.4,
22
- /** File encoding */
23
- FILE_ENCODING: "utf-8",
24
- };
25
- // Error messages (centralized for consistency)
26
- // Include actionable recovery guidance to help LLM self-correct
27
- const RECOVERY_HINT = "TIP: Use view_file first to get the exact content before editing.";
28
- const ERROR_MESSAGES = {
29
- FILE_NOT_FOUND: (filePath) => `File not found: ${filePath}. Use view_file to check the directory structure.`,
30
- PATH_NOT_FOUND: (filePath) => `File or directory not found: ${filePath}`,
31
- SECURITY_ERROR: (error) => `Security: ${error}`,
32
- EMPTY_SEARCH_STRING: "Search string cannot be empty",
33
- STRING_NOT_FOUND: (str) => `String not found in file: "${str}". Use view_file to see the exact file contents and copy the correct text.`,
34
- STRING_NOT_FOUND_MULTI: "String not found in file. For multi-line replacements, use view_file to get the exact content including whitespace and indentation.",
35
- FILE_MODIFIED_DURING_CONFIRMATION: "File was modified by another process during confirmation. Please retry the operation.",
36
- NO_EDITS_TO_UNDO: "No edits to undo",
37
- EDIT_CANCELLED: (operation) => `${operation} cancelled by user`,
38
- NO_EDITS_PROVIDED: "No edits provided",
39
- EMPTY_OLD_STR: (index) => `Edit ${index + 1}: old_str cannot be empty`,
40
- RECOVERY_HINT,
41
- /** Append recovery hint to any error message */
42
- withRecoveryHint: (msg) => `${msg} ${RECOVERY_HINT}`,
43
- };
44
- /**
45
- * Validate path security and return resolved path or error
46
- * Centralizes the repeated pattern of path validation across all methods
47
- */
48
- async function validateAndResolvePath(filePath) {
49
- const pathValidation = await validatePathSecure(filePath);
50
- if (!pathValidation.success) {
51
- return {
52
- success: false,
53
- error: ERROR_MESSAGES.SECURITY_ERROR(pathValidation.error || 'Unknown error'),
54
- };
55
- }
56
- // Path is guaranteed when success is true, but provide fallback for type safety
57
- return { path: pathValidation.path || filePath };
58
- }
59
- /**
60
- * Check if file exists and return appropriate error if not
61
- */
62
- async function checkFileExists(filePath) {
63
- const resolvedPath = path.resolve(filePath);
64
- if (!(await fs.pathExists(resolvedPath))) {
65
- return {
66
- success: false,
67
- error: ERROR_MESSAGES.FILE_NOT_FOUND(filePath),
68
- };
69
- }
70
- return null;
71
- }
72
- /**
73
- * Atomically write content to file using temp file + rename pattern
74
- * Ensures either full write or no write (prevents partial writes)
75
- */
76
- async function atomicWriteFile(filePath, content) {
77
- const tempPath = `${filePath}.tmp.${Date.now()}`;
78
- try {
79
- await writeFilePromise(tempPath, content, EDITOR_CONFIG.FILE_ENCODING);
80
- await fs.rename(tempPath, filePath);
81
- }
82
- catch (writeError) {
83
- // Clean up temp file on failure
84
- try {
85
- await fs.unlink(tempPath);
86
- }
87
- catch {
88
- // Ignore cleanup errors
89
- }
90
- throw writeError;
91
- }
92
- }
93
- export class TextEditorTool {
94
- editHistory = [];
95
- confirmationService = ConfirmationService.getInstance();
96
- checkpointCallback;
97
- async view(filePath, viewRange) {
98
- try {
99
- // SECURITY: Validate path to prevent traversal attacks (REQ-SEC-002)
100
- const pathResult = await validateAndResolvePath(filePath);
101
- if ('success' in pathResult)
102
- return pathResult; // Return error if validation failed
103
- const resolvedPath = pathResult.path;
104
- if (await fs.pathExists(resolvedPath)) {
105
- const stats = await fs.stat(resolvedPath);
106
- if (stats.isDirectory()) {
107
- const files = await fs.readdir(resolvedPath);
108
- return {
109
- success: true,
110
- output: `Directory contents of ${filePath}:\n${files.join("\n")}`,
111
- };
112
- }
113
- const content = await fs.readFile(resolvedPath, "utf-8");
114
- const lines = content.split("\n");
115
- if (viewRange) {
116
- const [start, end] = viewRange;
117
- // Validate line range
118
- if (start < 1) {
119
- return {
120
- success: false,
121
- error: `Invalid start line: ${start}. Line numbers must be >= 1.`,
122
- };
123
- }
124
- if (end < start) {
125
- return {
126
- success: false,
127
- error: `Invalid line range: end (${end}) must be >= start (${start}).`,
128
- };
129
- }
130
- if (start > lines.length) {
131
- return {
132
- success: false,
133
- error: `Start line ${start} exceeds file length (${lines.length} lines).`,
134
- };
135
- }
136
- // Clamp end to file length to avoid misleading output
137
- const actualEnd = Math.min(end, lines.length);
138
- const selectedLines = lines.slice(start - 1, actualEnd);
139
- const numberedLines = selectedLines
140
- .map((line, idx) => `${start + idx}: ${line}`)
141
- .join("\n");
142
- return {
143
- success: true,
144
- output: `Lines ${start}-${actualEnd} of ${filePath}:\n${numberedLines}`,
145
- };
146
- }
147
- // Format all lines with line numbers
148
- const allNumberedLines = lines
149
- .map((line, idx) => `${idx + 1}: ${line}`)
150
- .join("\n");
151
- const fullOutput = `Contents of ${filePath}:\n${allNumberedLines}`;
152
- // Apply message optimization for large files
153
- const optimizer = getMessageOptimizer();
154
- const optimized = optimizer.optimizeToolOutput(fullOutput, 'read_file');
155
- return {
156
- success: true,
157
- output: optimized.content,
158
- };
159
- }
160
- else {
161
- return {
162
- success: false,
163
- error: ERROR_MESSAGES.PATH_NOT_FOUND(filePath),
164
- };
165
- }
166
- }
167
- catch (error) {
168
- return createToolError(ErrorCategory.FILE_OPERATION, `View file`, error, { filePath });
169
- }
170
- }
171
- async strReplace(filePath, oldStr, newStr, replaceAll = false) {
172
- try {
173
- // SECURITY: Validate path to prevent traversal attacks (REQ-SEC-002)
174
- const pathResult = await validateAndResolvePath(filePath);
175
- if ('success' in pathResult)
176
- return pathResult;
177
- const resolvedPath = pathResult.path;
178
- // Validate inputs
179
- if (!oldStr) {
180
- return {
181
- success: false,
182
- error: ERROR_MESSAGES.EMPTY_SEARCH_STRING,
183
- };
184
- }
185
- // Check file exists
186
- const fileExistsError = await checkFileExists(resolvedPath);
187
- if (fileExistsError) {
188
- return fileExistsError;
189
- }
190
- // RACE CONDITION FIX: Read file with stat to get mtime for comparison
191
- const statsBefore = await fs.stat(resolvedPath);
192
- const content = await fs.readFile(resolvedPath, "utf-8");
193
- const mtimeBefore = statsBefore.mtimeMs;
194
- // Use actualOldStr to avoid modifying the parameter
195
- let actualOldStr = oldStr;
196
- if (!content.includes(oldStr)) {
197
- // Try whitespace-tolerant matching first
198
- const normalizedMatch = this.findNormalizedMatch(content, oldStr);
199
- if (normalizedMatch) {
200
- actualOldStr = normalizedMatch;
201
- }
202
- else if (oldStr.includes('\n')) {
203
- // Try fuzzy matching for multi-line strings
204
- const fuzzyResult = this.findFuzzyMatch(content, oldStr);
205
- if (fuzzyResult) {
206
- actualOldStr = fuzzyResult;
207
- }
208
- else {
209
- // Try line-by-line similarity matching
210
- const similarMatch = this.findSimilarBlock(content, oldStr);
211
- if (similarMatch.match) {
212
- actualOldStr = similarMatch.match;
213
- }
214
- else {
215
- // Provide helpful error with closest match info and recovery guidance
216
- const baseMsg = similarMatch.suggestion
217
- ? `String not found in file. ${similarMatch.suggestion}`
218
- : ERROR_MESSAGES.STRING_NOT_FOUND_MULTI;
219
- return {
220
- success: false,
221
- error: ERROR_MESSAGES.withRecoveryHint(baseMsg),
222
- };
223
- }
224
- }
225
- }
226
- else {
227
- // Single line - try to find similar line
228
- const similarLine = this.findSimilarLine(content, oldStr);
229
- if (similarLine.match) {
230
- actualOldStr = similarLine.match;
231
- }
232
- else {
233
- const baseMsg = similarLine.suggestion
234
- ? `String not found in file: "${oldStr}". ${similarLine.suggestion}`
235
- : ERROR_MESSAGES.STRING_NOT_FOUND(oldStr);
236
- return {
237
- success: false,
238
- error: ERROR_MESSAGES.withRecoveryHint(baseMsg),
239
- };
240
- }
241
- }
242
- }
243
- // Count occurrences using simple string splitting (more reliable than regex for multi-line strings)
244
- const occurrences = content.split(actualOldStr).length - 1;
245
- // Generate new content and diff for confirmation
246
- const newContent = replaceAll
247
- ? content.split(actualOldStr).join(newStr)
248
- : content.replace(actualOldStr, newStr);
249
- const oldLinesForDiff = content.split("\n");
250
- const newLinesForDiff = newContent.split("\n");
251
- let diffContent = this.generateDiff(oldLinesForDiff, newLinesForDiff, filePath);
252
- // Phase 2: Check if file operation is destructive
253
- const { isDestructive, matchedOperations } = isDestructiveFileOperation(filePath, 'edit');
254
- // Get auto-accept configuration
255
- const autoAcceptConfig = getSettingsManager().getAutoAcceptConfig();
256
- const isAutoAcceptEnabled = this.confirmationService.getSessionFlags().allOperations === true;
257
- // Determine if we should always confirm despite auto-accept
258
- const shouldAlwaysConfirm = isDestructive && matchedOperations.some(op => autoAcceptConfig?.alwaysConfirm?.includes(op.id));
259
- // Add safety warning to diff content if destructive
260
- if (isDestructive) {
261
- const warnings = matchedOperations.map(op => ` - ${op.name}: ${op.description}`).join('\n');
262
- diffContent = `⚠️ WARNING: This operation is flagged as destructive:\n${warnings}\n\n${diffContent}`;
263
- }
264
- const shouldProceed = await this.confirmationService.shouldProceed('file', {
265
- operation: `Edit file${replaceAll && occurrences > 1 ? ` (${occurrences} occurrences)` : ''}`,
266
- filename: filePath,
267
- showVSCodeOpen: false,
268
- content: diffContent,
269
- alwaysConfirm: shouldAlwaysConfirm, // Force confirmation for destructive ops
270
- // VS Code IPC diff preview fields
271
- oldContent: content,
272
- newContent: newContent,
273
- diffOperation: 'edit',
274
- });
275
- // Phase 2: Log to audit logger
276
- if (autoAcceptConfig && autoAcceptConfig.auditLog?.enabled) {
277
- const logger = getAutoAcceptLogger();
278
- logger.logFileOperation('edit', filePath, isDestructive, shouldProceed, // userConfirmed = true if user confirmed (shouldProceed=true)
279
- isAutoAcceptEnabled && !shouldAlwaysConfirm, // autoAccepted = true if auto-accept AND not forced confirm
280
- autoAcceptConfig.scope || 'session');
281
- }
282
- if (!shouldProceed) {
283
- return {
284
- success: false,
285
- error: ERROR_MESSAGES.EDIT_CANCELLED("File edit"),
286
- };
287
- }
288
- // RACE CONDITION FIX: Check if file was modified during confirmation
289
- // This prevents data loss from concurrent modifications
290
- const statsAfterConfirm = await fs.stat(resolvedPath);
291
- if (statsAfterConfirm.mtimeMs !== mtimeBefore) {
292
- return {
293
- success: false,
294
- error: ERROR_MESSAGES.FILE_MODIFIED_DURING_CONFIRMATION,
295
- };
296
- }
297
- // Create checkpoint before modification
298
- await this.createCheckpointIfNeeded(filePath, 'str_replace');
299
- // Atomic write
300
- await atomicWriteFile(resolvedPath, newContent);
301
- this.editHistory.push({
302
- command: "str_replace",
303
- path: filePath,
304
- old_str: oldStr,
305
- new_str: newStr,
306
- });
307
- // Reveal the file in VS Code (like Claude Code)
308
- const ipcClient = getVSCodeIPCClient();
309
- ipcClient.revealFile(resolvedPath, 'edit');
310
- return {
311
- success: true,
312
- output: diffContent,
313
- };
314
- }
315
- catch (error) {
316
- return createToolError(ErrorCategory.FILE_OPERATION, `Replace text`, error, { filePath });
317
- }
318
- }
319
- async create(filePath, content) {
320
- try {
321
- // SECURITY: Validate path to prevent traversal attacks (REQ-SEC-002)
322
- const pathResult = await validateAndResolvePath(filePath);
323
- if ('success' in pathResult)
324
- return pathResult;
325
- const resolvedPath = pathResult.path;
326
- // Create a diff-style preview for file creation
327
- const contentLines = content.split("\n");
328
- let diffContent = [
329
- `Created ${filePath}`,
330
- `--- /dev/null`,
331
- `+++ b/${filePath}`,
332
- `@@ -0,0 +1,${contentLines.length} @@`,
333
- ...contentLines.map((line) => `+${line}`),
334
- ].join("\n");
335
- // Phase 2: Check if file operation is destructive
336
- const { isDestructive, matchedOperations } = isDestructiveFileOperation(filePath, 'write');
337
- // Get auto-accept configuration
338
- const autoAcceptConfig = getSettingsManager().getAutoAcceptConfig();
339
- const isAutoAcceptEnabled = this.confirmationService.getSessionFlags().allOperations === true;
340
- // Determine if we should always confirm despite auto-accept
341
- const shouldAlwaysConfirm = isDestructive && matchedOperations.some(op => autoAcceptConfig?.alwaysConfirm?.includes(op.id));
342
- // Add safety warning to diff content if destructive
343
- if (isDestructive) {
344
- const warnings = matchedOperations.map(op => ` - ${op.name}: ${op.description}`).join('\n');
345
- diffContent = `⚠️ WARNING: This operation is flagged as destructive:\n${warnings}\n\n${diffContent}`;
346
- }
347
- const shouldProceed = await this.confirmationService.shouldProceed('file', {
348
- operation: "Write",
349
- filename: filePath,
350
- showVSCodeOpen: false,
351
- content: diffContent,
352
- alwaysConfirm: shouldAlwaysConfirm, // Force confirmation for destructive ops
353
- // VS Code IPC diff preview fields
354
- oldContent: '', // Empty for new file
355
- newContent: content,
356
- diffOperation: 'create',
357
- });
358
- // Phase 2: Log to audit logger
359
- if (autoAcceptConfig && autoAcceptConfig.auditLog?.enabled) {
360
- const logger = getAutoAcceptLogger();
361
- logger.logFileOperation('write', filePath, isDestructive, shouldProceed, // userConfirmed = true if user confirmed (shouldProceed=true)
362
- isAutoAcceptEnabled && !shouldAlwaysConfirm, // autoAccepted = true if auto-accept AND not forced confirm
363
- autoAcceptConfig.scope || 'session');
364
- }
365
- if (!shouldProceed) {
366
- return {
367
- success: false,
368
- error: ERROR_MESSAGES.EDIT_CANCELLED("File creation"),
369
- };
370
- }
371
- // Create checkpoint before modification (will skip if file doesn't exist)
372
- await this.createCheckpointIfNeeded(filePath, 'create');
373
- const dir = path.dirname(resolvedPath);
374
- await fs.ensureDir(dir);
375
- // Atomic write
376
- await atomicWriteFile(resolvedPath, content);
377
- this.editHistory.push({
378
- command: "create",
379
- path: filePath,
380
- content,
381
- });
382
- // Reveal the file in VS Code (like Claude Code)
383
- const ipcClient = getVSCodeIPCClient();
384
- ipcClient.revealFile(resolvedPath, 'create');
385
- // Generate diff output using the same method as str_replace
386
- const oldLines = []; // Empty for new files
387
- const newLines = content.split("\n");
388
- const diff = this.generateDiff(oldLines, newLines, filePath);
389
- return {
390
- success: true,
391
- output: diff,
392
- };
393
- }
394
- catch (error) {
395
- return createToolError(ErrorCategory.FILE_OPERATION, `Create file`, error, { filePath });
396
- }
397
- }
398
- async replaceLines(filePath, startLine, endLine, newContent) {
399
- try {
400
- // SECURITY: Validate path to prevent traversal attacks (REQ-SEC-002)
401
- const pathResult = await validateAndResolvePath(filePath);
402
- if ('success' in pathResult)
403
- return pathResult;
404
- const resolvedPath = pathResult.path;
405
- const fileExistsError = await checkFileExists(resolvedPath);
406
- if (fileExistsError) {
407
- return fileExistsError;
408
- }
409
- const fileContent = await fs.readFile(resolvedPath, "utf-8");
410
- const lines = fileContent.split("\n");
411
- if (startLine < 1 || startLine > lines.length) {
412
- return {
413
- success: false,
414
- error: `Invalid start line: ${startLine}. File has ${lines.length} lines.`,
415
- };
416
- }
417
- if (endLine < startLine || endLine > lines.length) {
418
- return {
419
- success: false,
420
- error: `Invalid end line: ${endLine}. Must be between ${startLine} and ${lines.length}.`,
421
- };
422
- }
423
- const sessionFlags = this.confirmationService.getSessionFlags();
424
- if (!sessionFlags.fileOperations && !sessionFlags.allOperations) {
425
- const newLines = [...lines];
426
- const replacementLines = newContent.split("\n");
427
- newLines.splice(startLine - 1, endLine - startLine + 1, ...replacementLines);
428
- const diffContent = this.generateDiff(lines, newLines, filePath);
429
- const confirmationResult = await this.confirmationService.requestConfirmation({
430
- operation: `Replace lines ${startLine}-${endLine}`,
431
- filename: filePath,
432
- showVSCodeOpen: false,
433
- content: diffContent,
434
- oldContent: fileContent,
435
- newContent: newLines.join("\n"),
436
- diffOperation: 'edit',
437
- lineStart: startLine,
438
- lineEnd: endLine,
439
- }, "file");
440
- if (!confirmationResult.confirmed) {
441
- return {
442
- success: false,
443
- error: confirmationResult.feedback || ERROR_MESSAGES.EDIT_CANCELLED("Line replacement"),
444
- };
445
- }
446
- }
447
- // Create checkpoint before modification
448
- await this.createCheckpointIfNeeded(filePath, 'replace_lines');
449
- const replacementLines = newContent.split("\n");
450
- lines.splice(startLine - 1, endLine - startLine + 1, ...replacementLines);
451
- const newFileContent = lines.join("\n");
452
- // Atomic write
453
- await atomicWriteFile(resolvedPath, newFileContent);
454
- this.editHistory.push({
455
- command: "str_replace",
456
- path: filePath,
457
- old_str: `lines ${startLine}-${endLine}`,
458
- new_str: newContent,
459
- });
460
- // Reveal the file in VS Code (like Claude Code)
461
- const ipcClient = getVSCodeIPCClient();
462
- ipcClient.revealFile(resolvedPath, 'edit');
463
- const oldLines = fileContent.split("\n");
464
- const diff = this.generateDiff(oldLines, lines, filePath);
465
- return {
466
- success: true,
467
- output: diff,
468
- };
469
- }
470
- catch (error) {
471
- return createToolError(ErrorCategory.FILE_OPERATION, `Replace lines`, error, { filePath });
472
- }
473
- }
474
- async insert(filePath, insertLine, content) {
475
- try {
476
- // SECURITY: Validate path to prevent traversal attacks (REQ-SEC-002)
477
- const pathResult = await validateAndResolvePath(filePath);
478
- if ('success' in pathResult)
479
- return pathResult;
480
- const resolvedPath = pathResult.path;
481
- const fileExistsError = await checkFileExists(resolvedPath);
482
- if (fileExistsError) {
483
- return fileExistsError;
484
- }
485
- const fileContent = await fs.readFile(resolvedPath, "utf-8");
486
- const lines = fileContent.split("\n");
487
- // Validate insert line
488
- if (insertLine < 1) {
489
- return {
490
- success: false,
491
- error: `Invalid insert line: ${insertLine}. Line numbers must be >= 1.`,
492
- };
493
- }
494
- if (insertLine > lines.length + 1) {
495
- return {
496
- success: false,
497
- error: `Invalid insert line: ${insertLine}. File has ${lines.length} lines (can insert at line ${lines.length + 1} to append).`,
498
- };
499
- }
500
- // Split content into individual lines for proper handling
501
- // This ensures multi-line content is correctly inserted and can be undone
502
- const contentLines = content.split("\n");
503
- const newLines = [...lines];
504
- newLines.splice(insertLine - 1, 0, ...contentLines);
505
- const newContent = newLines.join("\n");
506
- // Generate diff for confirmation
507
- const diffContent = this.generateDiff(lines, newLines, filePath);
508
- // Request confirmation (consistent with other editing methods)
509
- const shouldProceed = await this.confirmationService.shouldProceed('file', {
510
- operation: `Insert ${contentLines.length} line${contentLines.length !== 1 ? 's' : ''} at line ${insertLine}`,
511
- filename: filePath,
512
- showVSCodeOpen: false,
513
- content: diffContent,
514
- oldContent: fileContent,
515
- newContent: newContent,
516
- diffOperation: 'edit',
517
- lineStart: insertLine,
518
- lineEnd: insertLine,
519
- });
520
- if (!shouldProceed) {
521
- return {
522
- success: false,
523
- error: ERROR_MESSAGES.EDIT_CANCELLED("Insert operation"),
524
- };
525
- }
526
- // Create checkpoint before modification
527
- await this.createCheckpointIfNeeded(filePath, 'insert');
528
- // Atomic write
529
- await atomicWriteFile(resolvedPath, newContent);
530
- this.editHistory.push({
531
- command: "insert",
532
- path: filePath,
533
- insert_line: insertLine,
534
- content,
535
- });
536
- // Reveal the file in VS Code (like Claude Code)
537
- const ipcClient = getVSCodeIPCClient();
538
- ipcClient.revealFile(resolvedPath, 'edit');
539
- return {
540
- success: true,
541
- output: diffContent,
542
- };
543
- }
544
- catch (error) {
545
- return createToolError(ErrorCategory.FILE_OPERATION, `Insert content`, error, { filePath });
546
- }
547
- }
548
- /**
549
- * Make multiple edits to a file in a single atomic operation.
550
- * All edits are validated and previewed before applying.
551
- * If any edit fails validation, the entire operation is aborted.
552
- */
553
- async multiEdit(filePath, edits) {
554
- try {
555
- // SECURITY: Validate path to prevent traversal attacks
556
- const pathResult = await validateAndResolvePath(filePath);
557
- if ('success' in pathResult)
558
- return pathResult;
559
- const resolvedPath = pathResult.path;
560
- // Validate inputs
561
- if (!edits || edits.length === 0) {
562
- return {
563
- success: false,
564
- error: ERROR_MESSAGES.NO_EDITS_PROVIDED,
565
- };
566
- }
567
- for (let i = 0; i < edits.length; i++) {
568
- if (!edits[i].old_str) {
569
- return {
570
- success: false,
571
- error: `Edit ${i + 1}: old_str cannot be empty`,
572
- };
573
- }
574
- }
575
- // Check file exists
576
- const fileExistsError = await checkFileExists(resolvedPath);
577
- if (fileExistsError) {
578
- return fileExistsError;
579
- }
580
- // Read file with stat to get mtime for race condition protection
581
- const statsBefore = await fs.stat(resolvedPath);
582
- const originalContent = await fs.readFile(resolvedPath, "utf-8");
583
- const mtimeBefore = statsBefore.mtimeMs;
584
- // Apply all edits sequentially to validate and generate preview
585
- let workingContent = originalContent;
586
- const appliedEdits = [];
587
- for (let i = 0; i < edits.length; i++) {
588
- const edit = edits[i];
589
- let actualOldStr = edit.old_str;
590
- if (!workingContent.includes(edit.old_str)) {
591
- // Try whitespace-tolerant matching
592
- const normalizedMatch = this.findNormalizedMatch(workingContent, edit.old_str);
593
- if (normalizedMatch) {
594
- actualOldStr = normalizedMatch;
595
- }
596
- else if (edit.old_str.includes('\n')) {
597
- // Try fuzzy matching for multi-line strings
598
- const fuzzyResult = this.findFuzzyMatch(workingContent, edit.old_str);
599
- if (fuzzyResult) {
600
- actualOldStr = fuzzyResult;
601
- }
602
- else {
603
- const similarMatch = this.findSimilarBlock(workingContent, edit.old_str);
604
- if (similarMatch.match) {
605
- actualOldStr = similarMatch.match;
606
- }
607
- else {
608
- const baseMsg = similarMatch.suggestion
609
- ? `Edit ${i + 1}: String not found. ${similarMatch.suggestion}`
610
- : `Edit ${i + 1}: String not found in file (after applying previous edits).`;
611
- return {
612
- success: false,
613
- error: ERROR_MESSAGES.withRecoveryHint(baseMsg),
614
- };
615
- }
616
- }
617
- }
618
- else {
619
- const similarLine = this.findSimilarLine(workingContent, edit.old_str);
620
- if (similarLine.match) {
621
- actualOldStr = similarLine.match;
622
- }
623
- else {
624
- const baseMsg = similarLine.suggestion
625
- ? `Edit ${i + 1}: String not found: "${edit.old_str}". ${similarLine.suggestion}`
626
- : `Edit ${i + 1}: String not found: "${edit.old_str}".`;
627
- return {
628
- success: false,
629
- error: ERROR_MESSAGES.withRecoveryHint(baseMsg),
630
- };
631
- }
632
- }
633
- }
634
- // Apply this edit to working content
635
- workingContent = workingContent.replace(actualOldStr, edit.new_str);
636
- appliedEdits.push({ ...edit, actualOldStr });
637
- }
638
- // Generate unified diff showing all changes
639
- const oldLines = originalContent.split("\n");
640
- const newLines = workingContent.split("\n");
641
- let diffContent = this.generateDiff(oldLines, newLines, filePath);
642
- // Add edit count to diff header
643
- diffContent = `Multi-edit: ${edits.length} changes\n${diffContent}`;
644
- // Check if file operation is destructive
645
- const { isDestructive, matchedOperations } = isDestructiveFileOperation(filePath, 'edit');
646
- // Get auto-accept configuration
647
- const autoAcceptConfig = getSettingsManager().getAutoAcceptConfig();
648
- const isAutoAcceptEnabled = this.confirmationService.getSessionFlags().allOperations === true;
649
- const shouldAlwaysConfirm = isDestructive && matchedOperations.some(op => autoAcceptConfig?.alwaysConfirm?.includes(op.id));
650
- if (isDestructive) {
651
- const warnings = matchedOperations.map(op => ` - ${op.name}: ${op.description}`).join('\n');
652
- diffContent = `⚠️ WARNING: This operation is flagged as destructive:\n${warnings}\n\n${diffContent}`;
653
- }
654
- const shouldProceed = await this.confirmationService.shouldProceed('file', {
655
- operation: `Multi-edit (${edits.length} changes)`,
656
- filename: filePath,
657
- showVSCodeOpen: false,
658
- content: diffContent,
659
- alwaysConfirm: shouldAlwaysConfirm,
660
- // VS Code IPC diff preview fields
661
- oldContent: originalContent,
662
- newContent: workingContent,
663
- diffOperation: 'edit',
664
- });
665
- // Audit logging
666
- if (autoAcceptConfig && autoAcceptConfig.auditLog?.enabled) {
667
- const logger = getAutoAcceptLogger();
668
- logger.logFileOperation('edit', filePath, isDestructive, shouldProceed, // BUG FIX: was !shouldProceed (inverted)
669
- isAutoAcceptEnabled && !shouldAlwaysConfirm, autoAcceptConfig.scope || 'session');
670
- }
671
- if (!shouldProceed) {
672
- return {
673
- success: false,
674
- error: ERROR_MESSAGES.EDIT_CANCELLED("Multi-edit"),
675
- };
676
- }
677
- // Race condition check
678
- const statsAfterConfirm = await fs.stat(resolvedPath);
679
- if (statsAfterConfirm.mtimeMs !== mtimeBefore) {
680
- return {
681
- success: false,
682
- error: ERROR_MESSAGES.FILE_MODIFIED_DURING_CONFIRMATION,
683
- };
684
- }
685
- // Create checkpoint before modification
686
- await this.createCheckpointIfNeeded(filePath, 'multi_edit');
687
- // Atomic write
688
- await atomicWriteFile(resolvedPath, workingContent);
689
- // Record in edit history
690
- this.editHistory.push({
691
- command: "str_replace",
692
- path: filePath,
693
- old_str: `[multi-edit: ${edits.length} changes]`,
694
- new_str: workingContent,
695
- });
696
- // Reveal the file in VS Code (like Claude Code)
697
- const ipcClient = getVSCodeIPCClient();
698
- ipcClient.revealFile(resolvedPath, 'edit');
699
- return {
700
- success: true,
701
- output: diffContent,
702
- };
703
- }
704
- catch (error) {
705
- return createToolError(ErrorCategory.FILE_OPERATION, `Multi-edit file`, error, { filePath });
706
- }
707
- }
708
- async undoEdit() {
709
- if (this.editHistory.length === 0) {
710
- return {
711
- success: false,
712
- error: ERROR_MESSAGES.NO_EDITS_TO_UNDO,
713
- };
714
- }
715
- const lastEdit = this.editHistory.pop();
716
- if (!lastEdit) {
717
- return {
718
- success: false,
719
- error: "Failed to retrieve last edit",
720
- };
721
- }
722
- try {
723
- switch (lastEdit.command) {
724
- case "str_replace":
725
- if (lastEdit.path && lastEdit.old_str && lastEdit.new_str) {
726
- const content = await fs.readFile(lastEdit.path, "utf-8");
727
- const revertedContent = content.replace(lastEdit.new_str, lastEdit.old_str);
728
- await writeFilePromise(lastEdit.path, revertedContent, "utf-8");
729
- }
730
- break;
731
- case "create":
732
- if (lastEdit.path) {
733
- await fs.remove(lastEdit.path);
734
- }
735
- break;
736
- case "insert":
737
- if (lastEdit.path && lastEdit.insert_line && lastEdit.content !== undefined) {
738
- const content = await fs.readFile(lastEdit.path, "utf-8");
739
- const lines = content.split("\n");
740
- // Count how many lines were inserted (content may be multi-line)
741
- const insertedLineCount = lastEdit.content.split("\n").length;
742
- lines.splice(lastEdit.insert_line - 1, insertedLineCount);
743
- await writeFilePromise(lastEdit.path, lines.join("\n"), "utf-8");
744
- }
745
- break;
746
- }
747
- return {
748
- success: true,
749
- output: `Successfully undid ${lastEdit.command} operation`,
750
- };
751
- }
752
- catch (error) {
753
- return {
754
- success: false,
755
- error: `Error undoing edit: ${error.message}`,
756
- };
757
- }
758
- }
759
- findFuzzyMatch(content, searchStr) {
760
- const functionMatch = searchStr.match(/function\s+(\w+)/);
761
- if (!functionMatch || !functionMatch[1])
762
- return null;
763
- const functionName = functionMatch[1];
764
- const contentLines = content.split('\n');
765
- let functionStart = -1;
766
- for (let i = 0; i < contentLines.length; i++) {
767
- if (contentLines[i].includes(`function ${functionName}`) && contentLines[i].includes('{')) {
768
- functionStart = i;
769
- break;
770
- }
771
- }
772
- if (functionStart === -1)
773
- return null;
774
- let braceCount = 0;
775
- let functionEnd = functionStart;
776
- let foundClosingBrace = false;
777
- for (let i = functionStart; i < contentLines.length; i++) {
778
- const line = contentLines[i];
779
- for (const char of line) {
780
- if (char === '{')
781
- braceCount++;
782
- if (char === '}')
783
- braceCount--;
784
- }
785
- if (braceCount === 0 && i > functionStart) {
786
- functionEnd = i;
787
- foundClosingBrace = true;
788
- break;
789
- }
790
- }
791
- // BUG FIX: Reject unclosed functions (braces not balanced)
792
- if (!foundClosingBrace && braceCount !== 0) {
793
- return null;
794
- }
795
- const actualFunction = contentLines.slice(functionStart, functionEnd + 1).join('\n');
796
- const searchNormalized = this.normalizeForComparison(searchStr);
797
- const actualNormalized = this.normalizeForComparison(actualFunction);
798
- if (this.isSimilarStructure(searchNormalized, actualNormalized)) {
799
- return actualFunction;
800
- }
801
- return null;
802
- }
803
- normalizeForComparison(str) {
804
- return str
805
- .replace(/["'`]/g, '"')
806
- .replace(/\s+/g, ' ')
807
- .replace(/{\s+/g, '{ ')
808
- .replace(/\s+}/g, ' }')
809
- .replace(/;\s*/g, ';')
810
- .trim();
811
- }
812
- isSimilarStructure(search, actual) {
813
- const extractTokens = (str) => {
814
- const tokens = str.match(/\b(function|console\.log|return|if|else|for|while)\b/g) || [];
815
- return tokens;
816
- };
817
- const searchTokens = extractTokens(search);
818
- const actualTokens = extractTokens(actual);
819
- if (searchTokens.length !== actualTokens.length)
820
- return false;
821
- for (let i = 0; i < searchTokens.length; i++) {
822
- if (searchTokens[i] !== actualTokens[i])
823
- return false;
824
- }
825
- return true;
826
- }
827
- generateDiff(oldLines, newLines, filePath) {
828
- const CONTEXT_LINES = EDITOR_CONFIG.DIFF_CONTEXT_LINES;
829
- const changes = [];
830
- let i = 0, j = 0;
831
- while (i < oldLines.length || j < newLines.length) {
832
- while (i < oldLines.length && j < newLines.length && oldLines[i] === newLines[j]) {
833
- i++;
834
- j++;
835
- }
836
- if (i < oldLines.length || j < newLines.length) {
837
- const changeStart = { old: i, new: j };
838
- let oldEnd = i;
839
- let newEnd = j;
840
- // BUG FIX: Add iteration counter to prevent O(n²) complexity on adversarial inputs
841
- const maxIterations = oldLines.length + newLines.length;
842
- let iterations = 0;
843
- while (oldEnd < oldLines.length || newEnd < newLines.length) {
844
- // Safety check: prevent excessive iterations
845
- if (++iterations > maxIterations) {
846
- break;
847
- }
848
- let matchFound = false;
849
- let matchLength = 0;
850
- for (let k = 0; k < Math.min(2, oldLines.length - oldEnd, newLines.length - newEnd); k++) {
851
- if (oldEnd + k < oldLines.length &&
852
- newEnd + k < newLines.length &&
853
- oldLines[oldEnd + k] === newLines[newEnd + k]) {
854
- matchLength++;
855
- }
856
- else {
857
- break;
858
- }
859
- }
860
- if (matchLength >= 2 || (oldEnd >= oldLines.length && newEnd >= newLines.length)) {
861
- matchFound = true;
862
- }
863
- if (matchFound) {
864
- break;
865
- }
866
- // Prevent infinite loop - ensure progress is made
867
- let progress = false;
868
- if (oldEnd < oldLines.length) {
869
- oldEnd++;
870
- progress = true;
871
- }
872
- if (newEnd < newLines.length) {
873
- newEnd++;
874
- progress = true;
875
- }
876
- if (!progress) {
877
- // Both reached end, force exit to prevent infinite loop
878
- break;
879
- }
880
- }
881
- changes.push({
882
- oldStart: changeStart.old,
883
- oldEnd: oldEnd,
884
- newStart: changeStart.new,
885
- newEnd: newEnd
886
- });
887
- i = oldEnd;
888
- j = newEnd;
889
- }
890
- }
891
- const hunks = [];
892
- let accumulatedOffset = 0;
893
- for (let changeIdx = 0; changeIdx < changes.length; changeIdx++) {
894
- const change = changes[changeIdx];
895
- let contextStart = Math.max(0, change.oldStart - CONTEXT_LINES);
896
- let contextEnd = Math.min(oldLines.length, change.oldEnd + CONTEXT_LINES);
897
- if (hunks.length > 0) {
898
- const lastHunk = hunks[hunks.length - 1];
899
- const lastHunkEnd = lastHunk.oldStart + lastHunk.oldCount;
900
- if (lastHunkEnd >= contextStart) {
901
- const oldHunkEnd = lastHunk.oldStart + lastHunk.oldCount;
902
- const newContextEnd = Math.min(oldLines.length, change.oldEnd + CONTEXT_LINES);
903
- for (let idx = oldHunkEnd; idx < change.oldStart; idx++) {
904
- lastHunk.lines.push({ type: ' ', content: oldLines[idx] });
905
- }
906
- for (let idx = change.oldStart; idx < change.oldEnd; idx++) {
907
- lastHunk.lines.push({ type: '-', content: oldLines[idx] });
908
- }
909
- for (let idx = change.newStart; idx < change.newEnd; idx++) {
910
- lastHunk.lines.push({ type: '+', content: newLines[idx] });
911
- }
912
- for (let idx = change.oldEnd; idx < newContextEnd && idx < oldLines.length; idx++) {
913
- lastHunk.lines.push({ type: ' ', content: oldLines[idx] });
914
- }
915
- lastHunk.oldCount = newContextEnd - lastHunk.oldStart;
916
- lastHunk.newCount = lastHunk.oldCount + (change.newEnd - change.newStart) - (change.oldEnd - change.oldStart);
917
- continue;
918
- }
919
- }
920
- const hunk = {
921
- oldStart: contextStart + 1,
922
- oldCount: contextEnd - contextStart,
923
- newStart: contextStart + 1 + accumulatedOffset,
924
- newCount: contextEnd - contextStart + (change.newEnd - change.newStart) - (change.oldEnd - change.oldStart),
925
- lines: []
926
- };
927
- for (let idx = contextStart; idx < change.oldStart; idx++) {
928
- hunk.lines.push({ type: ' ', content: oldLines[idx] });
929
- }
930
- for (let idx = change.oldStart; idx < change.oldEnd; idx++) {
931
- hunk.lines.push({ type: '-', content: oldLines[idx] });
932
- }
933
- for (let idx = change.newStart; idx < change.newEnd; idx++) {
934
- hunk.lines.push({ type: '+', content: newLines[idx] });
935
- }
936
- for (let idx = change.oldEnd; idx < contextEnd && idx < oldLines.length; idx++) {
937
- hunk.lines.push({ type: ' ', content: oldLines[idx] });
938
- }
939
- hunks.push(hunk);
940
- accumulatedOffset += (change.newEnd - change.newStart) - (change.oldEnd - change.oldStart);
941
- }
942
- let addedLines = 0;
943
- let removedLines = 0;
944
- for (const hunk of hunks) {
945
- for (const line of hunk.lines) {
946
- if (line.type === '+')
947
- addedLines++;
948
- if (line.type === '-')
949
- removedLines++;
950
- }
951
- }
952
- let summary = `Updated ${filePath}`;
953
- if (addedLines > 0 && removedLines > 0) {
954
- summary += ` with ${addedLines} addition${addedLines !== 1 ? "s" : ""} and ${removedLines} removal${removedLines !== 1 ? "s" : ""}`;
955
- }
956
- else if (addedLines > 0) {
957
- summary += ` with ${addedLines} addition${addedLines !== 1 ? "s" : ""}`;
958
- }
959
- else if (removedLines > 0) {
960
- summary += ` with ${removedLines} removal${removedLines !== 1 ? "s" : ""}`;
961
- }
962
- else if (changes.length === 0) {
963
- return `No changes in ${filePath}`;
964
- }
965
- let diff = summary + "\n";
966
- diff += `--- a/${filePath}\n`;
967
- diff += `+++ b/${filePath}\n`;
968
- for (const hunk of hunks) {
969
- diff += `@@ -${hunk.oldStart},${hunk.oldCount} +${hunk.newStart},${hunk.newCount} @@\n`;
970
- for (const line of hunk.lines) {
971
- diff += `${line.type}${line.content}\n`;
972
- }
973
- }
974
- return diff.trim();
975
- }
976
- getEditHistory() {
977
- return [...this.editHistory];
978
- }
979
- /**
980
- * Set checkpoint callback for automatic checkpoint creation before file modifications
981
- */
982
- setCheckpointCallback(callback) {
983
- this.checkpointCallback = callback;
984
- }
985
- /**
986
- * Create checkpoint before modifying a file
987
- */
988
- async createCheckpointIfNeeded(filePath, operation) {
989
- if (!this.checkpointCallback) {
990
- return;
991
- }
992
- try {
993
- const resolvedPath = path.resolve(filePath);
994
- // Read current file content if it exists
995
- if (await fs.pathExists(resolvedPath)) {
996
- const content = await fs.readFile(resolvedPath, "utf-8");
997
- await this.checkpointCallback([{ path: filePath, content }], `Before ${operation}: ${filePath}`);
998
- }
999
- }
1000
- catch (error) {
1001
- // Don't fail the operation if checkpoint creation fails
1002
- console.warn(`Failed to create checkpoint: ${error instanceof Error ? error.message : 'Unknown error'}`);
1003
- }
1004
- }
1005
- /**
1006
- * Find a match by normalizing whitespace differences
1007
- * Handles: trailing whitespace, tabs vs spaces, line ending differences, indentation changes
1008
- */
1009
- findNormalizedMatch(content, searchStr) {
1010
- // Normalize line endings first
1011
- const normalizedContent = content.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
1012
- const normalizedSearch = searchStr.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
1013
- // If exact match after line ending normalization, find and return the actual string
1014
- if (normalizedContent.includes(normalizedSearch)) {
1015
- // Find the position in normalized content
1016
- const startPos = normalizedContent.indexOf(normalizedSearch);
1017
- const endPos = startPos + normalizedSearch.length;
1018
- // Map position back to original content
1019
- let originalStartPos = 0;
1020
- let normalizedPos = 0;
1021
- for (let i = 0; i < content.length && normalizedPos < startPos; i++) {
1022
- if (content[i] === '\r' && content[i + 1] === '\n') {
1023
- normalizedPos++; // \r\n becomes \n
1024
- i++; // Skip the \n
1025
- }
1026
- else if (content[i] === '\r') {
1027
- normalizedPos++; // \r becomes \n
1028
- }
1029
- else {
1030
- normalizedPos++;
1031
- }
1032
- originalStartPos = i + 1;
1033
- }
1034
- // Find the end position in original
1035
- let originalEndPos = originalStartPos;
1036
- for (let i = originalStartPos; i < content.length && normalizedPos < endPos; i++) {
1037
- if (content[i] === '\r' && content[i + 1] === '\n') {
1038
- normalizedPos++;
1039
- i++;
1040
- }
1041
- else if (content[i] === '\r') {
1042
- normalizedPos++;
1043
- }
1044
- else {
1045
- normalizedPos++;
1046
- }
1047
- originalEndPos = i + 1;
1048
- }
1049
- return content.substring(originalStartPos, originalEndPos);
1050
- }
1051
- const contentLines = content.split(/\r\n|\r|\n/);
1052
- const searchLines = searchStr.split(/\r\n|\r|\n/);
1053
- // Filter out empty lines from search for more flexible matching
1054
- const searchLinesNonEmpty = searchLines.filter(l => l.trim().length > 0);
1055
- // Try matching with trailing whitespace trimmed from each line
1056
- for (let i = 0; i <= contentLines.length - searchLines.length; i++) {
1057
- let match = true;
1058
- for (let j = 0; j < searchLines.length; j++) {
1059
- const contentLine = contentLines[i + j].trimEnd();
1060
- const searchLine = searchLines[j].trimEnd();
1061
- if (contentLine !== searchLine) {
1062
- match = false;
1063
- break;
1064
- }
1065
- }
1066
- if (match) {
1067
- return this.extractOriginalBlock(content, i, searchLines.length);
1068
- }
1069
- }
1070
- // Try matching with all whitespace fully normalized (aggressive mode)
1071
- // This handles indentation differences like 2-space vs 4-space
1072
- for (let i = 0; i <= contentLines.length - searchLines.length; i++) {
1073
- let match = true;
1074
- for (let j = 0; j < searchLines.length; j++) {
1075
- const contentLine = this.normalizeLineAggressively(contentLines[i + j]);
1076
- const searchLine = this.normalizeLineAggressively(searchLines[j]);
1077
- if (contentLine !== searchLine) {
1078
- match = false;
1079
- break;
1080
- }
1081
- }
1082
- if (match) {
1083
- return this.extractOriginalBlock(content, i, searchLines.length);
1084
- }
1085
- }
1086
- // Try matching with blank lines skipped in both (handles extra/missing blank lines)
1087
- const contentLinesNonEmpty = contentLines.map((l, idx) => ({ line: l, idx })).filter(x => x.line.trim().length > 0);
1088
- if (searchLinesNonEmpty.length > 0 && searchLinesNonEmpty.length <= contentLinesNonEmpty.length) {
1089
- for (let i = 0; i <= contentLinesNonEmpty.length - searchLinesNonEmpty.length; i++) {
1090
- let match = true;
1091
- for (let j = 0; j < searchLinesNonEmpty.length; j++) {
1092
- const contentLine = this.normalizeLineAggressively(contentLinesNonEmpty[i + j].line);
1093
- const searchLine = this.normalizeLineAggressively(searchLinesNonEmpty[j]);
1094
- if (contentLine !== searchLine) {
1095
- match = false;
1096
- break;
1097
- }
1098
- }
1099
- if (match) {
1100
- // Found a match - extract from first to last matching line
1101
- const startIdx = contentLinesNonEmpty[i].idx;
1102
- const endIdx = contentLinesNonEmpty[i + searchLinesNonEmpty.length - 1].idx;
1103
- return this.extractOriginalBlock(content, startIdx, endIdx - startIdx + 1);
1104
- }
1105
- }
1106
- }
1107
- return null;
1108
- }
1109
- /**
1110
- * Aggressively normalize a line for matching - removes all indentation and collapses whitespace
1111
- */
1112
- normalizeLineAggressively(line) {
1113
- return line
1114
- .trim() // Remove leading/trailing whitespace completely
1115
- .replace(/\s+/g, ' ') // Collapse multiple spaces to single space
1116
- .replace(/\s*([{}()[\];,:])\s*/g, '$1') // Remove spaces around punctuation
1117
- .replace(/["'`]/g, '"'); // Normalize quote styles
1118
- }
1119
- /**
1120
- * Extract a block of lines from original content, preserving original line endings
1121
- */
1122
- extractOriginalBlock(content, startLineIdx, numLines) {
1123
- // Find line positions in original content
1124
- const linePositions = [];
1125
- let pos = 0;
1126
- let lineStart = 0;
1127
- while (pos <= content.length) {
1128
- if (pos === content.length || content[pos] === '\n' || content[pos] === '\r') {
1129
- const lineEnd = pos;
1130
- linePositions.push({ start: lineStart, end: lineEnd });
1131
- if (pos < content.length) {
1132
- // Skip line ending
1133
- if (content[pos] === '\r' && content[pos + 1] === '\n') {
1134
- pos += 2;
1135
- }
1136
- else {
1137
- pos += 1;
1138
- }
1139
- lineStart = pos;
1140
- }
1141
- else {
1142
- break;
1143
- }
1144
- }
1145
- else {
1146
- pos++;
1147
- }
1148
- }
1149
- // Extract the requested lines
1150
- // BUG FIX: Also validate numLines to prevent negative endLineIdx calculation
1151
- if (startLineIdx >= linePositions.length || numLines <= 0) {
1152
- return '';
1153
- }
1154
- const endLineIdx = Math.min(startLineIdx + numLines - 1, linePositions.length - 1);
1155
- const blockStart = linePositions[startLineIdx].start;
1156
- const blockEnd = linePositions[endLineIdx].end;
1157
- return content.substring(blockStart, blockEnd);
1158
- }
1159
- /**
1160
- * Normalize indentation by converting tabs to spaces and trimming trailing whitespace
1161
- */
1162
- normalizeIndentation(line) {
1163
- return line.replace(/\t/g, ' ').trimEnd();
1164
- }
1165
- /**
1166
- * Find a similar block of code using line-by-line similarity matching
1167
- * Uses aggressive normalization and wider search windows
1168
- */
1169
- findSimilarBlock(content, searchStr) {
1170
- const contentLines = content.split(/\r?\n/);
1171
- const searchLines = searchStr.split(/\r?\n/);
1172
- if (searchLines.length === 0) {
1173
- return { match: null };
1174
- }
1175
- // Filter out blank lines for more robust matching
1176
- const searchLinesNonEmpty = searchLines.filter(l => l.trim().length > 0);
1177
- if (searchLinesNonEmpty.length === 0) {
1178
- return { match: null };
1179
- }
1180
- // Find the best matching block
1181
- let bestMatch = null;
1182
- const minScore = EDITOR_CONFIG.BLOCK_SIMILARITY_THRESHOLD;
1183
- // Normalize first search line for initial matching
1184
- const firstSearchLineNorm = this.normalizeLineAggressively(searchLinesNonEmpty[0]);
1185
- for (let i = 0; i < contentLines.length; i++) {
1186
- const firstContentLineNorm = this.normalizeLineAggressively(contentLines[i]);
1187
- // Quick check: first non-empty line should have some similarity (using normalized comparison)
1188
- if (firstContentLineNorm.length === 0)
1189
- continue;
1190
- if (this.lineSimilarityNormalized(firstContentLineNorm, firstSearchLineNorm) < EDITOR_CONFIG.SUGGESTION_SIMILARITY_THRESHOLD) {
1191
- continue;
1192
- }
1193
- // Try to match the block starting at this position - wider window (+15 instead of +5)
1194
- const blockEnd = Math.min(i + searchLines.length + 15, contentLines.length);
1195
- for (let endIdx = Math.max(i, i + searchLinesNonEmpty.length - 3); endIdx <= blockEnd; endIdx++) {
1196
- if (endIdx < i)
1197
- continue;
1198
- const candidateLines = contentLines.slice(i, endIdx + 1);
1199
- const score = this.blockSimilarityNormalized(candidateLines, searchLinesNonEmpty);
1200
- if (score >= minScore && (!bestMatch || score > bestMatch.score)) {
1201
- bestMatch = { startIdx: i, endIdx, score };
1202
- }
1203
- }
1204
- }
1205
- if (bestMatch && bestMatch.score >= minScore) {
1206
- return { match: contentLines.slice(bestMatch.startIdx, bestMatch.endIdx + 1).join('\n') };
1207
- }
1208
- // If no match found, try to provide a helpful suggestion
1209
- const suggestion = this.findClosestMatchSuggestion(contentLines, searchLines);
1210
- return { match: null, suggestion };
1211
- }
1212
- /**
1213
- * Line similarity using normalized comparison
1214
- */
1215
- lineSimilarityNormalized(norm1, norm2) {
1216
- if (norm1 === norm2)
1217
- return 1;
1218
- if (norm1.length === 0 && norm2.length === 0)
1219
- return 1;
1220
- if (norm1.length === 0 || norm2.length === 0)
1221
- return 0;
1222
- const maxLen = Math.max(norm1.length, norm2.length);
1223
- const distance = this.levenshteinDistance(norm1, norm2);
1224
- return 1 - (distance / maxLen);
1225
- }
1226
- /**
1227
- * Block similarity using normalized lines and skipping blank lines
1228
- */
1229
- blockSimilarityNormalized(candidateLines, searchLinesNonEmpty) {
1230
- if (searchLinesNonEmpty.length === 0)
1231
- return 0;
1232
- // Normalize and filter candidate lines
1233
- const candidateNonEmpty = candidateLines
1234
- .map(l => this.normalizeLineAggressively(l))
1235
- .filter(l => l.length > 0);
1236
- if (candidateNonEmpty.length === 0)
1237
- return 0;
1238
- // Use LCS-style matching for better tolerance
1239
- let matchedCount = 0;
1240
- let ci = 0;
1241
- for (const searchLine of searchLinesNonEmpty) {
1242
- const searchNorm = this.normalizeLineAggressively(searchLine);
1243
- if (searchNorm.length === 0)
1244
- continue;
1245
- // Look for a matching line in remaining candidates
1246
- while (ci < candidateNonEmpty.length) {
1247
- const sim = this.lineSimilarityNormalized(candidateNonEmpty[ci], searchNorm);
1248
- ci++;
1249
- if (sim >= 0.5) {
1250
- matchedCount++;
1251
- break;
1252
- }
1253
- }
1254
- }
1255
- return matchedCount / searchLinesNonEmpty.length;
1256
- }
1257
- /**
1258
- * Calculate similarity between two lines (0-1)
1259
- */
1260
- lineSimilarity(line1, line2) {
1261
- const s1 = line1.trim();
1262
- const s2 = line2.trim();
1263
- if (s1 === s2)
1264
- return 1;
1265
- if (s1.length === 0 && s2.length === 0)
1266
- return 1;
1267
- if (s1.length === 0 || s2.length === 0)
1268
- return 0;
1269
- // Use Levenshtein distance-based similarity
1270
- const maxLen = Math.max(s1.length, s2.length);
1271
- const distance = this.levenshteinDistance(s1, s2);
1272
- return 1 - (distance / maxLen);
1273
- }
1274
- /**
1275
- * Levenshtein distance for string similarity
1276
- */
1277
- levenshteinDistance(s1, s2) {
1278
- const m = s1.length;
1279
- const n = s2.length;
1280
- // Use two rows instead of full matrix for memory efficiency
1281
- let prev = new Array(n + 1);
1282
- let curr = new Array(n + 1);
1283
- for (let j = 0; j <= n; j++) {
1284
- prev[j] = j;
1285
- }
1286
- for (let i = 1; i <= m; i++) {
1287
- curr[0] = i;
1288
- for (let j = 1; j <= n; j++) {
1289
- if (s1[i - 1] === s2[j - 1]) {
1290
- curr[j] = prev[j - 1];
1291
- }
1292
- else {
1293
- curr[j] = 1 + Math.min(prev[j - 1], prev[j], curr[j - 1]);
1294
- }
1295
- }
1296
- [prev, curr] = [curr, prev];
1297
- }
1298
- return prev[n];
1299
- }
1300
- /**
1301
- * Find and suggest the closest matching location
1302
- */
1303
- findClosestMatchSuggestion(contentLines, searchLines) {
1304
- if (searchLines.length === 0)
1305
- return undefined;
1306
- const firstSearchLine = searchLines[0].trim();
1307
- let bestLineIdx = -1;
1308
- let bestSim = 0;
1309
- for (let i = 0; i < contentLines.length; i++) {
1310
- const sim = this.lineSimilarity(contentLines[i], firstSearchLine);
1311
- if (sim > bestSim) {
1312
- bestSim = sim;
1313
- bestLineIdx = i;
1314
- }
1315
- }
1316
- if (bestLineIdx >= 0 && bestSim >= EDITOR_CONFIG.SUGGESTION_SIMILARITY_THRESHOLD) {
1317
- const actualLine = contentLines[bestLineIdx].trim();
1318
- const lineNum = bestLineIdx + 1;
1319
- if (bestSim < 0.9) {
1320
- return `Did you mean line ${lineNum}? Found: "${actualLine.substring(0, 60)}${actualLine.length > 60 ? '...' : ''}"`;
1321
- }
1322
- }
1323
- return undefined;
1324
- }
1325
- /**
1326
- * Find a similar single line in the content
1327
- */
1328
- findSimilarLine(content, searchStr) {
1329
- const lines = content.split(/\r?\n/);
1330
- const searchTrimmed = searchStr.trim();
1331
- // First try exact match with trimmed whitespace
1332
- for (const line of lines) {
1333
- if (line.trim() === searchTrimmed) {
1334
- return { match: line };
1335
- }
1336
- }
1337
- // Try normalized indentation match
1338
- const searchNormalized = this.normalizeIndentation(searchStr);
1339
- for (const line of lines) {
1340
- if (this.normalizeIndentation(line) === searchNormalized) {
1341
- return { match: line };
1342
- }
1343
- }
1344
- // Find best similar line
1345
- let bestLine = null;
1346
- let bestSim = 0;
1347
- const minSim = EDITOR_CONFIG.LINE_SIMILARITY_THRESHOLD;
1348
- for (const line of lines) {
1349
- const sim = this.lineSimilarity(line, searchStr);
1350
- if (sim > bestSim) {
1351
- bestSim = sim;
1352
- bestLine = line;
1353
- }
1354
- }
1355
- if (bestLine && bestSim >= minSim) {
1356
- return { match: bestLine };
1357
- }
1358
- // Provide suggestion if we found something close
1359
- if (bestLine && bestSim >= 0.5) {
1360
- const lineIdx = lines.indexOf(bestLine);
1361
- return {
1362
- match: null,
1363
- suggestion: `Did you mean line ${lineIdx + 1}? Found: "${bestLine.trim().substring(0, 50)}${bestLine.trim().length > 50 ? '...' : ''}"`
1364
- };
1365
- }
1366
- return { match: null };
1367
- }
1368
- }
1369
- //# sourceMappingURL=text-editor.js.map