Steer

unlisted

by Raine

AI writing assistance you direct from the editor.

2 starsUpdated 23d ago
View on GitHub

Steer

AI writing assistance you direct from the Obsidian editor.

The point is not to have AI write everything for you. With Steer, you decide where you need help, what to ask for, and what goes into your note. Use it to get ideas, explore different directions, or polish what you already have.

Select a passage, leave a blank, or continue a sentence. Review suggestions before applying them, or stream a single continuation directly into the note.

Steer suggesting alternatives for selected text in Obsidian

Features

  • Rewrite selected text with built-in or custom actions.
  • Generate alternatives for selected text and refine them by tone, length, or instruction.
  • Apply free-text instructions to selections or complete notes.
  • Continue a sentence from the cursor with previews or direct streaming.
  • Fill ??? and {{described blanks}} from surrounding context.
  • Add context and model settings to individual notes.
  • Connect multiple OpenAI-compatible providers, including local endpoints.
  • Hand off writing tasks and context from an agent to Obsidian with the included skill.
  • Preview rewrites, fills, and optional sentence continuations before applying them.

Requires Obsidian 1.12.2 or later.

Install with BRAT

  1. Install and enable BRAT from Obsidian's Community plugins.
  2. Open Settings → BRAT and select Add beta plugin.
  3. Enter https://github.com/raine/steer and select Add plugin.
  4. Open Settings → Community plugins and enable Steer.

After installing BRAT, you can also open Steer directly in BRAT. BRAT installs updates from the latest GitHub release.

Install manually

  1. Download steer.zip from the latest GitHub release.
  2. Extract the included steer folder into <Vault>/.obsidian/plugins/.
  3. Restart Obsidian.
  4. Open Settings → Community plugins and enable Steer.

The installed files should be at <Vault>/.obsidian/plugins/steer/{main.js,manifest.json,styles.css}. Repeat the process with each release to update a manual installation.

Connect a model

Steer works with any OpenAI-compatible chat completions server. It does not bundle a model or provider.

  1. Open Settings → Steer.
  2. Set the provider Base URL, Endpoint, and Model.
  3. Add an authorization header if your server needs one. Header values are stored in Obsidian's secret storage.
  4. Click Test connection.

The default provider uses http://127.0.0.1:1234 with /v1/chat/completions. The model field starts empty because available model IDs depend on the server.

For example, claude-code-proxy lets you use Codex models through a ChatGPT Plus or Pro subscription instead of an OpenAI API key:

claude-code-proxy codex auth login
CCP_CODEX_RESPONSES_API=1 claude-code-proxy serve

Configure Steer with http://127.0.0.1:18765, /v1/chat/completions, and a model listed by claude-code-proxy models. Requests consume your subscription quota, and available models depend on your account.

You can add named providers and choose a global default. Individual notes can override the provider, model, and reasoning effort from the Steer view.

Rewrite selected text

Select text to open the optional action toolbar. You can also use the command palette, editor context menu, or a hotkey you assign.

  • Alternatives suggests several rewrites of the selection.
  • Simpler, Shorter, More natural, and Something else refine a suggestion. Drag from Alternatives to a refinement to request it directly.
  • Custom follows a free-text instruction for the selection.
  • Humanize, Shorten, and Make clearer are included as starter actions. You can create and arrange your own actions in settings.

Choosing a suggestion replaces the selected text.

Run Custom instruction without a selection to apply an instruction to the whole Markdown body. YAML frontmatter is excluded. Steer shows each result as a line diff and waits for you to click Apply.

Continue a sentence

Place the cursor where the sentence should continue. Run Continue sentence to choose from several streamed options. Run Continue sentence directly to generate one continuation and stream it into the editor as it is written.

Fill blanks

Use ??? when the surrounding text provides enough direction:

The release is ??? for teams with large projects.

Use a described blank when you want to be more specific:

{{briefly explain the performance improvement}}

Run Fill blanks, review the proposed text, and click Accept all. Markers inside YAML frontmatter, fenced code blocks, and inline code are ignored. All fills are applied as one edit, so one undo restores every marker.

Add context to a note

Run Steer to open the right-side view for the active note. Add background, audience, tone, or constraints there. Steer includes that context in later requests for the note.

Context follows note renames and is removed when the note is deleted. The view also provides per-note provider, model, and reasoning effort overrides.

On Obsidian Desktop, you can attach a Claude Code or Pi session .jsonl file. Steer stores a cleaned snapshot of the user and assistant messages. Thinking, tool activity, system records, and subagents are excluded. Use Refresh to read changes from the source file.

Hand off from a coding agent

On Obsidian Desktop, an agent can create or open a note, attach writing context, and focus it through the Obsidian CLI.

Create a request file:

{
  "version": 1,
  "path": "Messages/Feature announcement.md",
  "content": "# Feature announcement\n\n",
  "context": "The parser feature is complete. Emphasize the simpler setup."
}

Then target the intended vault:

obsidian vault="Writing" steer:handoff \
  request="/absolute/path/to/handoff.json"

The destination path is relative to the vault and must end in .md. Steer creates missing folders and notes. For an existing note, omit content to attach or clear context without replacing the note. The command opens the note and reveals the Steer view.

This feature requires Obsidian Desktop with its CLI installed.

Commands

Assign hotkeys in Settings → Hotkeys. Steer does not assign any by default. Mod+Shift+Space is a useful binding for Open assistant.

CommandWhat it does
Open assistantOpens the action list for selected text
Suggest alternativesImmediately requests alternatives for selected text
Custom instructionFollows an instruction for a selection or the whole note
Continue sentenceSuggests text at the cursor
Continue sentence directlyStreams one continuation into the editor
Fill blanksFills ??? and {{...}} markers
SteerOpens the context view for the active note

Keyboard

Arrow keys move through actions and suggestions. Enter runs or accepts the highlighted item. Number keys choose a visible suggestion. Escape cancels, including an in-flight request. Enter or r retries after an error. Mod+Enter submits a custom instruction.

Privacy

Steer sends data only after an explicit action or command. Opening the selection toolbar does not make a request, and Test connection sends a fixed diagnostic message without note content.

A writing request includes the active note, its target selection, cursor, or blanks, and any context saved for that note. Steer does not scan your vault, collect telemetry, or execute model output. Suggestions are inserted as plain text.

Provider header values use Obsidian's secret storage. Per-note context and attached conversation snapshots are stored in the plugin's data.json. Syncing .obsidian may sync that file. Your configured server receives request content under its own privacy and retention policy.

Optional debug logging keeps up to 100 calls in memory, including prompts and responses, and clears them when Obsidian restarts. It is disabled by default.

Build from source

npm install
npm run build

The build writes main.js. Copy main.js, manifest.json, and styles.css to <vault>/.obsidian/plugins/steer/, then enable Steer in Obsidian's Community plugins settings.

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.