@smthrs/std 0.0.0-stage → 1.0.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +130 -0
- package/LICENSE +21 -0
- package/README.md +152 -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 +304 -0
- package/dist/cjs/Bash.d.ts.map +1 -0
- package/dist/cjs/Bash.js +321 -0
- package/dist/cjs/Bash.js.map +7 -0
- package/dist/cjs/Checkpoints.d.ts +279 -0
- package/dist/cjs/Checkpoints.d.ts.map +1 -0
- package/dist/cjs/Checkpoints.js +145 -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 +24 -0
- package/dist/cjs/PortableSearch.d.ts.map +1 -0
- package/dist/cjs/PortableSearch.js +233 -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/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 +127 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +99 -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 +67 -0
- package/dist/cjs/internal/EnvelopePrecheck.d.ts.map +1 -0
- package/dist/cjs/internal/EnvelopePrecheck.js +124 -0
- package/dist/cjs/internal/EnvelopePrecheck.js.map +7 -0
- package/dist/cjs/internal/Exec.d.ts +139 -0
- package/dist/cjs/internal/Exec.d.ts.map +1 -0
- package/dist/cjs/internal/Exec.js +158 -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 +98 -0
- package/dist/cjs/internal/GitWorktree.d.ts.map +1 -0
- package/dist/cjs/internal/GitWorktree.js +270 -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/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/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 +114 -0
- package/dist/cjs/internal/Text.d.ts.map +1 -0
- package/dist/cjs/internal/Text.js +82 -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 +304 -0
- package/dist/esm/Bash.d.ts.map +1 -0
- package/dist/esm/Bash.js +469 -0
- package/dist/esm/Bash.js.map +1 -0
- package/dist/esm/Checkpoints.d.ts +279 -0
- package/dist/esm/Checkpoints.d.ts.map +1 -0
- package/dist/esm/Checkpoints.js +298 -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 +24 -0
- package/dist/esm/PortableSearch.d.ts.map +1 -0
- package/dist/esm/PortableSearch.js +240 -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/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 +127 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +127 -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 +67 -0
- package/dist/esm/internal/EnvelopePrecheck.d.ts.map +1 -0
- package/dist/esm/internal/EnvelopePrecheck.js +167 -0
- package/dist/esm/internal/EnvelopePrecheck.js.map +1 -0
- package/dist/esm/internal/Exec.d.ts +139 -0
- package/dist/esm/internal/Exec.d.ts.map +1 -0
- package/dist/esm/internal/Exec.js +193 -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 +98 -0
- package/dist/esm/internal/GitWorktree.d.ts.map +1 -0
- package/dist/esm/internal/GitWorktree.js +345 -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/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/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 +114 -0
- package/dist/esm/internal/Text.d.ts.map +1 -0
- package/dist/esm/internal/Text.js +130 -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 +117 -0
- package/docs/api.md +472 -0
- package/docs/concepts/effects-and-capabilities.md +136 -0
- package/docs/concepts/flows-and-handlers.md +115 -0
- package/docs/concepts/limits-and-disclosure.md +102 -0
- package/docs/concepts/search-contract.md +182 -0
- package/docs/guides/bind-the-standard-flows.md +114 -0
- package/docs/guides/implement-a-search-peer.md +133 -0
- package/docs/guides/pin-a-checkpoint.md +141 -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 +215 -0
- package/docs/guides/run-the-test-suite.md +154 -0
- package/docs/guides/search-a-workspace.md +148 -0
- package/docs/installation.md +111 -0
- package/docs/quickstart.md +125 -0
- package/docs/reference/flows.md +556 -0
- package/docs/troubleshooting.md +322 -0
- package/package.json +439 -3
- package/src/ApplyPatch.ts +458 -0
- package/src/Bash.ts +549 -0
- package/src/Checkpoints.ts +422 -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 +264 -0
- package/src/Probe.ts +284 -0
- package/src/Read.ts +359 -0
- package/src/Relocate.ts +166 -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 +154 -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 +233 -0
- package/src/internal/Exec.ts +314 -0
- package/src/internal/FileMutation.ts +231 -0
- package/src/internal/FsFailure.ts +51 -0
- package/src/internal/GitWorktree.ts +473 -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/SearchContract.ts +77 -0
- package/src/internal/Symbols.ts +88 -0
- package/src/internal/TestReport.ts +194 -0
- package/src/internal/Text.ts +170 -0
- package/src/internal/Url.ts +23 -0
- package/src/internal/Walk.ts +176 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Faithful port of Codex CLI output truncation.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `codex-rs/utils/string/src/truncate.rs` and
|
|
5
|
+
* `codex-rs/utils/output-truncation/src/lib.rs`: middle truncation on UTF-8
|
|
6
|
+
* boundaries with a `…{n} tokens truncated…` marker and a 4-bytes-per-token
|
|
7
|
+
* estimate, so ChatGPT-family models see the exact shapes they were
|
|
8
|
+
* posttrained on.
|
|
9
|
+
*
|
|
10
|
+
* @since 1.0.0
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const APPROX_BYTES_PER_TOKEN = 4
|
|
14
|
+
|
|
15
|
+
const encoder = new TextEncoder()
|
|
16
|
+
const decoder = new TextDecoder()
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* UTF-8 byte length of a string.
|
|
20
|
+
*
|
|
21
|
+
* @since 1.0.0
|
|
22
|
+
* @private
|
|
23
|
+
*/
|
|
24
|
+
export const byteLength = (text: string): number => encoder.encode(text).byteLength
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Approximate token count: ceil(utf8Bytes / 4).
|
|
28
|
+
*
|
|
29
|
+
* @since 1.0.0
|
|
30
|
+
* @private
|
|
31
|
+
*/
|
|
32
|
+
export const approxTokenCount = (text: string): number =>
|
|
33
|
+
Math.floor((byteLength(text) + APPROX_BYTES_PER_TOKEN - 1) / APPROX_BYTES_PER_TOKEN)
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Approximate byte budget for a token budget.
|
|
37
|
+
*
|
|
38
|
+
* @since 1.0.0
|
|
39
|
+
* @private
|
|
40
|
+
*/
|
|
41
|
+
export const approxBytesForTokens = (tokens: number): number => tokens * APPROX_BYTES_PER_TOKEN
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Approximate tokens represented by a byte count: ceil(bytes / 4).
|
|
45
|
+
*
|
|
46
|
+
* @since 1.0.0
|
|
47
|
+
* @private
|
|
48
|
+
*/
|
|
49
|
+
export const approxTokensFromByteCount = (bytes: number): number =>
|
|
50
|
+
Math.floor((bytes + APPROX_BYTES_PER_TOKEN - 1) / APPROX_BYTES_PER_TOKEN)
|
|
51
|
+
|
|
52
|
+
const formatTruncationMarker = (useTokens: boolean, removedCount: number): string =>
|
|
53
|
+
useTokens ? `…${removedCount} tokens truncated…` : `…${removedCount} chars truncated…`
|
|
54
|
+
|
|
55
|
+
interface Split {
|
|
56
|
+
readonly removedChars: number
|
|
57
|
+
readonly before: string
|
|
58
|
+
readonly after: string
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** A UTF-8 continuation byte is `10xxxxxx`; every other byte starts a character. */
|
|
62
|
+
const isContinuation = (byte: number): boolean => (byte & 0b1100_0000) === 0b1000_0000
|
|
63
|
+
|
|
64
|
+
/** The last character boundary at or before `offset`. */
|
|
65
|
+
const boundaryAtOrBefore = (bytes: Uint8Array, offset: number): number => {
|
|
66
|
+
let at = Math.min(offset, bytes.byteLength)
|
|
67
|
+
while (at > 0 && at < bytes.byteLength && isContinuation(bytes[at]!)) at--
|
|
68
|
+
return at
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** The first character boundary at or after `offset`. */
|
|
72
|
+
const boundaryAtOrAfter = (bytes: Uint8Array, offset: number): number => {
|
|
73
|
+
let at = Math.max(offset, 0)
|
|
74
|
+
while (at < bytes.byteLength && isContinuation(bytes[at]!)) at++
|
|
75
|
+
return at
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Splits `s` into the head that fits `beginningBytes` and the tail that fits
|
|
80
|
+
* `endBytes`, both cut on UTF-8 character boundaries, and counts the characters
|
|
81
|
+
* dropped between them.
|
|
82
|
+
*
|
|
83
|
+
* The boundaries are read off the encoded bytes rather than by re-encoding one
|
|
84
|
+
* character at a time: a per-character `TextEncoder.encode` costs about two
|
|
85
|
+
* microseconds, which is nineteen seconds for the eight megabytes a bounded
|
|
86
|
+
* capture can hand this function.
|
|
87
|
+
*/
|
|
88
|
+
const splitString = (s: string, beginningBytes: number, endBytes: number): Split => {
|
|
89
|
+
const bytes = encoder.encode(s)
|
|
90
|
+
const tailStartTarget = Math.max(bytes.byteLength - endBytes, 0)
|
|
91
|
+
const prefixEnd = boundaryAtOrBefore(bytes, beginningBytes)
|
|
92
|
+
const suffixStart = boundaryAtOrAfter(bytes, Math.max(tailStartTarget, prefixEnd))
|
|
93
|
+
let removedChars = 0
|
|
94
|
+
for (let at = prefixEnd; at < suffixStart; at++) if (!isContinuation(bytes[at]!)) removedChars++
|
|
95
|
+
return {
|
|
96
|
+
removedChars,
|
|
97
|
+
before: decoder.decode(bytes.subarray(0, prefixEnd)),
|
|
98
|
+
after: decoder.decode(bytes.subarray(suffixStart))
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const truncateWithByteEstimate = (s: string, maxBytes: number, useTokens: boolean): string => {
|
|
103
|
+
if (s === "") return ""
|
|
104
|
+
const totalBytes = byteLength(s)
|
|
105
|
+
if (maxBytes === 0) {
|
|
106
|
+
return formatTruncationMarker(useTokens, useTokens ? approxTokensFromByteCount(totalBytes) : [...s].length)
|
|
107
|
+
}
|
|
108
|
+
if (totalBytes <= maxBytes) return s
|
|
109
|
+
const leftBudget = Math.floor(maxBytes / 2)
|
|
110
|
+
const rightBudget = maxBytes - leftBudget
|
|
111
|
+
const { after, before, removedChars } = splitString(s, leftBudget, rightBudget)
|
|
112
|
+
const marker = formatTruncationMarker(
|
|
113
|
+
useTokens,
|
|
114
|
+
useTokens ? approxTokensFromByteCount(Math.max(totalBytes - maxBytes, 0)) : removedChars
|
|
115
|
+
)
|
|
116
|
+
return `${before}${marker}${after}`
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Middle-truncate to a byte budget with a char-count marker.
|
|
121
|
+
*
|
|
122
|
+
* @since 1.0.0
|
|
123
|
+
* @private
|
|
124
|
+
*/
|
|
125
|
+
export const truncateMiddleChars = (s: string, maxBytes: number): string => truncateWithByteEstimate(s, maxBytes, false)
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Middle-truncate to an approximate token budget, preserving the beginning
|
|
129
|
+
* and end. Returns the possibly truncated string and the original token
|
|
130
|
+
* count when truncation occurred.
|
|
131
|
+
*
|
|
132
|
+
* @since 1.0.0
|
|
133
|
+
* @private
|
|
134
|
+
*/
|
|
135
|
+
export const truncateMiddleWithTokenBudget = (
|
|
136
|
+
s: string,
|
|
137
|
+
maxTokens: number
|
|
138
|
+
): { readonly text: string; readonly originalTokenCount: number | undefined } => {
|
|
139
|
+
if (s === "") return { text: "", originalTokenCount: undefined }
|
|
140
|
+
if (maxTokens > 0 && byteLength(s) <= approxBytesForTokens(maxTokens)) {
|
|
141
|
+
return { text: s, originalTokenCount: undefined }
|
|
142
|
+
}
|
|
143
|
+
const truncated = truncateWithByteEstimate(s, approxBytesForTokens(maxTokens), true)
|
|
144
|
+
if (truncated === s) return { text: s, originalTokenCount: undefined }
|
|
145
|
+
return { text: truncated, originalTokenCount: approxTokenCount(s) }
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const countLines = (content: string): number => {
|
|
149
|
+
if (content === "") return 0
|
|
150
|
+
const parts = content.split("\n")
|
|
151
|
+
return parts[parts.length - 1] === "" ? parts.length - 1 : parts.length
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Codex `format_exec_output_for_model`: exit code, wall time, optional line
|
|
156
|
+
* count disclosure, then the (possibly middle-truncated) output.
|
|
157
|
+
*
|
|
158
|
+
* @since 1.0.0
|
|
159
|
+
* @private
|
|
160
|
+
*/
|
|
161
|
+
export const formatExecOutputForModel = (options: {
|
|
162
|
+
readonly output: string
|
|
163
|
+
readonly exitCode: number
|
|
164
|
+
readonly durationSeconds: number
|
|
165
|
+
readonly maxOutputTokens: number
|
|
166
|
+
readonly timedOutAfterMs?: number | undefined
|
|
167
|
+
}): string => {
|
|
168
|
+
const content = options.timedOutAfterMs === undefined
|
|
169
|
+
? options.output
|
|
170
|
+
: `command timed out after ${options.timedOutAfterMs} milliseconds\n${options.output}`
|
|
171
|
+
const durationSeconds = Math.round(options.durationSeconds * 10) / 10
|
|
172
|
+
const totalLines = countLines(content)
|
|
173
|
+
const formatted = truncateMiddleWithTokenBudget(content, options.maxOutputTokens).text
|
|
174
|
+
const sections = [
|
|
175
|
+
`Exit code: ${options.exitCode}`,
|
|
176
|
+
`Wall time: ${durationSeconds} seconds`
|
|
177
|
+
]
|
|
178
|
+
if (totalLines !== countLines(formatted)) sections.push(`Total output lines: ${totalLines}`)
|
|
179
|
+
sections.push("Output:")
|
|
180
|
+
sections.push(formatted)
|
|
181
|
+
return sections.join("\n")
|
|
182
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared declaration helpers for the standard flows.
|
|
3
|
+
*
|
|
4
|
+
* @since 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type * as Capability from "@smthrs/capability/Capability"
|
|
8
|
+
import * as Effects from "@smthrs/core/Effects"
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Options accepted by {@link envelope}.
|
|
12
|
+
*
|
|
13
|
+
* @category models
|
|
14
|
+
* @since 1.0.0
|
|
15
|
+
*/
|
|
16
|
+
export interface EnvelopeOptions {
|
|
17
|
+
readonly tier: "sealed" | "compensable" | "irreversible"
|
|
18
|
+
readonly mode: "hermetic" | "expected"
|
|
19
|
+
readonly reads: Iterable<string>
|
|
20
|
+
readonly writes: Iterable<string>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Builds a deterministic effect declaration for a standard flow.
|
|
25
|
+
*
|
|
26
|
+
* Every standard flow serializes on conflict: the library owns no lane
|
|
27
|
+
* partitioning of its own, so the conservative choice is the safe one.
|
|
28
|
+
*
|
|
29
|
+
* @category constructors
|
|
30
|
+
* @since 1.0.0
|
|
31
|
+
*/
|
|
32
|
+
export const envelope = (options: EnvelopeOptions): Effects.Declaration =>
|
|
33
|
+
Effects.make({
|
|
34
|
+
reads: options.reads,
|
|
35
|
+
writes: options.writes,
|
|
36
|
+
mode: options.mode,
|
|
37
|
+
onConflict: "serialize",
|
|
38
|
+
tier: options.tier
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Formats a capability request as the `action:resource` string carried on a
|
|
43
|
+
* flow declaration.
|
|
44
|
+
*
|
|
45
|
+
* @category constructors
|
|
46
|
+
* @since 1.0.0
|
|
47
|
+
*/
|
|
48
|
+
export const capability = (action: Capability.Action, resource: string): string => `${action}:${resource}`
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The read glob covering everything under one search root.
|
|
52
|
+
*
|
|
53
|
+
* `glob` and `grep` narrow their conservative `/**` declaration to the root the
|
|
54
|
+
* call actually names, and a declaration that disagreed between the two would
|
|
55
|
+
* make the same search reserve different paths depending on which flow ran it.
|
|
56
|
+
*
|
|
57
|
+
* @category constructors
|
|
58
|
+
* @since 1.0.0
|
|
59
|
+
*/
|
|
60
|
+
export const rootSubtree = (root: string): string => root === "/" ? "/**" : `${root.replace(/\/+$/, "")}/**`
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeps a bound language server in step with the files the mutation flows
|
|
3
|
+
* write, and reads back the errors an edit leaves.
|
|
4
|
+
*
|
|
5
|
+
* The server is optional: a host that binds no `LanguageServer` edits files
|
|
6
|
+
* exactly as before, and a server that fails or times out never fails the
|
|
7
|
+
* write that already happened.
|
|
8
|
+
*
|
|
9
|
+
* @since 1.0.0
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import * as Effect from "effect/Effect"
|
|
13
|
+
import * as Option from "effect/Option"
|
|
14
|
+
import * as Schema from "effect/Schema"
|
|
15
|
+
import * as LanguageServer from "../LanguageServer.ts"
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Most errors attached to one result.
|
|
19
|
+
*
|
|
20
|
+
* @category internal
|
|
21
|
+
* @since 1.0.0
|
|
22
|
+
*/
|
|
23
|
+
export const MAX_ERRORS = 20
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* One error-severity diagnostic, at its 1-based position.
|
|
27
|
+
*
|
|
28
|
+
* @category internal
|
|
29
|
+
* @since 1.0.0
|
|
30
|
+
*/
|
|
31
|
+
export const Problem = Schema.Struct({
|
|
32
|
+
line: Schema.Number.annotate({ description: "1-based line" }),
|
|
33
|
+
character: Schema.Number.annotate({ description: "1-based character" }),
|
|
34
|
+
message: Schema.String
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A decoded {@link Problem}.
|
|
39
|
+
*
|
|
40
|
+
* @category internal
|
|
41
|
+
* @since 1.0.0
|
|
42
|
+
*/
|
|
43
|
+
export type Problem = typeof Problem.Type
|
|
44
|
+
|
|
45
|
+
const record = (value: unknown): Readonly<Record<string, unknown>> | undefined =>
|
|
46
|
+
typeof value === "object" && value !== null && !Array.isArray(value)
|
|
47
|
+
? value as Readonly<Record<string, unknown>>
|
|
48
|
+
: undefined
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The error-severity items of a document diagnostic report, 1-based.
|
|
52
|
+
*
|
|
53
|
+
* @category internal
|
|
54
|
+
* @since 1.0.0
|
|
55
|
+
*/
|
|
56
|
+
export const errors = (report: unknown): ReadonlyArray<Problem> => {
|
|
57
|
+
const items = record(report)?.items
|
|
58
|
+
if (!Array.isArray(items)) return []
|
|
59
|
+
const found: Array<Problem> = []
|
|
60
|
+
for (const item of items) {
|
|
61
|
+
const diagnostic = record(item)
|
|
62
|
+
const start = record(record(diagnostic?.range)?.start)
|
|
63
|
+
if (
|
|
64
|
+
diagnostic?.severity !== 1 || typeof diagnostic.message !== "string" ||
|
|
65
|
+
typeof start?.line !== "number" || typeof start.character !== "number"
|
|
66
|
+
) continue
|
|
67
|
+
found.push({ line: start.line + 1, character: start.character + 1, message: diagnostic.message })
|
|
68
|
+
if (found.length === MAX_ERRORS) break
|
|
69
|
+
}
|
|
70
|
+
return found
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Sends a written file's new text to the bound server, if any. Succeeds with
|
|
75
|
+
* the server that took it.
|
|
76
|
+
*
|
|
77
|
+
* @category internal
|
|
78
|
+
* @since 1.0.0
|
|
79
|
+
*/
|
|
80
|
+
export const sync = (path: string, text: string): Effect.Effect<LanguageServer.LanguageServer | undefined> =>
|
|
81
|
+
Effect.serviceOption(LanguageServer.LanguageServer).pipe(
|
|
82
|
+
Effect.flatMap(Option.match({
|
|
83
|
+
onNone: () => Effect.succeed(undefined),
|
|
84
|
+
onSome: (server) =>
|
|
85
|
+
server.sync(path, text).pipe(
|
|
86
|
+
Effect.as(server),
|
|
87
|
+
Effect.orElseSucceed(() => undefined)
|
|
88
|
+
)
|
|
89
|
+
}))
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Tells the bound server, if any, that a file is gone.
|
|
94
|
+
*
|
|
95
|
+
* @category internal
|
|
96
|
+
* @since 1.0.0
|
|
97
|
+
*/
|
|
98
|
+
export const close = (path: string): Effect.Effect<void> =>
|
|
99
|
+
Effect.serviceOption(LanguageServer.LanguageServer).pipe(
|
|
100
|
+
Effect.flatMap(Option.match({
|
|
101
|
+
onNone: () => Effect.void,
|
|
102
|
+
onSome: (server) => server.close(path).pipe(Effect.ignore)
|
|
103
|
+
}))
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Tells the bound server, if any, to re-read every file it has open, after
|
|
108
|
+
* something other than the mutation flows may have changed them.
|
|
109
|
+
*
|
|
110
|
+
* @category internal
|
|
111
|
+
* @since 1.0.0
|
|
112
|
+
*/
|
|
113
|
+
export const refresh: Effect.Effect<void> = Effect.serviceOption(LanguageServer.LanguageServer).pipe(
|
|
114
|
+
Effect.flatMap(Option.match({
|
|
115
|
+
onNone: () => Effect.void,
|
|
116
|
+
onSome: (server) => server.refresh.pipe(Effect.ignore)
|
|
117
|
+
}))
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* The errors `server` reports for `path`, or `undefined` when it could not
|
|
122
|
+
* answer.
|
|
123
|
+
*
|
|
124
|
+
* @category internal
|
|
125
|
+
* @since 1.0.0
|
|
126
|
+
*/
|
|
127
|
+
export const errorsOf = (
|
|
128
|
+
server: LanguageServer.LanguageServer,
|
|
129
|
+
path: string
|
|
130
|
+
): Effect.Effect<ReadonlyArray<Problem> | undefined> =>
|
|
131
|
+
server.diagnostics(path).pipe(
|
|
132
|
+
Effect.map(errors),
|
|
133
|
+
Effect.orElseSucceed(() => undefined)
|
|
134
|
+
)
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The hermetic pre-check: a lexical scan of shell text for the paths it names,
|
|
3
|
+
* and the refusal when one of them falls outside the declared envelope.
|
|
4
|
+
*
|
|
5
|
+
* The scan is fail-closed over explicit path tokens and nothing more. It
|
|
6
|
+
* cannot prove confinement — a shell can name a path no lexer sees, through a
|
|
7
|
+
* variable, a substitution, or a program that opens a file of its own — so a
|
|
8
|
+
* kernel or host sandbox must eventually enforce and report the complete read
|
|
9
|
+
* and write sets.
|
|
10
|
+
*
|
|
11
|
+
* It lives beside the flow rather than inside it because it is its own
|
|
12
|
+
* concept, with its own vocabulary (Access, PathReference) and its own
|
|
13
|
+
* security history: three independent bypasses, each sufficient on its own to
|
|
14
|
+
* defeat it, are closed here.
|
|
15
|
+
*
|
|
16
|
+
* @since 1.0.0
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import type * as Path from "@smthrs/kernel/Path"
|
|
20
|
+
import * as StdError from "../StdError.ts"
|
|
21
|
+
import { withinEnvelope } from "./Paths.ts"
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The filesystem envelope one invocation declared.
|
|
25
|
+
*
|
|
26
|
+
* Structural rather than the hermetic `Bash.Input` itself: the scan needs the
|
|
27
|
+
* three fields and none of the rest, and depending on the flow module would
|
|
28
|
+
* make the flow and its pre-check import each other.
|
|
29
|
+
*
|
|
30
|
+
* @category models
|
|
31
|
+
* @since 1.0.0
|
|
32
|
+
*/
|
|
33
|
+
export interface Envelope {
|
|
34
|
+
readonly cwd?: string | undefined
|
|
35
|
+
readonly reads: ReadonlyArray<string>
|
|
36
|
+
readonly writes: ReadonlyArray<string>
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* How a command touches a path it names.
|
|
41
|
+
*
|
|
42
|
+
* @category models
|
|
43
|
+
* @since 1.0.0
|
|
44
|
+
*/
|
|
45
|
+
export type Access = "read" | "write"
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* One path a command names, and how it touches it.
|
|
49
|
+
*
|
|
50
|
+
* @category models
|
|
51
|
+
* @since 1.0.0
|
|
52
|
+
*/
|
|
53
|
+
export interface PathReference {
|
|
54
|
+
readonly access: Access
|
|
55
|
+
readonly value: string
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const commandSeparators = new Set(["&&", "||", ";", "|", "&", "\n"])
|
|
59
|
+
const redirections = new Set([">", ">>", "<", "<<"])
|
|
60
|
+
const writeCommands = new Set(["chmod", "chown", "mkdir", "rm", "rmdir", "tee", "touch", "truncate", "unlink"])
|
|
61
|
+
const destinationCommands = new Set(["cp", "install", "mv"])
|
|
62
|
+
const prefixWrappers = new Set(["env", "nice", "time", "sudo", "nohup", "xargs", "command", "exec"])
|
|
63
|
+
|
|
64
|
+
// Shell spaces may disappear, but a physical line ends one command. Retaining
|
|
65
|
+
// LF prevents a command on line one from classifying every later line's paths.
|
|
66
|
+
//
|
|
67
|
+
// A word is one or more runs of bare characters and quoted sections, not a
|
|
68
|
+
// bare run alone: `FOO="a b" rm /work/target` used to tokenize as `FOO="a`,
|
|
69
|
+
// `b"`, `rm`, `/work/target`, and since only the first token carried an `=`
|
|
70
|
+
// the command was read as `b"` rather than `rm` — so the delete was
|
|
71
|
+
// classified as a read and a hermetic call with `writes: []` spawned. The
|
|
72
|
+
// quoted alternatives come first inside the group so a quoted span is taken
|
|
73
|
+
// whole; the bare class excludes quotes so the branches cannot overlap.
|
|
74
|
+
const tokenize = (command: string): ReadonlyArray<string> =>
|
|
75
|
+
command.match(/\n|>>|<<|&&|\|\||[<>;|&]|(?:"(?:\\.|[^"\\])*"|'[^']*'|[^\s<>;|&"']+)+/g) ?? []
|
|
76
|
+
|
|
77
|
+
const unquote = (token: string): string => {
|
|
78
|
+
const first = token[0]
|
|
79
|
+
const last = token[token.length - 1]
|
|
80
|
+
return token.length >= 2 && (first === "'" || first === "\"") && last === first
|
|
81
|
+
? token.slice(1, -1)
|
|
82
|
+
: token
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const pathValue = (token: string): string =>
|
|
86
|
+
unquote(token)
|
|
87
|
+
.replace(/^\$\(+/, "")
|
|
88
|
+
.replace(/[),]+$/, "")
|
|
89
|
+
|
|
90
|
+
const isPathToken = (path: Path.Path, token: string): boolean =>
|
|
91
|
+
token === "." ||
|
|
92
|
+
token === ".." ||
|
|
93
|
+
token.startsWith("./") ||
|
|
94
|
+
token.startsWith("../") ||
|
|
95
|
+
path.isAbsolute(token) ||
|
|
96
|
+
/^[A-Za-z]:[\\/]/.test(token) ||
|
|
97
|
+
token.includes("/")
|
|
98
|
+
|
|
99
|
+
const segmentReferences = (path: Path.Path, tokens: ReadonlyArray<string>): ReadonlyArray<PathReference> => {
|
|
100
|
+
const commentIndex = tokens.findIndex((token) => token.startsWith("#"))
|
|
101
|
+
const active = commentIndex === -1 ? tokens : tokens.slice(0, commentIndex)
|
|
102
|
+
const hasWrapper = active.some((token) => prefixWrappers.has(path.basename(pathValue(token))))
|
|
103
|
+
let commandIndex = active.findIndex((token) =>
|
|
104
|
+
!redirections.has(token) &&
|
|
105
|
+
!token.includes("=") &&
|
|
106
|
+
!prefixWrappers.has(path.basename(pathValue(token))) &&
|
|
107
|
+
!token.startsWith("-") &&
|
|
108
|
+
token !== ""
|
|
109
|
+
)
|
|
110
|
+
if (hasWrapper) {
|
|
111
|
+
// Wrapper options can carry their own values. Prefer a later known
|
|
112
|
+
// mutating command so an option value cannot lend it a read classification.
|
|
113
|
+
const mutatingIndex = active.findIndex((token) => {
|
|
114
|
+
const command = path.basename(pathValue(token))
|
|
115
|
+
return writeCommands.has(command) || destinationCommands.has(command)
|
|
116
|
+
})
|
|
117
|
+
if (mutatingIndex !== -1) commandIndex = mutatingIndex
|
|
118
|
+
}
|
|
119
|
+
if (commandIndex === -1) return []
|
|
120
|
+
|
|
121
|
+
const command = path.basename(pathValue(active[commandIndex]!))
|
|
122
|
+
const candidates: Array<{ readonly index: number; readonly value: string }> = []
|
|
123
|
+
for (let index = 0; index < active.length; index++) {
|
|
124
|
+
const token = active[index]!
|
|
125
|
+
if (index === commandIndex || redirections.has(token) || token.startsWith("-")) continue
|
|
126
|
+
const value = pathValue(token)
|
|
127
|
+
if (value !== "" && isPathToken(path, value)) candidates.push({ index, value })
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const destinationIndex = destinationCommands.has(command)
|
|
131
|
+
? candidates[candidates.length - 1]?.index
|
|
132
|
+
: undefined
|
|
133
|
+
|
|
134
|
+
return candidates.map(({ index, value }) => {
|
|
135
|
+
const previous = active[index - 1]
|
|
136
|
+
const access: Access = previous === ">" || previous === ">>" ||
|
|
137
|
+
writeCommands.has(command) || destinationIndex === index
|
|
138
|
+
? "write"
|
|
139
|
+
: "read"
|
|
140
|
+
return { access, value }
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Every path token the shell text names, one segment at a time.
|
|
146
|
+
*
|
|
147
|
+
* @category pre-check
|
|
148
|
+
* @since 1.0.0
|
|
149
|
+
*/
|
|
150
|
+
export const commandReferences = (path: Path.Path, command: string): ReadonlyArray<PathReference> => {
|
|
151
|
+
const references: Array<PathReference> = []
|
|
152
|
+
let segment: Array<string> = []
|
|
153
|
+
for (const token of tokenize(command)) {
|
|
154
|
+
if (commandSeparators.has(token)) {
|
|
155
|
+
references.push(...segmentReferences(path, segment))
|
|
156
|
+
segment = []
|
|
157
|
+
} else {
|
|
158
|
+
segment.push(token)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
references.push(...segmentReferences(path, segment))
|
|
162
|
+
return references
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const resolvePath = (
|
|
166
|
+
path: Path.Path,
|
|
167
|
+
cwd: string,
|
|
168
|
+
value: string
|
|
169
|
+
): string => path.isAbsolute(value) ? path.normalize(value) : path.resolve(cwd, value)
|
|
170
|
+
|
|
171
|
+
const isDeclared = (
|
|
172
|
+
path: Path.Path,
|
|
173
|
+
cwd: string,
|
|
174
|
+
declared: ReadonlyArray<string>,
|
|
175
|
+
source: string
|
|
176
|
+
): boolean =>
|
|
177
|
+
withinEnvelope(
|
|
178
|
+
declared.map((entry) => resolvePath(path, cwd, entry)),
|
|
179
|
+
resolvePath(path, cwd, source)
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* The refusal shell text earns by naming a path outside its declared
|
|
184
|
+
* envelope, or `undefined` when every path it names is declared.
|
|
185
|
+
*
|
|
186
|
+
* @category pre-check
|
|
187
|
+
* @since 1.0.0
|
|
188
|
+
*/
|
|
189
|
+
export const outsideEnvelope = (
|
|
190
|
+
input: Envelope,
|
|
191
|
+
text: string,
|
|
192
|
+
path: Path.Path
|
|
193
|
+
): StdError.StdError | undefined => {
|
|
194
|
+
const base = path.resolve(".")
|
|
195
|
+
const cwd = path.resolve(input.cwd ?? ".")
|
|
196
|
+
// Passing the default explicitly is not a declaration the caller owes. A
|
|
197
|
+
// working directory is where the command runs, not a file it reads, and
|
|
198
|
+
// `cwd: "."` names exactly what omitting `cwd` names — so refusing it asked
|
|
199
|
+
// the caller to list the workspace root among its reads to say nothing at
|
|
200
|
+
// all. Agents hit this constantly: one SWE-bench run spent ten of its
|
|
201
|
+
// forty-eight tool calls re-issuing the same command after
|
|
202
|
+
// "Working directory is outside declared reads: <the workspace root>". A
|
|
203
|
+
// cwd that points somewhere else is still declared or refused.
|
|
204
|
+
if (input.cwd !== undefined && cwd !== base && !isDeclared(path, cwd, input.reads, cwd)) {
|
|
205
|
+
return new StdError.StdError({
|
|
206
|
+
code: "outside_declared_reads",
|
|
207
|
+
message: `Working directory is outside declared reads: ${cwd}`,
|
|
208
|
+
path: cwd
|
|
209
|
+
})
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// The Shell contract currently has no sandbox or access-reporting surface.
|
|
213
|
+
// This lexical scan is intentionally only a fail-closed pre-check for
|
|
214
|
+
// explicit path tokens. It cannot prove confinement; a kernel/host sandbox
|
|
215
|
+
// must eventually enforce and report the complete read and write sets.
|
|
216
|
+
for (const reference of commandReferences(path, text)) {
|
|
217
|
+
const resolved = resolvePath(path, cwd, reference.value)
|
|
218
|
+
// /dev/* is the process plumbing every shell one-liner leans on:
|
|
219
|
+
// `2>/dev/null`, `cat /dev/stdin`. Normalize first so a dot-dot segment
|
|
220
|
+
// cannot disguise an ordinary filesystem path as process plumbing.
|
|
221
|
+
if (resolved.startsWith("/dev/")) continue
|
|
222
|
+
const declared = reference.access === "write" ? input.writes : input.reads
|
|
223
|
+
if (!isDeclared(path, cwd, declared, resolved)) {
|
|
224
|
+
const code = reference.access === "write" ? "outside_declared_writes" : "outside_declared_reads"
|
|
225
|
+
return new StdError.StdError({
|
|
226
|
+
code,
|
|
227
|
+
message: `Command path is outside declared ${reference.access}s: ${resolved}`,
|
|
228
|
+
path: resolved
|
|
229
|
+
})
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return undefined
|
|
233
|
+
}
|