Project
Caret
A prompt palette that opens where the cursor already is, on three chat sites that each handle text differently.
problem
I was retyping the same instructions into Claude, Gemini, and ChatGPT several times a day. None of them had a way to save a prompt, and a prompt kept in one could not reach the other two.
The gap is small, and it opens every time a chat does.
trigger
Typing the trigger symbol at a word boundary opens a palette anchored above the cursor. Fuzzy search filters the library and the keyboard inserts the prompt without leaving the input.
The symbol defaults to > and is configurable
per site, because Claude claims / for its
own command menu, and a symbol free on one chat site can collide with a
shortcut on another.
adapters
The palette is the same everywhere. What happens when you pick a prompt is not: each site handles its input differently.
Three sites, two editor models. Claude and ChatGPT render their inputs
through ProseMirror, Gemini uses a plain contenteditable.
Writing into either directly bypasses the host's state handling. So
the insertion first offers the host a cancelable beforeinput event, and only if the host lets it through does it insert through the
browser's own editing command, which fires the events the host's framework
listens for. The adapter is picked by the input's element type, not by site,
so one contenteditable adapter serves all
three.
That adapter walks the DOM to find an absolute cursor position across fragmented text nodes, so the prompt replaces exactly the trigger and the typed query, not the text around them. Prompts stay in the browser, apart from the optional sync that reads them from GitHub.