Skip to content

/relaunch command - part c - #5593

Closed
M-Maciej wants to merge 5 commits into
Hmbown:mainfrom
M-Maciej:pr/relaunch-command
Closed

/relaunch command - part c#5593
M-Maciej wants to merge 5 commits into
Hmbown:mainfrom
M-Maciej:pr/relaunch-command

Conversation

@M-Maciej

@M-Maciej M-Maciej commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Closes #5532

Summary

/update installs a new binary and then tells the user to restart the app.
This adds the missing self-relaunch so a session switches to the current
binary in one step:

  • /relaunch behaves like /exit for persistence (save, restore terminal,
    telemetry flush, session_end emission) and then self-execs
    resume <session-id> — the CLI's positional resume form, which the
    standalone TUI binary also accepts. Atomic exec on Unix: no orphan
    process for a supervisor to reap.
  • argv[0] fallback: when current_exe resolves to a deleted or renamed
    path — the updater's rename-replacement case — /relaunch falls back to
    argv[0] instead of failing.
  • If the replacement fails, the session is already saved; the error names the
    exact resume command to continue with.
  • Windows keeps the documented manual-restart behavior (no exec); the
    portable argv-construction tests still exercise the resume-form builder on
    every platform.

Merge-order note

Merge order: after the cadence fix (a). No dependency on (b); the control
socket's relaunch verb (d) dispatches /relaunch through the generic
command seam, so it has no compile dependency on this branch — until this
merges the verb reports command_error, after it the verb is functional.

Windows build hygiene

The Windows CI gate denies dead code under -D warnings. relaunch_argv is
only called from the unix-only self-exec path, so the plain Windows lib build
flagged it. It is gated with #[cfg(any(unix, test))] — the item itself is
omitted from the plain Windows lib build instead of being allowed — so the
dead-code budget is untouched.

Testing

<!-- Exact gate commands (including the clippy allow list) are in
CONTRIBUTING.md → "Pre-push verification". -->

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets --all-features --locked (warning-free under the CI allow list)
  • cargo test --workspace --all-features --locked

Results: clippy clean on stable 1.98.0 under the CONTRIBUTING.md allow
list; full suite 13,376 passed / 0 failed (same one pre-existing
environmental skip as the outbox PR). Focused relaunch suite: 12/12
(argv construction incl. Windows-style path preservation,
deleted/renamed-current_exe fallback, resume-form args).

Checklist

  • Updated docs or comments as needed — Unreleased changelog entry;
    /update's module doc now explains why it does not chain /relaunch
  • Added or updated tests where relevant
  • Verified TUI behavior manually if UI changes — /relaunch exercised
    live on running sessions during development ( verified before split, not after )
  • Harvested/co-authored credit uses a GitHub numeric noreply address —
    every commit is authored under
    130112810+M-Maciej@users.noreply.github.com
  • Every commit carries a Signed-off-by (DCO)
  • No dead-code-budget change

…the same session

/relaunch reuses the /exit teardown path (engine shutdown, persistence
flush, terminal restore) and then replaces the process image with the
current executable run as `resume <session-id>`, so the resumed session
owns the same terminal with no orphan process.

- commands/groups/core/relaunch.rs: command; refuses unsaved sessions and
  in-flight runtime work, records the session id in App.pending_relaunch,
  and quits through the ordinary exit path.
- relaunch.rs: argv builder (<exe> resume <id>), the process-wide handoff,
  and the Unix CommandExt::exec that runs after telemetry close-out;
  Windows consumes the handoff as a no-op and the quit-time resume hint is
  the instruction.
- event_loop.rs: hands the pending id over after the persistence flush and
  suppresses the redundant resume hint; lib.rs execs after finish_telemetry
  so the old session's telemetry is recorded first.
- localization: CmdRelaunchDescription in all 15 complete packs plus the
  command contract bridge; update.rs no longer claims there is no
  self-exec pattern.

Signed-off-by: M-Maciej <130112810+M-Maciej@users.noreply.github.com>
current_executable() trusted std::env::current_exe() whenever it returned
Ok, but on Linux a binary replaced by rename resolves through
/proc/self/exe to a path with a literal " (deleted)" suffix that no
longer exists. exec_relaunch then exec'd the dead path and /relaunch
failed with "could not relaunch (... (deleted)): No such file or
directory".

Resolve the image path, then keep it only when it is non-empty, exists,
and its file name is not marked " (deleted)"; otherwise fall back to
argv[0] (the PATH-resolvable invocation name), preserving the existing
error-path fallback. relaunch_argv's "<exe> resume <session-id>" contract
is unchanged.

Signed-off-by: M-Maciej <130112810+M-Maciej@users.noreply.github.com>
The Windows CI gate (cargo test --no-run) denies dead code under
-D warnings. relaunch_argv is only called from the unix-only self-exec
path, so the plain Windows lib build flagged it. Gate the item itself
with #[cfg(any(unix, test))] — the portable argv-construction tests keep
exercising it on every platform — instead of adding a dead-code lint
allowance, so the dead-code budget is untouched.

Signed-off-by: M-Maciej <130112810+M-Maciej@users.noreply.github.com>
Regenerated crates/tui/CHANGELOG.md via scripts/sync-changelog.sh.

Signed-off-by: M-Maciej <130112810+M-Maciej@users.noreply.github.com>
@M-Maciej
M-Maciej requested a review from Hmbown as a code owner August 24, 2026 00:46
@github-actions

Copy link
Copy Markdown
Contributor

Thanks @M-Maciej for taking the time to contribute.

This repository is observing a maintainer-managed PR intake gate in dry-run mode, so this pull request is staying open. This note helps maintainers prepare the allowlist before any enforcement is considered.

Please read CONTRIBUTING.md for the expected contribution shape. A maintainer can grant recurring PR access by commenting /lgtm on a pull request.

@Hmbown

Hmbown commented Aug 25, 2026

Copy link
Copy Markdown
Owner

Reviewed from the 0.9.12 integration lane: same disposition as #5592 — implements #5532 (unlabeled for v0.9.12 in #5573), standalone off main, so not folded mid-cycle; @Hmbown's call whether 0.9.12 includes /relaunch. Nothing blocking from the description; will take + full-matrix verify on request.

@Hmbown Hmbown mentioned this pull request Aug 25, 2026
9 tasks
Resolves the only conflict: main's `## [Unreleased]` grew a `### Added`
list while this branch appended its /relaunch bullet at the same insertion
point. Kept both — main's list, with this PR's bullet appended — and
regenerated crates/tui/CHANGELOG.md via scripts/sync-changelog.sh.

No source files conflicted; every .rs change auto-merged.
@Hmbown Hmbown mentioned this pull request Aug 25, 2026
9 tasks
@Hmbown

Hmbown commented Aug 25, 2026

Copy link
Copy Markdown
Owner

Hi @M-Maciej — maintainer housekeeping on this PR, no code of yours was touched.

What I found. Two separate things were keeping this un-judgeable:

  1. The merge conflict was trivial. I merged origin/main in and the only conflict was CHANGELOG.md + its generated slice crates/tui/CHANGELOG.md: main's ## [Unreleased] / ### Added list grew while your bullet landed at the same insertion point. Every source file — including crates/tui/src/tui/ui/event_loop.rs, crates/tui/src/lib.rs, crates/tui/src/tui/ui.rs — auto-merged cleanly. I resolved it as "keep both" (main's list with your bullet appended) and regenerated the slice with scripts/sync-changelog.sh. cargo check --workspace --all-targets passes on the result.

  2. CI had never actually run on this PR. Not once. The repo is set to approval_policy: first_time_contributors for fork PRs, so your pull_request workflows were withheld pending a maintainer click — and nobody was watching that queue. The only two green checks you were seeing (gate, GitGuardian) are the two paths exempt from that gate. That is our process failure, not anything you did. Pushing the merge commit as a maintainer released the gate, so the full matrix is running on this PR right now for the first time.

I also prepended Closes #5532 to the PR description — the required link check wants an explicit closing keyword, and your commits already pointed at that issue.

Heads-up on what CI will report. main is currently red on two required checks that every open PR inherits, so ignore these if you see them:

  • Version driftmain is missing a changelog receipt for feat(tui): make Fleet roster editing discoverable #5604.
  • Test (windows-latest) — two Windows verbatim-path tests (tools::shell::tests::readonly_operands_are_workspace_bounded_and_symlink_aware, tools::subagent::tests::read_only_inspection_roles_execute_pwd_and_absolute_git_log).

Both are fixed by #5610, which is waiting to land. Anything else that goes red is worth your attention.

Sorry this sat for so long without a real signal. Same treatment applied to #5592 and #5594.

@Hmbown

Hmbown commented Aug 25, 2026

Copy link
Copy Markdown
Owner

Merged onto the v0.9.12 integration branch in 397b9cb; re-verified in-tree: /relaunch wiring in tui/event_loop.rs, tui/app.rs, and the control-socket relaunch verb in tui/control_socket.rs, with the portable argv-construction test suite. Closing as landed — thanks @M-Maciej!

@Hmbown Hmbown closed this Aug 25, 2026
Hmbown pushed a commit that referenced this pull request Aug 25, 2026
`/relaunch` saves like `/exit` then self-execs `resume <session-id>`
(Unix). argv[0] fallback covers a deleted/renamed current_exe after
`/update`. Authored by @M-Maciej; taken into the 0.9.12 integration
branch with its authorship preserved.

Adapted rather than clobbering integration locale keys: added
CmdRelaunchDescription next to the existing /loop keys, left the
FEAT-018 utility ContextualCommand surface intact, and only updated
the `/update` module doc to point at the new relaunch handoff.

Evidence:
  rustfmt --edition 2024
  cargo test -p codewhale-tui --lib --locked --offline --
    relaunch message_id_list_english_pack_stay_in_exact_sync
    -> 13 passed

Co-Authored-By: M-Maciej <130112810+M-Maciej@users.noreply.github.com>
Co-Authored-By: Grok 4.6 <noreply@anthropic.com>
Hmbown pushed a commit that referenced this pull request Aug 25, 2026
/#5594

Replay tonight's M-Maciej PRs onto the integration commits that landed
while the take was in flight (FEAT-019 /loop handler, image attach,
computer-use fallbacks). No further adaptation.

Co-Authored-By: Grok 4.6 <noreply@anthropic.com>
Hmbown pushed a commit that referenced this pull request Aug 25, 2026
/#5594

Pick up the MiniMax fact-guard commit that landed after the previous
replay so the take branch stays a descendant of integration.

Co-Authored-By: Grok 4.6 <noreply@anthropic.com>
Hmbown pushed a commit that referenced this pull request Aug 25, 2026
Take:
- #5592 lifecycle outbox (`[lifecycle_outbox]`, opt-in JSONL + webhook)
- #5593 /relaunch (save like /exit, Unix self-exec resume)
- #5594 per-session control socket (`[control_socket]`, Unix JSON-RPC)

Authorship of the original commits is preserved. Adapted onto the
#5586 extracted modules (doctor_cli, exec_agent, cli_args, config/merge)
and existing /loop locale keys rather than clobbering them. Did not
merge origin/main.

Co-Authored-By: M-Maciej <130112810+M-Maciej@users.noreply.github.com>
Co-Authored-By: Grok 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 01M0W25Y7BH0J5342G4WRNQZJT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: /relaunch — switch a running session to the current binary

2 participants