Skip to content

Add Google Docs support - #382

Merged
bartekplus merged 10 commits into
masterfrom
feature/google-docs
Sep 15, 2026
Merged

bartekplus merged 10 commits into
masterfrom
feature/google-docs

Conversation

@bartekplus

@bartekplus bartekplus commented Sep 15, 2026

Copy link
Copy Markdown
Owner

Summary

Adds local autocomplete for Google Docs through the editor's annotated-canvas API, reusing the existing predictor, grammar rules, themes, snippets and local learning. No new permissions, hosts, dependencies or network calls.

  • A MAIN-world bootstrap sets _docs_annotate_canvas_by_ext to FluentTyper's own extension ID at document_start, then reads the logical text and selection via _docs_annotate_getAnnotatedText.
  • The isolated-world GoogleDocsAdapter talks to the bridge over JSON CustomEvents and applies suggestions as single-use, model-verified transactions: select the minimal range, dispatch one synthetic plain-text paste, verify the resulting text. Unverified writes are never retried.
  • The generic SuggestionManager stays active for titles and comments; only the hidden text-event iframe is excluded.
  • Activates on any docs.google.com/document/.../edit URL, subject to the existing per-site enable/disable.

Verified live in Chrome against real Google Docs

Suggestions render at the caret, Tab acceptance is verified as applied, native undo/redo work, predictions continue normally after an accept, and the inline ghost matches the document text. Fixes made from that testing:

  • Docs blurs the editable inside the text-event iframe on setSelection; the bridge refocuses it before pasting.
  • Docs strips trailing ASCII spaces from a paste but converts NBSP to a space, so edge spaces are sent as NBSP.
  • An unverified write no longer locks the adapter for the session; it releases on the next user interaction.
  • With a collaborator caret visible, the menu is anchored to the local (black) caret instead of the fallback corner.
  • When a space already follows the completed word, the caret lands after it.
  • The inline ghost takes font family, size, zoom, bold, italic, underline and text color from the Docs toolbar (the caret element carries the 13px UI font), uses the caret height as line height, and is nudged to the canvas baseline.

Tests

  • bun run check, full unit suite, bun run test:e2e:docs (25 Chromium MAIN/isolated-world fixtures), bun run test:e2e smoke, and Chrome/Edge/Firefox builds all pass; CI is green.
  • New: tests/GoogleDocsModel.test.ts, tests/GoogleDocsTransaction.test.ts, tests/e2e/google-docs.e2e.test.ts plus fixture; the Docs fixture suite runs in the Chrome CI job. The fixture editor mirrors the live quirks above (blur on setSelection, paste space normalization, collaborator caret).
  • Operator-assisted live smoke script: bun run test:e2e:docs:live -- --help.

Reviewer notes

  • Not yet verified live: Edge and Firefox, native IMEs, collaboration races, tables/footnotes. See docs/google-docs-integration.md for the full matrix and limits.
  • Strikethrough and super/subscript are not mirrored onto the ghost; Docs exposes them only in the Format menu.
  • Known limitation documented there: the keyboard bridge exposes the current single-use token in a DOM attribute, so a page script could forge an acceptance of a visible suggestion; it can already edit the document through the same API, so the only extension-side effect is a spurious local learning record.

🤖 Generated with Claude Code

bartekplus and others added 5 commits September 15, 2026 08:53
Adds a Google Docs adapter that reads the logical document model through the
MAIN-world annotated-text API and applies suggestions as verified single-use
edit transactions. Reuses the existing predictor, grammar, theme and local
learning services. Includes model/transaction unit tests, a Chromium
MAIN/isolated-world fixture suite, an operator-assisted live check script and
docs. Activation is opt-in via the fluentTyperDocs=1 URL parameter pending
live validation.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Verified in Chrome against real Google Docs. Docs' setSelection blurs the
editable inside the text-event iframe, so the bridge now refocuses it before
pasting and accepts a blurred editable while the frame is focused. Docs strips
edge ASCII spaces from a plain-text paste but converts NBSP to a space, so
trailing spaces are sent as NBSP. An unverified write now stops blocking after
the next trusted user interaction instead of locking the adapter for the
session. The fixture editor mirrors the paste normalization.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Drops the fluentTyperDocs=1 opt-in parameter after live verification in
Chrome; per-site enable/disable still governs docs.google.com.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Docs renders collaborator carets with colored borders and the local caret
with a black one. Prefer the black caret before treating multiple visible
carets as ambiguous, which previously pushed the menu to the fallback corner.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
When a space already follows the completed word, the predictor appends
none; the edit now consumes that space so the caret lands after it, matching
the insert-space-after-autocomplete setting.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@bartekplus bartekplus self-assigned this Sep 15, 2026
bartekplus and others added 4 commits September 15, 2026 10:20
The fixture editor now blurs its editable on setSelection like live Docs, a
colored collaborator caret must not displace the local caret anchor, and an
unverified write is released after the next user interaction.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…t element

The caret element carries Docs' 13px UI font, so the ghost rendered small and
raised. A hidden style host now mirrors the toolbar font family, point size
and zoom, with the caret height as line height and a caret-derived fallback.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nline ghost

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@bartekplus
bartekplus merged commit 77973b2 into master Sep 15, 2026
8 checks passed
@bartekplus
bartekplus deleted the feature/google-docs branch September 15, 2026 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant