Skip to main content

Getting started

1

Fork the repository

Fork Rehanasharmin/Progflow on GitHub, then clone your fork:
git clone https://github.com/<your-username>/Progflow.git
cd Progflow
2

Build and verify

cargo build --release
./target/release/progflow --help
See Building from source for full prerequisites and install steps.
3

Create a branch

git checkout -b my-feature

Adding a new command

Each command lives in its own file under src/commands/. The pattern is consistent across all existing commands.
1

Create the command module

Add src/commands/<name>.rs with a pub fn run function that returns Result<(), AppError>:
// src/commands/yourcommand.rs
use crate::error::AppError;

pub fn run(name: &str) -> Result<(), AppError> {
    // implementation
    Ok(())
}
2

Export the module

Add a pub mod line to src/commands/mod.rs:
pub mod yourcommand;
3

Add a variant to the Commands enum

Open src/main.rs and add your variant to the Commands enum:
#[derive(Subcommand)]
enum Commands {
    // ... existing variants ...
    #[command(about = "Description of your command")]
    Yourcommand { name: String },
}
4

Dispatch in main

Add a match arm in the match cli.command block in main():
Commands::Yourcommand { name } => yourcommand::run(&name),
Import your new module at the top of main.rs alongside the other command imports:
use commands::{edit, list, new, note, off, on, yourcommand};

Error handling

Use the variants of AppError (defined in src/error.rs) to signal different failure modes:
VariantExit codeWhen to use
AppError::User(String)1Bad arguments, flow not found, or any user-fixable problem
AppError::Io(String, std::io::Error)2File read/write failures — include the file path as the first argument
AppError::Json(String, serde_json::Error)2JSON parse or serialization failures — include the file path as the first argument
// User error — describes what the user did wrong
return Err(AppError::User(format!("Flow '{}' does not exist", name)));

// IO error — wraps the underlying std::io::Error with context
fs::read_to_string(&path).map_err(|e| AppError::Io(path.display().to_string(), e))?;

// JSON error — wraps serde_json::Error with context
serde_json::from_str(&content).map_err(|e| AppError::Json(path.display().to_string(), e))?;
Error messages are printed to stderr by main() automatically — your command only needs to return the error.

Code style and checks

Run these commands before committing:
cargo fmt          # Format code
cargo clippy       # Lint for common mistakes
cargo test         # Run unit tests
cargo clippy treats warnings as guidance, not hard failures, but address any new warnings introduced by your change before opening a pull request.

Submitting a pull request

1

Push your branch

git push origin my-feature
2

Open a pull request

Open a pull request against the master branch of Rehanasharmin/Progflow.
3

Describe your change

In the pull request description, explain:
  • What the change does
  • Why it is needed or useful
  • Any edge cases or platform-specific behaviour to be aware of

Build docs developers (and LLMs) love