@theokit/sdk-tools 0.15.0 → 0.15.1
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 +11 -0
- package/dist/index.cjs +19 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +19 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.15.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4c5bd35: M15 review fixes (injected fs path only; local path unaffected): (1) the backend directory walk in
|
|
8
|
+
`glob_files`/`search_text` decides entry type via `stat` (which follows symlinks), so an in-boundary
|
|
9
|
+
symlink cycle could recurse until PATH_MAX — now depth-capped so it terminates; (2) `edit_file`'s
|
|
10
|
+
backend read mapped every failure to `not_found` — now only a genuinely missing file (`FileNotFoundError`)
|
|
11
|
+
maps to `not_found`; any other read error (e.g. a directory, a permission error) propagates (fail-loud),
|
|
12
|
+
matching the local path's ENOENT-only classification.
|
|
13
|
+
|
|
3
14
|
## 0.15.0
|
|
4
15
|
|
|
5
16
|
### Minor Changes
|
package/dist/index.cjs
CHANGED
|
@@ -381,8 +381,11 @@ async function editViaBackend(filesystem$1, ctx, path, old_string, new_string) {
|
|
|
381
381
|
let content;
|
|
382
382
|
try {
|
|
383
383
|
content = await backend.readFile(path);
|
|
384
|
-
} catch {
|
|
385
|
-
|
|
384
|
+
} catch (err) {
|
|
385
|
+
if (err instanceof filesystem.FileNotFoundError) {
|
|
386
|
+
return JSON.stringify({ ok: false, error: "not_found", path });
|
|
387
|
+
}
|
|
388
|
+
throw err;
|
|
386
389
|
}
|
|
387
390
|
const outcome = computeEdit(content, old_string, new_string);
|
|
388
391
|
if (!outcome.ok) return JSON.stringify({ ok: false, error: "no_match", path });
|
|
@@ -656,6 +659,7 @@ function runGitProcess(cwd, args, timeoutMs, maxStdoutBytes) {
|
|
|
656
659
|
});
|
|
657
660
|
}
|
|
658
661
|
var DEFAULT_EXCLUDES = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", ".theo"]);
|
|
662
|
+
var MAX_BACKEND_WALK_DEPTH = 64;
|
|
659
663
|
function createGlobTool(opts) {
|
|
660
664
|
const { projectRoot, filesystem: filesystem$1 } = opts;
|
|
661
665
|
return sdk.Tool.create({
|
|
@@ -673,7 +677,7 @@ function createGlobTool(opts) {
|
|
|
673
677
|
const backend = await filesystem.resolveFilesystem(filesystem$1, ctx ?? {});
|
|
674
678
|
const searchRel = cwd ?? "";
|
|
675
679
|
const found = [];
|
|
676
|
-
await walkDirBackend(backend, searchRel, searchRel, regex, found);
|
|
680
|
+
await walkDirBackend(backend, searchRel, searchRel, regex, found, 0);
|
|
677
681
|
return JSON.stringify({ ok: true, files: found.sort(), count: found.length });
|
|
678
682
|
}
|
|
679
683
|
const searchRoot = cwd ? safePathJoin(projectRoot, cwd) : projectRoot;
|
|
@@ -714,7 +718,8 @@ async function walkDir(base, dir, pattern, results) {
|
|
|
714
718
|
}
|
|
715
719
|
}
|
|
716
720
|
}
|
|
717
|
-
async function walkDirBackend(backend, base, dir, pattern, results) {
|
|
721
|
+
async function walkDirBackend(backend, base, dir, pattern, results, depth) {
|
|
722
|
+
if (depth > MAX_BACKEND_WALK_DEPTH) return;
|
|
718
723
|
let names;
|
|
719
724
|
try {
|
|
720
725
|
names = await backend.list(dir);
|
|
@@ -722,10 +727,10 @@ async function walkDirBackend(backend, base, dir, pattern, results) {
|
|
|
722
727
|
return;
|
|
723
728
|
}
|
|
724
729
|
for (const name of names) {
|
|
725
|
-
await walkBackendEntry(backend, base, dir, name, pattern, results);
|
|
730
|
+
await walkBackendEntry(backend, base, dir, name, pattern, results, depth);
|
|
726
731
|
}
|
|
727
732
|
}
|
|
728
|
-
async function walkBackendEntry(backend, base, dir, name, pattern, results) {
|
|
733
|
+
async function walkBackendEntry(backend, base, dir, name, pattern, results, depth) {
|
|
729
734
|
if (DEFAULT_EXCLUDES.has(name)) return;
|
|
730
735
|
const fullRel = dir === "" ? name : `${dir}/${name}`;
|
|
731
736
|
const relPath = base === "" ? fullRel : path.relative(base, fullRel);
|
|
@@ -736,7 +741,7 @@ async function walkBackendEntry(backend, base, dir, name, pattern, results) {
|
|
|
736
741
|
return;
|
|
737
742
|
}
|
|
738
743
|
if (st.isDirectory) {
|
|
739
|
-
await walkDirBackend(backend, base, fullRel, pattern, results);
|
|
744
|
+
await walkDirBackend(backend, base, fullRel, pattern, results, depth + 1);
|
|
740
745
|
} else if (st.isFile && pattern.test(relPath)) {
|
|
741
746
|
results.push(fullRel);
|
|
742
747
|
}
|
|
@@ -1808,6 +1813,7 @@ var DEFAULT_MAX_MATCHES = 100;
|
|
|
1808
1813
|
var DEFAULT_MAX_FILE_SIZE = 1024 * 1024;
|
|
1809
1814
|
var BINARY_PROBE_BYTES2 = 8 * 1024;
|
|
1810
1815
|
var PREVIEW_MAX = 200;
|
|
1816
|
+
var MAX_BACKEND_WALK_DEPTH2 = 64;
|
|
1811
1817
|
function createSearchTextTool(opts) {
|
|
1812
1818
|
const {
|
|
1813
1819
|
projectRoot,
|
|
@@ -1836,7 +1842,7 @@ function createSearchTextTool(opts) {
|
|
|
1836
1842
|
const scopeRel = resolveScopeRel(path, projectRoot);
|
|
1837
1843
|
if ("error" in scopeRel) return scopeRel.error;
|
|
1838
1844
|
const backend = await filesystem.resolveFilesystem(filesystem$1, ctx ?? {});
|
|
1839
|
-
await walkBackend(backend, scopeRel.rel, state);
|
|
1845
|
+
await walkBackend(backend, scopeRel.rel, state, 0);
|
|
1840
1846
|
return JSON.stringify({
|
|
1841
1847
|
ok: true,
|
|
1842
1848
|
matches: state.matches,
|
|
@@ -1946,8 +1952,9 @@ function resolveScopeRel(path, projectRoot) {
|
|
|
1946
1952
|
throw err;
|
|
1947
1953
|
}
|
|
1948
1954
|
}
|
|
1949
|
-
async function walkBackend(backend, dirRel, state) {
|
|
1955
|
+
async function walkBackend(backend, dirRel, state, depth) {
|
|
1950
1956
|
if (state.truncated) return;
|
|
1957
|
+
if (depth > MAX_BACKEND_WALK_DEPTH2) return;
|
|
1951
1958
|
let names;
|
|
1952
1959
|
try {
|
|
1953
1960
|
names = await backend.list(dirRel);
|
|
@@ -1956,10 +1963,10 @@ async function walkBackend(backend, dirRel, state) {
|
|
|
1956
1963
|
}
|
|
1957
1964
|
for (const name of names) {
|
|
1958
1965
|
if (state.truncated) return;
|
|
1959
|
-
await handleBackendEntry(backend, dirRel, name, state);
|
|
1966
|
+
await handleBackendEntry(backend, dirRel, name, state, depth);
|
|
1960
1967
|
}
|
|
1961
1968
|
}
|
|
1962
|
-
async function handleBackendEntry(backend, dirRel, name, state) {
|
|
1969
|
+
async function handleBackendEntry(backend, dirRel, name, state, depth) {
|
|
1963
1970
|
const entryRel = dirRel === "" ? name : `${dirRel}/${name}`;
|
|
1964
1971
|
if (isForbiddenPath(entryRel)) return;
|
|
1965
1972
|
let st;
|
|
@@ -1969,7 +1976,7 @@ async function handleBackendEntry(backend, dirRel, name, state) {
|
|
|
1969
1976
|
return;
|
|
1970
1977
|
}
|
|
1971
1978
|
if (st.isDirectory) {
|
|
1972
|
-
await walkBackend(backend, entryRel, state);
|
|
1979
|
+
await walkBackend(backend, entryRel, state, depth + 1);
|
|
1973
1980
|
} else if (st.isFile) {
|
|
1974
1981
|
await scanFileBackend(backend, entryRel, st.size, state);
|
|
1975
1982
|
}
|