alfrusco
A powerful, ergonomic Rust library for building Alfred workflows with ease. Alfrusco handles the complexity of Alfred's JSON protocol, provides rich item building capabilities, and includes advanced features like background jobs, clipboard operations, and comprehensive logging.
Features
- Simple & Ergonomic API - Intuitive builder patterns for creating Alfred items
- Async Support - Full async/await support for modern Rust applications
- Background Jobs - Run long-running tasks without blocking Alfred's UI
- Clipboard Integration - Built-in support for rich text and Markdown clipboard operations
- Smart Filtering - Automatic fuzzy search and sorting of results
- Workflow Management - Easy access to workflow directories and configuration
- Comprehensive Logging - Structured logging with file and console output
- URL Items - Specialized support for URL-based workflow items
- Environment Handling - Robust configuration management for Alfred environments
- Testing Support - Built-in testing utilities and mocking capabilities
๐ฆ Installation
Add alfrusco to your Cargo.toml:
[]
= "0.2"
# For async workflows
= { = "1", = ["full"] }
# For command-line argument parsing (recommended)
= { = "4", = ["derive", "env"] }
๐ Quick Start
Basic Synchronous Workflow
use ;
use AlfredEnvProvider;
use Parser;
Async Workflow with HTTP Requests
use ;
use AlfredEnvProvider;
use Parser;
use Deserialize;
async
๐๏ธ Core Concepts
Items
Items are the building blocks of Alfred workflows. Each item represents a choice in the Alfred selection UI:
use Item;
let item = new
.subtitle
.arg
.uid
.valid
.icon_from_image
.copy_text
.large_type_text
.quicklook_url
.var
.autocomplete;
Workflow Configuration
Alfrusco automatically handles Alfred's environment variables through configuration providers:
use ;
// For production (reads from Alfred environment variables)
let provider = AlfredEnvProvider;
// For testing (uses temporary directories)
let temp_dir = tempdir.unwrap;
let provider = TestingProvider;
Error Handling
Implement custom error types that work seamlessly with Alfred:
use ;
use Error;
// Errors automatically become Alfred items
๐ง Advanced Features
Background Jobs
Run long-running tasks without blocking Alfred's UI. This example fetches GitHub release data in the background and caches it to disk, showing cached results immediately while refreshing stale data:
use Command;
use Duration;
Enhanced Background Job Features:
- Smart Status Tracking: Jobs show detailed status messages like "Last succeeded 2 minutes ago (14:32:15), running for 3s" or "Last failed 5 minutes ago (14:29:42), running for 1s"
- Automatic Retry Logic: Failed jobs are automatically retried even if they ran recently, ensuring eventual success
- Context-Aware Icons: Visual indicators show job status at a glance:
- โ Success jobs show completion icon
- โ Failed jobs show error icon
- ๐ Retry attempts show sync icon
- ๐ First-time runs show clock icon
- Secure Shell Escaping: Arguments with spaces and special characters are properly escaped for security
- Robust Last-Run Tracking: All job executions are tracked regardless of success/failure for accurate status reporting
Background Job Status Messages:
When a background job is running, Alfred will display informative status items:
Background Job 'github-releases'
Last succeeded 2 minutes ago (14:32:15), running for 3s
This gives users clear visibility into:
- When the job last ran successfully or failed
- The exact time of the last execution
- How long the current execution has been running
- Visual context through appropriate icons
URL Items with Rich Clipboard Support
Create URL items with automatic clipboard integration:
use URLItem;
let url_item = new
.subtitle
.short_title // Used in Cmd+Shift modifier
.long_title // Used in Cmd+Ctrl modifier
.icon_for_filetype
.copy_text;
// Convert to regular Item (happens automatically when added to workflow)
let item: Item = url_item.into;
URL items automatically include modifiers for copying links:
- โ (Cmd): Copy as Markdown link
[title](url) - โฅ (Alt): Copy as rich text link (HTML)
- โโง (Cmd+Shift): Copy as Markdown with short title
- โฅโง (Alt+Shift): Copy as rich text with short title
- โโ (Cmd+Ctrl): Copy as Markdown with long title
- โฅโ (Alt+Ctrl): Copy as rich text with long title
Smart Filtering and Sorting
Enable automatic fuzzy search and sorting of results:
Workflow Directories
Access workflow-specific data and cache directories:
Response Caching and Rerun
Control Alfred's caching behavior and automatic refresh:
use Duration;
๐งช Testing
Alfrusco provides comprehensive testing support with shared utilities and organized test structure:
### Test Organization
Alfrusco maintains a comprehensive test suite with 112 tests across organized test files:
background_job_integration_tests.rs- Complete background job lifecycle testing (6 tests)clipboard_tests.rs- Clipboard functionality testing (4 tests)config_tests.rs- Configuration and environment testing (8 tests)error_injection_tests.rs- Error handling and edge cases (2 tests)error_tests.rs- Error type behavior (7 tests)logging_tests.rs- Logging functionality (1 test)runnable_tests.rs- Trait implementation testing (4 tests)tests/common/mod.rs- Shared test utilities and helpers
Shared Test Utilities
The tests/common/mod.rs module provides reusable testing utilities that eliminate code duplication and ensure
consistent test setup across the entire test suite. This includes helper functions for creating test workflows, managing
temporary directories, and common test operations.
## ๐ Examples
The `examples/` directory contains complete, runnable examples. Since these examples use `AlfredEnvProvider`, they require Alfred environment variables to be set. We provide a convenient script to run them with mock environment variables:
### Running Examples
**Option 1: Using the run script (recommended)**
```bash
# Basic static output
./run-example.sh static_output
# Success workflow with custom message
./run-example.sh success --message "Custom message"
# Async API example
./run-example.sh random_user search_term
# URL items demonstration
./run-example.sh url_items
# Background job example
./run-example.sh sleep --duration-in-seconds 10
# Error handling example
./run-example.sh error --file-path nonexistent.txt
Option 2: Using Make targets
# List all available examples
# Run specific examples
Option 3: Manual environment setup
# Set required Alfred environment variables
# Then run normally
Example Descriptions
- static_output - Basic workflow that returns static items without user input
- success - Simple workflow demonstrating command-line argument parsing
- random_user - Async workflow that fetches data from an external API with fuzzy filtering
- url_items - Demonstrates URL items with automatic clipboard integration and modifiers
- sleep - Shows background job execution with status monitoring
- error - Demonstrates custom error types and error item generation
- async_success - Basic async workflow example
- async_error - Async workflow with error handling examples
๐ API Reference
Core Types
Item
The primary building block for Alfred workflow results.
Key Methods:
new(title)- Create a new item with a titlesubtitle(text)- Set subtitle textarg(value)/args(values)- Set arguments passed to actionsvalid(bool)- Set whether the item is actionableuid(id)- Set unique identifier for Alfred's learningicon_from_image(path)/icon_for_filetype(type)- Set item iconscopy_text(text)/large_type_text(text)- Set text operationsquicklook_url(url)- Enable Quick Look previewvar(key, value)- Set workflow variablesautocomplete(text)- Set tab completion textmodifier(modifier)- Add keyboard modifier actions
URLItem
Specialized item type for URLs with automatic clipboard integration.
Key Methods:
new(title, url)- Create a URL itemsubtitle(text)- Override default URL subtitleshort_title(text)/long_title(text)- Set alternative titles for modifiersdisplay_title(text)- Override displayed title while preserving link titlecopy_text(text)- Set custom copy texticon_from_image(path)/icon_for_filetype(type)- Set icons
Workflow
Main workflow execution context.
Key Methods:
append_item(item)/append_items(items)- Add items to resultsprepend_item(item)/prepend_items(items)- Add items to beginningset_filter_keyword(query)- Enable fuzzy filteringdata_dir()/cache_dir()- Access workflow directoriesrun_in_background(name, max_age, command)- Execute background jobs
Response
Controls Alfred's response behavior.
Key Methods:
cache(duration, loose_reload)- Set caching behaviorrerun(interval)- Set automatic refresh intervalskip_knowledge(bool)- Control Alfred's knowledge integration
Traits
Runnable
For synchronous workflows.
AsyncRunnable
For asynchronous workflows.
WorkflowError
For custom error types that integrate with Alfred.
Configuration
AlfredEnvProvider
Production configuration provider that reads from Alfred environment variables.
TestingProvider
Testing configuration provider that uses temporary directories.
Execution Functions
execute(provider, runnable, writer)- Execute synchronous workflowexecute_async(provider, runnable, writer)- Execute asynchronous workflowinit_logging(provider)- Initialize structured logging## ๐ ๏ธ Development
Building from Source
Running Tests
# Run all tests
# Run tests with nextest (recommended)
# Run tests serially (for debugging flaky tests)
# Run with coverage
Running Examples
Examples require Alfred environment variables. Use the provided script:
# Basic static output
# Success workflow with custom message
# Async API example
# URL items demonstration
# Background job example
# Error handling example
# Or use Make targets
๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Development Setup
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for your changes
- Ensure all tests pass (
cargo nextest run) - Run clippy (
cargo clippy) - Format your code (
cargo fmt) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Code Style
- Follow Rust standard formatting (
cargo fmt) - Ensure clippy passes without warnings (
cargo clippy) - Add documentation for public APIs
- Include tests for new functionality
- Update examples if adding new features
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Support
- ๐ Documentation
- ๐ Issue Tracker
- ๐ฌ Discussions
Made with โค๏ธ for the Alfred and Rust communities.