A native VS Code extension for Fill-In-the-Middle (FIM) LLM code completion, shown as inline ghost text (press Tab to accept).
Unlike the Python llmsp language server
(which ghostCS shares its context-engineering design with), ghostCS does the
whole pipeline —
context building → LLM API call → ghost text — inside the extension host.
There is no language server and no Python process: the extension talks to
your backend over HTTP directly. That removes the client↔server↔subprocess seam
that made the LSP path unstable in VS Code.
keystroke ─► debounce + cancel-previous ─► context assembler ─► FIM backend ─► post-process ─► ghost text
│
┌───────────────────────────────┼───────────────────────────────┐
▼ ▼ ▼
L1 budgeted prefix/suffix L2 cross-file snippets L3 single/multi/empty
(token-aware windowing) (recently-edited ring mode (heuristic)
buffer + open files,
ranked by Jaccard)
The context engineering is ported 1:1 from the Python server's
context/
package — budgeted single-file windowing,
cross-file retrieval packed best-nearest-cursor, dedupe against the current
file, and a structural single/multi-line decision. Plus a prefix-keyed LRU
cache, per-document cancel-on-keystroke, and local-model warm-up.
- VS Code 1.91+ (for
InlineCompletionItemProvider). - A FIM backend reachable over HTTP:
- Ollama (default, local):
ollama serve+ a FIM-capable code model. - DeepSeek / OpenAI
gpt-3.5-turbo-instruct(hosted suffix FIM).
- Ollama (default, local):
editor.inlineSuggest.enabledmust stay on (the VS Code default).
No Python, no virtualenv.
ollama pull qwen2.5-coder:0.5b # small & fast; use :1.5b / :7b for quality
ollama serve # if not already runningThen in VS Code settings (defaults shown):
Open a file in one of ghostcs.languages, start typing, and accept ghost text
with Tab. The model is warmed up on activation so the first completion isn't
a slow cold load.
git clone https://github.com/owasikohu/ghostCS.git && cd ghostCS
npm install
npm run build # esbuild bundles src/extension.ts -> out/extension.js
npx @vscode/vsce package # produces ghostcs-0.1.0.vsix
code --install-extension ghostcs-0.1.0.vsixReload the window (Developer: Reload Window). Under Remote-WSL, ghostCS is a
workspace extension, so it runs Linux-side and reaches a local Ollama and
your *_API_KEY environment variables.
All under ghostcs.* (see Settings → Extensions → ghostCS):
| Setting | Default | Notes |
|---|---|---|
enabled |
true |
Toggle live with ghostCS: Toggle. |
languages |
python, js/ts, go, rust, … | Language ids that get completions. |
backend |
ollama |
ollama | deepseek | openai-instruct | mock. |
baseUrl / apiKey |
"" |
Override URL; key falls back to DEEPSEEK_API_KEY / OPENAI_API_KEY. |
model / modelFamily |
qwen2.5-coder:0.5b / qwen |
Family drives stop-tokens / sentinel cleanup. |
maxTokens / temperature |
128 / 0.1 |
Single-line mode caps tokens lower. |
debounceMs / requestTimeoutMs |
200 / 30000 |
|
multiline |
auto |
auto | single | multi. |
context.maxPromptTokens |
1536 |
Total prompt budget. |
context.crossFile |
true |
Layer 2 cross-file retrieval. |
context.crossFileTokens |
512 |
Reserve (also capped at half the prompt). |
context.retrieval |
jaccard |
jaccard | bm25 (→ jaccard) | none. |
context.maxSnippets |
4 |
|
context.ringChunks / context.ringChunkLines |
16 / 64 |
Recently-edited candidate pool. |
Use ghostCS: Restart after changing settings if a reload didn't pick them up.
npm run typecheck # tsc --noEmit
npm test # vitest — unit tests for the ported pure modules + backends
npm run build # esbuild bundleThe context pipeline, FIM templates, tokenizer, and orchestration helpers have
no vscode dependency, so they're tested directly with vitest. The provider
and entrypoint are exercised manually in VS Code.
{ "ghostcs.backend": "ollama", "ghostcs.model": "qwen2.5-coder:0.5b", "ghostcs.modelFamily": "qwen" }