Files
nibbleai/README.md
T
2026-05-24 21:27:01 -04:00

254 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# NibbleAI
> AI-powered tools for your Obsidian vault — speech-to-text, proofreading, title generation, property filling, and more.
[![Obsidian plugin](https://img.shields.io/badge/Obsidian-plugin-blue?logo=obsidian)](https://obsidian.md)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
NibbleAI is a central hub for small, practical AI-assisted tasks inside Obsidian. Instead of installing a dozen single-purpose plugins, NibbleAI gives you one consistent interface with shared configuration, a unified AI service, and a growing set of capabilities.
---
## Features
### 🎙️ Speech-to-Text (Transcription)
Record audio directly in Obsidian or upload existing audio/video files, and get instant transcripts via OpenAI Whisper (or any compatible API — Groq, Azure, etc.).
- **Record** with your microphone using the built-in recorder
- **Upload** audio/video files from disk
- **Transcribe** existing audio files via the file context menu
- **Post-process** transcripts with an LLM to fix grammar, remove filler words, and format as Markdown
- **Auto-generate** note filenames from the transcript content
- **Template system** for note content (`{{date}}`, `{{time}}`, `{{title}}`, `{{transcription}}`, `{{audioFile}}`)
### ✍️ Proofreading
Fix punctuation and grammar of selected text with a single command or right-click.
- **Prompt injection resistant** — the built-in system prompt explicitly guards against prompt injection attacks in the text being proofread
- **Smart quote replacement** — straight quotes → curly quotes (except in code blocks)
- Works with any OpenAI-compatible provider (OpenRouter, OpenAI, etc.)
### 🏷️ Title Generation
Generate a descriptive title for the current note with one command. Choose how to apply it:
- **Rename the file** — the note's filename becomes the generated title
- **Set a frontmatter property** — adds or updates a `title:` field in the YAML frontmatter
### 📋 Property Filling
Fill any frontmatter property with AI-generated content. Built-in quick commands for common properties:
- **Fill any property** — prompts you for the property name
- **Fill "summary"** — one-click command
- **Fill "tags"** — one-click command
- Customizable generation prompt with `{property}` placeholder
---
## Installation
### From Obsidian Community Plugins (once published)
1. Open **Settings****Community plugins**
2. Disable **Safe mode**
3. Click **Browse** and search for "NibbleAI"
4. Install and **Enable**
### Manual Installation
1. Download the latest release from the [Releases page](https://github.com/your-username/nibbleai/releases)
2. Extract the folder to `YourVault/.obsidian/plugins/nibbleai/`
3. Enable the plugin in **Settings****Community plugins**
### Build from Source
```bash
git clone https://github.com/your-username/nibbleai.git
cd nibbleai
npm install
npm run build
```
Then copy the `main.js`, `manifest.json`, and `styles.css` to your vault's plugins folder.
---
## Getting Started
### 1. Configure API Keys
Open **Settings****NibbleAI** and add at least one API key:
| Key | Used For |
|-----|----------|
| **Transcription API Key** | Whisper transcription (OpenAI, Groq, Azure) |
| **OpenAI API Key** | Proofreading, title generation, property filling, post-processing *(recommended: OpenRouter)* |
| **Anthropic API Key** | Post-processing with Claude models |
> **Tip:** For proofreading, title generation, and property filling, an [OpenRouter](https://openrouter.ai/keys) API key with a free model like `google/gemini-2.5-flash-lite` costs nothing and works great.
### 2. Try the Features
| Feature | How to Use |
|---------|-----------|
| **Record audio** | Click the 🤖 ribbon icon, or use the `Start/stop recording` command (`Alt+Q`) |
| **Upload audio** | Use the `Upload audio file` command |
| **Transcribe existing file** | Right-click an audio file in the file explorer |
| **Proofread text** | Select text → right-click → "Fix punctuation and grammar with AI" |
| **Generate title** | Use the `Generate title for current note` command |
| **Fill property** | Use the `Fill property with AI` command (or the presets for `summary` / `tags`) |
---
## Commands
| Command | Icon | Default Hotkey | Description |
|---------|------|----------------|-------------|
| Start/stop recording | `mic` | `Alt+Q` | Toggle recording on/off |
| Upload audio file | `upload` | — | Choose an audio/video file to transcribe |
| Pause/resume recording | `pause` | — | Pause or resume an active recording |
| Open recording controls | `popup-open` | — | Show the recording modal |
| Fix punctuation and grammar | `wand` | — | Proofread selected text with AI |
| Generate title for current note | `heading` | — | Generate and apply a title |
| Fill property with AI | `pencil` | — | Prompt for a property name, then fill it |
| Fill "summary" property | `list` | — | Directly fill the `summary` property |
| Fill "tags" property | `tags` | — | Directly fill the `tags` property |
---
## URI Protocol
NibbleAI registers the `nibbleai://` protocol handler, allowing external tools to control recording:
| URI | Action |
|-----|--------|
| `obsidian://nibbleai` | Open recording controls |
| `obsidian://nibbleai?command=start` | Start recording |
| `obsidian://nibbleai?command=stop` | Stop recording |
| `obsidian://nibbleai?command=pause` | Pause/resume recording |
| `obsidian://nibbleai?command=cancel` | Cancel recording |
This is useful for automation tools, Stream Deck, or scripting.
---
## Model Selection
Wherever you need to select an AI model (post-processing, proofreading, title generation), NibbleAI provides a **Browse models** button that opens a searchable dialog of available OpenRouter models:
- Models are fetched live from `openrouter.ai/api/v1/models`
- Free models appear first (marked with a **Free** badge)
- Type to filter by name, ID, or description
- You can still type a model ID manually if you prefer
---
## Settings Reference
### API Keys
Securely stored in your system keychain via Obsidian's SecretStorage. Never written to `data.json`.
### Transcription
| Setting | Default | Description |
|---------|---------|-------------|
| API URL | `https://api.openai.com/v1/audio/transcriptions` | Whisper-compatible endpoint |
| Model | `whisper-1` | Transcription model |
| Language | *(empty)* | Language hint (auto-detect if empty) |
| Prompt | *(empty)* | Boosts accuracy for specific terms |
| Cursor context | Off | Send text around cursor as context |
| Temperature | `0` | Sampling temperature (01) |
| Response format | `json` | Output format |
### Recording
| Setting | Default | Description |
|---------|---------|-------------|
| Microphone | Default | Audio input device |
| Save audio file | On | Save recording to vault |
| Audio save path | *(vault root)* | Folder for audio files |
### Output
| Setting | Default | Description |
|---------|---------|-------------|
| Create note file | On | Create a .md file per transcription |
| Note save path | *(vault root)* | Folder for notes |
| Note filename template | `{{datetime}}` | Variables: `{{date}}`, `{{time}}`, `{{datetime}}`, `{{title}}` |
| Note template | `![[{{audioFile}}]]\n{{transcription}}` | Variables: `{{transcription}}`, `{{audioFile}}`, `{{title}}` |
### Post-Processing
| Setting | Default | Description |
|---------|---------|-------------|
| Enable | Off | Clean up transcripts with an LLM |
| Provider | Anthropic | Anthropic, OpenAI, or Custom |
| Model | `claude-sonnet-4-20250514` | LLM for cleanup |
| Auto-generate title | Off | Create filenames from content |
### Proofreading
| Setting | Default | Description |
|---------|---------|-------------|
| Model | `openai/gpt-4o-mini` | Model for proofreading |
| Temperature | `0.2` | Lower = more consistent |
| Max tokens | `2000` | Maximum response length |
| System prompt | *(built-in)* | Editable with prompt injection protections |
### Title Generation
| Setting | Default | Description |
|---------|---------|-------------|
| Mode | Rename file | Rename file or set frontmatter property |
| Max title length | 8 words | Maximum words in generated title |
### Property Filler
| Setting | Default | Description |
|---------|---------|-------------|
| Custom prompt | *(built-in)* | Template with `{property}` placeholder |
| Overwrite existing | Off | Replace existing property values |
---
## Architecture
```
NibbleAI/
├── main.ts # Plugin entry point, commands, events
├── src/
│ ├── SettingsManager.ts # Settings + SecretStorage management
│ ├── AIService.ts # Unified AI client (OpenAI + Anthropic)
│ ├── ModelBrowser.ts # OpenRouter model suggest modal
│ ├── PostProcessor.ts # LLM post-processing for transcripts
│ ├── NibbleAISettingsTab.ts # Settings UI
│ ├── recorder/ # Audio recording (Timer, StatusBar, Controls, AudioRecorder)
│ ├── transcription/ # Whisper API calls + template rendering
│ ├── proofreading/ # Proofreading module
│ ├── title/ # Title generation module
│ └── property/ # Property filling module
└── styles.css # Plugin styles
```
All AI calls go through `AIService.callChatCompletion()`, which handles both OpenAI-compatible and Anthropic-native API formats. Each feature module is self-contained and receives the plugin instance for access to settings and the Obsidian API.
---
## Development
```bash
# Install dependencies
npm install
# Build for production
npm run build
# Watch mode (auto-rebuild on changes)
npm run dev
# Type-check only
npx tsc --noEmit -skipLibCheck
```
Set the `OUTPUT_PATH` environment variable to output `main.js` directly into your vault's plugin directory for fast iteration:
```bash
OUTPUT_PATH=/path/to/your/vault/.obsidian/plugins/nibbleai npm run dev
```
---
## License
MIT
---
*NibbleAI — small bites of AI for your Obsidian vault.*