Curtis.ai

unlisted

by Jordan Newell

AI chat + agent. 53 providers: ChatGPT, Claude, Gemini, DeepSeek, Ollama + local. Agent tools edit your notes, MCP client & server, skills, RAG vault search, scheduled runs, arena. Free, source-available.

Updated today
View on GitHub

The agent layer for Obsidian.
Every provider, one sidebar — 53 of them, OpenAI to Ollama. The agent reads and writes your notes, calls your MCP servers, learns skills, and remembers what matters. Conversations live as markdown in your vault. Your vault stays yours.

The arena in motion — one prompt typed once, streamed to two models in parallel, stop either column mid-flight, then Promote-to-chat keeps the winner

The arena, live: one prompt, two models in parallel — stop one column, promote the winner.

Live site Latest release License: BUSL-1.1 Obsidian 1.13+ 53 built-in providers Zero lint warnings GitHub Discussions

Website ↗ · Quick start · What's new · Features · Docs · Changelog · Feedback


Screenshots

Real captures, regenerated any time with npm run shots && npm run mockups (general set) and node scripts/capture-arena-shots.mjs (arena set, both themes + phone).

Arena — one prompt streaming to two models side by side, per-column Stop while streaming
Arena, light theme — both answers complete, Promote to chat on each columnArena on a phone — columns stack vertically
Multi-pane chat — two titled chat tabs in the center tab strip, each its own conversation and model; the pane menu renames, opens new tabs and windows
Memory — a plain markdown note in your vault; add or edit a fact, save, and Curtis recalls it in the next turn
Desktop — vault open, agent conversation on a local Ollama model with tool call and resultPhone — the agent conversation at phone width

Quick start

60 seconds to your first message.

  1. Install — download the latest release (main.js, manifest.json, styles.css) into <vault>/.obsidian/plugins/curtis-ai-chat/, then enable it under Settings → Community plugins. Or use BRAT for auto-updates during the beta.

  2. Configure one provider — open Settings → Curtis.ai → Provider Configuration, enable a provider, paste an API key. Keys are stored in your OS keychain via the Obsidian SecretStorage API. No key for some plans: ChatGPT (Sign in) uses OpenAI's official OAuth against your ChatGPT Plus/Pro plan, and Kimi for Coding / Alibaba Coding Plan take a plan key from those consoles. See Subscription plans and sign-in.

  3. Send a message — click the Curtis mark in the ribbon, pick a model from the header dropdown, type, hit Enter. (No command ships with a default hotkey; every command is assignable under Obsidian's Settings → Hotkeys.)

[!TIP] Want fully private, free, offline AI? Install Ollama, run ollama pull qwen2.5:7b-instruct, then enable Ollama (Local) in provider settings. No API key. Nothing leaves your machine.


Highlights

The flagship features. Full details in CHANGELOG.md and the per-feature docs.

FeatureWhat it does
🤖Curtis AgentAI calls tools to read, create, and edit your vault notes. Twelve built-in tools, every provider.
🎭Named agentsGive any model a role: persona + model routing + tool ceilings, bound to any chat with /agent — or spawned as swarm specialists.
🧠SkillsTeach any model a reusable procedure: vault skills in the open Agent Skills standard, discovered by description, loaded on demand in every chat, arena run, and headless run. Portable to and from Claude Code, Cursor, and Copilot.
🧩Harness profilesPick the base contract composed under every system prompt: the full Curtis contract, a no-persona plain assistant, or your own custom profile. Settings → Generation.
🔌MCP serversConnect MCP servers you already run — any tool they expose joins the agent's toolset, namespaced mcp__<server>__<tool>.
🛰️MCP server modeServe the vault — and your named agents — as MCP tools on localhost, so Claude Desktop, coding agents, and any MCP client can work your notes without opening Curtis.
🔑Subscription plansUse plans you already pay for: ChatGPT Plus/Pro via official sign-in (no API key), Kimi for Coding and the Alibaba Coding Plan via a pasted plan key.
⏰Scheduled runsPut a prompt or a named agent on a cadence — daily at a time or every N minutes. Each headless run lands as a markdown note.
⛁Terminal paneA shell next to your notes, plus the opt-in run_command agent tool with per-command approval.
⚔️Multi-model arenaStream one prompt to 2–4 models in parallel, side-by-side. Pick a winner, promote to chat.
🪟Multi-pane chatOpen another chat as a tab or its own OS window. Each keeps its own conversation, provider, and model — titled, so you can tell them apart.
🎨Inline diff rewriteCursor-style rewrite with an Accept/Reject diff modal. Assignable hotkey.
✍️Inline autocompleteGhost-text suggestions while you type in any note. Pause, Tab to accept. Small and local models work.
@@-mention vault notesType @ in chat → fuzzy-search your vault → attach note content as context.
📚Prompt librarySave prompts you reuse and drop them into any chat input: /prompt, or the book-marked button in the composer. One shared library, model-agnostic.
🎙️Voice I/OWhisper speech-to-text on the mic button. Browser TTS on every assistant message.
🔍Cross-conversation searchAssignable hotkey opens a fuzzy-matched picker across all conversations and messages.
📝Markdown exportDownload any conversation as .md. /export slash command or download icon.
📥Chat import + .curtBring ChatGPT, Claude, or any role-labeled chat history into Curtis — exports auto-detected, imports land as normal vault files. One .curt file = one portable conversation. Plus a full backup zip: chats, prompt library, harnesses, and settings (keys stripped), restorable section-by-section.
🔧Import from Claude CodeOne click adopts your Claude Code setup: MCP servers (imported disabled), vault skills, subagents as named agents (remote invocation off), CLAUDE.md as a harness profile. Desktop.
🧠MemoryAsk-before-saving capture with provenance: every fact records the conversation it came from, and replies show a "N memories" chip with the fact list behind it.
📓Recaps + Curtis Journal/recap writes a terse session summary into the chat and an append-only journal note — plus a "discussed in …" hint when your open note matches a past conversation.
🗂️Conversations as vault filesEvery chat persists as a markdown note in AI/Conversations/ — synced across devices, in native Obsidian search, and readable by the agent. Old localStorage history imports itself.

Plus a full type-safety pass: every AI provider response shape is strictly typed, with type-guard narrowing at every JSON boundary. Zero lint warnings on npm run build.


Features

🤖 Curtis Agent

The AI can now call tools to modify your vault. Twelve built-in tools: read_note, search_notes, semantic_search, create_note, edit_note, list_notes, get_tags, get_backlinks, get_current_note, get_current_date, calculator, load_skill (semantic_search joins with the vault retrieval index on, load_skill with Skills enabled).

  • Every major provider — Anthropic via native tool use, OpenAI-compatible endpoints (OpenAI, Gemini, Ollama, Groq, DeepSeek, custom). The model must support tool calling.
  • agentMaxTurns safety cap (default 5) prevents runaway tool loops
  • MCP servers — connect your existing Model Context Protocol servers (Settings → MCP servers) and every tool they expose becomes callable alongside the built-ins. Streamable HTTP transport — local stdio servers need an HTTP bridge such as mcp-proxy or supergateway.
  • Opt-in via Settings → Agent → Enable

→ docs/AGENT.md

🎭 Named agents

Create reusable workers — an Editor on Claude that can read but not write, a Researcher with web access and a read-only vault, a Librarian on local Ollama that never touches the network — and bind them to any chat with /agent or the header pill.

  • Model routing per role — the agent picks the provider/model; the pane picker stays yours
  • Tool ceilings — vault / web / MCP toggles that can only narrow what the global settings allow
  • Memory you can sever — a memory-off agent's facts never reach the shared memory file, so local-only lanes stay private end to end
  • Swarm specialists — a leader chat can spawn any agent by name as a follower with its own model and permissions

→ docs/AGENTS.md

⚔️ Multi-model arena

Pick 2–4 models, send one prompt, watch responses stream side-by-side. Click Promote to chat on any column to continue with that model.

  • Compare quality, latency, and cost live
  • All providers supported (mind per-provider rate limits)
  • Stacks vertically on mobile

→ docs/ARENA.md

🎨 Inline diff rewrite

Select text in any note → right-click → Rewrite with AI (diff) (or assign a hotkey under Settings → Hotkeys). The AI generates an improved version and a modal shows line-by-line green/red diff. Accept or reject.

  • Cursor-style review workflow
  • Reuses your active provider and model
  • Word-level diff and inline editor decorations are still on the roadmap

→ docs/DIFF_REWRITE.md

@ @-mention vault notes

Type @ in the chat input → fuzzy-search your vault → click a result to attach. Note content is prepended to your message as invisible context. Chips above the input show what's attached.

  • Active-note pill in the chat header for one-click attach of the current note
  • AI uses attached content as the source of truth — no re-searching
  • Works with or without the Agent enabled

→ docs/MENTIONS.md

✍️ Inline autocomplete

Keep typing — when you pause mid-word, a dimmed continuation appears after the cursor. Tab accepts, Escape dismisses, one undo removes it.

  • Works in every note, with any provider — including local Ollama models
  • Requests are debounced, cached, and capped at 60 tokens; the model picker steers you to small fast models
  • Tab only takes over while a suggestion is visible — vim users keep their indent
  • Off by default; session token spend is visible in /stats

→ docs/AUTOCOMPLETE.md

🎙️ Voice I/O

  • Speech-to-text — click the mic button, talk, transcribed text lands in the chat input. Transcribe on your OpenAI key (Whisper), Groq (whisper-large-v3-turbo), or any OpenAI-compatible endpoint; optional auto-send after dictation
  • Text-to-speech — speaker button on every assistant message. System voices (offline, no API key) or a neural voice on your OpenAI key (OpenAI /v1/audio/speech): ten voices, a steerable reading style, and automatic fallback to system voices if a request fails
  • Auto-speak toggle in the header for hands-free listening — works with either engine
  • Markdown is stripped before synthesis so the voice reads naturally

→ docs/VOICE.md

🪟 Multi-pane chat

Open another chat as a tab beside the active one, or pop one out into its own OS window. Every pane is a full, independent chat that starts fresh.

  • Open new chat tab and Open chat in new window in the command palette
  • Also the always-visible new-tab icon on the pane header, the popout icon (carries that chat into the window), and the pane's "..." menu
  • Tabs and windows are titled with their conversation — click the title in the chat header, or the pane menu, to rename
  • Per-pane conversation, provider, and model — two models at once with no cross-talk
  • Popout windows are desktop-only

→ docs/MULTIPANE.md

💬 Chat that gets out of the way

  • Terminal-style transcript — your messages echo as ❯ prompt lines, replies type out under the streaming neon caret
  • Model picker with capability pills (vision 👁, tools 🔧, context length)
  • Per-message hover actions: copy, quote-into-input, save-as-note, insert-into-active-note, regenerate, edit-and-resend
  • Conversation history dropdown
  • Cross-conversation search (assignable hotkey)

🖼️ Image attachments

  • Paste (Ctrl+V), drag-and-drop, or paperclip — three ways to attach
  • Images save as real vault files (not base64 blobs in localStorage)
  • Vision-capable models see them automatically; non-vision models get a clear "switch to a vision model" notice
  • Transcripts via /save-all embed images as ![[wikilinks]]

→ docs/IMAGES.md

✂️ Inline selection actions

Right-click any selection in a note for Explain · ELI5 · Summarize · TL;DR · Improve · Fix grammar · Shorten · Translate · Make a table · Pros & cons · Code review · Refactor · Add tests. Each writes the result directly back into the note — replace or insert-below.

→ docs/SELECTION_ACTIONS.md

🧠 Long-term memory

Curtis remembers durable facts about you across conversations — preferences, identity, projects, standing instructions. Facts live in a markdown file in your vault.

  • Ask before saving: after each turn the model proposes up to 3 facts — Save/Skip each, nothing persists without your tap
  • Provenance: every captured fact records the conversation it was learned from; Settings → Memory shows "learned · from " with a jump button
  • Memory chips: assistant replies show how many facts were in context; click to open the list with learned dates and source-conversation links. Removed facts say so instead of showing stale text
  • Manual: /remember <fact> or right-click selection → Save to memory
  • Edit UI: edit/delete individual facts from Settings → Memory
  • Recall: every prompt includes a ## What you know about the user block

→ docs/MEMORY.md

📓 Session recaps + Curtis Journal

Close out a working session with a summary you can find later.

  • /recap or Export → Recap conversation: 2-3 terse bullets — worked on, decided, left open — appended to the chat and logged to AI/Curtis Journal.md
  • The journal is plain append-only markdown in your vault, one entry per recap with a link back to the conversation
  • Relevance pulse: open a note that closely matches a past conversation and a quiet "discussed in …" hint appears under the chat header — click to jump straight back into it. Local similarity over your vault index, no API calls (Settings → Vault retrieval)

🔎 Vault retrieval (RAG)

Ask about your vault in plain language — the most relevant note excerpts are retrieved and injected into the prompt automatically.

  • Any embeddings provider — OpenAI, Gemini, Z.ai, or fully local via Ollama/LM Studio (Anthropic and Azure are excluded — no embeddings API / deployment-specific URL scheme)
  • Hybrid retrieval — semantic embeddings fused with keyword (BM25) matching via reciprocal rank fusion; exact names, tags, and identifiers match as well as meaning does, at zero extra cost
  • Automatic injection — top-k excerpts in every prompt; skipped when you @-attach a note, because curated context wins
  • Live index — edits re-embed in the background; rebuilds are incremental and cheap
  • semantic_search tool — the agent queries the vault by meaning and by keyword
  • Your index stays yours — int8-quantized JSON in the plugin folder; nothing uploaded beyond the embeddings provider you configure

Enable in Settings → Vault retrieval, then Rebuild index.

⌨️ Slash commands

Type / in the chat input for an autocomplete menu of 21 commands — /clear, /regen (alias /regenerate), /title, /leader, /agent, /skill, /copy, /note, /save-all, /paste, /prompt, /model, /provider, /system, /stats, /remember, /forget, /memory, /recap, /export, /help.

→ docs/SLASH_COMMANDS.md

⚙️ Customizable

  • Chat panel position (left/right), background (theme default or a wallpaper image from your vault)
  • Configurable system prompt, temperature, max tokens — with per-provider and per-model overrides for advanced request parameters
  • Enter-to-send (default) or Enter-for-newline
  • Auto-save assistant responses to a folder of your choice
  • Show or hide token counts after each response

🎛️ Advanced request parameters

Every provider card — and each of its models — takes overrides for temperature, max tokens, top-p/top-k/min-p, seed, stop sequences, and penalties, plus a reasoning-effort control mapped to each provider's dialect, an omit-temperature escape hatch for models that reject sampling params, and an "Extra body JSON" passthrough. Fields a provider's API rejects are dropped before the request goes out. Ollama adds hardware knobs — context window, GPU layers, CPU threads, keep-alive — over its native /api/chat dialect. Per-model beats per-provider beats the global Generation settings.

→ docs/PROVIDERS.md


Why Curtis.ai

Curtis.ai is the agent layer for Obsidian. Where other plugins focus on a single workflow (chat, RAG, or text generation), Curtis ships all three with a polyglot provider model and a native Obsidian feel. Every provider, one sidebar.

Curtis.aiSmart ConnectionsText GeneratorCopilot for Obsidian
All features free (no subscription)✅✅✅Core only — advanced features need Copilot Plus
Agent tools (vault-modifying)✅ 12 built-in + MCP❌❌✅ v4 agent chat
Vault retrieval (RAG)✅ hybrid — BM25 + any embeddings provider✅❌✅
Provider count531–21–210+
Local-first (Ollama, LM Studio)✅❌✅✅
Multi-model arena✅❌❌❌
Inline diff rewrite✅❌❌❌
Voice I/O✅❌❌❌
Long-term memory✅ Markdown-fileVector index❌✅ JSON
Native Obsidian rendering✅ MarkdownRendererPartial❌Partial

[!NOTE] Comparison refreshed 2026-10-03. Other plugins ship fast — Copilot's v4 agent chat is real and actively developed, Smart Connections remains the gold standard for RAG (Curtis' own retrieval is new; theirs is battle-tested), Text Generator excels at template-driven writing. Curtis aims to be the free, polyglot, local-first agent layer that ties chat, tools, and memory together.

Principles

  • Your data stays yours. Conversations as markdown files in your vault (AI/Conversations/ by default) — synced across devices, searchable in native Obsidian search, and readable by the agent. Images as real vault files. Memory as a markdown file you can read and edit. No telemetry, no tracking, no phone-home.
  • No vendor lock-in. Fifty-three providers ship built-in. Add any OpenAI-compatible endpoint as a custom provider in 30 seconds. Switch models mid-conversation.
  • Local-first when you need it. Enable Ollama and nothing ever leaves your machine. Useful for private notes, air-gapped machines, or when you just don't want to pay per token.
  • Native Obsidian feel. Real Obsidian setting components. Messages render through MarkdownRenderer. Themes respected — light, dark, Things, Minimal, all of them.

Configuration

Full configuration reference lives in the docs:

Or start at the docs index.


Privacy & security

Curtis.ai accesses your vault files only in user-initiated cases:

  1. Agent vault-search tool — when you explicitly invoke a tool in chat, the plugin enumerates markdown files. The agent sees file paths and contents you ask it to read.
  2. Image picker — when you click the paperclip, the plugin lists image files.
  3. Folder picker — when you configure auto-save or wallpaper folders.
  4. @-mention autocomplete — when you type @, the plugin fuzzy-searches note names. Note contents are only read when you actually attach and send.

No file contents are sent to AI providers except message text, attached images, attached note contents, and tool-call results. API keys are stored in your OS keychain (Windows Credential Manager / macOS Keychain / Linux Secret Service), never in the vault.

PERMISSIONS.md maps every vault-enumeration, clipboard, and dynamic-evaluation call site to the feature that requires it.

Clipboard: the plugin reads the system clipboard only when you paste into the chat input (Ctrl+V / long-press → Paste), and writes to it only when you click copy on a message. Nothing is read from or written to the clipboard in the background.

[!IMPORTANT] Tool calls go to your AI provider. Vault contents read by agent tools are sent to the provider as part of the conversation. If you're on a cloud provider, that content leaves your machine. Switch to Ollama for fully offline operation.

Network access

Curtis is vault-first — no background telemetry, no analytics, no auto-update checks. Every outbound request is user-initiated, except the always-on link-favicon fetch noted below. The plugin may contact these domains:

WhenDomainWhy
You send a message (cloud providers)Your provider's API (e.g. api.anthropic.com, api.openai.com, generativelanguage.googleapis.com)Chat completion / streaming
Vault retrieval builds or queries the index (opt-in)Your embeddings provider's APINote chunks and queries are sent for embedding
Vault retrieval uses Local (on-device) embeddings (opt-in)huggingface.coOne-time download of the embedding model weights (~30 MB, then cached by the WebView)
You send a message (Ollama / LM Studio)localhost / your custom endpointLocal model inference
You click "Test connection" or "Refresh models"Your provider's APIAuth + reachability check, model list
You use voice transcriptionapi.openai.com (default), or the dictation endpoint you configure (Groq / custom)Whisper-style transcription (only when voice input is on)
Read-aloud with the neural TTS engine (opt-in)api.openai.comOpenAI speech synthesis — off unless the read-aloud engine is set to Neural; system voices stay fully local
You sign in with the ChatGPT provider (desktop)auth.openai.comOpenAI OAuth — user-initiated sign-in and token refresh; tokens stored in the OS keychain
Chat renders a message containing an external linkicons.duckduckgo.comLink favicons — one request per domain, then cached (Settings → Chat UI; on by default — off keeps rendering fully local)
The agent calls web_search (opt-in)html.duckduckgo.comDuckDuckGo search
The agent calls read_url (opt-in)r.jina.aiURL → markdown reader
The agent calls MCP tools (opt-in)your own MCP serversUser-configured endpoints (Settings → MCP servers)
The agent calls GCP tools (opt-in connector)Google OAuth + storage.googleapis.comSign-in and read-only Cloud Storage requests for the GCP connector
You enable webhooks (Settings → Outbound events)Your webhook URLOutbound-only JSON event when a response or scheduled run finishes — metadata (provider, model, duration, tokens, cost), never message or note content; optional shared-secret header

The two web tools (web_search, read_url), voice transcription, MCP, the GCP connector, vault retrieval, and webhooks are off by default; link favicons are the one always-on exception (on by default, one cached request per domain — turn them off for fully local rendering). With the opt-ins off, the only external calls go to whichever AI provider you configured — or none, if you're on Ollama. MCP tool calls go only to the server URLs you entered; tool results travel through your AI provider like any other tool result.

Capabilities

Features that reach beyond reading and writing notes, and the gate each one ships behind:

CapabilityGateBounds
Terminal pane (desktop)Opens only when you ask — ribbon, command palette, or the chat top barA real shell in a docked pane or its own OS window; not restricted to the vault
run_command agent tool (desktop)Off by default; requires agent mode; confirmation per command (Deny / Run once / Always this session)Restricted to the vault by default (toggleable — bounds the AI, never your terminal pane); output capped; swarm followers ride the same gate
Vault shell (mobile)Same pane and tool, same confirmationsCurated command set (ls, cat, grep, find, …) implemented over the vault API — no OS processes, cannot touch anything outside the vault, rm moves to Obsidian trash
MCP server mode (desktop)Off by defaultBinds 127.0.0.1 only, bearer-token auth, refuses non-loopback hosts and browser origins; read-only until "Allow writes" is on; every client path passes a vault jail; run_agent additionally needs the agent's own Remote invocation toggle (default off)
GCP connectorOff by default; requires agent modeRead-only Cloud Storage (devstorage.read_only scope — cannot write even if asked) via your service-account key, stored in the OS keychain; three list/read tools
Public plugin APIOther Obsidian plugins call it explicitlychat() / runAgent() / read-only vault tools; shell commands excluded unless explicitly allowed
Outbound webhookOff by defaultOne-way: POSTs a metadata-only event (chat.completion, scheduled.run) to the URL you configure, with an optional shared-secret header — no inbound listener, no message or note content

Scheduled runs execute through the agent loop with shell access always excluded, and only agents with Remote invocation enabled can be put on a schedule.


Installation

[!TIP] Curtis.ai installs via BRAT for beta-channel updates, or manually (below).

Manual install

  1. Download the latest release main.js, manifest.json, and styles.css.
  2. In your vault, create .obsidian/plugins/curtis-ai-chat/.
  3. Copy the three files into that folder.
  4. Open Settings → Community plugins, refresh the list, enable Curtis.ai.

From source (developers)

git clone https://github.com/JordanNewell/curtis-ai-chat.git
cd curtis-ai-chat
npm install
npm run build

See CONTRIBUTING.md for dev setup, code style, and the audit checklist.


Mobile

Curtis.ai works on iOS and Android with a few caveats:

  • Hover-only elements (per-message toolbar, code-block copy) are always visible on touch at reduced opacity
  • Touch targets sized to Apple HIG minimums (44pt send button, 40pt header icons)
  • Wallpaper background auto-disabled on phones for scroll performance
  • /paste may fail if the OS blocks clipboard read — use Ctrl+V / long-press → Paste
  • Streaming falls back to buffered responses automatically when a provider blocks mobile CORS
  • Local providers work over LAN (http://192.168.1.50:11434/api/chat)

Roadmap

  • Curtis Agent: Anthropic, Gemini, and Ollama provider support (v1.1)
  • Inline diff rewrite: word-level diff and inline editor decorations
  • Settings: declarative getSettingDefinitions() — shipped in v1.2.0 (see ADR: settings API)
  • Vault retrieval (RAG): embedding index over the vault, auto-injected context, semantic_search agent tool (v1.4.0); hybrid retrieval — BM25 + cosine fused via RRF (v2.0.0)
  • MCP client: connect external MCP servers, their tools join the agent toolset (v1.4.0)
  • Conversations as vault markdown files with automatic localStorage import (v1.4.0)
  • Named agents + swarm mode: persona/model-routing/tool-ceiling workers, leader chats spawning follower agents (v2.0.0)
  • Terminal pane + opt-in run_command agent tool with per-command approval (v2.0.0)
  • Scheduled runs: a prompt or agent on a daily/interval cadence, headless, results as notes (v2.0.0)
  • MCP server mode: serve the vault and your agents to external AI apps on localhost (v2.0.0)
  • Public plugin API for other Obsidian plugins (v2.0.0)
  • GCP connector: read-only Cloud Storage as agent tools (v2.0.0)
  • Inline autocomplete: ghost text in any note, off by default (v2.0.0)
  • Voice settings: persisted voice/rate/pitch, karaoke highlight, auto-speak (v2.0.0)
  • Voice engines: neural TTS on the OpenAI key + dictation endpoints (Groq / any OpenAI-compatible host, auto-send) (v2.0.0)
  • Desktop notifications when a response finishes or fails (v2.0.0)
  • Voice: local offline neural TTS, streaming TTS, wake-word detection
  • Conversation branching UI
  • Plugin settings import/export — full backup & restore: chats, prompts, harness profiles, settings (v2.0.0)
  • Semantic memory retrieval via sqlite-vec (when memory exceeds ~150 facts)

Tracked live on the public roadmap project; open issues carry the detail.


Contributing

PRs welcome — see CONTRIBUTING.md for dev setup, code style, and the audit checklist every change goes through before merge.

[!NOTE] Not accepting external PRs yet while the 2.0 line stabilizes. Bug reports and feature requests via Issues are very welcome.

Architecture decisions

Settings API

Since v1.2.0 Curtis targets Obsidian 1.13.0+ and uses the declarative getSettingDefinitions() API for its settings tab. Every section and row is indexed by Obsidian's settings search; dynamic re-renders go through the sanctioned SettingTab.update().

History: through v1.1.x the floor was 1.11.4 (set by the SecretStorage API for per-provider key storage) and the tab used the imperative display() API, which Obsidian 1.13 deprecated. The dual-path (getSettingDefinitions() + display() fallback) was evaluated and rejected — the declarative path's SettingTab.update() is 1.13-only, so supporting both meant either shipping a broken tab on older versions or tripping the no-unsupported-api lint rule. When Obsidian 1.13.6 reached the stable channel for all desktop and mobile users (August 2026), the migration shipped as v1.2.0: a single declarative path, zero deprecation warnings, and settings search that actually finds things.

💬 Feedback

All feedback is public and lives on GitHub:

No GitHub account? Email hello@jordannewell.com and it gets posted publicly for you.


License

BUSL-1.1 © Jordan Newell. Free to use, modify, and redistribute for non-production purposes; production use — personal or business — is permitted so long as you are not offering Curtis, or a derivative of it, as a competing product or service. Each version converts to Apache-2.0 four years after release. The Curtis name and logo are trademarks of Jordan Newell.

Built by Jordan Newell

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.