AI Refiner
approvedby Maxim Kravtsov
Refine selected text with a floating prompt using CLI or API providers. - This plugin has not been manually reviewed by Obsidian staff.
AI Refiner
An Obsidian plugin that refines selected text in place through a floating prompt. Select text, describe how you want it changed, and the result replaces your selection.
It works with cloud APIs, local models, and AI CLIs — you choose the backend, and nothing leaves your machine unless you configure it to.
Features
- Floating prompt anchored to your cursor — type an instruction, press Enter, done.
- Result preview with diff (default) — the refined text is shown as a word-level diff against your selection with Apply / Retry / Copy / Discard before anything touches the note. Prefer the old behavior? Switch Result mode to Replace immediately in settings (upgrades from older versions keep it).
- Quick prompt presets — one-click Fix grammar, Make clearer, Shorten, Formal tone, Translate — fully editable, and you can add your own. Each prompt can optionally pin its own provider and model (e.g. run "Fix grammar" through a fast local model while everything else uses your default); the pin applies while the panel's instruction still matches the prompt, and CLI pins degrade to an API provider on mobile.
- Context scope — optionally send the surrounding paragraph or the whole note (trimmed to a window around the selection for huge notes) as read-only reference; only the selection is ever replaced. Pick the scope right in the panel.
- Multiple backends through one pipeline (see the table below).
- Three ways to trigger: command palette, ribbon icon, or a custom hotkey.
- Optional voice input — dictate your instruction via a Whisper-compatible transcription endpoint (off by default).
- Streaming preview — with preview mode on, the result streams into the panel
live. Streaming works out of the box for OpenAI, Anthropic, OpenRouter, Groq,
Mistral, DeepSeek, and xAI endpoints; local servers (Ollama, LM Studio) stream when
they allow Obsidian's origin (for Ollama set
OLLAMA_ORIGINS=app://obsidian.md*), otherwise they transparently fall back to buffered responses. - In-flight cancel — press Escape to cancel. CLI providers are terminated for real (SIGTERM), and streamed HTTP requests are truly aborted mid-flight. Only buffered (non-streaming) HTTP requests merely discard the result — Obsidian's network API cannot abort an already-sent request, so the server may still finish processing it.
- Safe replacement — if the document changes while a request runs, the stale result is discarded instead of overwriting unrelated text.
- Localized UI (English, Russian, Spanish) that follows your Obsidian language.
Providers
| Provider | Type | Platform | Notes |
|---|---|---|---|
| Custom API | Cloud / self-hosted | Desktop + mobile | OpenAI-compatible, Anthropic, Google Gemini, OpenRouter, Groq, and similar — detected from the endpoint URL. |
| Local models | Local | Desktop + mobile | Ollama and OpenAI-compatible local servers (LM Studio, etc.). |
| Gemini CLI | Local CLI | Desktop only | Runs the Gemini CLI as a child process. |
| Codex CLI | Local CLI | Desktop only | Runs the Codex CLI as a child process. |
On mobile, CLI providers are hidden and the plugin falls back to an API/local provider automatically.
Installation
Manual (from a release)
- Download
main.js,manifest.json, andstyles.cssfrom the latest release. - Copy them into your vault at
<Vault>/.obsidian/plugins/ai-refiner/. - Reload Obsidian and enable AI Refiner under Settings → Community plugins.
Build from source
npm install
npm run build
Then copy the produced main.js, manifest.json, and styles.css into the plugin
folder as above, or use the deploy helper:
OBSIDIAN_PLUGIN_DIR="$HOME/Obsidian/.obsidian/plugins/ai-refiner" npm run deploy
Installing the CLI providers (desktop)
CLI providers run a locally installed binary — the plugin never downloads or
executes remote code itself (for that reason there is no npx preset: npx -y
would fetch and run a package from the npm registry on every request). Install the
CLI you want once, sign in, and point the plugin at the binary:
- Codex CLI:
npm install -g @openai/codex(orbrew install codex), then runcodex loginin a terminal. Plugin default executable:codex. - Gemini CLI:
npm install -g @google/gemini-cli(orbrew install gemini-cli), then rungeminionce to authenticate. Plugin default executable:gemini.
If the bare command is not found from Obsidian (GUI apps don't inherit your shell
PATH), the plugin also checks the common install directories; otherwise set the
absolute path in settings (which codex / which gemini shows it). Configs from
older plugin versions that used the npx preset are migrated to the bare binary
automatically.
Usage
- Select some text in a note.
- Trigger AI Refiner via the command palette (AI refine selection), the ribbon icon, or your configured hotkey.
- Type an instruction (or pick a quick prompt) and press Enter.
- The refined text replaces your selection. Press Escape any time to cancel.
Settings
- Provider — the backend used for refinement.
- Result mode — preview the result (with a diff and Apply/Retry/Copy/Discard) or replace the selection immediately.
- Base instruction — optional text prepended to every request.
- Shortcut — capture and enable a custom hotkey.
- Voice input — enable the microphone button and set the transcription endpoint.
- Quick prompts — edit the built-in presets or add custom ones.
- Provider-specific fields:
- CLI: executable path, arguments (JSON array), timeout.
- API / local: endpoint, model (auto-detectable), token (if required).
Network use and privacy
This plugin makes network requests only to endpoints you configure. Nothing is sent anywhere by default, and there is no telemetry or analytics of any kind.
What is sent, and where:
- API / local providers — your selected text and the instruction go to the endpoint
URL you set. If the endpoint needs a key, it is sent as a request header
(
Authorization: Bearer …,x-api-key, orx-goog-api-key). - CLI providers (desktop only) — your text and instruction are written to the CLI process over stdin. Whatever that tool does with it (including its own network calls) is governed by that tool, not this plugin.
- Voice input (optional) — recorded audio is sent to the transcription endpoint you configure.
- Model discovery (optional) — pressing "detect models" queries the provider's models endpoint.
Token storage: on Obsidian 1.11.4+, API and voice tokens are kept in Obsidian's
SecretStorage (Settings → Keychain; encrypted at rest by your OS keychain since app
1.11.5) and are automatically migrated out of data.json on first load — the plaintext
copy is removed only after the keychain write is verified. Keychain secrets are
per device and never sync: after syncing a vault to a new device, re-enter the token
there once. On older Obsidian versions tokens remain unencrypted in the plugin's
data.json — a synced or backed-up vault propagates them, so do not share that file.
Mobile
The plugin runs on mobile. CLI providers require Node/Electron APIs and are therefore desktop-only; on mobile, use an API or local-model provider.
Development
npm install
npm run dev # watch build
npm run build # type-check + production bundle
npm run lint # eslint (incl. obsidianmd rules)
npm test # vitest unit tests for pure logic
Source lives in src/, split by responsibility: providers/ (backend strategies),
services/ (refine flow), ui/ (floating input), settings/, voice/, i18n/, and
utils/. Unit tests for the pure logic live in tests/.
Releasing
Releases are automated by .github/workflows/release.yml and triggered by pushing a
tag equal to the manifest version (no v prefix — the project-level .npmrc sets
tag-version-prefix="", so npm version creates the right tag regardless of your
global npm configuration).
npm run build # produce main.js
npm run release-check # versions in sync, artifacts present, tag format
npm version patch # or minor / major — bumps package.json + manifest.json,
# updates versions.json when minAppVersion changed,
# commits and creates the un-prefixed tag
git push && git push --tags
The workflow re-runs lint, tests, build, and release-check, then attests build
provenance and attaches main.js, manifest.json, and styles.css to a GitHub
release. versions.json gets a new entry only when minAppVersion changes — that map
is what serves older Obsidian installs the last compatible release.
License
Released under the 0BSD license. See LICENSE.
For plugin developers
Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.