@smthrs/std 0.0.0-stage → 1.0.0-rc.3

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 (555) hide show
  1. package/CHANGELOG.md +130 -0
  2. package/LICENSE +21 -0
  3. package/README.md +152 -2
  4. package/dist/cjs/ApplyPatch.d.ts +174 -0
  5. package/dist/cjs/ApplyPatch.d.ts.map +1 -0
  6. package/dist/cjs/ApplyPatch.js +309 -0
  7. package/dist/cjs/ApplyPatch.js.map +7 -0
  8. package/dist/cjs/Bash.d.ts +304 -0
  9. package/dist/cjs/Bash.d.ts.map +1 -0
  10. package/dist/cjs/Bash.js +321 -0
  11. package/dist/cjs/Bash.js.map +7 -0
  12. package/dist/cjs/Checkpoints.d.ts +279 -0
  13. package/dist/cjs/Checkpoints.d.ts.map +1 -0
  14. package/dist/cjs/Checkpoints.js +145 -0
  15. package/dist/cjs/Checkpoints.js.map +7 -0
  16. package/dist/cjs/Container.d.ts +132 -0
  17. package/dist/cjs/Container.d.ts.map +1 -0
  18. package/dist/cjs/Container.js +113 -0
  19. package/dist/cjs/Container.js.map +7 -0
  20. package/dist/cjs/Edit.d.ts +203 -0
  21. package/dist/cjs/Edit.d.ts.map +1 -0
  22. package/dist/cjs/Edit.js +258 -0
  23. package/dist/cjs/Edit.js.map +7 -0
  24. package/dist/cjs/ExaWebSearch.d.ts +22 -0
  25. package/dist/cjs/ExaWebSearch.d.ts.map +1 -0
  26. package/dist/cjs/ExaWebSearch.js +138 -0
  27. package/dist/cjs/ExaWebSearch.js.map +7 -0
  28. package/dist/cjs/Explore.d.ts +328 -0
  29. package/dist/cjs/Explore.d.ts.map +1 -0
  30. package/dist/cjs/Explore.js +90 -0
  31. package/dist/cjs/Explore.js.map +7 -0
  32. package/dist/cjs/Fetch.d.ts +130 -0
  33. package/dist/cjs/Fetch.d.ts.map +1 -0
  34. package/dist/cjs/Fetch.js +64 -0
  35. package/dist/cjs/Fetch.js.map +7 -0
  36. package/dist/cjs/Glob.d.ts +204 -0
  37. package/dist/cjs/Glob.d.ts.map +1 -0
  38. package/dist/cjs/Glob.js +94 -0
  39. package/dist/cjs/Glob.js.map +7 -0
  40. package/dist/cjs/Grep.d.ts +347 -0
  41. package/dist/cjs/Grep.d.ts.map +1 -0
  42. package/dist/cjs/Grep.js +181 -0
  43. package/dist/cjs/Grep.js.map +7 -0
  44. package/dist/cjs/HttpPost.d.ts +130 -0
  45. package/dist/cjs/HttpPost.d.ts.map +1 -0
  46. package/dist/cjs/HttpPost.js +72 -0
  47. package/dist/cjs/HttpPost.js.map +7 -0
  48. package/dist/cjs/LanguageServer.d.ts +90 -0
  49. package/dist/cjs/LanguageServer.d.ts.map +1 -0
  50. package/dist/cjs/LanguageServer.js +60 -0
  51. package/dist/cjs/LanguageServer.js.map +7 -0
  52. package/dist/cjs/Ls.d.ts +164 -0
  53. package/dist/cjs/Ls.d.ts.map +1 -0
  54. package/dist/cjs/Ls.js +136 -0
  55. package/dist/cjs/Ls.js.map +7 -0
  56. package/dist/cjs/Lsp.d.ts +125 -0
  57. package/dist/cjs/Lsp.d.ts.map +1 -0
  58. package/dist/cjs/Lsp.js +137 -0
  59. package/dist/cjs/Lsp.js.map +7 -0
  60. package/dist/cjs/Manifest.d.ts +918 -0
  61. package/dist/cjs/Manifest.d.ts.map +1 -0
  62. package/dist/cjs/Manifest.js +144 -0
  63. package/dist/cjs/Manifest.js.map +7 -0
  64. package/dist/cjs/NativeSearch.d.ts +38 -0
  65. package/dist/cjs/NativeSearch.d.ts.map +1 -0
  66. package/dist/cjs/NativeSearch.js +326 -0
  67. package/dist/cjs/NativeSearch.js.map +7 -0
  68. package/dist/cjs/NodeLanguageServer.d.ts +128 -0
  69. package/dist/cjs/NodeLanguageServer.d.ts.map +1 -0
  70. package/dist/cjs/NodeLanguageServer.js +796 -0
  71. package/dist/cjs/NodeLanguageServer.js.map +7 -0
  72. package/dist/cjs/PortableSearch.d.ts +24 -0
  73. package/dist/cjs/PortableSearch.d.ts.map +1 -0
  74. package/dist/cjs/PortableSearch.js +233 -0
  75. package/dist/cjs/PortableSearch.js.map +7 -0
  76. package/dist/cjs/Probe.d.ts +193 -0
  77. package/dist/cjs/Probe.d.ts.map +1 -0
  78. package/dist/cjs/Probe.js +134 -0
  79. package/dist/cjs/Probe.js.map +7 -0
  80. package/dist/cjs/Read.d.ts +189 -0
  81. package/dist/cjs/Read.d.ts.map +1 -0
  82. package/dist/cjs/Read.js +223 -0
  83. package/dist/cjs/Read.js.map +7 -0
  84. package/dist/cjs/Relocate.d.ts +73 -0
  85. package/dist/cjs/Relocate.d.ts.map +1 -0
  86. package/dist/cjs/Relocate.js +72 -0
  87. package/dist/cjs/Relocate.js.map +7 -0
  88. package/dist/cjs/Search.d.ts +163 -0
  89. package/dist/cjs/Search.d.ts.map +1 -0
  90. package/dist/cjs/Search.js +51 -0
  91. package/dist/cjs/Search.js.map +7 -0
  92. package/dist/cjs/SearchConformance.d.ts +115 -0
  93. package/dist/cjs/SearchConformance.d.ts.map +1 -0
  94. package/dist/cjs/SearchConformance.js +172 -0
  95. package/dist/cjs/SearchConformance.js.map +7 -0
  96. package/dist/cjs/SearchContract.d.ts +114 -0
  97. package/dist/cjs/SearchContract.d.ts.map +1 -0
  98. package/dist/cjs/SearchContract.js +339 -0
  99. package/dist/cjs/SearchContract.js.map +7 -0
  100. package/dist/cjs/ShellCommand.d.ts +164 -0
  101. package/dist/cjs/ShellCommand.d.ts.map +1 -0
  102. package/dist/cjs/ShellCommand.js +102 -0
  103. package/dist/cjs/ShellCommand.js.map +7 -0
  104. package/dist/cjs/StdError.d.ts +55 -0
  105. package/dist/cjs/StdError.d.ts.map +1 -0
  106. package/dist/cjs/StdError.js +74 -0
  107. package/dist/cjs/StdError.js.map +7 -0
  108. package/dist/cjs/TestRun.d.ts +311 -0
  109. package/dist/cjs/TestRun.d.ts.map +1 -0
  110. package/dist/cjs/TestRun.js +228 -0
  111. package/dist/cjs/TestRun.js.map +7 -0
  112. package/dist/cjs/TestRunner.d.ts +102 -0
  113. package/dist/cjs/TestRunner.d.ts.map +1 -0
  114. package/dist/cjs/TestRunner.js +54 -0
  115. package/dist/cjs/TestRunner.js.map +7 -0
  116. package/dist/cjs/TreeFingerprint.d.ts +140 -0
  117. package/dist/cjs/TreeFingerprint.d.ts.map +1 -0
  118. package/dist/cjs/TreeFingerprint.js +87 -0
  119. package/dist/cjs/TreeFingerprint.js.map +7 -0
  120. package/dist/cjs/UpdatePlan.d.ts +152 -0
  121. package/dist/cjs/UpdatePlan.d.ts.map +1 -0
  122. package/dist/cjs/UpdatePlan.js +87 -0
  123. package/dist/cjs/UpdatePlan.js.map +7 -0
  124. package/dist/cjs/WebFetch.d.ts +134 -0
  125. package/dist/cjs/WebFetch.d.ts.map +1 -0
  126. package/dist/cjs/WebFetch.js +140 -0
  127. package/dist/cjs/WebFetch.js.map +7 -0
  128. package/dist/cjs/WebSearch.d.ts +181 -0
  129. package/dist/cjs/WebSearch.d.ts.map +1 -0
  130. package/dist/cjs/WebSearch.js +86 -0
  131. package/dist/cjs/WebSearch.js.map +7 -0
  132. package/dist/cjs/Write.d.ts +147 -0
  133. package/dist/cjs/Write.d.ts.map +1 -0
  134. package/dist/cjs/Write.js +122 -0
  135. package/dist/cjs/Write.js.map +7 -0
  136. package/dist/cjs/index.d.ts +127 -0
  137. package/dist/cjs/index.d.ts.map +1 -0
  138. package/dist/cjs/index.js +99 -0
  139. package/dist/cjs/index.js.map +7 -0
  140. package/dist/cjs/internal/ApplyPatch.d.ts +145 -0
  141. package/dist/cjs/internal/ApplyPatch.d.ts.map +1 -0
  142. package/dist/cjs/internal/ApplyPatch.js +462 -0
  143. package/dist/cjs/internal/ApplyPatch.js.map +7 -0
  144. package/dist/cjs/internal/CodexText.d.ts +73 -0
  145. package/dist/cjs/internal/CodexText.d.ts.map +1 -0
  146. package/dist/cjs/internal/CodexText.js +108 -0
  147. package/dist/cjs/internal/CodexText.js.map +7 -0
  148. package/dist/cjs/internal/Declaration.d.ts +49 -0
  149. package/dist/cjs/internal/Declaration.d.ts.map +1 -0
  150. package/dist/cjs/internal/Declaration.js +46 -0
  151. package/dist/cjs/internal/Declaration.js.map +7 -0
  152. package/dist/cjs/internal/Diagnostics.d.ts +77 -0
  153. package/dist/cjs/internal/Diagnostics.d.ts.map +1 -0
  154. package/dist/cjs/internal/Diagnostics.js +89 -0
  155. package/dist/cjs/internal/Diagnostics.js.map +7 -0
  156. package/dist/cjs/internal/EnvelopePrecheck.d.ts +67 -0
  157. package/dist/cjs/internal/EnvelopePrecheck.d.ts.map +1 -0
  158. package/dist/cjs/internal/EnvelopePrecheck.js +124 -0
  159. package/dist/cjs/internal/EnvelopePrecheck.js.map +7 -0
  160. package/dist/cjs/internal/Exec.d.ts +139 -0
  161. package/dist/cjs/internal/Exec.d.ts.map +1 -0
  162. package/dist/cjs/internal/Exec.js +158 -0
  163. package/dist/cjs/internal/Exec.js.map +7 -0
  164. package/dist/cjs/internal/FileMutation.d.ts +109 -0
  165. package/dist/cjs/internal/FileMutation.d.ts.map +1 -0
  166. package/dist/cjs/internal/FileMutation.js +116 -0
  167. package/dist/cjs/internal/FileMutation.js.map +7 -0
  168. package/dist/cjs/internal/FsFailure.d.ts +38 -0
  169. package/dist/cjs/internal/FsFailure.d.ts.map +1 -0
  170. package/dist/cjs/internal/FsFailure.js +40 -0
  171. package/dist/cjs/internal/FsFailure.js.map +7 -0
  172. package/dist/cjs/internal/GitWorktree.d.ts +98 -0
  173. package/dist/cjs/internal/GitWorktree.d.ts.map +1 -0
  174. package/dist/cjs/internal/GitWorktree.js +270 -0
  175. package/dist/cjs/internal/GitWorktree.js.map +7 -0
  176. package/dist/cjs/internal/Grouping.d.ts +51 -0
  177. package/dist/cjs/internal/Grouping.d.ts.map +1 -0
  178. package/dist/cjs/internal/Grouping.js +83 -0
  179. package/dist/cjs/internal/Grouping.js.map +7 -0
  180. package/dist/cjs/internal/Html.d.ts +20 -0
  181. package/dist/cjs/internal/Html.d.ts.map +1 -0
  182. package/dist/cjs/internal/Html.js +81 -0
  183. package/dist/cjs/internal/Html.js.map +7 -0
  184. package/dist/cjs/internal/Http.d.ts +95 -0
  185. package/dist/cjs/internal/Http.d.ts.map +1 -0
  186. package/dist/cjs/internal/Http.js +153 -0
  187. package/dist/cjs/internal/Http.js.map +7 -0
  188. package/dist/cjs/internal/HttpNetwork.d.ts +27 -0
  189. package/dist/cjs/internal/HttpNetwork.d.ts.map +1 -0
  190. package/dist/cjs/internal/HttpNetwork.js +146 -0
  191. package/dist/cjs/internal/HttpNetwork.js.map +7 -0
  192. package/dist/cjs/internal/Ignore.d.ts +37 -0
  193. package/dist/cjs/internal/Ignore.d.ts.map +1 -0
  194. package/dist/cjs/internal/Ignore.js +100 -0
  195. package/dist/cjs/internal/Ignore.js.map +7 -0
  196. package/dist/cjs/internal/LinearRegex.d.ts +19 -0
  197. package/dist/cjs/internal/LinearRegex.d.ts.map +1 -0
  198. package/dist/cjs/internal/LinearRegex.js +166 -0
  199. package/dist/cjs/internal/LinearRegex.js.map +7 -0
  200. package/dist/cjs/internal/Match.d.ts +85 -0
  201. package/dist/cjs/internal/Match.d.ts.map +1 -0
  202. package/dist/cjs/internal/Match.js +99 -0
  203. package/dist/cjs/internal/Match.js.map +7 -0
  204. package/dist/cjs/internal/Paths.d.ts +23 -0
  205. package/dist/cjs/internal/Paths.d.ts.map +1 -0
  206. package/dist/cjs/internal/Paths.js +52 -0
  207. package/dist/cjs/internal/Paths.js.map +7 -0
  208. package/dist/cjs/internal/Preserve.d.ts +25 -0
  209. package/dist/cjs/internal/Preserve.d.ts.map +1 -0
  210. package/dist/cjs/internal/Preserve.js +88 -0
  211. package/dist/cjs/internal/Preserve.js.map +7 -0
  212. package/dist/cjs/internal/Prune.d.ts +35 -0
  213. package/dist/cjs/internal/Prune.d.ts.map +1 -0
  214. package/dist/cjs/internal/Prune.js +54 -0
  215. package/dist/cjs/internal/Prune.js.map +7 -0
  216. package/dist/cjs/internal/SearchContract.d.ts +63 -0
  217. package/dist/cjs/internal/SearchContract.d.ts.map +1 -0
  218. package/dist/cjs/internal/SearchContract.js +46 -0
  219. package/dist/cjs/internal/SearchContract.js.map +7 -0
  220. package/dist/cjs/internal/Symbols.d.ts +39 -0
  221. package/dist/cjs/internal/Symbols.d.ts.map +1 -0
  222. package/dist/cjs/internal/Symbols.js +59 -0
  223. package/dist/cjs/internal/Symbols.js.map +7 -0
  224. package/dist/cjs/internal/TestReport.d.ts +52 -0
  225. package/dist/cjs/internal/TestReport.d.ts.map +1 -0
  226. package/dist/cjs/internal/TestReport.js +131 -0
  227. package/dist/cjs/internal/TestReport.js.map +7 -0
  228. package/dist/cjs/internal/Text.d.ts +114 -0
  229. package/dist/cjs/internal/Text.d.ts.map +1 -0
  230. package/dist/cjs/internal/Text.js +82 -0
  231. package/dist/cjs/internal/Text.js.map +7 -0
  232. package/dist/cjs/internal/Url.d.ts +13 -0
  233. package/dist/cjs/internal/Url.d.ts.map +1 -0
  234. package/dist/cjs/internal/Url.js +35 -0
  235. package/dist/cjs/internal/Url.js.map +7 -0
  236. package/dist/cjs/internal/Walk.d.ts +72 -0
  237. package/dist/cjs/internal/Walk.d.ts.map +1 -0
  238. package/dist/cjs/internal/Walk.js +108 -0
  239. package/dist/cjs/internal/Walk.js.map +7 -0
  240. package/dist/cjs/package.json +1 -0
  241. package/dist/esm/ApplyPatch.d.ts +174 -0
  242. package/dist/esm/ApplyPatch.d.ts.map +1 -0
  243. package/dist/esm/ApplyPatch.js +346 -0
  244. package/dist/esm/ApplyPatch.js.map +1 -0
  245. package/dist/esm/Bash.d.ts +304 -0
  246. package/dist/esm/Bash.d.ts.map +1 -0
  247. package/dist/esm/Bash.js +469 -0
  248. package/dist/esm/Bash.js.map +1 -0
  249. package/dist/esm/Checkpoints.d.ts +279 -0
  250. package/dist/esm/Checkpoints.d.ts.map +1 -0
  251. package/dist/esm/Checkpoints.js +298 -0
  252. package/dist/esm/Checkpoints.js.map +1 -0
  253. package/dist/esm/Container.d.ts +132 -0
  254. package/dist/esm/Container.d.ts.map +1 -0
  255. package/dist/esm/Container.js +151 -0
  256. package/dist/esm/Container.js.map +1 -0
  257. package/dist/esm/Edit.d.ts +203 -0
  258. package/dist/esm/Edit.d.ts.map +1 -0
  259. package/dist/esm/Edit.js +296 -0
  260. package/dist/esm/Edit.js.map +1 -0
  261. package/dist/esm/ExaWebSearch.d.ts +22 -0
  262. package/dist/esm/ExaWebSearch.d.ts.map +1 -0
  263. package/dist/esm/ExaWebSearch.js +107 -0
  264. package/dist/esm/ExaWebSearch.js.map +1 -0
  265. package/dist/esm/Explore.d.ts +328 -0
  266. package/dist/esm/Explore.d.ts.map +1 -0
  267. package/dist/esm/Explore.js +106 -0
  268. package/dist/esm/Explore.js.map +1 -0
  269. package/dist/esm/Fetch.d.ts +130 -0
  270. package/dist/esm/Fetch.d.ts.map +1 -0
  271. package/dist/esm/Fetch.js +91 -0
  272. package/dist/esm/Fetch.js.map +1 -0
  273. package/dist/esm/Glob.d.ts +204 -0
  274. package/dist/esm/Glob.d.ts.map +1 -0
  275. package/dist/esm/Glob.js +177 -0
  276. package/dist/esm/Glob.js.map +1 -0
  277. package/dist/esm/Grep.d.ts +347 -0
  278. package/dist/esm/Grep.d.ts.map +1 -0
  279. package/dist/esm/Grep.js +289 -0
  280. package/dist/esm/Grep.js.map +1 -0
  281. package/dist/esm/HttpPost.d.ts +130 -0
  282. package/dist/esm/HttpPost.d.ts.map +1 -0
  283. package/dist/esm/HttpPost.js +89 -0
  284. package/dist/esm/HttpPost.js.map +1 -0
  285. package/dist/esm/LanguageServer.d.ts +90 -0
  286. package/dist/esm/LanguageServer.d.ts.map +1 -0
  287. package/dist/esm/LanguageServer.js +57 -0
  288. package/dist/esm/LanguageServer.js.map +1 -0
  289. package/dist/esm/Ls.d.ts +164 -0
  290. package/dist/esm/Ls.d.ts.map +1 -0
  291. package/dist/esm/Ls.js +178 -0
  292. package/dist/esm/Ls.js.map +1 -0
  293. package/dist/esm/Lsp.d.ts +125 -0
  294. package/dist/esm/Lsp.d.ts.map +1 -0
  295. package/dist/esm/Lsp.js +165 -0
  296. package/dist/esm/Lsp.js.map +1 -0
  297. package/dist/esm/Manifest.d.ts +918 -0
  298. package/dist/esm/Manifest.d.ts.map +1 -0
  299. package/dist/esm/Manifest.js +153 -0
  300. package/dist/esm/Manifest.js.map +1 -0
  301. package/dist/esm/NativeSearch.d.ts +38 -0
  302. package/dist/esm/NativeSearch.d.ts.map +1 -0
  303. package/dist/esm/NativeSearch.js +378 -0
  304. package/dist/esm/NativeSearch.js.map +1 -0
  305. package/dist/esm/NodeLanguageServer.d.ts +128 -0
  306. package/dist/esm/NodeLanguageServer.d.ts.map +1 -0
  307. package/dist/esm/NodeLanguageServer.js +843 -0
  308. package/dist/esm/NodeLanguageServer.js.map +1 -0
  309. package/dist/esm/PortableSearch.d.ts +24 -0
  310. package/dist/esm/PortableSearch.d.ts.map +1 -0
  311. package/dist/esm/PortableSearch.js +240 -0
  312. package/dist/esm/PortableSearch.js.map +1 -0
  313. package/dist/esm/Probe.d.ts +193 -0
  314. package/dist/esm/Probe.d.ts.map +1 -0
  315. package/dist/esm/Probe.js +225 -0
  316. package/dist/esm/Probe.js.map +1 -0
  317. package/dist/esm/Read.d.ts +189 -0
  318. package/dist/esm/Read.d.ts.map +1 -0
  319. package/dist/esm/Read.js +300 -0
  320. package/dist/esm/Read.js.map +1 -0
  321. package/dist/esm/Relocate.d.ts +73 -0
  322. package/dist/esm/Relocate.d.ts.map +1 -0
  323. package/dist/esm/Relocate.js +153 -0
  324. package/dist/esm/Relocate.js.map +1 -0
  325. package/dist/esm/Search.d.ts +163 -0
  326. package/dist/esm/Search.d.ts.map +1 -0
  327. package/dist/esm/Search.js +47 -0
  328. package/dist/esm/Search.js.map +1 -0
  329. package/dist/esm/SearchConformance.d.ts +115 -0
  330. package/dist/esm/SearchConformance.d.ts.map +1 -0
  331. package/dist/esm/SearchConformance.js +193 -0
  332. package/dist/esm/SearchConformance.js.map +1 -0
  333. package/dist/esm/SearchContract.d.ts +114 -0
  334. package/dist/esm/SearchContract.d.ts.map +1 -0
  335. package/dist/esm/SearchContract.js +461 -0
  336. package/dist/esm/SearchContract.js.map +1 -0
  337. package/dist/esm/ShellCommand.d.ts +164 -0
  338. package/dist/esm/ShellCommand.d.ts.map +1 -0
  339. package/dist/esm/ShellCommand.js +159 -0
  340. package/dist/esm/ShellCommand.js.map +1 -0
  341. package/dist/esm/StdError.d.ts +55 -0
  342. package/dist/esm/StdError.d.ts.map +1 -0
  343. package/dist/esm/StdError.js +71 -0
  344. package/dist/esm/StdError.js.map +1 -0
  345. package/dist/esm/TestRun.d.ts +311 -0
  346. package/dist/esm/TestRun.d.ts.map +1 -0
  347. package/dist/esm/TestRun.js +316 -0
  348. package/dist/esm/TestRun.js.map +1 -0
  349. package/dist/esm/TestRunner.d.ts +102 -0
  350. package/dist/esm/TestRunner.d.ts.map +1 -0
  351. package/dist/esm/TestRunner.js +68 -0
  352. package/dist/esm/TestRunner.js.map +1 -0
  353. package/dist/esm/TreeFingerprint.d.ts +140 -0
  354. package/dist/esm/TreeFingerprint.d.ts.map +1 -0
  355. package/dist/esm/TreeFingerprint.js +170 -0
  356. package/dist/esm/TreeFingerprint.js.map +1 -0
  357. package/dist/esm/UpdatePlan.d.ts +152 -0
  358. package/dist/esm/UpdatePlan.d.ts.map +1 -0
  359. package/dist/esm/UpdatePlan.js +129 -0
  360. package/dist/esm/UpdatePlan.js.map +1 -0
  361. package/dist/esm/WebFetch.d.ts +134 -0
  362. package/dist/esm/WebFetch.d.ts.map +1 -0
  363. package/dist/esm/WebFetch.js +151 -0
  364. package/dist/esm/WebFetch.js.map +1 -0
  365. package/dist/esm/WebSearch.d.ts +181 -0
  366. package/dist/esm/WebSearch.d.ts.map +1 -0
  367. package/dist/esm/WebSearch.js +134 -0
  368. package/dist/esm/WebSearch.js.map +1 -0
  369. package/dist/esm/Write.d.ts +147 -0
  370. package/dist/esm/Write.d.ts.map +1 -0
  371. package/dist/esm/Write.js +144 -0
  372. package/dist/esm/Write.js.map +1 -0
  373. package/dist/esm/index.d.ts +127 -0
  374. package/dist/esm/index.d.ts.map +1 -0
  375. package/dist/esm/index.js +127 -0
  376. package/dist/esm/index.js.map +1 -0
  377. package/dist/esm/internal/ApplyPatch.d.ts +145 -0
  378. package/dist/esm/internal/ApplyPatch.d.ts.map +1 -0
  379. package/dist/esm/internal/ApplyPatch.js +489 -0
  380. package/dist/esm/internal/ApplyPatch.js.map +1 -0
  381. package/dist/esm/internal/CodexText.d.ts +73 -0
  382. package/dist/esm/internal/CodexText.d.ts.map +1 -0
  383. package/dist/esm/internal/CodexText.js +156 -0
  384. package/dist/esm/internal/CodexText.js.map +1 -0
  385. package/dist/esm/internal/Declaration.d.ts +49 -0
  386. package/dist/esm/internal/Declaration.d.ts.map +1 -0
  387. package/dist/esm/internal/Declaration.js +42 -0
  388. package/dist/esm/internal/Declaration.js.map +1 -0
  389. package/dist/esm/internal/Diagnostics.d.ts +77 -0
  390. package/dist/esm/internal/Diagnostics.d.ts.map +1 -0
  391. package/dist/esm/internal/Diagnostics.js +99 -0
  392. package/dist/esm/internal/Diagnostics.js.map +1 -0
  393. package/dist/esm/internal/EnvelopePrecheck.d.ts +67 -0
  394. package/dist/esm/internal/EnvelopePrecheck.d.ts.map +1 -0
  395. package/dist/esm/internal/EnvelopePrecheck.js +167 -0
  396. package/dist/esm/internal/EnvelopePrecheck.js.map +1 -0
  397. package/dist/esm/internal/Exec.d.ts +139 -0
  398. package/dist/esm/internal/Exec.d.ts.map +1 -0
  399. package/dist/esm/internal/Exec.js +193 -0
  400. package/dist/esm/internal/Exec.js.map +1 -0
  401. package/dist/esm/internal/FileMutation.d.ts +109 -0
  402. package/dist/esm/internal/FileMutation.d.ts.map +1 -0
  403. package/dist/esm/internal/FileMutation.js +123 -0
  404. package/dist/esm/internal/FileMutation.js.map +1 -0
  405. package/dist/esm/internal/FsFailure.d.ts +38 -0
  406. package/dist/esm/internal/FsFailure.d.ts.map +1 -0
  407. package/dist/esm/internal/FsFailure.js +39 -0
  408. package/dist/esm/internal/FsFailure.js.map +1 -0
  409. package/dist/esm/internal/GitWorktree.d.ts +98 -0
  410. package/dist/esm/internal/GitWorktree.d.ts.map +1 -0
  411. package/dist/esm/internal/GitWorktree.js +345 -0
  412. package/dist/esm/internal/GitWorktree.js.map +1 -0
  413. package/dist/esm/internal/Grouping.d.ts +51 -0
  414. package/dist/esm/internal/Grouping.d.ts.map +1 -0
  415. package/dist/esm/internal/Grouping.js +99 -0
  416. package/dist/esm/internal/Grouping.js.map +1 -0
  417. package/dist/esm/internal/Html.d.ts +20 -0
  418. package/dist/esm/internal/Html.d.ts.map +1 -0
  419. package/dist/esm/internal/Html.js +70 -0
  420. package/dist/esm/internal/Html.js.map +1 -0
  421. package/dist/esm/internal/Http.d.ts +95 -0
  422. package/dist/esm/internal/Http.d.ts.map +1 -0
  423. package/dist/esm/internal/Http.js +154 -0
  424. package/dist/esm/internal/Http.js.map +1 -0
  425. package/dist/esm/internal/HttpNetwork.d.ts +27 -0
  426. package/dist/esm/internal/HttpNetwork.d.ts.map +1 -0
  427. package/dist/esm/internal/HttpNetwork.js +114 -0
  428. package/dist/esm/internal/HttpNetwork.js.map +1 -0
  429. package/dist/esm/internal/Ignore.d.ts +37 -0
  430. package/dist/esm/internal/Ignore.d.ts.map +1 -0
  431. package/dist/esm/internal/Ignore.js +128 -0
  432. package/dist/esm/internal/Ignore.js.map +1 -0
  433. package/dist/esm/internal/LinearRegex.d.ts +19 -0
  434. package/dist/esm/internal/LinearRegex.d.ts.map +1 -0
  435. package/dist/esm/internal/LinearRegex.js +176 -0
  436. package/dist/esm/internal/LinearRegex.js.map +1 -0
  437. package/dist/esm/internal/Match.d.ts +85 -0
  438. package/dist/esm/internal/Match.d.ts.map +1 -0
  439. package/dist/esm/internal/Match.js +142 -0
  440. package/dist/esm/internal/Match.js.map +1 -0
  441. package/dist/esm/internal/Paths.d.ts +23 -0
  442. package/dist/esm/internal/Paths.d.ts.map +1 -0
  443. package/dist/esm/internal/Paths.js +40 -0
  444. package/dist/esm/internal/Paths.js.map +1 -0
  445. package/dist/esm/internal/Preserve.d.ts +25 -0
  446. package/dist/esm/internal/Preserve.d.ts.map +1 -0
  447. package/dist/esm/internal/Preserve.js +70 -0
  448. package/dist/esm/internal/Preserve.js.map +1 -0
  449. package/dist/esm/internal/Prune.d.ts +35 -0
  450. package/dist/esm/internal/Prune.d.ts.map +1 -0
  451. package/dist/esm/internal/Prune.js +60 -0
  452. package/dist/esm/internal/Prune.js.map +1 -0
  453. package/dist/esm/internal/SearchContract.d.ts +63 -0
  454. package/dist/esm/internal/SearchContract.d.ts.map +1 -0
  455. package/dist/esm/internal/SearchContract.js +66 -0
  456. package/dist/esm/internal/SearchContract.js.map +1 -0
  457. package/dist/esm/internal/Symbols.d.ts +39 -0
  458. package/dist/esm/internal/Symbols.d.ts.map +1 -0
  459. package/dist/esm/internal/Symbols.js +79 -0
  460. package/dist/esm/internal/Symbols.js.map +1 -0
  461. package/dist/esm/internal/TestReport.d.ts +52 -0
  462. package/dist/esm/internal/TestReport.d.ts.map +1 -0
  463. package/dist/esm/internal/TestReport.js +172 -0
  464. package/dist/esm/internal/TestReport.js.map +1 -0
  465. package/dist/esm/internal/Text.d.ts +114 -0
  466. package/dist/esm/internal/Text.d.ts.map +1 -0
  467. package/dist/esm/internal/Text.js +130 -0
  468. package/dist/esm/internal/Text.js.map +1 -0
  469. package/dist/esm/internal/Url.d.ts +13 -0
  470. package/dist/esm/internal/Url.d.ts.map +1 -0
  471. package/dist/esm/internal/Url.js +27 -0
  472. package/dist/esm/internal/Url.js.map +1 -0
  473. package/dist/esm/internal/Walk.d.ts +72 -0
  474. package/dist/esm/internal/Walk.d.ts.map +1 -0
  475. package/dist/esm/internal/Walk.js +126 -0
  476. package/dist/esm/internal/Walk.js.map +1 -0
  477. package/docs/README.md +117 -0
  478. package/docs/api.md +472 -0
  479. package/docs/concepts/effects-and-capabilities.md +136 -0
  480. package/docs/concepts/flows-and-handlers.md +115 -0
  481. package/docs/concepts/limits-and-disclosure.md +102 -0
  482. package/docs/concepts/search-contract.md +182 -0
  483. package/docs/guides/bind-the-standard-flows.md +114 -0
  484. package/docs/guides/implement-a-search-peer.md +133 -0
  485. package/docs/guides/pin-a-checkpoint.md +141 -0
  486. package/docs/guides/query-a-language-server.md +257 -0
  487. package/docs/guides/reach-the-network.md +141 -0
  488. package/docs/guides/read-and-edit-a-file.md +240 -0
  489. package/docs/guides/run-a-shell-command.md +215 -0
  490. package/docs/guides/run-the-test-suite.md +154 -0
  491. package/docs/guides/search-a-workspace.md +148 -0
  492. package/docs/installation.md +111 -0
  493. package/docs/quickstart.md +125 -0
  494. package/docs/reference/flows.md +556 -0
  495. package/docs/troubleshooting.md +322 -0
  496. package/package.json +439 -3
  497. package/src/ApplyPatch.ts +458 -0
  498. package/src/Bash.ts +549 -0
  499. package/src/Checkpoints.ts +422 -0
  500. package/src/Container.ts +212 -0
  501. package/src/Edit.ts +366 -0
  502. package/src/ExaWebSearch.ts +145 -0
  503. package/src/Explore.ts +139 -0
  504. package/src/Fetch.ts +117 -0
  505. package/src/Glob.ts +200 -0
  506. package/src/Grep.ts +320 -0
  507. package/src/HttpPost.ts +120 -0
  508. package/src/LanguageServer.ts +110 -0
  509. package/src/Ls.ts +228 -0
  510. package/src/Lsp.ts +184 -0
  511. package/src/Manifest.ts +162 -0
  512. package/src/NativeSearch.ts +457 -0
  513. package/src/NodeLanguageServer.ts +1148 -0
  514. package/src/PortableSearch.ts +264 -0
  515. package/src/Probe.ts +284 -0
  516. package/src/Read.ts +359 -0
  517. package/src/Relocate.ts +166 -0
  518. package/src/Search.ts +185 -0
  519. package/src/SearchConformance.ts +288 -0
  520. package/src/SearchContract.ts +489 -0
  521. package/src/ShellCommand.ts +201 -0
  522. package/src/StdError.ts +80 -0
  523. package/src/TestRun.ts +401 -0
  524. package/src/TestRunner.ts +119 -0
  525. package/src/TreeFingerprint.ts +200 -0
  526. package/src/UpdatePlan.ts +171 -0
  527. package/src/WebFetch.ts +194 -0
  528. package/src/WebSearch.ts +165 -0
  529. package/src/Write.ts +195 -0
  530. package/src/index.ts +154 -0
  531. package/src/internal/ApplyPatch.ts +601 -0
  532. package/src/internal/CodexText.ts +182 -0
  533. package/src/internal/Declaration.ts +60 -0
  534. package/src/internal/Diagnostics.ts +134 -0
  535. package/src/internal/EnvelopePrecheck.ts +233 -0
  536. package/src/internal/Exec.ts +314 -0
  537. package/src/internal/FileMutation.ts +231 -0
  538. package/src/internal/FsFailure.ts +51 -0
  539. package/src/internal/GitWorktree.ts +473 -0
  540. package/src/internal/Grouping.ts +106 -0
  541. package/src/internal/Html.ts +87 -0
  542. package/src/internal/Http.ts +209 -0
  543. package/src/internal/HttpNetwork.ts +153 -0
  544. package/src/internal/Ignore.ts +135 -0
  545. package/src/internal/LinearRegex.ts +173 -0
  546. package/src/internal/Match.ts +172 -0
  547. package/src/internal/Paths.ts +42 -0
  548. package/src/internal/Preserve.ts +108 -0
  549. package/src/internal/Prune.ts +62 -0
  550. package/src/internal/SearchContract.ts +77 -0
  551. package/src/internal/Symbols.ts +88 -0
  552. package/src/internal/TestReport.ts +194 -0
  553. package/src/internal/Text.ts +170 -0
  554. package/src/internal/Url.ts +23 -0
  555. package/src/internal/Walk.ts +176 -0
package/src/Edit.ts ADDED
@@ -0,0 +1,366 @@
1
+ /**
2
+ * Edit flow declaration and portable handler.
3
+ *
4
+ * Three rules, each of them paid for by a measured failure:
5
+ *
6
+ * 1. **Exact or loud.** The anchor matches the file's bytes or the call fails
7
+ * with the file's actual bytes at the nearest region. No fuzzy apply reports
8
+ * success (sympy-15380 corrupted a file that way), and no failure returns a
9
+ * bare `null` (sphinx-7590 abandoned a correct edit twice against one).
10
+ * 2. **Anchors by reference.** A prior `grep` or `read` already located the
11
+ * region; `startLine`/`endLine` re-use that hit instead of retyping the text,
12
+ * and `expect` turns the retyped copy into a checked assertion rather than a
13
+ * search key.
14
+ * 3. **The hunk comes back.** The result carries the applied region as raw text
15
+ * with its line range, so a mis-indented edit costs one glance instead of an
16
+ * investigation (sphinx-7233 lost its verdict to a hunk nobody could see).
17
+ * With a `LanguageServer` bound, the file's errors after the edit come back
18
+ * too.
19
+ *
20
+ * @since 1.0.0
21
+ */
22
+
23
+ import * as Effect from "effect/Effect"
24
+ import * as FileSystem from "effect/FileSystem"
25
+ import * as Schema from "effect/Schema"
26
+ import { capability, envelope } from "./internal/Declaration.ts"
27
+ import * as Diagnostics from "./internal/Diagnostics.ts"
28
+ import * as FileMutation from "./internal/FileMutation.ts"
29
+ import * as FsFailure from "./internal/FsFailure.ts"
30
+ import * as Match from "./internal/Match.ts"
31
+ import * as Preserve from "./internal/Preserve.ts"
32
+ import { sourceLines } from "./internal/Text.ts"
33
+ import * as StdError from "./StdError.ts"
34
+
35
+ /**
36
+ * Registry name for the edit flow.
37
+ *
38
+ * @category identifiers
39
+ * @since 1.0.0
40
+ */
41
+ export const name = "edit"
42
+
43
+ /**
44
+ * Model-facing description of the edit flow.
45
+ *
46
+ * @category descriptions
47
+ * @since 1.0.0
48
+ */
49
+ export const description =
50
+ "Edit a file by exact text (oldString, unique unless replaceAll) or by an earlier hit's line range (startLine/endLine, optional expect). A miss returns the file's real text; a hit returns the hunk."
51
+
52
+ /**
53
+ * Input schema for the edit flow.
54
+ *
55
+ * @category schemas
56
+ * @since 1.0.0
57
+ */
58
+ export const Input = Schema.Struct({
59
+ path: Schema.String.annotate({ description: "Path of the file to edit" }),
60
+ oldString: Schema.optional(Schema.String).annotate({
61
+ description: "Exact text to replace, byte for byte, including surrounding context"
62
+ }),
63
+ startLine: Schema.optional(Schema.Int.check(Schema.isGreaterThanOrEqualTo(1))).annotate({
64
+ description: "First 1-based line to replace, from a prior read or grep hit; pair with endLine"
65
+ }),
66
+ endLine: Schema.optional(Schema.Int.check(Schema.isGreaterThanOrEqualTo(1))).annotate({
67
+ description: "Last 1-based line to replace, inclusive"
68
+ }),
69
+ expect: Schema.optional(Schema.String).annotate({
70
+ description: "What those lines currently hold; the edit fails loudly if they hold anything else"
71
+ }),
72
+ newString: Schema.String.annotate({ description: "Replacement text" }),
73
+ replaceAll: Schema.optional(Schema.Boolean).annotate({ description: "Replace every occurrence instead of one" })
74
+ })
75
+
76
+ /**
77
+ * Decoded input accepted by the `edit` flow.
78
+ *
79
+ * @category models
80
+ * @since 1.0.0
81
+ */
82
+ export type Input = typeof Input.Type
83
+
84
+ /**
85
+ * Output schema for the edit flow.
86
+ *
87
+ * @category schemas
88
+ * @since 1.0.0
89
+ */
90
+ export const Output = Schema.Struct({
91
+ path: Schema.String.annotate({ description: "Path that was edited" }),
92
+ replacements: Schema.Number.annotate({ description: "Number of occurrences replaced" }),
93
+ startLine: Schema.Number.annotate({ description: "First 1-based line of the returned hunk" }),
94
+ endLine: Schema.Number.annotate({ description: "Last 1-based line of the returned hunk" }),
95
+ hunk: Schema.String.annotate({
96
+ description: "The edited region as it now stands, raw and with its exact indentation, plus two lines of context"
97
+ }),
98
+ errors: Schema.optional(Schema.Array(Diagnostics.Problem)).annotate({
99
+ description: "Errors the language server reports in the file after the edit; absent when no server answered"
100
+ })
101
+ })
102
+
103
+ /**
104
+ * Decoded output returned by the `edit` flow.
105
+ *
106
+ * @category models
107
+ * @since 1.0.0
108
+ */
109
+ export type Output = typeof Output.Type
110
+
111
+ /**
112
+ * Static conservative effect envelope for the edit flow.
113
+ *
114
+ * @category effects
115
+ * @since 1.0.0
116
+ */
117
+ export const effects = envelope({ tier: "compensable", mode: "hermetic", reads: ["/**"], writes: ["/**"] })
118
+
119
+ /**
120
+ * Narrows the edit effect envelope to one input path.
121
+ *
122
+ * @category effects
123
+ * @since 1.0.0
124
+ */
125
+ export const effectsFor = (input: typeof Input.Type) =>
126
+ envelope({ tier: "compensable", mode: "hermetic", reads: [input.path], writes: [input.path] })
127
+
128
+ /**
129
+ * Capabilities required by the edit flow.
130
+ *
131
+ * @category capabilities
132
+ * @since 1.0.0
133
+ */
134
+ export const capabilities = [capability("fs:read", "/**"), capability("fs:write", "/**")]
135
+
136
+ /**
137
+ * Declaration-only edit flow.
138
+ *
139
+ * @category flows
140
+ * @since 1.0.0
141
+ */
142
+ export const flow = { name, description, input: Input, output: Output, capabilities, effects } as const
143
+
144
+ /**
145
+ * What a call to this flow does, for a reader of a run.
146
+ *
147
+ * Display metadata only. `@smthrs/registry` `Descriptor.FlowActivity` is the
148
+ * governing vocabulary and `StandardFlows` binds this value onto the flow's
149
+ * descriptor, where the binding site checks it. `declarationDigest` excludes
150
+ * it, so declaring it cannot invalidate a call identity or a cached prompt.
151
+ *
152
+ * @category presentation
153
+ * @since 1.0.0-rc.0
154
+ */
155
+ export const activity = "writes" as const
156
+
157
+ /**
158
+ * How one recorded call to this flow reads: the verb for each settlement, the
159
+ * input field that is its subject, and the measured output fields a one-line
160
+ * summary may count.
161
+ *
162
+ * Display metadata only, governed by `@smthrs/registry`
163
+ * `Descriptor.CallPresentation` and checked where `StandardFlows` binds it.
164
+ *
165
+ * @category presentation
166
+ * @since 1.0.0-rc.0
167
+ */
168
+ export const presentation = {
169
+ verb: { pending: "editing", success: "edited", failure: "failed to edit" },
170
+ subject: "path",
171
+ result: "edit"
172
+ } as const
173
+
174
+ const invalid = (path: string, message: string): StdError.StdError =>
175
+ new StdError.StdError({ code: "invalid_input", message, path })
176
+
177
+ /** The failure text for an anchor that is not in the file, with the file's own bytes. */
178
+ const miss = (path: string, content: string, needle: string, subject: string): StdError.StdError => {
179
+ const region = Match.nearest(content, needle)
180
+ return new StdError.StdError({
181
+ code: "no_match",
182
+ message: region === undefined
183
+ ? `${subject} does not occur in ${path}, and no line of it occurs there either — this is the wrong file, or the region is not what you remember. Read it and anchor on what it actually holds.`
184
+ : `${subject} does not occur in ${path}. Lines ${region.startLine}-${region.endLine} actually hold this, raw:\n${region.text}\n\nCopy the lines you meant from that text, or anchor by startLine/endLine instead.`,
185
+ path
186
+ })
187
+ }
188
+
189
+ /** The byte span of an inclusive 1-based line range, or the failure explaining why not. */
190
+ const lineSpan = (
191
+ path: string,
192
+ content: string,
193
+ startLine: number,
194
+ endLine: number
195
+ ): { readonly start: number; readonly end: number } | StdError.StdError => {
196
+ const lines = sourceLines(content)
197
+ if (endLine < startLine) return invalid(path, `endLine ${endLine} is before startLine ${startLine}`)
198
+ if (startLine > lines.length) {
199
+ return new StdError.StdError({
200
+ code: "offset_out_of_range",
201
+ message: `${path} has ${lines.length} lines, so line ${startLine} is outside it`,
202
+ path
203
+ })
204
+ }
205
+ if (endLine > lines.length) {
206
+ return new StdError.StdError({
207
+ code: "offset_out_of_range",
208
+ message: `Requested endLine ${endLine}, but ${path} has ${lines.length} lines`,
209
+ path
210
+ })
211
+ }
212
+ const last = endLine
213
+ let start = 0
214
+ for (let index = 0; index < startLine - 1; index++) start += lines[index]!.length + 1
215
+ let end = start
216
+ for (let index = startLine - 1; index < last; index++) end += lines[index]!.length + (index === last - 1 ? 0 : 1)
217
+ return { start, end }
218
+ }
219
+
220
+ /**
221
+ * Applies one exact-anchored edit through the permission-aware kernel filesystem.
222
+ *
223
+ * Every refusal names what the file actually holds. A non-unique match is a
224
+ * refusal rather than a silent first-match edit, and it reports the lines every
225
+ * occurrence sits on so the caller can widen the anchor without re-reading.
226
+ *
227
+ * @category handlers
228
+ * @since 1.0.0
229
+ */
230
+ export const run = Effect.fn("Edit.run")(function*(
231
+ input: typeof Input.Type
232
+ ): Effect.fn.Return<typeof Output.Type, StdError.StdError, FileSystem.FileSystem> {
233
+ const fileSystem = yield* FileSystem.FileSystem
234
+ const byLines = input.startLine !== undefined || input.endLine !== undefined
235
+ if (input.oldString !== undefined && byLines) {
236
+ return yield* Effect.fail(
237
+ invalid(input.path, "Anchor by oldString or by startLine/endLine, not by both")
238
+ )
239
+ }
240
+ if (input.oldString === undefined && !byLines) {
241
+ return yield* Effect.fail(
242
+ invalid(input.path, "Give either oldString or a startLine/endLine range; use the write flow to create a file")
243
+ )
244
+ }
245
+ if (byLines && (input.startLine === undefined || input.endLine === undefined)) {
246
+ return yield* Effect.fail(invalid(input.path, "A line anchor needs both startLine and endLine"))
247
+ }
248
+ if (input.oldString === "") {
249
+ return yield* Effect.fail(
250
+ invalid(input.path, "oldString must not be empty; use the write flow to create a file")
251
+ )
252
+ }
253
+ if (input.oldString !== undefined && input.expect !== undefined) {
254
+ return yield* Effect.fail(invalid(input.path, "expect cannot be used with oldString"))
255
+ }
256
+ if (byLines && input.replaceAll !== undefined) {
257
+ return yield* Effect.fail(invalid(input.path, "replaceAll cannot be used with startLine/endLine"))
258
+ }
259
+ const edited = yield* Effect.scoped(Effect.gen(function*() {
260
+ const mutation = yield* FileMutation.acquire(fileSystem, [input.path])
261
+ const bytes = yield* mutation.read(
262
+ input.path,
263
+ fileSystem.readFile(input.path).pipe(
264
+ Effect.mapError(FsFailure.reading(input.path, `File not found: ${input.path}`))
265
+ )
266
+ )
267
+ if (bytes.includes(0)) {
268
+ return yield* Effect.fail(
269
+ new StdError.StdError({
270
+ code: "binary_file",
271
+ message: `Cannot read binary file: ${input.path}`,
272
+ path: input.path
273
+ })
274
+ )
275
+ }
276
+ const content = yield* Effect.try({
277
+ try: () => new TextDecoder("utf-8", { fatal: true }).decode(bytes),
278
+ catch: () =>
279
+ new StdError.StdError({
280
+ code: "binary_file",
281
+ message: `File is not valid UTF-8: ${input.path}`,
282
+ path: input.path
283
+ })
284
+ })
285
+
286
+ const targets: Array<{ readonly start: number; readonly end: number }> = []
287
+ if (input.oldString !== undefined) {
288
+ const located = Match.locate(content, input.oldString)
289
+ if (located.length === 0) return yield* Effect.fail(miss(input.path, content, input.oldString, "oldString"))
290
+ if (located.length > 1 && input.replaceAll !== true) {
291
+ const at = located.map((span) => span.startLine).join(", ")
292
+ return yield* Effect.fail(
293
+ invalid(
294
+ input.path,
295
+ `oldString occurs ${located.length} times in ${input.path}, on lines ${at}; add surrounding context to pick one, anchor by startLine/endLine, or set replaceAll`
296
+ )
297
+ )
298
+ }
299
+ targets.push(...(input.replaceAll === true ? located : [located[0]!]))
300
+ } else {
301
+ const span = lineSpan(input.path, content, input.startLine!, input.endLine!)
302
+ if (span instanceof StdError.StdError) return yield* Effect.fail(span)
303
+ if (input.expect !== undefined && content.slice(span.start, span.end) !== input.expect) {
304
+ return yield* Effect.fail(
305
+ new StdError.StdError({
306
+ code: "no_match",
307
+ message:
308
+ `Lines ${input.startLine}-${input.endLine} of ${input.path} do not hold expect. They hold this, raw:\n${
309
+ content.slice(span.start, span.end)
310
+ }\n\nRe-read the file: it moved under the line numbers you anchored on.`,
311
+ path: input.path
312
+ })
313
+ )
314
+ }
315
+ targets.push(span)
316
+ }
317
+
318
+ let replaced = ""
319
+ let cursor = 0
320
+ for (const span of targets) {
321
+ replaced += content.slice(cursor, span.start) + input.newString
322
+ cursor = span.end
323
+ }
324
+ replaced += content.slice(cursor)
325
+ yield* mutation.commit(
326
+ [{
327
+ path: input.path,
328
+ content: new TextEncoder().encode(replaced)
329
+ }],
330
+ Preserve.writeFileString(fileSystem, input.path, replaced).pipe(
331
+ Effect.mapError((error) =>
332
+ error.reason.method === "chmod"
333
+ ? new StdError.StdError({
334
+ code: "command_failed",
335
+ message: `Could not preserve the mode of ${input.path} before replacement by chmod`,
336
+ path: input.path
337
+ })
338
+ : FsFailure.denied(input.path, () =>
339
+ new StdError.StdError({
340
+ code: "command_failed",
341
+ message: `Could not write ${input.path}`,
342
+ path: input.path
343
+ }))(
344
+ error
345
+ )
346
+ )
347
+ )
348
+ )
349
+ // Synced under the file lock, so a later edit's text never reaches the
350
+ // server before this one's.
351
+ const server = yield* Diagnostics.sync(input.path, replaced)
352
+ const first = targets[0]!
353
+ const applied = Match.hunk(replaced, first.start, first.start + input.newString.length)
354
+ const output: typeof Output.Type = {
355
+ path: input.path,
356
+ replacements: targets.length,
357
+ startLine: applied.startLine,
358
+ endLine: applied.endLine,
359
+ hunk: applied.text
360
+ }
361
+ return { output, server }
362
+ }))
363
+ // Without a synced text the server can only describe the file as it was.
364
+ const errors = edited.server === undefined ? undefined : yield* Diagnostics.errorsOf(edited.server, input.path)
365
+ return errors === undefined ? edited.output : { ...edited.output, errors }
366
+ })
@@ -0,0 +1,145 @@
1
+ /**
2
+ * The Exa provider for the `websearch` flow.
3
+ *
4
+ * {@link layer} binds `WebSearch.WebSearch` to the Exa search API. It reads the
5
+ * API key from a named credential on every search, calls Exa through the
6
+ * permission-checked `HttpClient`, and maps each hit onto `WebSearch.Result`.
7
+ *
8
+ * @since 1.0.0
9
+ */
10
+
11
+ import * as Credential from "@smthrs/control/Credential"
12
+ import * as HttpClient from "@smthrs/kernel/HttpClient"
13
+ import { Clock, Effect, Layer, Redacted, Schema } from "effect"
14
+ import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
15
+ import { header, readBounded } from "./internal/Http.ts"
16
+ import * as StdError from "./StdError.ts"
17
+ import * as WebSearch from "./WebSearch.ts"
18
+
19
+ const maxResults = 20
20
+ const requestTimeoutMs = 30_000
21
+ const ExaResult = Schema.Struct({
22
+ title: Schema.optional(Schema.String),
23
+ url: Schema.String,
24
+ text: Schema.optional(Schema.String),
25
+ publishedDate: Schema.optional(Schema.String)
26
+ })
27
+ const ExaResponse = Schema.Struct({
28
+ results: Schema.Array(ExaResult)
29
+ })
30
+ const freshnessDays = {
31
+ day: 1,
32
+ week: 7,
33
+ month: 31,
34
+ year: 365
35
+ } as const
36
+
37
+ const failure = (code: StdError.Code, message: string): StdError.StdError => new StdError.StdError({ code, message })
38
+
39
+ /**
40
+ * Provides {@link WebSearch.WebSearch} backed by the Exa API, reading its
41
+ * key from the named credential.
42
+ *
43
+ * @category layers
44
+ * @since 1.0.0
45
+ */
46
+ export const layer = (
47
+ credentialId: string
48
+ ): Layer.Layer<WebSearch.WebSearch, never, Credential.Credential | HttpClient.HttpClient> =>
49
+ Layer.effect(
50
+ WebSearch.WebSearch,
51
+ Effect.gen(function*() {
52
+ const credentials = yield* Credential.Credential
53
+ const http = yield* HttpClient.HttpClient
54
+ return WebSearch.make({
55
+ search: (input): Effect.Effect<typeof WebSearch.Output.Type, StdError.StdError> =>
56
+ Effect.gen(function*() {
57
+ const reference = yield* credentials.get(credentialId).pipe(Effect.mapError(() =>
58
+ new StdError.StdError({
59
+ code: "provider_unavailable",
60
+ message: "Configured Exa credential is unavailable"
61
+ })
62
+ ))
63
+ const secret = yield* credentials.resolve(reference).pipe(Effect.mapError(() =>
64
+ new StdError.StdError({
65
+ code: "provider_unavailable",
66
+ message: "Configured Exa credential cannot be resolved"
67
+ })
68
+ ))
69
+ const now = yield* Clock.currentTimeMillis
70
+ const request = HttpClientRequest.setHeaders(
71
+ HttpClientRequest.bodyJsonUnsafe(HttpClientRequest.post("https://api.exa.ai/search"), {
72
+ query: input.query,
73
+ numResults: Math.min(input.numResults ?? 8, maxResults),
74
+ ...(input.freshness === undefined
75
+ ? {}
76
+ : { startPublishedDate: new Date(now - freshnessDays[input.freshness] * 86_400_000).toISOString() })
77
+ }),
78
+ { "authorization": `Bearer ${Redacted.value(secret)}`, "content-type": "application/json" }
79
+ )
80
+ const response = yield* http.execute(request).pipe(
81
+ Effect.timeout(requestTimeoutMs),
82
+ Effect.mapError((error) =>
83
+ error._tag === "TimeoutError"
84
+ ? failure("timeout", "Exa search request timed out")
85
+ : failure("request_failed", "Exa search request failed")
86
+ )
87
+ )
88
+ const retryAfter = header(response.headers, "retry-after")
89
+ // Successful responses may carry pacing advice too; status decides refusal.
90
+ const refused = response.status < 200 || response.status >= 300
91
+ if (response.status === 429 || (refused && retryAfter !== undefined)) {
92
+ const delay = retryAfter === undefined
93
+ ? NaN
94
+ : /^\d+$/.test(retryAfter.trim())
95
+ ? Number(retryAfter)
96
+ : Math.max(0, Math.ceil((Date.parse(retryAfter) - (yield* Clock.currentTimeMillis)) / 1_000))
97
+ return yield* Effect.fail(
98
+ failure(
99
+ "rate_limited",
100
+ Number.isFinite(delay)
101
+ ? `Exa search was throttled; retry after ${delay} seconds`
102
+ : "Exa search was throttled"
103
+ )
104
+ )
105
+ }
106
+ if (response.status === 401 || response.status === 403) {
107
+ return yield* Effect.fail(failure("provider_unavailable", "Exa search authentication was rejected"))
108
+ }
109
+ if (response.status >= 500) {
110
+ return yield* Effect.fail(failure("provider_unavailable", `Exa search returned ${response.status}`))
111
+ }
112
+ if (response.status < 200 || response.status >= 300) {
113
+ return yield* Effect.fail(failure("request_failed", `Exa search returned ${response.status}`))
114
+ }
115
+ // Bound the body before decoding: an endpoint must not choose how
116
+ // much of it the host buffers.
117
+ const bytes = yield* readBounded(response.stream, "https://api.exa.ai/search").pipe(
118
+ Effect.timeout(requestTimeoutMs),
119
+ Effect.mapError((error) =>
120
+ error._tag === "TimeoutError"
121
+ ? failure("timeout", "Exa search response timed out")
122
+ : error instanceof StdError.StdError && error.code === "response_too_large"
123
+ ? failure("response_too_large", "Exa search response exceeds the 5 MiB limit")
124
+ : failure("request_failed", "Exa search response was invalid")
125
+ )
126
+ )
127
+ const body = yield* Schema.decodeUnknownEffect(Schema.fromJsonString(ExaResponse))(
128
+ new TextDecoder().decode(bytes)
129
+ ).pipe(
130
+ Effect.mapError(() =>
131
+ new StdError.StdError({ code: "request_failed", message: "Exa search response was invalid" })
132
+ )
133
+ )
134
+ return {
135
+ results: body.results.slice(0, Math.min(input.numResults ?? 8, maxResults)).map((result) => ({
136
+ title: result.title ?? result.url,
137
+ url: result.url,
138
+ snippet: (result.text ?? "").slice(0, 2_000),
139
+ ...(result.publishedDate === undefined ? {} : { publishedAt: result.publishedDate })
140
+ }))
141
+ }
142
+ })
143
+ })
144
+ })
145
+ )
package/src/Explore.ts ADDED
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Read-only workspace reconnaissance as a dynamic flow.
3
+ *
4
+ * @since 1.0.0
5
+ */
6
+
7
+ import * as Schema from "effect/Schema"
8
+ import * as Glob from "./Glob.ts"
9
+ import * as Grep from "./Grep.ts"
10
+ import { envelope } from "./internal/Declaration.ts"
11
+ import * as Ls from "./Ls.ts"
12
+ import * as Read from "./Read.ts"
13
+
14
+ /**
15
+ * Registry name for the explore flow.
16
+ *
17
+ * @category metadata
18
+ * @since 1.0.0
19
+ */
20
+ export const name = "explore" as const
21
+
22
+ /**
23
+ * Model-facing description of the explore flow.
24
+ *
25
+ * @category metadata
26
+ * @since 1.0.0
27
+ */
28
+ export const description =
29
+ "Investigate the workspace read-only, cite every finding as file:line, report evidence only, and never propose edits."
30
+
31
+ /**
32
+ * Input accepted by the explore flow.
33
+ *
34
+ * @category schemas
35
+ * @since 1.0.0
36
+ */
37
+ export const Input = Schema.Struct({
38
+ prompt: Schema.String.annotate({
39
+ description: "The workspace question to investigate."
40
+ })
41
+ })
42
+
43
+ /**
44
+ * Decoded input accepted by the `explore` flow.
45
+ *
46
+ * @category models
47
+ * @since 1.0.0
48
+ */
49
+ export type Input = typeof Input.Type
50
+
51
+ /**
52
+ * Output returned by the explore flow.
53
+ *
54
+ * @category schemas
55
+ * @since 1.0.0
56
+ */
57
+ export const Output = Schema.Struct({
58
+ findings: Schema.String.annotate({
59
+ description: "Evidence-backed findings with file:line citations."
60
+ })
61
+ })
62
+
63
+ /**
64
+ * Decoded output returned by the `explore` flow.
65
+ *
66
+ * @category models
67
+ * @since 1.0.0
68
+ */
69
+ export type Output = typeof Output.Type
70
+
71
+ /**
72
+ * Static effect envelope for read-only workspace reconnaissance.
73
+ *
74
+ * @category effects
75
+ * @since 1.0.0
76
+ */
77
+ export const effects = envelope({
78
+ tier: "sealed",
79
+ mode: "hermetic",
80
+ reads: ["/**"],
81
+ writes: []
82
+ })
83
+
84
+ /**
85
+ * Narrows the explore effect declaration for one decoded input.
86
+ *
87
+ * @category effects
88
+ * @since 1.0.0
89
+ */
90
+ export const effectsFor = (_input: typeof Input.Type) => effects
91
+
92
+ const flows = Object.freeze(
93
+ [
94
+ Read.flow,
95
+ Ls.flow,
96
+ Glob.flow,
97
+ Grep.flow
98
+ ] as const
99
+ )
100
+
101
+ /**
102
+ * Transitive capabilities of the read-only flows available to explore.
103
+ *
104
+ * @category capabilities
105
+ * @since 1.0.0
106
+ */
107
+ export const capabilities: ReadonlyArray<string> = Object.freeze(
108
+ [...new Set(flows.flatMap((flow) => flow.capabilities))].sort()
109
+ )
110
+
111
+ /**
112
+ * Constructs an explore flow, optionally pinned to a model.
113
+ *
114
+ * Model selection remains optional so the invoking seat can inject its model.
115
+ *
116
+ * @category constructors
117
+ * @since 1.0.0
118
+ */
119
+ export const make = (options: {
120
+ readonly model?: string | undefined
121
+ }) => ({
122
+ name,
123
+ description,
124
+ input: Input,
125
+ output: Output,
126
+ model: options.model,
127
+ flows,
128
+ prompt: description,
129
+ capabilities,
130
+ effects
131
+ } as const)
132
+
133
+ /**
134
+ * Default explore declaration with seat-selected model injection.
135
+ *
136
+ * @category flows
137
+ * @since 1.0.0
138
+ */
139
+ export const flow = make({})