Initial release v1.0.0

This commit is contained in:
2026-05-24 21:27:01 -04:00
commit af45cc762c
22 changed files with 3629 additions and 0 deletions
+254
View File
@@ -0,0 +1,254 @@
# 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.*