Initial project documentation for workflow-miner — a Rust CLI + zsh plugin that mines recurring command workflows from Atuin shell history.
4.0 KiB
4.0 KiB
Research: Rust Ecosystem & Dependencies
SQLite Access: rusqlite
Winner: rusqlite v0.38
| Feature | rusqlite | sqlx |
|---|---|---|
| Async | No (sync) | Yes |
| SQLite-only | Yes | No (multi-DB) |
| Bundled SQLite | Yes (feature flag) | No |
| Read-only support | Yes (SQLITE_OPEN_READ_ONLY) |
Yes |
Why rusqlite:
- Synchronous is fine for a CLI reading a local file
Connection::open_with_flags(path, OpenFlags::SQLITE_OPEN_READ_ONLY)ensures safetyfeatures = ["bundled"]includes SQLite 3.49.2 — no system dependency- Simpler dependency tree than sqlx
- WAL-safe: reading an Atuin DB in WAL mode from a separate process is safe
use rusqlite::{Connection, OpenFlags};
let db = Connection::open_with_flags(
"~/.local/share/atuin/history.db",
OpenFlags::SQLITE_OPEN_READ_ONLY | OpenFlags::SQLITE_OPEN_NO_MUTEX,
)?;
Shell Command Parsing
Level 1: Word splitting — shell-words
shell-words v1 — POSIX shell word splitting.
shell_words::split("git commit -m \"fix typo\"")
// → ["git", "commit", "-m", "fix typo"]
Simple, correct, well-maintained. Exactly what we need for command abstraction.
Level 2: Full AST parsing (optional)
| Crate | Version | Description | Maturity |
|---|---|---|---|
| brush-parser | 0.3.0 | Full POSIX/bash tokenizer + parser with AST | Active, part of brush-shell |
| conch-parser | 0.1.1 | Shell parser with AST builder | Stale |
| mystsh | Early | POSIX/bash parser | Newer, active |
Level 3: Variable expansion
shellexpand v3.1.1 — tilde and $VAR expansion. 10M+ downloads.
TUI: ratatui
Winner: ratatui v0.30
| Library | Stars | Status |
|---|---|---|
| ratatui | 18.6k | Active, community standard |
| cursive | ~3.8k | Maintained, less active |
| tui-rs | ~10k | Unmaintained (ratatui is the fork) |
Why ratatui:
- Immediate-mode rendering (you own the render loop)
- Widgets: Block, Paragraph, List, Table, Chart, BarChart, Tabs, etc.
- Backends: crossterm (default), termion, termwiz
- 100+ third-party widgets via awesome-ratatui
- 60+ FPS with complex layouts
- Since 0.30.0: modular architecture (ratatui-core, ratatui-widgets, ratatui-crossterm)
Relevant widgets for workflow dashboard:
Table— displaying discovered patternsList— navigating workflowsBarChart/Sparkline— frequency visualizationTabs— switching views
CLI Framework: clap
clap v4 with derive feature — standard, ergonomic.
Sequential Pattern Mining
No mature Rust crate exists. Zero repos in Rust on the sequential-pattern-mining GitHub topic.
Recommended: Implement PrefixSpan directly, porting from PrefixSpan-py. ~300-500 lines of Rust.
Justfile Generation
No Rust crate for generating Justfiles. Format is simple enough for string formatting.
Key syntax rules:
- Recipe bodies use spaces (with
set indent) or tabs - Recipe names: lowercase, hyphens allowed
- Variables:
name := "value", interpolated with{{name}} - Dependencies:
test: build lint - Parameters:
deploy target="default": - Shebang recipes: first line
#! @prefix suppresses echo- Validate with
just --fmt --check --unstable -f <file>
Recommended Cargo.toml
[workspace.dependencies]
rusqlite = { version = "0.38", features = ["bundled"] }
shell-words = "1"
ratatui = "0.30"
crossterm = "0.28"
chrono = { version = "0.4", features = ["serde"] }
clap = { version = "4", features = ["derive"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_yaml = "0.9"
anyhow = "1"
dirs = "6"