@smthrs/std 0.0.0-stage → 1.0.0-rc.12
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.
- package/CHANGELOG.md +148 -0
- package/LICENSE +21 -0
- package/README.md +156 -2
- package/dist/cjs/ApplyPatch.d.ts +174 -0
- package/dist/cjs/ApplyPatch.d.ts.map +1 -0
- package/dist/cjs/ApplyPatch.js +309 -0
- package/dist/cjs/ApplyPatch.js.map +7 -0
- package/dist/cjs/Bash.d.ts +390 -0
- package/dist/cjs/Bash.d.ts.map +1 -0
- package/dist/cjs/Bash.js +333 -0
- package/dist/cjs/Bash.js.map +7 -0
- package/dist/cjs/Checkpoints.d.ts +322 -0
- package/dist/cjs/Checkpoints.d.ts.map +1 -0
- package/dist/cjs/Checkpoints.js +233 -0
- package/dist/cjs/Checkpoints.js.map +7 -0
- package/dist/cjs/Container.d.ts +132 -0
- package/dist/cjs/Container.d.ts.map +1 -0
- package/dist/cjs/Container.js +113 -0
- package/dist/cjs/Container.js.map +7 -0
- package/dist/cjs/Edit.d.ts +203 -0
- package/dist/cjs/Edit.d.ts.map +1 -0
- package/dist/cjs/Edit.js +258 -0
- package/dist/cjs/Edit.js.map +7 -0
- package/dist/cjs/ExaWebSearch.d.ts +22 -0
- package/dist/cjs/ExaWebSearch.d.ts.map +1 -0
- package/dist/cjs/ExaWebSearch.js +138 -0
- package/dist/cjs/ExaWebSearch.js.map +7 -0
- package/dist/cjs/Explore.d.ts +328 -0
- package/dist/cjs/Explore.d.ts.map +1 -0
- package/dist/cjs/Explore.js +90 -0
- package/dist/cjs/Explore.js.map +7 -0
- package/dist/cjs/Fetch.d.ts +130 -0
- package/dist/cjs/Fetch.d.ts.map +1 -0
- package/dist/cjs/Fetch.js +64 -0
- package/dist/cjs/Fetch.js.map +7 -0
- package/dist/cjs/Glob.d.ts +204 -0
- package/dist/cjs/Glob.d.ts.map +1 -0
- package/dist/cjs/Glob.js +94 -0
- package/dist/cjs/Glob.js.map +7 -0
- package/dist/cjs/Grep.d.ts +347 -0
- package/dist/cjs/Grep.d.ts.map +1 -0
- package/dist/cjs/Grep.js +181 -0
- package/dist/cjs/Grep.js.map +7 -0
- package/dist/cjs/HttpPost.d.ts +130 -0
- package/dist/cjs/HttpPost.d.ts.map +1 -0
- package/dist/cjs/HttpPost.js +72 -0
- package/dist/cjs/HttpPost.js.map +7 -0
- package/dist/cjs/LanguageServer.d.ts +90 -0
- package/dist/cjs/LanguageServer.d.ts.map +1 -0
- package/dist/cjs/LanguageServer.js +60 -0
- package/dist/cjs/LanguageServer.js.map +7 -0
- package/dist/cjs/Ls.d.ts +164 -0
- package/dist/cjs/Ls.d.ts.map +1 -0
- package/dist/cjs/Ls.js +136 -0
- package/dist/cjs/Ls.js.map +7 -0
- package/dist/cjs/Lsp.d.ts +125 -0
- package/dist/cjs/Lsp.d.ts.map +1 -0
- package/dist/cjs/Lsp.js +137 -0
- package/dist/cjs/Lsp.js.map +7 -0
- package/dist/cjs/Manifest.d.ts +918 -0
- package/dist/cjs/Manifest.d.ts.map +1 -0
- package/dist/cjs/Manifest.js +144 -0
- package/dist/cjs/Manifest.js.map +7 -0
- package/dist/cjs/NativeSearch.d.ts +38 -0
- package/dist/cjs/NativeSearch.d.ts.map +1 -0
- package/dist/cjs/NativeSearch.js +326 -0
- package/dist/cjs/NativeSearch.js.map +7 -0
- package/dist/cjs/NodeLanguageServer.d.ts +128 -0
- package/dist/cjs/NodeLanguageServer.d.ts.map +1 -0
- package/dist/cjs/NodeLanguageServer.js +796 -0
- package/dist/cjs/NodeLanguageServer.js.map +7 -0
- package/dist/cjs/PortableSearch.d.ts +36 -0
- package/dist/cjs/PortableSearch.d.ts.map +1 -0
- package/dist/cjs/PortableSearch.js +240 -0
- package/dist/cjs/PortableSearch.js.map +7 -0
- package/dist/cjs/Probe.d.ts +193 -0
- package/dist/cjs/Probe.d.ts.map +1 -0
- package/dist/cjs/Probe.js +134 -0
- package/dist/cjs/Probe.js.map +7 -0
- package/dist/cjs/Read.d.ts +189 -0
- package/dist/cjs/Read.d.ts.map +1 -0
- package/dist/cjs/Read.js +223 -0
- package/dist/cjs/Read.js.map +7 -0
- package/dist/cjs/Relocate.d.ts +73 -0
- package/dist/cjs/Relocate.d.ts.map +1 -0
- package/dist/cjs/Relocate.js +72 -0
- package/dist/cjs/Relocate.js.map +7 -0
- package/dist/cjs/RemoteSearch.d.ts +54 -0
- package/dist/cjs/RemoteSearch.d.ts.map +1 -0
- package/dist/cjs/RemoteSearch.js +134 -0
- package/dist/cjs/RemoteSearch.js.map +7 -0
- package/dist/cjs/Search.d.ts +163 -0
- package/dist/cjs/Search.d.ts.map +1 -0
- package/dist/cjs/Search.js +51 -0
- package/dist/cjs/Search.js.map +7 -0
- package/dist/cjs/SearchConformance.d.ts +115 -0
- package/dist/cjs/SearchConformance.d.ts.map +1 -0
- package/dist/cjs/SearchConformance.js +172 -0
- package/dist/cjs/SearchConformance.js.map +7 -0
- package/dist/cjs/SearchContract.d.ts +114 -0
- package/dist/cjs/SearchContract.d.ts.map +1 -0
- package/dist/cjs/SearchContract.js +339 -0
- package/dist/cjs/SearchContract.js.map +7 -0
- package/dist/cjs/ShellCommand.d.ts +164 -0
- package/dist/cjs/ShellCommand.d.ts.map +1 -0
- package/dist/cjs/ShellCommand.js +102 -0
- package/dist/cjs/ShellCommand.js.map +7 -0
- package/dist/cjs/StdError.d.ts +55 -0
- package/dist/cjs/StdError.d.ts.map +1 -0
- package/dist/cjs/StdError.js +74 -0
- package/dist/cjs/StdError.js.map +7 -0
- package/dist/cjs/TestRun.d.ts +311 -0
- package/dist/cjs/TestRun.d.ts.map +1 -0
- package/dist/cjs/TestRun.js +228 -0
- package/dist/cjs/TestRun.js.map +7 -0
- package/dist/cjs/TestRunner.d.ts +102 -0
- package/dist/cjs/TestRunner.d.ts.map +1 -0
- package/dist/cjs/TestRunner.js +54 -0
- package/dist/cjs/TestRunner.js.map +7 -0
- package/dist/cjs/TreeFingerprint.d.ts +140 -0
- package/dist/cjs/TreeFingerprint.d.ts.map +1 -0
- package/dist/cjs/TreeFingerprint.js +87 -0
- package/dist/cjs/TreeFingerprint.js.map +7 -0
- package/dist/cjs/UpdatePlan.d.ts +152 -0
- package/dist/cjs/UpdatePlan.d.ts.map +1 -0
- package/dist/cjs/UpdatePlan.js +87 -0
- package/dist/cjs/UpdatePlan.js.map +7 -0
- package/dist/cjs/WebFetch.d.ts +134 -0
- package/dist/cjs/WebFetch.d.ts.map +1 -0
- package/dist/cjs/WebFetch.js +140 -0
- package/dist/cjs/WebFetch.js.map +7 -0
- package/dist/cjs/WebSearch.d.ts +181 -0
- package/dist/cjs/WebSearch.d.ts.map +1 -0
- package/dist/cjs/WebSearch.js +86 -0
- package/dist/cjs/WebSearch.js.map +7 -0
- package/dist/cjs/Write.d.ts +147 -0
- package/dist/cjs/Write.d.ts.map +1 -0
- package/dist/cjs/Write.js +122 -0
- package/dist/cjs/Write.js.map +7 -0
- package/dist/cjs/index.d.ts +129 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +101 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/ApplyPatch.d.ts +145 -0
- package/dist/cjs/internal/ApplyPatch.d.ts.map +1 -0
- package/dist/cjs/internal/ApplyPatch.js +462 -0
- package/dist/cjs/internal/ApplyPatch.js.map +7 -0
- package/dist/cjs/internal/CodexText.d.ts +73 -0
- package/dist/cjs/internal/CodexText.d.ts.map +1 -0
- package/dist/cjs/internal/CodexText.js +108 -0
- package/dist/cjs/internal/CodexText.js.map +7 -0
- package/dist/cjs/internal/Declaration.d.ts +49 -0
- package/dist/cjs/internal/Declaration.d.ts.map +1 -0
- package/dist/cjs/internal/Declaration.js +46 -0
- package/dist/cjs/internal/Declaration.js.map +7 -0
- package/dist/cjs/internal/Diagnostics.d.ts +77 -0
- package/dist/cjs/internal/Diagnostics.d.ts.map +1 -0
- package/dist/cjs/internal/Diagnostics.js +89 -0
- package/dist/cjs/internal/Diagnostics.js.map +7 -0
- package/dist/cjs/internal/EnvelopePrecheck.d.ts +69 -0
- package/dist/cjs/internal/EnvelopePrecheck.d.ts.map +1 -0
- package/dist/cjs/internal/EnvelopePrecheck.js +323 -0
- package/dist/cjs/internal/EnvelopePrecheck.js.map +7 -0
- package/dist/cjs/internal/Exec.d.ts +151 -0
- package/dist/cjs/internal/Exec.d.ts.map +1 -0
- package/dist/cjs/internal/Exec.js +207 -0
- package/dist/cjs/internal/Exec.js.map +7 -0
- package/dist/cjs/internal/FileMutation.d.ts +109 -0
- package/dist/cjs/internal/FileMutation.d.ts.map +1 -0
- package/dist/cjs/internal/FileMutation.js +116 -0
- package/dist/cjs/internal/FileMutation.js.map +7 -0
- package/dist/cjs/internal/FsFailure.d.ts +38 -0
- package/dist/cjs/internal/FsFailure.d.ts.map +1 -0
- package/dist/cjs/internal/FsFailure.js +40 -0
- package/dist/cjs/internal/FsFailure.js.map +7 -0
- package/dist/cjs/internal/GitWorktree.d.ts +108 -0
- package/dist/cjs/internal/GitWorktree.d.ts.map +1 -0
- package/dist/cjs/internal/GitWorktree.js +276 -0
- package/dist/cjs/internal/GitWorktree.js.map +7 -0
- package/dist/cjs/internal/Grouping.d.ts +51 -0
- package/dist/cjs/internal/Grouping.d.ts.map +1 -0
- package/dist/cjs/internal/Grouping.js +83 -0
- package/dist/cjs/internal/Grouping.js.map +7 -0
- package/dist/cjs/internal/Html.d.ts +20 -0
- package/dist/cjs/internal/Html.d.ts.map +1 -0
- package/dist/cjs/internal/Html.js +81 -0
- package/dist/cjs/internal/Html.js.map +7 -0
- package/dist/cjs/internal/Http.d.ts +95 -0
- package/dist/cjs/internal/Http.d.ts.map +1 -0
- package/dist/cjs/internal/Http.js +153 -0
- package/dist/cjs/internal/Http.js.map +7 -0
- package/dist/cjs/internal/HttpNetwork.d.ts +27 -0
- package/dist/cjs/internal/HttpNetwork.d.ts.map +1 -0
- package/dist/cjs/internal/HttpNetwork.js +146 -0
- package/dist/cjs/internal/HttpNetwork.js.map +7 -0
- package/dist/cjs/internal/Ignore.d.ts +37 -0
- package/dist/cjs/internal/Ignore.d.ts.map +1 -0
- package/dist/cjs/internal/Ignore.js +100 -0
- package/dist/cjs/internal/Ignore.js.map +7 -0
- package/dist/cjs/internal/LinearRegex.d.ts +19 -0
- package/dist/cjs/internal/LinearRegex.d.ts.map +1 -0
- package/dist/cjs/internal/LinearRegex.js +166 -0
- package/dist/cjs/internal/LinearRegex.js.map +7 -0
- package/dist/cjs/internal/Match.d.ts +85 -0
- package/dist/cjs/internal/Match.d.ts.map +1 -0
- package/dist/cjs/internal/Match.js +99 -0
- package/dist/cjs/internal/Match.js.map +7 -0
- package/dist/cjs/internal/Paths.d.ts +23 -0
- package/dist/cjs/internal/Paths.d.ts.map +1 -0
- package/dist/cjs/internal/Paths.js +52 -0
- package/dist/cjs/internal/Paths.js.map +7 -0
- package/dist/cjs/internal/Preserve.d.ts +25 -0
- package/dist/cjs/internal/Preserve.d.ts.map +1 -0
- package/dist/cjs/internal/Preserve.js +88 -0
- package/dist/cjs/internal/Preserve.js.map +7 -0
- package/dist/cjs/internal/Prune.d.ts +35 -0
- package/dist/cjs/internal/Prune.d.ts.map +1 -0
- package/dist/cjs/internal/Prune.js +54 -0
- package/dist/cjs/internal/Prune.js.map +7 -0
- package/dist/cjs/internal/RemoteTree.d.ts +60 -0
- package/dist/cjs/internal/RemoteTree.d.ts.map +1 -0
- package/dist/cjs/internal/RemoteTree.js +123 -0
- package/dist/cjs/internal/RemoteTree.js.map +7 -0
- package/dist/cjs/internal/SearchContract.d.ts +63 -0
- package/dist/cjs/internal/SearchContract.d.ts.map +1 -0
- package/dist/cjs/internal/SearchContract.js +46 -0
- package/dist/cjs/internal/SearchContract.js.map +7 -0
- package/dist/cjs/internal/Symbols.d.ts +39 -0
- package/dist/cjs/internal/Symbols.d.ts.map +1 -0
- package/dist/cjs/internal/Symbols.js +59 -0
- package/dist/cjs/internal/Symbols.js.map +7 -0
- package/dist/cjs/internal/Tar.d.ts +23 -0
- package/dist/cjs/internal/Tar.d.ts.map +1 -0
- package/dist/cjs/internal/Tar.js +86 -0
- package/dist/cjs/internal/Tar.js.map +7 -0
- package/dist/cjs/internal/TestReport.d.ts +52 -0
- package/dist/cjs/internal/TestReport.d.ts.map +1 -0
- package/dist/cjs/internal/TestReport.js +131 -0
- package/dist/cjs/internal/TestReport.js.map +7 -0
- package/dist/cjs/internal/Text.d.ts +125 -0
- package/dist/cjs/internal/Text.d.ts.map +1 -0
- package/dist/cjs/internal/Text.js +85 -0
- package/dist/cjs/internal/Text.js.map +7 -0
- package/dist/cjs/internal/Url.d.ts +13 -0
- package/dist/cjs/internal/Url.d.ts.map +1 -0
- package/dist/cjs/internal/Url.js +35 -0
- package/dist/cjs/internal/Url.js.map +7 -0
- package/dist/cjs/internal/Walk.d.ts +72 -0
- package/dist/cjs/internal/Walk.d.ts.map +1 -0
- package/dist/cjs/internal/Walk.js +108 -0
- package/dist/cjs/internal/Walk.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/ApplyPatch.d.ts +174 -0
- package/dist/esm/ApplyPatch.d.ts.map +1 -0
- package/dist/esm/ApplyPatch.js +346 -0
- package/dist/esm/ApplyPatch.js.map +1 -0
- package/dist/esm/Bash.d.ts +390 -0
- package/dist/esm/Bash.d.ts.map +1 -0
- package/dist/esm/Bash.js +514 -0
- package/dist/esm/Bash.js.map +1 -0
- package/dist/esm/Checkpoints.d.ts +322 -0
- package/dist/esm/Checkpoints.d.ts.map +1 -0
- package/dist/esm/Checkpoints.js +396 -0
- package/dist/esm/Checkpoints.js.map +1 -0
- package/dist/esm/Container.d.ts +132 -0
- package/dist/esm/Container.d.ts.map +1 -0
- package/dist/esm/Container.js +151 -0
- package/dist/esm/Container.js.map +1 -0
- package/dist/esm/Edit.d.ts +203 -0
- package/dist/esm/Edit.d.ts.map +1 -0
- package/dist/esm/Edit.js +296 -0
- package/dist/esm/Edit.js.map +1 -0
- package/dist/esm/ExaWebSearch.d.ts +22 -0
- package/dist/esm/ExaWebSearch.d.ts.map +1 -0
- package/dist/esm/ExaWebSearch.js +107 -0
- package/dist/esm/ExaWebSearch.js.map +1 -0
- package/dist/esm/Explore.d.ts +328 -0
- package/dist/esm/Explore.d.ts.map +1 -0
- package/dist/esm/Explore.js +106 -0
- package/dist/esm/Explore.js.map +1 -0
- package/dist/esm/Fetch.d.ts +130 -0
- package/dist/esm/Fetch.d.ts.map +1 -0
- package/dist/esm/Fetch.js +91 -0
- package/dist/esm/Fetch.js.map +1 -0
- package/dist/esm/Glob.d.ts +204 -0
- package/dist/esm/Glob.d.ts.map +1 -0
- package/dist/esm/Glob.js +177 -0
- package/dist/esm/Glob.js.map +1 -0
- package/dist/esm/Grep.d.ts +347 -0
- package/dist/esm/Grep.d.ts.map +1 -0
- package/dist/esm/Grep.js +289 -0
- package/dist/esm/Grep.js.map +1 -0
- package/dist/esm/HttpPost.d.ts +130 -0
- package/dist/esm/HttpPost.d.ts.map +1 -0
- package/dist/esm/HttpPost.js +89 -0
- package/dist/esm/HttpPost.js.map +1 -0
- package/dist/esm/LanguageServer.d.ts +90 -0
- package/dist/esm/LanguageServer.d.ts.map +1 -0
- package/dist/esm/LanguageServer.js +57 -0
- package/dist/esm/LanguageServer.js.map +1 -0
- package/dist/esm/Ls.d.ts +164 -0
- package/dist/esm/Ls.d.ts.map +1 -0
- package/dist/esm/Ls.js +178 -0
- package/dist/esm/Ls.js.map +1 -0
- package/dist/esm/Lsp.d.ts +125 -0
- package/dist/esm/Lsp.d.ts.map +1 -0
- package/dist/esm/Lsp.js +165 -0
- package/dist/esm/Lsp.js.map +1 -0
- package/dist/esm/Manifest.d.ts +918 -0
- package/dist/esm/Manifest.d.ts.map +1 -0
- package/dist/esm/Manifest.js +153 -0
- package/dist/esm/Manifest.js.map +1 -0
- package/dist/esm/NativeSearch.d.ts +38 -0
- package/dist/esm/NativeSearch.d.ts.map +1 -0
- package/dist/esm/NativeSearch.js +378 -0
- package/dist/esm/NativeSearch.js.map +1 -0
- package/dist/esm/NodeLanguageServer.d.ts +128 -0
- package/dist/esm/NodeLanguageServer.d.ts.map +1 -0
- package/dist/esm/NodeLanguageServer.js +843 -0
- package/dist/esm/NodeLanguageServer.js.map +1 -0
- package/dist/esm/PortableSearch.d.ts +36 -0
- package/dist/esm/PortableSearch.d.ts.map +1 -0
- package/dist/esm/PortableSearch.js +256 -0
- package/dist/esm/PortableSearch.js.map +1 -0
- package/dist/esm/Probe.d.ts +193 -0
- package/dist/esm/Probe.d.ts.map +1 -0
- package/dist/esm/Probe.js +225 -0
- package/dist/esm/Probe.js.map +1 -0
- package/dist/esm/Read.d.ts +189 -0
- package/dist/esm/Read.d.ts.map +1 -0
- package/dist/esm/Read.js +300 -0
- package/dist/esm/Read.js.map +1 -0
- package/dist/esm/Relocate.d.ts +73 -0
- package/dist/esm/Relocate.d.ts.map +1 -0
- package/dist/esm/Relocate.js +153 -0
- package/dist/esm/Relocate.js.map +1 -0
- package/dist/esm/RemoteSearch.d.ts +54 -0
- package/dist/esm/RemoteSearch.d.ts.map +1 -0
- package/dist/esm/RemoteSearch.js +162 -0
- package/dist/esm/RemoteSearch.js.map +1 -0
- package/dist/esm/Search.d.ts +163 -0
- package/dist/esm/Search.d.ts.map +1 -0
- package/dist/esm/Search.js +47 -0
- package/dist/esm/Search.js.map +1 -0
- package/dist/esm/SearchConformance.d.ts +115 -0
- package/dist/esm/SearchConformance.d.ts.map +1 -0
- package/dist/esm/SearchConformance.js +193 -0
- package/dist/esm/SearchConformance.js.map +1 -0
- package/dist/esm/SearchContract.d.ts +114 -0
- package/dist/esm/SearchContract.d.ts.map +1 -0
- package/dist/esm/SearchContract.js +461 -0
- package/dist/esm/SearchContract.js.map +1 -0
- package/dist/esm/ShellCommand.d.ts +164 -0
- package/dist/esm/ShellCommand.d.ts.map +1 -0
- package/dist/esm/ShellCommand.js +159 -0
- package/dist/esm/ShellCommand.js.map +1 -0
- package/dist/esm/StdError.d.ts +55 -0
- package/dist/esm/StdError.d.ts.map +1 -0
- package/dist/esm/StdError.js +71 -0
- package/dist/esm/StdError.js.map +1 -0
- package/dist/esm/TestRun.d.ts +311 -0
- package/dist/esm/TestRun.d.ts.map +1 -0
- package/dist/esm/TestRun.js +316 -0
- package/dist/esm/TestRun.js.map +1 -0
- package/dist/esm/TestRunner.d.ts +102 -0
- package/dist/esm/TestRunner.d.ts.map +1 -0
- package/dist/esm/TestRunner.js +68 -0
- package/dist/esm/TestRunner.js.map +1 -0
- package/dist/esm/TreeFingerprint.d.ts +140 -0
- package/dist/esm/TreeFingerprint.d.ts.map +1 -0
- package/dist/esm/TreeFingerprint.js +170 -0
- package/dist/esm/TreeFingerprint.js.map +1 -0
- package/dist/esm/UpdatePlan.d.ts +152 -0
- package/dist/esm/UpdatePlan.d.ts.map +1 -0
- package/dist/esm/UpdatePlan.js +129 -0
- package/dist/esm/UpdatePlan.js.map +1 -0
- package/dist/esm/WebFetch.d.ts +134 -0
- package/dist/esm/WebFetch.d.ts.map +1 -0
- package/dist/esm/WebFetch.js +151 -0
- package/dist/esm/WebFetch.js.map +1 -0
- package/dist/esm/WebSearch.d.ts +181 -0
- package/dist/esm/WebSearch.d.ts.map +1 -0
- package/dist/esm/WebSearch.js +134 -0
- package/dist/esm/WebSearch.js.map +1 -0
- package/dist/esm/Write.d.ts +147 -0
- package/dist/esm/Write.d.ts.map +1 -0
- package/dist/esm/Write.js +144 -0
- package/dist/esm/Write.js.map +1 -0
- package/dist/esm/index.d.ts +129 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +129 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/ApplyPatch.d.ts +145 -0
- package/dist/esm/internal/ApplyPatch.d.ts.map +1 -0
- package/dist/esm/internal/ApplyPatch.js +489 -0
- package/dist/esm/internal/ApplyPatch.js.map +1 -0
- package/dist/esm/internal/CodexText.d.ts +73 -0
- package/dist/esm/internal/CodexText.d.ts.map +1 -0
- package/dist/esm/internal/CodexText.js +156 -0
- package/dist/esm/internal/CodexText.js.map +1 -0
- package/dist/esm/internal/Declaration.d.ts +49 -0
- package/dist/esm/internal/Declaration.d.ts.map +1 -0
- package/dist/esm/internal/Declaration.js +42 -0
- package/dist/esm/internal/Declaration.js.map +1 -0
- package/dist/esm/internal/Diagnostics.d.ts +77 -0
- package/dist/esm/internal/Diagnostics.d.ts.map +1 -0
- package/dist/esm/internal/Diagnostics.js +99 -0
- package/dist/esm/internal/Diagnostics.js.map +1 -0
- package/dist/esm/internal/EnvelopePrecheck.d.ts +69 -0
- package/dist/esm/internal/EnvelopePrecheck.d.ts.map +1 -0
- package/dist/esm/internal/EnvelopePrecheck.js +426 -0
- package/dist/esm/internal/EnvelopePrecheck.js.map +1 -0
- package/dist/esm/internal/Exec.d.ts +151 -0
- package/dist/esm/internal/Exec.d.ts.map +1 -0
- package/dist/esm/internal/Exec.js +285 -0
- package/dist/esm/internal/Exec.js.map +1 -0
- package/dist/esm/internal/FileMutation.d.ts +109 -0
- package/dist/esm/internal/FileMutation.d.ts.map +1 -0
- package/dist/esm/internal/FileMutation.js +123 -0
- package/dist/esm/internal/FileMutation.js.map +1 -0
- package/dist/esm/internal/FsFailure.d.ts +38 -0
- package/dist/esm/internal/FsFailure.d.ts.map +1 -0
- package/dist/esm/internal/FsFailure.js +39 -0
- package/dist/esm/internal/FsFailure.js.map +1 -0
- package/dist/esm/internal/GitWorktree.d.ts +108 -0
- package/dist/esm/internal/GitWorktree.d.ts.map +1 -0
- package/dist/esm/internal/GitWorktree.js +352 -0
- package/dist/esm/internal/GitWorktree.js.map +1 -0
- package/dist/esm/internal/Grouping.d.ts +51 -0
- package/dist/esm/internal/Grouping.d.ts.map +1 -0
- package/dist/esm/internal/Grouping.js +99 -0
- package/dist/esm/internal/Grouping.js.map +1 -0
- package/dist/esm/internal/Html.d.ts +20 -0
- package/dist/esm/internal/Html.d.ts.map +1 -0
- package/dist/esm/internal/Html.js +70 -0
- package/dist/esm/internal/Html.js.map +1 -0
- package/dist/esm/internal/Http.d.ts +95 -0
- package/dist/esm/internal/Http.d.ts.map +1 -0
- package/dist/esm/internal/Http.js +154 -0
- package/dist/esm/internal/Http.js.map +1 -0
- package/dist/esm/internal/HttpNetwork.d.ts +27 -0
- package/dist/esm/internal/HttpNetwork.d.ts.map +1 -0
- package/dist/esm/internal/HttpNetwork.js +114 -0
- package/dist/esm/internal/HttpNetwork.js.map +1 -0
- package/dist/esm/internal/Ignore.d.ts +37 -0
- package/dist/esm/internal/Ignore.d.ts.map +1 -0
- package/dist/esm/internal/Ignore.js +128 -0
- package/dist/esm/internal/Ignore.js.map +1 -0
- package/dist/esm/internal/LinearRegex.d.ts +19 -0
- package/dist/esm/internal/LinearRegex.d.ts.map +1 -0
- package/dist/esm/internal/LinearRegex.js +176 -0
- package/dist/esm/internal/LinearRegex.js.map +1 -0
- package/dist/esm/internal/Match.d.ts +85 -0
- package/dist/esm/internal/Match.d.ts.map +1 -0
- package/dist/esm/internal/Match.js +142 -0
- package/dist/esm/internal/Match.js.map +1 -0
- package/dist/esm/internal/Paths.d.ts +23 -0
- package/dist/esm/internal/Paths.d.ts.map +1 -0
- package/dist/esm/internal/Paths.js +40 -0
- package/dist/esm/internal/Paths.js.map +1 -0
- package/dist/esm/internal/Preserve.d.ts +25 -0
- package/dist/esm/internal/Preserve.d.ts.map +1 -0
- package/dist/esm/internal/Preserve.js +70 -0
- package/dist/esm/internal/Preserve.js.map +1 -0
- package/dist/esm/internal/Prune.d.ts +35 -0
- package/dist/esm/internal/Prune.d.ts.map +1 -0
- package/dist/esm/internal/Prune.js +60 -0
- package/dist/esm/internal/Prune.js.map +1 -0
- package/dist/esm/internal/RemoteTree.d.ts +60 -0
- package/dist/esm/internal/RemoteTree.d.ts.map +1 -0
- package/dist/esm/internal/RemoteTree.js +132 -0
- package/dist/esm/internal/RemoteTree.js.map +1 -0
- package/dist/esm/internal/SearchContract.d.ts +63 -0
- package/dist/esm/internal/SearchContract.d.ts.map +1 -0
- package/dist/esm/internal/SearchContract.js +66 -0
- package/dist/esm/internal/SearchContract.js.map +1 -0
- package/dist/esm/internal/Symbols.d.ts +39 -0
- package/dist/esm/internal/Symbols.d.ts.map +1 -0
- package/dist/esm/internal/Symbols.js +79 -0
- package/dist/esm/internal/Symbols.js.map +1 -0
- package/dist/esm/internal/Tar.d.ts +23 -0
- package/dist/esm/internal/Tar.d.ts.map +1 -0
- package/dist/esm/internal/Tar.js +97 -0
- package/dist/esm/internal/Tar.js.map +1 -0
- package/dist/esm/internal/TestReport.d.ts +52 -0
- package/dist/esm/internal/TestReport.d.ts.map +1 -0
- package/dist/esm/internal/TestReport.js +172 -0
- package/dist/esm/internal/TestReport.js.map +1 -0
- package/dist/esm/internal/Text.d.ts +125 -0
- package/dist/esm/internal/Text.d.ts.map +1 -0
- package/dist/esm/internal/Text.js +141 -0
- package/dist/esm/internal/Text.js.map +1 -0
- package/dist/esm/internal/Url.d.ts +13 -0
- package/dist/esm/internal/Url.d.ts.map +1 -0
- package/dist/esm/internal/Url.js +27 -0
- package/dist/esm/internal/Url.js.map +1 -0
- package/dist/esm/internal/Walk.d.ts +72 -0
- package/dist/esm/internal/Walk.d.ts.map +1 -0
- package/dist/esm/internal/Walk.js +126 -0
- package/dist/esm/internal/Walk.js.map +1 -0
- package/docs/README.md +119 -0
- package/docs/api.md +499 -0
- package/docs/concepts/effects-and-capabilities.md +138 -0
- package/docs/concepts/flows-and-handlers.md +115 -0
- package/docs/concepts/limits-and-disclosure.md +105 -0
- package/docs/concepts/search-contract.md +182 -0
- package/docs/guides/bind-the-standard-flows.md +116 -0
- package/docs/guides/implement-a-search-peer.md +133 -0
- package/docs/guides/pin-a-checkpoint.md +161 -0
- package/docs/guides/query-a-language-server.md +257 -0
- package/docs/guides/reach-the-network.md +141 -0
- package/docs/guides/read-and-edit-a-file.md +240 -0
- package/docs/guides/run-a-shell-command.md +236 -0
- package/docs/guides/run-the-test-suite.md +154 -0
- package/docs/guides/search-a-workspace.md +148 -0
- package/docs/installation.md +115 -0
- package/docs/quickstart.md +125 -0
- package/docs/reference/flows.md +556 -0
- package/docs/troubleshooting.md +347 -0
- package/package.json +449 -3
- package/src/ApplyPatch.ts +458 -0
- package/src/Bash.ts +619 -0
- package/src/Checkpoints.ts +589 -0
- package/src/Container.ts +212 -0
- package/src/Edit.ts +366 -0
- package/src/ExaWebSearch.ts +145 -0
- package/src/Explore.ts +139 -0
- package/src/Fetch.ts +117 -0
- package/src/Glob.ts +200 -0
- package/src/Grep.ts +320 -0
- package/src/HttpPost.ts +120 -0
- package/src/LanguageServer.ts +110 -0
- package/src/Ls.ts +228 -0
- package/src/Lsp.ts +184 -0
- package/src/Manifest.ts +162 -0
- package/src/NativeSearch.ts +457 -0
- package/src/NodeLanguageServer.ts +1148 -0
- package/src/PortableSearch.ts +284 -0
- package/src/Probe.ts +284 -0
- package/src/Read.ts +359 -0
- package/src/Relocate.ts +166 -0
- package/src/RemoteSearch.ts +199 -0
- package/src/Search.ts +185 -0
- package/src/SearchConformance.ts +288 -0
- package/src/SearchContract.ts +489 -0
- package/src/ShellCommand.ts +201 -0
- package/src/StdError.ts +80 -0
- package/src/TestRun.ts +401 -0
- package/src/TestRunner.ts +119 -0
- package/src/TreeFingerprint.ts +200 -0
- package/src/UpdatePlan.ts +171 -0
- package/src/WebFetch.ts +194 -0
- package/src/WebSearch.ts +165 -0
- package/src/Write.ts +195 -0
- package/src/index.ts +157 -0
- package/src/internal/ApplyPatch.ts +601 -0
- package/src/internal/CodexText.ts +182 -0
- package/src/internal/Declaration.ts +60 -0
- package/src/internal/Diagnostics.ts +134 -0
- package/src/internal/EnvelopePrecheck.ts +489 -0
- package/src/internal/Exec.ts +427 -0
- package/src/internal/FileMutation.ts +231 -0
- package/src/internal/FsFailure.ts +51 -0
- package/src/internal/GitWorktree.ts +491 -0
- package/src/internal/Grouping.ts +106 -0
- package/src/internal/Html.ts +87 -0
- package/src/internal/Http.ts +209 -0
- package/src/internal/HttpNetwork.ts +153 -0
- package/src/internal/Ignore.ts +135 -0
- package/src/internal/LinearRegex.ts +173 -0
- package/src/internal/Match.ts +172 -0
- package/src/internal/Paths.ts +42 -0
- package/src/internal/Preserve.ts +108 -0
- package/src/internal/Prune.ts +62 -0
- package/src/internal/RemoteTree.ts +159 -0
- package/src/internal/SearchContract.ts +77 -0
- package/src/internal/Symbols.ts +88 -0
- package/src/internal/Tar.ts +95 -0
- package/src/internal/TestReport.ts +194 -0
- package/src/internal/Text.ts +185 -0
- package/src/internal/Url.ts +23 -0
- package/src/internal/Walk.ts +176 -0
package/src/Read.ts
ADDED
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read flow declaration and portable handler.
|
|
3
|
+
*
|
|
4
|
+
* `content` is raw file text. It used to be rendered as `NNN\t<line>`, and that
|
|
5
|
+
* rendering was the single most expensive tool defect measured on the 45-instance
|
|
6
|
+
* SWE-bench trace program: an anchor copied out of a read carried the gutter, so
|
|
7
|
+
* every `edit` built from a read missed, and every cell that wanted a literal
|
|
8
|
+
* line had to strip the prefix in JavaScript first. Two instances (django-13346,
|
|
9
|
+
* django-14351) spent whole frames writing string surgery against text the file
|
|
10
|
+
* does not contain. Line numbers are facts about the page, so they are page
|
|
11
|
+
* fields — `startLine` and `endLine` — and never bytes inside the text.
|
|
12
|
+
*
|
|
13
|
+
* Every line in `content` is a whole line: a page cut short by the byte budget
|
|
14
|
+
* drops its trailing partial line rather than handing back a fragment that looks
|
|
15
|
+
* like an anchor and is not one. CRLF lines retain their trailing CR; only
|
|
16
|
+
* the page's final LF is omitted.
|
|
17
|
+
*
|
|
18
|
+
* @since 1.0.0
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import * as Effect from "effect/Effect"
|
|
22
|
+
import * as FileSystem from "effect/FileSystem"
|
|
23
|
+
import * as Option from "effect/Option"
|
|
24
|
+
import * as Schema from "effect/Schema"
|
|
25
|
+
import { capability, envelope } from "./internal/Declaration.ts"
|
|
26
|
+
import * as FileMutation from "./internal/FileMutation.ts"
|
|
27
|
+
import * as FsFailure from "./internal/FsFailure.ts"
|
|
28
|
+
import { DEFAULT_READ_LIMIT, MAX_LINE_CHARS, MAX_OUTPUT_BYTES, notice, slice, truncateBytes } from "./internal/Text.ts"
|
|
29
|
+
import * as StdError from "./StdError.ts"
|
|
30
|
+
|
|
31
|
+
export { Preconditions, ReadSession, type VersionedFileSystem } from "./internal/FileMutation.ts"
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Registry name for the read flow.
|
|
35
|
+
*
|
|
36
|
+
* @category identifiers
|
|
37
|
+
* @since 1.0.0
|
|
38
|
+
*/
|
|
39
|
+
export const name = "read"
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Model-facing description of the read flow.
|
|
43
|
+
*
|
|
44
|
+
* @category descriptions
|
|
45
|
+
* @since 1.0.0
|
|
46
|
+
*/
|
|
47
|
+
export const description =
|
|
48
|
+
"Read a text file by 1-based offset and limit. content is RAW file text with no line-number prefixes, so any line of it is an edit anchor as it stands; the numbers are startLine/endLine."
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Input schema for the read flow.
|
|
52
|
+
*
|
|
53
|
+
* @category schemas
|
|
54
|
+
* @since 1.0.0
|
|
55
|
+
*/
|
|
56
|
+
export const Input = Schema.Struct({
|
|
57
|
+
path: Schema.String.annotate({ description: "Path of the text file to read" }),
|
|
58
|
+
offset: Schema.optional(Schema.Int.check(Schema.isGreaterThanOrEqualTo(1))).annotate({
|
|
59
|
+
description: "1-based line offset"
|
|
60
|
+
}),
|
|
61
|
+
limit: Schema.optional(Schema.Int.check(Schema.isGreaterThanOrEqualTo(1))).annotate({
|
|
62
|
+
description: "Maximum number of lines to return"
|
|
63
|
+
})
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Decoded input accepted by the `read` flow.
|
|
68
|
+
*
|
|
69
|
+
* @category models
|
|
70
|
+
* @since 1.0.0
|
|
71
|
+
*/
|
|
72
|
+
export type Input = typeof Input.Type
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Output schema for the read flow.
|
|
76
|
+
*
|
|
77
|
+
* @category schemas
|
|
78
|
+
* @since 1.0.0
|
|
79
|
+
*/
|
|
80
|
+
export const Output = Schema.Struct({
|
|
81
|
+
content: Schema.String.annotate({
|
|
82
|
+
description: "Raw page text, preserving CR bytes and omitting the final LF; never line-number prefixed"
|
|
83
|
+
}),
|
|
84
|
+
startLine: Schema.Number.annotate({ description: "First returned 1-based line number" }),
|
|
85
|
+
endLine: Schema.Number.annotate({
|
|
86
|
+
description: "Last returned 1-based line number, or startLine - 1 when no lines are returned"
|
|
87
|
+
}),
|
|
88
|
+
totalLines: Schema.Number.annotate({ description: "Total number of source lines" }),
|
|
89
|
+
truncated: Schema.Boolean.annotate({ description: "Whether displayed output was truncated" }),
|
|
90
|
+
notice: Schema.optional(Schema.String.annotate({ description: "Truncation disclosure" }))
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Decoded output returned by the `read` flow.
|
|
95
|
+
*
|
|
96
|
+
* @category models
|
|
97
|
+
* @since 1.0.0
|
|
98
|
+
*/
|
|
99
|
+
export type Output = typeof Output.Type
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Static conservative effect envelope for the read flow.
|
|
103
|
+
*
|
|
104
|
+
* @category effects
|
|
105
|
+
* @since 1.0.0
|
|
106
|
+
*/
|
|
107
|
+
export const effects = envelope({
|
|
108
|
+
tier: "sealed",
|
|
109
|
+
mode: "hermetic",
|
|
110
|
+
reads: ["/**"],
|
|
111
|
+
writes: []
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Narrows the read effect envelope to one input path.
|
|
116
|
+
*
|
|
117
|
+
* @category effects
|
|
118
|
+
* @since 1.0.0
|
|
119
|
+
*/
|
|
120
|
+
export const effectsFor = (input: typeof Input.Type) =>
|
|
121
|
+
envelope({
|
|
122
|
+
tier: "sealed",
|
|
123
|
+
mode: "hermetic",
|
|
124
|
+
reads: [input.path],
|
|
125
|
+
writes: []
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Capabilities required by the read flow.
|
|
130
|
+
*
|
|
131
|
+
* @category capabilities
|
|
132
|
+
* @since 1.0.0
|
|
133
|
+
*/
|
|
134
|
+
export const capabilities = [capability("fs:read", "/**")]
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Declaration-only read 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 = "reads" 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: "reading", success: "read", failure: "failed to read" },
|
|
170
|
+
subject: "path",
|
|
171
|
+
result: "read"
|
|
172
|
+
} as const
|
|
173
|
+
|
|
174
|
+
const clipLine = (line: string): string => {
|
|
175
|
+
let scalars = 0
|
|
176
|
+
let end = 0
|
|
177
|
+
for (const scalar of line) {
|
|
178
|
+
if (scalars === MAX_LINE_CHARS) return line.slice(0, end)
|
|
179
|
+
scalars++
|
|
180
|
+
end += scalar.length
|
|
181
|
+
}
|
|
182
|
+
return line
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* The largest file `read` loads.
|
|
187
|
+
*
|
|
188
|
+
* `read` decodes the whole file to count its lines, so the file is held in
|
|
189
|
+
* memory twice over: its bytes and a UTF-16 string. Past this bound a page
|
|
190
|
+
* read would cost the host gigabytes for a window of a few thousand lines,
|
|
191
|
+
* and past 2 GiB Node cannot load the file at all.
|
|
192
|
+
*
|
|
193
|
+
* @category constants
|
|
194
|
+
* @since 1.0.0
|
|
195
|
+
*/
|
|
196
|
+
export const MAX_READ_FILE_BYTES = 64 * 1024 * 1024
|
|
197
|
+
|
|
198
|
+
const fileError = (path: string) => FsFailure.reading(path, `File not found: ${path}`)
|
|
199
|
+
|
|
200
|
+
const sharedPrefix = (left: string, right: string): number => {
|
|
201
|
+
let index = 0
|
|
202
|
+
while (index < left.length && index < right.length && left[index] === right[index]) index++
|
|
203
|
+
return index
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Where a guessed relative path stops existing, and what is there instead.
|
|
208
|
+
*
|
|
209
|
+
* A worker that guesses `packages/smithers/flow/src/Flow.ts` learns nothing
|
|
210
|
+
* from "not found" and guesses again. Naming the nearest directory that exists
|
|
211
|
+
* and its entries, closest name first, turns the next call into a choice.
|
|
212
|
+
* Absolute paths and paths that climb out with `..` get no listing: the call
|
|
213
|
+
* declared one file, and the working tree is the only place a listing is
|
|
214
|
+
* already the caller's to read.
|
|
215
|
+
*/
|
|
216
|
+
const nearest = (
|
|
217
|
+
fileSystem: FileSystem.FileSystem,
|
|
218
|
+
path: string
|
|
219
|
+
): Effect.Effect<string> =>
|
|
220
|
+
Effect.gen(function*() {
|
|
221
|
+
const segments = path.split("/").filter((segment) => segment !== "" && segment !== ".")
|
|
222
|
+
if (path.startsWith("/") || segments.includes("..")) return ""
|
|
223
|
+
for (let depth = segments.length - 1; depth >= 0; depth--) {
|
|
224
|
+
const directory = segments.slice(0, depth).join("/")
|
|
225
|
+
const entries = yield* fileSystem.readDirectory(directory === "" ? "." : directory).pipe(Effect.option)
|
|
226
|
+
if (Option.isNone(entries)) continue
|
|
227
|
+
const missing = segments[depth]!.toLowerCase()
|
|
228
|
+
const ranked = entries.value
|
|
229
|
+
.filter((entry) => !entry.startsWith("."))
|
|
230
|
+
.map((entry) => ({ entry, score: sharedPrefix(entry.toLowerCase(), missing) }))
|
|
231
|
+
.sort((left, right) => right.score - left.score)
|
|
232
|
+
.map(({ entry }) => entry)
|
|
233
|
+
if (ranked.length === 0) return ""
|
|
234
|
+
const shown = ranked.slice(0, 12).join(", ")
|
|
235
|
+
const more = ranked.length > 12 ? ` and ${ranked.length - 12} more` : ""
|
|
236
|
+
return `. ${directory === "" ? "The working directory" : directory} holds: ${shown}${more}.`
|
|
237
|
+
}
|
|
238
|
+
return ""
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
const missingFile = (fileSystem: FileSystem.FileSystem, path: string) =>
|
|
242
|
+
Effect.flatMap(nearest(fileSystem, path), (hint) =>
|
|
243
|
+
Effect.fail(
|
|
244
|
+
new StdError.StdError({
|
|
245
|
+
code: "not_found",
|
|
246
|
+
message: `File not found: ${path}${hint}`,
|
|
247
|
+
path
|
|
248
|
+
})
|
|
249
|
+
))
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Reads, validates, and renders one page of a UTF-8 text file.
|
|
253
|
+
*
|
|
254
|
+
* The kernel filesystem exposes bytes rather than a guaranteed UTF-8 string,
|
|
255
|
+
* so decoding is deliberately fatal to keep binary input in the typed channel.
|
|
256
|
+
*
|
|
257
|
+
* @category handlers
|
|
258
|
+
* @since 1.0.0
|
|
259
|
+
*/
|
|
260
|
+
export const run = Effect.fn("Read.run")(function*(
|
|
261
|
+
input: typeof Input.Type
|
|
262
|
+
): Effect.fn.Return<typeof Output.Type, StdError.StdError, FileSystem.FileSystem> {
|
|
263
|
+
const fileSystem = yield* FileSystem.FileSystem
|
|
264
|
+
const info = yield* fileSystem.stat(input.path).pipe(
|
|
265
|
+
Effect.catchTag(
|
|
266
|
+
"PlatformError",
|
|
267
|
+
(error) =>
|
|
268
|
+
error.reason._tag === "NotFound"
|
|
269
|
+
? missingFile(fileSystem, input.path)
|
|
270
|
+
: Effect.fail(fileError(input.path)(error))
|
|
271
|
+
)
|
|
272
|
+
)
|
|
273
|
+
if (info.type === "Directory") {
|
|
274
|
+
return yield* Effect.fail(
|
|
275
|
+
new StdError.StdError({
|
|
276
|
+
code: "is_directory",
|
|
277
|
+
message: `Cannot read a directory: ${input.path}`,
|
|
278
|
+
path: input.path
|
|
279
|
+
})
|
|
280
|
+
)
|
|
281
|
+
}
|
|
282
|
+
if (info.type !== "File") {
|
|
283
|
+
return yield* Effect.fail(
|
|
284
|
+
new StdError.StdError({
|
|
285
|
+
code: "not_found",
|
|
286
|
+
message: `File not found: ${input.path}`,
|
|
287
|
+
path: input.path
|
|
288
|
+
})
|
|
289
|
+
)
|
|
290
|
+
}
|
|
291
|
+
const size = Number(info.size)
|
|
292
|
+
if (size > MAX_READ_FILE_BYTES) {
|
|
293
|
+
return yield* Effect.fail(
|
|
294
|
+
new StdError.StdError({
|
|
295
|
+
code: "response_too_large",
|
|
296
|
+
message:
|
|
297
|
+
`${input.path} is ${size} bytes, over the ${MAX_READ_FILE_BYTES}-byte read limit; search it with grep or print a line range with bash`,
|
|
298
|
+
path: input.path
|
|
299
|
+
})
|
|
300
|
+
)
|
|
301
|
+
}
|
|
302
|
+
const bytes = yield* fileSystem.readFile(input.path).pipe(Effect.mapError(fileError(input.path)))
|
|
303
|
+
if (bytes.includes(0)) {
|
|
304
|
+
return yield* Effect.fail(
|
|
305
|
+
new StdError.StdError({
|
|
306
|
+
code: "binary_file",
|
|
307
|
+
message: `Cannot read binary file: ${input.path}`,
|
|
308
|
+
path: input.path
|
|
309
|
+
})
|
|
310
|
+
)
|
|
311
|
+
}
|
|
312
|
+
const text = yield* Effect.try({
|
|
313
|
+
try: () => new TextDecoder("utf-8", { fatal: true }).decode(bytes),
|
|
314
|
+
catch: () =>
|
|
315
|
+
new StdError.StdError({
|
|
316
|
+
code: "binary_file",
|
|
317
|
+
message: `File is not valid UTF-8: ${input.path}`,
|
|
318
|
+
path: input.path
|
|
319
|
+
})
|
|
320
|
+
})
|
|
321
|
+
const offset = input.offset ?? 1
|
|
322
|
+
const page = slice(text, { offset, limit: input.limit ?? DEFAULT_READ_LIMIT })
|
|
323
|
+
// An empty file has no lines, and reading one is not an out-of-range read:
|
|
324
|
+
// the caller asked for the first page and there is nothing on it. Only an
|
|
325
|
+
// offset past the first line of a file that has none is out of range.
|
|
326
|
+
if (offset > Math.max(page.totalLines, 1)) {
|
|
327
|
+
return yield* Effect.fail(
|
|
328
|
+
new StdError.StdError({
|
|
329
|
+
code: "offset_out_of_range",
|
|
330
|
+
message: `Line offset ${offset} is outside ${input.path}`,
|
|
331
|
+
path: input.path
|
|
332
|
+
})
|
|
333
|
+
)
|
|
334
|
+
}
|
|
335
|
+
const lines = page.lines.map(clipLine)
|
|
336
|
+
const longLinesTruncated = lines.some((line, index) => line !== page.lines[index])
|
|
337
|
+
const rendered = truncateBytes(lines.join("\n"), MAX_OUTPUT_BYTES, { keep: "head" })
|
|
338
|
+
// A byte budget cuts mid-line. A partial line reads like an anchor and is not
|
|
339
|
+
// one, so the page ends at the last whole line it could afford.
|
|
340
|
+
const whole = rendered.truncated
|
|
341
|
+
? rendered.text.slice(0, Math.max(0, rendered.text.lastIndexOf("\n")))
|
|
342
|
+
: rendered.text
|
|
343
|
+
// Each clipped line fits the byte budget, so a truncated page retains at least one whole line.
|
|
344
|
+
const shown = rendered.truncated ? whole.split("\n").length : lines.length
|
|
345
|
+
const endLine = page.startLine + shown - 1
|
|
346
|
+
const truncated = longLinesTruncated || rendered.truncated || page.endLine < page.totalLines
|
|
347
|
+
const clipped = longLinesTruncated
|
|
348
|
+
? ` Lines longer than ${MAX_LINE_CHARS} Unicode scalar values are clipped, so such a line is not an edit anchor.`
|
|
349
|
+
: ""
|
|
350
|
+
yield* FileMutation.recordRead(fileSystem, input.path, bytes)
|
|
351
|
+
return {
|
|
352
|
+
content: whole,
|
|
353
|
+
startLine: page.startLine,
|
|
354
|
+
endLine,
|
|
355
|
+
totalLines: page.totalLines,
|
|
356
|
+
truncated,
|
|
357
|
+
...(truncated ? { notice: `${notice("lines", shown, page.totalLines)}${clipped}` } : {})
|
|
358
|
+
}
|
|
359
|
+
})
|
package/src/Relocate.ts
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What can be pointed at a checkpoint, and what cannot.
|
|
3
|
+
*
|
|
4
|
+
* {@link relocate} is the closed answer, and it is the half of the checkpoint
|
|
5
|
+
* feature that tracks the flows rather than git: it knows that `bash` carries
|
|
6
|
+
* its working directory in `cwd` and that `read`, `ls`, `grep` and `glob` carry
|
|
7
|
+
* their subject in `path`, `path`, `root` and `root`. `Checkpoints` changes when
|
|
8
|
+
* git does; this changes when one of those five input shapes does, which is why
|
|
9
|
+
* it is a module of its own. `Relocate.test.ts` decodes every rewritten input
|
|
10
|
+
* with the flow's own `Input` schema, so a renamed field fails there rather than
|
|
11
|
+
* silently relocating nothing.
|
|
12
|
+
*
|
|
13
|
+
* `bash` names *where it runs*, so it is relocated by its `cwd` — into the
|
|
14
|
+
* checkpoint, and into the same subdirectory of it the call asked for, because a
|
|
15
|
+
* check declared in `tests/` that silently ran at the top would come back
|
|
16
|
+
* failing for a reason nobody chose. `read`, `ls`, `grep` and `glob` name *what
|
|
17
|
+
* they touch* relative to the workspace root, so they are relocated by prefixing
|
|
18
|
+
* that root — and only when the path they name stays inside the tree, because an
|
|
19
|
+
* absolute path in these runs is a container path the host cannot rebase and a
|
|
20
|
+
* `..` path is the live tree under another name. Every other flow answers
|
|
21
|
+
* `checkpoint_unsupported` through the harness, including `test`, which already
|
|
22
|
+
* has `against: "base"` for exactly this question and would otherwise have two
|
|
23
|
+
* mechanisms that can disagree.
|
|
24
|
+
*
|
|
25
|
+
* @since 1.0.0
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import type { Schema } from "effect"
|
|
29
|
+
import type { Materialized } from "./Checkpoints.ts"
|
|
30
|
+
import { withoutTrailingSlash } from "./internal/Paths.ts"
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The flows whose input names where they run or what they read, and the field
|
|
34
|
+
* that says so.
|
|
35
|
+
*
|
|
36
|
+
* A closed table rather than a per-flow hook, because the set is small and the
|
|
37
|
+
* rule for admitting one is exact: the field has to name a location the whole
|
|
38
|
+
* call is relative to. `bash` runs in a directory; the four readers resolve
|
|
39
|
+
* their subject against the workspace root. Everything else — an edit, a patch,
|
|
40
|
+
* a web fetch, a memory write — either names no location or writes, and both
|
|
41
|
+
* are refused above this module.
|
|
42
|
+
*
|
|
43
|
+
* `test` is deliberately absent. It answers this exact question already, with
|
|
44
|
+
* `against: "base"`, and a second mechanism pointed at the same tree is a way
|
|
45
|
+
* for two answers to disagree.
|
|
46
|
+
*/
|
|
47
|
+
const located: Readonly<Record<string, { readonly field: string; readonly kind: "cwd" | "path" }>> = {
|
|
48
|
+
bash: { field: "cwd", kind: "cwd" },
|
|
49
|
+
read: { field: "path", kind: "path" },
|
|
50
|
+
ls: { field: "path", kind: "path" },
|
|
51
|
+
grep: { field: "root", kind: "path" },
|
|
52
|
+
glob: { field: "root", kind: "path" }
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Why one input could not be pointed at a checkpoint.
|
|
57
|
+
*
|
|
58
|
+
* @category models
|
|
59
|
+
* @since 1.0.0
|
|
60
|
+
*/
|
|
61
|
+
export type Relocation =
|
|
62
|
+
| { readonly _tag: "Relocated"; readonly input: Schema.Json }
|
|
63
|
+
| { readonly _tag: "UnsupportedFlow" }
|
|
64
|
+
| { readonly _tag: "AbsolutePath"; readonly path: string }
|
|
65
|
+
| { readonly _tag: "OutsideTree"; readonly path: string }
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Resolves `.` and `..` inside a relative path, or answers `undefined` when the
|
|
69
|
+
* path climbs out of whatever it would be joined under.
|
|
70
|
+
*
|
|
71
|
+
* This is the whole of the isolation the reader rule can enforce, and it is not
|
|
72
|
+
* optional. Prefixing blindly turns `../../mod.py` into
|
|
73
|
+
* `.flows-checkpoints/cp-1-0/../../mod.py`, which is a path back into the live
|
|
74
|
+
* tree — so the cell would read the work it is trying to take a baseline
|
|
75
|
+
* against, the journal would record that reading under the checkpoint it named,
|
|
76
|
+
* and the call key folds the checkpoint in, so the live reading would replay as
|
|
77
|
+
* a pinned one forever. A proof built on it is a proof of nothing, which is the
|
|
78
|
+
* exact failure this module exists to abolish.
|
|
79
|
+
*/
|
|
80
|
+
const contained = (path: string): string | undefined => {
|
|
81
|
+
const parts: Array<string> = []
|
|
82
|
+
for (const segment of path.split("/")) {
|
|
83
|
+
if (segment === "" || segment === ".") continue
|
|
84
|
+
if (segment !== "..") {
|
|
85
|
+
parts.push(segment)
|
|
86
|
+
continue
|
|
87
|
+
}
|
|
88
|
+
if (parts.length === 0) return undefined
|
|
89
|
+
parts.pop()
|
|
90
|
+
}
|
|
91
|
+
return parts.join("/")
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The part of `declared` that names a place inside `root`, or `undefined` when
|
|
96
|
+
* it names somewhere the checkpoint does not hold a copy of.
|
|
97
|
+
*
|
|
98
|
+
* A relative path is already workspace-relative. An absolute one is compared
|
|
99
|
+
* against the root on the side that issued it — a container call names the
|
|
100
|
+
* mount, a host call names this machine — because that is the only prefix the
|
|
101
|
+
* store can strip without guessing.
|
|
102
|
+
*/
|
|
103
|
+
const within = (root: string, declared: string): string | undefined => {
|
|
104
|
+
if (!declared.startsWith("/")) return contained(declared)
|
|
105
|
+
if (withoutTrailingSlash(declared) === root) return ""
|
|
106
|
+
return declared.startsWith(`${root}/`) ? contained(declared.slice(root.length + 1)) : undefined
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Rewrites one call's input so the call runs against a materialized checkpoint.
|
|
111
|
+
*
|
|
112
|
+
* Returns the rewritten input, or the reason there is none. A `bash` call runs
|
|
113
|
+
* in the checkpoint's directory — from the *guest* side when it names a
|
|
114
|
+
* container, because that is the path the container will be given — and keeps
|
|
115
|
+
* whatever subdirectory it asked for: a check declared in `tests/` runs in the
|
|
116
|
+
* checkpoint's `tests/`. A working directory the checkpoint holds no copy of,
|
|
117
|
+
* such as somewhere else on the machine, becomes the checkpoint's own top,
|
|
118
|
+
* because a tree is all this can offer and there is no subpath in it to keep.
|
|
119
|
+
*
|
|
120
|
+
* A reader takes the checkpoint's workspace-relative directory as the prefix of
|
|
121
|
+
* what it names, because these flows resolve their subject against the
|
|
122
|
+
* workspace root and the checkpoint is a directory under it.
|
|
123
|
+
*
|
|
124
|
+
* Two paths are refused rather than rewritten, and both for the same reason —
|
|
125
|
+
* the host would otherwise hand back a reading of a tree the cell did not name.
|
|
126
|
+
* An absolute path in these runs is a container path, and the host cannot know
|
|
127
|
+
* which prefix of it names the tree. A relative path that climbs past the
|
|
128
|
+
* checkpoint with `..` names the live tree, exactly the tree the reading was
|
|
129
|
+
* taken to avoid.
|
|
130
|
+
*
|
|
131
|
+
* @category conversions
|
|
132
|
+
* @since 1.0.0
|
|
133
|
+
*/
|
|
134
|
+
export const relocate = (
|
|
135
|
+
flow: string,
|
|
136
|
+
input: Schema.Json,
|
|
137
|
+
materialized: Materialized
|
|
138
|
+
): Relocation => {
|
|
139
|
+
const rule = located[flow]
|
|
140
|
+
if (rule === undefined) return { _tag: "UnsupportedFlow" }
|
|
141
|
+
const record = input !== null && typeof input === "object" && !Array.isArray(input)
|
|
142
|
+
? input as Record<string, Schema.Json>
|
|
143
|
+
: {}
|
|
144
|
+
const declared = record[rule.field]
|
|
145
|
+
if (rule.kind === "cwd") {
|
|
146
|
+
// A container call is given the path the container will resolve; a host
|
|
147
|
+
// call is given the host's. `bash` chooses which by naming a container, so
|
|
148
|
+
// this reads the same field it does.
|
|
149
|
+
const containerised = typeof record["container"] === "string" && record["container"] !== ""
|
|
150
|
+
const base = containerised ? materialized.guest : materialized.host
|
|
151
|
+
const kept = typeof declared === "string" && declared !== ""
|
|
152
|
+
? within(containerised ? materialized.guestRoot : materialized.root, declared)
|
|
153
|
+
: ""
|
|
154
|
+
return {
|
|
155
|
+
_tag: "Relocated",
|
|
156
|
+
input: { ...record, cwd: kept === undefined || kept === "" ? base : `${base}/${kept}` }
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
const relative = materialized.host.slice(withoutTrailingSlash(materialized.root).length + 1)
|
|
160
|
+
if (declared === undefined) return { _tag: "Relocated", input: { ...record, [rule.field]: relative } }
|
|
161
|
+
if (typeof declared !== "string") return { _tag: "UnsupportedFlow" }
|
|
162
|
+
if (declared.startsWith("/")) return { _tag: "AbsolutePath", path: declared }
|
|
163
|
+
const kept = contained(declared)
|
|
164
|
+
if (kept === undefined) return { _tag: "OutsideTree", path: declared }
|
|
165
|
+
return { _tag: "Relocated", input: { ...record, [rule.field]: kept === "" ? relative : `${relative}/${kept}` } }
|
|
166
|
+
}
|