diff --git a/.gitignore b/.gitignore index 17ea1d3a..3cb62641 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,6 @@ aipass_json/ setup-workspace.sh + +# Local cheat sheets (not source code) +# Docker.md diff --git a/AIPASS_REGISTRY.json b/AIPASS_REGISTRY.json index c124468f..4d58baff 100644 --- a/AIPASS_REGISTRY.json +++ b/AIPASS_REGISTRY.json @@ -37,7 +37,7 @@ }, { "name": "DEVPULSE", - "path": "/home/aipass/aipass_business/AIPass/src/aipass/devpulse", + "path": "src/aipass/devpulse", "profile": "library", "description": "Orchestration hub for AIPass public repo. Manages dev notes, DPLANs, system status dashboards. The DEV_CENTRAL of AIPass.", "email": "@devpulse", diff --git a/src/aipass/seedgo/apps/standards/aipass/handlers/audit/discovery.py b/src/aipass/seedgo/apps/standards/aipass/handlers/audit/discovery.py index 8f45a4f6..33cd7eb9 100644 --- a/src/aipass/seedgo/apps/standards/aipass/handlers/audit/discovery.py +++ b/src/aipass/seedgo/apps/standards/aipass/handlers/audit/discovery.py @@ -31,11 +31,12 @@ import json def _is_branch_private(branch_name: str) -> bool: """Check if branch is in the private registry.""" - registry_path = Path.home() / "PRIVATE_BRANCH_REGISTRY.json" - if not registry_path.exists(): + registry_path = _find_registry() + priv_path = registry_path.parent / "PRIVATE_BRANCH_REGISTRY.json" if registry_path.exists() else None + if not priv_path or not priv_path.exists(): return False try: - with open(registry_path, 'r', encoding='utf-8') as f: + with open(priv_path, 'r', encoding='utf-8') as f: registry = json.load(f) for branch in registry.get("branches", []): if branch.get("name", "").upper() == branch_name.upper(): diff --git a/src/aipass/seedgo/apps/standards/aipass/handlers/diagnostics/discovery.py b/src/aipass/seedgo/apps/standards/aipass/handlers/diagnostics/discovery.py index a0386658..48a59247 100644 --- a/src/aipass/seedgo/apps/standards/aipass/handlers/diagnostics/discovery.py +++ b/src/aipass/seedgo/apps/standards/aipass/handlers/diagnostics/discovery.py @@ -1,42 +1,68 @@ """ Branch Discovery Handler -Discovers all branches from the registry for diagnostics scanning. +Discovers all branches from AIPASS_REGISTRY.json for diagnostics scanning. """ # =================== META ==================== # Name: discovery.py # Description: Branch Discovery Handler -# Version: 1.0.0 +# Version: 2.0.0 # Created: 2026-03-05 -# Modified: 2026-03-05 +# Modified: 2026-03-06 # ============================================= +import json +from pathlib import Path from typing import Dict, List +def _find_registry() -> Path: + """Find AIPASS_REGISTRY.json by walking up from this file's location.""" + current = Path(__file__).resolve().parent + for parent in [current] + list(current.parents): + candidate = parent / "AIPASS_REGISTRY.json" + if candidate.exists(): + return candidate + return Path.cwd() / "AIPASS_REGISTRY.json" + + def discover_branches() -> List[Dict]: """ - Discover all branches from registry + Discover all branches from AIPASS_REGISTRY.json for diagnostics. Returns: List of dicts with 'name' and 'path' keys """ - import sys - from pathlib import Path + branches = [] + registry_path = _find_registry() - # Infrastructure - AIPASS_ROOT = Path.home() / "aipass_core" - sys.path.insert(0, str(AIPASS_ROOT)) - sys.path.insert(0, str(Path.home())) - - # Import at function level to avoid orchestration at module level - from drone.apps.modules import get_all_branches + if not registry_path.exists(): + return branches try: - branches = get_all_branches() - return branches - except Exception as e: + with open(registry_path, 'r', encoding='utf-8') as f: + registry_data = json.load(f) + + registry_dir = registry_path.parent + + for branch in registry_data.get('branches', []): + branch_name = branch.get('name', '') + raw_path = branch.get('path', '') + branch_path = Path(raw_path) + + if not branch_path.is_absolute(): + branch_path = (registry_dir / branch_path).resolve() + + if branch_path.exists(): + branches.append({ + 'name': branch_name, + 'path': str(branch_path) + }) + + return sorted(branches, key=lambda x: x['name']) + + except (json.JSONDecodeError, IOError) as e: print(f"Error discovering branches: {e}") - return [] + return branches diff --git a/src/aipass/seedgo/apps/standards/aipass/handlers/standards/architecture_check.py b/src/aipass/seedgo/apps/standards/aipass/handlers/standards/architecture_check.py index 60b413b8..3c5ef967 100644 --- a/src/aipass/seedgo/apps/standards/aipass/handlers/standards/architecture_check.py +++ b/src/aipass/seedgo/apps/standards/aipass/handlers/standards/architecture_check.py @@ -411,7 +411,7 @@ def check_template_baseline(module_path: str, bypass_rules: list | None = None) # Find the branch root (parent of apps/ directory) current = path.parent - while current != Path.home() and current.name != '/': + while current != current.parent: if current.name == 'apps' and current.parent: branch_path = current.parent break diff --git a/src/aipass/seedgo/apps/standards/aipass/handlers/standards/readme_generator.py b/src/aipass/seedgo/apps/standards/aipass/handlers/standards/readme_generator.py index ade960fa..f1d57ee6 100644 --- a/src/aipass/seedgo/apps/standards/aipass/handlers/standards/readme_generator.py +++ b/src/aipass/seedgo/apps/standards/aipass/handlers/standards/readme_generator.py @@ -661,7 +661,7 @@ def update_readme_auto_sections(branch_path: str, dry_run: bool = False) -> dict if __name__ == "__main__": - target = sys.argv[1] if len(sys.argv) > 1 else str(Path.home() / "aipass_core" / "cortex") + target = sys.argv[1] if len(sys.argv) > 1 else str(Path.cwd()) print(f"Generating README sections for: {target}\n{'='*70}") sections = generate_all_sections(target) for name, content in sections.items(): diff --git a/src/aipass/seedgo/apps/standards/aipass/handlers/standards/readme_ops.py b/src/aipass/seedgo/apps/standards/aipass/handlers/standards/readme_ops.py index bc37be73..f9dfabb9 100644 --- a/src/aipass/seedgo/apps/standards/aipass/handlers/standards/readme_ops.py +++ b/src/aipass/seedgo/apps/standards/aipass/handlers/standards/readme_ops.py @@ -28,8 +28,18 @@ from typing import Dict, List, Optional # CONSTANTS # ============================================================================= -REGISTRY_PATH = Path.home() / "BRANCH_REGISTRY.json" -GENERATOR_PATH = Path.home() / "seed" / "apps" / "handlers" / "standards" / "readme_generator.py" +def _find_registry() -> Path: + """Find AIPASS_REGISTRY.json by walking up from this file's location.""" + current = Path(__file__).resolve().parent + for parent in [current] + list(current.parents): + candidate = parent / "AIPASS_REGISTRY.json" + if candidate.exists(): + return candidate + 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" # Section display names for output SECTION_NAMES = { diff --git a/src/aipass/seedgo/apps/standards/aipass/handlers/verify/command_check.py b/src/aipass/seedgo/apps/standards/aipass/handlers/verify/command_check.py index 61873431..77769f9a 100644 --- a/src/aipass/seedgo/apps/standards/aipass/handlers/verify/command_check.py +++ b/src/aipass/seedgo/apps/standards/aipass/handlers/verify/command_check.py @@ -33,7 +33,7 @@ def check_command_consistency() -> Dict: Returns: Dict with check results """ - seed_path = Path.home() / "seed" + seed_path = Path(__file__).resolve().parents[5] # -> seedgo root missing_docs = [] # Define command flags to check (source of truth: where they're implemented) diff --git a/src/aipass/seedgo/apps/standards/aipass/handlers/verify/freshness_check.py b/src/aipass/seedgo/apps/standards/aipass/handlers/verify/freshness_check.py index 0222d0a4..0b10fb42 100644 --- a/src/aipass/seedgo/apps/standards/aipass/handlers/verify/freshness_check.py +++ b/src/aipass/seedgo/apps/standards/aipass/handlers/verify/freshness_check.py @@ -26,7 +26,7 @@ def check_file_freshness() -> Dict: Returns: Dict with check results """ - seed_path = Path.home() / "seed" + seed_path = Path(__file__).resolve().parents[5] # -> seedgo root issues = [] # Check if standards_audit.py exists diff --git a/src/aipass/seedgo/apps/standards/aipass/handlers/verify/help_check.py b/src/aipass/seedgo/apps/standards/aipass/handlers/verify/help_check.py index b67feb4e..bd654d16 100644 --- a/src/aipass/seedgo/apps/standards/aipass/handlers/verify/help_check.py +++ b/src/aipass/seedgo/apps/standards/aipass/handlers/verify/help_check.py @@ -29,7 +29,7 @@ def check_help_consistency() -> Dict: Returns: Dict with check results """ - seed_file = Path.home() / "seed" / "apps" / "seed.py" + seed_file = Path(__file__).resolve().parents[5] / "apps" / "seedgo.py" # seedgo root / apps / seedgo.py issues = [] if not seed_file.exists(): diff --git a/src/aipass/seedgo/apps/standards/aipass/handlers/verify/stale_check.py b/src/aipass/seedgo/apps/standards/aipass/handlers/verify/stale_check.py index e6c4008e..781ba98f 100644 --- a/src/aipass/seedgo/apps/standards/aipass/handlers/verify/stale_check.py +++ b/src/aipass/seedgo/apps/standards/aipass/handlers/verify/stale_check.py @@ -29,7 +29,7 @@ def check_stale_patterns() -> Dict: Returns: Dict with check results """ - seed_path = Path.home() / "seed" + seed_path = Path(__file__).resolve().parents[5] # -> seedgo root deprecated_patterns = ignore_handler.get_deprecated_patterns() violations = [] diff --git a/src/aipass/seedgo/apps/standards/aipass/modules/cli_standard.py b/src/aipass/seedgo/apps/standards/aipass/modules/cli_standard.py index 44c1f431..45a43d2b 100755 --- a/src/aipass/seedgo/apps/standards/aipass/modules/cli_standard.py +++ b/src/aipass/seedgo/apps/standards/aipass/modules/cli_standard.py @@ -121,7 +121,7 @@ def print_standard(): def run_demo(): """Run the CLI layout demo""" import subprocess - demo_path = "/home/aipass/aipass_core/cli/tools/cli_layout_demo.py" + demo_path = str(Path(__file__).resolve().parents[3] / "cli" / "tools" / "cli_layout_demo.py") console.print() console.print("[bold cyan]Running CLI Demo...[/bold cyan]") diff --git a/src/aipass/seedgo/apps/standards/aipass/modules/standards_audit.py b/src/aipass/seedgo/apps/standards/aipass/modules/standards_audit.py index a37e0514..65ddd193 100755 --- a/src/aipass/seedgo/apps/standards/aipass/modules/standards_audit.py +++ b/src/aipass/seedgo/apps/standards/aipass/modules/standards_audit.py @@ -100,34 +100,13 @@ def handle_command(command: str, args: List[str]) -> bool: # If targeting a private branch directly, only allow audit from inside # that branch's directory. This enforces isolation per DPLAN-035. if specific_branch and _is_branch_private(specific_branch): - # Resolve branch path from registry to check CWD - import json as _json - _registry_path = Path.home() / "BRANCH_REGISTRY.json" + # Look up branch path from discovered branches (uses registry internally) _branch_path = None - if _registry_path.exists(): - try: - with open(_registry_path, 'r', encoding='utf-8') as _f: - _reg = _json.load(_f) - for _b in _reg.get('branches', []): - if _b.get('name', '').upper() == specific_branch.upper(): - _branch_path = Path(_b['path']) - break - except (ValueError, IOError): - pass - - # Also check PRIVATE_BRANCH_REGISTRY for path - if _branch_path is None: - _priv_path = Path.home() / "PRIVATE_BRANCH_REGISTRY.json" - if _priv_path.exists(): - try: - with open(_priv_path, 'r', encoding='utf-8') as _f: - _priv = _json.load(_f) - for _b in _priv.get('branches', []): - if _b.get('name', '').upper() == specific_branch.upper(): - _branch_path = Path(_b['path']) - break - except (ValueError, IOError): - pass + _priv_branches = discover_branches(include_private=True) + for _b in _priv_branches: + if _b['name'].upper() == specific_branch.upper(): + _branch_path = Path(_b['path']) + break if _branch_path is not None: cwd = Path.cwd()