@cleanslate/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (581) hide show
  1. package/LICENSE +22 -0
  2. package/NOTICE +48 -0
  3. package/README.md +103 -0
  4. package/VENDOR.md +60 -0
  5. package/dist/agent/cleanSlateAgentExecutionPhase.d.ts +55 -0
  6. package/dist/agent/cleanSlateAgentExecutionPhase.d.ts.map +1 -0
  7. package/dist/agent/cleanSlateAgentExecutionPhase.js +474 -0
  8. package/dist/agent/cleanSlateAgentExecutionPhase.js.map +1 -0
  9. package/dist/agent/cleanSlateAgentExecutionSupport.d.ts +22 -0
  10. package/dist/agent/cleanSlateAgentExecutionSupport.d.ts.map +1 -0
  11. package/dist/agent/cleanSlateAgentExecutionSupport.js +205 -0
  12. package/dist/agent/cleanSlateAgentExecutionSupport.js.map +1 -0
  13. package/dist/agent/cleanSlateAgentParsing.d.ts +21 -0
  14. package/dist/agent/cleanSlateAgentParsing.d.ts.map +1 -0
  15. package/dist/agent/cleanSlateAgentParsing.js +106 -0
  16. package/dist/agent/cleanSlateAgentParsing.js.map +1 -0
  17. package/dist/agent/cleanSlateAgentSession.d.ts +44 -0
  18. package/dist/agent/cleanSlateAgentSession.d.ts.map +1 -0
  19. package/dist/agent/cleanSlateAgentSession.js +205 -0
  20. package/dist/agent/cleanSlateAgentSession.js.map +1 -0
  21. package/dist/agent/cleanSlateAgentTypes.d.ts +91 -0
  22. package/dist/agent/cleanSlateAgentTypes.d.ts.map +1 -0
  23. package/dist/agent/cleanSlateAgentTypes.js +27 -0
  24. package/dist/agent/cleanSlateAgentTypes.js.map +1 -0
  25. package/dist/agent/cleanSlateCommandPolicy.d.ts +12 -0
  26. package/dist/agent/cleanSlateCommandPolicy.d.ts.map +1 -0
  27. package/dist/agent/cleanSlateCommandPolicy.js +30 -0
  28. package/dist/agent/cleanSlateCommandPolicy.js.map +1 -0
  29. package/dist/agent/cleanSlateContextBudgetManager.d.ts +82 -0
  30. package/dist/agent/cleanSlateContextBudgetManager.d.ts.map +1 -0
  31. package/dist/agent/cleanSlateContextBudgetManager.js +419 -0
  32. package/dist/agent/cleanSlateContextBudgetManager.js.map +1 -0
  33. package/dist/agent/cleanSlateDomainProfile.d.ts +71 -0
  34. package/dist/agent/cleanSlateDomainProfile.d.ts.map +1 -0
  35. package/dist/agent/cleanSlateDomainProfile.js +124 -0
  36. package/dist/agent/cleanSlateDomainProfile.js.map +1 -0
  37. package/dist/agent/cleanSlateExecutionBudget.d.ts +19 -0
  38. package/dist/agent/cleanSlateExecutionBudget.d.ts.map +1 -0
  39. package/dist/agent/cleanSlateExecutionBudget.js +28 -0
  40. package/dist/agent/cleanSlateExecutionBudget.js.map +1 -0
  41. package/dist/agent/cleanSlateExecutionEditPolicy.d.ts +15 -0
  42. package/dist/agent/cleanSlateExecutionEditPolicy.d.ts.map +1 -0
  43. package/dist/agent/cleanSlateExecutionEditPolicy.js +148 -0
  44. package/dist/agent/cleanSlateExecutionEditPolicy.js.map +1 -0
  45. package/dist/agent/cleanSlateExecutionEvidenceLedger.d.ts +23 -0
  46. package/dist/agent/cleanSlateExecutionEvidenceLedger.d.ts.map +1 -0
  47. package/dist/agent/cleanSlateExecutionEvidenceLedger.js +121 -0
  48. package/dist/agent/cleanSlateExecutionEvidenceLedger.js.map +1 -0
  49. package/dist/agent/cleanSlateExecutionLoopPrompts.d.ts +5 -0
  50. package/dist/agent/cleanSlateExecutionLoopPrompts.d.ts.map +1 -0
  51. package/dist/agent/cleanSlateExecutionLoopPrompts.js +41 -0
  52. package/dist/agent/cleanSlateExecutionLoopPrompts.js.map +1 -0
  53. package/dist/agent/cleanSlateExecutionQuery.d.ts +162 -0
  54. package/dist/agent/cleanSlateExecutionQuery.d.ts.map +1 -0
  55. package/dist/agent/cleanSlateExecutionQuery.js +1448 -0
  56. package/dist/agent/cleanSlateExecutionQuery.js.map +1 -0
  57. package/dist/agent/cleanSlateFilesModifiedService.d.ts +96 -0
  58. package/dist/agent/cleanSlateFilesModifiedService.d.ts.map +1 -0
  59. package/dist/agent/cleanSlateFilesModifiedService.js +581 -0
  60. package/dist/agent/cleanSlateFilesModifiedService.js.map +1 -0
  61. package/dist/agent/cleanSlateNativeToolTranscript.d.ts +22 -0
  62. package/dist/agent/cleanSlateNativeToolTranscript.d.ts.map +1 -0
  63. package/dist/agent/cleanSlateNativeToolTranscript.js +77 -0
  64. package/dist/agent/cleanSlateNativeToolTranscript.js.map +1 -0
  65. package/dist/agent/cleanSlatePrompts.d.ts +30 -0
  66. package/dist/agent/cleanSlatePrompts.d.ts.map +1 -0
  67. package/dist/agent/cleanSlatePrompts.js +65 -0
  68. package/dist/agent/cleanSlatePrompts.js.map +1 -0
  69. package/dist/agent/cleanSlateQueryRunner.d.ts +56 -0
  70. package/dist/agent/cleanSlateQueryRunner.d.ts.map +1 -0
  71. package/dist/agent/cleanSlateQueryRunner.js +69 -0
  72. package/dist/agent/cleanSlateQueryRunner.js.map +1 -0
  73. package/dist/agent/cleanSlateRuntimePromptBuilder.d.ts +30 -0
  74. package/dist/agent/cleanSlateRuntimePromptBuilder.d.ts.map +1 -0
  75. package/dist/agent/cleanSlateRuntimePromptBuilder.js +99 -0
  76. package/dist/agent/cleanSlateRuntimePromptBuilder.js.map +1 -0
  77. package/dist/agent/cleanSlateStreamingToolExecutor.d.ts +55 -0
  78. package/dist/agent/cleanSlateStreamingToolExecutor.d.ts.map +1 -0
  79. package/dist/agent/cleanSlateStreamingToolExecutor.js +214 -0
  80. package/dist/agent/cleanSlateStreamingToolExecutor.js.map +1 -0
  81. package/dist/agent/cleanSlateToolCallLedger.d.ts +32 -0
  82. package/dist/agent/cleanSlateToolCallLedger.d.ts.map +1 -0
  83. package/dist/agent/cleanSlateToolCallLedger.js +164 -0
  84. package/dist/agent/cleanSlateToolCallLedger.js.map +1 -0
  85. package/dist/agent/cleanSlateToolResultPromptSerializer.d.ts +9 -0
  86. package/dist/agent/cleanSlateToolResultPromptSerializer.d.ts.map +1 -0
  87. package/dist/agent/cleanSlateToolResultPromptSerializer.js +184 -0
  88. package/dist/agent/cleanSlateToolResultPromptSerializer.js.map +1 -0
  89. package/dist/composer/commands/slashCommands.d.ts +8 -0
  90. package/dist/composer/commands/slashCommands.d.ts.map +1 -0
  91. package/dist/composer/commands/slashCommands.js +46 -0
  92. package/dist/composer/commands/slashCommands.js.map +1 -0
  93. package/dist/composer/instructions/baseInstructions.d.ts +3 -0
  94. package/dist/composer/instructions/baseInstructions.d.ts.map +1 -0
  95. package/dist/composer/instructions/baseInstructions.js +35 -0
  96. package/dist/composer/instructions/baseInstructions.js.map +1 -0
  97. package/dist/composer/instructions/runtimeInstructions.d.ts +11 -0
  98. package/dist/composer/instructions/runtimeInstructions.d.ts.map +1 -0
  99. package/dist/composer/instructions/runtimeInstructions.js +31 -0
  100. package/dist/composer/instructions/runtimeInstructions.js.map +1 -0
  101. package/dist/composer/kernel/coreKernel.d.ts +3 -0
  102. package/dist/composer/kernel/coreKernel.d.ts.map +1 -0
  103. package/dist/composer/kernel/coreKernel.js +11 -0
  104. package/dist/composer/kernel/coreKernel.js.map +1 -0
  105. package/dist/composer/kernel/editingRules.d.ts +3 -0
  106. package/dist/composer/kernel/editingRules.d.ts.map +1 -0
  107. package/dist/composer/kernel/editingRules.js +24 -0
  108. package/dist/composer/kernel/editingRules.js.map +1 -0
  109. package/dist/composer/kernel/toolProtocols.d.ts +2 -0
  110. package/dist/composer/kernel/toolProtocols.d.ts.map +1 -0
  111. package/dist/composer/kernel/toolProtocols.js +32 -0
  112. package/dist/composer/kernel/toolProtocols.js.map +1 -0
  113. package/dist/composer/modes/execution.mode.d.ts +2 -0
  114. package/dist/composer/modes/execution.mode.d.ts.map +1 -0
  115. package/dist/composer/modes/execution.mode.js +21 -0
  116. package/dist/composer/modes/execution.mode.js.map +1 -0
  117. package/dist/composer/modes/planning.mode.d.ts +2 -0
  118. package/dist/composer/modes/planning.mode.d.ts.map +1 -0
  119. package/dist/composer/modes/planning.mode.js +23 -0
  120. package/dist/composer/modes/planning.mode.js.map +1 -0
  121. package/dist/composer/promptComposer.d.ts +22 -0
  122. package/dist/composer/promptComposer.d.ts.map +1 -0
  123. package/dist/composer/promptComposer.js +62 -0
  124. package/dist/composer/promptComposer.js.map +1 -0
  125. package/dist/composer/registry/agentSchema.d.ts +16 -0
  126. package/dist/composer/registry/agentSchema.d.ts.map +1 -0
  127. package/dist/composer/registry/agentSchema.js +6 -0
  128. package/dist/composer/registry/agentSchema.js.map +1 -0
  129. package/dist/core/arrays.d.ts +311 -0
  130. package/dist/core/arrays.d.ts.map +1 -0
  131. package/dist/core/arrays.js +811 -0
  132. package/dist/core/arrays.js.map +1 -0
  133. package/dist/core/arraysFind.d.ts +72 -0
  134. package/dist/core/arraysFind.d.ts.map +1 -0
  135. package/dist/core/arraysFind.js +200 -0
  136. package/dist/core/arraysFind.js.map +1 -0
  137. package/dist/core/assert.d.ts +36 -0
  138. package/dist/core/assert.d.ts.map +1 -0
  139. package/dist/core/assert.js +84 -0
  140. package/dist/core/assert.js.map +1 -0
  141. package/dist/core/async.d.ts +11 -0
  142. package/dist/core/async.d.ts.map +1 -0
  143. package/dist/core/async.js +6 -0
  144. package/dist/core/async.js.map +1 -0
  145. package/dist/core/buffer.d.ts +23 -0
  146. package/dist/core/buffer.d.ts.map +1 -0
  147. package/dist/core/buffer.js +40 -0
  148. package/dist/core/buffer.js.map +1 -0
  149. package/dist/core/cancellation.d.ts +52 -0
  150. package/dist/core/cancellation.d.ts.map +1 -0
  151. package/dist/core/cancellation.js +169 -0
  152. package/dist/core/cancellation.js.map +1 -0
  153. package/dist/core/charCode.d.ts +428 -0
  154. package/dist/core/charCode.d.ts.map +1 -0
  155. package/dist/core/charCode.js +439 -0
  156. package/dist/core/charCode.js.map +1 -0
  157. package/dist/core/collections.d.ts +49 -0
  158. package/dist/core/collections.d.ts.map +1 -0
  159. package/dist/core/collections.js +132 -0
  160. package/dist/core/collections.js.map +1 -0
  161. package/dist/core/diff/diff.d.ts +151 -0
  162. package/dist/core/diff/diff.d.ts.map +1 -0
  163. package/dist/core/diff/diff.js +1076 -0
  164. package/dist/core/diff/diff.js.map +1 -0
  165. package/dist/core/diff/diffChange.d.ts +39 -0
  166. package/dist/core/diff/diffChange.d.ts.map +1 -0
  167. package/dist/core/diff/diffChange.js +37 -0
  168. package/dist/core/diff/diffChange.js.map +1 -0
  169. package/dist/core/errors.d.ts +114 -0
  170. package/dist/core/errors.d.ts.map +1 -0
  171. package/dist/core/errors.js +258 -0
  172. package/dist/core/errors.js.map +1 -0
  173. package/dist/core/event.d.ts +595 -0
  174. package/dist/core/event.d.ts.map +1 -0
  175. package/dist/core/event.js +1479 -0
  176. package/dist/core/event.js.map +1 -0
  177. package/dist/core/functional.d.ts +5 -0
  178. package/dist/core/functional.d.ts.map +1 -0
  179. package/dist/core/functional.js +35 -0
  180. package/dist/core/functional.js.map +1 -0
  181. package/dist/core/hash.d.ts +15 -0
  182. package/dist/core/hash.d.ts.map +1 -0
  183. package/dist/core/hash.js +27 -0
  184. package/dist/core/hash.js.map +1 -0
  185. package/dist/core/iterator.d.ts +33 -0
  186. package/dist/core/iterator.d.ts.map +1 -0
  187. package/dist/core/iterator.js +188 -0
  188. package/dist/core/iterator.js.map +1 -0
  189. package/dist/core/lifecycle.d.ts +313 -0
  190. package/dist/core/lifecycle.d.ts.map +1 -0
  191. package/dist/core/lifecycle.js +789 -0
  192. package/dist/core/lifecycle.js.map +1 -0
  193. package/dist/core/linkedList.d.ts +17 -0
  194. package/dist/core/linkedList.d.ts.map +1 -0
  195. package/dist/core/linkedList.js +138 -0
  196. package/dist/core/linkedList.js.map +1 -0
  197. package/dist/core/map.d.ts +175 -0
  198. package/dist/core/map.d.ts.map +1 -0
  199. package/dist/core/map.js +796 -0
  200. package/dist/core/map.js.map +1 -0
  201. package/dist/core/marshallingIds.d.ts +29 -0
  202. package/dist/core/marshallingIds.d.ts.map +1 -0
  203. package/dist/core/marshallingIds.js +38 -0
  204. package/dist/core/marshallingIds.js.map +1 -0
  205. package/dist/core/observable.d.ts +28 -0
  206. package/dist/core/observable.d.ts.map +1 -0
  207. package/dist/core/observable.js +6 -0
  208. package/dist/core/observable.js.map +1 -0
  209. package/dist/core/platform.d.ts +4 -0
  210. package/dist/core/platform.d.ts.map +1 -0
  211. package/dist/core/platform.js +17 -0
  212. package/dist/core/platform.js.map +1 -0
  213. package/dist/core/position.d.ts +91 -0
  214. package/dist/core/position.d.ts.map +1 -0
  215. package/dist/core/position.js +145 -0
  216. package/dist/core/position.js.map +1 -0
  217. package/dist/core/range.d.ts +198 -0
  218. package/dist/core/range.d.ts.map +1 -0
  219. package/dist/core/range.js +426 -0
  220. package/dist/core/range.js.map +1 -0
  221. package/dist/core/resources.d.ts +10 -0
  222. package/dist/core/resources.d.ts.map +1 -0
  223. package/dist/core/resources.js +126 -0
  224. package/dist/core/resources.js.map +1 -0
  225. package/dist/core/sequence.d.ts +20 -0
  226. package/dist/core/sequence.d.ts.map +1 -0
  227. package/dist/core/sequence.js +21 -0
  228. package/dist/core/sequence.js.map +1 -0
  229. package/dist/core/stopwatch.d.ts +11 -0
  230. package/dist/core/stopwatch.d.ts.map +1 -0
  231. package/dist/core/stopwatch.js +33 -0
  232. package/dist/core/stopwatch.js.map +1 -0
  233. package/dist/core/symbols.d.ts +5 -0
  234. package/dist/core/symbols.d.ts.map +1 -0
  235. package/dist/core/symbols.js +13 -0
  236. package/dist/core/symbols.js.map +1 -0
  237. package/dist/core/types.d.ts +229 -0
  238. package/dist/core/types.d.ts.map +1 -0
  239. package/dist/core/types.js +278 -0
  240. package/dist/core/types.js.map +1 -0
  241. package/dist/core/uint.d.ts +32 -0
  242. package/dist/core/uint.d.ts.map +1 -0
  243. package/dist/core/uint.js +57 -0
  244. package/dist/core/uint.js.map +1 -0
  245. package/dist/core/uri.d.ts +172 -0
  246. package/dist/core/uri.d.ts.map +1 -0
  247. package/dist/core/uri.js +623 -0
  248. package/dist/core/uri.js.map +1 -0
  249. package/dist/host/browserAutomation.d.ts +276 -0
  250. package/dist/host/browserAutomation.d.ts.map +1 -0
  251. package/dist/host/browserAutomation.js +6 -0
  252. package/dist/host/browserAutomation.js.map +1 -0
  253. package/dist/host/diagnostics.d.ts +68 -0
  254. package/dist/host/diagnostics.d.ts.map +1 -0
  255. package/dist/host/diagnostics.js +41 -0
  256. package/dist/host/diagnostics.js.map +1 -0
  257. package/dist/host/files.d.ts +70 -0
  258. package/dist/host/files.d.ts.map +1 -0
  259. package/dist/host/files.js +54 -0
  260. package/dist/host/files.js.map +1 -0
  261. package/dist/host/services.d.ts +106 -0
  262. package/dist/host/services.d.ts.map +1 -0
  263. package/dist/host/services.js +6 -0
  264. package/dist/host/services.js.map +1 -0
  265. package/dist/host/symbols.d.ts +45 -0
  266. package/dist/host/symbols.d.ts.map +1 -0
  267. package/dist/host/symbols.js +43 -0
  268. package/dist/host/symbols.js.map +1 -0
  269. package/dist/host/textModel.d.ts +83 -0
  270. package/dist/host/textModel.d.ts.map +1 -0
  271. package/dist/host/textModel.js +6 -0
  272. package/dist/host/textModel.js.map +1 -0
  273. package/dist/host/workspace.d.ts +123 -0
  274. package/dist/host/workspace.d.ts.map +1 -0
  275. package/dist/host/workspace.js +32 -0
  276. package/dist/host/workspace.js.map +1 -0
  277. package/dist/index.d.ts +40 -0
  278. package/dist/index.d.ts.map +1 -0
  279. package/dist/index.js +26 -0
  280. package/dist/index.js.map +1 -0
  281. package/dist/node/cleanSlateAnthropicMessageAdapter.d.ts +12 -0
  282. package/dist/node/cleanSlateAnthropicMessageAdapter.d.ts.map +1 -0
  283. package/dist/node/cleanSlateAnthropicMessageAdapter.js +130 -0
  284. package/dist/node/cleanSlateAnthropicMessageAdapter.js.map +1 -0
  285. package/dist/node/cleanSlateHeadlessRunner.d.ts +63 -0
  286. package/dist/node/cleanSlateHeadlessRunner.d.ts.map +1 -0
  287. package/dist/node/cleanSlateHeadlessRunner.js +84 -0
  288. package/dist/node/cleanSlateHeadlessRunner.js.map +1 -0
  289. package/dist/node/cleanSlateNodeAgentRuntime.d.ts +94 -0
  290. package/dist/node/cleanSlateNodeAgentRuntime.d.ts.map +1 -0
  291. package/dist/node/cleanSlateNodeAgentRuntime.js +339 -0
  292. package/dist/node/cleanSlateNodeAgentRuntime.js.map +1 -0
  293. package/dist/node/cleanSlateNodeBrowserAutomation.d.ts +279 -0
  294. package/dist/node/cleanSlateNodeBrowserAutomation.d.ts.map +1 -0
  295. package/dist/node/cleanSlateNodeBrowserAutomation.js +470 -0
  296. package/dist/node/cleanSlateNodeBrowserAutomation.js.map +1 -0
  297. package/dist/node/cleanSlateNodeCommandService.d.ts +40 -0
  298. package/dist/node/cleanSlateNodeCommandService.d.ts.map +1 -0
  299. package/dist/node/cleanSlateNodeCommandService.js +435 -0
  300. package/dist/node/cleanSlateNodeCommandService.js.map +1 -0
  301. package/dist/node/cleanSlateNodeFileServices.d.ts +68 -0
  302. package/dist/node/cleanSlateNodeFileServices.d.ts.map +1 -0
  303. package/dist/node/cleanSlateNodeFileServices.js +138 -0
  304. package/dist/node/cleanSlateNodeFileServices.js.map +1 -0
  305. package/dist/node/cleanSlateNodeIndexService.d.ts +17 -0
  306. package/dist/node/cleanSlateNodeIndexService.d.ts.map +1 -0
  307. package/dist/node/cleanSlateNodeIndexService.js +128 -0
  308. package/dist/node/cleanSlateNodeIndexService.js.map +1 -0
  309. package/dist/node/cleanSlateNodeLanguageCommands.d.ts +11 -0
  310. package/dist/node/cleanSlateNodeLanguageCommands.d.ts.map +1 -0
  311. package/dist/node/cleanSlateNodeLanguageCommands.js +146 -0
  312. package/dist/node/cleanSlateNodeLanguageCommands.js.map +1 -0
  313. package/dist/node/cleanSlateNodeMainService.d.ts +87 -0
  314. package/dist/node/cleanSlateNodeMainService.d.ts.map +1 -0
  315. package/dist/node/cleanSlateNodeMainService.js +1304 -0
  316. package/dist/node/cleanSlateNodeMainService.js.map +1 -0
  317. package/dist/node/cleanSlateNodeMcpClient.d.ts +20 -0
  318. package/dist/node/cleanSlateNodeMcpClient.d.ts.map +1 -0
  319. package/dist/node/cleanSlateNodeMcpClient.js +184 -0
  320. package/dist/node/cleanSlateNodeMcpClient.js.map +1 -0
  321. package/dist/node/cleanSlateNodeSearchService.d.ts +14 -0
  322. package/dist/node/cleanSlateNodeSearchService.d.ts.map +1 -0
  323. package/dist/node/cleanSlateNodeSearchService.js +180 -0
  324. package/dist/node/cleanSlateNodeSearchService.js.map +1 -0
  325. package/dist/node/cleanSlateNodeTextModel.d.ts +56 -0
  326. package/dist/node/cleanSlateNodeTextModel.d.ts.map +1 -0
  327. package/dist/node/cleanSlateNodeTextModel.js +127 -0
  328. package/dist/node/cleanSlateNodeTextModel.js.map +1 -0
  329. package/dist/node/cleanSlateNodeToolContext.d.ts +50 -0
  330. package/dist/node/cleanSlateNodeToolContext.d.ts.map +1 -0
  331. package/dist/node/cleanSlateNodeToolContext.js +134 -0
  332. package/dist/node/cleanSlateNodeToolContext.js.map +1 -0
  333. package/dist/node/cleanSlateNodeWebRetrieval.d.ts +20 -0
  334. package/dist/node/cleanSlateNodeWebRetrieval.d.ts.map +1 -0
  335. package/dist/node/cleanSlateNodeWebRetrieval.js +379 -0
  336. package/dist/node/cleanSlateNodeWebRetrieval.js.map +1 -0
  337. package/dist/node/cleanSlateOpenAIMessageAdapter.d.ts +8 -0
  338. package/dist/node/cleanSlateOpenAIMessageAdapter.d.ts.map +1 -0
  339. package/dist/node/cleanSlateOpenAIMessageAdapter.js +111 -0
  340. package/dist/node/cleanSlateOpenAIMessageAdapter.js.map +1 -0
  341. package/dist/node/cleanSlateProviderSchemaNormalizer.d.ts +18 -0
  342. package/dist/node/cleanSlateProviderSchemaNormalizer.d.ts.map +1 -0
  343. package/dist/node/cleanSlateProviderSchemaNormalizer.js +175 -0
  344. package/dist/node/cleanSlateProviderSchemaNormalizer.js.map +1 -0
  345. package/dist/node/index.d.ts +25 -0
  346. package/dist/node/index.d.ts.map +1 -0
  347. package/dist/node/index.js +28 -0
  348. package/dist/node/index.js.map +1 -0
  349. package/dist/protocol/cleanSlateAI.d.ts +964 -0
  350. package/dist/protocol/cleanSlateAI.d.ts.map +1 -0
  351. package/dist/protocol/cleanSlateAI.js +35 -0
  352. package/dist/protocol/cleanSlateAI.js.map +1 -0
  353. package/dist/protocol/cleanSlateModelCapabilities.d.ts +86 -0
  354. package/dist/protocol/cleanSlateModelCapabilities.d.ts.map +1 -0
  355. package/dist/protocol/cleanSlateModelCapabilities.js +1104 -0
  356. package/dist/protocol/cleanSlateModelCapabilities.js.map +1 -0
  357. package/dist/protocol/cleanSlateProviderMessageTransforms.d.ts +11 -0
  358. package/dist/protocol/cleanSlateProviderMessageTransforms.d.ts.map +1 -0
  359. package/dist/protocol/cleanSlateProviderMessageTransforms.js +178 -0
  360. package/dist/protocol/cleanSlateProviderMessageTransforms.js.map +1 -0
  361. package/dist/protocol/cleanSlateService.d.ts +68 -0
  362. package/dist/protocol/cleanSlateService.d.ts.map +1 -0
  363. package/dist/protocol/cleanSlateService.js +1149 -0
  364. package/dist/protocol/cleanSlateService.js.map +1 -0
  365. package/dist/services/cleanSlateCancellation.d.ts +7 -0
  366. package/dist/services/cleanSlateCancellation.d.ts.map +1 -0
  367. package/dist/services/cleanSlateCancellation.js +56 -0
  368. package/dist/services/cleanSlateCancellation.js.map +1 -0
  369. package/dist/services/cleanSlateCommandExecutionService.d.ts +25 -0
  370. package/dist/services/cleanSlateCommandExecutionService.d.ts.map +1 -0
  371. package/dist/services/cleanSlateCommandExecutionService.js +31 -0
  372. package/dist/services/cleanSlateCommandExecutionService.js.map +1 -0
  373. package/dist/services/cleanSlateDiffService.d.ts +62 -0
  374. package/dist/services/cleanSlateDiffService.d.ts.map +1 -0
  375. package/dist/services/cleanSlateDiffService.js +428 -0
  376. package/dist/services/cleanSlateDiffService.js.map +1 -0
  377. package/dist/services/cleanSlateEditMatchValidator.d.ts +63 -0
  378. package/dist/services/cleanSlateEditMatchValidator.d.ts.map +1 -0
  379. package/dist/services/cleanSlateEditMatchValidator.js +341 -0
  380. package/dist/services/cleanSlateEditMatchValidator.js.map +1 -0
  381. package/dist/services/cleanSlateEditService.d.ts +155 -0
  382. package/dist/services/cleanSlateEditService.d.ts.map +1 -0
  383. package/dist/services/cleanSlateEditService.js +848 -0
  384. package/dist/services/cleanSlateEditService.js.map +1 -0
  385. package/dist/services/cleanSlateFileHistory.d.ts +56 -0
  386. package/dist/services/cleanSlateFileHistory.d.ts.map +1 -0
  387. package/dist/services/cleanSlateFileHistory.js +157 -0
  388. package/dist/services/cleanSlateFileHistory.js.map +1 -0
  389. package/dist/services/cleanSlateTaskEvidenceCodec.d.ts +15 -0
  390. package/dist/services/cleanSlateTaskEvidenceCodec.d.ts.map +1 -0
  391. package/dist/services/cleanSlateTaskEvidenceCodec.js +151 -0
  392. package/dist/services/cleanSlateTaskEvidenceCodec.js.map +1 -0
  393. package/dist/services/cleanSlateTaskSessionService.d.ts +258 -0
  394. package/dist/services/cleanSlateTaskSessionService.d.ts.map +1 -0
  395. package/dist/services/cleanSlateTaskSessionService.js +1079 -0
  396. package/dist/services/cleanSlateTaskSessionService.js.map +1 -0
  397. package/dist/services/cleanSlateTaskState.d.ts +32 -0
  398. package/dist/services/cleanSlateTaskState.d.ts.map +1 -0
  399. package/dist/services/cleanSlateTaskState.js +40 -0
  400. package/dist/services/cleanSlateTaskState.js.map +1 -0
  401. package/dist/services/cleanSlateThreadService.d.ts +64 -0
  402. package/dist/services/cleanSlateThreadService.d.ts.map +1 -0
  403. package/dist/services/cleanSlateThreadService.js +188 -0
  404. package/dist/services/cleanSlateThreadService.js.map +1 -0
  405. package/dist/services/cleanSlateTools.d.ts +29 -0
  406. package/dist/services/cleanSlateTools.d.ts.map +1 -0
  407. package/dist/services/cleanSlateTools.js +38 -0
  408. package/dist/services/cleanSlateTools.js.map +1 -0
  409. package/dist/services/cleanSlateVerificationTargetTracker.d.ts +23 -0
  410. package/dist/services/cleanSlateVerificationTargetTracker.d.ts.map +1 -0
  411. package/dist/services/cleanSlateVerificationTargetTracker.js +214 -0
  412. package/dist/services/cleanSlateVerificationTargetTracker.js.map +1 -0
  413. package/dist/skills/cleanSlateSkillCatalog.d.ts +29 -0
  414. package/dist/skills/cleanSlateSkillCatalog.d.ts.map +1 -0
  415. package/dist/skills/cleanSlateSkillCatalog.js +225 -0
  416. package/dist/skills/cleanSlateSkillCatalog.js.map +1 -0
  417. package/dist/tools/ApplyEditTool.d.ts +73 -0
  418. package/dist/tools/ApplyEditTool.d.ts.map +1 -0
  419. package/dist/tools/ApplyEditTool.js +741 -0
  420. package/dist/tools/ApplyEditTool.js.map +1 -0
  421. package/dist/tools/AskQuestionTool.d.ts +3 -0
  422. package/dist/tools/AskQuestionTool.d.ts.map +1 -0
  423. package/dist/tools/AskQuestionTool.js +113 -0
  424. package/dist/tools/AskQuestionTool.js.map +1 -0
  425. package/dist/tools/BrowserAutomationTools.d.ts +28 -0
  426. package/dist/tools/BrowserAutomationTools.d.ts.map +1 -0
  427. package/dist/tools/BrowserAutomationTools.js +639 -0
  428. package/dist/tools/BrowserAutomationTools.js.map +1 -0
  429. package/dist/tools/CreateMultipleFilesTool.d.ts +6 -0
  430. package/dist/tools/CreateMultipleFilesTool.d.ts.map +1 -0
  431. package/dist/tools/CreateMultipleFilesTool.js +115 -0
  432. package/dist/tools/CreateMultipleFilesTool.js.map +1 -0
  433. package/dist/tools/ExecuteCommandTool.d.ts +12 -0
  434. package/dist/tools/ExecuteCommandTool.d.ts.map +1 -0
  435. package/dist/tools/ExecuteCommandTool.js +378 -0
  436. package/dist/tools/ExecuteCommandTool.js.map +1 -0
  437. package/dist/tools/FileHistoryRewindTool.d.ts +3 -0
  438. package/dist/tools/FileHistoryRewindTool.d.ts.map +1 -0
  439. package/dist/tools/FileHistoryRewindTool.js +45 -0
  440. package/dist/tools/FileHistoryRewindTool.js.map +1 -0
  441. package/dist/tools/FindByNameTool.d.ts +6 -0
  442. package/dist/tools/FindByNameTool.d.ts.map +1 -0
  443. package/dist/tools/FindByNameTool.js +80 -0
  444. package/dist/tools/FindByNameTool.js.map +1 -0
  445. package/dist/tools/FindReferencesTool.d.ts +3 -0
  446. package/dist/tools/FindReferencesTool.d.ts.map +1 -0
  447. package/dist/tools/FindReferencesTool.js +128 -0
  448. package/dist/tools/FindReferencesTool.js.map +1 -0
  449. package/dist/tools/GetDefinitionsTool.d.ts +3 -0
  450. package/dist/tools/GetDefinitionsTool.d.ts.map +1 -0
  451. package/dist/tools/GetDefinitionsTool.js +136 -0
  452. package/dist/tools/GetDefinitionsTool.js.map +1 -0
  453. package/dist/tools/GetOpenFilesTool.d.ts +6 -0
  454. package/dist/tools/GetOpenFilesTool.d.ts.map +1 -0
  455. package/dist/tools/GetOpenFilesTool.js +21 -0
  456. package/dist/tools/GetOpenFilesTool.js.map +1 -0
  457. package/dist/tools/GrepSearchTool.d.ts +7 -0
  458. package/dist/tools/GrepSearchTool.d.ts.map +1 -0
  459. package/dist/tools/GrepSearchTool.js +95 -0
  460. package/dist/tools/GrepSearchTool.js.map +1 -0
  461. package/dist/tools/ListDirTool.d.ts +6 -0
  462. package/dist/tools/ListDirTool.d.ts.map +1 -0
  463. package/dist/tools/ListDirTool.js +39 -0
  464. package/dist/tools/ListDirTool.js.map +1 -0
  465. package/dist/tools/MCPTools.d.ts +6 -0
  466. package/dist/tools/MCPTools.d.ts.map +1 -0
  467. package/dist/tools/MCPTools.js +103 -0
  468. package/dist/tools/MCPTools.js.map +1 -0
  469. package/dist/tools/MultiFileReplaceTool.d.ts +6 -0
  470. package/dist/tools/MultiFileReplaceTool.d.ts.map +1 -0
  471. package/dist/tools/MultiFileReplaceTool.js +345 -0
  472. package/dist/tools/MultiFileReplaceTool.js.map +1 -0
  473. package/dist/tools/ReadFileRangeTool.d.ts +6 -0
  474. package/dist/tools/ReadFileRangeTool.d.ts.map +1 -0
  475. package/dist/tools/ReadFileRangeTool.js +150 -0
  476. package/dist/tools/ReadFileRangeTool.js.map +1 -0
  477. package/dist/tools/ReadFileTool.d.ts +6 -0
  478. package/dist/tools/ReadFileTool.d.ts.map +1 -0
  479. package/dist/tools/ReadFileTool.js +183 -0
  480. package/dist/tools/ReadFileTool.js.map +1 -0
  481. package/dist/tools/ReadLintsTool.d.ts +6 -0
  482. package/dist/tools/ReadLintsTool.d.ts.map +1 -0
  483. package/dist/tools/ReadLintsTool.js +83 -0
  484. package/dist/tools/ReadLintsTool.js.map +1 -0
  485. package/dist/tools/ReadReferenceTool.d.ts +6 -0
  486. package/dist/tools/ReadReferenceTool.d.ts.map +1 -0
  487. package/dist/tools/ReadReferenceTool.js +24 -0
  488. package/dist/tools/ReadReferenceTool.js.map +1 -0
  489. package/dist/tools/ReadSymbolsTool.d.ts +3 -0
  490. package/dist/tools/ReadSymbolsTool.d.ts.map +1 -0
  491. package/dist/tools/ReadSymbolsTool.js +100 -0
  492. package/dist/tools/ReadSymbolsTool.js.map +1 -0
  493. package/dist/tools/SearchCodebaseTool.d.ts +6 -0
  494. package/dist/tools/SearchCodebaseTool.d.ts.map +1 -0
  495. package/dist/tools/SearchCodebaseTool.js +30 -0
  496. package/dist/tools/SearchCodebaseTool.js.map +1 -0
  497. package/dist/tools/SearchWorkspaceTool.d.ts +7 -0
  498. package/dist/tools/SearchWorkspaceTool.d.ts.map +1 -0
  499. package/dist/tools/SearchWorkspaceTool.js +21 -0
  500. package/dist/tools/SearchWorkspaceTool.js.map +1 -0
  501. package/dist/tools/SemanticSearchTool.d.ts +12 -0
  502. package/dist/tools/SemanticSearchTool.d.ts.map +1 -0
  503. package/dist/tools/SemanticSearchTool.js +46 -0
  504. package/dist/tools/SemanticSearchTool.js.map +1 -0
  505. package/dist/tools/SkillTools.d.ts +3 -0
  506. package/dist/tools/SkillTools.d.ts.map +1 -0
  507. package/dist/tools/SkillTools.js +108 -0
  508. package/dist/tools/SkillTools.js.map +1 -0
  509. package/dist/tools/SpawnWorkerTool.d.ts +6 -0
  510. package/dist/tools/SpawnWorkerTool.d.ts.map +1 -0
  511. package/dist/tools/SpawnWorkerTool.js +28 -0
  512. package/dist/tools/SpawnWorkerTool.js.map +1 -0
  513. package/dist/tools/SubmitArtifactTool.d.ts +3 -0
  514. package/dist/tools/SubmitArtifactTool.d.ts.map +1 -0
  515. package/dist/tools/SubmitArtifactTool.js +121 -0
  516. package/dist/tools/SubmitArtifactTool.js.map +1 -0
  517. package/dist/tools/UndoEditTool.d.ts +3 -0
  518. package/dist/tools/UndoEditTool.d.ts.map +1 -0
  519. package/dist/tools/UndoEditTool.js +66 -0
  520. package/dist/tools/UndoEditTool.js.map +1 -0
  521. package/dist/tools/UpdateTodoTool.d.ts +6 -0
  522. package/dist/tools/UpdateTodoTool.d.ts.map +1 -0
  523. package/dist/tools/UpdateTodoTool.js +116 -0
  524. package/dist/tools/UpdateTodoTool.js.map +1 -0
  525. package/dist/tools/WebRetrievalTools.d.ts +4 -0
  526. package/dist/tools/WebRetrievalTools.d.ts.map +1 -0
  527. package/dist/tools/WebRetrievalTools.js +169 -0
  528. package/dist/tools/WebRetrievalTools.js.map +1 -0
  529. package/dist/tools/WriteFileTool.d.ts +6 -0
  530. package/dist/tools/WriteFileTool.d.ts.map +1 -0
  531. package/dist/tools/WriteFileTool.js +145 -0
  532. package/dist/tools/WriteFileTool.js.map +1 -0
  533. package/dist/tools/cleanSlateFileReadPolicy.d.ts +33 -0
  534. package/dist/tools/cleanSlateFileReadPolicy.d.ts.map +1 -0
  535. package/dist/tools/cleanSlateFileReadPolicy.js +84 -0
  536. package/dist/tools/cleanSlateFileReadPolicy.js.map +1 -0
  537. package/dist/tools/cleanSlateHostTypes.d.ts +100 -0
  538. package/dist/tools/cleanSlateHostTypes.d.ts.map +1 -0
  539. package/dist/tools/cleanSlateHostTypes.js +6 -0
  540. package/dist/tools/cleanSlateHostTypes.js.map +1 -0
  541. package/dist/tools/cleanSlatePlanArtifactPolicy.d.ts +47 -0
  542. package/dist/tools/cleanSlatePlanArtifactPolicy.d.ts.map +1 -0
  543. package/dist/tools/cleanSlatePlanArtifactPolicy.js +126 -0
  544. package/dist/tools/cleanSlatePlanArtifactPolicy.js.map +1 -0
  545. package/dist/tools/cleanSlateStaleDiagnosticPolicy.d.ts +3 -0
  546. package/dist/tools/cleanSlateStaleDiagnosticPolicy.d.ts.map +1 -0
  547. package/dist/tools/cleanSlateStaleDiagnosticPolicy.js +13 -0
  548. package/dist/tools/cleanSlateStaleDiagnosticPolicy.js.map +1 -0
  549. package/dist/tools/languageFeatureActivation.d.ts +13 -0
  550. package/dist/tools/languageFeatureActivation.d.ts.map +1 -0
  551. package/dist/tools/languageFeatureActivation.js +95 -0
  552. package/dist/tools/languageFeatureActivation.js.map +1 -0
  553. package/dist/tools/registry.d.ts +5 -0
  554. package/dist/tools/registry.d.ts.map +1 -0
  555. package/dist/tools/registry.js +104 -0
  556. package/dist/tools/registry.js.map +1 -0
  557. package/dist/tools/structuredEditCanonicalizer.d.ts +11 -0
  558. package/dist/tools/structuredEditCanonicalizer.d.ts.map +1 -0
  559. package/dist/tools/structuredEditCanonicalizer.js +44 -0
  560. package/dist/tools/structuredEditCanonicalizer.js.map +1 -0
  561. package/dist/tools/symbolContext.d.ts +36 -0
  562. package/dist/tools/symbolContext.d.ts.map +1 -0
  563. package/dist/tools/symbolContext.js +146 -0
  564. package/dist/tools/symbolContext.js.map +1 -0
  565. package/dist/tools/symbolEditResolver.d.ts +11 -0
  566. package/dist/tools/symbolEditResolver.d.ts.map +1 -0
  567. package/dist/tools/symbolEditResolver.js +259 -0
  568. package/dist/tools/symbolEditResolver.js.map +1 -0
  569. package/dist/tools/symbolIndex.d.ts +18 -0
  570. package/dist/tools/symbolIndex.d.ts.map +1 -0
  571. package/dist/tools/symbolIndex.js +235 -0
  572. package/dist/tools/symbolIndex.js.map +1 -0
  573. package/dist/tools/types.d.ts +108 -0
  574. package/dist/tools/types.d.ts.map +1 -0
  575. package/dist/tools/types.js +6 -0
  576. package/dist/tools/types.js.map +1 -0
  577. package/dist/tools/utils.d.ts +56 -0
  578. package/dist/tools/utils.d.ts.map +1 -0
  579. package/dist/tools/utils.js +205 -0
  580. package/dist/tools/utils.js.map +1 -0
  581. package/package.json +71 -0
@@ -0,0 +1,848 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) CleanSlate. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { Range } from '../core/range.js';
6
+ import { CleanSlateDiffService } from './cleanSlateDiffService.js';
7
+ import { MarkerSeverity } from '../host/diagnostics.js';
8
+ import { CleanSlateEditMatchValidator } from './cleanSlateEditMatchValidator.js';
9
+ export class CleanSlateEditService {
10
+ static { this.MIN_CONTEXTUAL_EXACT_LINES = 5; }
11
+ static { this.MARKER_VALIDATION_TIMEOUT_MS = 1200; }
12
+ /**
13
+ * Collapses typographic quotes to their ASCII equivalents so text written by
14
+ * a model (which emits straight quotes) can be compared against file content
15
+ * that may use curly ones.
16
+ */
17
+ static normalizeQuotes(str) {
18
+ return str.replace(/[‘’]/g, '\'').replace(/[“”]/g, '"');
19
+ }
20
+ /**
21
+ * Typographic quotes come in directional pairs, so a straight quote can only
22
+ * be restored once we know whether it opened or closed a span. Rather than
23
+ * inspect each character's neighbours, walk the text once per quote kind and
24
+ * alternate: the first occurrence opens, the next closes, and so on. An
25
+ * apostrophe inside a word (`don't`) is never a span boundary, so it is
26
+ * always the closing form and does not flip the alternation.
27
+ */
28
+ static { this.CURLY_BY_KIND = {
29
+ '"': { open: '“', close: '”' },
30
+ '\'': { open: '‘', close: '’' }
31
+ }; }
32
+ static restoreCurlyQuotes(text, kind) {
33
+ const { open, close } = CleanSlateEditService.CURLY_BY_KIND[kind];
34
+ const isWordChar = (char) => char !== undefined && /[\p{L}\p{N}]/u.test(char);
35
+ let out = '';
36
+ let expectingOpen = true;
37
+ for (let i = 0; i < text.length; i++) {
38
+ const char = text[i];
39
+ if (char !== kind) {
40
+ out += char;
41
+ continue;
42
+ }
43
+ // Word-internal apostrophe: a contraction, not a quoted span.
44
+ if (kind === '\'' && isWordChar(text[i - 1]) && isWordChar(text[i + 1])) {
45
+ out += close;
46
+ continue;
47
+ }
48
+ out += expectingOpen ? open : close;
49
+ expectingOpen = !expectingOpen;
50
+ }
51
+ return out;
52
+ }
53
+ /**
54
+ * The model writes straight quotes even when the file uses typographic ones.
55
+ * When matching had to normalize the file text to find the target, the
56
+ * replacement must be converted back so the edit does not silently rewrite
57
+ * the file's punctuation.
58
+ */
59
+ static preserveQuoteStyle(oldString, actualOldString, newString) {
60
+ if (oldString === actualOldString) {
61
+ return newString;
62
+ }
63
+ let result = newString;
64
+ for (const kind of ['"', '\'']) {
65
+ const { open, close } = CleanSlateEditService.CURLY_BY_KIND[kind];
66
+ if (actualOldString.includes(open) || actualOldString.includes(close)) {
67
+ result = CleanSlateEditService.restoreCurlyQuotes(result, kind);
68
+ }
69
+ }
70
+ return result;
71
+ }
72
+ static planEdits(model, request) {
73
+ const normalizedRequest = request;
74
+ if (normalizedRequest.expectedVersionId !== undefined && normalizedRequest.expectedVersionId !== model.getVersionId()) {
75
+ return this.failure([
76
+ this.createDiagnostic('file_changed', `The file changed since the edit was prepared. Expected version ${normalizedRequest.expectedVersionId}, but the current version is ${model.getVersionId()}. Re-read the file and retry.`)
77
+ ]);
78
+ }
79
+ if (Array.isArray(normalizedRequest.edits) && normalizedRequest.edits.length > 0) {
80
+ return this.planStructuredEdits(model, normalizedRequest.edits, typeof normalizedRequest.expectedVersionId === 'number');
81
+ }
82
+ return this.failure([
83
+ this.createDiagnostic('invalid_input', 'apply_edit requires a non-empty structured "edits" array.')
84
+ ]);
85
+ }
86
+ static async validatePlannedEditsAsync(model, plannedEdits, treeSitterLibraryService) {
87
+ const structuralDiagnostic = this.findStructuralIntegrityDiagnostic(model, plannedEdits);
88
+ if (structuralDiagnostic) {
89
+ return structuralDiagnostic;
90
+ }
91
+ if (!treeSitterLibraryService || plannedEdits.length === 0 || !this.isCodeLikeResource(model.uri)) {
92
+ return undefined;
93
+ }
94
+ const previewContent = this.computePreviewContent(model, plannedEdits);
95
+ return this.findTreeSitterStructuralDiagnostic(model, previewContent, treeSitterLibraryService);
96
+ }
97
+ static computeEdits(model, request) {
98
+ const plan = this.planEdits(model, request);
99
+ if (!plan.ok) {
100
+ throw new Error(this.formatFailure(plan));
101
+ }
102
+ return plan.edits.map(edit => ({ range: edit.range, text: edit.text }));
103
+ }
104
+ static formatFailure(result) {
105
+ if (result.ok) {
106
+ return result.summary;
107
+ }
108
+ const detail = result.diagnostics
109
+ .map((diagnostic, index) => {
110
+ const hintLine = diagnostic.fallbackHint ? `\n Hint: ${diagnostic.fallbackHint}` : '';
111
+ return `${index + 1}. [${diagnostic.code}] ${diagnostic.message}${hintLine}`;
112
+ })
113
+ .join('\n');
114
+ return detail ? `${result.summary}\n${detail}` : result.summary;
115
+ }
116
+ static buildRecoveryHint(diagnostic, model) {
117
+ switch (diagnostic?.code) {
118
+ case 'no_match': {
119
+ const isLargeFile = model && model.getLineCount() > 1000;
120
+ return isLargeFile
121
+ ? 'The target was not found in the current large file. Re-read the relevant current text, then retry with an exact old_string copied from that result.'
122
+ : 'Re-read the relevant current text and retry with an exact old_string copied from that result.';
123
+ }
124
+ case 'ambiguous_match':
125
+ return 'Found multiple matches for old_string. Add only enough current surrounding text to make old_string unique, or set replace_all when every occurrence should change.';
126
+ case 'file_changed':
127
+ return 'The file changed outside this edit operation. Re-read its current text and retry with a current old_string.';
128
+ case 'no_op':
129
+ return 'The requested replacement already matches the file. Skip it or verify the target.';
130
+ case 'overlapping_edits':
131
+ return 'Split the overlapping edits into smaller non-overlapping operations and retry.';
132
+ case 'unsafe_large_deletion':
133
+ return 'Use smaller targeted replacements instead of one large deletion, then retry.';
134
+ case 'structural_validation_failed':
135
+ return 'The edit would corrupt delimiter structure. Re-read the surrounding code and retry with a balanced replacement.';
136
+ case 'symbol_snippet_not_found':
137
+ return 'The legacy target was not found. Re-read the relevant current text and retry through apply_edit with an exact old_string.';
138
+ case 'structural_target_required':
139
+ return 'Retry through apply_edit with an exact current old_string that uniquely identifies the intended declaration.';
140
+ case 'low_confidence_match':
141
+ return 'The target was not safe enough to edit. Re-read the relevant current text and retry with a longer unique old_string.';
142
+ default:
143
+ return 'Inspect the diagnostics, re-read the file only if the current text is unknown, and retry with a precise old_string.';
144
+ }
145
+ }
146
+ static planStructuredEdits(model, edits, hasVersionGuard) {
147
+ const plannedEdits = [];
148
+ const diagnostics = [];
149
+ const fileContents = model.getValue();
150
+ for (let idx = 0; idx < edits.length; idx++) {
151
+ const edit = edits[idx];
152
+ switch (edit.mode) {
153
+ case 'replace_exact': {
154
+ if (typeof edit.originalText !== 'string' || typeof edit.replacementText !== 'string') {
155
+ diagnostics.push(this.createDiagnostic('invalid_input', 'Structured edit mode "replace_exact" requires both "originalText" and "replacementText".', idx, 'exact'));
156
+ continue;
157
+ }
158
+ const resolution = this.resolveUniqueMatch(model, fileContents, edit.originalText, idx, 'replace_exact', {
159
+ contextBefore: edit.contextBefore,
160
+ contextAfter: edit.contextAfter,
161
+ allowFlexibleFallback: false,
162
+ minimumConfidence: this.getMinimumConfidenceForExact(model, edit)
163
+ });
164
+ if (!resolution.ok) {
165
+ diagnostics.push(resolution.diagnostic);
166
+ continue;
167
+ }
168
+ this.logEditDecision(`replace_exact accepted via ${resolution.match.strategy}; matches=${resolution.match.matchCount}; confidence=${resolution.match.confidence.toFixed(2)}.`);
169
+ plannedEdits.push({
170
+ range: resolution.match.range,
171
+ text: this.preserveQuoteStyle(edit.originalText, resolution.match.matchedText, edit.replacementText),
172
+ blockIndex: idx,
173
+ originalTextSnippet: this.clipSnippet(edit.originalText.trim()),
174
+ strategy: resolution.match.strategy,
175
+ sourceMode: 'replace_exact',
176
+ confidence: resolution.match.confidence,
177
+ matchCount: resolution.match.matchCount
178
+ });
179
+ continue;
180
+ }
181
+ case 'replace_range': {
182
+ const range = this.createRangeFromStructuredEdit(model, edit, idx);
183
+ if (!range.ok) {
184
+ diagnostics.push(range.diagnostic);
185
+ continue;
186
+ }
187
+ const replacementText = edit.replacementText ?? '';
188
+ let plannedRange = range.range;
189
+ let originalTextSnippet = this.clipSnippet(model.getValueInRange(plannedRange));
190
+ let strategy = 'replace_range';
191
+ let confidence = this.scoreRangeConfidence(model, edit, plannedRange, hasVersionGuard);
192
+ if (this.requiresOriginalTextForRange(model, edit, plannedRange, hasVersionGuard)) {
193
+ diagnostics.push(this.createDiagnostic('range_requires_original_text', 'Large multi-line replace_range edits require originalText, expectedVersionId, or structuralOrigin to prevent stale-coordinate edits.', idx, 'replace_range', this.clipSnippet(model.getValueInRange(plannedRange)), undefined, confidence, 'fallback_orchestration: re-read the range, attach originalText, or use replace_symbol.'));
194
+ this.logEditDecision('replace_range rejected: missing drift guard for large multi-line edit.');
195
+ continue;
196
+ }
197
+ if (typeof edit.originalText === 'string') {
198
+ const currentText = model.getValueInRange(plannedRange);
199
+ if (this.normalizeLineEndings(currentText) !== this.normalizeLineEndings(edit.originalText)) {
200
+ const resyncedMatch = this.resolveUniqueMatch(model, fileContents, edit.originalText, idx, 'replace_range', {
201
+ contextBefore: edit.contextBefore,
202
+ contextAfter: edit.contextAfter,
203
+ // Tolerate whitespace/indentation/trailing-punctuation drift, the most common cause
204
+ // of a replace_range no_match. Still uniqueness- and confidence-guarded below.
205
+ allowFlexibleFallback: true,
206
+ minimumConfidence: 0.78,
207
+ preferredRange: plannedRange,
208
+ preferredRangeToleranceLines: Math.max(6, plannedRange.endLineNumber - plannedRange.startLineNumber + 5)
209
+ });
210
+ if (!resyncedMatch.ok || (resyncedMatch.match.strategy !== 'exact' && resyncedMatch.match.strategy !== 'normalized_quotes' && resyncedMatch.match.strategy !== 'flexible_lines')) {
211
+ diagnostics.push(!resyncedMatch.ok
212
+ ? {
213
+ ...resyncedMatch.diagnostic,
214
+ message: `The provided range no longer matches the expected original text. ${resyncedMatch.diagnostic.message}`
215
+ }
216
+ : this.createDiagnostic('file_changed', `The provided range no longer matches the expected original text, and the original text could not be re-synced by an exact match. Re-read the current range and retry.`, idx, 'replace_range', this.clipSnippet(edit.originalText)));
217
+ continue;
218
+ }
219
+ plannedRange = resyncedMatch.match.range;
220
+ originalTextSnippet = this.clipSnippet(resyncedMatch.match.matchedText);
221
+ strategy = 'resynced_range';
222
+ confidence = resyncedMatch.match.confidence;
223
+ this.logEditDecision(`replace_range resynced via ${resyncedMatch.match.strategy}; matches=${resyncedMatch.match.matchCount}; confidence=${resyncedMatch.match.confidence.toFixed(2)}.`);
224
+ }
225
+ }
226
+ this.logEditDecision(`replace_range accepted; confidence=${confidence.toFixed(2)}; structuralOrigin=${edit.structuralOrigin ?? 'none'}.`);
227
+ plannedEdits.push({
228
+ range: plannedRange,
229
+ text: typeof edit.originalText === 'string' ? this.preserveQuoteStyle(edit.originalText, model.getValueInRange(plannedRange), replacementText) : replacementText,
230
+ blockIndex: idx,
231
+ originalTextSnippet,
232
+ strategy,
233
+ sourceMode: 'replace_range',
234
+ confidence,
235
+ matchCount: 1
236
+ });
237
+ continue;
238
+ }
239
+ case 'full_file': {
240
+ const newContent = edit.content ?? edit.replacementText;
241
+ if (typeof newContent !== 'string') {
242
+ diagnostics.push(this.createDiagnostic('invalid_input', 'Structured edit mode "full_file" requires "content" or "replacementText".', idx, 'full_file'));
243
+ continue;
244
+ }
245
+ const diffPlan = this.planFullFileReplacement(model, newContent, idx);
246
+ if (!diffPlan.ok) {
247
+ diagnostics.push(diffPlan.diagnostic);
248
+ continue;
249
+ }
250
+ plannedEdits.push(...diffPlan.edits);
251
+ this.logEditDecision(`full_file reduced to ${diffPlan.edits.length} minimal diff block(s).`);
252
+ continue;
253
+ }
254
+ case 'replace_symbol': {
255
+ // This should normally be handled by symbolEditResolver.ts,
256
+ // but we add it here for robustness if the resolver is bypassed.
257
+ diagnostics.push(this.createDiagnostic('invalid_input', 'Structured edit mode "replace_symbol" requires pre-resolution by a symbol provider. Re-read the symbols and retry.', idx, undefined, edit.symbolName));
258
+ continue;
259
+ }
260
+ default: {
261
+ diagnostics.push(this.createDiagnostic('invalid_input', `Unsupported structured edit mode "${edit.mode}".`, idx));
262
+ continue;
263
+ }
264
+ }
265
+ }
266
+ return this.finalizePlan(model, plannedEdits, diagnostics);
267
+ }
268
+ static finalizePlan(model, plannedEdits, diagnostics) {
269
+ const overlapDiagnostic = this.findOverlapDiagnostic(model, plannedEdits);
270
+ if (overlapDiagnostic) {
271
+ diagnostics.push(overlapDiagnostic);
272
+ }
273
+ if (diagnostics.length > 0) {
274
+ return this.failure(diagnostics);
275
+ }
276
+ const finalEdits = plannedEdits.filter(edit => model.getValueInRange(edit.range) !== edit.text);
277
+ if (finalEdits.length === 0) {
278
+ return this.success([], 'NO_OP: The requested edits already match the file content.');
279
+ }
280
+ return this.success(finalEdits, `Prepared ${finalEdits.length} edit${finalEdits.length === 1 ? '' : 's'} safely.`);
281
+ }
282
+ static success(edits, summary) {
283
+ return {
284
+ ok: true,
285
+ inputKind: 'structured',
286
+ summary,
287
+ edits,
288
+ diagnostics: [],
289
+ warnings: []
290
+ };
291
+ }
292
+ static failure(diagnostics) {
293
+ const primary = diagnostics[0];
294
+ const summary = primary
295
+ ? `Edit planning failed with ${diagnostics.length} issue${diagnostics.length === 1 ? '' : 's'}.`
296
+ : 'Edit planning failed.';
297
+ return {
298
+ ok: false,
299
+ inputKind: 'structured',
300
+ summary,
301
+ edits: [],
302
+ diagnostics,
303
+ warnings: []
304
+ };
305
+ }
306
+ static createDiagnostic(code, message, blockIndex, strategy, snippet, matchCount, confidence, fallbackHint, extra) {
307
+ return { code, message, blockIndex, strategy, snippet, matchCount, confidence, fallbackHint, ...extra };
308
+ }
309
+ static resolveUniqueMatch(model, fileContents, searchText, blockIndex, strategyHint, options = {}) {
310
+ const validation = CleanSlateEditMatchValidator.validateUniqueTextMatch(model, fileContents, searchText, {
311
+ modeLabel: strategyHint,
312
+ contextBefore: options.contextBefore,
313
+ contextAfter: options.contextAfter,
314
+ allowFlexibleFallback: options.allowFlexibleFallback,
315
+ minimumConfidence: options.minimumConfidence,
316
+ preferredRange: options.preferredRange,
317
+ preferredRangeToleranceLines: options.preferredRangeToleranceLines,
318
+ logger: message => this.logEditDecision(message)
319
+ });
320
+ if (validation.ok) {
321
+ return {
322
+ ok: true,
323
+ match: validation.match
324
+ };
325
+ }
326
+ const preferredRecoveryMode = this.inferPreferredRecoveryMode(model, searchText, strategyHint);
327
+ return {
328
+ ok: false,
329
+ diagnostic: this.createDiagnostic(validation.failure.code, validation.failure.message, blockIndex, validation.failure.strategy, validation.failure.snippet, validation.failure.matchCount, validation.failure.confidence, this.buildFailureFallbackHint(preferredRecoveryMode), {
330
+ allMatches: validation.failure.allMatches,
331
+ preferredRecoveryMode
332
+ })
333
+ };
334
+ }
335
+ static inferPreferredRecoveryMode(model, searchText, strategyHint) {
336
+ if (!this.isCodeLikeResource(model.uri)) {
337
+ return 'replace_exact';
338
+ }
339
+ if (strategyHint === 'replace_range') {
340
+ return 'replace_range';
341
+ }
342
+ return 'replace_exact';
343
+ }
344
+ static buildFailureFallbackHint(preferredRecoveryMode) {
345
+ return 'Recovery path: use a larger current old_string that uniquely identifies the intended occurrence, or set replace_all when every occurrence should change.';
346
+ }
347
+ static getMinimumConfidenceForExact(model, edit) {
348
+ if (!this.isCodeLikeResource(model.uri)) {
349
+ return 0.7;
350
+ }
351
+ if (model.getLineCount() >= 5000) {
352
+ return this.countNonEmptyLines(edit.originalText ?? '') >= this.MIN_CONTEXTUAL_EXACT_LINES || edit.contextBefore || edit.contextAfter
353
+ ? 0.82
354
+ : 0.92;
355
+ }
356
+ return 0.72;
357
+ }
358
+ static requiresOriginalTextForRange(model, edit, range, hasVersionGuard) {
359
+ if (!this.isCodeLikeResource(model.uri) || model.getLineCount() < 500) {
360
+ return false;
361
+ }
362
+ if (hasVersionGuard || edit.structuralOrigin || typeof edit.originalText === 'string') {
363
+ return false;
364
+ }
365
+ return range.endLineNumber > range.startLineNumber;
366
+ }
367
+ static scoreRangeConfidence(model, edit, range, hasVersionGuard) {
368
+ let confidence = 0.78;
369
+ if (hasVersionGuard) {
370
+ confidence += 0.08;
371
+ }
372
+ if (edit.structuralOrigin === 'symbol') {
373
+ confidence += 0.12;
374
+ }
375
+ else if (edit.structuralOrigin === 'tree_sitter_declaration') {
376
+ confidence += 0.1;
377
+ }
378
+ if (typeof edit.originalText === 'string') {
379
+ confidence += 0.08;
380
+ }
381
+ if (range.startColumn === 1 && range.endColumn === model.getLineMaxColumn(range.endLineNumber)) {
382
+ confidence += 0.02;
383
+ }
384
+ return Math.max(0, Math.min(1, Number(confidence.toFixed(2))));
385
+ }
386
+ static countNonEmptyLines(text) {
387
+ return text.replace(/\r\n/g, '\n')
388
+ .split('\n')
389
+ .filter(line => line.trim().length > 0)
390
+ .length;
391
+ }
392
+ static logEditDecision(message) {
393
+ console.info(`[CleanSlateEdit] ${message}`);
394
+ }
395
+ static createRangeFromStructuredEdit(model, edit, blockIndex) {
396
+ const { startLine, endLine } = edit;
397
+ if (startLine === undefined || endLine === undefined) {
398
+ return {
399
+ ok: false,
400
+ diagnostic: this.createDiagnostic('invalid_input', 'Structured edit mode "replace_range" requires "startLine" and "endLine".', blockIndex, 'replace_range')
401
+ };
402
+ }
403
+ const lineCount = model.getLineCount();
404
+ if (startLine < 1 || endLine < startLine || endLine > lineCount) {
405
+ return {
406
+ ok: false,
407
+ diagnostic: this.createDiagnostic('invalid_input', `The requested range ${startLine}:${edit.startColumn ?? 1}-${endLine}:${edit.endColumn ?? model.getLineMaxColumn(endLine)} is outside the current file.`, blockIndex, 'replace_range')
408
+ };
409
+ }
410
+ const startColumn = edit.startColumn ?? 1;
411
+ const endColumn = edit.endColumn ?? model.getLineMaxColumn(endLine);
412
+ return {
413
+ ok: true,
414
+ range: new Range(startLine, startColumn, endLine, endColumn)
415
+ };
416
+ }
417
+ static planFullFileReplacement(model, newContent, blockIndex) {
418
+ try {
419
+ const changes = this.computeSmartDiff(model, newContent);
420
+ return {
421
+ ok: true,
422
+ edits: changes.map(change => ({
423
+ range: change.range,
424
+ text: change.text,
425
+ blockIndex,
426
+ originalTextSnippet: '',
427
+ strategy: 'full_file'
428
+ }))
429
+ };
430
+ }
431
+ catch (error) {
432
+ const message = String(error);
433
+ const code = message.includes('Safety Block')
434
+ ? 'unsafe_large_deletion'
435
+ : 'invalid_input';
436
+ return {
437
+ ok: false,
438
+ diagnostic: this.createDiagnostic(code, message, blockIndex, 'full_file')
439
+ };
440
+ }
441
+ }
442
+ static findOverlapDiagnostic(model, plannedEdits) {
443
+ const sortedEdits = [...plannedEdits].sort((a, b) => {
444
+ const lineDelta = a.range.startLineNumber - b.range.startLineNumber;
445
+ if (lineDelta !== 0) {
446
+ return lineDelta;
447
+ }
448
+ return a.range.startColumn - b.range.startColumn;
449
+ });
450
+ for (let i = 0; i < sortedEdits.length - 1; i++) {
451
+ const current = sortedEdits[i];
452
+ const next = sortedEdits[i + 1];
453
+ const currentEnd = model.getOffsetAt({
454
+ lineNumber: current.range.endLineNumber,
455
+ column: current.range.endColumn
456
+ });
457
+ const nextStart = model.getOffsetAt({
458
+ lineNumber: next.range.startLineNumber,
459
+ column: next.range.startColumn
460
+ });
461
+ if (nextStart <= currentEnd) {
462
+ return this.createDiagnostic('overlapping_edits', `Two edits target overlapping regions near line ${current.range.endLineNumber}. Split them into a single edit or use non-overlapping ranges.`, undefined, current.strategy);
463
+ }
464
+ }
465
+ return undefined;
466
+ }
467
+ static findStructuralIntegrityDiagnostic(model, plannedEdits) {
468
+ if (!this.shouldValidateStructuralIntegrity(model, plannedEdits)) {
469
+ return undefined;
470
+ }
471
+ const beforeScan = this.scanDelimiterIntegrity(model.getValue());
472
+ if (beforeScan.ok) {
473
+ const previewContent = this.computePreviewContent(model, plannedEdits);
474
+ const afterScan = this.scanDelimiterIntegrity(previewContent);
475
+ if (!afterScan.ok) {
476
+ return this.createDiagnostic('structural_validation_failed', `The planned edit would leave the file structurally unbalanced: ${afterScan.message}`, undefined, plannedEdits[0]?.strategy);
477
+ }
478
+ }
479
+ return undefined;
480
+ }
481
+ static async findTreeSitterStructuralDiagnostic(model, previewContent, treeSitterLibraryService) {
482
+ if (!this.isCodeLikeResource(model.uri)) {
483
+ return undefined;
484
+ }
485
+ const languageId = model.getLanguageId();
486
+ if (!languageId) {
487
+ return undefined;
488
+ }
489
+ let parser;
490
+ let beforeTree;
491
+ let afterTree;
492
+ try {
493
+ const [ParserCtor, language] = await Promise.all([
494
+ treeSitterLibraryService.getParserClass(),
495
+ treeSitterLibraryService.getLanguagePromise(languageId)
496
+ ]);
497
+ if (!language) {
498
+ return undefined;
499
+ }
500
+ parser = new ParserCtor();
501
+ parser.setLanguage(language);
502
+ beforeTree = parser.parse(model.getValue());
503
+ afterTree = parser.parse(previewContent);
504
+ if (!beforeTree || !afterTree) {
505
+ return undefined;
506
+ }
507
+ const beforeSummary = this.collectTreeSitterSyntaxErrorSummary(beforeTree);
508
+ const afterSummary = this.collectTreeSitterSyntaxErrorSummary(afterTree);
509
+ const introducedErrors = afterSummary.errorNodeCount - beforeSummary.errorNodeCount;
510
+ if (!afterSummary.hasErrors) {
511
+ return undefined;
512
+ }
513
+ if (!beforeSummary.hasErrors || introducedErrors > 0) {
514
+ const location = afterSummary.firstErrorLine !== undefined && afterSummary.firstErrorColumn !== undefined
515
+ ? ` near ${afterSummary.firstErrorLine}:${afterSummary.firstErrorColumn}`
516
+ : '';
517
+ const errorType = afterSummary.firstErrorType ? ` (${afterSummary.firstErrorType})` : '';
518
+ const issueCount = Math.max(1, introducedErrors > 0 ? introducedErrors : afterSummary.errorNodeCount);
519
+ return this.createDiagnostic('structural_validation_failed', `Tree-sitter preview detected ${issueCount} new syntax error node${issueCount === 1 ? '' : 's'}${location}${errorType}. Re-read the surrounding symbol and retry with a smaller, syntax-preserving edit.`);
520
+ }
521
+ }
522
+ catch {
523
+ return undefined;
524
+ }
525
+ finally {
526
+ afterTree?.delete();
527
+ beforeTree?.delete();
528
+ parser?.delete();
529
+ }
530
+ return undefined;
531
+ }
532
+ static shouldValidateStructuralIntegrity(model, plannedEdits) {
533
+ if (!this.isCodeLikeResource(model.uri)) {
534
+ return false;
535
+ }
536
+ return plannedEdits.some(edit => {
537
+ const originalText = model.getValueInRange(edit.range);
538
+ return this.containsStructuralSyntax(originalText) || this.containsStructuralSyntax(edit.text);
539
+ });
540
+ }
541
+ static computePreviewContent(model, plannedEdits) {
542
+ let content = model.getValue();
543
+ const editsByDescendingOffset = [...plannedEdits].sort((a, b) => {
544
+ const aStart = model.getOffsetAt({ lineNumber: a.range.startLineNumber, column: a.range.startColumn });
545
+ const bStart = model.getOffsetAt({ lineNumber: b.range.startLineNumber, column: b.range.startColumn });
546
+ return bStart - aStart;
547
+ });
548
+ for (const edit of editsByDescendingOffset) {
549
+ const startOffset = model.getOffsetAt({ lineNumber: edit.range.startLineNumber, column: edit.range.startColumn });
550
+ const endOffset = model.getOffsetAt({ lineNumber: edit.range.endLineNumber, column: edit.range.endColumn });
551
+ content = `${content.slice(0, startOffset)}${edit.text}${content.slice(endOffset)}`;
552
+ }
553
+ return content;
554
+ }
555
+ static collectTreeSitterSyntaxErrorSummary(tree) {
556
+ if (!tree.rootNode.hasError) {
557
+ return {
558
+ hasErrors: false,
559
+ errorNodeCount: 0
560
+ };
561
+ }
562
+ let errorNodeCount = 0;
563
+ let firstErrorType;
564
+ let firstErrorLine;
565
+ let firstErrorColumn;
566
+ const stack = [tree.rootNode];
567
+ while (stack.length > 0) {
568
+ const currentNode = stack.pop();
569
+ if (currentNode.type === 'ERROR') {
570
+ errorNodeCount++;
571
+ if (firstErrorType === undefined) {
572
+ firstErrorType = currentNode.type;
573
+ firstErrorLine = currentNode.startPosition.row + 1;
574
+ firstErrorColumn = currentNode.startPosition.column + 1;
575
+ }
576
+ }
577
+ for (let childIndex = currentNode.children.length - 1; childIndex >= 0; childIndex--) {
578
+ const childNode = currentNode.children[childIndex];
579
+ if (childNode) {
580
+ stack.push(childNode);
581
+ }
582
+ }
583
+ }
584
+ if (errorNodeCount === 0) {
585
+ return {
586
+ hasErrors: true,
587
+ errorNodeCount: 1,
588
+ firstErrorType: tree.rootNode.type,
589
+ firstErrorLine: tree.rootNode.startPosition.row + 1,
590
+ firstErrorColumn: tree.rootNode.startPosition.column + 1
591
+ };
592
+ }
593
+ return {
594
+ hasErrors: true,
595
+ errorNodeCount,
596
+ firstErrorType,
597
+ firstErrorLine,
598
+ firstErrorColumn
599
+ };
600
+ }
601
+ static scanDelimiterIntegrity(content) {
602
+ const openerByCloser = new Map([
603
+ [')', '('],
604
+ [']', '['],
605
+ ['}', '{']
606
+ ]);
607
+ const closerByOpener = new Map([
608
+ ['(', ')'],
609
+ ['[', ']'],
610
+ ['{', '}']
611
+ ]);
612
+ const stack = [];
613
+ let line = 1;
614
+ let column = 1;
615
+ let state = 'code';
616
+ let escaped = false;
617
+ for (let i = 0; i < content.length; i++) {
618
+ const char = content[i];
619
+ const next = content[i + 1];
620
+ if (state === 'lineComment') {
621
+ if (char === '\n') {
622
+ state = 'code';
623
+ }
624
+ ({ line, column } = this.advanceTextPosition(char, line, column));
625
+ continue;
626
+ }
627
+ if (state === 'blockComment') {
628
+ if (char === '*' && next === '/') {
629
+ i++;
630
+ column += 2;
631
+ state = 'code';
632
+ continue;
633
+ }
634
+ ({ line, column } = this.advanceTextPosition(char, line, column));
635
+ continue;
636
+ }
637
+ if (state === 'singleQuote' || state === 'doubleQuote' || state === 'backtick') {
638
+ const closingChar = state === 'singleQuote' ? '\'' : state === 'doubleQuote' ? '"' : '`';
639
+ if (escaped) {
640
+ escaped = false;
641
+ }
642
+ else if (char === '\\') {
643
+ escaped = true;
644
+ }
645
+ else if (char === closingChar) {
646
+ state = 'code';
647
+ }
648
+ ({ line, column } = this.advanceTextPosition(char, line, column));
649
+ continue;
650
+ }
651
+ if (char === '/' && next === '/') {
652
+ i++;
653
+ column += 2;
654
+ state = 'lineComment';
655
+ continue;
656
+ }
657
+ if (char === '/' && next === '*') {
658
+ i++;
659
+ column += 2;
660
+ state = 'blockComment';
661
+ continue;
662
+ }
663
+ if (char === '\'') {
664
+ state = 'singleQuote';
665
+ ({ line, column } = this.advanceTextPosition(char, line, column));
666
+ continue;
667
+ }
668
+ if (char === '"') {
669
+ state = 'doubleQuote';
670
+ ({ line, column } = this.advanceTextPosition(char, line, column));
671
+ continue;
672
+ }
673
+ if (char === '`') {
674
+ state = 'backtick';
675
+ ({ line, column } = this.advanceTextPosition(char, line, column));
676
+ continue;
677
+ }
678
+ if (closerByOpener.has(char)) {
679
+ stack.push({ char, line, column });
680
+ }
681
+ else if (openerByCloser.has(char)) {
682
+ const expectedOpener = openerByCloser.get(char);
683
+ const actualOpener = stack.pop();
684
+ if (!actualOpener || actualOpener.char !== expectedOpener) {
685
+ return {
686
+ ok: false,
687
+ message: `unexpected "${char}" at ${line}:${column}`,
688
+ line,
689
+ column
690
+ };
691
+ }
692
+ }
693
+ ({ line, column } = this.advanceTextPosition(char, line, column));
694
+ }
695
+ const unclosed = stack.pop();
696
+ if (unclosed) {
697
+ return {
698
+ ok: false,
699
+ message: `unclosed "${unclosed.char}" from ${unclosed.line}:${unclosed.column}`,
700
+ line: unclosed.line,
701
+ column: unclosed.column
702
+ };
703
+ }
704
+ return { ok: true };
705
+ }
706
+ static advanceTextPosition(char, line, column) {
707
+ if (char === '\n') {
708
+ return { line: line + 1, column: 1 };
709
+ }
710
+ return { line, column: column + 1 };
711
+ }
712
+ static containsStructuralSyntax(text) {
713
+ return /[{}()[\]]/.test(text);
714
+ }
715
+ static isCodeLikeResource(uri) {
716
+ const normalizedPath = uri.path.toLowerCase();
717
+ return /\.(c|cc|cpp|cs|css|dart|go|h|hpp|java|js|jsx|kt|less|m|mm|php|rs|scss|swift|ts|tsx|vue)$/.test(normalizedPath);
718
+ }
719
+ static captureMarkerValidationBaseline(markerService, resource) {
720
+ const signatures = new Map();
721
+ for (const marker of markerService.read({ resource, severities: MarkerSeverity.Error })) {
722
+ const signature = this.markerValidationSignature(marker);
723
+ signatures.set(signature, (signatures.get(signature) ?? 0) + 1);
724
+ }
725
+ return { signatures };
726
+ }
727
+ static createMarkerRefreshWaiter(markerService, resource, timeoutMs = CleanSlateEditService.MARKER_VALIDATION_TIMEOUT_MS) {
728
+ let finished = false;
729
+ let resolveWait = () => { };
730
+ const waitPromise = new Promise(resolve => {
731
+ resolveWait = resolve;
732
+ });
733
+ let timeoutHandle;
734
+ let disposable = markerService.onMarkerChanged(resources => {
735
+ if (resources.some(changedResource => changedResource.toString() === resource.toString())) {
736
+ finish();
737
+ }
738
+ });
739
+ const finish = () => {
740
+ if (finished) {
741
+ return;
742
+ }
743
+ finished = true;
744
+ if (timeoutHandle !== undefined) {
745
+ clearTimeout(timeoutHandle);
746
+ timeoutHandle = undefined;
747
+ }
748
+ disposable.dispose();
749
+ resolveWait();
750
+ };
751
+ timeoutHandle = setTimeout(finish, timeoutMs);
752
+ return {
753
+ wait: () => waitPromise,
754
+ dispose: finish
755
+ };
756
+ }
757
+ static async validateMarkersAfterEdit(markerService, resource, baseline, waiter) {
758
+ if (waiter) {
759
+ await waiter.wait();
760
+ waiter.dispose();
761
+ }
762
+ const baselineRemaining = new Map(baseline.signatures);
763
+ const issues = [];
764
+ for (const marker of markerService.read({ resource, severities: MarkerSeverity.Error })) {
765
+ const signature = this.markerValidationSignature(marker);
766
+ const remainingCount = baselineRemaining.get(signature) ?? 0;
767
+ if (remainingCount > 0) {
768
+ baselineRemaining.set(signature, remainingCount - 1);
769
+ continue;
770
+ }
771
+ issues.push(this.toMarkerValidationIssue(marker));
772
+ }
773
+ return {
774
+ ok: issues.length === 0,
775
+ issues
776
+ };
777
+ }
778
+ static async rollbackModelToContent(model, expectedContent) {
779
+ try {
780
+ // Optional: a headless model has no undo stack, and the direct
781
+ // restoration below is the fallback either way.
782
+ await model.undo?.();
783
+ }
784
+ catch {
785
+ // Fall back to direct restoration below.
786
+ }
787
+ if (model.getValue() === expectedContent) {
788
+ return;
789
+ }
790
+ model.pushStackElement();
791
+ model.pushEditOperations(null, [{ range: model.getFullModelRange(), text: expectedContent }], () => null);
792
+ model.pushStackElement();
793
+ }
794
+ static markerValidationSignature(marker) {
795
+ const code = typeof marker.code === 'string' ? marker.code : marker.code?.value ?? '';
796
+ return [
797
+ marker.owner,
798
+ marker.source ?? '',
799
+ code,
800
+ marker.severity,
801
+ marker.message
802
+ ].join('\u241F');
803
+ }
804
+ static toMarkerValidationIssue(marker) {
805
+ const code = typeof marker.code === 'string' ? marker.code : marker.code?.value;
806
+ return {
807
+ resource: marker.resource.fsPath,
808
+ severity: MarkerSeverity.toString(marker.severity),
809
+ message: marker.message,
810
+ startLineNumber: marker.startLineNumber,
811
+ startColumn: marker.startColumn,
812
+ endLineNumber: marker.endLineNumber,
813
+ endColumn: marker.endColumn,
814
+ source: marker.source,
815
+ code
816
+ };
817
+ }
818
+ static clipSnippet(value, maxLength = 120) {
819
+ if (value.length <= maxLength) {
820
+ return value;
821
+ }
822
+ return `${value.slice(0, maxLength)}...`;
823
+ }
824
+ static normalizeLineEndings(str) {
825
+ return str.replace(/\r\n/g, '\n');
826
+ }
827
+ static computeSmartDiff(model, newContent) {
828
+ const currentContent = model.getValue();
829
+ const lineCount = model.getLineCount();
830
+ const newLines = newContent.split('\n').length;
831
+ const isNewContentSubstantial = newContent.length > (currentContent.length * 0.2) || newLines > 5;
832
+ const isFileManageable = lineCount < 500;
833
+ if (isNewContentSubstantial || isFileManageable) {
834
+ const changes = CleanSlateDiffService.computeDiff(currentContent, newContent);
835
+ const totalDeletedLines = changes.reduce((acc, edit) => {
836
+ return acc + (edit.range.endLineNumber - edit.range.startLineNumber + 1);
837
+ }, 0);
838
+ const isDeletingMajority = totalDeletedLines > (lineCount * 0.85);
839
+ const isShrinkingSignificantly = newContent.length < (currentContent.length * 0.2);
840
+ if (isDeletingMajority && isShrinkingSignificantly) {
841
+ throw new Error(`Safety Block: The proposed edit would delete ${Math.round((totalDeletedLines / lineCount) * 100)}% of the file (${totalDeletedLines}/${lineCount} lines deleted). This appears to be a truncated response.`);
842
+ }
843
+ return changes.map(change => ({ range: Range.lift(change.range), text: change.text ?? '' }));
844
+ }
845
+ throw new Error('AI returned whole-file content without a safe target. Re-read the file and retry apply_edit with an exact current old_string.');
846
+ }
847
+ }
848
+ //# sourceMappingURL=cleanSlateEditService.js.map