BRISTLENOSE(1)

NAME
bristlenose - user-research transcription and quote extraction engine

SYNOPSIS
bristlenose [command] [options]
bristlenose run input-dir [-o output-dir] [-p project-name] [options]
bristlenose transcribe-only input-dir [-o output-dir] [options]
bristlenose analyze transcripts-dir [-o output-dir] [options]
bristlenose render input-dir [-o output-dir] [options]
bristlenose doctor
bristlenose help [topic]

DESCRIPTION
bristlenose processes user-research interview recordings into structured, themed, timestamped quotes. It transcribes audio locally using Whisper, extracts and enriches quotes via LLM (Anthropic or OpenAI), groups them by screen and theme, and renders a browsable HTML report. Nothing is uploaded; recordings stay on your machine.

The HTML report includes sections (grouped by screen), themes (cross-participant patterns), a sentiment histogram, friction points, user journeys, clickable timecodes with a popout video player, favourite quotes with CSV export, inline editing, and a tag system with auto-suggest.

COMMANDS

run Full pipeline: ingest files, transcribe, identify speakers, extract quotes, cluster by screen, group by theme, update participant registry, render HTML and Markdown reports. Requires an API key. PII redaction is off by default; use --redact-pii to enable.

transcribe-only
    Transcription only. No LLM calls, no API key needed. Produces raw transcript files in output/raw_transcripts/.

analyze
    Run LLM analysis on existing transcript .txt files. Skips ingestion and transcription. Useful after reviewing or editing raw transcripts.

render
    Re-render reports from existing intermediate JSON data. No transcription, no LLM calls, no API key needed. Useful after CSS or JavaScript changes.

doctor
    Check runtime dependencies and show tailored fix instructions. Tests FFmpeg, transcription backend, Whisper model cache, API key validity, network connectivity, PII redaction dependencies, and disk space. Also runs automatically on first invocation and as a pre-flight check before pipeline commands.

help [topic]
    Show detailed help. Topics: commands, config, workflows, or any command name.

OPTIONS

  Global options

-V, --version
    Show version and exit.

--help
    Show command help and exit.

  Options for run

-o, --output DIR
    Output directory. Default: output.

-p, --project NAME
    Project name for the report header. Defaults to the input folder name.

-b, --whisper-backend BACKEND
    Transcription backend: auto (detect hardware), mlx (Apple Silicon GPU), faster-whisper (CUDA/CPU). Default: auto.

-w, --whisper-model MODEL
    Whisper model size: tiny, base, small, medium, large-v3, large-v3-turbo. Default: large-v3-turbo.

-l, --llm PROVIDER
    LLM provider: anthropic, openai. Default: anthropic.

--redact-pii
    Redact personally identifying information from transcripts. PII is retained by default.

--retain-pii
    Retain PII in transcripts (default behaviour). Mutually exclusive with --redact-pii.

--skip-transcription
    Skip audio transcription (use existing transcripts).

-c, --config PATH
    Path to a bristlenose.toml config file.

--clean
    Delete the output directory before running.

-v, --verbose
    Enable verbose logging.

  Options for transcribe-only

-o, --output DIR
    Output directory.

-w, --whisper-model MODEL
    Whisper model size.

-v, --verbose
    Enable verbose logging.

  Options for analyze

-o, --output DIR
    Output directory.

-p, --project NAME
    Project name.

-l, --llm PROVIDER
    LLM provider.

-v, --verbose
    Enable verbose logging.

  Options for render

-o, --output DIR
    Output directory. Must contain an intermediate/ directory from a previous run.

-p, --project NAME
    Project name.

--clean
    Accepted for consistency but ignored — render is always non-destructive (overwrites reports only, never touches transcripts, people.yaml, or intermediate data).

-v, --verbose
    Enable verbose logging.

CONFIGURATION
Settings are loaded in order (last wins):

1.  Built-in defaults

2.  .env file (searched upward from the current directory)

3.  Environment variables with prefix BRISTLENOSE_

4.  CLI flags

  API keys

BRISTLENOSE_ANTHROPIC_API_KEY
    Anthropic API key.

BRISTLENOSE_OPENAI_API_KEY
    OpenAI API key.

  LLM settings

BRISTLENOSE_LLM_PROVIDER
    anthropic or openai. Default: anthropic.

BRISTLENOSE_LLM_MODEL
    Model name. Default: claude-sonnet-4-20250514.

BRISTLENOSE_LLM_MAX_TOKENS
    Maximum response tokens. Default: 8192.

BRISTLENOSE_LLM_TEMPERATURE
    Sampling temperature. Default: 0.1.

BRISTLENOSE_LLM_CONCURRENCY
    Parallel LLM calls. Default: 3.

  Transcription settings

BRISTLENOSE_WHISPER_BACKEND
    auto, mlx, or faster-whisper. Default: auto.

BRISTLENOSE_WHISPER_MODEL
    Model size. Default: large-v3-turbo.

BRISTLENOSE_WHISPER_LANGUAGE
    Language code. Default: en.

BRISTLENOSE_WHISPER_DEVICE
    Device for faster-whisper: cpu, cuda, or auto. Default: auto.

BRISTLENOSE_WHISPER_COMPUTE_TYPE
    Compute type for faster-whisper: int8, float16, or float32. Default: int8.

  PII settings

BRISTLENOSE_PII_ENABLED
    Enable PII redaction. Default: false.

BRISTLENOSE_PII_LLM_PASS
    Extra LLM-based PII pass. Default: false.

BRISTLENOSE_PII_CUSTOM_NAMES
    Comma-separated list of additional names to redact.

  Pipeline settings

BRISTLENOSE_MIN_QUOTE_WORDS
    Minimum words per extracted quote. Default: 5.

BRISTLENOSE_MERGE_SPEAKER_GAP_SECONDS
    Gap threshold for merging consecutive speaker segments. Default: 2.0.

INPUT FILES
bristlenose accepts any mix of audio, video, subtitle, and transcript files:

    Audio:       .wav .mp3 .m4a .flac .ogg .wma .aac
    Video:       .mp4 .mov .avi .mkv .webm
    Subtitles:   .srt .vtt
    Transcripts: .docx (Microsoft Teams exports), .txt

Files sharing a name stem (e.g. p1.mp4 and p1.srt) are treated as a single session. When subtitles or transcripts exist, transcription is skipped for that session.

Platform naming conventions are auto-detected for session grouping: Microsoft Teams recording/transcript suffixes, Zoom cloud prefixes and meeting IDs, Zoom local recording folders, and Google Meet parenthetical timestamps are all stripped before stem comparison.

OUTPUT

    output/
      research_report.html       browsable report
      research_report.md         Markdown version
      transcript_p*.html         per-participant transcript pages
      bristlenose-theme.css      stylesheet (regenerated on every run)
      bristlenose-logo.png       project logo (light mode)
      bristlenose-logo-dark.png  project logo (dark mode)
      bristlenose-player.html    popout video player
      people.yaml                participant registry (stats + editable fields)
      raw_transcripts/           one .txt and .md per participant
      cooked_transcripts/        PII-redacted transcripts (only with --redact-pii)
      intermediate/              JSON snapshots for re-rendering

EXAMPLES
Full pipeline run:

    bristlenose run ./interviews/ -o ./results/ -p "Q1 Usability Study"

Transcribe only (no API key needed):

    bristlenose transcribe-only ./interviews/ -o ./results/

Analyse existing transcripts:

    bristlenose analyze ./results/raw_transcripts/ -o ./results/

Re-render after CSS changes (no API key needed):

    bristlenose render ./interviews/ -o ./results/

Check dependencies and setup:

    bristlenose doctor

Show configuration reference:

    bristlenose help config

HARDWARE
Transcription hardware is auto-detected:

•   Apple Silicon: MLX on Metal GPU

•   NVIDIA: faster-whisper with CUDA

•   Other: CPU fallback

FILES

.env
    Environment variables file, searched upward from the current directory.

.env.example
    Template with all available configuration variables.

bristlenose.toml
    Optional TOML configuration file.

EXIT STATUS

0   Success.

1   Error (missing input, configuration problem, pipeline failure).

BUGS
Report bugs at https://github.com/cassiocassio/bristlenose/issues.

AUTHOR
Cassio https://github.com/cassiocassio

LICENSE
AGPL-3.0. See the LICENSE file in the source distribution.

SEE ALSO
ffmpeg(1), whisper(1)

Full documentation: https://github.com/cassiocassio/bristlenose