Compacts the design discussion into a reference: the workflow model
(pure Remote-SSH by default, opportunistic local clones for
self-contained python+uv projects only), how to run the script, the
home-machine prerequisite (Tailscale SSH), and the gotchas hit while
building it (PATH issues after su, stale sudo group membership, the
token-paste-into-shell bug, the spurious-space host alias bug, and
the tailnet-wide MagicDNS requirement) so they don't need re-debugging.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Tailscale's raw HostName field is whatever the OS reports (e.g.
"Pixel 9" with a literal space for an Android device), which breaks
when written unquoted into an SSH config Host line - ssh_config treats
space-separated words as multiple patterns, not one literal name.
DNSName is already sanitized (hyphens, no spaces) for exactly this
purpose, so derive the alias from its first label instead.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The summary just said "all OK" and left you to figure out what to do.
Now it lists the tailnet hosts this run actually found and spells out
the exact VS Code Remote-SSH steps to reach one, instead of assuming
you remember from the design conversation.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
readline's bracketed-paste handling didn't reliably prevent the
paste-leaking-into-shell issue in practice (likely tmux/terminal
paste passthrough not cooperating). Reading raw stdin until EOF
(Ctrl-D) sidesteps the problem entirely - it doesn't depend on any
terminal capability, it just keeps consuming bytes including embedded
newlines until you explicitly signal you're done. Token is visible
while pasting now (no -s); acceptable since this only matters on a
personal machine where terminal history exposure isn't a concern.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Plain `read -rsp` has no paste awareness: a token with a trailing
newline (common from some "copy token" UI buttons) terminates the
read early, and whatever came after in the paste is left in the
terminal's input buffer - which the shell then executes as a command
once the script exits. `read -e` uses GNU readline, which honors
bracketed paste and inserts a multi-line paste as literal text
instead of treating embedded newlines as Enter.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Print length + first/last 4 chars of the captured token instead of
the full secret, and strip stray whitespace (a trailing newline in a
copied token can silently truncate what read captures mid-paste).
Helps distinguish a truncated paste from an actually-wrong token
without exposing the credential in scrollback.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Persist the last-entered values to ~/.config/travel-bootstrap/config
and offer them as the prompt default, so a re-run only needs Enter
instead of retyping the same values every time.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
curl -f collapsed auth failures, wrong paths, and real network errors
into the same vague "could not reach" message. Now reports the actual
HTTP status and response body, and prompts print exactly where to
generate a Forgejo access token before asking for it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Idempotent setup for a disposable Debian travel laptop: base packages
(vim, tmux, mosh, tailscale, uv, VS Code + Remote-SSH, firefox-esr),
tailscale join, SSH config regenerated from live tailnet peers (wildcard
+ per-peer entries), fresh SSH key registered to Forgejo via API, and
Firefox hardened to forced-incognito with no history and forced uBlock
Origin. No repos cloned by default - workflow starts as pure Remote-SSH
to the home machine, local clones added opportunistically per project.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>