Maxim Kravtsov100 downloadsRefine selected text with a floating prompt using CLI or API providers.
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.
OLLAMA_ORIGINS=app://obsidian.md*),
otherwise they transparently fall back to buffered responses.| 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.
main.js, manifest.json, and styles.css from the latest release.<Vault>/.obsidian/plugins/ai-refiner/.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
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:
npm install -g @openai/codex (or brew install codex), then run
codex login in a terminal. Plugin default executable: codex.npm install -g @google/gemini-cli (or brew install gemini-cli),
then run gemini once 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.
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:
Authorization: Bearer …, x-api-key, or x-goog-api-key).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.
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.
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/.
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.
Released under the 0BSD license. See LICENSE.