From 6038b938f03c4100d99ea30a42df5a6735faac9e Mon Sep 17 00:00:00 2001 From: sskys18 Date: Fri, 11 Sep 2026 16:00:35 +0900 Subject: [PATCH] feat(interactive): put resume command on own line The resume command printed on quit exists to be copied, but the dimmed "To resume this session:" label shared its line, so a double-click or triple-click selection dragged the label in and the command had to be trimmed by hand before pasting. Write the label and the command as two lines so line-wise selection copies exactly the runnable command. When the hint appears is unchanged: still the non-signal shutdown path only, still gated on formatResumeCommand() returning a command. --- .../src/modes/interactive/changes.md | 18 ++++++++++++++++++ .../src/modes/interactive/interactive-mode.ts | 4 +++- ...0-signal-shutdown-extension-cleanup.test.ts | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/packages/coding-agent/src/modes/interactive/changes.md b/packages/coding-agent/src/modes/interactive/changes.md index 842794ca4e..8fe91c18c3 100644 --- a/packages/coding-agent/src/modes/interactive/changes.md +++ b/packages/coding-agent/src/modes/interactive/changes.md @@ -1,3 +1,21 @@ +## 2026-09-11 - The resume hint prints the command on its own line + +### What changed + +- `packages/coding-agent/src/modes/interactive/interactive-mode.ts`: the interactive quit path writes the resume hint as two lines - the dimmed `To resume this session:` label, then the resume command on the following line - instead of one line separated by a space. The hint is still emitted only for the non-signal shutdown path and is still gated on `formatResumeCommand` returning a command, so nothing changes about when it appears. + +### Why + +- The command is meant to be copied. On one line the dimmed label shares the line with the command, so a double-click or triple-click selection picks up the label prefix and the user has to trim it before pasting. Putting the command alone on the second line makes line-wise selection copy exactly the runnable command. + +### Why an extension could not handle it + +- The hint is written with `process.stdout.write` from `InteractiveMode.shutdown()` after the TUI has already been torn down and the runtime host disposed. No extension hook runs at that point, and extensions must not write to stdout around the terminal owner. + +### Expected merge conflict zones + +- LOW: the single `process.stdout.write` resume-hint call in `InteractiveMode.shutdown()` and the matching expectation in `packages/coding-agent/test/suite/regressions/5080-signal-shutdown-extension-cleanup.test.ts`. + ## 2026-09-10 - Safe account labels in footer and English help (senpi#1495) ### What changed diff --git a/packages/coding-agent/src/modes/interactive/interactive-mode.ts b/packages/coding-agent/src/modes/interactive/interactive-mode.ts index bc716a8183..3aeb1f155d 100644 --- a/packages/coding-agent/src/modes/interactive/interactive-mode.ts +++ b/packages/coding-agent/src/modes/interactive/interactive-mode.ts @@ -6106,7 +6106,9 @@ export class InteractiveMode { const resumeCommand = formatResumeCommand(this.sessionManager); if (resumeCommand) { - process.stdout.write(`${chalk.dim("To resume this session:")} ${resumeCommand}\n`); + // The command goes on its own line so a double-click or triple-click + // selects the command alone, without the dimmed label prefix. + process.stdout.write(`${chalk.dim("To resume this session:")}\n${resumeCommand}\n`); } process.exit(0); diff --git a/packages/coding-agent/test/suite/regressions/5080-signal-shutdown-extension-cleanup.test.ts b/packages/coding-agent/test/suite/regressions/5080-signal-shutdown-extension-cleanup.test.ts index 9ccf77cdd6..f3b8aa552d 100644 --- a/packages/coding-agent/test/suite/regressions/5080-signal-shutdown-extension-cleanup.test.ts +++ b/packages/coding-agent/test/suite/regressions/5080-signal-shutdown-extension-cleanup.test.ts @@ -147,7 +147,7 @@ describe("InteractiveMode.shutdown ordering (#5080)", () => { expect(order).toEqual(["drainInput", "stop", "dispose"]); expect(stdoutWrite).toHaveBeenCalledWith( - `${chalk.dim("To resume this session:")} ${APP_NAME} --session test-session\n`, + `${chalk.dim("To resume this session:")}\n${APP_NAME} --session test-session\n`, ); });