Files
AIPass/src/aipass/backup/apps/handlers/config/config_handler.py
T
AIOSAIandClaude Opus 4.6 babedd9c64 feat(system): seedgo v2 operational, full system audit, 14/15 branches at 99%
Three days of intensive work bringing seedgo to full operational status
and driving all branches through comprehensive standards compliance.

Seedgo v2.0.0:
- 22 checkers active (up from 20), standards pack fully operational
- New introspection standard researched from Dev-Pass, FPLAN-0017 open
- Bypass system for false positives (.seedgo config)
- Standards query and audit commands fully functional

System-wide audit (FPLAN-0016):
- All 14 auditable branches at 99%+ compliance
- CLI imports standardized across all branches (console from cli.apps.modules)
- handle_command(command, args) → bool contract added to all modules
- print_help() function naming fixed for checker pattern matching
- Handler extraction: large modules split, file I/O moved to handler layer
- New handlers created across ai_mail, backup, daemon, flow, skills, spawn, seedgo

Branch-specific highlights:
- ai_mail: email.py split 840→420 lines, 4 new handlers
- flow: dplan_flow.py 688→591 lines, 4 new handlers
- seedgo: massive restructure — standards moved to handlers/aipass_standards/,
  old standards/ tree removed, bypass system added, diagnostics module
- commons: database module added, CLI imports fixed
- skills: 5 handle_commands added, help function renamed
- trigger: error reporter handler, handle_command routing
- All branches: consistent architecture, clean drone routing

Culture doc (CLAUDE.md) added — documents AIPass philosophy, identity,
memory system, and collaboration principles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 01:26:42 -07:00

482 lines
14 KiB
Python
Executable File

# =================== AIPass ====================
# Name: config_handler.py
# Description: Backup system configuration and patterns
# Version: 2.0.2
# Created: 2025-11-23
# Modified: 2026-03-09
# =============================================
"""
Backup System Configuration Handler
Centralized configuration management for backup system.
Contains all backup modes, ignore patterns, and configuration constants.
Pure configuration with helper functions for pattern access and filtering.
"""
# =============================================
# IMPORTS
# =============================================
from pathlib import Path
from typing import Dict, Set, List, Optional
# =============================================
# CONFIGURATION CONSTANTS
# =============================================
# Base backup directory - dynamically determined relative to branch root
# Module is in apps/handlers/config/, so parent.parent.parent.parent gets to branch root
BASE_BACKUP_DIR = str(Path(__file__).parent.parent.parent.parent / "backups")
# Specific backup destinations for each system
BACKUP_DESTINATIONS = {
"system_snapshot": f"{BASE_BACKUP_DIR}",
"versioned_backup": f"{BASE_BACKUP_DIR}",
}
# =============================================
# IGNORE PATTERNS
# =============================================
# Global ignore patterns (what NOT to backup across all systems)
GLOBAL_IGNORE_PATTERNS = [
# Python cache and temp files
"__pycache__",
"*.pyc",
"*.pyo",
# Virtual environments
".venv",
"venv",
# Node.js
"node_modules",
"npm-debug.log",
"yarn-error.log",
# Operating system files
".DS_Store",
"Thumbs.db",
"desktop.ini",
"nul", # Windows reserved filename issue
# Temporary files
#"temp",
".temp",
"tmp",
".tmp",
"*.tmp",
"*.temp",
# Build and distribution directories
"build",
"dist",
"install",
"lib",
"bin",
# IDE and editor files
"*.swp",
"*.swo",
"*~",
# Backup directories (prevent recursive backups) - CRITICAL!
"backups", # Matches any directory named "backups"
"backup_system/backups", # Explicit path to our backup directory
"*/backups", # Any backups subdirectory
"system_snapshot", # Snapshot backup folder name
"versioned_backup", # Versioned backup folder name
"deleted_branches", # Deleted/archived branches (trash folder)
# System backups and trash
"TimeShift*",
"timeshift*",
".local/share/Trash",
"Trash",
# Linux system directories (don't backup user settings/cache)
".local",
".cache",
".config",
".mozilla",
".gnupg",
".ssh",
".vscode/cli", # VS Code CLI binary (large, regenerates)
".vscode/extensions", # VS Code extensions (large, regenerates)
".vscode-server", # VS Code remote server
".npm-global",
".pki",
".dotnet",
".var", # System application data (Flatpak, etc)
".backup", # Old backup directories
".antigravity", # AI assistant cache/data
".gemini", # AI assistant cache
# Version control (huge number of files!)
".git", # Git repositories are version controlled elsewhere
# IDE and editor directories
".idea", # IntelliJ IDEA settings
".eclipse", # Eclipse settings
# Claude Code session files (change every session) - synced from .gitignore
#".claude/projects",
".claude/todos",
".claude/shell-snapshots",
".claude/ide",
".claude/statsig",
#".claude/plugins",
".claude/.credentials.json",
".claude/debug",
".claude/file-history",
".claude/history.jsonl",
".claude/.update.lock",
".claude/.projects",
#".claude/hooks/.last_diagnostics_file",
".serena/logs",
".code",
# Development cache/build directories
".npm",
".cargo",
".rustup",
".gem",
".gradle",
".m2",
# Application data we don't need in backups
".thunderbird",
".wine",
".steam",
".zoom",
# User directories that shouldn't be backed up
"Downloads",
#"Music",
"Videos",
"Pictures",
"Dropbox",
"system_logs",
"external_repos", # External git repos - version controlled elsewhere
"mcp_servers/context7", # External MCP server repo
"mcp_servers/playwright-mcp", # External MCP server repo
"mcp_servers/serena", # External MCP server repo
"mcp_servers/servers", # External MCP server repo
"mcp_servers/dropbox", # External MCP server repo
# Archive and compressed files
"*.zip",
"*.tar",
"*.gz",
"*.bz2",
"*.rar",
"*.7z",
"*.whl", # Python wheel files (long filenames in archives)
# Large binary/image files (VMs, disk images)
"*.img", # Disk images (sandbox.img, etc - can be 50GB+)
"*.iso", # ISO files
"*.vmdk", # Virtual machine disk
"*.vdi", # VirtualBox disk image
"*.qcow2", # QEMU disk image
# Image/media files (screenshots, icons, etc.)
"*.png",
"*.jpg",
"*.jpeg",
"*.gif",
"*.svg",
"*.webp",
"*.ico",
"*.bmp",
"*.tiff",
"*.tif",
# Log files
"*.log",
"logs",
# Most JSON files (frequent changes, not human-readable diffs)
"*_data.json",
"*_log.json",
"*_registry.json",
"snapshot_backup.json",
"snapshot_backup_changelog.json",
# Miscellaneous
"*.db",
"*.bashrc",
"*.bash_history",
"*.bash_logout",
#"*.claude.json.backup",
#"*.env",
"*.lesshst",
"*.npmrc",
"*.sudo_as_admin_successful",
]
# Notable patterns to highlight when skipped
CLI_TRACKING_PATTERNS = []
# Files that should be backed up but NOT generate diff files
DIFF_IGNORE_PATTERNS = [
# Log files (append-only, huge diffs)
"*.log",
"*.logs",
"system_logs/*.log",
# Most JSON files (frequent changes, not human-readable diffs)
#"*_config.json",
#"*_data.json",
#"*_log.json",
#"*_registry.json",
# Python cache/compiled
"*.pyc",
"*.pyo",
"*.pyd",
"__pycache__/*",
# Database files
"*.db",
"*.sqlite",
"*.sqlite3",
# Binary/media files
"*.exe",
"*.dll",
"*.so",
"*.dylib",
# Pickle/cache files
"*.pkl",
"*.pickle",
# Temporary files
"*.tmp",
"*.temp",
"*.bak",
"~*",
]
# Files that should be backed up despite matching ignore patterns
# Synced from .gitignore exceptions (! prefix patterns)
IGNORE_EXCEPTIONS = [
".gitignore", # Root .gitignore file should be backed up
"*.local.md", # AIPass session tracking files (caught by .local pattern but should be backed up)
".vscode/settings.json", # VS Code settings
"*/.claude/settings.local.json", # Claude local settings in any directory
"tools/cleanup_configs/*.json", # Cleanup config files
"*_config.json", # All config JSON files
"drone/commands/global/*.json", # Drone global commands
".claude.json", # Claude config
".mcp.json", # MCP config
".config/nerd-dictation/*", # Nerd dictation config
".commands.json", # Commands config
"BRANCH_REGISTRY.json", # Core ecosystem registry - vital file
# === TEMPLATES: FULL EXCEPTION - EVERY FILE ===
"templates/**", # FULL EXCEPTION: Include EVERY file in templates directory
"*/templates/**", # Templates in any subdirectory
"templates/*/**", # All subdirectories and files in templates
"*/templates/*/**", # All subdirectories and files in templates anywhere
# === TEMPLATE SUBDIRECTORIES (explicit) ===
"templates/ai_branch_setup_template/ai_mail.local/**",
"templates/ai_branch_setup_template/logs/**",
"templates/ai_branch_setup_template/standards.local/**",
"templates/ai_branch_setup_template/.claude/**",
"templates/ai_branch_setup_template/.archive/**",
# === MARKERS ===
".gitkeep", # Include all .gitkeep marker files (especially in templates)
".gitattributes", # Git attributes files
".local.json"
]
# Files that SHOULD have diffs created (exceptions to ignore patterns)
DIFF_INCLUDE_PATTERNS = [
"profile.json",
"pyrightconfig.json",
"package.json",
".mcp.json",
"settings.json",
"settings.local.json",
]
# =============================================
# BACKUP MODE CONFIGURATIONS
# =============================================
BACKUP_MODES = {
'snapshot': {
'name': 'System Snapshot',
'description': 'Dynamic instant backup (overwrites previous)',
'destination': BACKUP_DESTINATIONS["system_snapshot"],
'folder_name': 'system_snapshot',
'behavior': 'dynamic', # overwrites previous
'usage': 'Quick saves before changes'
},
'versioned': {
'name': 'Versioned Backup',
'description': 'Cumulative version history (keeps all file versions)',
'destination': BACKUP_DESTINATIONS["versioned_backup"],
'folder_name': 'versioned_backup',
'behavior': 'versioned', # keeps all versions
'usage': 'Complete file version history in single location'
},
}
# =============================================
# HELPER FUNCTIONS
# =============================================
def get_ignore_patterns() -> List[str]:
"""Get the global ignore patterns list
Returns:
Copy of global ignore patterns list
"""
return GLOBAL_IGNORE_PATTERNS.copy()
def get_cli_tracking_patterns() -> List[str]:
"""Get the CLI tracking patterns list
Returns:
Copy of CLI tracking patterns list
"""
return CLI_TRACKING_PATTERNS.copy()
def get_backup_destination(system_name: str) -> str:
"""Get backup destination for a specific backup system
Args:
system_name: Name of the backup system
Returns:
Path to backup destination, or base directory if not found
"""
return BACKUP_DESTINATIONS.get(system_name, BASE_BACKUP_DIR)
def filter_tracked_items(skipped_items: Dict[str, Set[str]]) -> Dict[str, Set[str]]:
"""Filter skipped items to only show project-specific items
Uses CLI tracking patterns to identify important items worth showing to user.
Args:
skipped_items: Dictionary with 'directories' and 'files' sets
Returns:
Filtered dictionary with only tracked items
"""
tracking_patterns = get_cli_tracking_patterns()
filtered_items = {
"directories": set(),
"files": set()
}
def matches_pattern(item_path: str, patterns: List[str]) -> bool:
"""Check if item path matches any tracking pattern"""
for pattern in patterns:
if pattern in item_path or item_path.startswith(pattern):
return True
# Check wildcard patterns
if pattern.startswith('*') and item_path.endswith(pattern[1:]):
return True
return False
# Filter directories
for directory in skipped_items.get("directories", set()):
if matches_pattern(directory, tracking_patterns):
filtered_items["directories"].add(directory)
# Filter files
for file_path in skipped_items.get("files", set()):
if matches_pattern(file_path, tracking_patterns):
filtered_items["files"].add(file_path)
return filtered_items
def should_ignore(path: Path, ignore_patterns: Optional[List[str]] = None,
exceptions: Optional[List[str]] = None,
backup_dest: Optional[Path] = None) -> bool:
"""Check if a file/folder should be ignored based on patterns.
Centralizes ignore pattern matching logic used during backup scanning.
Checks exceptions first (files that should NOT be ignored), then patterns.
Args:
path: Path object to check
ignore_patterns: List of patterns to ignore (defaults to GLOBAL_IGNORE_PATTERNS)
exceptions: List of exception patterns (defaults to IGNORE_EXCEPTIONS)
backup_dest: Optional backup destination to always ignore
Returns:
True if path should be ignored, False otherwise
Example:
# From backup engine
should_ignore(Path("/home/user/file.pyc")) # True
should_ignore(Path("/home/user/.gitignore")) # False (exception)
"""
import os
# Use defaults if not provided
if ignore_patterns is None:
ignore_patterns = GLOBAL_IGNORE_PATTERNS
if exceptions is None:
exceptions = IGNORE_EXCEPTIONS
path_str = str(path)
parts = set(path_str.split(os.sep))
name = path.name
# Always ignore backup destination if provided
if backup_dest and str(backup_dest) in path_str:
return True
# Ignore paths containing 'Backups'
if 'Backups' in parts:
return True
# Check exceptions first - files that should NOT be ignored
for exception in exceptions:
# Full path matching for template exceptions
if "**" in exception:
# Convert glob pattern to regex-like check
exception_parts = exception.split("/**")[0] # Get everything before /**
if exception_parts in path_str or exception_parts in "/".join(parts):
return False # Matches exception pattern - don't ignore
elif exception.startswith('*') and name.endswith(exception[1:]):
return False # Matches wildcard exception pattern
elif exception == name:
return False # Exact match
elif exception in path_str:
return False # Exception pattern is in the full path
# Check ignore patterns
for pattern in ignore_patterns:
# Special case: "backups" should only match directory names, not filenames
if pattern == "backups":
if "backups" in parts: # Only ignore if "backups" is a directory in the path
return True
elif pattern == name:
return True
elif pattern.startswith('*') and name.endswith(pattern[1:]):
return True
elif pattern in parts or pattern in path_str:
return True
return False
# =============================================
# MODULE INITIALIZATION
# =============================================
# No initialization needed - pure configuration