When using Codex, unwanted line breaks can sometimes appear in the prompt field. This can make prompts harder to read, edit, and send in a clean format. This script is designed to prevent that problem in ChatGPT Codex Cloud.
What This Script Does
This UserScript watches the prompt input area in Codex Cloud and automatically removes newline characters that appear in the text.
More specifically, it monitors the #prompt-textarea element and cleans up line breaks found in its direct paragraph elements. As a result, prompts stay in a single-line format instead of being split across multiple lines unexpectedly.
The script also tries to preserve the caret position after cleaning the text. This helps keep typing smooth and reduces disruption while editing.
Why Use It
The main purpose of this script is to make prompt entry more stable and easier to manage.
It can be useful when you want to:
- avoid accidental line breaks in prompts
- keep prompts in a clean, single-line format
- reduce editing issues caused by unexpected newlines
From a user perspective, it works as a simple helper that automatically removes unwanted line breaks while you type.
How to Use It
Add It as a UserScript
This code is meant to be used as a UserScript. In practice, that means installing a browser extension that supports UserScripts and then adding this script to it.
Once it is installed, the script runs automatically on the matching Codex Cloud pages.
Supported Pages
The script is set to run on these URLs:
https://chatgpt.com/codex/cloudhttps://chatgpt.com/codex/cloud/*
When you open one of these pages, the script starts working automatically.
How It Works in Practice
After the page loads, the script waits for the prompt editor to appear. Once the editor is available, it starts listening for input changes.
Each time you type, the script checks whether newline characters have appeared in the prompt. If they have, it removes them and then restores the caret as naturally as possible.
Things to Keep in Mind
It Is Best for Single-Line Prompts
Because this script removes line breaks, it is best suited for workflows where prompts are meant to stay on one line. It is not a good fit if you intentionally want to write multi-line prompts.
It Helps Keep Input Clean
This script is especially useful for people who want a simpler, cleaner prompt field and do not want formatting problems caused by unexpected newlines.
Conclusion
This UserScript is a simple way to prevent unwanted newlines in Codex Cloud prompts. It watches the input field, removes line breaks automatically, and keeps the caret position as stable as possible.
You do not need to understand the internal implementation in detail to use it. In practical terms, it is a lightweight tool for keeping Codex prompts clean and easy to edit.
// ==UserScript==
// @name ChatGPT Codex Cloud - Remove Newlines in Prompt
// @namespace https://chatgpt.com/
// @version 1.1.0
// @description Remove CR/LF from direct <p> children on paste event.
// @match https://chatgpt.com/codex/cloud
// @match https://chatgpt.com/codex/cloud/*
// @grant none
// ==/UserScript==
(() => {
"use strict";
let observerA = null; // waits for #prompt-textarea to appear
let observerB = null; // waits for #prompt-textarea to be removed
let currentEditor = null;
let pasteHandler = null;
function log(...args) {
console.log("[prompt-textarea-debug]", ...args);
}
function sanitizeParagraphs() {
const editor = document.querySelector("#prompt-textarea");
if (!editor) {
log("sanitizeParagraphs(): editor not found");
return;
}
const paragraphs = document.querySelectorAll("#prompt-textarea > p");
log("sanitizeParagraphs()", {
paragraphCount: paragraphs.length,
});
paragraphs.forEach((p, index) => {
const before = p.innerHTML;
const after = before.replaceAll("\r", "").replaceAll("\n", "");
if (before !== after) {
log(`paragraph ${index} changed`, { before, after });
p.innerHTML = after;
} else {
log(`paragraph ${index} unchanged`);
}
});
}
function attachToEditor(editor) {
log("attachToEditor()", editor);
currentEditor = editor;
pasteHandler = (e) => {
log("paste event fired");
// paste後にDOMが更新されてから処理
setTimeout(() => {
sanitizeParagraphs();
}, 0);
};
editor.addEventListener("paste", pasteHandler);
log("paste listener attached");
if (observerA) {
observerA.disconnect();
observerA = null;
}
observerB = new MutationObserver(() => {
const stillThere = document.querySelector("#prompt-textarea");
if (!stillThere) {
log("#prompt-textarea removed");
if (currentEditor && pasteHandler) {
currentEditor.removeEventListener("paste", pasteHandler);
log("paste listener removed");
}
currentEditor = null;
pasteHandler = null;
observerB.disconnect();
observerB = null;
waitForEditor();
}
});
observerB.observe(document.documentElement, {
childList: true,
subtree: true,
});
log("observerB started");
}
function waitForEditor() {
log("waitForEditor()");
const editor = document.querySelector("#prompt-textarea");
if (editor) {
attachToEditor(editor);
return;
}
observerA = new MutationObserver(() => {
const found = document.querySelector("#prompt-textarea");
if (found) {
log("#prompt-textarea appeared");
attachToEditor(found);
}
});
observerA.observe(document.documentElement, {
childList: true,
subtree: true,
});
log("observerA started");
}
log("userscript initialized", { href: location.href });
waitForEditor();
})();
Top comments (0)