diff --git a/docs/cli/README.md b/docs/cli/README.md index 36dc4f7..65ed54b 100644 --- a/docs/cli/README.md +++ b/docs/cli/README.md @@ -6,13 +6,12 @@ This directory contains automatically generated CLI reference documentation for - [index.md](index.md) - Main CLI reference with overview of all commands - [about.md](about.md) - About command documentation -- [castchat.md](castchat.md) - Interactive AI chat documentation -- [config.md](config.md) - Configuration management documentation +- [chat.md](chat.md) - Interactive AI chat documentation +- [configure.md](configure.md) - Configuration management documentation - [download.md](download.md) - Episode download documentation -- [meta.md](meta.md) - Metadata download documentation -- [sql.md](sql.md) - SQL query documentation -- [sync.md](sync.md) - Synchronization documentation -- [transcription.md](transcription.md) - Transcription documentation +- [query.md](query.md) - SQL query documentation +- [subscribe.md](subscribe.md) - Subscription synchronization documentation +- [transcribe.md](transcribe.md) - Transcription documentation ## Generating Documentation diff --git a/docs/cli/castchat.md b/docs/cli/castchat.md deleted file mode 100644 index f1206b8..0000000 --- a/docs/cli/castchat.md +++ /dev/null @@ -1,110 +0,0 @@ -# castchat - Interactive AI Chat - -The `castchat` command starts an interactive AI-powered REPL session for exploring your podcast transcription archive using natural language queries. - -## Command Help - - -``` -Usage: cli castchat [OPTIONS] - - Interactive AI chat for exploring transcribed podcast content. - - Start an interactive REPL session powered by PydanticAI to explore your - podcast transcription archive using natural language queries. The agent can - search across all transcribed episodes to answer questions about topics, - guests, and specific content. - - Requires chromadb and pydantic-ai dependencies: pip install - retrocast[castchat] - - Example queries: - What episodes discussed machine learning? - Where did - they talk about climate change? - Which episodes featured interviews with - scientists? - -Options: - -d, --database PATH Path to retrocast database (defaults to app directory - database) - -m, --model TEXT Anthropic model to use for the agent - --rebuild-index Rebuild the ChromaDB index from scratch - --help Show this message and exit. - -``` - - -## Requirements - -The castchat feature requires optional dependencies: - -```bash -pip install retrocast[castchat] -``` - -This installs: -- `chromadb` - Vector database for semantic search -- `pydantic-ai` - AI agent framework - -## Usage - -### Basic Usage - -Start an interactive chat session: - -```bash -retrocast castchat -``` - -### With Custom Database - -Specify a custom database location: - -```bash -retrocast castchat --database /path/to/database.db -``` - -### With Custom Model - -Use a specific Anthropic model: - -```bash -retrocast castchat --model claude-3-5-sonnet-20241022 -``` - -### Rebuild Index - -Rebuild the ChromaDB index from scratch: - -```bash -retrocast castchat --rebuild-index -``` - -## Example Queries - -Once in the interactive session, you can ask questions like: - -- "What episodes discussed machine learning?" -- "Where did they talk about climate change?" -- "Which episodes featured interviews with scientists?" -- "Find episodes about Python programming" -- "What did they say about AI ethics?" - -The agent searches across all transcribed episodes to find relevant content and provide contextualized answers. - -## How It Works - -1. **Indexing**: Transcriptions are indexed in a ChromaDB vector database -2. **Query Processing**: Your questions are converted to semantic embeddings -3. **Search**: Similar content is retrieved using vector similarity -4. **AI Response**: An AI agent synthesizes the information into a natural language answer - -## Tips - -- Be specific in your questions for better results -- The quality of answers depends on having transcribed episodes -- Use the `--rebuild-index` flag if you've added new transcriptions -- The agent has context about your entire podcast archive diff --git a/docs/cli/chat.md b/docs/cli/chat.md new file mode 100644 index 0000000..bcaa06e --- /dev/null +++ b/docs/cli/chat.md @@ -0,0 +1,36 @@ +# chat - Interactive AI Chat + +The `chat` command starts the agentic AI chat experience for transcribed content. + + +``` +Usage: cli chat [OPTIONS] + + Interactive AI chat for exploring transcribed podcast content. + + Start an interactive REPL session powered by PydanticAI to explore your + podcast transcription archive using natural language queries. The agent can + search across all transcribed episodes to answer questions about topics, + guests, and specific content. + + Requires chromadb and pydantic-ai dependencies: pip install + retrocast[castchat] + + Example queries: - What episodes discussed machine learning? - Where did + they talk about climate change? - Which episodes featured interviews with + scientists? + +Options: + -d, --database PATH Path to retrocast database (defaults to app directory + database) + -m, --model TEXT Anthropic model to use for the agent + --rebuild-index Rebuild the ChromaDB index from scratch + --help Show this message and exit. + +``` + diff --git a/docs/cli/config.md b/docs/cli/config.md deleted file mode 100644 index c668851..0000000 --- a/docs/cli/config.md +++ /dev/null @@ -1,237 +0,0 @@ -# config - Manage Configuration - -The `config` command group manages the retrocast configuration directory and database. - -## Command Group Help - - -``` -Usage: cli config [OPTIONS] COMMAND [ARGS]... - - Manage the retrocast configuration data - -Options: - --help Show this message and exit. - -Commands: - archive Archive the configuration directory as a gzipped tarball - check Report configuration status without making changes - initialize Create the retrocast configuration directory - location Output the location of the configuration directory. - reset-db Reset the database schema (WARNING: destroys all data) - -``` - - -## Subcommands - -### archive - Archive Configuration - -Create a compressed backup of your configuration directory. - - -``` -Usage: cli config archive [OPTIONS] - - Archive the configuration directory as a gzipped tarball - -Options: - -o, --output FILE Destination for the gzipped archive. Writes to - stdout when omitted. - -c, --compression-level INTEGER RANGE - Gzip compression level (0-9). [default: 6; - 0<=x<=9] - -f, --force Overwrite the output archive if it exists. - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -retrocast config archive -``` - -Creates a gzipped tarball of your configuration directory in your home directory. - -### check - Check Status - -Check the status of your configuration and database without making changes. - - -``` -Usage: cli config check [OPTIONS] - - Report configuration status without making changes - -Options: - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -retrocast config check -``` - -Reports on: -- Configuration directory location -- Database file existence and location -- Authentication status - -### initialize - Initialize Configuration - -Create the retrocast configuration directory and database. - - -``` -Usage: cli config initialize [OPTIONS] - - Create the retrocast configuration directory - -Options: - -y, --yes Create the directory without confirmation prompts. - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -retrocast config initialize -``` - -Creates the configuration directory structure in the XDG data directory (typically `~/.local/share/net.memexponent.retrocast/` on Linux). - -### location - Show Location - -Display the path to your configuration directory. - - -``` -Usage: cli config location [OPTIONS] - - Output the location of the configuration directory. - - By default, displays a formatted table showing all configuration paths. Use - --format json to output all paths as a JSON object. Use --db-path to output - only the database path as a JSON string. Use --app-dir to output only the app - directory path as a JSON string. - - Examples: retrocast config location # Table view - retrocast config location --format json # All paths as JSON retrocast - config location --db-path # Just database path retrocast config - location --app-dir # Just app directory - -Options: - -f, --format [console|json] - -d, --db-path Output only the database path as a JSON string - -a, --app-dir Output only the app directory path as a JSON - string - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -retrocast config location -``` - -Outputs the absolute path to your configuration directory. - -### reset-db - Reset Database - -Reset the database schema, destroying all existing data. - - -``` -Usage: cli config reset-db [OPTIONS] - - Reset the database schema (WARNING: destroys all data) - -Options: - --dry-run Show what would be reset without actually performing the reset. - -y, --yes Skip confirmation prompt and proceed with reset. - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -retrocast config reset-db -``` - -**⚠️ WARNING:** This command destroys all data in the database. Use with caution and only when you want to start fresh. - -## Configuration Directory - -The configuration directory contains: -- `retrocast.db` - SQLite database with podcast metadata -- `auth.json` - Overcast authentication credentials -- `episode_downloads/` - Downloaded episode files -- `transcripts/` - Episode transcription files -- `chapters/` - Chapter information - -## Examples - -Check if your setup is ready: - -```bash -retrocast config check -``` - -Initialize a fresh installation: - -```bash -retrocast config initialize -``` - -Find your configuration directory: - -```bash -retrocast config location -``` - -Backup your configuration before major changes: - -```bash -retrocast config archive -``` diff --git a/docs/cli/configure.md b/docs/cli/configure.md new file mode 100644 index 0000000..7fb89b9 --- /dev/null +++ b/docs/cli/configure.md @@ -0,0 +1,27 @@ +# configure - Manage Configuration + +The `configure` command group manages local retrocast configuration and database setup. + + +``` +Usage: cli configure [OPTIONS] COMMAND [ARGS]... + + Manage the retrocast configuration data + +Options: + --help Show this message and exit. + +Commands: + archive Archive the configuration directory as a gzipped tarball + check Report configuration status without making changes + initialize Create the retrocast configuration directory + location Output the location of the configuration directory. + reset-db Reset the database schema (WARNING: destroys all data) + +``` + diff --git a/docs/cli/index.md b/docs/cli/index.md index dcf3ad1..968bd7b 100644 --- a/docs/cli/index.md +++ b/docs/cli/index.md @@ -22,14 +22,14 @@ Options: --help Show this message and exit. Commands: - about* Display information about retrocast - castchat Interactive AI chat for exploring transcribed podcast... - config Manage the retrocast configuration data - download Download episode content with pluggable backends - meta Download episode metadata and derived information - sql Query and inspect SQLite database - sync Synchronize subscription metadata - transcription Manage audio transcriptions (create, search, analyze). + about* Display information about retrocast + chat Interactive AI chat for exploring transcribed podcast content. + configure Manage the retrocast configuration data + download Download episode content with pluggable backends + index Create and manage search indexes + query Query and inspect SQLite database + subscribe Manage feed subscriptions + transcribe Manage audio transcriptions (create, search, analyze). ``` @@ -37,10 +37,10 @@ Commands: ## Available Command Groups - [about](about.md) - Display information about retrocast -- [castchat](castchat.md) - Interactive AI chat for exploring transcribed podcasts -- [config](config.md) - Manage retrocast configuration +- [chat](chat.md) - Interactive AI chat for exploring transcribed podcasts +- [configure](configure.md) - Manage retrocast configuration - [download](download.md) - Download episode content -- [meta](meta.md) - Download episode metadata -- [sql](sql.md) - Query and inspect SQLite database -- [sync](sync.md) - Synchronize subscription metadata -- [transcription](transcription.md) - Manage audio transcriptions +- [query](query.md) - Query and inspect SQLite database +- [subscribe](subscribe.md) - Synchronize subscription metadata +- [transcribe](transcribe.md) - Manage audio transcriptions +- [index](index.md) - Create and manage search indexes diff --git a/docs/cli/meta.md b/docs/cli/meta.md deleted file mode 100644 index 14d3ace..0000000 --- a/docs/cli/meta.md +++ /dev/null @@ -1,167 +0,0 @@ -# meta - Download Episode Metadata - -The `meta` command group provides tools for downloading episode metadata and derived information. - -## Command Group Help - - -``` -Usage: cli meta [OPTIONS] COMMAND [ARGS]... - - Download episode metadata and derived information - -Options: - --help Show this message and exit. - -Commands: - overcast Retrieve episode metadata and information via overcast plugin - -``` - - -## Subcommands - -### overcast - Overcast Metadata - -Retrieve episode metadata via the Overcast plugin. - - -``` -Usage: cli meta overcast [OPTIONS] COMMAND [ARGS]... - - Retrieve episode metadata and information via overcast plugin - -Options: - --help Show this message and exit. - -Commands: - chapters Download and store available chapters for all or starred... - transcripts Download available transcripts for all or starred episodes. - -``` - - -#### overcast chapters - Download Chapters - -Download and store available chapters for episodes. - - -``` -Usage: cli meta overcast chapters [OPTIONS] - - Download and store available chapters for all or starred episodes. - -Options: - -d, --database FILE Path to database file (defaults to retrocast.db in app - directory) - -p, --path DIRECTORY - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -# Download chapters for all episodes -retrocast meta overcast chapters -``` - -#### overcast transcripts - Download Transcripts - -Download available transcripts for episodes. - - -``` -Usage: cli meta overcast transcripts [OPTIONS] - - Download available transcripts for all or starred episodes. - -Options: - -d, --database FILE Path to database file (defaults to retrocast.db in app - directory) - -p, --path DIRECTORY - -s, --starred-only - -v, --verbose - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -# Download transcripts for all episodes -retrocast meta overcast transcripts - -# Download transcripts for starred episodes only -retrocast meta overcast transcripts --starred-only -``` - -## What Are Chapters? - -Podcast chapters are markers in audio files that divide an episode into segments. They can include: -- Chapter titles -- Start times -- URLs and images -- Descriptions - -## What Are Transcripts? - -Some podcasts provide pre-generated transcripts in various formats (VTT, SRT, JSON). These transcripts contain: -- Time-stamped text of spoken content -- Speaker labels (in some cases) -- Word-level timing (in some formats) - -## Examples - -### Download All Chapters - -```bash -retrocast meta overcast chapters -``` - -### Download Transcripts - -```bash -retrocast meta overcast transcripts -``` - -### Download Transcripts for Starred Episodes - -```bash -retrocast meta overcast transcripts --starred-only -``` - -## Storage - -Downloaded metadata is stored in: -- **Chapters**: Database table `chapters` -- **Transcripts**: `~/.local/share/net.memexponent.retrocast/transcripts/` directory - -## Notes - -- Chapter and transcript availability depends on the podcast feed -- Not all podcasts provide chapters or transcripts -- Chapters are embedded in the RSS feed or audio file metadata -- Transcripts may be provided as separate files linked in the feed diff --git a/docs/cli/query.md b/docs/cli/query.md new file mode 100644 index 0000000..f4678ad --- /dev/null +++ b/docs/cli/query.md @@ -0,0 +1,70 @@ +# query - Query Databases + +The `query` command group provides database querying and inspection utilities. + + +``` +Usage: cli query [OPTIONS] COMMAND [ARGS]... + +Query and inspect SQLite database + +These commands provide read-only access to your scrobbledb database +using the sqlite-utils CLI. The database path defaults to your +scrobbledb database in the XDG data directory. + +Default Database Location: + {PLATFORM_APP_DIR}/retrocast.db + + +To check if your database is initialized: + scrobbledb init --dry-run + +Core Scrobble Data Tables: + artists - Artist information (id, name) + albums - Album information (id, title, artist_id) + tracks - Track information (id, title, album_id) + plays - Play events (track_id, timestamp) + +Examples: + + # Query the database + scrobbledb sql query "SELECT * FROM tracks LIMIT 10" + + # List all tables with row counts + scrobbledb sql tables --counts + + # View table schema + scrobbledb sql schema tracks + + # Browse table data + scrobbledb sql rows plays --limit 20 + + # Use a different database + scrobbledb sql query "SELECT * FROM users" --database /path/to/other.db + +Options: + -d, --database FILE Database path (default: scrobbledb database in XDG data + dir) + --help Show this message and exit. + +Commands: + analyze-tables Analyze the columns in one or more tables. + dump Output a SQL dump of the schema and full contents of the... + indexes Show indexes for the whole database or specific tables. + memory Execute SQL query against an in-memory database,... + plugins List installed sqlite-utils plugins. + query Execute SQL query and return the results as JSON. + rows Output all rows in the specified table. + schema Show full schema for this database or for specified tables. + search Execute a full-text search against this table. + tables List the tables in the database. + triggers Show triggers configured in this database. + views List the views in the database. + +``` + diff --git a/docs/cli/sql.md b/docs/cli/sql.md deleted file mode 100644 index e0ba3e3..0000000 --- a/docs/cli/sql.md +++ /dev/null @@ -1,626 +0,0 @@ -# sql - Query SQLite Database - -The `sql` command group provides read-only access to query and inspect your retrocast SQLite database using the sqlite-utils CLI. - -## Command Group Help - - -``` -Usage: cli sql [OPTIONS] COMMAND [ARGS]... - -Query and inspect SQLite database - -These commands provide read-only access to your scrobbledb database -using the sqlite-utils CLI. The database path defaults to your -scrobbledb database in the XDG data directory. - -Default Database Location: - {PLATFORM_APP_DIR}/retrocast.db - - -To check if your database is initialized: - scrobbledb init --dry-run - -Core Scrobble Data Tables: - artists - Artist information (id, name) - albums - Album information (id, title, artist_id) - tracks - Track information (id, title, album_id) - plays - Play events (track_id, timestamp) - -Examples: - - # Query the database - scrobbledb sql query "SELECT * FROM tracks LIMIT 10" - - # List all tables with row counts - scrobbledb sql tables --counts - - # View table schema - scrobbledb sql schema tracks - - # Browse table data - scrobbledb sql rows plays --limit 20 - - # Use a different database - scrobbledb sql query "SELECT * FROM users" --database /path/to/other.db - -Options: - -d, --database FILE Database path (default: scrobbledb database in XDG data - dir) - --help Show this message and exit. - -Commands: - analyze-tables Analyze the columns in one or more tables. - dump Output a SQL dump of the schema and full contents of the... - indexes Show indexes for the whole database or specific tables. - memory Execute SQL query against an in-memory database,... - plugins List installed sqlite-utils plugins. - query Execute SQL query and return the results as JSON. - rows Output all rows in the specified table. - schema Show full schema for this database or for specified tables. - search Execute a full-text search against this table. - tables List the tables in the database. - triggers Show triggers configured in this database. - views List the views in the database. - -``` - - -## Database Location - -Default database location: -``` -~/.local/share/net.memexponent.retrocast/retrocast.db -``` - -## Core Database Tables - -### Subscription Data -- `feeds` - Podcast feed information from Overcast -- `feeds_extended` - Extended metadata from full RSS feeds -- `episodes` - Episode information from Overcast -- `episodes_extended` - Extended episode metadata from RSS -- `playlists` - Overcast playlist information - -### Additional Data -- `chapters` - Episode chapter markers -- `episode_downloads` - Downloaded episode tracking - -### Views -- `episodes_played` - Filtered view of played episodes -- `episodes_deleted` - Filtered view of deleted episodes -- `episodes_starred` - Filtered view of starred episodes - -## Subcommands - -### analyze-tables - Analyze Columns - -Analyze the columns in database tables. - - -``` -Usage: cli sql analyze-tables [OPTIONS] [TABLES]... - - Analyze the columns in one or more tables. - - Example: - - scrobbledb sql analyze-tables tracks - scrobbledb sql analyze-tables tracks -c artist_name - -Options: - -c, --column TEXT Specific columns to analyze - --save Save results to _analyze_tables table - --common-limit INTEGER How many common values to return for each column - (default 10) - --no-most Skip most common values - --no-least Skip least common values - --load-extension TEXT Path to SQLite extension, with optional :entrypoint - --help Show this message and exit. - -``` - - -### dump - Export Database - -Output a SQL dump of the schema and contents. - - -``` -Usage: cli sql dump [OPTIONS] - - Output a SQL dump of the schema and full contents of the database. - - Example: - - scrobbledb sql dump > backup.sql - -Options: - --load-extension TEXT Path to SQLite extension, with optional :entrypoint - --help Show this message and exit. - -``` - - -### indexes - Show Indexes - -Show indexes for the database or specific tables. - - -``` -Usage: cli sql indexes [OPTIONS] [TABLES]... - - Show indexes for the whole database or specific tables. - - Example: - - scrobbledb sql indexes - scrobbledb sql indexes tracks - -Options: - --aux Include auxiliary columns - --nl Output newline-delimited JSON - --arrays Output rows as arrays instead of objects - --csv Output CSV - --tsv Output TSV - --no-headers Omit CSV headers - -t, --table Output as a formatted table - --fmt TEXT Table format - see tabulate documentation for available - formats - --json-cols Detect JSON cols and output them as JSON, not escaped - strings - --load-extension TEXT Path to SQLite extension, with optional :entrypoint - --help Show this message and exit. - -``` - - -### memory - In-Memory Query - -Execute SQL query against an in-memory database. - - -``` -Usage: cli sql memory [OPTIONS] [PATHS]... SQL_QUERY - - Execute SQL query against an in-memory database, optionally populated by - imported data. - - Example: - - scrobbledb sql memory data.csv "SELECT * FROM data LIMIT 10" - -Options: - --functions TEXT Python code defining one or more custom SQL - functions - --attach ... Additional databases to attach - specify alias and - filepath - --flatten Flatten nested JSON objects, so {"foo": {"bar": - 1}} becomes {"foo_bar": 1} - --nl Output newline-delimited JSON - --arrays Output rows as arrays instead of objects - --csv Output CSV - --tsv Output TSV - --no-headers Omit CSV headers - -t, --table Output as a formatted table - --fmt TEXT Table format - see tabulate documentation for - available formats - --json-cols Detect JSON cols and output them as JSON, not - escaped strings - -r, --raw Raw output, first column of first row - --raw-lines Raw output, first column of each row - -p, --param ... Named :parameters for SQL query - --encoding TEXT Character encoding for CSV files - --no-detect-types Treat all CSV columns as TEXT - --schema Show SQL schema for in-memory database - --dump Dump SQL for in-memory database - --save FILE Save in-memory database to this file - --analyze Analyze resulting tables - --load-extension TEXT Path to SQLite extension, with optional - :entrypoint - --help Show this message and exit. - -``` - - -### plugins - List Plugins - -List installed sqlite-utils plugins. - - -``` -Usage: cli sql plugins [OPTIONS] - - List installed sqlite-utils plugins. - - Example: - - scrobbledb sql plugins - -Options: - --help Show this message and exit. - -``` - - -### query - Execute SQL - -Execute SQL query and return results as JSON. - - -``` -Usage: cli sql query [OPTIONS] SQL_QUERY - - Execute SQL query and return the results as JSON. - - Example: - - scrobbledb sql query "SELECT * FROM tracks WHERE artist_id = :id LIMIT 10" -p id 123 - -Options: - --attach ... Additional databases to attach - specify alias and - filepath - --nl Output newline-delimited JSON - --arrays Output rows as arrays instead of objects - --csv Output CSV - --tsv Output TSV - --no-headers Omit CSV headers - -t, --table Output as a formatted table - --fmt TEXT Table format - see tabulate documentation for - available formats - --json-cols Detect JSON cols and output them as JSON, not - escaped strings - -r, --raw Raw output, first column of first row - --raw-lines Raw output, first column of each row - -p, --param ... Named :parameters for SQL query - --functions TEXT Python code defining one or more custom SQL - functions - --load-extension TEXT Path to SQLite extension, with optional - :entrypoint - --help Show this message and exit. - -``` - - -### rows - Browse Table Data - -Output all rows in a table. - - -``` -Usage: cli sql rows [OPTIONS] TABLE_NAME - - Output all rows in the specified table. - - Example: - - scrobbledb sql rows plays --limit 20 - scrobbledb sql rows tracks -c artist_name -c track_title --limit 10 - scrobbledb sql rows plays --where "timestamp > :date" -p date 2024-01-01 - - Security Note: The --where and --order options accept raw SQL. Use --param - for untrusted user data to prevent SQL injection. Column and table names - are automatically quoted. - -Options: - -c, --column TEXT Columns to return - --where TEXT SQL where clause to filter rows (use --param for - user data) - -o, --order TEXT Order by ('column' or 'column desc') - --limit INTEGER Number of rows to return - --offset INTEGER SQL offset to use - --nl Output newline-delimited JSON - --arrays Output rows as arrays instead of objects - --csv Output CSV - --tsv Output TSV - --no-headers Omit CSV headers - -t, --table-format Output as a formatted table - --fmt TEXT Table format - see tabulate documentation for - available formats - --json-cols Detect JSON cols and output them as JSON, not - escaped strings - -p, --param ... Named :parameters for SQL query - --load-extension TEXT Path to SQLite extension, with optional - :entrypoint - --help Show this message and exit. - -``` - - -### schema - Show Schema - -Show schema for database or specific tables. - - -``` -Usage: cli sql schema [OPTIONS] [TABLES]... - - Show full schema for this database or for specified tables. - - Example: - - scrobbledb sql schema - scrobbledb sql schema tracks plays - -Options: - --load-extension TEXT Path to SQLite extension, with optional :entrypoint - --help Show this message and exit. - -``` - - -### search - Full-Text Search - -Execute full-text search against a table. - - -``` -Usage: cli sql search [OPTIONS] DBTABLE Q - - Execute a full-text search against this table. - - Example: - - scrobbledb sql search tracks "rolling stones" --limit 10 - -Options: - -o, --order [relevance|score] Order by relevance or score (relevance is the - default) - -c, --column TEXT Columns to return - --limit INTEGER Number of rows to return - --sql Show SQL query that would be run - --quote Apply FTS quoting rules to search term - --nl Output newline-delimited JSON - --arrays Output rows as arrays instead of objects - --csv-output, --csv Output CSV - --tsv Output TSV - --no-headers Omit CSV headers - -t, --table Output as a formatted table - --fmt TEXT Table format - see tabulate documentation for - available formats - --json-cols Detect JSON cols and output them as JSON, not - escaped strings - --load-extension TEXT Path to SQLite extension, with optional - :entrypoint - --help Show this message and exit. - -``` - - -### tables - List Tables - -List all tables in the database. - - -``` -Usage: cli sql tables [OPTIONS] - - List the tables in the database. - - Example: - - scrobbledb sql tables --counts --columns - -Options: - --fts4 Just show FTS4 enabled tables - --fts5 Just show FTS5 enabled tables - --counts Include row counts per table - --nl Output newline-delimited JSON - --arrays Output rows as arrays instead of objects - --csv Output CSV - --tsv Output TSV - --no-headers Omit CSV headers - -t, --table Output as a formatted table - --fmt TEXT Table format - see tabulate documentation for available - formats - --json-cols Detect JSON cols and output them as JSON, not escaped - strings - --columns Include list of columns for each table - --schema Include schema for each table - --load-extension TEXT Path to SQLite extension, with optional :entrypoint - --help Show this message and exit. - -``` - - -### triggers - Show Triggers - -Show triggers configured in the database. - - -``` -Usage: cli sql triggers [OPTIONS] [TABLES]... - - Show triggers configured in this database. - - Example: - - scrobbledb sql triggers - -Options: - --nl Output newline-delimited JSON - --arrays Output rows as arrays instead of objects - --csv Output CSV - --tsv Output TSV - --no-headers Omit CSV headers - -t, --table Output as a formatted table - --fmt TEXT Table format - see tabulate documentation for available - formats - --json-cols Detect JSON cols and output them as JSON, not escaped - strings - --load-extension TEXT Path to SQLite extension, with optional :entrypoint - --help Show this message and exit. - -``` - - -### views - List Views - -List all views in the database. - - -``` -Usage: cli sql views [OPTIONS] - - List the views in the database. - - Example: - - scrobbledb sql views --counts - -Options: - --counts Include row counts per view - --nl Output newline-delimited JSON - --arrays Output rows as arrays instead of objects - --csv Output CSV - --tsv Output TSV - --no-headers Omit CSV headers - -t, --table Output as a formatted table - --fmt TEXT Table format - see tabulate documentation for available - formats - --json-cols Detect JSON cols and output them as JSON, not escaped - strings - --columns Include list of columns for each view - --schema Include schema for each view - --load-extension TEXT Path to SQLite extension, with optional :entrypoint - --help Show this message and exit. - -``` - - -## Examples - -### List All Tables - -```bash -retrocast sql tables --counts -``` - -### View Table Schema - -```bash -retrocast sql schema episodes -``` - -### Query Episodes - -```bash -retrocast sql query "SELECT * FROM episodes LIMIT 10" -``` - -### Browse Table Data - -```bash -retrocast sql rows episodes --limit 20 -``` - -### Full-Text Search - -```bash -retrocast sql search episodes "machine learning" -``` - -### Export Database - -```bash -retrocast sql dump > backup.sql -``` - -### Use Different Database - -```bash -retrocast sql query "SELECT * FROM feeds" --database /path/to/other.db -``` - -## Advanced Queries - -### Find Recently Played Episodes - -```bash -retrocast sql query "SELECT title, userUpdatedDate FROM episodes_played ORDER BY userUpdatedDate DESC LIMIT 10" -``` - -### Count Episodes by Feed - -```bash -retrocast sql query "SELECT feeds.title, COUNT(episodes.overcastId) as count FROM feeds LEFT JOIN episodes ON feeds.overcastId = episodes.overcastFeedId GROUP BY feeds.overcastId ORDER BY count DESC" -``` - -### Search Episode Descriptions - -```bash -retrocast sql search episodes_extended "artificial intelligence" -``` - -## Tips - -- Use `--csv` or `--json` flags to change output format -- Use `--nl` for newline-delimited JSON -- Use `--table` for pretty table output -- Full-text search works on tables with FTS enabled (feeds, episodes) -- The database is read-only through these commands diff --git a/docs/cli/subscribe.md b/docs/cli/subscribe.md new file mode 100644 index 0000000..0307412 --- /dev/null +++ b/docs/cli/subscribe.md @@ -0,0 +1,23 @@ +# subscribe - Manage Feed Subscriptions + +The `subscribe` command group manages feed subscriptions and Overcast synchronization. + + +``` +Usage: cli subscribe [OPTIONS] COMMAND [ARGS]... + + Manage feed subscriptions + +Options: + --help Show this message and exit. + +Commands: + overcast Manage subscriptions via overcast plugin + +``` + diff --git a/docs/cli/sync.md b/docs/cli/sync.md deleted file mode 100644 index 2d0073b..0000000 --- a/docs/cli/sync.md +++ /dev/null @@ -1,495 +0,0 @@ -# sync - Synchronize Subscription Metadata - -The `sync` command group synchronizes your podcast subscription metadata from various sources. - -## Command Group Help - - -``` -Usage: cli sync [OPTIONS] COMMAND [ARGS]... - - Synchronize subscription metadata - -Options: - --help Show this message and exit. - -Commands: - overcast Synchronize subscription metadata via overcast plugin - -``` - - -## Subcommands - -### overcast - Sync from Overcast - -Synchronize subscription metadata via the Overcast plugin. - - -``` -Usage: cli sync overcast [OPTIONS] COMMAND [ARGS]... - - Synchronize subscription metadata via overcast plugin - -Options: - --help Show this message and exit. - -Commands: - all Run all steps to save, extend, download transcripts, and... - auth Save authentication credentials to a JSON file. - chapters Download and store available chapters for all or starred... - check Check authentication and database setup status. - episodes Export episodes as CSV or JSON filtered by feed titles. - extend Download XML feed and extract all feed and episode tags... - html Download and store available chapters for all or starred... - init Initialize Overcast database in user platform directory. - save Save Overcast info to SQLite database. - subscriptions List feed titles. - transcripts Download available transcripts for all or starred episodes. - -``` - - -#### overcast all - Run All Steps - -Run all synchronization steps in sequence. - - -``` -Usage: cli sync overcast all [OPTIONS] - - Run all steps to save, extend, download transcripts, and chapters. - - This command sequentially executes the following: 1. Save Overcast information - to the SQLite database. 2. Extend the database with new feed and episode data. - 3. Download available transcripts for all or starred episodes. 4. Download and - store available chapters for all or starred episodes. - -Options: - -d, --database FILE Path to database file (defaults to retrocast.db in app - directory) - -a, --auth FILE Custom path to auth.json file (defaults to app directory) - -v, --verbose - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -retrocast sync overcast all -``` - -This runs all steps: auth check, save, extend, transcripts, and chapters. - -#### overcast auth - Authenticate - -Save Overcast authentication credentials. - - -``` -Usage: cli sync overcast auth [OPTIONS] - - Save authentication credentials to a JSON file. - -Options: - -a, --auth FILE Custom path to save auth cookie (defaults to app directory) - --email TEXT - --password TEXT - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -retrocast sync overcast auth -``` - -Prompts for your Overcast credentials and saves them securely. - -#### overcast chapters - Download Chapters - -Download and store chapter information. - - -``` -Usage: cli sync overcast chapters [OPTIONS] - - Download and store available chapters for all or starred episodes. - -Options: - -d, --database FILE Path to database file (defaults to retrocast.db in app - directory) - -p, --path DIRECTORY - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -# Download chapters for all episodes -retrocast sync overcast chapters -``` - -#### overcast check - Check Status - -Check authentication and database setup. - - -``` -Usage: cli sync overcast check [OPTIONS] - - Check authentication and database setup status. - -Options: - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -retrocast sync overcast check -``` - -#### overcast episodes - Export Episodes - -Export episodes as CSV or JSON. - - -``` -Usage: cli sync overcast episodes [OPTIONS] [FEED_TITLES]... - - Export episodes as CSV or JSON filtered by feed titles. - - If no feed titles are provided, exports episodes from all feeds. - -Options: - -d, --database FILE Path to database file (defaults to - retrocast.db in app directory) - -o, --output FILE Output file path (default: stdout) - --format [csv|json] Output format. - --all-episodes / --played-episodes - Only played or all episodes from selected - feeds [default: played-episodes] - -a, --all-feeds / --subbed-feeds - Select from subscribed or all feeds. - [default: subbed-feeds] - -c, --count INTEGER Limit the number of episodes returned. - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -# Export all episodes as JSON -retrocast sync overcast episodes - -# Export specific feed episodes -retrocast sync overcast episodes --feed "Podcast Name" -``` - -#### overcast extend - Download Full Feeds - -Download XML feeds and extract all metadata. - - -``` -Usage: cli sync overcast extend [OPTIONS] - - Download XML feed and extract all feed and episode tags and attributes. - -Options: - -d, --database FILE Path to database file (defaults to retrocast.db in app - directory) - -na, --no-archive - -v, --verbose - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -retrocast sync overcast extend -``` - -Downloads full RSS/Atom feeds for all subscriptions to get complete metadata. - -#### overcast html - Generate HTML - -Generate HTML output for browsing episodes. - - -``` -Usage: cli sync overcast html [OPTIONS] - - Download and store available chapters for all or starred episodes. - -Options: - -d, --database FILE Path to database file (defaults to retrocast.db in app - directory) - -o, --output DIRECTORY - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -retrocast sync overcast html -``` - -#### overcast init - Initialize Database - -Initialize the Overcast database. - - -``` -Usage: cli sync overcast init [OPTIONS] - - Initialize Overcast database in user platform directory. - -Options: - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -retrocast sync overcast init -``` - -#### overcast save - Save to Database - -Save Overcast subscription info to the database. - - -``` -Usage: cli sync overcast save [OPTIONS] - - Save Overcast info to SQLite database. - -Options: - -d, --database FILE Path to database file (defaults to retrocast.db in app - directory) - -a, --auth FILE Custom path to auth.json file (defaults to app directory) - --load FILE Load OPML from this file instead of the API - -na, --no-archive - -v, --verbose - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -retrocast sync overcast save -``` - -Fetches your Overcast OPML data and saves feeds, episodes, and playlists to the database. - -#### overcast subscriptions - List Subscriptions - -List your subscribed podcast feeds. - - -``` -Usage: cli sync overcast subscriptions [OPTIONS] - - List feed titles. - - Default is only podcasts subscribed in Overcast. - - Use --json to output detailed feed data in JSON format. - -Options: - -d, --database FILE Path to database file (defaults to retrocast.db in app - directory) - --all List all feeds known to Overcast, not just subscribed - ones. - --json Output feed data in JSON format. - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -retrocast sync overcast subscriptions -``` - -#### overcast transcripts - Download Transcripts - -Download available transcripts. - - -``` -Usage: cli sync overcast transcripts [OPTIONS] - - Download available transcripts for all or starred episodes. - -Options: - -d, --database FILE Path to database file (defaults to retrocast.db in app - directory) - -p, --path DIRECTORY - -s, --starred-only - -v, --verbose - --help Show this message and exit. - -``` - - -**Usage:** - -```bash -# Download transcripts for all episodes -retrocast sync overcast transcripts - -# Download transcripts for starred episodes only -retrocast sync overcast transcripts --starred-only -``` - -## Typical Workflow - -### Initial Setup - -```bash -# 1. Authenticate with Overcast -retrocast sync overcast auth - -# 2. Initialize database -retrocast sync overcast init - -# 3. Run all synchronization steps -retrocast sync overcast all -``` - -### Regular Updates - -```bash -# Quick sync of new data -retrocast sync overcast save -retrocast sync overcast extend -``` - -### Full Refresh - -```bash -# Complete synchronization -retrocast sync overcast all -``` - -## What Gets Synchronized? - -### Basic Info (save) -- Podcast feed metadata -- Episode information -- Play history -- Starred episodes -- Playlists - -### Extended Info (extend) -- Full RSS feed data -- Rich episode descriptions -- Episode artwork -- Show notes -- All RSS tags and attributes - -### Additional Data -- Chapter markers -- Podcast transcripts (when available) - -## Storage - -All synchronized data is stored in: -``` -~/.local/share/net.memexponent.retrocast/retrocast.db -``` - -## Tips - -- Run `sync overcast auth` first on a new installation -- Use `sync overcast all` for complete synchronization -- Use `sync overcast save` for quick updates -- The `--starred` flag processes only starred episodes -- Extend downloads full feeds for rich metadata diff --git a/docs/cli/transcribe.md b/docs/cli/transcribe.md new file mode 100644 index 0000000..7f572b3 --- /dev/null +++ b/docs/cli/transcribe.md @@ -0,0 +1,31 @@ +# transcribe - Manage Audio Transcriptions + +The `transcribe` command group applies ASR and provides transcription workflows. + + +``` + + Usage: cli transcribe [OPTIONS] COMMAND [ARGS]... + + Manage audio transcriptions (create, search, analyze). + ++--------------------------------------------------------------------------------------------------+ +| --help Show this message and exit. | ++--------------------------------------------------------------------------------------------------+ ++--------------------------------------------------------------------------------------------------+ +| backends Manage transcription backends. | +| episodes Manage and view transcribed episodes. | +| podcasts Manage and view transcribed podcasts. | +| process Process audio files to create transcriptions. | +| search Search transcribed podcast content. | +| summary Display overall transcription statistics. | +| validate Validate all JSON transcription files in the app directory. | ++--------------------------------------------------------------------------------------------------+ +``` + diff --git a/docs/cli/transcription.md b/docs/cli/transcription.md deleted file mode 100644 index bb324bc..0000000 --- a/docs/cli/transcription.md +++ /dev/null @@ -1,517 +0,0 @@ -# transcription - Manage Audio Transcriptions - -The `transcription` command group manages audio transcriptions, allowing you to create, search, and analyze podcast transcripts. - -## Command Group Help - - -``` - - Usage: cli transcription [OPTIONS] COMMAND [ARGS]... - - Manage audio transcriptions (create, search, analyze). - -+--------------------------------------------------------------------------------------------------+ -| --help Show this message and exit. | -+--------------------------------------------------------------------------------------------------+ -+--------------------------------------------------------------------------------------------------+ -| backends Manage transcription backends. | -| episodes Manage and view transcribed episodes. | -| podcasts Manage and view transcribed podcasts. | -| process Process audio files to create transcriptions. | -| search Search transcribed podcast content. | -| summary Display overall transcription statistics. | -| validate Validate all JSON transcription files in the app directory. | -+--------------------------------------------------------------------------------------------------+ -``` - - -## Subcommands - -### backends - Manage Backends - -Manage transcription backends (MLX Whisper, faster-whisper, etc.). - - -``` - - Usage: cli transcription backends [OPTIONS] COMMAND [ARGS]... - - Manage transcription backends. - Commands for listing, testing, and managing transcription backends. - -+--------------------------------------------------------------------------------------------------+ -| --help Show this message and exit. | -+--------------------------------------------------------------------------------------------------+ -+--------------------------------------------------------------------------------------------------+ -| list List available transcription backends. | -| test Test if a specific backend is available. | -+--------------------------------------------------------------------------------------------------+ -``` - - -**Usage:** - -```bash -retrocast transcription backends -``` - -Shows available transcription backends and their status. - -### episodes - View Transcribed Episodes - -View and manage transcribed episodes. - - -``` - - Usage: cli transcription episodes [OPTIONS] COMMAND [ARGS]... - - Manage and view transcribed episodes. - Commands for listing and summarizing episodes with transcriptions. - -+--------------------------------------------------------------------------------------------------+ -| --help Show this message and exit. | -+--------------------------------------------------------------------------------------------------+ -+--------------------------------------------------------------------------------------------------+ -| list List transcribed episodes. | -| summary Show summary statistics for transcribed episodes. | -+--------------------------------------------------------------------------------------------------+ -``` - - -**Usage:** - -```bash -# List all transcribed episodes -retrocast transcription episodes - -# Show episodes for specific podcast -retrocast transcription episodes --podcast "Podcast Name" -``` - -### podcasts - View Transcribed Podcasts - -View and manage transcribed podcasts. - - -``` - - Usage: cli transcription podcasts [OPTIONS] COMMAND [ARGS]... - - Manage and view transcribed podcasts. - Commands for listing and summarizing podcasts with transcriptions. - -+--------------------------------------------------------------------------------------------------+ -| --help Show this message and exit. | -+--------------------------------------------------------------------------------------------------+ -+--------------------------------------------------------------------------------------------------+ -| list List all podcasts with transcriptions. | -| summary Show summary statistics for podcasts. | -+--------------------------------------------------------------------------------------------------+ -``` - - -**Usage:** - -```bash -retrocast transcription podcasts -``` - -Lists all podcasts that have at least one transcribed episode. - -### process - Create Transcriptions - -Process audio files to create transcriptions. - - -``` - - Usage: cli transcription process [OPTIONS] [PATHS]... - - Process audio files to create transcriptions. - PATHS: One or more audio files or directories containing audio files. Can be omitted when using --from-downloads. - - Examples: - - - # Process a single file - retrocast transcription process episode.mp3 - - # Process all files in a directory - retrocast transcription process /path/to/podcast/ - - # Use specific backend and model - retrocast transcription process --backend mlx-whisper --model medium file.mp3 - - # Save as SRT subtitle format - retrocast transcription process --format srt episode.mp3 - - # Process all downloaded episodes from a specific podcast - retrocast transcription process --from-downloads --podcast "Tech Podcast" - - # List available podcasts from downloads - retrocast transcription process --list-podcasts - - # Process all downloaded episodes - retrocast transcription process --from-downloads - - -+--------------------------------------------------------------------------------------------------+ -| --from-downloads Process episodes from the episode_downloads | -| directory. | -| --podcast TEXT Filter by podcast name (use with | -| --from-downloads or directory paths). | -| --list-podcasts List available podcasts from downloads and | -| exit. | -| --backend [auto|mlx-whisper|faster-whisper] Transcription backend to use. | -| --model [tiny|base|small|medium|large] Whisper model size. | -| --language TEXT Audio language code (e.g., 'en', 'es'). | -| Auto-detected if not specified. | -| --output-dir PATH Output directory for transcription files | -| (defaults to app_dir/transcriptions). | -| --format [txt|json|srt|vtt] Output format for transcription files. | -| --force Re-transcribe even if transcription already | -| exists. | -| --db PATH Path to database file (defaults to | -| app_dir/retrocast.db). | -| --help Show this message and exit. | -+--------------------------------------------------------------------------------------------------+ -``` - - -**Usage:** - -```bash -# Process all downloaded episodes -retrocast transcription process - -# Process specific podcast -retrocast transcription process --podcast "Podcast Name" - -# Process with specific backend and model -retrocast transcription process --backend mlx-whisper --model medium -``` - -### search - Search Transcripts - -Search transcribed podcast content. - - -``` - - Usage: cli transcription search [OPTIONS] QUERY - - Search transcribed podcast content. - QUERY: Search query string (FTS5 syntax supported). - - Examples: - - - # Simple search - retrocast transcription search "machine learning" - - # Search with filters - retrocast transcription search "AI" --podcast "Tech Podcast" --limit 10 - - # Search with date range - retrocast transcription search "python" --date-from "2024-01-01" --date-to "2024-12-31" - - # Export results to JSON - retrocast transcription search "data science" --export json --output results.json - - # Search with context and pagination - retrocast transcription search "neural networks" --context 2 --page 2 --limit 10 - - -+--------------------------------------------------------------------------------------------------+ -| --podcast TEXT Filter by podcast title. | -| --speaker TEXT Filter by speaker ID (requires diarization). | -| --backend TEXT Filter by transcription backend (e.g., 'mlx-whisper'). | -| --model TEXT Filter by model size (e.g., 'base', 'medium'). | -| --date-from TEXT Filter by creation date (ISO format, e.g., '2024-01-01'). | -| --date-to TEXT Filter by creation date (ISO format, e.g., '2024-12-31'). | -| --limit INTEGER Maximum number of results to display. | -| --page INTEGER Page number for pagination (starts at 1). | -| --context INTEGER Number of surrounding segments to show for context. | -| --export [json|csv|html] Export results to file format. | -| --output PATH Output file path for export (defaults to search_results.{format}). | -| --db PATH Path to database file (defaults to app_dir/retrocast.db). | -| --help Show this message and exit. | -+--------------------------------------------------------------------------------------------------+ -``` - - -**Usage:** - -```bash -# Search all transcripts -retrocast transcription search "machine learning" - -# Search within specific podcast -retrocast transcription search "AI" --podcast "Tech Podcast" - -# Limit results -retrocast transcription search "python" --limit 10 -``` - -### summary - View Statistics - -Display overall transcription statistics. - - -``` - - Usage: cli transcription summary [OPTIONS] - - Display overall transcription statistics. - Shows a comprehensive summary of all transcriptions in the database, including counts, duration, backends used, and more. - - Example: retrocast transcription summary - -+--------------------------------------------------------------------------------------------------+ -| --db PATH Path to database file (defaults to app_dir/retrocast.db). | -| --help Show this message and exit. | -+--------------------------------------------------------------------------------------------------+ -``` - - -**Usage:** - -```bash -retrocast transcription summary -``` - -Shows: -- Total transcribed episodes -- Total transcribed podcasts -- Storage usage -- Backend statistics - -### validate - Validate Transcripts - -Validate all JSON transcription files. - - -``` - - Usage: cli transcription validate [OPTIONS] - - Validate all JSON transcription files in the app directory. - Checks that all JSON transcription files conform to the expected schema using pydantic validation. Displays progress during validation and provides a summary report at the end. - - Example: retrocast transcription validate retrocast transcription validate --verbose retrocast transcription validate --output-dir /custom/path - -+--------------------------------------------------------------------------------------------------+ -| --output-dir PATH Directory containing transcription JSON files (defaults to | -| app_dir/transcriptions). | -| --verbose -v Show detailed validation errors for each file. | -| --help Show this message and exit. | -+--------------------------------------------------------------------------------------------------+ -``` - - -**Usage:** - -```bash -retrocast transcription validate -``` - -Checks all transcription JSON files for: -- Valid JSON syntax -- Required fields -- Proper structure - -## Transcription Backends - -retrocast supports multiple transcription backends: - -### MLX Whisper (Apple Silicon only) - -Optimized for Apple Silicon Macs with Metal acceleration. - -**Installation:** - -```bash -pip install retrocast[transcription-mlx] -``` - -**Features:** -- Fast performance on M1/M2/M3 chips -- Low memory usage -- Metal acceleration - -### faster-whisper (CPU) - -CPU-based transcription, works on any platform. - -**Installation:** - -```bash -pip install retrocast[transcription-cpu] -``` - -### faster-whisper (CUDA) - -GPU-accelerated transcription for NVIDIA GPUs. - -**Installation:** - -```bash -pip install retrocast[transcription-cuda] -``` - -### Diarization - -Speaker detection and labeling (requires additional dependencies). - -**Installation:** - -```bash -pip install retrocast[transcription-diarization] -``` - -## Transcript Storage - -Transcripts are stored in: -``` -~/.local/share/net.memexponent.retrocast/transcripts/ -``` - -Each transcript includes: -- Full text transcription -- Word-level timestamps -- Confidence scores -- Speaker labels (if diarized) -- Metadata (duration, language, etc.) - -## Examples - -### Process All Episodes - -```bash -retrocast transcription process -``` - -### Search Transcripts - -```bash -retrocast transcription search "artificial intelligence" -``` - -### View Statistics - -```bash -retrocast transcription summary -``` - -### Validate All Transcripts - -```bash -retrocast transcription validate -``` - -## Workflow - -### Initial Transcription - -```bash -# 1. Install backend (choose one) -pip install retrocast[transcription-mlx] # Mac -pip install retrocast[transcription-cuda] # Linux with GPU -pip install retrocast[transcription-cpu] # Any platform - -# 2. Download episodes -retrocast download podcast-archiver --feed - -# 3. Create transcriptions -retrocast transcription process - -# 4. Search content -retrocast transcription search "topic" -``` - -### Update Transcriptions - -```bash -# Process only new episodes -retrocast transcription process -``` - -## Performance Tips - -- MLX Whisper is fastest on Apple Silicon -- CUDA backend is fastest on NVIDIA GPUs -- CPU backend works everywhere but is slower -- Diarization adds processing time but provides speaker labels -- Process overnight for large archives -- Use `--limit` to test on a few episodes first - -## See Also - -- [Full Transcription Documentation](../TRANSCRIPTION.md) -- [Transcription Developer Guide](../TRANSCRIPTION_DEVELOPER.md) diff --git a/plans/2026-02-16-205506-command-reorg-implementation-summary.md b/plans/2026-02-16-205506-command-reorg-implementation-summary.md new file mode 100644 index 0000000..512d1c8 --- /dev/null +++ b/plans/2026-02-16-205506-command-reorg-implementation-summary.md @@ -0,0 +1,68 @@ +# Implementation Summary: Rename and Reorganize Command Structure + +**Timestamp:** 2026-02-16T20:55:06.228Z + +## Overview of Requested Work + +The issue requested a command structure that is more action-oriented, with the following top-level commands: + +- `configure` — manage configuration +- `chat` — agentic AI chat with transcribed/indexed data +- `transcribe` — apply ASR to downloaded episodes +- `download` — download and manage episodes +- `query` — query/manage subscription, episode, metadata, and transcription databases +- `index` — create/manage transcription search indexes (new area) +- `subscribe` — manage feed subscriptions +- `about` — quick philosophical readme + +It also requested moving existing top-level subgroup behavior (`meta`, `sync`) into the new command layout, and updating tests to match. + +## Implemented Changes + +### 1) Top-Level CLI Reorganization + +Implemented the requested command names and structure: + +- `config` → `configure` +- `castchat` → `chat` +- `transcription` → `transcribe` +- `sql` → `query` +- `sync`/`meta` exposure removed from top level +- `subscribe` introduced as the subscription-focused top-level group +- `index` introduced as a new top-level group (with `status` placeholder) + +### 2) Subgroup Relocation + +- Overcast workflows were moved under `subscribe overcast ...`. +- References to old paths in user-facing help/messages were updated to the new command paths. + +### 3) Tests Updated + +Tests were aligned to the new command structure, including: + +- CLI command-path tests +- transcription command tests +- reset-db command-path tests +- SQL/query command-path tests +- docs-generation expectations + +## Documentation Updates + +CLI docs were updated to match renamed/reorganized commands, including command index/README references and renamed command documentation files for: + +- `chat` +- `configure` +- `query` +- `subscribe` +- `transcribe` + +## Validation Performed + +- Targeted test runs for affected command/test modules +- Full QA (`poe qa`) run after implementation updates +- Manual CLI help verification confirmed expected top-level commands: + - `about`, `chat`, `configure`, `download`, `index`, `query`, `subscribe`, `transcribe` + +## Result + +The implemented work satisfies the requested action-oriented command layout, relocates prior `meta`/`sync` behavior into the new structure, and updates test/documentation coverage to reflect the final command model. diff --git a/pyproject.toml b/pyproject.toml index d122590..20d1572 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -213,12 +213,12 @@ ignore_fail = false # Documentation generation [tool.poe.tasks."docs:generate"] help = "Generate CLI documentation using cog" -cmd = "env PYTHONPATH=src COLUMNS=200 uv run cog -r docs/cli/about.md docs/cli/castchat.md docs/cli/config.md docs/cli/download.md docs/cli/index.md docs/cli/meta.md docs/cli/sql.md docs/cli/sync.md docs/cli/transcription.md" +cmd = "env PYTHONPATH=src COLUMNS=200 uv run cog -r docs/cli/about.md docs/cli/chat.md docs/cli/configure.md docs/cli/download.md docs/cli/index.md docs/cli/query.md docs/cli/subscribe.md docs/cli/transcribe.md" # cmd = "env PYTHONPATH=src COLUMNS=100 uv run cog -r docs/cli/*.md" [tool.poe.tasks."docs:check"] help = "Check if CLI documentation is up to date" -cmd = "env PYTHONPATH=src COLUMNS=200 uv run cog --check --diff docs/cli/about.md docs/cli/castchat.md docs/cli/config.md docs/cli/download.md docs/cli/index.md docs/cli/meta.md docs/cli/sql.md docs/cli/sync.md docs/cli/transcription.md" +cmd = "env PYTHONPATH=src COLUMNS=200 uv run cog --check --diff docs/cli/about.md docs/cli/chat.md docs/cli/configure.md docs/cli/download.md docs/cli/index.md docs/cli/query.md docs/cli/subscribe.md docs/cli/transcribe.md" # cmd = "env PYTHONPATH=src COLUMNS=100 python -m cogapp --check docs/cli/*.md" # Transcription backend installation diff --git a/src/retrocast/cli.py b/src/retrocast/cli.py index 618ac44..c3ac8ee 100755 --- a/src/retrocast/cli.py +++ b/src/retrocast/cli.py @@ -29,7 +29,7 @@ from retrocast.download_commands import download from retrocast.episode_db_commands import episode_db from retrocast.logging_config import setup_logging -from retrocast.overcast import chapters, overcast, transcripts +from retrocast.overcast import overcast from retrocast.process_commands import transcription from . import sql_cli @@ -83,7 +83,7 @@ def about() -> None: console.print(Markdown(about_text)) -@cli.group() +@cli.group(name="configure") @click.pass_context def config(ctx: click.Context) -> None: """Manage the retrocast configuration data""" @@ -119,7 +119,7 @@ def check(ctx: click.Context) -> None: "App Directory", str(app_dir), "[green]✓ Found[/green]" if app_exists else "[red]✗ Missing[/red]", - "" if app_exists else "Run: retrocast config initialize", + "" if app_exists else "Run: retrocast configure initialize", ) if app_exists: @@ -127,7 +127,7 @@ def check(ctx: click.Context) -> None: "Auth File", str(auth_path), "[green]✓ Found[/green]" if auth_exists else "[yellow]⚠ Missing[/yellow]", - "retrocast sync overcast auth" if not auth_exists else "", + "retrocast subscribe overcast auth" if not auth_exists else "", ) # Database row with initialization status @@ -136,10 +136,10 @@ def check(ctx: click.Context) -> None: db_action = "" elif db_exists: db_status = "[yellow]⚠ Not initialized[/yellow]" - db_action = "retrocast config initialize" + db_action = "retrocast configure initialize" else: db_status = "[yellow]⚠ Missing[/yellow]" - db_action = "retrocast config initialize" + db_action = "retrocast configure initialize" table.add_row( "Database", @@ -214,9 +214,9 @@ def config_initialize(ctx: click.Context, yes: bool) -> None: console.print(table) console.print() console.print("[dim]Next steps:[/dim]") - console.print(" 1. Authenticate: [cyan]retrocast sync overcast auth[/cyan]") - console.print(" 2. Sync data: [cyan]retrocast sync overcast save[/cyan]") - console.print(" 3. Download: [cyan]retrocast meta overcast transcripts[/cyan]") + console.print(" 1. Authenticate: [cyan]retrocast subscribe overcast auth[/cyan]") + console.print(" 2. Sync data: [cyan]retrocast subscribe overcast save[/cyan]") + console.print(" 3. Download: [cyan]retrocast subscribe overcast transcripts[/cyan]") console.print() @@ -316,10 +316,10 @@ def location(ctx: click.Context, output_format, db_path_flag: bool, app_dir_flag Use --app-dir to output only the app directory path as a JSON string. Examples: - retrocast config location # Table view - retrocast config location --format json # All paths as JSON - retrocast config location --db-path # Just database path - retrocast config location --app-dir # Just app directory + retrocast configure location # Table view + retrocast configure location --format json # All paths as JSON + retrocast configure location --db-path # Just database path + retrocast configure location --app-dir # Just app directory """ # Validate mutual exclusivity of output options @@ -377,7 +377,7 @@ def location(ctx: click.Context, output_format, db_path_flag: bool, app_dir_flag "App Directory", str(app_dir), "[green]✓ Found[/green]" if app_exists else "[red]✗ Missing[/red]", - "" if app_exists else "Run: retrocast config initialize", + "" if app_exists else "Run: retrocast configure initialize", ) if app_exists: @@ -385,13 +385,13 @@ def location(ctx: click.Context, output_format, db_path_flag: bool, app_dir_flag "Auth File", str(auth_path), "[green]✓ Found[/green]" if auth_exists else "[yellow]⚠ Missing[/yellow]", - "retrocast sync overcast auth" if not auth_exists else "", + "retrocast subscribe overcast auth" if not auth_exists else "", ) table.add_row( "Database", str(db_path), "[green]✓ Found[/green]" if db_exists else "[yellow]⚠ Missing[/yellow]", - "retrocast sync overcast save" if not db_exists else "", + "retrocast subscribe overcast save" if not db_exists else "", ) else: table.add_row("Auth File", str(auth_path), "[dim]n/a[/dim]", "Initialize app directory") @@ -534,7 +534,7 @@ def format_truncated_list(items: list[str], max_items: int) -> str: console.print("[green]✓ Database schema reset successfully![/green]") console.print() console.print("[dim]The database has been reset to a clean state with empty tables.[/dim]") - console.print("[dim]Run 'retrocast sync overcast save' to populate with data.[/dim]") + console.print("[dim]Run 'retrocast subscribe overcast save' to populate with data.[/dim]") except Exception as e: console.print(f"[red]✗ Error resetting database: {e}[/red]") logger.exception("Database reset failed") @@ -543,18 +543,24 @@ def format_truncated_list(items: list[str], max_items: int) -> str: @cli.group() @click.pass_context -def sync(ctx: click.Context) -> None: - """Synchronize subscription metadata""" +def subscribe(ctx: click.Context) -> None: + """Manage feed subscriptions""" pass @cli.group() @click.pass_context -def meta(ctx: click.Context) -> None: - """Download episode metadata and derived information""" +def index(ctx: click.Context) -> None: + """Create and manage search indexes""" pass +@index.command() +def status() -> None: + """Show index command availability""" + Console().print("[yellow]Index management commands are not implemented yet.[/yellow]") + + def _attach_podcast_archiver_passthroughs(main_group: DefaultGroup) -> None: download_command = main_group.commands.get("download") @@ -634,16 +640,8 @@ def archiver_wrapped(ctx: rich_click.RichContext, **kwargs): logger.debug(f"Attached llm command: {archiver_wrapped}") -# Register overcast commands -sync.add_command(overcast) - -# Register retrieval aliases -overcast_meta = click.Group( - "overcast", help="Retrieve episode metadata and information via overcast plugin" -) -overcast_meta.add_command(transcripts) -overcast_meta.add_command(chapters) -meta.add_command(overcast_meta) +# Register subscription commands +subscribe.add_command(overcast) # Register download commands cli.add_command(download) @@ -655,9 +653,10 @@ def archiver_wrapped(ctx: rich_click.RichContext, **kwargs): cli.add_command(transcription) cli.add_command(sql_cli.sql) +cli.add_command(index) -@cli.command() +@cli.command(name="chat") @click.option( "-d", "--database", @@ -717,7 +716,7 @@ def castchat( if not db_path.exists(): console.print(f"[bold red]Error:[/bold red] Database not found at {db_path}") - console.print("Run [cyan]retrocast sync overcast[/cyan] first to create the database") + console.print("Run [cyan]retrocast subscribe overcast[/cyan] first to create the database") raise click.Abort() # Initialize datastore @@ -749,7 +748,7 @@ def castchat( if indexed_count == 0: console.print("[bold red]No transcription segments found![/bold red]") console.print( - "Run [cyan]retrocast transcription transcribe[/cyan] to transcribe episodes first" + "Run [cyan]retrocast transcribe process[/cyan] to transcribe episodes first" ) raise click.Abort() diff --git a/src/retrocast/overcast.py b/src/retrocast/overcast.py index 9267bbb..b091630 100644 --- a/src/retrocast/overcast.py +++ b/src/retrocast/overcast.py @@ -217,7 +217,7 @@ def _auth_and_fetch(auth_path: str | None, archive: Path | None) -> str: @click.group() @click.pass_context def overcast(ctx: click.Context) -> None: - """Synchronize subscription metadata via overcast plugin""" + """Manage subscriptions via overcast plugin""" pass @@ -259,12 +259,14 @@ def init(ctx: click.Context) -> None: console.print("[dim]Database schema initialized successfully.[/dim]") console.print() console.print("[dim]Next steps:[/dim]") - console.print(" 1. Authenticate: [cyan]retrocast sync overcast auth[/cyan]") - console.print(" 2. Sync data: [cyan]retrocast sync overcast save[/cyan]") - console.print(" 3. Download: [cyan]retrocast retrieve overcast transcripts[/cyan]") + console.print(" 1. Authenticate: [cyan]retrocast subscribe overcast auth[/cyan]") + console.print(" 2. Sync data: [cyan]retrocast subscribe overcast save[/cyan]") + console.print(" 3. Download: [cyan]retrocast subscribe overcast transcripts[/cyan]") console.print() else: - console.print("[dim]Use [cyan]retrocast sync overcast check[/cyan] to verify setup.[/dim]") + console.print( + "[dim]Use [cyan]retrocast subscribe overcast check[/cyan] to verify setup.[/dim]" + ) console.print() @@ -296,7 +298,7 @@ def check(ctx: click.Context) -> None: "App Directory", str(app_dir), "[green]✓[/green]" if app_exists else "[red]✗ Missing[/red]", - "" if app_exists else "Run: retrocast config initialize", + "" if app_exists else "Run: retrocast configure initialize", ) # Add auth row @@ -307,7 +309,7 @@ def check(ctx: click.Context) -> None: "Auth File", str(auth_path), "[red]✗ Not found[/red]", - "Run: retrocast sync overcast auth", + "Run: retrocast subscribe overcast auth", ) # Add database row @@ -318,7 +320,7 @@ def check(ctx: click.Context) -> None: "Database", str(db_path), "[red]✗ Not found[/red]", - "Run: retrocast sync overcast save", + "Run: retrocast subscribe overcast save", ) console.print() @@ -526,12 +528,6 @@ def transcripts( # noqa: C901 ) -> None: """Download available transcripts for all or starred episodes.""" - if ctx.command_path.startswith("retrocast sync"): - Console(stderr=True).print( - "[yellow]Use `retrocast retrieve overcast transcripts` for future runs." - " The current location will be deprecated.[/yellow]", - ) - resolved_db_path = _resolve_db_path(ctx, db_path) if not _confirm_db_creation(resolved_db_path): @@ -625,12 +621,6 @@ def chapters( ) -> None: """Download and store available chapters for all or starred episodes.""" - if ctx.command_path.startswith("retrocast sync"): - Console(stderr=True).print( - "[yellow]Use `retrocast retrieve overcast chapters` for future runs." - " The current location will be deprecated.[/yellow]", - ) - resolved_db_path = _resolve_db_path(ctx, db_path) app_dir = _ensure_app_dir_from_ctx(ctx) diff --git a/src/retrocast/process_commands.py b/src/retrocast/process_commands.py index 6ce5fd2..2319604 100644 --- a/src/retrocast/process_commands.py +++ b/src/retrocast/process_commands.py @@ -28,7 +28,7 @@ AUDIO_EXTENSIONS = {".mp3", ".m4a", ".ogg", ".opus", ".wav", ".flac", ".aac"} -@click.group(name="transcription") +@click.group(name="transcribe") @click.pass_context def transcription(ctx: click.RichContext) -> None: """Manage audio transcriptions (create, search, analyze).""" @@ -125,25 +125,25 @@ def process_audio( # noqa: C901 Examples: # Process a single file - retrocast transcription process episode.mp3 + retrocast transcribe process episode.mp3 # Process all files in a directory - retrocast transcription process /path/to/podcast/ + retrocast transcribe process /path/to/podcast/ # Use specific backend and model - retrocast transcription process --backend mlx-whisper --model medium file.mp3 + retrocast transcribe process --backend mlx-whisper --model medium file.mp3 # Save as SRT subtitle format - retrocast transcription process --format srt episode.mp3 + retrocast transcribe process --format srt episode.mp3 # Process all downloaded episodes from a specific podcast - retrocast transcription process --from-downloads --podcast "Tech Podcast" + retrocast transcribe process --from-downloads --podcast "Tech Podcast" # List available podcasts from downloads - retrocast transcription process --list-podcasts + retrocast transcribe process --list-podcasts # Process all downloaded episodes - retrocast transcription process --from-downloads + retrocast transcribe process --from-downloads """ # Setup app_dir = get_app_dir(create=True) @@ -585,9 +585,9 @@ def validate_transcriptions( a summary report at the end. Example: - retrocast transcription validate - retrocast transcription validate --verbose - retrocast transcription validate --output-dir /custom/path + retrocast transcribe validate + retrocast transcribe validate --verbose + retrocast transcribe validate --output-dir /custom/path """ # Setup app_dir = get_app_dir(create=False) @@ -674,7 +674,7 @@ def list_backends() -> None: Shows which backends are installed and available on your system. Example: - retrocast transcription backends list + retrocast transcribe backends list """ from retrocast.transcription.backends import get_all_backends @@ -730,7 +730,7 @@ def test_backend(backend_name: str) -> None: BACKEND_NAME: Name of backend to test (e.g., 'mlx-whisper') Example: - retrocast transcription backends test mlx-whisper + retrocast transcribe backends test mlx-whisper """ from retrocast.transcription.backends import get_all_backends @@ -863,19 +863,19 @@ def search( Examples: # Simple search - retrocast transcription search "machine learning" + retrocast transcribe search "machine learning" # Search with filters - retrocast transcription search "AI" --podcast "Tech Podcast" --limit 10 + retrocast transcribe search "AI" --podcast "Tech Podcast" --limit 10 # Search with date range - retrocast transcription search "python" --date-from "2024-01-01" --date-to "2024-12-31" + retrocast transcribe search "python" --date-from "2024-01-01" --date-to "2024-12-31" # Export results to JSON - retrocast transcription search "data science" --export json --output results.json + retrocast transcribe search "data science" --export json --output results.json # Search with context and pagination - retrocast transcription search "neural networks" --context 2 --page 2 --limit 10 + retrocast transcribe search "neural networks" --context 2 --page 2 --limit 10 """ from rich.markup import escape @@ -1224,7 +1224,7 @@ def summary( including counts, duration, backends used, and more. Example: - retrocast transcription summary + retrocast transcribe summary """ # Setup database if db_path is None: @@ -1241,7 +1241,7 @@ def summary( if stats["total_transcriptions"] == 0: console.print( "\n[yellow]No transcriptions found in database.[/yellow]\n" - "Use 'retrocast transcription process' to create transcriptions.\n" + "Use 'retrocast transcribe process' to create transcriptions.\n" ) return @@ -1336,8 +1336,8 @@ def podcasts_list( Shows podcasts sorted by number of transcribed episodes. Example: - retrocast transcription podcasts list - retrocast transcription podcasts list --limit 10 + retrocast transcribe podcasts list + retrocast transcribe podcasts list --limit 10 """ # Setup database if db_path is None: @@ -1354,7 +1354,7 @@ def podcasts_list( if not stats: console.print( "\n[yellow]No transcriptions found in database.[/yellow]\n" - "Use 'retrocast transcription process' to create transcriptions.\n" + "Use 'retrocast transcribe process' to create transcriptions.\n" ) return @@ -1407,8 +1407,8 @@ def podcasts_summary( Otherwise, shows overview for all podcasts. Examples: - retrocast transcription podcasts summary - retrocast transcription podcasts summary "Tech Podcast" + retrocast transcribe podcasts summary + retrocast transcribe podcasts summary "Tech Podcast" """ # Setup database if db_path is None: @@ -1468,7 +1468,7 @@ def podcasts_summary( if not stats: console.print( "\n[yellow]No transcriptions found in database.[/yellow]\n" - "Use 'retrocast transcription process' to create transcriptions.\n" + "Use 'retrocast transcribe process' to create transcriptions.\n" ) return @@ -1577,9 +1577,9 @@ def episodes_list( Shows episodes sorted by the specified order (default: most recent first). Examples: - retrocast transcription episodes list - retrocast transcription episodes list --podcast "Tech Podcast" - retrocast transcription episodes list --order duration --limit 10 + retrocast transcribe episodes list + retrocast transcribe episodes list --podcast "Tech Podcast" + retrocast transcribe episodes list --order duration --limit 10 """ # Setup database if db_path is None: @@ -1617,7 +1617,7 @@ def episodes_list( else: console.print( "\n[yellow]No transcriptions found in database.[/yellow]\n" - "Use 'retrocast transcription process' to create transcriptions.\n" + "Use 'retrocast transcribe process' to create transcriptions.\n" ) return @@ -1710,8 +1710,8 @@ def episodes_summary( Displays aggregate statistics about transcribed episodes. Examples: - retrocast transcription episodes summary - retrocast transcription episodes summary --podcast "Tech Podcast" + retrocast transcribe episodes summary + retrocast transcribe episodes summary --podcast "Tech Podcast" """ # Setup database if db_path is None: @@ -1734,7 +1734,7 @@ def episodes_summary( else: console.print( "\n[yellow]No transcriptions found in database.[/yellow]\n" - "Use 'retrocast transcription process' to create transcriptions.\n" + "Use 'retrocast transcribe process' to create transcriptions.\n" ) return diff --git a/src/retrocast/sql_cli.py b/src/retrocast/sql_cli.py index 13d7923..ed702a6 100644 --- a/src/retrocast/sql_cli.py +++ b/src/retrocast/sql_cli.py @@ -186,7 +186,7 @@ def format_help(self, ctx, formatter): self.format_options(ctx, formatter) -@click.group(cls=SqlGroup) +@click.group(name="query", cls=SqlGroup) @click.option( "--database", "-d", diff --git a/tests/test_cli.py b/tests/test_cli.py index 7a3c629..7ed70c8 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -89,7 +89,7 @@ def test_config_check_reports_missing_without_creating(monkeypatch, tmp_path: Pa shutil.rmtree(app_dir) runner = CliRunner() - result = runner.invoke(cli, ["config", "check"]) + result = runner.invoke(cli, ["configure", "check"]) assert result.exit_code == 1 assert "retrocast configuration" in result.output.lower() @@ -108,12 +108,12 @@ def test_config_check_detects_uninitialized_database(monkeypatch, tmp_path: Path monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() - result = runner.invoke(cli, ["config", "check"]) + result = runner.invoke(cli, ["configure", "check"]) assert result.exit_code == 1 assert "Not initialized" in result.output # Check for the action text (may be wrapped in table) - assert "config" in result.output.lower() and "initialize" in result.output.lower() + assert "configure" in result.output.lower() and "initialize" in result.output.lower() def test_config_check_detects_initialized_database(monkeypatch, tmp_path: Path) -> None: @@ -130,7 +130,7 @@ def test_config_check_detects_initialized_database(monkeypatch, tmp_path: Path) monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() - result = runner.invoke(cli, ["config", "check"]) + result = runner.invoke(cli, ["configure", "check"]) assert result.exit_code == 1 # Still incomplete due to missing auth assert "Initialized" in result.output @@ -142,7 +142,7 @@ def test_config_location_json(monkeypatch, tmp_path: Path) -> None: monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() - result = runner.invoke(cli, ["config", "location", "--format", "json"]) + result = runner.invoke(cli, ["configure", "location", "--format", "json"]) assert result.exit_code == 0, result.output assert json.loads(result.stdout) == { @@ -157,7 +157,7 @@ def test_config_location_missing(monkeypatch, tmp_path: Path) -> None: monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() - result = runner.invoke(cli, ["config", "location"]) + result = runner.invoke(cli, ["configure", "location"]) assert result.exit_code == 1 assert "configuration locations" in result.output.lower() @@ -175,7 +175,7 @@ def test_config_location_ready(monkeypatch, tmp_path: Path) -> None: monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() - result = runner.invoke(cli, ["config", "location"]) + result = runner.invoke(cli, ["configure", "location"]) assert result.exit_code == 0, result.output assert "configuration ready" in result.output.lower() @@ -187,7 +187,7 @@ def test_config_location_db_path(monkeypatch, tmp_path: Path) -> None: monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() - result = runner.invoke(cli, ["config", "location", "--db-path"]) + result = runner.invoke(cli, ["configure", "location", "--db-path"]) assert result.exit_code == 0, result.output # Parse the JSON string output @@ -199,7 +199,7 @@ def test_config_location_app_dir(monkeypatch, tmp_path: Path) -> None: monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() - result = runner.invoke(cli, ["config", "location", "--app-dir"]) + result = runner.invoke(cli, ["configure", "location", "--app-dir"]) assert result.exit_code == 0, result.output # Parse the JSON string output @@ -213,17 +213,17 @@ def test_config_location_mutual_exclusivity(monkeypatch, tmp_path: Path) -> None runner = CliRunner() # Test --format json with --db-path - result = runner.invoke(cli, ["config", "location", "--format", "json", "--db-path"]) + result = runner.invoke(cli, ["configure", "location", "--format", "json", "--db-path"]) assert result.exit_code != 0 assert "only one output option" in result.output.lower() # Test --db-path with --app-dir - result = runner.invoke(cli, ["config", "location", "--db-path", "--app-dir"]) + result = runner.invoke(cli, ["configure", "location", "--db-path", "--app-dir"]) assert result.exit_code != 0 assert "only one output option" in result.output.lower() # Test --format json with --app-dir - result = runner.invoke(cli, ["config", "location", "--format", "json", "--app-dir"]) + result = runner.invoke(cli, ["configure", "location", "--format", "json", "--app-dir"]) assert result.exit_code != 0 assert "only one output option" in result.output.lower() @@ -236,7 +236,7 @@ def test_config_location_json_encoding(monkeypatch, tmp_path: Path) -> None: runner = CliRunner() # Test --db-path with special characters in path - result = runner.invoke(cli, ["config", "location", "--db-path"]) + result = runner.invoke(cli, ["configure", "location", "--db-path"]) assert result.exit_code == 0, result.output # Verify JSON is properly encoded and parseable parsed = json.loads(result.stdout) @@ -244,29 +244,38 @@ def test_config_location_json_encoding(monkeypatch, tmp_path: Path) -> None: assert "retrocast tests with spaces" in parsed # Test --app-dir with special characters in path - result = runner.invoke(cli, ["config", "location", "--app-dir"]) + result = runner.invoke(cli, ["configure", "location", "--app-dir"]) assert result.exit_code == 0, result.output parsed = json.loads(result.stdout) assert parsed == str(app_dir) assert "retrocast tests with spaces" in parsed -def test_meta_group_exposes_overcast_transcripts_help() -> None: +def test_subscribe_group_exposes_overcast_transcripts_help() -> None: runner = CliRunner() - result = runner.invoke(cli, ["meta", "overcast", "transcripts", "--help"]) + result = runner.invoke(cli, ["subscribe", "overcast", "transcripts", "--help"]) assert result.exit_code == 0 assert "Download available transcripts" in result.output +def test_index_group_exposes_status_help() -> None: + runner = CliRunner() + + result = runner.invoke(cli, ["index", "status", "--help"]) + + assert result.exit_code == 0 + assert "Show index command availability" in result.output + + def test_config_initialize_creates_database_with_schemas(monkeypatch, tmp_path: Path) -> None: """Test that config initialize creates database with all required schemas.""" app_dir = tmp_path / "retrocast-tests" monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() - result = runner.invoke(cli, ["config", "initialize", "-y"]) + result = runner.invoke(cli, ["configure", "initialize", "-y"]) assert result.exit_code == 0, result.output assert app_dir.exists() @@ -309,11 +318,11 @@ def test_config_initialize_idempotent(monkeypatch, tmp_path: Path) -> None: runner = CliRunner() # First initialization - result1 = runner.invoke(cli, ["config", "initialize", "-y"]) + result1 = runner.invoke(cli, ["configure", "initialize", "-y"]) assert result1.exit_code == 0 # Second initialization (should succeed without errors) - result2 = runner.invoke(cli, ["config", "initialize", "-y"]) + result2 = runner.invoke(cli, ["configure", "initialize", "-y"]) assert result2.exit_code == 0 # Database should still be valid @@ -321,13 +330,13 @@ def test_config_initialize_idempotent(monkeypatch, tmp_path: Path) -> None: assert db_path.exists() -def test_sync_overcast_init_creates_database_with_schemas(monkeypatch, tmp_path: Path) -> None: - """Test that sync overcast init creates database with all required schemas.""" +def test_subscribe_overcast_init_creates_database_with_schemas(monkeypatch, tmp_path: Path) -> None: + """Test that subscribe overcast init creates database with all required schemas.""" app_dir = tmp_path / "retrocast-tests" monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() - result = runner.invoke(cli, ["sync", "overcast", "init"]) + result = runner.invoke(cli, ["subscribe", "overcast", "init"]) assert result.exit_code == 0, result.output assert app_dir.exists() @@ -362,20 +371,20 @@ def test_sync_overcast_init_creates_database_with_schemas(monkeypatch, tmp_path: assert "Created" in result.output or "Already exists" in result.output -def test_sync_overcast_init_idempotent(monkeypatch, tmp_path: Path) -> None: - """Test that sync overcast init can be run multiple times safely.""" +def test_subscribe_overcast_init_idempotent(monkeypatch, tmp_path: Path) -> None: + """Test that subscribe overcast init can be run multiple times safely.""" app_dir = tmp_path / "retrocast-tests" monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() # First initialization - result1 = runner.invoke(cli, ["sync", "overcast", "init"]) + result1 = runner.invoke(cli, ["subscribe", "overcast", "init"]) assert result1.exit_code == 0 assert "Created" in result1.output # Second initialization (should succeed and report already exists) - result2 = runner.invoke(cli, ["sync", "overcast", "init"]) + result2 = runner.invoke(cli, ["subscribe", "overcast", "init"]) assert result2.exit_code == 0 assert "Already exists" in result2.output diff --git a/tests/test_docs_generation.py b/tests/test_docs_generation.py index ccf5ef4..003354c 100644 --- a/tests/test_docs_generation.py +++ b/tests/test_docs_generation.py @@ -16,13 +16,12 @@ def test_docs_cli_directory_exists(): "README.md", "index.md", "about.md", - "castchat.md", - "config.md", + "chat.md", + "configure.md", "download.md", - "meta.md", - "sql.md", - "sync.md", - "transcription.md", + "query.md", + "subscribe.md", + "transcribe.md", ] for filename in expected_files: @@ -52,14 +51,13 @@ def test_docs_check_command(): # Get list of markdown files to check (excluding README.md which doesn't have cog directives) docs_files = [ "docs/cli/about.md", - "docs/cli/castchat.md", - "docs/cli/config.md", + "docs/cli/chat.md", + "docs/cli/configure.md", "docs/cli/download.md", "docs/cli/index.md", - "docs/cli/meta.md", - "docs/cli/sql.md", - "docs/cli/sync.md", - "docs/cli/transcription.md", + "docs/cli/query.md", + "docs/cli/subscribe.md", + "docs/cli/transcribe.md", ] # Run the docs:check task @@ -82,7 +80,7 @@ def test_cog_directives_present(): docs_cli_dir = Path("docs/cli") # Check a few key files for cog directives - files_to_check = ["index.md", "config.md", "download.md"] + files_to_check = ["index.md", "configure.md", "download.md"] for filename in files_to_check: file_path = docs_cli_dir / filename @@ -125,13 +123,13 @@ def test_all_command_groups_documented(): # These are the main command groups from the CLI command_groups = [ "about", - "castchat", - "config", + "chat", + "configure", "download", - "meta", - "sql", - "sync", - "transcription", + "index", + "query", + "subscribe", + "transcribe", ] for command in command_groups: @@ -145,7 +143,7 @@ def test_clean_help_output_imported_not_defined(): """Test that clean_help_output is imported from doc_utils, not defined inline.""" docs_files = [ "docs/cli/download.md", - "docs/cli/transcription.md", + "docs/cli/transcribe.md", ] for filepath in docs_files: diff --git a/tests/test_process_commands.py b/tests/test_process_commands.py index 4dbd633..1628a0b 100644 --- a/tests/test_process_commands.py +++ b/tests/test_process_commands.py @@ -20,7 +20,7 @@ def runner(self): def test_transcription_help(self, runner): """Test transcription command help.""" - result = runner.invoke(cli, ["transcription", "--help"]) + result = runner.invoke(cli, ["transcribe", "--help"]) assert result.exit_code == 0 assert "Manage audio transcriptions" in result.output assert "process" in result.output @@ -28,20 +28,20 @@ def test_transcription_help(self, runner): def test_list_backends(self, runner): """Test backends list command.""" - result = runner.invoke(cli, ["transcription", "backends", "list"]) + result = runner.invoke(cli, ["transcribe", "backends", "list"]) assert result.exit_code == 0 assert "Backend" in result.output assert "mlx-whisper" in result.output def test_test_backend_unknown(self, runner): """Test backends test with unknown backend.""" - result = runner.invoke(cli, ["transcription", "backends", "test", "nonexistent"]) + result = runner.invoke(cli, ["transcribe", "backends", "test", "nonexistent"]) assert result.exit_code == 0 assert "Unknown backend" in result.output def test_test_backend_mlx(self, runner): """Test backends test with MLX backend.""" - result = runner.invoke(cli, ["transcription", "backends", "test", "mlx-whisper"]) + result = runner.invoke(cli, ["transcribe", "backends", "test", "mlx-whisper"]) assert result.exit_code == 0 assert "mlx-whisper" in result.output # Should show not available on non-macOS or without mlx_whisper installed @@ -51,13 +51,13 @@ def test_test_backend_mlx(self, runner): def test_process_no_paths(self, runner): """Test process command with no paths.""" - result = runner.invoke(cli, ["transcription", "process"]) + result = runner.invoke(cli, ["transcribe", "process"]) assert result.exit_code != 0 # Should error because no paths provided def test_process_help(self, runner): """Test process command help.""" - result = runner.invoke(cli, ["transcription", "process", "--help"]) + result = runner.invoke(cli, ["transcribe", "process", "--help"]) assert result.exit_code == 0 assert "Process audio files" in result.output assert "--backend" in result.output @@ -71,7 +71,7 @@ def test_process_list_podcasts_no_downloads(self, runner): """Test process --list-podcasts with no downloads directory.""" with runner.isolated_filesystem(): result = runner.invoke( - cli, ["transcription", "process", "--list-podcasts", "--db", "test.db"] + cli, ["transcribe", "process", "--list-podcasts", "--db", "test.db"] ) assert result.exit_code == 0 # Should show message about no downloads @@ -88,14 +88,14 @@ def test_process_from_downloads_no_directory(self, runner): cwd = Path(os.getcwd()) with patch("retrocast.process_commands.get_app_dir", return_value=cwd): result = runner.invoke( - cli, ["transcription", "process", "--from-downloads", "--db", "test.db"] + cli, ["transcribe", "process", "--from-downloads", "--db", "test.db"] ) assert result.exit_code != 0 assert "downloads directory not found" in result.output def test_search_help(self, runner): """Test search command help.""" - result = runner.invoke(cli, ["transcription", "search", "--help"]) + result = runner.invoke(cli, ["transcribe", "search", "--help"]) assert result.exit_code == 0 assert "Search transcribed podcast content" in result.output assert "--podcast" in result.output @@ -111,7 +111,7 @@ def test_search_help(self, runner): def test_search_no_query(self, runner): """Test search command with no query.""" - result = runner.invoke(cli, ["transcription", "search"]) + result = runner.invoke(cli, ["transcribe", "search"]) assert result.exit_code != 0 # Should error because query is required @@ -119,7 +119,7 @@ def test_search_no_database(self, runner): """Test search command with non-existent/empty database.""" with runner.isolated_filesystem(): result = runner.invoke( - cli, ["transcription", "search", "test", "--db", "nonexistent.db"] + cli, ["transcribe", "search", "test", "--db", "nonexistent.db"] ) # Should succeed but find no results (empty database created) assert result.exit_code == 0 @@ -127,7 +127,7 @@ def test_search_no_database(self, runner): def test_summary_help(self, runner): """Test summary command help.""" - result = runner.invoke(cli, ["transcription", "summary", "--help"]) + result = runner.invoke(cli, ["transcribe", "summary", "--help"]) assert result.exit_code == 0 assert "Display overall transcription statistics" in result.output @@ -135,7 +135,7 @@ def test_summary_no_database(self, runner): """Test summary command with new/empty database.""" with runner.isolated_filesystem(): result = runner.invoke( - cli, ["transcription", "summary", "--db", "test.db"] + cli, ["transcribe", "summary", "--db", "test.db"] ) # Should succeed but show no transcriptions message assert result.exit_code == 0 @@ -143,7 +143,7 @@ def test_summary_no_database(self, runner): def test_podcasts_list_help(self, runner): """Test podcasts list command help.""" - result = runner.invoke(cli, ["transcription", "podcasts", "list", "--help"]) + result = runner.invoke(cli, ["transcribe", "podcasts", "list", "--help"]) assert result.exit_code == 0 assert "List all podcasts with transcriptions" in result.output assert "--limit" in result.output @@ -152,14 +152,14 @@ def test_podcasts_list_no_database(self, runner): """Test podcasts list with new/empty database.""" with runner.isolated_filesystem(): result = runner.invoke( - cli, ["transcription", "podcasts", "list", "--db", "test.db"] + cli, ["transcribe", "podcasts", "list", "--db", "test.db"] ) assert result.exit_code == 0 assert "No transcriptions found" in result.output def test_podcasts_summary_help(self, runner): """Test podcasts summary command help.""" - result = runner.invoke(cli, ["transcription", "podcasts", "summary", "--help"]) + result = runner.invoke(cli, ["transcribe", "podcasts", "summary", "--help"]) assert result.exit_code == 0 assert "Show summary statistics for podcasts" in result.output @@ -167,14 +167,14 @@ def test_podcasts_summary_no_database(self, runner): """Test podcasts summary with new/empty database.""" with runner.isolated_filesystem(): result = runner.invoke( - cli, ["transcription", "podcasts", "summary", "--db", "test.db"] + cli, ["transcribe", "podcasts", "summary", "--db", "test.db"] ) assert result.exit_code == 0 assert "No transcriptions found" in result.output def test_episodes_list_help(self, runner): """Test episodes list command help.""" - result = runner.invoke(cli, ["transcription", "episodes", "list", "--help"]) + result = runner.invoke(cli, ["transcribe", "episodes", "list", "--help"]) assert result.exit_code == 0 assert "List transcribed episodes" in result.output assert "--podcast" in result.output @@ -186,14 +186,14 @@ def test_episodes_list_no_database(self, runner): """Test episodes list with new/empty database.""" with runner.isolated_filesystem(): result = runner.invoke( - cli, ["transcription", "episodes", "list", "--db", "test.db"] + cli, ["transcribe", "episodes", "list", "--db", "test.db"] ) assert result.exit_code == 0 assert "No transcriptions found" in result.output def test_episodes_summary_help(self, runner): """Test episodes summary command help.""" - result = runner.invoke(cli, ["transcription", "episodes", "summary", "--help"]) + result = runner.invoke(cli, ["transcribe", "episodes", "summary", "--help"]) assert result.exit_code == 0 assert "Show summary statistics for transcribed episodes" in result.output assert "--podcast" in result.output @@ -202,7 +202,7 @@ def test_episodes_summary_no_database(self, runner): """Test episodes summary with new/empty database.""" with runner.isolated_filesystem(): result = runner.invoke( - cli, ["transcription", "episodes", "summary", "--db", "test.db"] + cli, ["transcribe", "episodes", "summary", "--db", "test.db"] ) assert result.exit_code == 0 assert "No transcriptions found" in result.output diff --git a/tests/test_reset_db.py b/tests/test_reset_db.py index a982781..9e3cb57 100644 --- a/tests/test_reset_db.py +++ b/tests/test_reset_db.py @@ -41,7 +41,7 @@ def test_reset_db_with_nonexistent_database(monkeypatch, tmp_path: Path) -> None monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() - result = runner.invoke(cli, ["config", "reset-db"]) + result = runner.invoke(cli, ["configure", "reset-db"]) assert result.exit_code == 0 assert "does not exist" in result.output.lower() @@ -59,7 +59,7 @@ def test_reset_db_dry_run(monkeypatch, tmp_path: Path) -> None: monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() - result = runner.invoke(cli, ["config", "reset-db", "--dry-run"]) + result = runner.invoke(cli, ["configure", "reset-db", "--dry-run"]) assert result.exit_code == 0 assert "dry run" in result.output.lower() @@ -86,7 +86,7 @@ def test_reset_db_with_confirmation_no(monkeypatch, tmp_path: Path) -> None: monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() - result = runner.invoke(cli, ["config", "reset-db"], input="n\n") + result = runner.invoke(cli, ["configure", "reset-db"], input="n\n") assert result.exit_code == 0 assert "cancelled" in result.output.lower() @@ -119,7 +119,7 @@ def test_reset_db_with_confirmation_yes(monkeypatch, tmp_path: Path) -> None: monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() - result = runner.invoke(cli, ["config", "reset-db"], input="y\n") + result = runner.invoke(cli, ["configure", "reset-db"], input="y\n") assert result.exit_code == 0 assert "successfully" in result.output.lower() @@ -148,7 +148,7 @@ def test_reset_db_with_yes_flag(monkeypatch, tmp_path: Path) -> None: monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() - result = runner.invoke(cli, ["config", "reset-db", "-y"]) + result = runner.invoke(cli, ["configure", "reset-db", "-y"]) assert result.exit_code == 0 assert "successfully" in result.output.lower() @@ -175,7 +175,7 @@ def test_reset_db_recreates_all_tables(monkeypatch, tmp_path: Path) -> None: monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() - result = runner.invoke(cli, ["config", "reset-db", "-y"]) + result = runner.invoke(cli, ["configure", "reset-db", "-y"]) assert result.exit_code == 0 @@ -225,7 +225,7 @@ def test_reset_db_dry_run_shows_correct_counts(monkeypatch, tmp_path: Path) -> N monkeypatch.setattr(platformdirs, "user_data_dir", lambda *_, **__: str(app_dir)) runner = CliRunner() - result = runner.invoke(cli, ["config", "reset-db", "--dry-run"]) + result = runner.invoke(cli, ["configure", "reset-db", "--dry-run"]) assert result.exit_code == 0 diff --git a/tests/test_sql_cli_podcast_archiver_attach.py b/tests/test_sql_cli_podcast_archiver_attach.py index 2b9f59d..e15d4ea 100644 --- a/tests/test_sql_cli_podcast_archiver_attach.py +++ b/tests/test_sql_cli_podcast_archiver_attach.py @@ -31,7 +31,7 @@ def test_sql_query_attaches_podcast_archiver(monkeypatch, tmp_path: Path) -> Non result = runner.invoke( cli, [ - "sql", + "query", "--database", str(main_db), "query", @@ -52,7 +52,7 @@ def test_sql_rows_supports_podcast_archiver_tables(monkeypatch, tmp_path: Path) result = runner.invoke( cli, [ - "sql", + "query", "--database", str(main_db), "rows", diff --git a/tests/test_transcription_validate.py b/tests/test_transcription_validate.py index afe3557..58bf0bf 100644 --- a/tests/test_transcription_validate.py +++ b/tests/test_transcription_validate.py @@ -36,7 +36,7 @@ def test_validate_command_with_valid_files(): # Run validate command result = runner.invoke( cli, - ["transcription", "validate", "--output-dir", str(Path(tmpdir) / "transcriptions")], + ["transcribe", "validate", "--output-dir", str(Path(tmpdir) / "transcriptions")], ) assert result.exit_code == 0 @@ -71,7 +71,7 @@ def test_validate_command_with_invalid_files(): # Run validate command result = runner.invoke( cli, - ["transcription", "validate", "--output-dir", str(Path(tmpdir) / "transcriptions")], + ["transcribe", "validate", "--output-dir", str(Path(tmpdir) / "transcriptions")], ) assert result.exit_code == 1 @@ -95,7 +95,7 @@ def test_validate_command_with_broken_json(): # Run validate command result = runner.invoke( cli, - ["transcription", "validate", "--output-dir", str(Path(tmpdir) / "transcriptions")], + ["transcribe", "validate", "--output-dir", str(Path(tmpdir) / "transcriptions")], ) assert result.exit_code == 1 @@ -146,7 +146,7 @@ def test_validate_command_verbose_mode(): result = runner.invoke( cli, [ - "transcription", + "transcribe", "validate", "--output-dir", str(Path(tmpdir) / "transcriptions"), @@ -171,7 +171,7 @@ def test_validate_command_no_files(): # Run validate command result = runner.invoke( - cli, ["transcription", "validate", "--output-dir", str(output_dir)] + cli, ["transcribe", "validate", "--output-dir", str(output_dir)] ) assert result.exit_code == 0 @@ -187,7 +187,7 @@ def test_validate_command_missing_directory(): # Run validate command result = runner.invoke( - cli, ["transcription", "validate", "--output-dir", str(nonexistent)] + cli, ["transcribe", "validate", "--output-dir", str(nonexistent)] ) assert result.exit_code == 1 @@ -224,7 +224,7 @@ def test_validate_command_with_speakers(): # Run validate command result = runner.invoke( cli, - ["transcription", "validate", "--output-dir", str(Path(tmpdir) / "transcriptions")], + ["transcribe", "validate", "--output-dir", str(Path(tmpdir) / "transcriptions")], ) assert result.exit_code == 0