clonetty 0.0.1

Spawn a new Alacritty window cloning an existing terminal's working directory and its nested-shell environment stack, so Ctrl-D peels back one shell layer at a time.
//! `clonetty shell-init <shell>` — emit a shell snippet that records each
//! interactive shell's *live* environment to `$XDG_RUNTIME_DIR/clonetty/<pid>`.
//!
//! That file is the witness `proc::leaf_witness_env` reads when the focused
//! terminal's innermost shell is idle (no child process to read the post-`exec`
//! env from), so `--focused`/`--pid` can still reconstruct an idle nix-shell's
//! innermost layer — the case external `/proc` capture cannot otherwise recover.
//!
//! The point of a subcommand (vs. documenting a multiline rc snippet) is that the
//! logic lives *here*, tool-owned and versioned; the user's config keeps one line:
//!
//! ```text
//! eval "$(clonetty shell-init bash)"                          # ~/.bashrc
//! programs.bash.initExtra = ''eval "$(clonetty shell-init bash)"'';  # home-manager
//! ```
//!
//! Only bash is supported: `nix-shell` always runs bash for its layers and
//! clonetty's reconstruction assumes bash, so the innermost shell a nix stack
//! needs recorded is bash regardless of the user's login shell.

use clap::ValueEnum;

/// Shell dialect to emit an init snippet for.
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum Shell {
    Bash,
}

/// The init snippet for `shell`, ready to `eval`.
pub fn snippet(shell: Shell) -> &'static str {
    match shell {
        Shell::Bash => BASH,
    }
}

const BASH: &str = r##"# clonetty shell-init (bash): record this shell's live environment each prompt so
# `clonetty --focused`/`--pid` can reconstruct an idle nix-shell's innermost layer.
# Passive — writes a file per prompt; nothing is triggered by keystrokes. The file
# lives under $XDG_RUNTIME_DIR (0700 tmpfs) and is written 0600 (it may hold secrets).
__clonetty_dir="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/clonetty"
__clonetty_rec() {
  [ -d "$__clonetty_dir" ] || { command mkdir -p "$__clonetty_dir" && command chmod 700 "$__clonetty_dir"; }
  # `cat` is a child, so /proc/self/environ is THIS shell's live, post-nix-shell
  # env, in the NUL-separated format clonetty parses. `$$` stays the shell PID even
  # inside the ( ) subshell, so the file is keyed by the PID clonetty descends to.
  ( umask 077; command cat /proc/self/environ > "$__clonetty_dir/$$" ) 2>/dev/null
}
# Idempotent: safe to eval more than once (bash re-sources rc per nix-shell layer).
case "$PROMPT_COMMAND" in
  *__clonetty_rec*) ;;
  *) PROMPT_COMMAND="__clonetty_rec${PROMPT_COMMAND:+; $PROMPT_COMMAND}" ;;
esac
# Best-effort cleanup on exit, without clobbering an existing EXIT trap (files are
# in tmpfs and PID-keyed, so a lingering one is harmless if we skip this).
[ -n "$(trap -p EXIT)" ] || trap 'command rm -f "$__clonetty_dir/$$"' EXIT
"##;