Merge PR #2950: feat(coding-agent): add copy affordance to completed /btw answers (@wolfiesch)
Adds 'c copy' to the completed /btw panel footer (alongside b branch / Esc dismiss), copying the sanitized visible answer to the clipboard. The copy shortcut is guarded by canCopyBtw + main-editor focus + empty editor.
This commit is contained in:
@@ -16,6 +16,7 @@ export class BtwPanelComponent extends Container {
|
||||
#state: BtwPanelState = "running";
|
||||
#answer = "";
|
||||
#errorMessage: string | undefined;
|
||||
#visibleAnswer = "";
|
||||
#closed = false;
|
||||
|
||||
constructor(options: BtwPanelComponentOptions) {
|
||||
@@ -28,12 +29,14 @@ export class BtwPanelComponent extends Container {
|
||||
appendText(delta: string): void {
|
||||
if (!delta || this.#closed) return;
|
||||
this.#answer += delta;
|
||||
this.#visibleAnswer = replaceTabs(this.#answer).trim();
|
||||
this.#rebuild();
|
||||
}
|
||||
|
||||
setAnswer(text: string): void {
|
||||
if (this.#closed) return;
|
||||
this.#answer = text;
|
||||
this.#visibleAnswer = replaceTabs(text).trim();
|
||||
this.#rebuild();
|
||||
}
|
||||
|
||||
@@ -59,7 +62,16 @@ export class BtwPanelComponent extends Container {
|
||||
}
|
||||
|
||||
isBranchable(): boolean {
|
||||
return this.#state === "complete" && this.#answer.trim().length > 0;
|
||||
return this.isCopyable();
|
||||
}
|
||||
|
||||
isCopyable(): boolean {
|
||||
return this.#state === "complete" && this.#visibleAnswer.length > 0;
|
||||
}
|
||||
|
||||
getCopyText(): string | undefined {
|
||||
if (!this.isCopyable()) return undefined;
|
||||
return this.#visibleAnswer;
|
||||
}
|
||||
|
||||
close(): void {
|
||||
@@ -89,7 +101,7 @@ export class BtwPanelComponent extends Container {
|
||||
case "running":
|
||||
return theme.fg("muted", "Esc cancel /btw");
|
||||
case "complete":
|
||||
return theme.fg("muted", this.isBranchable() ? "b branch · Esc dismiss" : "Esc dismiss");
|
||||
return theme.fg("muted", this.isCopyable() ? "c copy · b branch to chat · Esc dismiss" : "Esc dismiss");
|
||||
case "aborted":
|
||||
return theme.fg("warning", `${theme.status.warning} Cancelled · Esc dismiss`);
|
||||
case "error":
|
||||
@@ -101,7 +113,7 @@ export class BtwPanelComponent extends Container {
|
||||
if (this.#state === "error") {
|
||||
return new Text(theme.fg("error", replaceTabs(this.#errorMessage ?? "Unknown error")), 1, 0);
|
||||
}
|
||||
const text = replaceTabs(this.#answer).trim();
|
||||
const text = this.#visibleAnswer;
|
||||
if (!text) {
|
||||
const waiting =
|
||||
this.#state === "running" ? `${theme.status.pending} Waiting for response…` : "No text returned.";
|
||||
|
||||
Reference in New Issue
Block a user