# mdgaziur/findex architecture

> Architecture diagram of the GitHub repository mdgaziur/findex, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/mdgaziur/findex
- Repository: https://github.com/mdgaziur/findex

## Overview

1. **Workspace shape**
   - This is a Rust workspace with three core crates:
     - `findex`: the actual launcher application.
     - `findex-daemon`: a small helper process for external triggering.
     - `findex-plugin`: the ABI/support crate used by dynamically loaded plugins.
   - The rest of the repo is packaging, samples, and deployment glue.

2. **Primary runtime: `findex`**
   - `crates/findex/src/main.rs` is the main executable entry point.
   - It is a GTK3 desktop app for Linux that opens a launcher window, reads user input, computes results, and executes the chosen target.
   - The app is split into smaller UI modules under `src/gui/`, which keeps the launcher shell, search input, result list, and dialog behavior separate.

3. **UI composition**
   - The launcher UI is built from a small set of GTK widgets:
     - search box (`searchbox.rs`)
     - scrollable results list (`result_list.rs`, `result_list_row.rs`)
     - dialog/window chrome (`dialog.rs`)
   - The README’s CSS class table matches these widget boundaries, so styling is a first-class part of the UI architecture rather than an afterthought.

4. **Search and result data flow**
   - User input flows from the search box into the launcher logic.
   - Results are assembled from multiple sources:
     - local application entries via `app_list.rs`
     - plugin-provided results via the plugin subsystem
   - The result list is then rendered in the GTK list view, and selection/keyboard shortcuts are used to launch the chosen result.

5. **Application discovery**
   - `app_list.rs` suggests the launcher maintains a catalog of installed desktop applications, likely from standard Linux application metadata.
   - This forms the built-in search corpus, separate from plugin results.
   - The app list is one of the main data sources feeding the ranking/filtering path.

6. **Configuration and theming boundary**
   - `config.rs` handles runtime behavior settings, loaded from user config.
   - Behavior is driven by `~/.config/findex/settings.toml`, while visuals come from `style.css`.
   - The repo also includes a bundled default stylesheet under `css/style.css`, which is copied into the install location and can be overridden by the user.

7. **Activation and daemon boundary**
   - `findex-daemon` is a separate process whose role is to make the launcher triggerable externally, especially in environments where global hotkeys are limited.
   - The README shows a `toggle_file`-based control path under `~/.config/findex/`, so the daemon acts as a bridge between external events and the GUI launcher.
   - On X11 the app can bind keys directly; on Wayland the daemon/file-trigger path becomes the workaround.

8. **Plugin architecture**
   - `findex-plugin` defines the stable plugin interface and result types used across dynamic library boundaries.
   - It uses an ABI-stability layer (`abi_stable`) so plugins can be compiled separately and loaded as `.so` files.
   - The plugin contract is simple: initialize with config, then handle a query and return a list of results.

9. **Plugin ecosystem**
   - The `plugins/` directory contains example plugins such as `cmd`, `github-repo`, `math`, and `urlopen`.
   - These are separate crates, built as shared libraries, and illustrate how the launcher is extended without changing the main binary.
   - Plugins can be invoked by prefix and optionally by custom keyboard shortcut, which inserts the prefix into the search box.

10. **Packaging and deployment**
    - `installer.sh`, `service/findex-daemon.service`, and the README’s installation notes show that deployment is part of the repo’s architecture.
    - The daemon is intended to run as a user service or autostart process.
    - Logs are written to `${XDG_CACHE_HOME}/findex-logs`, which is the main operational boundary for debugging.

11. **Net effect**
    - The architecture is: GTK launcher UI at the center, local app search as the default corpus, plugins as extensible result providers, and a small daemon as the external trigger path.
    - Styling and behavior are both user-configurable through files, while the plugin interface is isolated behind a dedicated ABI crate.

Main entry points: [`crates/findex/src/gui/result_list.rs`](https://github.com/mdgaziur/findex/blob/development/crates/findex/src/gui/result_list.rs) (Result list), [`crates/findex-plugin/src/lib.rs`](https://github.com/mdgaziur/findex/blob/development/crates/findex-plugin/src/lib.rs) (Plugin API), [`crates/findex/src/main.rs`](https://github.com/mdgaziur/findex/blob/development/crates/findex/src/main.rs) (Launcher), [`crates/findex/src/gui/mod.rs`](https://github.com/mdgaziur/findex/blob/development/crates/findex/src/gui/mod.rs) (GUI core)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_core["Core runtime"]
  node_findex_main["Launcher<br/>gtk3 app<br/>[main.rs]"]
  node_gui_mod["GUI core<br/>ui module<br/>[mod.rs]"]
  node_searchbox["Search box<br/>input widget<br/>[searchbox.rs]"]
  node_result_list["Result list<br/>results view<br/>[result_list.rs]"]
  node_result_row["Result row<br/>row widget<br/>[result_list_row.rs]"]
  node_dialog["Dialog chrome<br/>window shell<br/>[dialog.rs]"]
  node_css["Styling<br/>theme loader<br/>[css.rs]"]
  node_config["Config<br/>settings<br/>[config.rs]"]
  node_app_list["App catalog<br/>app discovery<br/>[app_list.rs]"]
end

subgraph group_plugins["Plugins"]
  node_plugin_api["Plugin API<br/>abi crate<br/>[lib.rs]"]
  node_plugin_internal["ABI internals<br/>abi support<br/>[findex_internal.rs]"]
  node_plugin_cmd["Cmd plugin<br/>plugin crate<br/>[lib.rs]"]
  node_plugin_github["GitHub plugin<br/>plugin crate<br/>[lib.rs]"]
  node_plugin_math["Math plugin<br/>plugin crate<br/>[lib.rs]"]
  node_plugin_urlopen["URL open<br/>plugin crate<br/>[lib.rs]"]
end

subgraph group_ops["Packaging"]
  node_daemon_main["Daemon<br/>helper process<br/>[main.rs]"]
  node_installer["Installer<br/>deploy script<br/>[installer.sh]"]
  node_service_unit["Service unit<br/>systemd unit"]
end

node_findex_main -->|"boots UI"| node_gui_mod
node_findex_main -->|"loads"| node_config
node_findex_main -->|"indexes apps"| node_app_list
node_findex_main -->|"loads plugins"| node_plugin_api
node_gui_mod -->|"composes"| node_searchbox
node_gui_mod -->|"composes"| node_result_list
node_gui_mod -->|"composes"| node_dialog
node_result_list -->|"renders"| node_result_row
node_searchbox -->|"drives"| node_result_list
node_app_list -->|"feeds"| node_result_list
node_plugin_api -->|"defines ABI"| node_plugin_internal
node_plugin_api -->|"implements"| node_plugin_cmd
node_plugin_api -->|"implements"| node_plugin_github
node_plugin_api -->|"implements"| node_plugin_math
node_plugin_api -->|"implements"| node_plugin_urlopen
node_plugin_cmd -->|"returns results"| node_result_list
node_plugin_github -->|"returns results"| node_result_list
node_plugin_math -->|"returns results"| node_result_list
node_plugin_urlopen -->|"returns results"| node_result_list
node_daemon_main -->|"triggers"| node_dialog
node_installer -->|"installs"| node_service_unit
node_installer -->|"deploys"| node_daemon_main

click node_findex_main "https://github.com/mdgaziur/findex/blob/development/crates/findex/src/main.rs"
click node_gui_mod "https://github.com/mdgaziur/findex/blob/development/crates/findex/src/gui/mod.rs"
click node_searchbox "https://github.com/mdgaziur/findex/blob/development/crates/findex/src/gui/searchbox.rs"
click node_result_list "https://github.com/mdgaziur/findex/blob/development/crates/findex/src/gui/result_list.rs"
click node_result_row "https://github.com/mdgaziur/findex/blob/development/crates/findex/src/gui/result_list_row.rs"
click node_dialog "https://github.com/mdgaziur/findex/blob/development/crates/findex/src/gui/dialog.rs"
click node_css "https://github.com/mdgaziur/findex/blob/development/crates/findex/src/gui/css.rs"
click node_config "https://github.com/mdgaziur/findex/blob/development/crates/findex/src/config.rs"
click node_app_list "https://github.com/mdgaziur/findex/blob/development/crates/findex/src/app_list.rs"
click node_daemon_main "https://github.com/mdgaziur/findex/blob/development/crates/findex-daemon/src/main.rs"
click node_plugin_api "https://github.com/mdgaziur/findex/blob/development/crates/findex-plugin/src/lib.rs"
click node_plugin_internal "https://github.com/mdgaziur/findex/blob/development/crates/findex-plugin/src/findex_internal.rs"
click node_plugin_cmd "https://github.com/mdgaziur/findex/blob/development/plugins/cmd/src/lib.rs"
click node_plugin_github "https://github.com/mdgaziur/findex/blob/development/plugins/github-repo/src/lib.rs"
click node_plugin_math "https://github.com/mdgaziur/findex/blob/development/plugins/math/src/lib.rs"
click node_plugin_urlopen "https://github.com/mdgaziur/findex/blob/development/plugins/urlopen/src/lib.rs"
click node_installer "https://github.com/mdgaziur/findex/blob/development/installer.sh"
click node_service_unit "https://github.com/mdgaziur/findex/blob/development/service/findex-daemon.service"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_findex_main,node_gui_mod,node_searchbox,node_result_list,node_result_row,node_dialog,node_css,node_config,node_app_list toneBlue
class node_plugin_api,node_plugin_internal,node_plugin_cmd,node_plugin_github,node_plugin_math,node_plugin_urlopen toneAmber
class node_daemon_main,node_installer,node_service_unit toneMint
```

## Components

### Core runtime

Launcher app, UI, configuration, and built-in app discovery.

- [Launcher](https://github.com/mdgaziur/findex/blob/development/crates/findex/src/main.rs): gtk3 app · Main desktop launcher executable entry point. · `crates/findex/src/main.rs`
- [GUI core](https://github.com/mdgaziur/findex/blob/development/crates/findex/src/gui/mod.rs): ui module · Top-level UI module wiring the launcher shell. · `crates/findex/src/gui/mod.rs`
- [Search box](https://github.com/mdgaziur/findex/blob/development/crates/findex/src/gui/searchbox.rs): input widget · User query entry and prefix insertion. · `crates/findex/src/gui/searchbox.rs`
- [Result list](https://github.com/mdgaziur/findex/blob/development/crates/findex/src/gui/result_list.rs): results view · Scrollable list that renders and updates matches. · `crates/findex/src/gui/result_list.rs`
- [Result row](https://github.com/mdgaziur/findex/blob/development/crates/findex/src/gui/result_list_row.rs): row widget · Single selectable result item for the list. · `crates/findex/src/gui/result_list_row.rs`
- [Dialog chrome](https://github.com/mdgaziur/findex/blob/development/crates/findex/src/gui/dialog.rs): window shell · Launcher window/dialog behavior and key handling. · `crates/findex/src/gui/dialog.rs`
- [Styling](https://github.com/mdgaziur/findex/blob/development/crates/findex/src/gui/css.rs): theme loader · GTK styling integration for bundled and user CSS. · `crates/findex/src/gui/css.rs`
- [Config](https://github.com/mdgaziur/findex/blob/development/crates/findex/src/config.rs): settings · Runtime settings loaded from user configuration. · `crates/findex/src/config.rs`
- [App catalog](https://github.com/mdgaziur/findex/blob/development/crates/findex/src/app_list.rs): app discovery · Built-in catalog of installed desktop applications. · `crates/findex/src/app_list.rs`

### Plugins

Stable plugin ABI plus example dynamic plugins.

- [Plugin API](https://github.com/mdgaziur/findex/blob/development/crates/findex-plugin/src/lib.rs): abi crate · Stable plugin interface and shared result types. · `crates/findex-plugin/src/lib.rs`
- [ABI internals](https://github.com/mdgaziur/findex/blob/development/crates/findex-plugin/src/findex_internal.rs): abi support · Internal ABI-stable definitions shared across plugin boundaries. · `crates/findex-plugin/src/findex_internal.rs`
- [Cmd plugin](https://github.com/mdgaziur/findex/blob/development/plugins/cmd/src/lib.rs): plugin crate · Example plugin for command execution. · `plugins/cmd/src/lib.rs`
- [GitHub plugin](https://github.com/mdgaziur/findex/blob/development/plugins/github-repo/src/lib.rs): plugin crate · Example plugin for repository search actions. · `plugins/github-repo/src/lib.rs`
- [Math plugin](https://github.com/mdgaziur/findex/blob/development/plugins/math/src/lib.rs): plugin crate · Example plugin for calculator-style queries. · `plugins/math/src/lib.rs`
- [URL open](https://github.com/mdgaziur/findex/blob/development/plugins/urlopen/src/lib.rs): plugin crate · Example plugin for opening URLs. · `plugins/urlopen/src/lib.rs`

### Packaging

Daemon, service unit, installer, and repo glue.

- [Daemon](https://github.com/mdgaziur/findex/blob/development/crates/findex-daemon/src/main.rs): helper process · External trigger bridge for showing or hiding the launcher. · `crates/findex-daemon/src/main.rs`
- [Installer](https://github.com/mdgaziur/findex/blob/development/installer.sh): deploy script · Packaging and installation helper script. · `installer.sh`
- [Service unit](https://github.com/mdgaziur/findex/blob/development/service/findex-daemon.service): systemd unit · User-service definition for the daemon. · `service/findex-daemon.service`

## Connections

- Launcher → GUI core: boots UI · Main binary initializes the launcher UI stack.
- Launcher → Config: loads · Reads runtime behavior settings at startup.
- Launcher → App catalog: indexes apps · Builds the default search corpus from installed applications.
- Launcher → Plugin API: loads plugins · Uses the plugin ABI to discover and invoke extensions.
- GUI core → Search box: composes · Wires the query entry into the launcher shell.
- GUI core → Result list: composes · Includes the scrolling results surface.
- GUI core → Dialog chrome: composes · Owns the launcher window/dialog behavior.
- Result list → Result row: renders · Displays each match as an individual selectable row.
- Search box → Result list: drives · Query changes update the results shown to the user.
- App catalog → Result list: feeds · Built-in app entries become searchable results.
- Plugin API → ABI internals: defines ABI · Stable boundary types are encoded through ABI-safe internals.
- Plugin API → Cmd plugin: implements · Example plugin built against the shared interface.
- Plugin API → GitHub plugin: implements · Example plugin built against the shared interface.
- Plugin API → Math plugin: implements · Example plugin built against the shared interface.
- Plugin API → URL open: implements · Example plugin built against the shared interface.
- Cmd plugin → Result list: returns results · Plugin-provided matches are merged into the launcher view.
- GitHub plugin → Result list: returns results · Plugin-provided matches are merged into the launcher view.
- Math plugin → Result list: returns results · Plugin-provided matches are merged into the launcher view.
- URL open → Result list: returns results · Plugin-provided matches are merged into the launcher view.
- Daemon → Dialog chrome: triggers · External events toggle or raise the launcher window.
- Installer → Service unit: installs · Deployment script includes daemon service setup.
- Installer → Daemon: deploys · Installer provisions the helper process.
