Initial release v1.0.0
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
# NibbleAI
|
||||
|
||||
> AI-powered tools for your Obsidian vault — speech-to-text, proofreading, title generation, property filling, and more.
|
||||
|
||||
[](https://obsidian.md)
|
||||
[](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 (0–1) |
|
||||
| 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.*
|
||||
Reference in New Issue
Block a user