# AppLocate Dataflow Diagram This document describes the data flow through the AppLocate application from user input to structured output. ## High-Level Overview ```mermaid flowchart TB subgraph Input CLI[("CLI Input
(query + flags)")] end subgraph "Argument Parsing" Parser["System.CommandLine
Parser"] Validator["Argument Validator"] end subgraph "Source Registry" Registry["ISourceRegistry"] subgraph "Discovery Sources" direction TB RegistryUninstall["Registry Uninstall
(HKLM/HKCU)"] AppPaths["App Paths
(Registry)"] StartMenu["Start Menu
Shortcuts (.lnk)"] Process["Process Source
(Running)"] PathSearch["PATH Search
(where.exe)"] ServicesTask["Services &
Scheduled Tasks"] MSIX["MSIX/Store
Packages"] HeuristicFS["Heuristic FS
Scan"] Scoop["Scoop
Source"] Chocolatey["Chocolatey
Source"] Winget["Winget
Source"] end end subgraph "Processing Pipeline" Aggregator["Parallel Aggregator
(Channel-based)"] Deduplicator["Path Deduplicator"] RulesEngine["Rules Engine
(YAML)"] Ranker["Ranker
(Scoring)"] Filter["Result Filters
(type, scope, confidence)"] Collapser["Best-Per-Type
Collapser"] end subgraph "Output Formatting" JSON["JSON Serializer
(JsonContext)"] CSV["CSV Writer"] Text["Text Formatter
(ANSI colors)"] end subgraph Output STDOUT[("stdout")] STDERR[("stderr
(diagnostics)")] end CLI --> Parser Parser --> Validator Validator -->|SourceOptions| Registry Registry --> RegistryUninstall Registry --> AppPaths Registry --> StartMenu Registry --> Process Registry --> PathSearch Registry --> ServicesTask Registry --> MSIX Registry --> HeuristicFS Registry --> Scoop Registry --> Chocolatey Registry --> Winget RegistryUninstall -->|AppHit| Aggregator AppPaths -->|AppHit| Aggregator StartMenu -->|AppHit| Aggregator Process -->|AppHit| Aggregator PathSearch -->|AppHit| Aggregator ServicesTask -->|AppHit| Aggregator MSIX -->|AppHit| Aggregator HeuristicFS -->|AppHit| Aggregator Scoop -->|AppHit| Aggregator Chocolatey -->|AppHit| Aggregator Winget -->|AppHit| Aggregator Aggregator --> Deduplicator Deduplicator --> RulesEngine RulesEngine -->|"Expanded
config/data hits"| Ranker Ranker -->|Scored AppHit| Filter Filter --> Collapser Collapser -->|--json| JSON Collapser -->|--csv| CSV Collapser -->|--text| Text JSON --> STDOUT CSV --> STDOUT Text --> STDOUT Validator -->|errors| STDERR Registry -->|--trace timing| STDERR ``` ## Detailed Component Dataflow ### 1. Input Processing ```mermaid flowchart LR subgraph "CLI Arguments" Args["string[] args"] end subgraph "Parsed Options" Query["query: string"] Format["format: json|csv|text"] Scope["scope: user|machine|both"] Types["types: exe|install-dir|config|data"] Flags["flags: --all, --evidence, etc."] end subgraph "SourceOptions Record" SO["SourceOptions
• UserOnly
• MachineOnly
• Timeout
• Strict
• IncludeEvidence
• OriginalQuery"] end Args --> Query Args --> Format Args --> Scope Args --> Types Args --> Flags Query --> SO Scope --> SO Flags --> SO ``` ### 2. Source Execution (Parallel) ```mermaid flowchart TB subgraph "Query Dispatch" Query["Normalized Query"] Options["SourceOptions"] end subgraph "Parallel Execution (SemaphoreSlim)" direction LR T1["Task 1"] T2["Task 2"] T3["Task 3"] TN["Task N"] end subgraph "ISource.QueryAsync" S1["Source 1"] S2["Source 2"] S3["Source 3"] SN["Source N"] end subgraph "Channel" Chan["Bounded Channel
(backpressure)"] end Query --> T1 & T2 & T3 & TN Options --> T1 & T2 & T3 & TN T1 --> S1 T2 --> S2 T3 --> S3 TN --> SN S1 -->|"yield AppHit"| Chan S2 -->|"yield AppHit"| Chan S3 -->|"yield AppHit"| Chan SN -->|"yield AppHit"| Chan ``` ### 3. AppHit Data Model ```mermaid classDiagram class AppHit { +HitType Type +Scope Scope +string Path +string? Version +PackageType PackageType +string[] Source +double Confidence +Dictionary~string,string~? Evidence +ScoreBreakdown? Breakdown } class HitType { <> InstallDir Exe Config Data } class Scope { <> User Machine } class PackageType { <> MSI MSIX Store EXE Portable ClickOnce Squirrel Scoop Chocolatey Winget Unknown } class ScoreBreakdown { +double Base +double NameMatch +double TokenCoverage +double AliasBonus +double EvidenceBoost +double MultiSource +double Penalties +double Total } AppHit --> HitType AppHit --> Scope AppHit --> PackageType AppHit --> ScoreBreakdown ``` ### 4. Ranking Pipeline ```mermaid flowchart TB subgraph "Input" Hit["Raw AppHit
(Confidence = 0)"] Query["Normalized Query"] end subgraph "Ranker.ScoreWithBreakdown()" Base["Base Score
(by HitType)"] Name["Name Match
(exact/partial/fuzzy)"] Token["Token Coverage
(Jaccard + span)"] Alias["Alias Matching
(vscode ↔ code)"] Evidence["Evidence Boost
(registry, shortcut, process)"] Multi["Multi-Source
(harmonic diminishing)"] Penalty["Penalties
(temp, cache, generic)"] end subgraph "Output" Scored["Scored AppHit
(Confidence ∈ [0,1])"] Breakdown["ScoreBreakdown"] end Hit --> Base Query --> Name Query --> Token Query --> Alias Base --> |+0.08| Evidence Name --> |+0.35 max| Evidence Token --> |+0.27 max| Evidence Alias --> |+0.10 max| Evidence Evidence --> |+0.15 max| Multi Multi --> |+0.18 max| Penalty Penalty --> |−0.20 max| Scored Scored --> Breakdown ``` ### 5. Rules Engine Expansion ```mermaid flowchart LR subgraph "Input" ExeHit["Exe AppHit
(e.g., Code.exe)"] RulesYAML["apps.default.yaml
(147 app rules)"] end subgraph "RulesEngine.LoadAsync()" Match["Match Query
anyOf: [code, vscode]"] ConfigPaths["config:
%APPDATA%/Code/User"] DataPaths["data:
%LOCALAPPDATA%/..."] end subgraph "Output" ConfigHit["Config AppHit"] DataHit["Data AppHit"] end ExeHit --> Match RulesYAML --> Match Match --> ConfigPaths Match --> DataPaths ConfigPaths -->|"Expand env vars"| ConfigHit DataPaths -->|"Expand env vars"| DataHit ``` ### 6. Output Pipeline ```mermaid flowchart TB subgraph "Filtering" AllHits["All Scored Hits"] TypeFilter["--exe, --config, etc."] ScopeFilter["--user, --machine"] ConfFilter["--confidence-min"] LimitFilter["--limit"] end subgraph "Collapsing (unless --all)" ExeCollapse["Top 3 Exe
(distinct dirs)"] InstallCollapse["Paired InstallDir"] ConfigCollapse["Best Config"] DataCollapse["Best Data"] end subgraph "Serialization" JSON["JsonSerializer
(source-gen JsonContext)"] CSV["Manual CSV
(quoted, escaped)"] Text["ANSI Text
([0.92] Exe path)"] end subgraph "Output Enrichment" EvidenceFlag["--evidence"] BreakdownFlag["--score-breakdown"] PkgSourceFlag["--package-source"] end AllHits --> TypeFilter --> ScopeFilter --> ConfFilter --> LimitFilter LimitFilter -->|"--all"| JSON & CSV & Text LimitFilter -->|"default"| ExeCollapse ExeCollapse --> InstallCollapse --> ConfigCollapse --> DataCollapse DataCollapse --> JSON & CSV & Text EvidenceFlag --> JSON & CSV & Text BreakdownFlag --> JSON & Text PkgSourceFlag --> CSV & Text ``` ## Source Data Origins | Source | Windows API / Location | Returns | |--------|------------------------|---------| | **RegistryUninstallSource** | `HKLM/HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall` | InstallDir, Exe, Version | | **AppPathsSource** | `HKLM/HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths` | Exe | | **StartMenuShortcutSource** | `%APPDATA%\Microsoft\Windows\Start Menu`, `%PROGRAMDATA%\...` | Exe (via .lnk target) | | **ProcessSource** | `Process.GetProcesses()` | Exe (running) | | **PathSearchSource** | `%PATH%` directories, `where.exe` | Exe | | **ServicesTasksSource** | `sc query`, Task Scheduler | Exe | | **MsixStoreSource** | `Windows.Management.Deployment.PackageManager` | InstallDir, Exe | | **HeuristicFsSource** | Program Files, AppData (bounded scan) | Exe, InstallDir | | **ScoopSource** | `~\scoop\apps`, `C:\ProgramData\scoop\apps` | Exe, InstallDir | | **ChocolateySource** | `C:\ProgramData\chocolatey\lib` | Exe, InstallDir | | **WingetSource** | `winget list --id` output | Exe, InstallDir | ## Exit Code Flow ```mermaid flowchart TD Start([Start]) --> Parse{Parse Args} Parse -->|Error| Exit2([Exit 2]) Parse -->|--help or no args| Help[Show Help] --> Exit0a([Exit 0]) Parse -->|Valid| Query[Execute Query] Query --> Results{Results Found?} Results -->|Yes| Output[Format & Output] --> Exit0b([Exit 0]) Results -->|No| Exit1([Exit 1]) ``` --- *Generated for AppLocate v0.1.5 — See [README.md](../README.md) for CLI usage.*