78 Commits
Author SHA1 Message Date
d3380c668a feat: fzf README preview with glow support
continuous-integration/drone/tag Build is passing
continuous-integration/drone/push Build is passing
- Show README.md in the right 40% of the fzf picker on hover
- Render with glow (CLICOLOR_FORCE=1 for colors in non-TTY pipe) when available, fall back to cat
- Preview command uses sh -c for fish/zsh/bash compatibility
- Bump version to 0.10.0

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-03-05 20:24:13 -03:00
cinco 8aa341080d perf: stale-while-revalidate cache — always instant startup
continuous-integration/drone/tag Build is passing
continuous-integration/drone/push Build is passing
Cache is now returned immediately on every run. When stale (age >
cache_ttl_hours), a detached background process rebuilds it
incrementally via --background-refresh, so blocking scans never
happen in the foreground after the first run.

cache_ttl_hours is now actually enforced (previously ignored).
2026-03-04 23:39:30 -03:00
cinco 2abf7e77b4 🐛 fix: run shortcut and desktop wizards after default config too
continuous-integration/drone/tag Build is passing
continuous-integration/drone/push Build is passing
The shortcut/desktop setup was only offered when the user chose the
interactive wizard path; the default config path skipped them entirely.

Move both setup_shortcut_wizard and setup_desktop_integration_wizard
calls out of run_wizard and into ensure_config_exists so they always
run after the config file is written, regardless of the setup mode chosen.
2026-03-01 21:37:14 -03:00
cinco 2d7d49d548 🔖 chore: bump version to 0.9.0 and update CHANGELOG
continuous-integration/drone/tag Build is passing
continuous-integration/drone/push Build is passing
2026-03-01 20:15:33 -03:00
cinco ee2059986c feat: add first-run setup choice prompt
When no config file exists, ask the user whether to run the
interactive wizard or apply sensible defaults immediately.

- Add `SetupChoice` enum and `parse_setup_choice_input` (pure, tested)
- Add `render_setup_choice_prompt` and `render_default_config_saved` UI helpers
- Extract `Config::write_default_config` and `Config::run_wizard` from
  `ensure_config_exists` for clarity; routing now driven by the user's choice
- 9 new tests covering all branches of `parse_setup_choice_input` and
  the default-config write path
2026-03-01 20:15:30 -03:00
cinco 2da5715a34 🔖 chore: bump version to 0.8.3 and commit Cargo.lock
continuous-integration/drone/tag Build is passing
continuous-integration/drone/push Build is passing
2026-03-01 20:00:50 -03:00
cinco 4263f0379d 🐛 fix: handle space after colon in GitHub API JSON tag_name field
continuous-integration/drone/tag Build is passing
continuous-integration/drone/push Build is passing
2026-03-01 19:59:12 -03:00
cinco a8f88e852c 🐛 fix: show GitHub API response when install.sh fails to fetch release
continuous-integration/drone/tag Build is passing
continuous-integration/drone/push Build is passing
Remove -f from curl API call so HTTP errors are visible instead of
silently swallowed; print up to 400 bytes of the raw response to stderr.

Bumps version to 0.8.1.
2026-03-01 19:56:01 -03:00
cinco 0e2745acf1 ♻️ refactor: rename --create-desktop-shortcut to --setup-desktop-shortcut
continuous-integration/drone/tag Build is passing
continuous-integration/drone/push Build is passing
2026-03-01 19:42:12 -03:00
cinco d7246298b1 feat: add desktop integration wizard and --create-desktop-shortcut
- install_desktop_integration_to() writes .desktop and downloads icon
- setup_desktop_integration_wizard() prompts and installs to XDG paths
- --create-desktop-shortcut flag to re-run at any time
- First-run wizard now also offers desktop integration after shortcut setup
- 164 tests passing
2026-03-01 19:40:15 -03:00
cinco 3aacf30697 feat: keyboard shortcut setup wizard (0.8.0)
- Add --setup-shortcut flag to configure a desktop keybinding
- Wizard runs automatically on first run after config creation
- Supports Hyprland (bindings.conf + hyprctl conflict check),
  GNOME (gsettings) and KDE (kglobalshortcutsrc)
- Hyprland: prefers omarchy-launch-tui, falls back to xdg-terminal-exec
- Conflict detection with fallback combo suggestions
- Add tmuxido.desktop and install icon + .desktop in install.sh
- 157 tests passing
2026-03-01 19:22:32 -03:00
cinco 906eec994f 📸 decrease canvas size in icon assets
continuous-integration/drone/push Build is passing
2026-03-01 18:51:31 -03:00
cinco d0f6592729 📷 add tmuxido small icons
continuous-integration/drone/push Build is passing
2026-03-01 18:41:12 -03:00
cinco 3f72128a25 🔖 chore: bump version to 0.7.1 and update CHANGELOG
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2026-03-01 05:07:06 -03:00
cinco cc16cde540 📝 docs: add ASCII art previews for each available tmux layout in README 2026-03-01 05:07:03 -03:00
cinco db08840b64 🐛 fix: ask for layout in interactive wizard when window has multiple panes
Add `render_layout_prompt` and `parse_layout_input` to ui.rs so that
the first-run wizard asks the user to choose a tmux layout (1–5 or by
name) for each window that has 2 or more panes. Previously, layout was
always silently set to None.

Also update `render_config_created` to display the chosen layout in the
post-setup summary.

Closes: layout never being set during interactive setup
2026-03-01 05:07:00 -03:00
cinco 4ecdf96db8 📝 docs: update install URL to GitHub and fix default session description 2026-03-01 05:01:04 -03:00
cinco b05c188477 🐛 fix: consolidate publish-github into single shell block
continuous-integration/drone/push Build is failing
continuous-integration/drone/tag Build is passing
Multiple command blocks caused $RELEASE_ID to be lost between shells.
Using ${ARCH} with braces triggered Drone variable substitution before
the shell ran, resulting in an empty arch name. Fix: single | block
with all logic, iterate over full filenames (same pattern as publish),
and use ENVIRON["DRONE_TAG"] in awk to bypass Drone substitution.
2026-03-01 04:56:36 -03:00
cinco 75d66cd47c feat: publish releases to GitHub and update install source
- Self-update now queries the GitHub Releases API (parse_latest_tag extracted for testability)
- install.sh now fetches and downloads from GitHub Releases
- Drone CI release pipeline publishes to both Gitea and GitHub via GITHUB_TOKEN secret
- Bump version to 0.7.0
2026-03-01 04:50:52 -03:00
cinco 973042ce7d 🔖 chore: bump version to 0.6.0 and update CHANGELOG
continuous-integration/drone/tag Build is passing
2026-03-01 04:07:41 -03:00
cinco 0f27bedc94 feat: periodic update check on startup
On startup, if `update_check_interval_hours` have elapsed since the last
check, fetches the latest release tag from the Gitea API and prints a
notice when a newer version is available. Silent on network failure or
no update found.

- New `update_check` module with injected fetcher for full testability
- Cache at ~/.cache/tmuxido/update_check.json tracks timestamp + version
- `fetch_latest_tag` and `version_compare` promoted to `pub(crate)`
- 6 unit tests covering disabled, interval not elapsed, fetch triggered,
  equal versions, update available, and current-newer edge case
2026-03-01 04:07:38 -03:00
cinco da6311bc53 feat: add update_check_interval_hours config field
Adds `update_check_interval_hours: u64` (serde default 24, 0 = disabled)
to Config struct, enabling periodic update check control via config file.
2026-03-01 04:07:31 -03:00
cinco 2b1773375a 🐛 fix: add test for asset name format and bump to 0.5.2
continuous-integration/drone/tag Build is passing
Adds a unit test that asserts detect_arch returns names prefixed
with 'tmuxido-' and suffixed with '-linux', matching what CI uploads.
2026-03-01 03:43:10 -03:00
cinco 36aaa65945 📝 docs: add changelog entry for 0.5.1
continuous-integration/drone/tag Build is passing
2026-03-01 03:38:04 -03:00
cinco 10a38a1f85 🔧 ci: delete existing release before recreating on retag
When a tag is deleted and recreated, the CI tried to POST a new
release that already existed, getting 409 and leaving RELEASE_ID
null, which caused asset uploads to fail with 405. Now checks for
an existing release by tag and deletes it before creating a new one.
2026-03-01 03:34:27 -03:00
cinco 42bdc1d409 🐛 fix: correct asset name and bump version to 0.5.1
detect_arch was returning "x86_64-linux" but CI uploads assets as
"tmuxido-x86_64-linux", causing 404 on self-update. Also bumps
Cargo.toml to 0.5.1 which was missing from the hotfix tag.
2026-03-01 03:31:10 -03:00
cinco a592c99375 🐛 fix: target tmux windows by name instead of numeric index
Removes base-index detection which was unreliable and defaulted to 0
when tmux's actual base-index was 1, causing "index in use" and
"can't find window" errors on session creation.
2026-03-01 03:17:28 -03:00
cinco ff6050c718 test: add comprehensive tests for interactive configuration wizard
continuous-integration/drone/tag Build is failing
Add unit tests for the UI parsing functions and configuration logic
to restore test coverage after adding the interactive setup wizard.

- Add parse_max_depth_input, parse_cache_enabled_input, parse_cache_ttl_input
- Add parse_comma_separated_list helper function with tests
- Add tests for all parsing functions covering valid/invalid/empty inputs
- Add tests for color functions and UI render functions
- Add integration test for config with windows and panes
- Refactor config.rs to use shared parsing functions from ui module
2026-03-01 02:35:50 -03:00
cinco 15a11ef79c 🔧 chore: update Cargo.lock for version 0.5.0
Add missing Cargo.lock update with lipgloss and its dependencies.
2026-03-01 02:25:01 -03:00
cinco 6050cb70f3 🔖 chore: bump version to 0.5.0
Update version in Cargo.toml and add CHANGELOG entry for the new
interactive configuration wizard feature.
2026-03-01 02:23:52 -03:00
cinco 61f6a9fee3 feat: add interactive pane and command configuration to setup wizard
Expand the configuration wizard to allow users to define panes within
each window and specify startup commands for each pane. This provides
a complete tmux session setup during initial configuration.

- Add prompts for configuring panes in each window
- Add prompts for startup commands per pane
- Show full window/pane structure in summary
- Display pane commands in the final configuration review
2026-03-01 02:21:12 -03:00
cinco e0da58d114 feat: add interactive setup prompt with lipgloss styling and emojis
Add styled first-time setup UI using lipgloss with Tokyo Night theme
colors. The prompt now includes emojis and better visual feedback when
creating the initial configuration file.

- Add new ui module with styled render functions
- Prompt user for project paths interactively on first run
- Parse comma-separated paths with whitespace trimming
- Show styled success message with configured directories
- Add lipgloss dependency for terminal styling
2026-03-01 02:08:49 -03:00
cinco 437584aac7 test: add comprehensive tests for get_projects function
continuous-integration/drone/tag Build is failing
Add 6 new unit tests covering all execution paths:
- Cache disabled → full scan
- Force refresh → full scan
- No cache → initial scan
- Old cache format → upgrade
- Cache with changes → incremental update
- Cache loaded flow

Refactor get_projects to use dependency injection for testability,
allowing mocks for cache operations and filesystem scanning.

Bump version to 0.4.3
2026-03-01 01:46:22 -03:00
cinco 960724685c 📝 docs: update README with improved layout and Rust edition badge
- Move project title below badges for better visual hierarchy
- Update Rust edition badge from 2024 to 2026
- Maintain all existing badges and links
2026-03-01 01:25:24 -03:00
cinco 639bcdf643 📚 docs: center badges in README 2026-03-01 01:20:55 -03:00
cinco ddb4b70234 📚 docs: add avatar to author section
Use GitHub avatar image in the author section.
2026-03-01 01:19:45 -03:00
cinco 32155bc1d2 📚 docs: add author section to README
Add GitHub profile link and badge for @cinco.
2026-03-01 01:18:49 -03:00
cinco e4cc280f28 🐛 fix: bump version to 0.4.2 to fix self-update version mismatch
continuous-integration/drone/tag Build is failing
The Cargo.toml was still at 0.4.0 while the release was tagged as 0.4.1,
causing the --update command to always think there's a new version available.

Bumping to 0.4.2 ensures the binary version matches the release tag.
2026-03-01 01:13:21 -03:00
cinco 868540b92a force update
continuous-integration/drone/tag Build is failing
2026-03-01 01:04:15 -03:00
cinco 0af46bd6a5 🔧 ci: update release trigger to match tags without v prefix
continuous-integration/drone/tag Build is failing
2026-03-01 00:58:53 -03:00
cinco ba3f923781 feat: add self-update capability
Add `tmuxido --update` command to update binary from latest release.
- New `self_update` module with version comparison
- Atomic binary replacement with backup/rollback
- Fetches latest release from Gitea API
- Downloads correct binary for system architecture
2026-03-01 00:34:42 -03:00
cinco fcb7c7f6a6 🐛 fix(ci): read DRONE_TAG via awk ENVIRON to fix empty release body
continuous-integration/drone/tag Build is failing
Drone CI substitutes ${VAR} in commands before the shell runs.
Since TAG is a local shell variable (not a Drone var), ${TAG} was
replaced with an empty string, causing the awk pattern to match
nothing and the release body to be empty.

Fix: read DRONE_TAG directly inside awk via ENVIRON["DRONE_TAG"]
and strip the v-prefix with gsub — no intermediate shell variable needed.

Also translate CHANGELOG.md to English.
2026-03-01 00:19:10 -03:00
cinco 3c78a5afe3 🐛 fix(ci): corrigir pipeline release para tags v*
- Filtro de ref corrigido: [0-9]* → v* para bater em tags "v0.3.0"
- awk agora strip o prefixo 'v' de DRONE_TAG antes de buscar no CHANGELOG
- Adiciona entrada 0.3.0 no CHANGELOG.md
2026-03-01 00:01:29 -03:00
cinco 4dcac9a6aa feat: verificar dependências fzf e tmux ao iniciar
Adiciona módulo `deps` que, antes de qualquer operação, verifica se
fzf e tmux estão instalados no sistema. Caso faltem, detecta o
gerenciador de pacotes da distro (apt, pacman, dnf, yum, zypper,
emerge, xbps, apk), informa ao usuário e oferece instalar com o
comando adequado.

- `src/deps.rs`: Dep, PackageManager, BinaryChecker (trait injetável),
  check_missing(), detect_package_manager(), ensure_dependencies()
- `src/main.rs`: chama ensure_dependencies() antes do fluxo principal
- `tests/deps.rs`: 11 testes de integração com SystemBinaryChecker real
- `tests/docker/`: Dockerfile multi-stage + suite de 15 testes em
  container Ubuntu 24.04 simulando novo usuário (sem fzf/tmux)
- `.dockerignore`: exclui target/, .git/, .claude/ do contexto Docker
2026-02-28 23:58:09 -03:00
cincoandClaude Sonnet 4.6 32c40b7226 ci: migrate coverage badge to orphan badges branch
Replace Gitea packages (served as octet-stream) with a dedicated
orphan branch. Raw branch URL serves SVG with correct content-type.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 23:25:10 -03:00
cincoandClaude Sonnet 4.6 c1adc92c1c fix(ci): delete existing package before PUT to avoid 409
Gitea generic packages returns 409 if file already exists at same
version. Delete the version first, then re-upload.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 23:17:56 -03:00
cincoandClaude Sonnet 4.6 e6180b57c3 ci: migrate coverage badge to Gitea Packages
Replace commit-based badge update with a single PUT to the Gitea
generic packages API. Removes the badges/ directory from the repo
and eliminates CI commits on every push.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 23:16:03 -03:00
cinco 90e3b65820 ci: update coverage badge [CI SKIP] 2026-03-01 01:57:30 +00:00
cincoandClaude Sonnet 4.6 fc2f503886 ci: renomear branch master para main
Atualiza referências de master para main em .drone.yml e README.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 22:56:07 -03:00
cinco b29baee9c4 🎨 docs: adicionar logo ao README 2026-02-28 22:51:48 -03:00
cinco 6d842b83ba ci: update coverage badge [CI SKIP] 2026-03-01 01:33:39 +00:00
cinco b4877007f2 🐛 fix(ci): gerar badge SVG inline e remover tr com octais 2026-02-28 22:32:19 -03:00
cinco 29ff9535a7 🐛 fix(ci): unificar blocks e sanitizar JSON do Gitea antes do jq 2026-02-28 22:27:08 -03:00
cinco dec566320f ci: add coverage badge [CI SKIP] 2026-03-01 01:22:12 +00:00
cinco 6275c638d9 🔖 chore: atualizar Cargo.lock para versão 0.2.4 2026-02-28 22:20:45 -03:00
cinco 4d6af13134 🔧 chore: adicionar drone-ci-mcp e corrigir formato do hook PostToolUse 2026-02-28 22:20:42 -03:00
cinco b2a0ee5e08 🐛 fix(ci): usar base64 -w 0 e POST/PUT correto no upload do badge 2026-02-28 22:20:40 -03:00
cinco 2bc516ed6d ci: debug base64 and SHA GET response 2026-02-28 21:48:39 -03:00
cinco 7e70157097 ci: add debug output to coverage upload step 2026-02-28 21:44:08 -03:00
cinco ef13e884ba ci: use awk to parse coverage percentage 2026-02-28 21:38:28 -03:00
cinco b6e33c37ac ci: fix coverage parsing and JSON payload construction 2026-02-28 21:34:01 -03:00
cinco 20f516cffb ci: store coverage badge via repo contents API 2026-02-28 21:29:29 -03:00
cinco a5429c3543 chore: bump version to 0.2.4
continuous-integration/drone/tag Build is failing
2026-02-28 21:23:31 -03:00
cinco 8a7df892e8 ci: fix tarpaulin JSON field for coverage percentage 2026-02-28 21:19:56 -03:00
cinco f0949e08c5 ci: restrict release pipeline to version tags only 2026-02-28 21:14:14 -03:00
cinco d80857090e docs: update CI badge label in README.md
continuous-integration/drone/tag Build is failing
Changed the CI badge label from "CI" to "Build Status" for better clarity and consistency with common badge naming conventions.
2026-02-28 21:10:45 -03:00
cinco 19f36060a0 ci: use Gitea generic package registry for coverage badge 2026-02-28 21:08:39 -03:00
cinco 2dc12e37c9 chore: bump version to 0.2.2
continuous-integration/drone/tag Build is failing
2026-02-28 21:04:39 -03:00
cinco 280a180d3e ci: add coverage badge pipeline and README badges 2026-02-28 21:04:05 -03:00
cinco 5f281b1f9e docs: add CHANGELOG and use it as release description in CI 2026-02-28 20:26:29 -03:00
cinco 9150f93f6a ci: add test pipeline and bump version to 0.2.1
continuous-integration/drone/tag Build is failing
Adds a Drone CI pipeline that runs on push and pull_request events,
executing cargo fmt --check, cargo clippy, and cargo test in sequence.
2026-02-28 20:23:09 -03:00
cincoandClaude Sonnet 4.6 a076cf2543 chore: bump version to 0.2.0
continuous-integration/drone/tag Build is failing
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 20:17:05 -03:00
cincoandClaude Sonnet 4.6 9198c481c0 test: add integration tests for scan, session config and cache lifecycle
tests/scan.rs: 3 tests exercising scan_from_root via the public API —
finds git repos, skips hidden directories, and respects max_depth.
Note: tempfile::tempdir() generates hidden paths (.tmpXXXXXX) on this
system, so each test creates a visible scan_root/ subdirectory to avoid
filter_entry silently skipping the walk root.

tests/session_config.rs: 2 tests for SessionConfig::load_from_project —
loads a .tmuxido.toml written into a temp dir and returns None when the
file is absent.

tests/cache_lifecycle.rs: round-trip test that saves a ProjectCache and
reloads it, verifying the projects list survives serialisation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 20:16:09 -03:00
cincoandClaude Sonnet 4.6 bfdc1e2093 test: add unit tests for cache, session and config modules
cache.rs: make minimal_roots pub(crate); add 8 tests covering the
minimal_roots helper (empty input, single root, nested vs sibling dirs)
and validate_and_update (stale project removal, no-change short-circuit,
mtime-triggered rescan, legacy empty dir_mtimes).

session.rs: make session_name pub(crate); add 5 tests covering session
name sanitisation (dots→underscores, spaces→dashes, fallback for root
path) and TOML parsing for Window and SessionConfig with layout.

config.rs: add 3 tests covering serde defaults when optional fields are
absent, full config parsing and invalid TOML rejection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 20:15:42 -03:00
cincoandClaude Sonnet 4.6 d35acdeb55 refactor: extract business logic into lib.rs
Move scan_from_root, scan_all_roots, get_projects, show_cache_status
and launch_tmux_session from main.rs into a new src/lib.rs, making
them pub so they are testable independently of the binary entrypoint.

main.rs is now a thin entrypoint that imports from tmuxido:: and keeps
only select_project_with_fzf (interactive subprocess, not unit-testable).

Add tempfile = "3" to [dev-dependencies] in preparation for tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 20:15:27 -03:00
cincoandClaude Sonnet 4.6 30d6c3d1c5 chore: install Claude scaffold
Add CLAUDE.md with project-specific rules (test structure, naming
conventions, MCP tools reference). Add .mcp.json for rust-mcp and
crates-io MCP servers. Add rust-toolchain.toml pinning stable with
rustfmt and clippy. Add .claude/settings.json with PostToolUse hook
that runs cargo test automatically after every file edit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 20:15:08 -03:00
cinco 562febaafe Remove personal path references from defaults and examples
continuous-integration/drone/tag Build is failing
Replace machine-specific paths with generic examples.
2026-02-28 19:22:06 -03:00
cinco 71da4149b8 Initial release of tmuxido
continuous-integration/drone/tag Build is failing
Rust-based tmux project launcher with fzf selection, incremental
mtime-based cache, per-project .tmuxido.toml session config, and
Drone CI pipeline for automated binary releases.
2026-02-28 19:06:43 -03:00