Bucky brings the Midnight Commander dual-panel experience to your terminal, connecting Amazon S3, Google Cloud Storage, SFTP, and your local filesystem through a single, keyboard-driven interface. Built with Go and the Charm Bracelet stack.
App walkthrough GIF
Tab--profileSpace to check rows, then bulk transfer, move, or delete/auto, dark, and light modesgo install github.com/mrpbennett/bucky/cmd/bucky@latest
git clone https://github.com/mrpbennett/bucky.git
cd bucky
go build -o bucky ./cmd/bucky
./bucky # launch with profile picker
./bucky --profile prod_s3 # connect directly to a profile
./bucky -p staging_sftp # short flag
Bucky reads a single TOML file at ~/.config/bucky/config.toml. If this file is missing or invalid, Bucky exits with an error.
theme = "auto" # auto | dark | light
sort_by = "name" # name | size | date
sort_order = "asc" # asc | desc
show_hidden = false
local_start_at_cwd = true # true: launch directory; false: home directory
[sync]
dry_run_default = true
compare_mode = "mtime_size" # mtime_size | size_only | exact_timestamps
delete_default = false
no_overwrite_default = false
concurrency = 4
[profile.prod_s3]
type = "s3"
bucket = "my-prod-bucket" # use "*" or omit to list all accessible buckets
region = "us-east-1" # defaults to us-east-1
prefix = "backups/"
Optional fields: endpoint (for S3-compatible APIs), access_key + secret_key, aws_profile, aws_credentials_file, aws_config_file.
Credential resolution order:
access_key + secret_key (static)aws_profile (shared config)Bucky also auto-discovers non-default entries from ~/.aws/credentials and surfaces them as profiles if not already defined.
[profile.staging_sftp]
type = "sftp"
host = "sftp.example.com"
port = 22 # defaults to 22
username = "deploy"
private_key_path = "~/.ssh/id_ed25519"
known_hosts_path = "~/.ssh/known_hosts" # defaults to ~/.ssh/known_hosts
prefix = "/var/data/"
Auth options: password, private_key_path (with optional private_key_passphrase). Both can be combined.
Set insecure_ignore_host_key = true to skip host key verification (not recommended for production).
[profile.analytics_gcs]
type = "gcs"
bucket = "analytics-bucket"
project_id = "my-project"
gcp_credentials_file = "~/.config/gcloud/app-credentials.json"
prefix = "exports/"
Auth: Set gcp_credentials_file for explicit credentials, or rely on Application Default Credentials (gcp_use_adc = true, the default). Optional endpoint override.
t)Space (or just position the cursor).t to arm the transfer.t again from either panel to execute.Starting from the left (remote) panel downloads; starting from the right (local) panel uploads.
File transfer workflow GIF
m)m.m again to execute.Moves are destructive and only operate within the remote backend.
s)s to open the sync setup overlay.Enter to generate a preview plan showing exactly what will change.Enter to execute (or e to return to setup).
Sync workflow GIF
p)Press p on any file to open a syntax-highlighted preview overlay. CSV and TSV files get rainbow column coloring. Preview reads up to 64 KiB of content.
File preview GIF
R)Press R to open a Vim-style rename modal with full normal, insert, and visual mode support.
Rename modal GIF
| Key | Action |
|---|---|
? | Toggle help overlay |
i | Toggle metadata pane |
Tab | Switch between left/right panels |
1 | Focus left panel |
2 | Focus right panel |
3 | Focus log panel |
[ | Toggle left pane |
] | Toggle right pane |
P | Return to profile picker |
Esc | Cancel active transfer/move/sync mode |
| Key | Action |
|---|---|
Up / k | Move cursor up |
Down / j | Move cursor down |
Ctrl+d | Half-page down |
Ctrl+u | Half-page up |
Enter / l | Open directory |
- / h | Go to parent directory |
gg | Jump to first row |
G | Jump to last row |
q / Ctrl+c | Quit app |
| Key | Action |
|---|---|
Space | Toggle selection on current row and advance cursor |
a | Create a new directory |
t | Transfer (two-phase: arm then confirm) |
m | Move on remote backend (two-phase: arm then confirm) |
d | Delete with confirmation modal |
r | Refresh current directory |
R | Rename (opens Vim-style modal) |
p | Preview file |
s | Open sync setup |
| Key | Action |
|---|---|
o | Cycle sort field: name, size, date |
O | Toggle sort direction |
. | Toggle hidden files |
/ | Open live search |
Enter | Accept search |
Esc | Cancel search |
S is reserved for a future repeat-sync shortcut.
Setup overlay:
| Key | Action |
|---|---|
Tab | Toggle sync direction |
c | Cycle compare mode |
d / n / r | Toggle delete / no-overwrite / dry-run |
i / x | Edit include / exclude patterns |
Enter | Generate preview plan |
Esc | Cancel sync |
Preview overlay:
| Key | Action |
|---|---|
Enter | Execute sync plan |
e | Return to setup |
Esc | Cancel |
Summary overlay:
| Key | Action |
|---|---|
Enter / Esc | Close summary |
Core:
| Key | Action |
|---|---|
Enter | Confirm rename |
Esc (NORMAL) | Cancel rename |
Esc (INSERT/VISUAL) | Return to NORMAL mode |
NORMAL mode:
| Key | Action |
|---|---|
h / l | Move left / right |
0 / $ | Start / end of filename |
w / e / b | Word motions |
i / a / I / A | Enter INSERT mode |
v | Enter VISUAL mode |
x | Delete character under cursor |
d + motion | Delete by motion |
c + motion | Change by motion |
dd | Clear whole filename |
VISUAL mode:
| Key | Action |
|---|---|
h / l / w / e / b / 0 / $ | Adjust selection |
d | Delete selection |
c | Change selection, enter INSERT |
v | Exit VISUAL mode |
| Key | Action |
|---|---|
p / Esc / Backspace | Close preview |
Up / k | Scroll up |
Down / j | Scroll down |
gg | Top of preview |
G | Bottom of preview |
q / Ctrl+c | Quit app |
Preview reads up to 64 KiB. CSV/TSV files use rainbow column coloring.
Delete confirmation:
| Key | Action |
|---|---|
Tab / Left / Right / h / l | Switch button |
Enter | Confirm |
Esc | Cancel |
Transfer progress:
| Key | Action |
|---|---|
Esc | Cancel in-flight transfer |
Help overlay:
| Key | Action |
|---|---|
? / Esc | Close help |
Profile picker:
| Key | Action |
|---|---|
j / Down | Next profile |
k / Up | Previous profile |
Enter | Connect |
q / Esc | Quit |
Log panel (focus with 3):
| Key | Action |
|---|---|
j / Down | Scroll newer |
k / Up | Scroll older |
go build -o bucky ./cmd/bucky # build binary
go run ./cmd/bucky # run without building
go install ./cmd/bucky # install to $GOPATH/bin
go test ./... # run all tests
go vet ./... # static analysis
gofmt -w . # format code
cmd/bucky/main.go CLI entrypoint
internal/
backend/ Storage backend interface and implementations
s3.go, sftp.go, gcs.go, local.go, multibucket.go
config/ Config loading and profile parsing
transfer/ Transfer primitives and progress messages
ui/
app.go Root Bubble Tea model
browser/ Dual-panel file browser component
transfer/ Transfer queue and progress display
status/ Status bar with keybinding hints
assets/ Logo and static assets
docs/ Design documents and implementation plan
The Backend interface (internal/backend/) is the core abstraction. S3, GCS, SFTP, and Local backends all implement the same interface so the UI layer never deals with storage-specific logic.
The UI layer (internal/ui/) uses Bubble Tea's Elm architecture (Model / Update / View). The root app.go model orchestrates panels, overlays, and the transfer queue.
The Transfer engine (internal/transfer/) runs outside the Bubble Tea event loop via goroutines, pushing progress updates back through program.Send(). Supports concurrent transfers with configurable limits.
Config (internal/config/) parses TOML profiles from ~/.config/bucky/config.toml using Viper.
MIT
44 commits
Go
100.0%
Bucky brings the Midnight Commander dual-panel experience to your terminal, connecting Amazon S3, Google Cloud Storage, SFTP, and your local filesystem through a single, keyboard-driven interface. Built with Go and the Charm Bracelet stack.
App walkthrough GIF
Tab--profileSpace to check rows, then bulk transfer, move, or delete/auto, dark, and light modesgo install github.com/mrpbennett/bucky/cmd/bucky@latest
git clone https://github.com/mrpbennett/bucky.git
cd bucky
go build -o bucky ./cmd/bucky
./bucky # launch with profile picker
./bucky --profile prod_s3 # connect directly to a profile
./bucky -p staging_sftp # short flag
Bucky reads a single TOML file at ~/.config/bucky/config.toml. If this file is missing or invalid, Bucky exits with an error.
theme = "auto" # auto | dark | light
sort_by = "name" # name | size | date
sort_order = "asc" # asc | desc
show_hidden = false
local_start_at_cwd = true # true: launch directory; false: home directory
[sync]
dry_run_default = true
compare_mode = "mtime_size" # mtime_size | size_only | exact_timestamps
delete_default = false
no_overwrite_default = false
concurrency = 4
[profile.prod_s3]
type = "s3"
bucket = "my-prod-bucket" # use "*" or omit to list all accessible buckets
region = "us-east-1" # defaults to us-east-1
prefix = "backups/"
Optional fields: endpoint (for S3-compatible APIs), access_key + secret_key, aws_profile, aws_credentials_file, aws_config_file.
Credential resolution order:
access_key + secret_key (static)aws_profile (shared config)Bucky also auto-discovers non-default entries from ~/.aws/credentials and surfaces them as profiles if not already defined.
[profile.staging_sftp]
type = "sftp"
host = "sftp.example.com"
port = 22 # defaults to 22
username = "deploy"
private_key_path = "~/.ssh/id_ed25519"
known_hosts_path = "~/.ssh/known_hosts" # defaults to ~/.ssh/known_hosts
prefix = "/var/data/"
Auth options: password, private_key_path (with optional private_key_passphrase). Both can be combined.
Set insecure_ignore_host_key = true to skip host key verification (not recommended for production).
[profile.analytics_gcs]
type = "gcs"
bucket = "analytics-bucket"
project_id = "my-project"
gcp_credentials_file = "~/.config/gcloud/app-credentials.json"
prefix = "exports/"
Auth: Set gcp_credentials_file for explicit credentials, or rely on Application Default Credentials (gcp_use_adc = true, the default). Optional endpoint override.
t)Space (or just position the cursor).t to arm the transfer.t again from either panel to execute.Starting from the left (remote) panel downloads; starting from the right (local) panel uploads.
File transfer workflow GIF
m)m.m again to execute.Moves are destructive and only operate within the remote backend.
s)s to open the sync setup overlay.Enter to generate a preview plan showing exactly what will change.Enter to execute (or e to return to setup).
Sync workflow GIF
p)Press p on any file to open a syntax-highlighted preview overlay. CSV and TSV files get rainbow column coloring. Preview reads up to 64 KiB of content.
File preview GIF
R)Press R to open a Vim-style rename modal with full normal, insert, and visual mode support.
Rename modal GIF
| Key | Action |
|---|---|
? | Toggle help overlay |
i | Toggle metadata pane |
Tab | Switch between left/right panels |
1 | Focus left panel |
2 | Focus right panel |
3 | Focus log panel |
[ | Toggle left pane |
] | Toggle right pane |
P | Return to profile picker |
Esc | Cancel active transfer/move/sync mode |
| Key | Action |
|---|---|
Up / k | Move cursor up |
Down / j | Move cursor down |
Ctrl+d | Half-page down |
Ctrl+u | Half-page up |
Enter / l | Open directory |
- / h | Go to parent directory |
gg | Jump to first row |
G | Jump to last row |
q / Ctrl+c | Quit app |
| Key | Action |
|---|---|
Space | Toggle selection on current row and advance cursor |
a | Create a new directory |
t | Transfer (two-phase: arm then confirm) |
m | Move on remote backend (two-phase: arm then confirm) |
d | Delete with confirmation modal |
r | Refresh current directory |
R | Rename (opens Vim-style modal) |
p | Preview file |
s | Open sync setup |
| Key | Action |
|---|---|
o | Cycle sort field: name, size, date |
O | Toggle sort direction |
. | Toggle hidden files |
/ | Open live search |
Enter | Accept search |
Esc | Cancel search |
S is reserved for a future repeat-sync shortcut.
Setup overlay:
| Key | Action |
|---|---|
Tab | Toggle sync direction |
c | Cycle compare mode |
d / n / r | Toggle delete / no-overwrite / dry-run |
i / x | Edit include / exclude patterns |
Enter | Generate preview plan |
Esc | Cancel sync |
Preview overlay:
| Key | Action |
|---|---|
Enter | Execute sync plan |
e | Return to setup |
Esc | Cancel |
Summary overlay:
| Key | Action |
|---|---|
Enter / Esc | Close summary |
Core:
| Key | Action |
|---|---|
Enter | Confirm rename |
Esc (NORMAL) | Cancel rename |
Esc (INSERT/VISUAL) | Return to NORMAL mode |
NORMAL mode:
| Key | Action |
|---|---|
h / l | Move left / right |
0 / $ | Start / end of filename |
w / e / b | Word motions |
i / a / I / A | Enter INSERT mode |
v | Enter VISUAL mode |
x | Delete character under cursor |
d + motion | Delete by motion |
c + motion | Change by motion |
dd | Clear whole filename |
VISUAL mode:
| Key | Action |
|---|---|
h / l / w / e / b / 0 / $ | Adjust selection |
d | Delete selection |
c | Change selection, enter INSERT |
v | Exit VISUAL mode |
| Key | Action |
|---|---|
p / Esc / Backspace | Close preview |
Up / k | Scroll up |
Down / j | Scroll down |
gg | Top of preview |
G | Bottom of preview |
q / Ctrl+c | Quit app |
Preview reads up to 64 KiB. CSV/TSV files use rainbow column coloring.
Delete confirmation:
| Key | Action |
|---|---|
Tab / Left / Right / h / l | Switch button |
Enter | Confirm |
Esc | Cancel |
Transfer progress:
| Key | Action |
|---|---|
Esc | Cancel in-flight transfer |
Help overlay:
| Key | Action |
|---|---|
? / Esc | Close help |
Profile picker:
| Key | Action |
|---|---|
j / Down | Next profile |
k / Up | Previous profile |
Enter | Connect |
q / Esc | Quit |
Log panel (focus with 3):
| Key | Action |
|---|---|
j / Down | Scroll newer |
k / Up | Scroll older |
go build -o bucky ./cmd/bucky # build binary
go run ./cmd/bucky # run without building
go install ./cmd/bucky # install to $GOPATH/bin
go test ./... # run all tests
go vet ./... # static analysis
gofmt -w . # format code
cmd/bucky/main.go CLI entrypoint
internal/
backend/ Storage backend interface and implementations
s3.go, sftp.go, gcs.go, local.go, multibucket.go
config/ Config loading and profile parsing
transfer/ Transfer primitives and progress messages
ui/
app.go Root Bubble Tea model
browser/ Dual-panel file browser component
transfer/ Transfer queue and progress display
status/ Status bar with keybinding hints
assets/ Logo and static assets
docs/ Design documents and implementation plan
The Backend interface (internal/backend/) is the core abstraction. S3, GCS, SFTP, and Local backends all implement the same interface so the UI layer never deals with storage-specific logic.
The UI layer (internal/ui/) uses Bubble Tea's Elm architecture (Model / Update / View). The root app.go model orchestrates panels, overlays, and the transfer queue.
The Transfer engine (internal/transfer/) runs outside the Bubble Tea event loop via goroutines, pushing progress updates back through program.Send(). Supports concurrent transfers with configurable limits.
Config (internal/config/) parses TOML profiles from ~/.config/bucky/config.toml using Viper.
MIT
44 commits
Go
100.0%