@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
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Implement your own search peer"
|
|
3
|
+
description: "Bind a third implementation of the Search service using the shared matcher, then prove it agrees with a reference peer using the differential conformance kit."
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 9
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
`Search` is a public extension seam. A host binds its own implementation and
|
|
9
|
+
every `grep` and `glob` call in the package goes through it, so an index server,
|
|
10
|
+
a remote service, or a virtual filesystem can back the search flows. This guide
|
|
11
|
+
is about filling that seam without drifting from what a pattern means.
|
|
12
|
+
|
|
13
|
+
## The interface
|
|
14
|
+
|
|
15
|
+
Two methods, both taking normalized input:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import * as Search from "@smthrs/std/Search"
|
|
19
|
+
import * as Effect from "effect/Effect"
|
|
20
|
+
import * as Layer from "effect/Layer"
|
|
21
|
+
|
|
22
|
+
const peer = Search.make({
|
|
23
|
+
grep: (input) =>
|
|
24
|
+
Effect.succeed({
|
|
25
|
+
matches: [],
|
|
26
|
+
files: [],
|
|
27
|
+
filesSearched: 0,
|
|
28
|
+
skippedBinary: 0,
|
|
29
|
+
truncated: false
|
|
30
|
+
}),
|
|
31
|
+
glob: (input) => Effect.succeed({ paths: [], total: 0, truncated: false })
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
const layer = Layer.succeed(Search.Search, peer)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`Grep.run` and `Glob.run` do the validation and defaulting before they call you,
|
|
38
|
+
so `GrepInput` and `GlobInput` arrive complete: `root` is resolved, `globs` is an
|
|
39
|
+
array, the context fields are numbers, and `limit` is already capped. Your
|
|
40
|
+
implementation never sees an undefined option.
|
|
41
|
+
|
|
42
|
+
The error channel is `StdError`, and the codes a peer produces are `not_found`
|
|
43
|
+
for a missing root, `invalid_pattern` for a pattern it cannot compile, and
|
|
44
|
+
`command_failed` for a host failure of its own.
|
|
45
|
+
|
|
46
|
+
## Reuse the shared matcher
|
|
47
|
+
|
|
48
|
+
Do not reimplement pattern or glob semantics. `SearchContract` exports exactly
|
|
49
|
+
the functions both shipped peers build on:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import * as SearchContract from "@smthrs/std/SearchContract"
|
|
53
|
+
|
|
54
|
+
SearchContract.validatePattern(pattern, fixedStrings) // StdError | undefined
|
|
55
|
+
SearchContract.validateGlob(glob) // StdError | undefined
|
|
56
|
+
SearchContract.canonicalGlob("./src/**/*.ts ") // "/src/**/*.ts"
|
|
57
|
+
SearchContract.expression(pattern, fixedStrings, insensitive) // a RegExp
|
|
58
|
+
SearchContract.matchesGlob("*.ts", "src/widen.ts", "widen.ts") // true
|
|
59
|
+
SearchContract.includedByGlobs(globs, relative, basename) // ordered include and exclude
|
|
60
|
+
SearchContract.unsatisfiableNotice({ fileSystem, path, root, globs, hidden })
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`matchesGlob` and `includedByGlobs` take a candidate's path **relative to the
|
|
64
|
+
root** and its basename, which is the whole of the root-relative rule described
|
|
65
|
+
in [The search contract](../concepts/search-contract.md).
|
|
66
|
+
|
|
67
|
+
`unsatisfiableNotice` is what keeps an empty answer honest: attach its result to
|
|
68
|
+
`notice` when your peer produced no entries, so "the tree holds no match" and
|
|
69
|
+
"this pattern can never match" stay distinguishable.
|
|
70
|
+
|
|
71
|
+
## Prove it agrees
|
|
72
|
+
|
|
73
|
+
`SearchConformance` generates a tree and a batch of calls from a seed, runs them
|
|
74
|
+
through two implementations, and reports every answer that differs. It knows
|
|
75
|
+
nothing about which peer is right: a divergence is the finding.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { NodeServices } from "@effect/platform-node"
|
|
79
|
+
import type * as KernelPath from "@smthrs/kernel/Path"
|
|
80
|
+
import * as PortableSearch from "@smthrs/std/PortableSearch"
|
|
81
|
+
import type * as Search from "@smthrs/std/Search"
|
|
82
|
+
import * as SearchConformance from "@smthrs/std/SearchConformance"
|
|
83
|
+
import * as Effect from "effect/Effect"
|
|
84
|
+
import type * as FileSystem from "effect/FileSystem"
|
|
85
|
+
|
|
86
|
+
const check = (subject: Search.Search) =>
|
|
87
|
+
Effect.gen(function*() {
|
|
88
|
+
const plan = SearchConformance.plan({
|
|
89
|
+
seed: 1234,
|
|
90
|
+
root: "/tmp/conformance",
|
|
91
|
+
files: 24,
|
|
92
|
+
calls: 40
|
|
93
|
+
})
|
|
94
|
+
yield* SearchConformance.materialize(plan)
|
|
95
|
+
|
|
96
|
+
const services = yield* Effect.context<FileSystem.FileSystem | KernelPath.Path>()
|
|
97
|
+
const divergences = yield* SearchConformance.compare({
|
|
98
|
+
plan,
|
|
99
|
+
subject,
|
|
100
|
+
reference: PortableSearch.make(services)
|
|
101
|
+
})
|
|
102
|
+
return SearchConformance.report(divergences)
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
const report = await Effect.runPromise(Effect.provide(check(peer), NodeServices.layer))
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
| Export | What it does |
|
|
109
|
+
| ------------- | --------------------------------------------------------------------- |
|
|
110
|
+
| `plan` | Builds a reproducible tree and call batch from a seed. |
|
|
111
|
+
| `materialize` | Writes that plan's tree under its root. |
|
|
112
|
+
| `compare` | Runs every call through both peers and returns the `Divergence` list. |
|
|
113
|
+
| `report` | Renders divergences as the text a failing run should print. |
|
|
114
|
+
|
|
115
|
+
The same seed and root always produce the same plan, so a divergence a run
|
|
116
|
+
reports replays exactly by rerunning that seed. A failure is compared like any
|
|
117
|
+
other answer: two peers that refuse the same call with the same code agree, and
|
|
118
|
+
one that refuses where the other answers has diverged.
|
|
119
|
+
|
|
120
|
+
`PortableSearch` is the obvious reference, because it needs no external binary.
|
|
121
|
+
|
|
122
|
+
## What the generator will not tell you
|
|
123
|
+
|
|
124
|
+
The generator deliberately stays inside the ground both peers claim to share: no
|
|
125
|
+
symlinks, no unreadable directories, no CRLF, no NUL bytes, no filename a shell
|
|
126
|
+
would have to quote. Those cases have an intended behavior rather than merely an
|
|
127
|
+
agreed one, and a generator can only say that two peers disagree, never which is
|
|
128
|
+
right. Pin them with hand-written cases alongside the conformance run.
|
|
129
|
+
|
|
130
|
+
The kit earns its place on the cases nobody thought to write down. A literal `?`
|
|
131
|
+
matched `fo` in one shipped peer and `foo?` in the other for as long as nobody
|
|
132
|
+
wrote that case; the generator found it, along with a `maxCount` interaction with
|
|
133
|
+
context lines and a disagreement between `ignoreCase` and `smartCase`.
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Pin a tree and read it later"
|
|
3
|
+
description: "Record the working tree as a checkpoint, materialize it as a scratch directory for the length of one call, and relocate a read or a command onto it."
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 6
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
A checkpoint is a **value**. Minting one changes nothing about the workspace,
|
|
9
|
+
and running a call against one leaves the live tree exactly as it stands. That
|
|
10
|
+
is the whole of what it buys: before it existed, the only way to answer "did
|
|
11
|
+
this fail before my change" was to undo the change, which means reverting the
|
|
12
|
+
very work the reading was meant to prove.
|
|
13
|
+
|
|
14
|
+
This module is the host half of [`@smthrs/harness`](/api/harness)'s
|
|
15
|
+
`ctx.checkpoint()` and `ctx.call(flow, input, { at })`. The harness owns the
|
|
16
|
+
surface, the identity, the bound, and the refusals; this owns the two host
|
|
17
|
+
operations that need a real tree.
|
|
18
|
+
|
|
19
|
+
## Bind the git store
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import * as Checkpoints from "@smthrs/std/Checkpoints"
|
|
23
|
+
|
|
24
|
+
const store = Checkpoints.layerGit({
|
|
25
|
+
root: "/workspace/repo", // the host path of the git repository
|
|
26
|
+
cwd: "/testbed", // where a container sees that same directory
|
|
27
|
+
baseRef: "refs/flows/capture-base" // optional
|
|
28
|
+
})
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`layerGit` requires a `ChildProcessSpawner`. A host that pins nothing binds
|
|
32
|
+
`Checkpoints.layerNoop`, whose refusal says to take the reading on the live tree
|
|
33
|
+
instead.
|
|
34
|
+
|
|
35
|
+
## Bind the container store
|
|
36
|
+
|
|
37
|
+
When the repository lives only in a container and `bash` runs there, bind
|
|
38
|
+
`layerContainer` instead. It runs git inside that container through the
|
|
39
|
+
`Container` transport `bash` uses, so `ctx.base` and `ctx.checkpoint()` read the
|
|
40
|
+
container's tree. A git store would look for the repository on the host and
|
|
41
|
+
refuse every call that names a checkpoint.
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
const store = Checkpoints.layerContainer({
|
|
45
|
+
container: "task", // the container `bash` runs in
|
|
46
|
+
cwd: "/app" // optional; absent is the container's working directory
|
|
47
|
+
})
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`layerContainer` requires a `ChildProcessSpawner` and a `Container`. It records
|
|
51
|
+
and names a checkpoint as the git store does, and checks a tree out at the same
|
|
52
|
+
`<top>/.flows-checkpoints/<id>-<lease>` path inside the container, so a
|
|
53
|
+
relocated `bash` call keeps its subdirectory.
|
|
54
|
+
|
|
55
|
+
## Capture and materialize
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import * as Effect from "effect/Effect"
|
|
59
|
+
|
|
60
|
+
const reading = Effect.gen(function*() {
|
|
61
|
+
const checkpoints = yield* Checkpoints.Checkpoints
|
|
62
|
+
const snapshot = yield* checkpoints.capture("before-fix")
|
|
63
|
+
return yield* checkpoints.materialize(snapshot.id, (tree) => Effect.succeed(tree.host))
|
|
64
|
+
})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`capture(id)` records the working tree as it stands and returns a `Snapshot`
|
|
68
|
+
with the `id` you gave and the store's own `ref` for it. `materialize(id, use)`
|
|
69
|
+
hands the tree back as a directory for the length of the effect you pass, and
|
|
70
|
+
removes it however that effect ends. It is scoped rather than returned, because
|
|
71
|
+
a run killed at its wall-clock budget would otherwise leave a second checkout of
|
|
72
|
+
the whole repository inside the tree whose diff is the run's answer.
|
|
73
|
+
|
|
74
|
+
A `Materialized` carries four paths, because one directory can have two names:
|
|
75
|
+
|
|
76
|
+
| Field | Meaning |
|
|
77
|
+
| ----------- | ----------------------------------------------------- |
|
|
78
|
+
| `host` | Where a process on this machine finds the checkpoint. |
|
|
79
|
+
| `guest` | Where a container finds the same directory. |
|
|
80
|
+
| `root` | The workspace itself, as this machine names it. |
|
|
81
|
+
| `guestRoot` | The workspace as a container names it. |
|
|
82
|
+
|
|
83
|
+
`Checkpoints.baseId` is `"base"`, the tree the run opened on. It is not minted:
|
|
84
|
+
the store uses `baseRef` when one is declared. A declared ref that
|
|
85
|
+
does not resolve is `not_found`. Otherwise it tries `TestRunner.captureBase`
|
|
86
|
+
and then `HEAD`, matching `test`.
|
|
87
|
+
|
|
88
|
+
## What the git binding does, and does not do
|
|
89
|
+
|
|
90
|
+
`layerGit` records with `git stash create`, which is the one git command that
|
|
91
|
+
records the working tree and changes nothing else: it does not move the
|
|
92
|
+
worktree and does not touch the stash ref. It runs against a temporary shadow
|
|
93
|
+
`GIT_DIR` that shares only the workspace's objects and reads a copy of the
|
|
94
|
+
workspace index, so it never writes the agent's index and never runs a hook,
|
|
95
|
+
`core.fsmonitor` command or filter driver the workspace's `.git` names. That matters
|
|
96
|
+
because the agent runs `git` in this same workspace and its own `git diff` is
|
|
97
|
+
the run's evidence. A capture that staged into the real index would be the
|
|
98
|
+
harness editing the evidence while recording it. A tree with nothing to record
|
|
99
|
+
prints nothing, and the checkpoint is then `HEAD`, which is exactly what the
|
|
100
|
+
tree is.
|
|
101
|
+
|
|
102
|
+
The commit is named in the repository's own git config, under
|
|
103
|
+
`Checkpoints.configSection` (`flows-checkpoint`), and **not** by a ref. A ref is
|
|
104
|
+
history: `git log --all` lists it, `git show` prints it, and `git log --all -S`
|
|
105
|
+
searches it, so a checkpoint named by a ref would hand an agent a commit
|
|
106
|
+
containing its own edit and let it read that back as if it were upstream work.
|
|
107
|
+
Under config the commit object stays unreferenced, a checkout by id works
|
|
108
|
+
perfectly well, and no command that walks refs can reach it.
|
|
109
|
+
|
|
110
|
+
One command still sees it: `git fsck` reports it as a dangling commit, because
|
|
111
|
+
that is what an unreferenced commit is. A checkout is a standalone repository
|
|
112
|
+
rather than a worktree of the workspace, so `git log --all` in the workspace
|
|
113
|
+
does not list it even while a call runs in it.
|
|
114
|
+
|
|
115
|
+
Untracked files are not in the recorded tree, which matches how a patch is
|
|
116
|
+
captured. Materialization is a detached checkout at
|
|
117
|
+
`<root>/.flows-checkpoints/<id>-<lease>`, under `Checkpoints.scratchDirectory`.
|
|
118
|
+
Its own `.git` names the commit in `HEAD` and reaches the workspace's objects
|
|
119
|
+
through a relative `objects/info/alternates`, so git run in it through a
|
|
120
|
+
container mount works.
|
|
121
|
+
Each call gets a unique lease, so overlapping calls never remove each other's
|
|
122
|
+
checkout. Existing checkouts are left alone; a `SIGKILL` can leave one behind.
|
|
123
|
+
Inside the workspace is the only placement that works, for the same reason the
|
|
124
|
+
`test` baseline is placed there: a container sees the workspace through a mount,
|
|
125
|
+
and a scratch checkout anywhere else on the host is not visible to it.
|
|
126
|
+
|
|
127
|
+
## Point a call at a checkpoint
|
|
128
|
+
|
|
129
|
+
`relocate` rewrites one call's input so the call runs against a materialized
|
|
130
|
+
checkpoint. It is a closed table, not a per-flow hook:
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
const relocation = Checkpoints.relocate("read", { path: "src/widen.ts" }, tree)
|
|
134
|
+
|
|
135
|
+
if (relocation._tag === "Relocated") {
|
|
136
|
+
// relocation.input now reads .flows-checkpoints/<id>-<lease>/src/widen.ts
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
| Flow | The field it is relocated by |
|
|
141
|
+
| -------------- | ---------------------------------------------------------------------- |
|
|
142
|
+
| `bash` | `cwd`, into the checkpoint and into the same subdirectory it asked for |
|
|
143
|
+
| `read`, `ls` | `path`, prefixed with the checkpoint's workspace-relative directory |
|
|
144
|
+
| `grep`, `glob` | `root`, prefixed the same way |
|
|
145
|
+
|
|
146
|
+
`bash` is relocated from the guest side when the call names a container, because
|
|
147
|
+
that is the path the container will be given. Keeping the subdirectory matters:
|
|
148
|
+
a check declared in `tests/` that silently ran at the top would come back
|
|
149
|
+
failing for a reason nobody chose.
|
|
150
|
+
|
|
151
|
+
Three inputs are refused rather than rewritten, and the tag says which:
|
|
152
|
+
|
|
153
|
+
- `UnsupportedFlow`, for any flow outside that table. `test` is deliberately
|
|
154
|
+
outside it: it answers this question already with `against: "base"`, and two
|
|
155
|
+
mechanisms pointed at one tree are two answers that can disagree.
|
|
156
|
+
- `AbsolutePath`, because an absolute path in these runs is a container path and
|
|
157
|
+
the host cannot know which prefix of it names the tree.
|
|
158
|
+
- `OutsideTree`, for a relative path that climbs past the checkpoint with `..`,
|
|
159
|
+
which names the live tree under another name. That is exactly the tree the
|
|
160
|
+
reading was taken to avoid, and a call key folds the checkpoint in, so a live
|
|
161
|
+
reading recorded under a checkpoint would replay as a pinned one forever.
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Query a language server"
|
|
3
|
+
description: "Run the ten LSP operations through the lsp flow, spawn a server with NodeLanguageServer, and understand the 1-based coordinates and the pass-through result."
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 8
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
`lsp` is one flow with ten operations. It answers the questions a text search
|
|
9
|
+
cannot: where a symbol is defined, who calls it, what type it has.
|
|
10
|
+
|
|
11
|
+
## Spawn a server
|
|
12
|
+
|
|
13
|
+
`NodeLanguageServer` speaks framed JSON-RPC over ordinary stdio pipes, spawned
|
|
14
|
+
through [`@smthrs/kernel`](/api/kernel)'s `ChildProcessSpawner`. No terminal is
|
|
15
|
+
involved.
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import * as NodeLanguageServer from "@smthrs/std/NodeLanguageServer"
|
|
19
|
+
|
|
20
|
+
const server = NodeLanguageServer.layer({
|
|
21
|
+
command: "typescript-language-server",
|
|
22
|
+
args: ["--stdio"],
|
|
23
|
+
cwd: "/workspace",
|
|
24
|
+
environment: { NODE_ENV: "development" },
|
|
25
|
+
timeoutMs: 30_000
|
|
26
|
+
})
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The layer sends `initialize` with `cwd` as the root URI and then `initialized`,
|
|
30
|
+
so the service is ready when it resolves. `timeoutMs` defaults to 30 seconds and
|
|
31
|
+
bounds every request as well as every write to the server's standard input.
|
|
32
|
+
The child inherits only `PATH`, `HOME`, `USER`, `LANG`, `LC_*`, `TERM`, `TMPDIR`,
|
|
33
|
+
and `SHELL`, with credential-shaped names withheld. Declare other names through
|
|
34
|
+
`environment`; explicit values override the allowlist.
|
|
35
|
+
|
|
36
|
+
### Keep the server's code out of the workspace
|
|
37
|
+
|
|
38
|
+
The server runs on the host as the host user, so a program the workspace
|
|
39
|
+
supplies would let files an agent wrote choose what the host executes. The
|
|
40
|
+
layer fails with `permission_denied`, before spawning, when:
|
|
41
|
+
|
|
42
|
+
- `command` resolves to a file under `cwd`, directly, through a `PATH` entry
|
|
43
|
+
such as `node_modules/.bin`, or through a symlink planted there;
|
|
44
|
+
- an argument, or the value after `=` in one, names an existing file under
|
|
45
|
+
`cwd`;
|
|
46
|
+
- `command` is a launcher whose arguments choose what runs: a shell
|
|
47
|
+
(`sh -c ...`), `env`, a package runner (`npx`, `pnpm exec`, `npm`, `yarn`,
|
|
48
|
+
`bunx`, `bun x`, `deno`), or `node` or `bun` given inline code or a preload
|
|
49
|
+
(`-e`, `-p`, `-r`, `--require`, `--import`, `--loader`). `npx` and
|
|
50
|
+
`pnpm exec` resolve the workspace's `node_modules/.bin` first, and inline
|
|
51
|
+
code resolves bare requires from `cwd`. Name the server's own host binary,
|
|
52
|
+
or an interpreter and a host script file, instead.
|
|
53
|
+
|
|
54
|
+
The layer cannot see what the server loads after it starts. By default
|
|
55
|
+
typescript-language-server runs the workspace's own `node_modules/typescript`;
|
|
56
|
+
tsserver started with `--allowLocalPluginLoads` loads `tsconfig` plugins from
|
|
57
|
+
the project; rust-analyzer runs build scripts and proc macros. Pin those to
|
|
58
|
+
host copies, or run the server in a sandbox:
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const server = NodeLanguageServer.layer({
|
|
62
|
+
command: "/opt/lsp/node_modules/.bin/typescript-language-server",
|
|
63
|
+
args: ["--stdio"],
|
|
64
|
+
cwd: "/workspace",
|
|
65
|
+
initializationOptions: { tsserver: { path: "/opt/lsp/node_modules/typescript/lib/tsserver.js" } }
|
|
66
|
+
})
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`initializationOptions` is sent on `initialize` unchanged. With `tsserver.path`
|
|
70
|
+
outside the workspace and local plugin loads left off, tsserver probes for
|
|
71
|
+
plugins only beside its own install.
|
|
72
|
+
|
|
73
|
+
A host with no server binds `LanguageServer.layerNoop`, and every operation
|
|
74
|
+
fails with `unsupported`.
|
|
75
|
+
|
|
76
|
+
### One server per language
|
|
77
|
+
|
|
78
|
+
Pass several configs and each file goes to the server whose `extensions`
|
|
79
|
+
include its extension. A config without `extensions` takes every file no other
|
|
80
|
+
server claims; a file nobody claims fails with `unsupported`.
|
|
81
|
+
`workspaceSymbols` asks every server and concatenates the answers.
|
|
82
|
+
|
|
83
|
+
`NodeLanguageServer.layerLazy` takes the same configs but starts each server on
|
|
84
|
+
the first request for one of its files, so a host can bind servers a run may
|
|
85
|
+
never need. The workspace checks above still run when the layer is built. A
|
|
86
|
+
server starts with the services and permissions of the code that built the
|
|
87
|
+
layer, not those of the request that first needs it. A server that fails to
|
|
88
|
+
start fails that request and every later one for its files. `refresh` and
|
|
89
|
+
`close` never start a server.
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
const servers = NodeLanguageServer.layer([
|
|
93
|
+
{ command: "typescript-language-server", args: ["--stdio"], cwd: "/workspace", extensions: [".ts", ".tsx"] },
|
|
94
|
+
{ command: "pyright-langserver", args: ["--stdio"], cwd: "/workspace", extensions: [".py"] }
|
|
95
|
+
])
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Edits reach the server
|
|
99
|
+
|
|
100
|
+
With a `LanguageServer` bound, `edit`, `write` and `apply_patch` send each file
|
|
101
|
+
they write to its server after the entire operation succeeds: `textDocument/didOpen` the first time, then
|
|
102
|
+
`textDocument/didChange` with the full text. A file `apply_patch` deletes or
|
|
103
|
+
moves away gets `textDocument/didClose`. `edit` then returns `errors`, the
|
|
104
|
+
error-severity diagnostics in the file after the edit (at most 20, 1-based
|
|
105
|
+
positions). `errors` is absent when no server is bound or it did not answer;
|
|
106
|
+
the edit itself never fails because of the server.
|
|
107
|
+
|
|
108
|
+
`bash` does not know which files a command changed, so after a command on the
|
|
109
|
+
host it calls `refresh`: the client re-reads every file it has open, sends the
|
|
110
|
+
text of each that changed, and closes each that is gone. A command run in a
|
|
111
|
+
container leaves the host's files alone and refreshes nothing.
|
|
112
|
+
|
|
113
|
+
`diagnostics` pulls `textDocument/diagnostic`. A server that answers
|
|
114
|
+
`MethodNotFound` is read from its `textDocument/publishDiagnostics`
|
|
115
|
+
notifications instead: the client opens the file if it is not open yet and waits
|
|
116
|
+
up to `settleMs` (5 seconds by default) for a publish for the latest synced
|
|
117
|
+
text, then fails with `timeout`. After a publish it keeps waiting while later
|
|
118
|
+
ones arrive less than `quietMs` (300 ms by default) apart, within `settleMs`, and
|
|
119
|
+
answers with the last. Either way the answer is a report,
|
|
120
|
+
`{ kind: "full", items }`.
|
|
121
|
+
|
|
122
|
+
A publish that carries no version counts for the text synced before it arrived.
|
|
123
|
+
Before each sync the client sends a `$/` request, which the specification has
|
|
124
|
+
every server refuse at once, so a report the server wrote earlier (such as the
|
|
125
|
+
empty one typescript-language-server publishes when a file closes) reaches the
|
|
126
|
+
client first and never counts for the new text. A server that does not answer
|
|
127
|
+
within a second is not asked again.
|
|
128
|
+
|
|
129
|
+
### typescript-language-server
|
|
130
|
+
|
|
131
|
+
typescript-language-server 6 has no pull diagnostics, publishes without
|
|
132
|
+
versions, and publishes nothing for a change that leaves a file with no
|
|
133
|
+
problems, so such a change always waits the full `settleMs` and fails with
|
|
134
|
+
`timeout`. On the first open of a file it publishes syntax errors before
|
|
135
|
+
semantic ones. Pick `settleMs` and `quietMs` from a measurement on your host:
|
|
136
|
+
|
|
137
|
+
```sh
|
|
138
|
+
node scripts/lsp-settle-bench.ts <typescript-language-server or gopls> <tsserver.js or -> <workspace> <iterations> <settleMs> <quietMs> <file>...
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Measured settle with real servers
|
|
142
|
+
|
|
143
|
+
Repeat it with `sh scripts/lsp-real.sh <dir> [iterations] [settleMs] [quietMs]`.
|
|
144
|
+
It installs typescript-language-server 6.0.1 with typescript 5.9.3 (typescript 7
|
|
145
|
+
ships no `tsserver.js`) and, when Go is on `PATH`, gopls under `<dir>`, runs
|
|
146
|
+
`test/NodeLanguageServerReal.test.ts` (a real server on `test/fixtures/lsp/ts`;
|
|
147
|
+
skipped when no server is on `PATH` or named by `SMITHERS_LSP_TLS` and
|
|
148
|
+
`SMITHERS_LSP_TSSERVER`), then writes `<dir>/out/ts.json` and `go.json`. Each
|
|
149
|
+
file is opened with a type error, then cycles fix, comment-only change, restore,
|
|
150
|
+
break, close and reopen, 5 times, at `settleMs` 3000 and `quietMs` 500.
|
|
151
|
+
|
|
152
|
+
One run on a 14 CPU macOS host at load average 44 to 54, from other agents, on
|
|
153
|
+
the two-file fixtures. Milliseconds from sync to the first publish (raw, p50 and
|
|
154
|
+
max), and to the client's answer:
|
|
155
|
+
|
|
156
|
+
| Server, step | First publish | Client answer | Correct |
|
|
157
|
+
| ---------------------------- | -------------------- | ------------------------ | ------------------------ |
|
|
158
|
+
| tls, fix | 377 to 623, max 1301 | 878 to 908, max 3010 | 9/10 |
|
|
159
|
+
| tls, break | 373 to 401, max 472 | 874 to 887, max 1202 | 10/10 |
|
|
160
|
+
| tls, reopen | 1 to 4, max 33 | 864 to 871, max 930 | 10/10 |
|
|
161
|
+
| tls, comment-only or restore | none | waits `settleMs` (3.0 s) | 1/20, no errors returned |
|
|
162
|
+
| tls, cold open | none in 4 s | 3.0 s, `timeout` | 0/2 |
|
|
163
|
+
| gopls, every step | 2 to 5, max 24 | 1 to 3, max 6 | 50/50 |
|
|
164
|
+
| gopls, cold open | 252 to 1541 | 415 to 553 | 2/2 |
|
|
165
|
+
|
|
166
|
+
`settleMs: 3000` and `quietMs: 500` hold for warm typescript-language-server
|
|
167
|
+
edits. Limitations: one host, loaded, n of 5 per step and 2 files; a cold open
|
|
168
|
+
under load exceeded 3 s for both files, and a change that leaves a file
|
|
169
|
+
clean returns no `errors` after the full `settleMs`. gopls publishes within
|
|
170
|
+
milliseconds, so it never needs more than the defaults. No Python server was
|
|
171
|
+
measured. The raw JSON is written by the script and is not checked in.
|
|
172
|
+
|
|
173
|
+
## Run a query
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
import * as Lsp from "@smthrs/std/Lsp"
|
|
177
|
+
|
|
178
|
+
const definition = Lsp.run({
|
|
179
|
+
operation: "definition",
|
|
180
|
+
path: "/workspace/src/widen.ts",
|
|
181
|
+
line: 12,
|
|
182
|
+
character: 17
|
|
183
|
+
})
|
|
184
|
+
// definition.result is the server's own answer, passed through unchanged
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
| Operation | What it takes |
|
|
188
|
+
| ----------------------- | --------------------------- |
|
|
189
|
+
| `hover` | `path`, `line`, `character` |
|
|
190
|
+
| `definition` | `path`, `line`, `character` |
|
|
191
|
+
| `references` | `path`, `line`, `character` |
|
|
192
|
+
| `implementation` | `path`, `line`, `character` |
|
|
193
|
+
| `prepareCallHierarchy` | `path`, `line`, `character` |
|
|
194
|
+
| `callHierarchyIncoming` | `path`, `line`, `character` |
|
|
195
|
+
| `callHierarchyOutgoing` | `path`, `line`, `character` |
|
|
196
|
+
| `documentSymbols` | `path` |
|
|
197
|
+
| `diagnostics` | `path` |
|
|
198
|
+
| `workspaceSymbols` | `query` |
|
|
199
|
+
|
|
200
|
+
`line` and `character` are **1-based**, which is how `read` and `grep` report
|
|
201
|
+
them, so a hit from a search is a position you can pass straight in. The flow
|
|
202
|
+
converts to the protocol's 0-based coordinates for you.
|
|
203
|
+
|
|
204
|
+
`path` must be a normalized absolute path. A relative path, or a missing one for
|
|
205
|
+
any operation except `workspaceSymbols`, fails with `invalid_input`, as does a
|
|
206
|
+
position operation missing `line` or `character`. The server reads the file
|
|
207
|
+
itself, so the flow first reads `path` through the bound `FileSystem`: a path the
|
|
208
|
+
guarded filesystem denies fails with `permission_denied` before the server sees
|
|
209
|
+
it.
|
|
210
|
+
|
|
211
|
+
`references` includes the declaration. The two call-hierarchy directions run
|
|
212
|
+
`prepareCallHierarchy` first and return an empty array when the server prepares
|
|
213
|
+
no item, so a position that is not a callable is an empty answer rather than a
|
|
214
|
+
failure.
|
|
215
|
+
|
|
216
|
+
## The result is not a schema
|
|
217
|
+
|
|
218
|
+
`Output` is `{ result: unknown }`. The server's answer is passed through in the
|
|
219
|
+
server's own shape, because LSP responses vary by server and by version, and
|
|
220
|
+
narrowing them here would be a second, staler schema. Decode it on the caller's
|
|
221
|
+
side against what the server you bound actually returns.
|
|
222
|
+
|
|
223
|
+
## Bounds a server cannot exceed
|
|
224
|
+
|
|
225
|
+
The client refuses a malformed or oversized stream rather than growing without
|
|
226
|
+
limit:
|
|
227
|
+
|
|
228
|
+
| Bound | Value |
|
|
229
|
+
| ----------------------------------------- | --------------------------------------------------- |
|
|
230
|
+
| One JSON-RPC frame body | 8 MiB |
|
|
231
|
+
| One frame's headers | 8 KiB |
|
|
232
|
+
| `NodeLanguageServer.MAX_QUEUED_FRAMES` | 256 frames buffered for the server's standard input |
|
|
233
|
+
| `NodeLanguageServer.MAX_PENDING_REQUESTS` | 512 concurrent in-flight requests |
|
|
234
|
+
|
|
235
|
+
Every queued write uses the request timeout, so a server that stops reading
|
|
236
|
+
produces a typed `timeout` rather than an unbounded queue or a new hang. Process
|
|
237
|
+
exit or a closed stdout fails every pending request after at most 100 ms for
|
|
238
|
+
stderr to finish draining.
|
|
239
|
+
|
|
240
|
+
Request errors include the protocol `method`. A server refusal keeps its numeric
|
|
241
|
+
code, message, and optional data in `StdError.rpcError`; the response frame limit
|
|
242
|
+
bounds that data. The main error message also includes the server message.
|
|
243
|
+
`StdError.stderr`, when present, contains the latest stderr tail, captured from
|
|
244
|
+
at most 64 KiB. Initialization failures and exits retain this diagnostic context.
|
|
245
|
+
|
|
246
|
+
## Bring your own server
|
|
247
|
+
|
|
248
|
+
`LanguageServer` is an ordinary service interface: ten query methods, each
|
|
249
|
+
taking a `Position` (`path`, `line`, `character`) or a string, plus
|
|
250
|
+
`sync(path, text)` and `close(path)`. A host with its own client, in-process
|
|
251
|
+
index, or remote service implements those twelve methods and
|
|
252
|
+
binds them with `LanguageServer.make`. Nothing above the service knows which one
|
|
253
|
+
answered.
|
|
254
|
+
|
|
255
|
+
One detail to implement against: a `Position` reaching the service is already
|
|
256
|
+
**0-based**. The 1-based to 0-based conversion happens in the flow, so the
|
|
257
|
+
service speaks the protocol's own coordinates.
|