fix: /clear now clears terminal screen and resets context left indicator (#425)
## What does this PR do?
* Implements the full `/clear` command in **codex‑cli**:
* Resets chat history **and** wipes the terminal screen.
* Shows a single system message: `Context cleared`.
* Adds comprehensive unit tests for the new behaviour.
## Why is it needed?
* Fixes user‑reported bugs:
* **#395**
* **#405**
## How is it implemented?
* **Code** – Adds `process.stdout.write('\x1b[3J\x1b[H\x1b[2J')` in
`terminal.tsx`. Removed reference to `prev` in `
setItems((prev) => [
...prev,
` in `terminal-chat-new-input.tsx` & `terminal-chat-input.tsx`.
## CI / QA
All commands pass locally:
```bash
pnpm test # green
pnpm run lint # green
pnpm run typecheck # zero TS errors
```
## Results
https://github.com/user-attachments/assets/11dcf05c-e054-495a-8ecb-ac6ef21a9da4
---------
Co-authored-by: Thibault Sottiaux <tibo@openai.com>
This commit is contained in:
@@ -191,6 +191,12 @@ export default function TerminalChatInput({
|
||||
case "/bug":
|
||||
onSubmit(cmd);
|
||||
break;
|
||||
case "/clear":
|
||||
onSubmit(cmd);
|
||||
break;
|
||||
case "/clearhistory":
|
||||
onSubmit(cmd);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -396,19 +402,29 @@ export default function TerminalChatInput({
|
||||
setInput("");
|
||||
setSessionId("");
|
||||
setLastResponseId("");
|
||||
// Clear the terminal screen (including scrollback) before resetting context
|
||||
clearTerminal();
|
||||
|
||||
// Emit a system notice in the chat; no raw console writes so Ink keeps control.
|
||||
|
||||
// Emit a system message to confirm the clear action. We *append*
|
||||
// it so Ink's <Static> treats it as new output and actually renders it.
|
||||
setItems((prev) => {
|
||||
const filteredOldItems = prev.filter((item) => {
|
||||
// Remove any token‑heavy entries (user/assistant turns and function calls)
|
||||
if (
|
||||
item.type === "message" &&
|
||||
(item.role === "user" || item.role === "assistant")
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (
|
||||
item.type === "function_call" ||
|
||||
item.type === "function_call_output"
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true; // keep developer/system and other meta entries
|
||||
});
|
||||
|
||||
return [
|
||||
|
||||
@@ -263,17 +263,16 @@ export default function TerminalChatInput({
|
||||
setInput("");
|
||||
setSessionId("");
|
||||
setLastResponseId("");
|
||||
// Clear the terminal screen (including scrollback) before resetting context
|
||||
clearTerminal();
|
||||
|
||||
// Emit a system message to confirm the clear action. We *append*
|
||||
// it so Ink's <Static> treats it as new output and actually renders it.
|
||||
setItems((prev) => [
|
||||
...prev,
|
||||
// Print a clear confirmation and reset conversation items.
|
||||
setItems([
|
||||
{
|
||||
id: `clear-${Date.now()}`,
|
||||
type: "message",
|
||||
role: "system",
|
||||
content: [{ type: "input_text", text: "Context cleared" }],
|
||||
content: [{ type: "input_text", text: "Terminal cleared" }],
|
||||
},
|
||||
]);
|
||||
|
||||
|
||||
@@ -50,6 +50,8 @@ export function clearTerminal(): void {
|
||||
if (inkRenderer) {
|
||||
inkRenderer.clear();
|
||||
}
|
||||
// Also clear scrollback and primary buffer to ensure a truly blank slate
|
||||
process.stdout.write("\x1b[3J\x1b[H\x1b[2J");
|
||||
}
|
||||
|
||||
export function onExit(): void {
|
||||
|
||||
Reference in New Issue
Block a user