Skip to content

Commit 8db2eef

Browse files
WARDEN: Lifecycle Assurance & Release v0.1.21
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: shenald-dev <245350826+shenald-dev@users.noreply.github.com>
1 parent db34979 commit 8db2eef

5 files changed

Lines changed: 27 additions & 2 deletions

File tree

.jules/bolt.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,11 @@ When passing raw user strings containing square brackets (like file paths, direc
116116

117117
Action:
118118
Always use `rich.markup.escape(str(variable))` before injecting unvalidated user-provided strings into `rich` print statements to guarantee safe output.
119+
120+
## 2026-04-28 — Pre-computing `_base_prefix` for Fast-Path Slicing
121+
122+
Learning:
123+
Inside the `_is_ignored_impl` hot path in `watchdog`, calling `os.path.relpath` for relative event paths when they could be sliced using `len(self._base_prefix)` introduced measurable latency in high-volume events. Additionally, generically calling `.removeprefix('./')` on paths could cause unexpected resolution regressions.
124+
125+
Action:
126+
Pre-compute `_base_prefix` during initialization (`os.path.join(self.base_path, '')`) and use it in `startswith()` alongside `_abs_base_path` for fast string slicing. Also removed the blind `.removeprefix('./')` behavior to improve robustness.

.jules/warden.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,11 @@ Observed the preceding agent optimized console logging by escaping string inputs
152152

153153
Alignment / Deferred:
154154
Version bumped to `0.1.20` as a patch release reflecting the crash fix. No dead code required pruning.
155+
156+
## 2026-04-28 — Assessment & Lifecycle
157+
158+
Observation / Pruned:
159+
Observed the preceding agent optimized the ignore file watcher hot path by pre-computing `_base_prefix` for fast string slicing of relative paths, mitigating `os.path.relpath` overhead during burst events. The `.removeprefix('./')` call was also removed to prevent potential path resolution regressions. Assured the logic remains structurally sound, and the test suite passes.
160+
161+
Alignment / Deferred:
162+
Version bumped to `0.1.21` as a patch release. Updated CHANGELOG.md. No dead code or dependency upgrades required.

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## [0.1.21] - 2026-04-28
4+
5+
### Changed
6+
* **[Performance]:** Optimized the file event hot path by pre-computing directory prefixes to use fast string slicing instead of `os.path.relpath`.
7+
* **[Reliability]:** Removed blanket `.removeprefix('./')` calls on event paths to prevent unexpected path resolution regressions.
8+
39
## [0.1.20] - 2026-04-27
410

511
### Changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "echo-watcher"
3-
version = "0.1.20"
3+
version = "0.1.21"
44
description = "📡 Lightweight file watcher. Trigger commands on changes. <5MB RAM, single binary."
55
authors = [
66
{ name = "shenald-dev", email = "bot@shenald.dev" }

src/echo/watcher.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def __init__(self, command: str, base_path: str = ".", ignore_patterns: list[str
2121
self.command = command
2222
self.base_path = base_path
2323
self._abs_base_path = os.path.join(os.path.abspath(base_path), '')
24+
self._base_prefix = os.path.join(self.base_path, '')
2425

2526
# Default ignore patterns
2627
default_ignores = [".git", "__pycache__", ".pytest_cache", ".ruff_cache", "node_modules", ".venv", "venv"]
@@ -166,6 +167,8 @@ def _run_command(self, event_path):
166167
def _is_ignored_impl(self, path: str) -> bool:
167168
if path.startswith(self._abs_base_path):
168169
path = path[len(self._abs_base_path):]
170+
elif path.startswith(self._base_prefix):
171+
path = path[len(self._base_prefix):]
169172
elif path == self.base_path or path == self._abs_base_path.rstrip(os.sep):
170173
path = "."
171174
else:
@@ -176,7 +179,7 @@ def _is_ignored_impl(self, path: str) -> bool:
176179
if not path:
177180
return False
178181

179-
normalized_path = path.replace('\\', '/').removeprefix('./')
182+
normalized_path = path.replace('\\', '/')
180183

181184
parts = normalized_path.split('/')
182185
if not self.exact_ignores.isdisjoint(parts):

0 commit comments

Comments
 (0)