Transform podcast episodes into structured markdown notes
Project description
Inkwell CLI
Transform podcast episodes into structured, searchable markdown notes for Obsidian.
Inkwell downloads audio from RSS feeds (including private/paid feeds), transcribes content, extracts key information through LLM processing, and optionally conducts an interactive interview to capture personal insights.
Vision: Transform passive podcast listening into active knowledge building by capturing both what was said and what you thought about it.
Status
๐ v1.0.0 - Production Ready!
All core features implemented and thoroughly tested:
- โ Podcast feed management (add, list, remove)
- โ Multi-tier transcription (YouTube โ Gemini)
- โ LLM-based content extraction with templates
- โ Interactive interview mode with Claude
- โ Obsidian integration (wikilinks, tags, Dataview)
- โ Cost tracking and optimization
- โ Error handling with retry logic
- โ Comprehensive E2E testing
- โ Complete user documentation
Quick Start
Installation
# Clone repository
git clone https://github.com/your-username/inkwell-cli.git
cd inkwell-cli
# Install dependencies using uv
uv sync --dev
API Keys
# Set your API keys
export GOOGLE_API_KEY="your-gemini-api-key"
export ANTHROPIC_API_KEY="your-claude-api-key" # Optional, for interview mode
Process Your First Episode
# Add a podcast feed
uv run inkwell add "https://feed.syntax.fm/rss" --name syntax
# Process the latest episode
uv run inkwell fetch syntax --latest
# Output:
# Processing: Modern CSS Features (Episode 789)
# Transcription: YouTube API (free) โ
# Extraction: Gemini Flash โ
# Templates: 4
# Cost: $0.0055
# Output: ./output/syntax-2025-11-13-modern-css-features/
# โ Complete!
That's it! You now have a structured markdown directory ready for Obsidian.
Features
๐๏ธ Smart Transcription
Multi-tier transcription that optimizes for cost and quality:
- Cache (Free): Check local cache first (30-day TTL)
- YouTube (Free): Extract existing transcripts from YouTube videos
- Gemini (Paid): Download audio and transcribe as fallback (~$0.115/episode)
Result: Most episodes cost $0.005-0.012 (YouTube + extraction)
๐ค LLM Content Extraction
Template-based extraction pulls structured information from transcripts:
- Summary: Episode overview with key topics
- Quotes: Memorable quotes with context
- Key Concepts: Main ideas and takeaways
- Context-specific: Tools mentioned, books referenced, people discussed, etc.
Obsidian Features:
- Wikilinks: Auto-generated
[[links]]for entities (books, people, concepts) - Tags: Smart tag generation using LLM (e.g.,
#productivity,#ai,#health) - Dataview: Rich frontmatter for Obsidian Dataview queries
๐ฌ Interactive Interview Mode
Capture your thoughts while the episode is fresh:
uv run inkwell fetch syntax --latest --interview
Claude will ask you questions like:
- "What stood out most to you?"
- "How might you apply these ideas?"
- "What questions do you still have?"
Your responses are saved in my-notes.md within the episode directory.
๐ฐ Cost Tracking
Know exactly what you're spending:
# View overall spending
uv run inkwell costs
# View recent operations
uv run inkwell costs --recent 10
# Filter by provider
uv run inkwell costs --provider gemini --days 30
# See today's costs
uv run inkwell costs --days 1
Typical Costs:
- YouTube + Gemini extraction: $0.005-0.012
- Gemini transcription + extraction: $0.115-0.175
- Recommendation: Use YouTube when available (saves 95%)
๐ Obsidian Integration
Every episode output includes:
Frontmatter (Dataview-compatible):
---
podcast: Syntax FM
episode: Modern CSS Features
episode_date: 2025-11-13
duration_minutes: 42
rating: null
topics: [css, web-development, frontend]
people: [Wes Bos, Scott Tolinski]
tools: [CSS Grid, Flexbox, Container Queries]
books: []
tags: [podcast, technical, web-development]
---
Wikilinks: Automatic [[Entity]] links for discoverability
Tags: Smart contextual tags (#css, #web-development, etc.)
Dataview Queries: See docs/dataview-queries.md for 27 example queries
๐ Robust Error Handling
Automatic retry with exponential backoff:
- API failures: 3 attempts with backoff
- Rate limits: Intelligent retry timing
- Network errors: Automatic recovery
- Transient failures: Handled gracefully
Graceful degradation: If YouTube fails, falls back to Gemini
๐งช Comprehensive Testing
- Unit Tests: 180+ tests covering all components
- Integration Tests: 30+ tests for end-to-end workflows
- E2E Tests: 7 tests validating complete pipeline
- Total: 200+ tests with extensive coverage
E2E Test Coverage:
- 5 diverse content types (technical, interview, discussion, educational, storytelling)
- Duration range: 15-90 minutes
- Quality validation: Files, frontmatter, wikilinks, tags
- Cost benchmarking: Expected vs actual costs
Documentation
For Users
- Tutorial: 10-minute walkthrough for beginners
- User Guide: Complete reference documentation
- Examples & Workflows: Common use cases and automation
- Dataview Queries: 27 example Obsidian queries
For Developers
- Developer Knowledge System: Complete DKS overview
- Architecture Decision Records: Design decisions and rationale
- Development Logs: Implementation journals
- Lessons Learned: Retrospectives and insights
- Research Docs: Technology research notes
Basic Usage
Feed Management
# Add a podcast
uv run inkwell add "https://feed.syntax.fm/rss" --name syntax
# Add with authentication
uv run inkwell add "https://private.com/feed.rss" --name premium --auth
# List your podcasts
uv run inkwell list
# Remove a podcast
uv run inkwell remove syntax
Processing Episodes
# Process latest episode
uv run inkwell fetch syntax --latest
# Process specific episode number
uv run inkwell fetch syntax --episode 789
# Process multiple episodes
uv run inkwell fetch syntax --count 5
# Process with interview mode
uv run inkwell fetch syntax --latest --interview
# Overwrite existing output
uv run inkwell fetch syntax --latest --overwrite
# Use specific provider
uv run inkwell fetch syntax --latest --provider claude
Cost Management
# View all costs
uv run inkwell costs
# View last 10 operations
uv run inkwell costs --recent 10
# View by date range
uv run inkwell costs --days 7
# Filter by provider
uv run inkwell costs --provider gemini
# Filter by operation
uv run inkwell costs --operation transcription
# Clear cost history
uv run inkwell costs --clear
Cache Management
# View cache stats
uv run inkwell cache stats
# Clear all cache
uv run inkwell cache clear
# Clear expired only
uv run inkwell cache clear-expired
Output Structure
Each processed episode creates a directory:
output/
โโโ podcast-name-YYYY-MM-DD-episode-title/
โโโ .metadata.yaml # Episode metadata and cost tracking
โโโ summary.md # Episode summary with frontmatter
โโโ quotes.md # Memorable quotes with context
โโโ key-concepts.md # Main ideas and concepts
โโโ tools-mentioned.md # Tools, software, frameworks
โโโ books-mentioned.md # Books and resources
โโโ people-mentioned.md # People discussed
โโโ my-notes.md # Your interview responses (if --interview)
Frontmatter (all .md files):
---
podcast: Syntax FM
episode: Modern CSS Features
episode_date: 2025-11-13
duration_minutes: 42
topics: [css, web-development]
people: [Wes Bos, Scott Tolinski]
tags: [podcast, technical, web-development]
---
Wikilinks embedded in content:
- Books:
[[Atomic Habits]] - People:
[[James Clear]] - Concepts:
[[Habit Stacking]]
Requirements
- Python: 3.10 or higher
- ffmpeg: Required for audio processing
- API Keys:
- Google AI (Gemini) API key (required)
- Anthropic (Claude) API key (optional, for interview mode)
Configuration
Inkwell uses XDG Base Directory specifications:
- Config:
~/.config/inkwell/config.yaml - Feeds:
~/.config/inkwell/feeds.yaml - Costs:
~/.config/inkwell/costs.json - Cache:
~/.cache/inkwell/transcripts/ - Logs:
~/.local/state/inkwell/inkwell.log
Configuration Options
Edit ~/.config/inkwell/config.yaml:
version: "1"
log_level: INFO
default_output_dir: ./output
default_provider: gemini # or "claude"
youtube_check: true
max_episodes_per_run: 10
# Optional API keys (or use environment variables)
gemini_api_key: ""
anthropic_api_key: ""
# Templates to enable
templates_enabled:
- summary
- quotes
- key-concepts
- tools-mentioned
- books-mentioned
- people-mentioned
# Obsidian features
wikilinks_enabled: true
tags_enabled: true
dataview_frontmatter: true
Editing Configuration
You can edit the configuration file directly using inkwell config edit:
# Edit config file in your default editor
uv run inkwell config edit
Supported Editors: atom, code, ed, emacs, gedit, helix, kate, micro, nano, notepad, notepad++, nvim, subl, vi, vim
Set your preferred editor with the EDITOR environment variable:
export EDITOR=vim
uv run inkwell config edit
For security reasons, only whitelisted editors are supported. If you need to use a different editor, you can edit the config file manually:
# View config location
uv run inkwell config show
# Edit manually
nano ~/.config/inkwell/config.yaml
Architecture
High-Level Pipeline
RSS Feed โ Parse Episodes โ Check YouTube โ Download Audio
โ Transcribe (YouTube or Gemini)
โ Extract Content (Template-based LLM)
โ Generate Wikilinks & Tags
โ [Optional] Interactive Interview
โ Generate Markdown Files
โ Save to Output Directory
Key Components
-
Feed Management (
src/inkwell/feeds/)- RSS/Atom parsing with authentication
- Secure credential encryption
-
Transcription (
src/inkwell/transcription/)- YouTube transcript extraction (free)
- Gemini API fallback (paid)
- 30-day cache with TTL
-
Extraction (
src/inkwell/extraction/)- Template-based LLM prompts
- Multi-provider support (Gemini, Claude)
- Context-aware extraction
-
Obsidian Integration (
src/inkwell/obsidian/)- Wikilink generation from entities
- Smart tag generation with LLM
- Dataview-compatible frontmatter
-
Interview Mode (
src/inkwell/interview/)- Claude Agent SDK integration
- Interactive Q&A with streaming
- Personal insights capture
-
Cost Tracking (
src/inkwell/utils/costs.py)- Per-operation cost calculation
- JSON-based persistence
- Filtering and aggregation
-
Error Handling (
src/inkwell/utils/retry.py)- Exponential backoff with jitter
- Automatic retry for transient failures
- Graceful degradation
Project Structure
inkwell-cli/
โโโ src/inkwell/ # Main package
โ โโโ cli.py # CLI entry point
โ โโโ config/ # Configuration management
โ โโโ feeds/ # RSS parsing
โ โโโ transcription/ # Transcription system
โ โโโ audio/ # Audio download
โ โโโ extraction/ # LLM extraction (Phase 3)
โ โโโ obsidian/ # Obsidian integration (Phase 5)
โ โโโ interview/ # Interview mode (Phase 4)
โ โโโ utils/ # Utilities (costs, retry, etc.)
โโโ tests/ # Test suite (200+ tests)
โ โโโ unit/ # Unit tests
โ โโโ integration/ # Integration tests
โ โโโ e2e/ # End-to-end tests
โโโ docs/ # Documentation (DKS)
โ โโโ adr/ # Architecture decisions
โ โโโ devlog/ # Development logs
โ โโโ lessons/ # Lessons learned
โ โโโ research/ # Research notes
โ โโโ experiments/ # Benchmarks
โ โโโ user-guide.md # Complete user reference
โ โโโ tutorial.md # 10-minute tutorial
โ โโโ examples.md # Workflows and examples
โ โโโ dataview-queries.md # Obsidian Dataview examples
โโโ templates/ # LLM extraction templates
โโโ summary.md
โโโ quotes.md
โโโ key-concepts.md
โโโ ...
Development
Setup Development Environment
# Install development dependencies
uv sync --dev
# Install pre-commit hooks
uv run pre-commit install
# Run tests
uv run pytest
# Run with coverage
uv run pytest --cov=inkwell --cov-report=html
# Run linting
uv run ruff check .
# Format code
uv run ruff format .
# Type checking
uv run mypy src/
Running Tests
# Run all tests
uv run pytest
# Run specific test types
uv run pytest tests/unit/ # Unit tests
uv run pytest tests/integration/ # Integration tests
uv run pytest tests/e2e/ # E2E tests
# Run with verbose output
uv run pytest -v
# Run specific test file
uv run pytest tests/unit/test_costs.py -v
Code Quality Standards
This project maintains high code quality:
- Type hints: Full coverage with mypy validation
- Linting: Ruff for code style
- Testing: 200+ tests with extensive coverage
- Documentation: Comprehensive DKS documentation
- Error handling: Robust retry logic
- Performance: Benchmarked and optimized
Roadmap
โ Phase 1: Foundation (Complete)
- โ Project scaffolding and build system
- โ Configuration management with encryption
- โ RSS feed parsing and validation
- โ CLI with rich terminal output
- โ Comprehensive test suite
โ Phase 2: Transcription (Complete)
- โ YouTube transcript API integration
- โ Google Gemini fallback transcription
- โ Audio download with yt-dlp
- โ Transcript caching with TTL
- โ Multi-tier orchestration with cost optimization
โ Phase 3: LLM Extraction (Complete)
- โ Template-based LLM prompts
- โ Content extraction (quotes, concepts, etc.)
- โ Markdown generation
- โ Metadata management
- โ Multi-provider support (Gemini, Claude)
โ Phase 4: Interactive Interview (Complete)
- โ Claude Agent SDK integration
- โ Interactive Q&A mode with streaming
- โ Personal insights capture
- โ Interview transcript storage
โ Phase 5: Obsidian Integration (Complete)
- โ Wikilink generation from entities
- โ Smart tag generation with LLM
- โ Dataview-compatible frontmatter
- โ Cost tracking system
- โ Error handling with retry logic
- โ E2E test framework
- โ Complete user documentation
๐ฎ Future Enhancements
- Custom templates and prompts
- Batch processing automation
- Export formats (PDF, HTML)
- Web dashboard for management
- Mobile app integration
- Community template marketplace
Contributing
We welcome contributions! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes with tests
- Run tests and linting (
uv run pytest && uv run ruff check .) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
See CLAUDE.md for development guidelines.
License
MIT License - See LICENSE file for details.
Acknowledgments
Core Libraries:
- typer: CLI framework
- rich: Terminal formatting
- pydantic: Data validation
- feedparser: RSS/Atom parsing
- yt-dlp: Audio download
- google-generativeai: Gemini API
- anthropic: Claude API
- claude-agent-sdk: Interactive interview mode
Special Thanks:
- The Obsidian community for inspiration
- Claude (Anthropic) for development assistance
- All podcast creators who make great content
Support
- Issues: GitHub Issues
- Documentation: See
docs/directory - Tutorial: docs/tutorial.md
- User Guide: docs/user-guide.md
- Examples: docs/examples.md
Built with โค๏ธ for knowledge workers who love podcasts.
Transform passive listening into active learning.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file inkwell_cli-0.17.1.tar.gz.
File metadata
- Download URL: inkwell_cli-0.17.1.tar.gz
- Upload date:
- Size: 1.6 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c6994de1d57875c7724470b05638ab9b35f7aea93b3b3fa6243226d0c7b5dc71
|
|
| MD5 |
d6b15c921719dabf6448377f2638d030
|
|
| BLAKE2b-256 |
42caf88990c7a9db57212cb262149333bdaa7878daf27611eedcb580305fcc50
|
Provenance
The following attestation bundles were made for inkwell_cli-0.17.1.tar.gz:
Publisher:
publish.yml on chekos/inkwell-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
inkwell_cli-0.17.1.tar.gz -
Subject digest:
c6994de1d57875c7724470b05638ab9b35f7aea93b3b3fa6243226d0c7b5dc71 - Sigstore transparency entry: 799134837
- Sigstore integration time:
-
Permalink:
chekos/inkwell-cli@a6d9b43926054bf334989beac2ac970837e3c4dc -
Branch / Tag:
refs/tags/v0.17.1 - Owner: https://github.com/chekos
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a6d9b43926054bf334989beac2ac970837e3c4dc -
Trigger Event:
release
-
Statement type:
File details
Details for the file inkwell_cli-0.17.1-py3-none-any.whl.
File metadata
- Download URL: inkwell_cli-0.17.1-py3-none-any.whl
- Upload date:
- Size: 179.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0add2782a7d37e3815bf45c108b1ee21eb15f77ced42857cc6e05a124a7ebb84
|
|
| MD5 |
277489366145199ee9ed6f77745bf0b6
|
|
| BLAKE2b-256 |
6c894170b314ec3167e9886c2d6e8eb21074da31d7d9b700f4da89c353efd40f
|
Provenance
The following attestation bundles were made for inkwell_cli-0.17.1-py3-none-any.whl:
Publisher:
publish.yml on chekos/inkwell-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
inkwell_cli-0.17.1-py3-none-any.whl -
Subject digest:
0add2782a7d37e3815bf45c108b1ee21eb15f77ced42857cc6e05a124a7ebb84 - Sigstore transparency entry: 799134839
- Sigstore integration time:
-
Permalink:
chekos/inkwell-cli@a6d9b43926054bf334989beac2ac970837e3c4dc -
Branch / Tag:
refs/tags/v0.17.1 - Owner: https://github.com/chekos
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a6d9b43926054bf334989beac2ac970837e3c4dc -
Trigger Event:
release
-
Statement type: