From 166b68b72c9cb70d122db3c52b8f6cb873ce956f Mon Sep 17 00:00:00 2001 From: AIOSAI Date: Wed, 22 Apr 2026 20:11:46 -0700 Subject: [PATCH] fix(seedgo): CWD-first _find_registry() in 3 handlers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bypass_handler.py, diagnostics/discovery.py, readme_ops.py all walked from __file__ only — finds AIPass registry even when CWD is an external project. Now follows audit/discovery.py pattern: CWD parents first, __file__ fallback, *_REGISTRY.json glob instead of hardcoded name. Removed module-level REGISTRY_PATH caching from bypass_handler and readme_ops (lazy call instead). --- .../apps/handlers/bypass/bypass_handler.py | 23 ++++++++------- .../apps/handlers/diagnostics/discovery.py | 13 ++++++--- .../seedgo/apps/handlers/readme/readme_ops.py | 28 +++++++++++-------- 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/aipass/seedgo/apps/handlers/bypass/bypass_handler.py b/src/aipass/seedgo/apps/handlers/bypass/bypass_handler.py index 61cb9e40..a30c265b 100644 --- a/src/aipass/seedgo/apps/handlers/bypass/bypass_handler.py +++ b/src/aipass/seedgo/apps/handlers/bypass/bypass_handler.py @@ -57,18 +57,20 @@ BYPASS_TEMPLATE = { def _find_registry() -> Path: - """Find AIPASS_REGISTRY.json by walking up from this file's location.""" + """Find *_REGISTRY.json — CWD-first for external project support, then __file__ fallback.""" + cwd = Path.cwd() + for parent in [cwd] + list(cwd.parents): + matches = sorted(parent.glob("*_REGISTRY.json")) + if matches: + return matches[0] current = Path(__file__).resolve().parent for parent in [current] + list(current.parents): - candidate = parent / "AIPASS_REGISTRY.json" - if candidate.exists(): - return candidate + matches = sorted(parent.glob("*_REGISTRY.json")) + if matches: + return matches[0] return Path.cwd() / "AIPASS_REGISTRY.json" -REGISTRY_PATH = _find_registry() - - # ============================================================================= # PUBLIC API # ============================================================================= @@ -85,16 +87,17 @@ def get_branch_from_path(file_path: str) -> Optional[Dict[str, Any]]: Branch dict with name, path, etc. or None if not in a branch """ try: - if not REGISTRY_PATH.exists(): + registry_path = _find_registry() + if not registry_path.exists(): logger.warning("[bypass_handler] AIPASS_REGISTRY.json not found") return None - with open(REGISTRY_PATH, "r", encoding="utf-8") as f: + with open(registry_path, "r", encoding="utf-8") as f: registry = json.load(f) file_path = str(Path(file_path).resolve()) - registry_dir = REGISTRY_PATH.parent + registry_dir = registry_path.parent def _resolve(raw: str) -> str: p = Path(raw) diff --git a/src/aipass/seedgo/apps/handlers/diagnostics/discovery.py b/src/aipass/seedgo/apps/handlers/diagnostics/discovery.py index 21554e37..79673827 100644 --- a/src/aipass/seedgo/apps/handlers/diagnostics/discovery.py +++ b/src/aipass/seedgo/apps/handlers/diagnostics/discovery.py @@ -21,12 +21,17 @@ from aipass.seedgo.apps.handlers.json import json_handler def _find_registry() -> Path: - """Find AIPASS_REGISTRY.json by walking up from this file's location.""" + """Find *_REGISTRY.json — CWD-first for external project support, then __file__ fallback.""" + cwd = Path.cwd() + for parent in [cwd] + list(cwd.parents): + matches = sorted(parent.glob("*_REGISTRY.json")) + if matches: + return matches[0] current = Path(__file__).resolve().parent for parent in [current] + list(current.parents): - candidate = parent / "AIPASS_REGISTRY.json" - if candidate.exists(): - return candidate + matches = sorted(parent.glob("*_REGISTRY.json")) + if matches: + return matches[0] return Path.cwd() / "AIPASS_REGISTRY.json" diff --git a/src/aipass/seedgo/apps/handlers/readme/readme_ops.py b/src/aipass/seedgo/apps/handlers/readme/readme_ops.py index e40fce28..a0a7a290 100644 --- a/src/aipass/seedgo/apps/handlers/readme/readme_ops.py +++ b/src/aipass/seedgo/apps/handlers/readme/readme_ops.py @@ -31,16 +31,20 @@ from aipass.seedgo.apps.handlers.json import json_handler def _find_registry() -> Path: - """Find AIPASS_REGISTRY.json by walking up from this file's location.""" + """Find *_REGISTRY.json — CWD-first for external project support, then __file__ fallback.""" + cwd = Path.cwd() + for parent in [cwd] + list(cwd.parents): + matches = sorted(parent.glob("*_REGISTRY.json")) + if matches: + return matches[0] current = Path(__file__).resolve().parent for parent in [current] + list(current.parents): - candidate = parent / "AIPASS_REGISTRY.json" - if candidate.exists(): - return candidate + matches = sorted(parent.glob("*_REGISTRY.json")) + if matches: + return matches[0] return Path.cwd() / "AIPASS_REGISTRY.json" -REGISTRY_PATH = _find_registry() # Generator lives in same handlers/standards/ directory as this file GENERATOR_PATH = Path(__file__).resolve().parent / "readme_generator.py" @@ -69,14 +73,15 @@ def resolve_branch(branch_arg: str) -> Optional[Dict]: Returns: Branch dict from registry, or None if not found """ - if not REGISTRY_PATH.exists(): + registry_path = _find_registry() + if not registry_path.exists(): return None try: - content = REGISTRY_PATH.read_text(encoding="utf-8") + content = registry_path.read_text(encoding="utf-8") registry = json.loads(content) except (json.JSONDecodeError, OSError): - logger.info("Cannot read registry for branch resolution: %s", REGISTRY_PATH) + logger.info("Cannot read registry for branch resolution: %s", registry_path) return None # Strip @ prefix and normalize @@ -101,15 +106,16 @@ def get_all_branches() -> List[Dict]: Returns: List of branch dicts, or empty list on failure """ - if not REGISTRY_PATH.exists(): + registry_path = _find_registry() + if not registry_path.exists(): return [] try: - content = REGISTRY_PATH.read_text(encoding="utf-8") + content = registry_path.read_text(encoding="utf-8") registry = json.loads(content) return registry.get("branches", []) except (json.JSONDecodeError, OSError): - logger.info("Cannot read registry for branch listing: %s", REGISTRY_PATH) + logger.info("Cannot read registry for branch listing: %s", registry_path) return []