Adds a StepRunUpdater step that starts app-dono-updater after the app
container comes up: a poll loop (docker pull, compare image IDs,
recreate on change) baked into the official docker:cli image via
`sh -c`, reusing the same docker run argv as the initial container
start so the two can't drift.
Not built on Watchtower: containrrr/watchtower was archived upstream
in Dec 2025 with no maintained successor recommended for production
use, so this avoids taking on that dependency.
Introduce tui.Version (defaults to "dev"), stamped at build time via a
VERSION_LDFLAG in the Makefile (-X .../internal/tui.Version=$(VERSION))
across all build targets. main.go handles "--version"/"-v" before
launching the TUI, and the version is shown next to the title in the
header. Docs updated (README + CLAUDE).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the hardcoded dummy fallback for Certificates.DirPath in loadConfig
so the field shows its placeholder instead of a pre-filled value, matching
the DB URL and central server URL fields. An existing config.toml still
seeds it on re-run.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the hardcoded dummy fallbacks for Database.URL and
Application.CentralServerURL in loadConfig so these inputs display their
placeholder instead of a pre-filled value. An existing config.toml still
seeds them on re-run via the decode, so real defaults are preserved.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
bubbles/v2 textinput truncates the placeholder to its first rune when the
input width is 0 (the default): it sizes the placeholder buffer to
Width()+1 and early-returns after the first character. Set a non-zero
width on every text input (defaultInputWidth) and resize inputs
responsively to the terminal on WindowSizeMsg via FormStep.SetWidth, so
placeholders render in full and inputs fill the available width.
Adds a regression test asserting the placeholder renders past its first
rune.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Implements three UX improvements (TODO #1–#3):
- Back navigation: Esc returns to the previous input step. The Model keeps
a history stack of input steps (advance/goBack helpers); action/wait
steps are excluded via isInputStep so back never re-enters a
side-effecting step. Form values are preserved.
- Review step (StepReview): shows all collected config for confirmation
before any file is written; Enter installs, Esc edits.
- Retry vs. fix: transient failures (image pull, container run) offer
"r: tentar novamente" instead of quitting; validation failures route
back to the relevant form to correct the value.
Adds nav_test.go for the history/navigation logic and updates
README/CLAUDE/docs (incl. docs/TODO.md tracking the remaining ideas).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cover the deploy-critical pure logic:
- GenerateConfigTOML: round-trip decode of values + a guard asserting the
config port is always containerAppPort (host port must not leak)
- GenerateWireguardConfig: MTU emitted/commented, PROTO default UDP
- WriteConfigFile / WriteWireguardConfigFile: numeric validation rejects
bad input and does not write a file
- FormStep.Values(): text/password/select resolution and select default
fallback
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The container always listens on 8080 internally while the user-provided
port is only the host-side mapping. Make this explicit without changing
behavior or the generated config:
- add a named containerAppPort constant and use it in both the docker -p
mapping and the config.toml generation (was a bare 8080 literal in two
places)
- document why config.toml hardcodes the port, so it isn't "fixed" back
to the form value
- relabel the form field to "Porta (host)"
The generated config.toml is byte-identical (port = 8080).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
DownloadImageCmd and DownloadWireguardImageCmd were identical except for
the image URL. Collapse them into one DownloadImageCmd that takes the
image as a parameter, passing imageName/wireguardImageName at the call
sites.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The network creation error format string had a trailing "output" with no
verb, silently dropping the captured docker output. Add the missing %s.
Also replace the hardcoded "app-dono_app" literal with the networkName
constant in RunAppClienteContainer.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>