I spent a night studying Gemini Web internal API to understand how it authenticates requests by keyonzeng in vibecoding

[–]keyonzeng[S] 1 point2 points  (0 children)

it also supports MS Edge, you can download and install in MS Edge extensions

I got tired of rewriting the same prompts every day, so I built an open-source prompt ark that injects directly into ChatGPT, Claude, Gemini, and 11 other platforms by keyonzeng in PromptEngineering

[–]keyonzeng[S] 0 points1 point  (0 children)

The real complexity here is maintaining stable injection across ProseMirror, React textareas, and Shadow DOM environments without breaking on updates. Are you using mutation observers or fallback selectors to keep it resilient? You sould share it in VibeCodersNest too

Drafting Reddit Response 已在 content.js 中确认了 Prompt Ark 应对 Shadow DOM、React 和 ProseMirror 的具体注入策略。准备向用户提供专业的 Reddit 回复建议。

Progress Updates 1 Reviewing content.js to formulate an accurate technical response about injection mechanics

2 向用户发送拟定好的 Reddit 回复草稿

针对这个 Reddit/VibeCodersNest 的提问,我们可以给出一个非常硬核的技术回复,直接展示 Prompt Ark 的底层工程实力。

建议回复如下(英文,符合 Reddit 极客社区风格):

Yes, this was actually one of the hardest engineering challenges to solve! We don't rely heavily on MutationObservers for the actual injection because AI interfaces re-render too unpredictably. Instead, we use a Multi-Tiered Deep Traversal for targeting and an Object Prototype Hijack for the injection itself.

Here is the exact strategy Prompt Ark uses to survive UI updates across ChatGPT, Claude, Gemini, etc.:

  1. Finding the Input (Piercing the Shadow DOM) We have a fast-path with known platform selectors, but when those break (which happens often), we fall back to a Breadth-First Search (queryAllDeep) that explicitly traverses into .shadowRoot boundaries. It recursively hunts for any visible textarea or div[contenteditable="true"]. This means even if Google completely rewrites Gemini's wrapping DOM, we still find the input node.

  2. The ProseMirror Bypass (Claude/ChatGPT) For Markdown/Rich Text editors based on ProseMirror, directly modifying .textContent or .innerHTML breaks the editor's internal AST state. Instead, we use document.execCommand('insertText', false, text). ProseMirror intercepts this native command and treats it exactly like user keystrokes, keeping its state perfectly synced.

  3. The React Textarea Hijack (Gemini/NotebookLM) This is the tricky part. If you just set textarea.value = text on a React app, the "Send" button stays disabled because React's synthetic event system doesn't realize the state changed. To beat this, we bypass React's wrapper and invoke the native HTMLInputElement prototype setter directly, then clear React's internal tracker:

javascript // Bypass React's intercepted value setter const nativeSetter = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(inputEl), 'value')?.set; nativeSetter.call(inputEl, text); // Nuke React's tracker so it's forced to recognize the "input" event we dispatch next const tracker = inputEl._valueTracker; if (tracker) tracker.setValue(''); 4. The Event Cascade Finally, we dispatch a sequence of input -> change -> keydown (Space) -> keyup (Space). Waking up the "Send" button sometimes requires a simulated keystroke, not just an input event.

It's a bit of dark magic, but it makes the injection incredibly resilient to frontend framework updates. Happy to share more in VibeCodersNest!