GitHub Docs

Inline AI completion. In VibeCoder, it appears on its own as you pause typing, or immediately on ⌥\. In VS Code, it is still explicit-trigger only — press ⌥\ at the cursor. Either way: read the grey suggestion, press Tab to accept or Esc to dismiss.

Ghost text is VibeCody’s short-form AI completion. It renders inline at the cursor and accepts with Tab — the ergonomics people expect from a modern editor. VibeCoder answers both a debounced pause in typing and an explicit ask (reverted 2026-09-11, below); VS Code remains explicit-trigger only: nothing is requested there, and nothing appears, while you type.

For a larger change you want to review hunk-by-hunk, use Diffcomplete (⌘.) instead.


Quick start

  1. Open a file in VibeCoder, or any file in VS Code with the VibeCLI extension installed.
  2. Put the cursor where the code should go.
  3. Press ⌥\ (Alt-Backslash on every platform). Or run AI: Inline Completion at Cursor from the command palette.
  4. A grey suggestion appears inline.
  5. Tab accepts it. Esc dismisses it. Typing anything else dismisses it too.

If nothing appears, the model decided nothing belonged at that cursor — that is a normal answer, not an error.


Why it looks like other tools, and why VibeCoder and VS Code now differ

VibeCody removed its original keystroke-driven ghost-text implementation (SupercompleteEngine) in 5a7eef7c: that one ran on a debounce timer after every keystroke, kept a rolling buffer of your recent edits, and used them to predict the next one. It was flagged HIGH severity in an internal patent audit and removed with “no kill-switch, no opt-in path” — a deliberate call, not an oversight. What replaced it was explicit-trigger only, specifically to avoid that flagged pattern.

On 2026-09-11, VibeCoder’s copy of this was reverted back to also answering typing, at the repo owner’s explicit request, made after being told this reinstates a keystroke-driven pattern from that same flagged category — reusing the existing FIM completion backend (vibe_ai::ghost) rather than resurrecting SupercompleteEngine’s edit-history/next-edit-prediction machinery, which stays removed. VS Code’s implementation was not changed and remains explicit-trigger only. The two hosts intentionally diverge now:

  VS Code (explicit-trigger) VibeCoder (since 2026-09-11)
Trigger ⌥\ only typing (debounced) or ⌥\
Sees your edit history no — nothing retained between requests no — nothing retained between requests
Auto-retrieval of other files no no
Requests while you type zero one per debounced pause (AUTOMATIC_DEBOUNCE_MS, currently 350ms), cancelled by the next keystroke
Accept Tab Tab

VibeCoder’s gate is in vibecoder/src/lib/ghostText.ts; VS Code’s is unchanged in vscode-extension/src/ghost-text.ts. Both still key off the named trigger-kind member, not a literal — see the box below, which still applies to VS Code and to VibeCoder’s explicit path.

For contributors: the enum is inverted between the two hosts. Monaco has InlineCompletionTriggerKind = { Automatic: 0, Explicit: 1 }; VS Code has { Invoke: 0, Automatic: 1 }. The same names carry opposite numbers, so a literal comparison copied from one host to the other gates on exactly the wrong half. Always compare against the named member.

The patent-audit document this all refers to (notes/PATENT_AUDIT_INLINE.md) is gitignored and was not consulted when VibeCoder’s gate was reverted — if it draws a narrower line than “any keystroke-driven ghost text,” that revert should be checked against it.


What gets sent

Per request — one ⌥\ press, or one debounced pause in typing on VibeCoder — carrying:

  • Prefix — up to 160 lines before the cursor.
  • Suffix — up to 60 lines after the cursor.
  • File path and language, for the prompt header.
  • Project memory — your author-written VIBECLI.md / AGENTS.md / CLAUDE.md, the same audit-restricted source diffcomplete uses. Never auto-extracted state.

Nothing else. No edit history, no telemetry about what you accepted or rejected, no embedding search — the request shape did not change in the 2026-09-11 revert, only how often it’s sent.

The response is capped at 12 lines (vibe_ai::ghost::MAX_COMPLETION_LINES). When the cap clips a suggestion the editor says so — accept what you have and trigger again to continue.


Provider and model

Ghost text is provider-agnostic and never defaults to a single vendor.

  • VibeCoder uses the provider selected in the toolbar, with that provider’s registry default model. On an explicit ⌥\, no provider selected means a toast telling you to pick one. On an automatic (typing) trigger, the same case is silent rather than a toast on every debounced pause — either way, nothing is called.
  • VS Code uses the vibecli.provider and vibecli.model settings. The daemon only honours the override when both are set — leave vibecli.model empty and the daemon uses whichever provider and model it was started with.

Architecture

VS Code:   [ ⌥\ press ] ─────────────────────────────────────┐
VibeCoder: [ ⌥\ press ]  or  [ pause after typing ] ──────────┤
                                                               ▼
                                    editor.action.inlineSuggest.trigger
                                    (⌥\ path only — typing calls the
                                     provider directly)              │
                                                               ▼
                            inline-completion provider
                            VS Code:   trigger kind Automatic? ──► return nothing
                            VibeCoder: trigger kind Automatic? ──► debounce, then continue
                                                               │
                                                               ▼
                            VibeCoder: ghost_complete (Tauri command)
                            VS Code:   POST /v1/ghost/complete (daemon, bearer auth)
                                                               │
                                                               ▼
                                        vibe_ai::ghost::generate()
                                                               │
                                        ├─► system prompt demanding bare insertion text
                                        ├─► prefix / cursor / suffix as labeled regions
                                        ├─► project memory as a separate system message
                                                               ▼
                            sanitize_completion() — unwraps stray code fences, caps at 12 lines,
                                                     preserves leading indentation

Leading whitespace is deliberately preserved: at a cursor sitting at column 0 of an indented block, the indentation is the first thing that belongs there.


What ghost text is NOT

  • Not FIM. The model receives prefix and suffix as discrete labeled regions, not a single fill-in-middle template.
  • Not next-edit prediction. Each request is independent; nothing about your previous edits or previous suggestions is carried forward — SupercompleteEngine’s rolling edit-history buffer stays removed even in VibeCoder’s reverted, keystroke-driven path.
  • Not auto-retrieval. No embedding search, no call-graph walk, no symbol-server probe.
  • On VS Code, still not keystroke-driven — that host was not touched by the 2026-09-11 revert and remains explicit-trigger only.