From 53541b110b17ee1aa18da604e223f35a29b686da Mon Sep 17 00:00:00 2001 From: can1357 Date: Mon, 19 Jan 2026 03:17:22 +0100 Subject: [PATCH] feat(coding-agent/core): added depth-controlled search and path utilities - Added maxdepth and mindepth parameters to find function for depth-controlled file search. - Added counter function to count occurrences and sort by frequency. - Added basenames function to extract base names from paths. - Fixed biome.json configuration to remove invalid double negation pattern. --- biome.json | 9 +--- packages/coding-agent/CHANGELOG.md | 5 ++ .../coding-agent/src/core/python-prelude.py | 47 ++++++++++++++++++- 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/biome.json b/biome.json index 8ca064def..abe534405 100644 --- a/biome.json +++ b/biome.json @@ -35,19 +35,14 @@ "files": { "includes": [ "packages/*/src/**/*.ts", - "!**/vendor/**/*", "packages/*/test/**/*.ts", "packages/coding-agent/examples/**/*.ts", - "packages/web-ui/src/**/*.ts", - "packages/web-ui/example/**/*.ts", + "!**/vendor/**/*", "!**/node_modules/**/*", "!**/test-sessions.ts", "!**/models.generated.ts", "!**/template.generated.ts", - "!**/gen/agent_pb.ts", - "!packages/web-ui/src/app.css", - "!packages/mom/data/**/*", - "!!**/node_modules" + "!**/gen/agent_pb.ts" ] }, "assist": { "actions": { "source": { "organizeImports": "on" } } } diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index a34a559d5..40c4ce3d7 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -1,6 +1,11 @@ # Changelog ## [Unreleased] +### Added + +- Added maxdepth and mindepth parameters to find function for depth-controlled file search +- Added counter function to count occurrences and sort by frequency +- Added basenames function to extract base names from paths ## [6.0.0] - 2026-01-19 diff --git a/packages/coding-agent/src/core/python-prelude.py b/packages/coding-agent/src/core/python-prelude.py index 0e03a823e..2d3652875 100644 --- a/packages/coding-agent/src/core/python-prelude.py +++ b/packages/coding-agent/src/core/python-prelude.py @@ -191,14 +191,26 @@ if "__omp_prelude_loaded__" not in globals(): limit: int = 1000, hidden: bool = False, sort_by_mtime: bool = False, + maxdepth: int | None = None, + mindepth: int | None = None, ) -> list[Path]: - """Recursive glob find. Respects .gitignore.""" - p = Path(path) + """Recursive glob find. Respects .gitignore. + + maxdepth/mindepth are relative to path (0 = path itself, 1 = direct children). + """ + p = Path(path).resolve() + base_depth = len(p.parts) ignore_patterns = _load_gitignore_patterns(p) matches: list[Path] = [] for m in p.rglob(pattern): if len(matches) >= limit: break + # Check depth constraints + rel_depth = len(m.resolve().parts) - base_depth + if maxdepth is not None and rel_depth > maxdepth: + continue + if mindepth is not None and rel_depth < mindepth: + continue # Skip hidden files unless requested if not hidden and any(part.startswith(".") for part in m.parts): continue @@ -485,6 +497,30 @@ if "__omp_prelude_loaded__" not in globals(): return groups return "\n".join(line for _, line in groups) + @_category("Text") + def counter( + items: str | list, + *, + limit: int | None = None, + reverse: bool = True, + ) -> list[tuple[int, str]]: + """Count occurrences and sort by frequency. Like sort | uniq -c | sort -rn. + + items: text (splits into lines) or list of strings + reverse: True for descending (most common first), False for ascending + Returns: [(count, item), ...] sorted by count + """ + from collections import Counter + if isinstance(items, str): + items = items.splitlines() + counts = Counter(items) + sorted_items = sorted(counts.items(), key=lambda x: (x[1], x[0]), reverse=reverse) + if limit is not None: + sorted_items = sorted_items[:limit] + result = [(count, item) for item, count in sorted_items] + _emit_status("counter", unique=len(counts), total=sum(counts.values()), top=result[:10]) + return result + @_category("Text") def cols(text: str, *indices: int, sep: str | None = None) -> str: """Extract columns from text (0-indexed). Like cut.""" @@ -497,6 +533,13 @@ if "__omp_prelude_loaded__" not in globals(): _emit_status("cols", lines=len(result_lines), columns=list(indices)) return out + @_category("Navigation") + def basenames(paths: list[str | Path]) -> list[str]: + """Extract basename from each path. Like: sed 's|.*/||'.""" + names = [Path(p).name for p in paths] + _emit_status("basenames", count=len(names), sample=names[:10]) + return names + @_category("Navigation") def tree(path: str | Path = ".", *, max_depth: int = 3, show_hidden: bool = False) -> str: """Return directory tree."""