syntaxis/shared/templates/new-tool-with-shared-features
Jesús Pérez 9cef9b8d57 refactor: consolidate configuration directories
Merge _configs/ into config/ for single configuration directory.
Update all path references.

Changes:
- Move _configs/* to config/
- Update .gitignore for new patterns
- No code references to _configs/ found

Impact: -1 root directory (layout_conventions.md compliance)
2025-12-26 18:36:23 +00:00
..

New Tool with Shared Features Template

This is a production-ready template for creating new Rust CLI tools in the Tools ecosystem that integrate shared utilities from the moment of creation.

What's Included

Shared Utilities Integration

  • Project detection from .project/ or .vapora/
  • Interactive project selection with inquire
  • Database migration discovery and management
  • XDG directory support (data, config, cache)

Professional CLI Structure

  • Proper error handling with Result<T>
  • Async/await ready with tokio
  • Structured logging with tracing
  • Colored output with colored crate

Best Practices

  • Zero unsafe code
  • No unwrap() in production code
  • Comprehensive documentation
  • Test template included

Pre-configured Dependencies

  • All necessary shared utilities
  • All standard Tools ecosystem crates
  • Production-ready configuration

Using This Template

1. Copy Template

cp -r /Users/Akasha/Tools/shared/templates/new-tool-with-shared-features ~/my-tool
cd ~/my-tool

2. Customize Variables

Replace these placeholders throughout the files:

  • {{tool_name}} → Your tool's descriptive name (e.g., "Task Manager")
  • {{tool_name_kebab}} → CLI name (e.g., "task-manager")

Example:

sed -i '' 's/{{tool_name}}/My Tool/g' Cargo.toml src/main.rs
sed -i '' 's/{{tool_name_kebab}}/my-tool/g' Cargo.toml src/main.rs

3. Customize Commands

In src/main.rs, replace the Main command with your actual commands:

#[derive(Subcommand)]
enum Commands {
    /// Your actual command
    Process {
        #[arg(value_name = "FILE")]
        input: PathBuf,
    },

    // ... keep the three shared commands ...
    Detect,
    SelectProject,
    FindMigrations { path: String },
}

4. Implement Main Logic

Replace the main_command() function with your tool's logic:

async fn main_command(input: &Path) -> Result<()> {
    // Your implementation
    Ok(())
}

5. Test

cargo test
cargo build
./target/debug/my-tool detect
./target/debug/my-tool select-project
./target/debug/my-tool find-migrations --path .

Template Files

Cargo.toml

Pre-configured with:

  • Tools ecosystem shared utilities
  • All recommended dependencies
  • Production-ready build settings
  • Development dependencies for testing

src/main.rs

Includes:

  • CLI struct with clap derive macros
  • Three integrated shared commands (detect, select-project, find-migrations)
  • Early return pattern for non-database commands
  • Colored output demonstrations
  • Documentation examples
  • Basic test template

Directory Structure

After customization:

my-tool/
├── Cargo.toml                  # Workspace and dependencies
├── README.md                   # Your tool documentation
├── QUICKSTART.md               # 5-10 minute setup guide
├── src/
│   └── main.rs                 # CLI entry point with shared features
├── data/
│   └── migration/              # SQL migrations
│       ├── 001_initial.sql
│       └── 002_add_index.sql
├── examples/
│   └── config.toml             # Example configuration
└── tests/                      # Integration tests

Key Features Integrated

1. Project Detection

./my-tool detect

Shows detected project from .project/lifecycle.toml or .vapora/lifecycle.toml

2. Interactive Selection

./my-tool select-project

Uses inquire for interactive project picker with arrow key support

3. Migration Discovery

./my-tool find-migrations --path .

Discovers and lists SQL migration files in data/migration/ directory

Next Steps

Add Your Main Commands

  1. Define command in Commands enum
  2. Add match arm in main command handler
  3. Implement command function
  4. Add tests

Add Configuration Support

use tools_shared::find_config_path;

let config = find_config_path("my-tool.toml")?;

Add Database Support

use sqlx::sqlite::SqlitePool;
use tools_shared::find_db_path;

let db_path = find_db_path("my-tool.db");
let pool = SqlitePool::connect(&format!("sqlite://{}", db_path.display())).await?;

Add Async Handlers

The template uses #[tokio::main] and is ready for async handlers:

async fn my_async_command() -> Result<()> {
    // async implementation
    Ok(())
}

Best Practices Already Included

Error Handling

  • All functions return Result<T>
  • No unwrap() in production code
  • Proper error propagation with ?

Logging

  • Structured logging with tracing
  • Verbose logging support with --verbose flag
  • Integration ready for RUST_LOG environment variable

Code Quality

  • Zero unsafe code
  • Production-ready dependencies
  • Formatted and linted code

Documentation

  • Module-level documentation
  • Command documentation
  • Usage examples

Common Additions

Add Global Project Flag

#[derive(Parser)]
struct Cli {
    /// Project name (auto-detected if omitted)
    #[arg(short = 'p', long, global = true)]
    project: Option<String>,

    // ... rest of CLI ...
}

Add Subcommands

#[derive(Subcommand)]
enum Commands {
    #[command(subcommand)]
    Config(ConfigCommands),
}

#[derive(Subcommand)]
enum ConfigCommands {
    Init { path: PathBuf },
    Show { path: PathBuf },
}

Add Configuration File Support

Create config.rs:

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
pub struct Config {
    pub name: String,
    pub version: String,
}

impl Config {
    pub fn load(path: &Path) -> Result<Self> {
        let contents = std::fs::read_to_string(path)?;
        Ok(toml::from_str(&contents)?)
    }
}

Troubleshooting

Compilation Errors

# Update Rust
rustup update

# Clean and rebuild
cargo clean
cargo build

Missing Dependencies

All dependencies should be in Cargo.toml. If you need to add more:

cargo add dependency-name

Project Detection Not Working

Verify .project/lifecycle.toml or .vapora/lifecycle.toml exists in your project directory or a parent directory.

Testing Template

The template includes a basic test:

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_main_command() {
        assert!(main_command(".").is_ok());
    }
}

Add more tests as needed:

cargo test
cargo test --verbose
RUST_LOG=debug cargo test -- --nocapture

Integration with Tools Ecosystem

Once your tool is ready:

  1. Move to /Users/Akasha/Tools/my-tool/
  2. Update main README.md
  3. Create Claude Code skills in .claude/skills/
  4. Add to /Users/Akasha/Tools/README.md
  5. Commit to git

Reference Implementations

Study these complete implementations:

  • /Users/Akasha/Tools/hello-tool/ - Simple reference
  • /Users/Akasha/Tools/tracking-manager/ - Production with database
  • /Users/Akasha/Tools/doc-syntaxis/ - Complex integration

Support

For detailed integration guidance, see:

  • Skill: .claude/skills/shared-utilities-integration.md
  • Guide: /Users/Akasha/Tools/shared/rust/INTEGRATION_GUIDE.md
  • README: /Users/Akasha/Tools/shared/rust/README.md

Customization Checklist

  • Replace {{tool_name}} with your tool name
  • Replace {{tool_name_kebab}} with CLI name
  • Update description in Cargo.toml
  • Update authors in Cargo.toml
  • Implement your main command logic
  • Add your actual CLI commands
  • Create data/migration/ directory if needed
  • Create examples/config.toml if needed
  • Test all commands
  • Update README.md with your tool info
  • Create QUICKSTART.md
  • Add tests

License

MIT - Same as Tools ecosystem