Introduction
What is FsPulse?
FsPulse is an essential filesystem integrity tool for system administrators, home-lab enthusiasts, and anyone who takes data preservation seriously. It runs as a background service that continuously monitors your critical directories, watching for the silent threats that traditional backup systems miss: bit rot, corruption, and unexpected tampering.
Your files can change without you knowing. Hard drives degrade. Ransomware alters files while preserving timestamps. FsPulse catches these problems early through two powerful detection methods:
- Content Hashing (SHA2): Detects when file contents change even though filesystem metadata stays the same—the telltale sign of bit rot or sophisticated tampering
 - Format Validation: Uses open-source libraries to read and validate file structures, catching corruption in FLAC audio, JPEG/PNG images, PDFs, and more
 
Instead of waiting for a file to fail when you need it most, FsPulse gives you continuous awareness. Run manual scans when you want, or let scheduled scans (coming soon) monitor your data automatically. When issues are detected, FsPulse's alert system flags them immediately through an elegant web interface.
Whether you're protecting family photos, managing media libraries, or maintaining production servers, FsPulse provides the peace of mind that comes from knowing your data is actually intact—not just backed up.
  
  
  Web UI showing real-time scan progress with live statistics
Key Capabilities
- Dual Interface — Run as a web service with elegant browser UI, or use the full-featured CLI with interactive terminal modes
 - Integrity Detection — SHA2 hashing catches content changes even when filesystem metadata stays the same; format validators detect corruption in supported file types
 - Change Tracking — Deep directory scanning captures all additions, modifications, and deletions across scan sessions
 - Alert System — Suspicious hash changes and validation failures are flagged immediately with status management (Open/Flagged/Dismissed)
 - Powerful Query Language — SQL-inspired syntax lets you filter, sort, and analyze your data with precision
 - Production Ready — Official Docker images (multi-architecture), comprehensive documentation, and native installers
 
Usage Modes
FsPulse offers flexibility in how you interact with it:
- 
Web UI Mode: Run
fspulse serveto start the server and access the full web interface at http://127.0.0.1:8080. Great for visual data exploration, managing multiple roots, and real-time scan monitoring. - 
Command-Line Mode: Use direct terminal commands like
fspulse scan,fspulse query, andfspulse reportfor automation, scripted workflows, and quick one-off operations. - 
Interactive Terminal Mode: Use
fspulse interactfor menu-driven navigation orfspulse explorefor a full-screen data explorer TUI—perfect for terminal users who want visual feedback without leaving the command line. 
FsPulse is designed to scale across large file systems while maintaining clarity and control for the user.
This book provides comprehensive documentation for all aspects of FsPulse. Start with Getting Started for installation, or jump to any section that interests you.
Getting Started
FsPulse can be installed in one of four ways:
- Run with Docker (Recommended)
 - Install via crates.io
 - Clone and build from source
 - Download a pre-built release binary from GitHub
 
Choose the method that works best for your platform and preferences.
1. Run with Docker (Recommended)
The easiest way to run FsPulse is with Docker:
docker pull gtunesdev/fspulse:latest
docker run -d \
  --name fspulse \
  -p 8080:8080 \
  -v fspulse-data:/data \
  gtunesdev/fspulse:latest
Access the web UI at http://localhost:8080
The web UI provides full functionality: managing roots, initiating scans, querying data, and viewing results—all from your browser.
See the Docker Deployment chapter for complete documentation including:
- Volume management for scanning host directories
 - Configuration options
 - Docker Compose examples
 - NAS deployment (TrueNAS, Unraid)
 - Troubleshooting
 
2. Install via Crates.io
The easiest way to get FsPulse is via crates.io:
cargo install fspulse
This will download, compile, and install the latest version of FsPulse into Cargo’s bin directory, typically ~/.cargo/bin. That directory is usually already in your PATH. If it's not, you may need to add it manually.
Then run:
fspulse --help
To upgrade to the latest version later:
cargo install fspulse --force
3. Clone and Build from Source
If you prefer working directly with the source code (for example, to contribute or try out development versions):
git clone https://github.com/gtunes-dev/fspulse.git
cd fspulse
cargo build --release
Then run it from the release build directory:
./target/release/fspulse --help
4. Download Pre-Built Release Binaries
Pre-built release binaries for Linux, macOS, and Windows are available on the GitHub Releases page:
- Visit the releases page.
 - Download the appropriate archive for your operating system.
 - Unpack the archive.
 - Optionally move the 
fspulsebinary to a directory included in yourPATH. 
For example, on Unix systems:
mv fspulse /usr/local/bin/
Then confirm it's working:
fspulse --help
Usage: Web UI or CLI
After installation, you can use FsPulse in two ways:
Web UI (Server Mode)
Start the server:
fspulse serve
Then open your browser to http://localhost:8080 to access the web interface.
The web UI provides:
- Root management (create, view, delete roots)
 - Scan initiation with real-time progress
 - Interactive data exploration
 - Powerful query interface
 
Command-Line Interface
Use FsPulse directly from the terminal:
Scan a directory:
fspulse scan --root-path /some/directory
Interactive exploration:
fspulse interact  # Menu-driven interface
fspulse explore   # Data explorer TUI
Query results:
# Items whose path contains 'reports'
fspulse query "items where item_path:('reports')"
# Changes involving items detected as invalid
fspulse query "changes where val_new:(I) show default, val_old, val_new order by change_id desc"
See the Query Syntax page for more examples and the Command-Line Interface page for all available commands.
Docker Deployment
The easiest way to run FsPulse is with Docker. The container runs FsPulse as a background service with the web UI accessible on port 8080. You can manage roots, initiate scans, query data, and view results—all from your browser.
Quick Start
Get FsPulse running in three simple steps:
# 1. Pull the image
docker pull gtunesdev/fspulse:latest
# 2. Run the container
docker run -d \
  --name fspulse \
  -p 8080:8080 \
  -v fspulse-data:/data \
  gtunesdev/fspulse:latest
# 3. Access the web UI
open http://localhost:8080
That's it! The web UI is now running.
This basic setup stores all FsPulse data (database, config, logs) in a Docker volume and uses default settings. If you need to customize settings (like running as a specific user for NAS deployments, or changing the port), see the Configuration and NAS Deployments sections below.
Scanning Your Files
To scan directories on your host machine, you need to mount them into the container. FsPulse can then scan these mounted paths.
Mounting Directories
Add -v flags to mount host directories into the container. We recommend mounting them under /roots for clarity:
docker run -d \
  --name fspulse \
  -p 8080:8080 \
  -v fspulse-data:/data \
  -v ~/Documents:/roots/documents:ro \
  -v ~/Photos:/roots/photos:ro \
  gtunesdev/fspulse:latest
The :ro (read-only) flag is recommended for safety—FsPulse only reads files during scans and never modifies them.
Creating Roots in the Web UI
After mounting directories:
- Open http://localhost:8080 in your browser
 - Navigate to Manage Roots in the sidebar
 - Click Add Root
 - Enter the container path: 
/roots/documents(not the host path~/Documents) - Click Create Root
 
Important: Always use the container path (e.g., /roots/documents), not the host path. The container doesn't know about host paths.
Once roots are created, you can scan them from the web UI and monitor progress in real-time.
Docker Compose (Recommended)
For persistent deployments, Docker Compose is cleaner and easier to manage:
version: '3.8'
services:
  fspulse:
    image: gtunesdev/fspulse:latest
    container_name: fspulse
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      # Persistent data storage - REQUIRED
      # Must map /data to either a Docker volume (shown here) or a host path
      # Must support read/write access for database, config, and logs
      - fspulse-data:/data
      # Alternative: use a host path instead
      # - /path/on/host/fspulse-data:/data
      # Directories to scan (read-only recommended for safety)
      - ~/Documents:/roots/documents:ro
      - ~/Photos:/roots/photos:ro
    environment:
      # Optional: override any configuration setting
      # See Configuration section below and https://gtunes-dev.github.io/fspulse/configuration.html
      - TZ=America/New_York
volumes:
  fspulse-data:
Save as docker-compose.yml and run:
docker-compose up -d
Configuration
FsPulse creates a default config.toml on first run with sensible defaults. Most users won't need to change anything, but when you do, there are three ways to customize settings.
Option 1: Use Environment Variables (Easiest)
Override any setting using environment variables. This works with both docker run and Docker Compose.
Docker Compose example:
services:
  fspulse:
    image: gtunesdev/fspulse:latest
    environment:
      - FSPULSE_SERVER_PORT=9090      # Change web UI port
      - FSPULSE_LOGGING_FSPULSE=debug # Enable debug logging
      - FSPULSE_ANALYSIS_THREADS=16   # Use 16 analysis threads
    ports:
      - "9090:9090"
Command line example (equivalent to above):
docker run -d \
  --name fspulse \
  -p 9090:9090 \
  -e FSPULSE_SERVER_PORT=9090 \
  -e FSPULSE_LOGGING_FSPULSE=debug \
  -e FSPULSE_ANALYSIS_THREADS=16 \
  -v fspulse-data:/data \
  gtunesdev/fspulse:latest
Environment variables follow the pattern FSPULSE_<SECTION>_<FIELD> and override any settings in config.toml. See the Configuration chapter for a complete list of available variables and their purposes.
Option 2: Edit the Config File
If you prefer editing the config file directly:
- 
Extract the auto-generated config:
docker exec fspulse cat /data/config.toml > config.toml - 
Edit
config.tomlwith your preferred settings - 
Copy back and restart:
docker cp config.toml fspulse:/data/config.toml docker restart fspulse 
Option 3: Pre-Mount Your Own Config (Advanced)
If you want custom settings before first launch, create your own config.toml and mount it:
volumes:
  - fspulse-data:/data
  - ./my-config.toml:/data/config.toml:ro
Most users should start with Option 1 (environment variables) or Option 2 (edit after first run).
NAS Deployments (TrueNAS, Unraid)
NAS systems often have specific user IDs for file ownership. By default, FsPulse runs as user 1000, but you may need it to match your file ownership.
Setting User and Group IDs
Use PUID and PGID environment variables to run FsPulse as a specific user:
TrueNAS Example (apps user = UID 34):
docker run -d \
  --name fspulse \
  -p 8080:8080 \
  -e PUID=34 \
  -e PGID=34 \
  -e TZ=America/New_York \
  -v /mnt/pool/fspulse/data:/data \
  -v /mnt/pool/documents:/roots/docs:ro \
  gtunesdev/fspulse:latest
Unraid Example (custom UID 1001):
docker run -d \
  --name fspulse \
  -p 8080:8080 \
  -e PUID=1001 \
  -e PGID=100 \
  -v /mnt/user/appdata/fspulse:/data \
  -v /mnt/user/photos:/roots/photos:ro \
  gtunesdev/fspulse:latest
Why PUID/PGID Matters
Even though you mount directories as read-only (:ro), Linux permissions still apply. If your files are owned by UID 34 and aren't world-readable, FsPulse (running as UID 1000 by default) won't be able to scan them. Setting PUID=34 makes FsPulse run as the same user that owns the files.
When to use PUID/PGID:
- Files have restrictive permissions (not world-readable)
 - Using NAS with specific user accounts (TrueNAS, Unraid, Synology)
 - You need the 
/datadirectory to match specific host ownership 
Using the CLI
While the web UI provides full functionality, you can also use CLI commands via docker exec:
# Run a query
docker exec fspulse fspulse query "items where scan:(5)"
# View reports
docker exec fspulse fspulse report scans --last 10
# Interactive menu (requires -it flags)
docker exec -it fspulse fspulse interact
# Data explorer TUI (requires -it flags)
docker exec -it fspulse fspulse explore
The -it flags are required for interactive modes (interact and explore) to properly handle terminal input.
Helper script (optional): Create fspulse-docker.sh to simplify CLI access:
#!/bin/bash
docker exec fspulse fspulse "$@"
Then use it: ./fspulse-docker.sh query "items limit 10"
Advanced Topics
Custom Network Settings
If you're using macvlan or host networking, ensure the server binds to all interfaces:
services:
  fspulse:
    image: gtunesdev/fspulse:latest
    network_mode: host
    environment:
      - FSPULSE_SERVER_HOST=0.0.0.0  # Required for non-bridge networking
      - FSPULSE_SERVER_PORT=8080
Note: The Docker image sets FSPULSE_SERVER_HOST=0.0.0.0 by default, so this is only needed if your config.toml overrides it to 127.0.0.1.
Reverse Proxy Setup
For public access with authentication, use a reverse proxy like nginx:
server {
    listen 80;
    server_name fspulse.example.com;
    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        # WebSocket support for scan progress
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}
Using Bind Mounts Instead of Volumes
By default, we use Docker volumes (-v fspulse-data:/data) which Docker manages automatically. For NAS deployments, you might prefer bind mounts to integrate with your existing backup schemes:
# Create directory on host
mkdir -p /mnt/pool/fspulse/data
# Use bind mount
docker run -d \
  --name fspulse \
  -p 8080:8080 \
  -v /mnt/pool/fspulse/data:/data \  # Bind mount to host path
  gtunesdev/fspulse:latest
Benefits of bind mounts for NAS:
- Included in your NAS snapshot schedule
 - Backed up with your existing backup system
 - Directly accessible for manual inspection
 
Trade-off: You need to manage permissions yourself (use PUID/PGID if needed).
Troubleshooting
Cannot Access Web UI
Problem: http://localhost:8080 doesn't respond
Solutions:
- 
Check the container is running:
docker ps | grep fspulse - 
Check logs for errors:
docker logs fspulseLook for "Server started" message.
 - 
Verify port mapping:
docker port fspulseShould show
8080/tcp -> 0.0.0.0:8080 
Permission Denied Errors
Problem: "Permission denied" when scanning or accessing /data
Solutions:
- 
Check file ownership:
ls -ln /path/to/your/files - 
Set PUID/PGID to match file owner:
docker run -e PUID=1000 -e PGID=1000 ... - 
For bind mounts, ensure host directory is writable:
chown -R 1000:1000 /mnt/pool/fspulse/data 
Interactive Mode Doesn't Work
Problem: fspulse interact or fspulse explore looks broken in docker exec
Solution: Use -it flags for proper terminal:
# Wrong (missing -it)
docker exec fspulse fspulse interact
# Correct
docker exec -it fspulse fspulse interact
Configuration Changes Don't Persist
Problem: Settings revert after container restart
Solution: Verify /data volume is mounted:
docker inspect fspulse | grep -A 10 Mounts
If missing, recreate container with volume:
docker stop fspulse
docker rm fspulse
docker run -d --name fspulse -v fspulse-data:/data ...
Database Locked Errors
Problem: "Database is locked" errors
Cause: Multiple containers accessing the same database
Solution: Only run one FsPulse container per database. Don't mount the same /data volume to multiple containers.
Data Backup
Backing Up Your Data
For Docker volumes:
# Stop container
docker stop fspulse
# Backup volume
docker run --rm \
  -v fspulse-data:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/fspulse-backup.tar.gz /data
# Restart container
docker start fspulse
For bind mounts:
# Simply backup the host directory
tar czf fspulse-backup.tar.gz /mnt/pool/fspulse/data
Restoring from Backup
For Docker volumes:
# Create volume
docker volume create fspulse-data-restored
# Restore data
docker run --rm \
  -v fspulse-data-restored:/data \
  -v $(pwd):/backup \
  alpine sh -c "cd / && tar xzf /backup/fspulse-backup.tar.gz"
# Use restored volume
docker run -d --name fspulse -v fspulse-data-restored:/data ...
For bind mounts:
tar xzf fspulse-backup.tar.gz -C /mnt/pool/fspulse/data
Image Tags and Updates
FsPulse provides multiple tags for different update strategies:
| Tag | Description | When to Use | 
|---|---|---|
latest | Latest stable release | Production (pinned versions) | 
1.2.3 | Specific version | Production (exact control) | 
1.2 | Latest patch of minor version | Production (auto-patch updates) | 
main | Development builds | Testing new features | 
Recommendation: Use specific version tags (1.2.3) or minor version tags (1.2) for production. Avoid latest in production to prevent unexpected updates.
Updating to a new version:
docker pull gtunesdev/fspulse:1.2.3
docker stop fspulse
docker rm fspulse
docker run -d --name fspulse -v fspulse-data:/data ... gtunesdev/fspulse:1.2.3
Your data persists in the volume across updates.
Platform Support
FsPulse images support multiple architectures—Docker automatically pulls the correct one for your platform:
- linux/amd64 - Intel/AMD processors (most common)
 - linux/arm64 - ARM processors (Apple Silicon, Raspberry Pi 4, ARM servers)
 
Next Steps
- Explore the Configuration reference for all available settings
 - Learn about Query Syntax for advanced data filtering
 - Read Scanning to understand how scans work
 - Check Command-Line Interface for all CLI commands
 
Getting Help
- Issues: GitHub Issues
 - Docker Hub: gtunesdev/fspulse
 - Documentation: FsPulse Book
 
Scanning
FsPulse scans are at the core of how it tracks changes to the file system over time. A scan creates a snapshot of a root directory and analyzes changes compared to previous scans. This page explains how to initiate scans, how incomplete scans are handled, and the phases involved in each scan.
Initiating a Scan
You can start a scan in three ways:
- 
Web UI (Server Mode):
- Start the server: 
fspulse serve - Open http://localhost:8080 in your browser
 - Navigate to Manage Roots
 - Select a root and click Scan Root
 - Monitor real-time progress in the web interface
 
 - Start the server: 
 - 
Command line:
fspulse scan --root-path /your/path - 
Interactive mode: From the interactive menu, select Scan to re-scan a root path that has previously been scanned.
 
Note: The web UI and command line support scanning both new and existing roots. Interactive mode (
fspulse interact) only supports scanning previously scanned paths. To scan a new root for the first time, use the web UI or command line.
Once a scan on a root has begun, it must complete or be explicitly stopped before another scan on the same root can be started. Scans on other roots can run independently.
Docker users: When running FsPulse in Docker, the container runs in server mode by default. Access the web UI to manage scans, or use docker exec to run CLI commands. See the Docker Deployment chapter for details.
Hashing
Hashing is a key capabilities of FsPulse.
FsPulse uses the standard SHA2 (256) message-digest algorithm to compute digital fingerprints of file contents. The intent of hashing is to enable the detection of changes to file content in cases where the modification date and file size have not changed. One example of a case where this might occur is data decay. FsPulse can be used to create a hash baseline by scanning with the "hash" option. By default, a "hash" scan will compute hashes for items that have never been hashed or whose file size or modification date has changed. If the "hash-all" flag is passed along with the "hash" flag, FsPulse will hash all files, including those that have been previously hashed. If a hash is detected to have changed, a change record will be created.
The query below, for example, will find and show changes where file metadata has not changed, but the file's hash has changed.
fspulse query 'changes where meta_change:(F), hash_change:(T) show default, item_path order by change_id desc'
Validating
FsPulse can attempt to assess the "validity" of files.
FsPulse uses community-contributed libraries to "validate" files. Validation is implemented as opening and reading or traversing the file. These community libraries raise a variety of "errors" when invalid content is encountered.
FsPulse's ability to validate files is limited to the capabilities of the libraries that it uses and these libraries vary in terms of completeness and accuracy. In some cases, such as FsPulse's use of lopdf to validate PDF files, false positive "errors" may be detected as a consequence of lopdf encountering PDF file contents it does not yet understand. Despite these limitations, FsPulse offers a unique and effective view into potential validity issues in files.
As with hash options, FsPulse has two command-line flags related to validation: "validate" and "validate-all".
Passing "validate" will cause FsPulse to perform a validation pass on all files that have never been validated or have changed in terms of modification date or size. Passing "validate-all" will cause FsPulse to validate all files.
Validation states are stored in the database as:
- U: Unknown. No validation has been performed
 - N: No Validator. No validator exists for this file type
 - V: Valid. Validation was performed and no errors were encountered
 - I: Invalid. Validation was performed and an error was encountered
 
In the case of 'I', the validation error will be stored as val_error on the Item alongside the validation state, which is stored as val. When an item's validation state changes in any way, the change is recorded on a change record and the old and new states are both available on that record.
If a validation pass produces an error which is identical to the previously seen error, no change is recorded.
An example of a query that displays validation state changes is:
 fspulse query 'changes where val_change:(T) show default, item_path order by change_id desc'
Additional queries can be easily composed which filter on specific old and new validation states.
In-Progress Scans
FsPulse is designed to be resilient to interruptions like system crashes or power loss. If a scan stops before completing, FsPulse saves its state so it can be resumed later.
To resume or discard an in-progress scan:
fspulse scan --root-path /your/path
If a scan is in progress, FsPulse will prompt you to:
- Resume the scan from where it left off
 - Stop the scan and discard its partial results
 
Stopping a scan reverts the database to its pre-scan state. All detected changes, computed hashes, and validations from that partial scan will be discarded.
Phases of a Scan
Each scan proceeds in three main phases:
1. Discovery
The directory tree is deeply traversed. For each file or folder encountered:
- If not seen before:
- A new item is created
 - An Add change is recorded
 
 - If seen before:
- FsPulse compares current file system metadata:
- Modification date (files and folders)
 - File size (files only)
 
 - If metadata differs, the item is updated and a Modify change is recorded
 
 - FsPulse compares current file system metadata:
 - If the path matches a tombstoned item (previously deleted):
- If type matches (file/folder), the tombstone is reactivated and an Add change is created
 - If type differs, FsPulse creates a new item and new Add change
 
 
Files and folders are treated as distinct types. A single path that appears as both a file and folder at different times results in two separate items.
2. Sweep
FsPulse identifies items not seen during the current scan:
- Any item that:
- Is not a tombstone, and
 - Was not visited in the scan
 
 
...is marked as a tombstone, and a Delete change is created.
Moved files appear as deletes and adds, as FsPulse does not yet track move operations.
3. Analysis
This phase runs only if the scan is started with --hash and/or --validate.
- Hashing — Computes a SHA2 hash of file contents
 - Validation — Uses file-type-specific validators to check content integrity
 
If either the hash or validation result changes:
- If an Add or Modify change already exists, the new data is attached to it
 - Otherwise, a new Modify change is created
 
Each change stores both the old and new values for comparison.
Performance and Threading
The analysis phase runs in parallel:
- Default: 8 threads
 - User-configurable in Configuration
 
Summary of Phases
| Phase | Purpose | 
|---|---|
| Discovery | Finds and records new or modified items | 
| Sweep | Marks missing items as tombstones and records deletions | 
| Analysis | Computes hashes/validations and records changes if values differ | 
Each scan provides a consistent view of the file system at a moment in time and captures important differences across revisions.
Configuration
FsPulse supports persistent, user-defined configuration through a file named config.toml. This file allows you to control logging behavior, analysis settings, server configuration, and more.
📦 Docker Users: If you're running FsPulse in Docker, see the Docker Deployment chapter for Docker-specific configuration including environment variable overrides and volume management.
Finding config.toml
The location of config.toml depends on how you're running FsPulse:
Docker Deployments
When running in Docker, the config file is located at /data/config.toml inside the container. FsPulse automatically creates this file with default settings on first run.
To access it from your host machine:
# View the config
docker exec fspulse cat /data/config.toml
# Extract to edit
docker exec fspulse cat /data/config.toml > config.toml
See the Docker Deployment chapter for details on editing the config in Docker.
Native Installations
FsPulse uses the directories crate to determine platform-specific locations:
| Platform | Location Description | Example Path | 
|---|---|---|
| Linux | $XDG_DATA_HOME | /home/alice/.local/share/fspulse | 
| macOS | Application Support | /Users/alice/Library/Application Support/fspulse | 
| Windows | Local AppData | C:\Users\Alice\AppData\Local\fspulse | 
On first run, FsPulse automatically creates this directory and writes a default config.toml if one doesn't exist.
Tip: You can delete
config.tomlat any time to regenerate it with defaults. Newly introduced settings will not automatically be added to an existing file.
Configuration Settings
Here are the current available settings and their default values:
[logging]
fspulse = "info"
lopdf = "error"
[server]
port = 8080
host = "127.0.0.1"
[analysis]
threads = 8
hash = "sha2"
Logging
FsPulse uses the Rust log crate, and so does the PDF validation crate lopdf. You can configure logging levels independently for each subsystem in the [logging] section.
Supported log levels:
error– only critical errorswarn– warnings and errorsinfo– general status messages (default for FsPulse)debug– verbose output for debuggingtrace– extremely detailed logs
Log File Behavior
- Logs are written to a 
logs/folder inside the same local data directory asconfig.toml - Each run of FsPulse creates a new log file, named using the current date and time
 - FsPulse retains up to 100 log files; older files are automatically deleted
 
Server Settings
The [server] section controls the web UI server behavior when running fspulse serve.
host: IP address to bind to (default:127.0.0.1)127.0.0.1- Localhost only (secure, only accessible from same machine)0.0.0.0- All interfaces (required for Docker, remote access)
port: Port number to listen on (default:8080)
Note: In Docker deployments, the host should be 0.0.0.0 to allow access from outside the container. The Docker image sets this automatically via environment variable.
Analysis Settings
The [analysis] section controls how many threads are used during the analysis phase of scanning (for hashing and validation).
threads: number of worker threads (default:8)
You can adjust this based on your system's CPU count or performance needs.
hash: hash function to use when hashing files. Values can besha2ormd5(default:sha2)
Sha2 is more secure but is slower. It is appropriate for most users.
Environment Variables
All configuration settings can be overridden using environment variables. This is particularly useful for:
- Docker deployments where editing files is inconvenient
 - Different environments (development, staging, production) with different settings
 - NAS deployments (TrueNAS, Unraid) using web-based configuration UIs
 - CI/CD pipelines where configuration is managed externally
 
How It Works
Environment variables follow the pattern: FSPULSE_<SECTION>_<FIELD>
The <SECTION> corresponds to a section in config.toml (like [server], [logging], [analysis]), and <FIELD> is the setting name within that section.
Precedence (highest to lowest):
- Environment variables - Override everything
 - config.toml - User-defined settings
 - Built-in defaults - Fallback values
 
This allows you to set sensible defaults in config.toml and override them as needed per deployment.
Complete Variable Reference
Server Settings
Control the web UI server behavior (when running fspulse serve):
| Variable | Default | Valid Values | Description | 
|---|---|---|---|
FSPULSE_SERVER_HOST | 127.0.0.1 | IP address | Bind address. Use 0.0.0.0 for Docker/remote access, 127.0.0.1 for localhost only | 
FSPULSE_SERVER_PORT | 8080 | 1-65535 | Web UI port number | 
Examples:
# Native - serve only on localhost
export FSPULSE_SERVER_HOST=127.0.0.1
export FSPULSE_SERVER_PORT=8080
fspulse serve
# Docker - must bind to all interfaces
docker run -e FSPULSE_SERVER_HOST=0.0.0.0 -e FSPULSE_SERVER_PORT=9090 -p 9090:9090 ...
Logging Settings
Configure log output verbosity:
| Variable | Default | Valid Values | Description | 
|---|---|---|---|
FSPULSE_LOGGING_FSPULSE | info | error, warn, info, debug, trace | FsPulse application log level | 
FSPULSE_LOGGING_LOPDF | error | error, warn, info, debug, trace | PDF library (lopdf) log level | 
Examples:
# Enable debug logging
export FSPULSE_LOGGING_FSPULSE=debug
export FSPULSE_LOGGING_LOPDF=error
# Docker
docker run -e FSPULSE_LOGGING_FSPULSE=debug ...
Analysis Settings
Configure scan behavior, hashing, and validation:
| Variable | Default | Valid Values | Description | 
|---|---|---|---|
FSPULSE_ANALYSIS_THREADS | 8 | 1-256 | Number of worker threads for analysis phase (hashing/validation) | 
FSPULSE_ANALYSIS_HASH | sha2 | sha2, md5 | Hash algorithm (sha2 is more secure, md5 is faster) | 
Examples:
# Use 16 threads with MD5 hashing
export FSPULSE_ANALYSIS_THREADS=16
export FSPULSE_ANALYSIS_HASH=md5
# Docker
docker run -e FSPULSE_ANALYSIS_THREADS=16 -e FSPULSE_ANALYSIS_HASH=md5 ...
Database Settings
Control database location (advanced):
| Variable | Default | Valid Values | Description | 
|---|---|---|---|
FSPULSE_DATA_DIR | Platform-specific | Directory path | Override entire data directory location | 
FSPULSE_DATABASE_PATH | <data_dir> | Directory path | Override database directory (rarely needed) | 
Note: Most users should use FSPULSE_DATA_DIR rather than FSPULSE_DATABASE_PATH. In Docker, this defaults to /data.
Docker-Specific Variables
These variables are specific to Docker deployments:
| Variable | Default | Valid Values | Description | 
|---|---|---|---|
PUID | 1000 | UID number | User ID to run FsPulse as (for NAS permission matching) | 
PGID | 1000 | GID number | Group ID to run FsPulse as (for NAS permission matching) | 
TZ | UTC | Timezone string | Timezone for log timestamps and UI (e.g., America/New_York) | 
See Docker Deployment - NAS Deployments for details on PUID/PGID usage.
Usage Examples
Native (Linux/macOS/Windows):
# Set environment variables
export FSPULSE_SERVER_PORT=9090
export FSPULSE_LOGGING_FSPULSE=debug
export FSPULSE_ANALYSIS_THREADS=16
# Run FsPulse (uses env vars)
fspulse serve
Docker - Command Line:
docker run -d \
  --name fspulse \
  -e FSPULSE_SERVER_PORT=9090 \
  -e FSPULSE_LOGGING_FSPULSE=debug \
  -e FSPULSE_ANALYSIS_THREADS=16 \
  -p 9090:9090 \
  -v fspulse-data:/data \
  gtunesdev/fspulse:latest
Docker Compose:
services:
  fspulse:
    image: gtunesdev/fspulse:latest
    environment:
      - FSPULSE_SERVER_PORT=9090
      - FSPULSE_LOGGING_FSPULSE=debug
      - FSPULSE_ANALYSIS_THREADS=16
    ports:
      - "9090:9090"
Verifying Environment Variables
To see what environment variables FsPulse is using:
Native:
env | grep FSPULSE_
Docker:
docker exec fspulse env | grep FSPULSE_
Docker Configuration
When running FsPulse in Docker, configuration is managed slightly differently. The config file lives at /data/config.toml inside the container, and you have several options for customizing settings.
For step-by-step instructions on configuring FsPulse in Docker, including editing config files and using environment variables, see the Docker Deployment - Configuration section.
New Settings and Restoring Defaults
FsPulse may expand its configuration options over time. When new settings are introduced, they won't automatically appear in your existing config.toml. To take advantage of new options, either:
- Manually add new settings to your config file
 - Delete the file to allow FsPulse to regenerate it with all current defaults
 
Query Syntax
FsPulse provides a flexible, SQL-like query language for exploring scan results. This language supports filtering, custom column selection, ordering, and limiting the number of results.
Query Structure
Each query begins with one of the four supported domains:
rootsscansitemschanges
You can then add any of the following optional clauses:
DOMAIN [WHERE ...] [SHOW ...] [ORDER BY ...] [LIMIT ...]
Column Availability
roots Domain
All queries that retrieve root information begin with the keyword roots:
roots [WHERE ...] [SHOW ...] [ORDER BY ...] [LIMIT ...]
| Property | Type | 
|---|---|
root_id | Integer | 
root_path | Path | 
scans Domain
All queries that retrieve scan information begin with the keyword scans:
scans [WHERE ...] [SHOW ...] [ORDER BY ...] [LIMIT ...]
| Property | Type | Description | 
|---|---|---|
scan_id | Integer | Unique scan identifier | 
root_id | Integer | Root directory identifier | 
scan_state | Scan State Enum | State of the scan | 
is_hash | Boolean | Hash new or changed files | 
hash_all | Boolean | Hash all items including unchanged | 
is_val | Boolean | Validate new or changed files | 
val_all | Boolean | Validate all items including unchanged | 
scan_time | Date | Timestamp when scan was performed | 
file_count | Integer | Count of files found in the scan | 
folder_count | Integer | Count of directories found in the scan | 
total_file_size | Integer | Total size in bytes of all files in the scan | 
alert_count | Integer | Number of alerts created during the scan | 
add_count | Integer | Number of items added in the scan | 
modify_count | Integer | Number of items modified in the scan | 
delete_count | Integer | Number of items deleted in the scan | 
error | String | Error message if scan failed | 
items Domain
All queries that retrieve item information begin with the keyword items:
items [WHERE ...] [SHOW ...] [ORDER BY ...] [LIMIT ...]
| Property | Type | 
|---|---|
item_id | Integer | 
scan_id | Integer | 
root_id | Integer | 
item_path | Path | 
item_type | Item Type Enum | 
last_scan | Integer | 
is_ts | Boolean | 
mod_date | Date | 
file_size | Integer | 
last_hash_scan | Integer | 
file_hash | String | 
last_val_scan | Integer | 
val | Validation Status | 
val_error | String | 
changes Domain
All queries that retrieve change history begin with the keyword changes:
changes [WHERE ...] [SHOW ...] [ORDER BY ...] [LIMIT ...]
| Property | Type | 
|---|---|
change_id | Integer | 
root_id | Integer | 
scan_id | Integer | 
item_id | Integer | 
item_path | Path | 
change_type | Change Type Enum | 
is_undelete | Boolean | 
meta_change | Boolean | 
mod_date_old | Date | 
mod_date_new | Date | 
hash_change | Boolean | 
last_hash_scan_old | Integer | 
hash_old | String | 
hash_new | String | 
val_change | Boolean | 
last_val_scan_old | Integer | 
val_old | Validation Status | 
val_new | Validation Status | 
val_error_old | String | 
val_error_new | String | 
The WHERE Clause
The WHERE clause filters results using one or more filters. Each filter has the structure:
column_name:(value1, value2, ...)
Values must match the column’s type. You can use individual values, ranges (when supported), or a comma-separated combination. Values are not quoted unless explicitly shown.
| Type | Examples | Notes | 
|---|---|---|
| Integer | 5, 1..5, 3, 5, 7..9, null, not null, NULL, NOT NULL | Supports ranges and nullability. Ranges are inclusive. | 
| Date | 2024-01-01, 2024-01-01..2024-06-30, null, not null, NULL, NOT NULL | Use YYYY-MM-DD. Ranges are inclusive. | 
| Boolean | true, false, T, F, null, not null, NULL, NOT NULL | Values are unquoted. Null values are allowed in all-lower or all-upper case. | 
| String | 'example', 'error: missing EOF', null, NULL | Quoted strings. Null values are allowed in all-lower or all-upper case. | 
| Path | 'photos/reports', 'file.txt' | Must be quoted. Null values are not supported. | 
| Validation Status | V, I, N, U, null, not null, NULL, NOT NULL | Valid (V), Invalid (I), No Validator (N), Unknown (U). Unquoted. Ranges not supported. | 
| Item Type Enum | F, D, S, O, null, not null, NULL, NOT NULL | File (F), Directory (D), Symlink (S), Other (O). Unquoted. Ranges not supported. | 
| Change Type Enum | N, A, M, D, null, not null, NULL, NOT NULL | No Change (N), Add (A), Modify (M), Delete (D). Unquoted. Ranges not supported. | 
| Scan State Enum | S, W, A, C, P, E, null, not null, NULL, NOT NULL | Scanning (S), Sweeping (W), Analyzing (A), Completed (C), Stopped (P), Error (E). Unquoted. Ranges not supported. | 
Combining Filters
When specifying multiple values within a single filter, the match is logically OR. When specifying multiple filters across different columns, the match is logically AND.
For example:
scans where scan_time:(2025-01-01..2025-01-07, 2025-02-01..2025-02-07), hashing:(T)
This query matches scans that:
- Occurred in either the first week of January 2025 or the first week of February 2025
 - AND were performed with hashing enabled
 
The SHOW Clause
The SHOW clause controls which columns are displayed and how some of them are formatted. If omitted, a default column set is used.
You may specify:
- A list of column names
 - The keyword 
defaultto insert the default set - The keyword 
allto show all available columns 
Formatting modifiers can be applied using the @ symbol:
item_path@name, mod_date@short
Format Specifiers by Type
| Type | Allowed Format Modifiers | 
|---|---|
| Date | full, short, timestamp | 
| Path | full, relative, short, name | 
| Validation / Enum / Boolean | full, short | 
| Integer / String | (no formatting options) | 
The timestamp format modifier converts dates to UTC timestamps (seconds since Unix epoch), which is useful for programmatic processing or web applications that need to format dates in the user's local timezone.
The ORDER BY Clause
Specifies sort order for the results:
items order by mod_date desc, item_path asc
If direction is omitted, ASC is assumed.
The LIMIT Clause
Restricts the number of rows returned:
items limit 50
Examples
# Items whose path contains 'reports'
items where item_path:('reports')
# Changes involving validation failures
changes where val_new:(I) show default, val_old, val_new order by change_id desc
# Scans with timestamp for programmatic processing
scans show scan_id, scan_time@timestamp, file_count order by scan_time desc limit 10
# Scans with changes and alerts
scans show scan_id, file_count, total_file_size, add_count, modify_count, delete_count, alert_count order by scan_time desc
See also: Interactive Mode · Validators · Configuration
Command-Line Interface
FsPulse provides multiple modes of operation:
- Server mode — Run as a background service with web UI (see 
servecommand) - Command-line interface (CLI) — Direct terminal commands documented on this page
 - Interactive modes — Menu-driven and data explorer interfaces (see Interactive Mode)
 
This page documents the full CLI, including top-level commands, available subcommands, and commonly used options.
Getting Help
At any time, you can get help from the CLI using:
fspulse --help
fspulse <command> --help
For example:
fspulse scan --help
fspulse report items --help
Top-Level Commands
serve
Start the FsPulse server to run as a background service with browser-based access.
fspulse serve
The server will start on the configured host and port (default: http://127.0.0.1:8080). Access the web UI to:
- Manage roots (create, view, delete)
 - Initiate scans with real-time progress
 - Query and explore data
 - View scan results and changes
 
Configuration: Server host and port can be configured in config.toml under [server] section, or via environment variables FSPULSE_SERVER_HOST and FSPULSE_SERVER_PORT.
Docker users: The container automatically runs in serve mode. You can still access CLI commands via docker exec:
docker exec fspulse fspulse query "items limit 10"
docker exec -it fspulse fspulse interact
See the Docker Deployment chapter for more details.
interact
Launches FsPulse in interactive menu mode.
fspulse interact
- Provides a guided menu for scanning and reporting
 - Allows interactive query mode with history
 - Only usable for roots that have already been scanned
 
See the Interactive Mode chapter for full details.
explore
Launches an interactive, terminal-based data explorer.
fspulse explore
- Browse roots, scans, items, and changes in a full-screen TUI
 - Navigate between entity views using keyboard shortcuts
 - Filter and sort data interactively
 
This is different from interact (which is menu-driven). The explore command provides a more visual, spreadsheet-like interface for exploring your data.
scan
Performs a filesystem scan.
fspulse scan [--root-id <id> | --root-path <path> | --last] [--hash] [--validate]
--root-id— scan an existing root by ID--root-path— scan a new or existing root by its path--last— scan the most recently scanned root--hash— compute SHA2 hashes on new or changed files--hash-all— compute SHA2 hashes on all files (requires --hash)--validate— validate new or changed files with known formats (see Validators)--validate-all— validate all files (requires --validate)
report
Generates prebuilt reports about roots, scans, items, or changes.
fspulse report <subcommand> [options]
Available subcommands:
roots
fspulse report roots [--root-id <id> | --root-path <path>]
scans
fspulse report scans [--scan-id <id> | --last <N>]
items
fspulse report items [--item-id <id> | --item-path <path> | --root-id <id>] [--invalid]
changes
fspulse report changes [--change-id <id> | --item-id <id> | --scan-id <id>]
Notes:
--invalidonitemsrequires--root-id
query
Executes a structured query using FsPulse's flexible syntax.
fspulse query "<query string>"
Example:
fspulse query "items where item_path:('docs') order by mod_date desc limit 10"
See Query Syntax for full details.
Database Location
FsPulse automatically determines the database location using the following precedence:
FSPULSE_DATA_DIRenvironment variable (if set)config.toml[database]pathsetting (if configured)- Platform-specific data directory (default):
- Linux: 
~/.local/share/fspulse/ - macOS: 
~/Library/Application Support/fspulse/ - Windows: 
%LOCALAPPDATA%\fspulse\ 
 - Linux: 
 
The database file is always named fspulse.db within the determined directory.
For Docker deployments, the database is stored in /data/fspulse.db inside the container. See the Docker Deployment chapter for details.
For more information on configuration, see the Configuration chapter.
See also: Interactive Mode · Query Syntax · Configuration
Interactive Mode
FsPulse provides two terminal-based interactive interfaces for working with your data:
fspulse interact— Menu-driven interface (documented on this page)fspulse explore— Visual data explorer TUI (see below)
Both provide alternative ways to interact with FsPulse without needing the web UI.
Interactive Menu (fspulse interact)
The interact command provides a menu-driven interface for common tasks.

To launch:
fspulse interact
Available Options
The interactive menu offers:
- Scan — Re-scan a previously scanned root
 - Query — Run custom queries using the query language
 - Report — View predefined summary reports
 - Exit — Close interactive mode
 
Scan
This option lets you scan a folder that has already been scanned.
⚠️ You must first perform a scan from the command line using:
fspulse scan --root-path /your/path
Once a root has been scanned at least once, it becomes available in the interactive menu.
Interactive scans allow you to toggle:
- Hashing — compute SHA2 file hashes
 - Validation — check file content integrity for supported types
 
Query
Allows you to enter queries using FsPulse’s query syntax.
- Use full expressions like:
items where item_path:('photos') changes where val_new:(I) show default, val_old, val_new - Queries may be repeated until you type 
qorexit - Query errors provide detailed syntax feedback
 - Use the ↑ and ↓ arrow keys to scroll through previous entries in your session
 
Report
Provides quick access to common predefined reports:
- List all roots
 - Show recent scans
 - Display invalid items
 - View changes from the latest scan
 
Reports are internally implemented as saved queries and will expand over time.
Data Explorer (fspulse explore)
The explore command provides a visual, terminal-based data explorer—a full-screen TUI for browsing your FsPulse data.
To launch:
fspulse explore
Key Features
- Visual Interface: Spreadsheet-like display of roots, scans, items, and changes
 - Keyboard Navigation: Use arrow keys, Tab, and shortcuts to navigate
 - Entity Views: Switch between different data types (roots, scans, items, changes)
 - Filtering & Sorting: Interactive controls for refining results
 - Full-Screen: Maximizes terminal space for data exploration
 
Differences from interact
| Feature | interact | explore | 
|---|---|---|
| Interface | Menu-driven prompts | Full-screen visual TUI | 
| Navigation | Text-based selection | Arrow keys, visual navigation | 
| Data Display | List-based output | Table/grid layout | 
| Best For | Quick scans and queries | Visual data exploration | 
Docker Usage
Both interactive modes work in Docker via docker exec with the -it flags:
# Interactive menu
docker exec -it fspulse fspulse interact
# Data explorer
docker exec -it fspulse fspulse explore
Important: The -it flags are required for proper terminal interaction.
Summary
FsPulse offers multiple ways to interact with your data:
- Web UI — Full-featured browser interface (via 
fspulse serve) - Interactive Menu — Quick access to common tasks (via 
fspulse interact) - Data Explorer — Visual terminal-based exploration (via 
fspulse explore) - Direct CLI — Scriptable commands for automation (see Command-Line Interface)
 
Choose the interface that best fits your workflow.
Validators
FsPulse can optionally validate file contents during the analysis phase of a scan. To enable validation, pass the --validate flag when initiating a scan.
fspulse scan --root-path /your/path --validate
Validation allows FsPulse to go beyond basic metadata inspection and attempt to decode the file's contents using format-specific logic. This helps detect corruption or formatting issues in supported file types.
Validation Status Codes
Each item in the database has an associated validation status:
| Status Code | Meaning | 
|---|---|
U | Unknown — item has never been included in a validation scan | 
V | Valid — most recent validation scan found no issues | 
I | Invalid — validation failed; see validation_error field | 
N | No Validator — FsPulse does not currently support this file type | 
The
validation_errorfield contains the error message returned by the validator only if the item was marked invalid. This field is empty for valid items or items with no validator.
Note: Some validation "errors" surfaced by the underlying libraries may not indicate corruption, but rather unsupported edge cases or metadata formatting. Always review the error messages before assuming a file is damaged.
Supported Validators
FsPulse relies on external Rust crates for performing format-specific validation. We gratefully acknowledge the work of the developers behind these crates for making them available to the Rust community.
| File Types | Crate | Link | 
|---|---|---|
FLAC audio (.flac) | claxon | claxon on GitHub | 
Images (.jpg, .jpeg, .png, .gif, .tiff, .bmp) | image | image on GitHub | 
PDF documents (.pdf) | lopdf | lopdf on GitHub | 
Validation support may expand in future versions of FsPulse to cover additional file types such as ZIP archives, audio metadata, or XML/JSON files.
$1 See the Query Syntax page for full details on query clauses and supported filters.
Concepts
FsPulse is centered around tracking and understanding the state of the file system over time. The core entities in FsPulse — roots, scans, items, and changes — represent a layered model of this information.
Scans
Scans are the units of work performed by FsPulse. A scan is performed on a file system tree specified by a path. A scan deeply traverses the specified path and its children, recording information on the files and directories discovered. The details of scanning are explained in Scanning.
Root
A root is the starting point for a scan. It represents a specific path on the file system that you explicitly tell FsPulse to track.
Each root is stored persistently in the database, and every scan you perform refers back to a root.
- Paths are stored as absolute paths.
 - Each root has a unique ID.
 - You can scan a root multiple times over time.
 
Scan
A scan is a snapshot of a root directory at a specific point in time.
Each scan records metadata about:
- The time the scan was performed
 - Whether hashing and validation were enabled
 - The collection of items (files and folders) found during the scan
 
Scans are always tied to a root via root_id, and are ordered chronologically by scan_time.
Item
An item represents a single file or folder discovered during a scan.
Each item includes metadata such as:
- Path
 - Whether it's a file or directory
 - Last modified date
 - Size
 - Optional hash and validation info
 
Items are created when newly seen, and marked with a tombstone (is_ts = true) if they were present in previous scans but no longer exist.
Change
A change represents a detected difference in an item between the current scan and a previous one.
Changes may reflect:
- File additions
 - File deletions
 - Metadata or content modifications
 
Each change is associated with both the scan and the item it affects.
Entity Flow
A simplified representation of how the entities relate:
Root
 └── Scan (per run)
      └── Item (files and folders)
           └── Change (if the item changed)
These concepts form the foundation of FsPulse’s scan and query capabilities. Understanding them will help you make the most of both interactive and command-line modes.
Database
FsPulse uses an embedded SQLite database to store all scan-related data. The database schema mirrors the core domain concepts used in FsPulse: roots, scans, items, and changes.
Database Name and Location
The database file is always named:
fspulse.db
By default, FsPulse stores the database in the root of the user's home directory, as determined by the directories crate.
| Platform | Base Location | Example | 
|---|---|---|
| Linux | $HOME | /home/alice | 
| macOS | $HOME | /Users/Alice | 
| Windows | {FOLDERID_Profile} | C:\Users\Alice | 
The full path might look like:
/home/alice/fspulse.db
Custom Database Path
You can override the default location using the --db-path option:
fspulse --db-path /some/other/folder
In this case, FsPulse will look for (or create) a file named fspulse.db inside the specified folder. The filename cannot be changed — only the directory is configurable.
Schema Overview
The database schema is implemented using Rust and reflects the same logical structure used by the query interface:
roots— scanned root directoriesscans— individual scan snapshotsitems— discovered files and folders with metadatachanges— additions, deletions, and modifications between scans
The schema is versioned to allow future upgrades without requiring a full reset.
Exploring the Database
Because FsPulse uses SQLite, you can inspect the database using any compatible tool, such as:
- DB Browser for SQLite
 - The 
sqlite3command-line tool - SQLite integrations in many IDEs and database browsers
 
⚠️ Caution: Making manual changes to the database may affect FsPulse's behavior or stability. Read-only access is recommended.
FsPulse manages all internal data access automatically. Most users will not need to interact with the database directly.
Development
FsPulse is under active development, with regular improvements being made to both its functionality and documentation.
At this time, FsPulse is not open for public contribution. This may change in the future as the project matures and its architecture stabilizes. If you're interested in the project, you're encouraged to:
- Explore the source code
 - Open GitHub issues to report bugs or request features
 - Follow the project for updates
 
Your interest and feedback are appreciated.
License
FsPulse is released under the MIT License. You are free to use, modify, and distribute the software under the terms of this license.
Acknowledged Dependencies
FsPulse relies on several open source Rust crates. We gratefully acknowledge the work of these maintainers, particularly for enabling file format validation:
claxon— FLAC audio decodingimage— image decoding for JPG, PNG, GIF, TIFF, BMPlopdf— PDF parsing and validation
Additional dependencies are listed in the project’s Cargo.toml.
If contribution opportunities open in the future, setup instructions and contribution guidelines will be added here.
Roadmap
FsPulse is an actively evolving project. This roadmap outlines current priorities and areas under consideration for future development. Some features listed here are planned, while others are exploratory.
Planned Enhancements
These areas are actively being developed or prioritized:
🔍 Expanded Query Capabilities
- Support for additional filter types and data expressions
 - More flexible clause ordering and nesting
 - Improved error reporting and suggestions
 - Customizable output formats in the 
showclause 
📂 Additional Validators
- Add support for additional file types, such as:
- ZIP and archive formats
 - Audio metadata (ID3, Vorbis Comments)
 - Structured text formats (JSON, XML)
 
 - Improve clarity of validation errors
 
Possible Future Directions
📊 Reporting and Output
- Saved or user-defined reports
 - Aggregated summaries
 - Export formats: CSV, JSON, GPX
 
💻 Interactive Experience
- Query bookmarks or saved history
 - Persistent history across sessions
 - Scrollable/full-screen output views
 
🌐 Integration & Automation
- JSON export for pipelines and automation
 - Integration with backup or monitoring systems
 - CLI-friendly structured output
 
🧰 UI and Visualization Tools
- Optional terminal-based dashboard (TUI)
 - Future possibility of a lightweight web viewer
 
Community Involvement (Future)
While FsPulse is not currently accepting contributions, this may change. Potential areas for future help include:
- Adding validators for more file types
 - Improving query engine features
 - Translations and localization
 - Performance optimization for large-scale scans
 
If you have ideas, feature requests, or feedback, please open a GitHub issue — community input is welcome.