DEV Community

vast cow
vast cow

Posted on

Preventing ` ` from Entering Codex Prompts

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/cloud
  • https://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();
})();
Enter fullscreen mode Exit fullscreen mode

Top comments (0)