- 🔴 Critical: Security vulnerabilities requiring immediate attention
- 🟠 High: Significant functionality or architectural issues
- 🟡 Medium: Improvements and enhancements
- 🟢 Low: Nice-to-have features
- ✅ Complete: Finished items
- File:
install.sh - Issue: Downloads and executes binaries without checksum verification
- Risk: Man-in-the-middle attacks or compromised GitHub releases
- Fix: Add SHA256 checksum verification using GitHub's published checksums
- File:
src/install/mod.rs(install_or_update_tool) - Issue: Executes downloaded binaries without cryptographic verification
- Risk: Tampered releases from compromised maintainer accounts
- Fix: Implement trust-on-first-use (TOFU) with stored checksums, verify when available
- Current state:
src/install/mod.rs(1147 lines),src/main.rs(910 lines) - Progress:
install.rswas split intoinstall/mod.rs+install/github.rs, but both files remain large - Remaining work:
src/ main.rs # Still 910 lines; extract shim/symlink/self-update logic install/ mod.rs # Still 1147 lines; split further: core.rs # Installation orchestration (install_or_update_tool) recovery.rs # Self-healing (try_recover_tool, recover_all_installed_tools) updates.rs # Update checking (check_for_updates) version.rs # Version matching (version_matches, find_highest_version) list.rs # Tool listing/display (list_installed_tools) shim.rs # Extract from main.rs: create_shim_script, create_tool_symlink, strip_platform_suffix security.rs # Security utilities (path validation, checksums)
- File:
src/tool_id.rs(line 85:Some("default".to_string())) - Issue: String sentinel values "default" and "latest" used inconsistently (led to bug fixed in v0.6.2)
- Fix: Refactor
version: Option<String>to typed enum:pub enum Version { Latest, // Use GitHub's latest Specific(String), // Explicit version }
- Benefit: Compile-time prevention of invalid states
- File:
src/main.rs(Pull handler lines 246-282, execute_run lines 617-641) - Issue:
GitHubReleaseErrormatch arms duplicated in Pull and execute_run - Fix: Create helper function
handle_install_error()
- Issue: String literals scattered throughout ("github", "url", "__", "latest", "default", 0o755)
- Fix: Create
src/constants.rsmodule:pub const FORGE_GITHUB: &str = "github"; pub const FORGE_URL: &str = "url"; pub const DIR_SEPARATOR: &str = "__"; pub const PERM_EXECUTABLE: u32 = 0o755; // etc.
- File:
src/download.rs(line 34:fs::File::create) - Issue: Downloaded file is world-readable until permissions are set after extraction
- Fix: Set restrictive permissions (0o600) on creation, finalize after download
- File: Multiple locations in
src/main.rs - Issue: Error messages reveal internal paths (executable_path shown in logs)
- Fix: Sanitize paths in user-facing errors, use relative paths or tool names only
- File:
src/download.rs(line 17:reqwest::get(url)) - Issue: No limit on HTTP redirects during download (uses reqwest default)
- Fix: Build a
reqwest::Clientwith explicit max 10 redirects
- Issue: No way to configure certificate validation for corporate proxies
- Fix: Add
TOOLER_CA_BUNDLEandTOOLER_NO_VERIFY_TLS(with warnings) environment variables
- Issue: No maximum file size limit; malicious releases could exhaust disk space
- Fix: Add 500MB default limit, configurable via
TOOLER_MAX_DOWNLOAD_SIZE
- File:
src/main.rs(create_tool_symlink, create_shim_script) - Issue: Tool names used in shell scripts and symlink paths without validation
- Fix: Validate tool names contain only alphanumeric, hyphens, and underscores
- Issue:
try_recover_toolneeds improvement for deeply nested version structures (e.g.,infisical-cli/v0.41.90) - Related: Properly handle complex GitHub tag formats
- File:
src/install/mod.rs(lines 877-888) - Issue: When recovering tools from filesystem, install type detection relies on file count heuristic (<=3 files = binary)
- Fix: Store install type metadata more reliably, improve detection logic
- Functions:
find_highest_version()(src/install/mod.rs:541),api_version()(src/tool_id.rs:127) - Status: Marked
#[allow(dead_code)]but never called outside tests - Action: Remove or properly integrate
- File:
tests/test_version.rs - Issue: Contains only a standalone
main()function with a copy ofversion_matches()logic; not a real test module - Fix: Remove or convert to a proper unit test
- File:
src/install/github.rs(line 96) - Issue:
discover_url_versions()is an empty stub returningOk(vec![]) - Action: Implement directory scraping or remove if not needed
- Issue:
tooler run foo(unqualified name without/) makes GitHub API call that returns 404 - Fix: Check if tool exists locally or is qualified (has
/) before calling GitHub
- Feature: "Smart versioning" to handle tags with/without 'v' prefixes automatically
- Benefit: More flexible version specification
- ✅ Path Traversal Protection for Tar Archives: Added
starts_with(extract_dir)validation to bothextract_tar_gzandextract_tar_xzinsrc/download.rs, matching the existing ZIP protection - ✅ Self-Update:
tooler update toolerreplaces the running binary viahandle_self_update()insrc/main.rs - ✅ Multi-Binary Symlinks:
pullandruncreate symlinks for all executables found in the tool directory, not just the primary binary - ✅ Platform Suffix Stripping:
strip_platform_suffix()extracts base tool names (e.g.,cmk.linux.x86-64becomescmk) for cleaner symlinks - ✅ Deep Search Improvements:
find_tool_entryandhas_matching_binarymatch binaries with platform suffixes (e.g., searching for "cmk" findscmk.linux.x86-64) - ✅ Install Script Improvements:
install.shtriesghCLI first for authenticated API access, provides rate limit error guidance, and bootstraps self-update viatooler pull morgaesis/tooler - ✅ Initial install.rs Split: Extracted
src/install/github.rsfrom monolithicsrc/install.rsintosrc/install/module structure
- ✅ "default" Version Bug: Fixed 404 error when running tools without explicit version
- Added
build_gh_release_url()function with proper version handling - Added unit tests for all version cases
- Converted e2e tests to feature flags (
#[cfg(feature = "e2e")])
- Added
- ✅ Tool Aliases and automatic deduction
- ✅ Multi-binary archive support (kubeadm from kubectl)
- ✅ Auto-shimming default enabled
- ✅ Tooler-controlled shim directory (
~/.local/share/tooler/shims) - ✅
tooler config showwith format options - ✅ Auto-shim on
tooler pull - ✅ Enhanced
tooler listwith colors, age, architecture, stale status - ✅ Fixed version display 'v' prefix bug
- ✅ Log level via
LOG_LEVELandTOOLER_LOG_LEVEL - ✅ Actual auto-updates on run
- ✅ Self-healing filesystem discovery (recover lost configs)
- ✅ Fixed terraform/tflint substring matching bug
- ✅ Fixed tool age reporting (using
installed_atnotlast_accessed) - ✅ Robust update check logic with
last_checkedfield - ✅ Fixed usage tracking for short-name queries
- 🔮 Enhanced Forge Support: GitLab, Gitea, or other Git hosts
- 🔮 Export/Import Config: Easier migration of toolsets between machines
- 🔮 Lock Files: Pin entire toolset versions for reproducible environments
- 🔮 Plugin System: Allow custom install logic for complex tools
- 🔮 Binary Signing: Cryptographic signatures for all downloaded tools
- Path traversal attempts in archives (protection exists but no test)
- Checksum verification failure handling (not yet implemented)
- Tool name sanitization (malicious names)
- Permission error handling (read-only filesystems)
- Concurrent installation race conditions
- Malformed config recovery edge cases
- Binary architecture mismatch rejection
tests/
unit/ # Unit tests for specific modules
test_version.rs
test_platform.rs
test_config.rs
integration/ # Integration tests
test_cli.rs
test_install.rs
test_recovery.rs
e2e/ # End-to-end tests (network required)
test_github_tools.rs
test_url_tools.rs
security/ # Security-focused tests
test_path_traversal.rs
test_checksum_verify.rs
test_input_validation.rs
common.rs # Shared test utilities
- Security First: All file operations validated, checksums verified, paths sanitized
- Fail Secure: Default to safe behavior (no execution without verification)
- Separation of Concerns: Each module has single responsibility
- Type Safety: Use enums instead of string sentinel values
- Testability: Small, focused functions that can be unit tested
- Defense in Depth: Multiple validation layers
- Planning files (task_plan.md, findings.md, progress.md, SECURITY_REVIEW.md) are local working documents and should not be committed
- Use priority levels (Critical/High/Medium/Low) instead of time-based language
- E2E tests use
#[cfg(feature = "e2e")]and require--features e2eflag - All tests must use proper isolation (TOOLER_CONFIG, TOOLER_DATA_DIR, etc.)