Skip to content

feat(scanners): base ABC, registry, and 14 scanner plugins#1

Open
wgordon17 wants to merge 7 commits intogordon-code:mainfrom
wgordon17:feat/phase-3-scanners
Open

feat(scanners): base ABC, registry, and 14 scanner plugins#1
wgordon17 wants to merge 7 commits intogordon-code:mainfrom
wgordon17:feat/phase-3-scanners

Conversation

@wgordon17
Copy link
Member

Summary

  • BaseScannerPlugin ABC with @register decorator and plugin registry
  • Shared _utils.py: run_command (never shell=True), read_plist_safe, hash_file, read_launchd_plists
  • 14 concrete scanners: preferences, applications, homebrew, dotfiles, app_config, fonts, launch_agents, shell, network, security, system, display, audio, cron
  • Scanner names match SystemState fields exactly for CLI wiring
  • Sensitive env var filtering in shell scanner
  • Network scanner uses batched subprocess calls (no N+1)
  • 193 tests (149 scanner + 44 model), ruff clean, pyright clean

Base scanner architecture:
- BaseScannerPlugin ABC with @register decorator for auto-registration
- Shared _utils.py: run_command (never shell=True), read_plist_safe,
  hash_file, read_launchd_plists
- Scanner names match SystemState fields for CLI wiring

14 concrete scanners:
- preferences: plistlib reads from 4 preference directories
- applications: /Applications scan + Info.plist + mas cross-reference
- homebrew: brew bundle dump + version enrichment via model_copy
- dotfiles: known dotfiles + .config/ scan, symlink/stow/git detection
- app_config: Application Support + Group Containers, file type classification
- fonts: user + system fonts filtered by extension
- launch_agents: LaunchAgents/Daemons plists + sfltool login items
- shell: fish/zsh/bash rc parsing, sensitive env var filtering
- network: batched listallhardwareports + ifconfig (no N+1)
- security: FileVault, SIP, Gatekeeper, firewall, TCC.db (read-only)
- system: hostname, timezone, locale, pmset, Spotlight
- display: system_profiler SPDisplaysDataType JSON parsing
- audio: system_profiler SPAudioDataType + osascript alert volume
- cron: crontab -l + launchd StartCalendarInterval detection

193 tests (149 scanner + 44 model), ruff clean, pyright clean.
@wgordon17 wgordon17 force-pushed the feat/phase-3-scanners branch from 3dccf45 to f09331c Compare March 7, 2026 22:35
- Remove dead except ValueError around is_relative_to() in dotfiles
- Remove unused _path param from _detect_manager
- Refactor register from bare decorator to register(name) factory,
  eliminating import-time class instantiation
- Extract _classify_device() helper in audio scanner
- Tighten shell function regex to column-0 only
- Add comments: sfltool JSON limitation, en0 Wi-Fi fallback, heredoc caveat
- Add 18 tests: sensitive env filtering (posix+fish), hash_file (6),
  read_launchd_plists (4), large file skip, unclassified audio device,
  stow parent-name detection, Group Containers, display resolution fallback,
  posix function detection
- Catches ValueError/OverflowError in read_plist_safe for corrupt dates
- Skips plists with non-dict root values in preferences scanner
- Adds /etc/localtime symlink fallback when systemsetup needs admin
- Reduces expected PermissionError logs to DEBUG in app_config scanner
- Replaces broken JSON parser with text format parser for sfltool dumpbtm
- Filters by current user UID and login item type
- Falls back to Bundle Identifier when Name is null
- Skips plists with non-dict root values in preferences scanner
- Detects login shell via dscl instead of $SHELL env var
- Splits plist error handling by type: PermissionError→DEBUG,
  ValueError/OverflowError→WARNING, OSError→WARNING
- Apple-prefixed app dirs get DEBUG, non-Apple keep WARNING
- Captures enabled/disabled disposition from BTM login items
- Adds SLF001 per-file-ignore for test private member access
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant