yt-agent 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. yt_agent-0.3.0/.dockerignore +18 -0
  2. yt_agent-0.3.0/.github/ISSUE_TEMPLATE/bug_report.yml +41 -0
  3. yt_agent-0.3.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  4. yt_agent-0.3.0/.github/ISSUE_TEMPLATE/feature_request.yml +24 -0
  5. yt_agent-0.3.0/.github/dependabot.yml +16 -0
  6. yt_agent-0.3.0/.github/pull_request_template.md +16 -0
  7. yt_agent-0.3.0/.github/workflows/ci.yml +109 -0
  8. yt_agent-0.3.0/.github/workflows/release.yml +29 -0
  9. yt_agent-0.3.0/.gitignore +25 -0
  10. yt_agent-0.3.0/.pre-commit-config.yaml +26 -0
  11. yt_agent-0.3.0/AGENTS.md +57 -0
  12. yt_agent-0.3.0/CHANGELOG.md +81 -0
  13. yt_agent-0.3.0/CODEOWNERS +1 -0
  14. yt_agent-0.3.0/CODE_OF_CONDUCT.md +19 -0
  15. yt_agent-0.3.0/CONTRIBUTING.md +68 -0
  16. yt_agent-0.3.0/Dockerfile +37 -0
  17. yt_agent-0.3.0/LICENSE +21 -0
  18. yt_agent-0.3.0/PKG-INFO +379 -0
  19. yt_agent-0.3.0/README.md +327 -0
  20. yt_agent-0.3.0/SECURITY.md +32 -0
  21. yt_agent-0.3.0/SUPPORT.md +13 -0
  22. yt_agent-0.3.0/THIRD_PARTY.md +34 -0
  23. yt_agent-0.3.0/assets/brand/yt-agent-hero.png +0 -0
  24. yt_agent-0.3.0/assets/screenshots/cleanup-dry-run.png +0 -0
  25. yt_agent-0.3.0/assets/screenshots/cleanup-dry-run.svg +65 -0
  26. yt_agent-0.3.0/assets/screenshots/clips-search.png +0 -0
  27. yt_agent-0.3.0/assets/screenshots/doctor-updated.png +0 -0
  28. yt_agent-0.3.0/assets/screenshots/doctor-updated.svg +129 -0
  29. yt_agent-0.3.0/assets/screenshots/doctor.png +0 -0
  30. yt_agent-0.3.0/assets/screenshots/export-json.png +0 -0
  31. yt_agent-0.3.0/assets/screenshots/export-json.svg +182 -0
  32. yt_agent-0.3.0/assets/screenshots/history.png +0 -0
  33. yt_agent-0.3.0/assets/screenshots/history.svg +100 -0
  34. yt_agent-0.3.0/assets/screenshots/library-channels.png +0 -0
  35. yt_agent-0.3.0/assets/screenshots/library-channels.svg +84 -0
  36. yt_agent-0.3.0/assets/screenshots/playlist-select.png +0 -0
  37. yt_agent-0.3.0/assets/screenshots/search.png +0 -0
  38. yt_agent-0.3.0/assets/screenshots/tui.png +0 -0
  39. yt_agent-0.3.0/assets/screenshots/verbose.png +0 -0
  40. yt_agent-0.3.0/assets/screenshots/verbose.svg +144 -0
  41. yt_agent-0.3.0/config/config.sample.toml +16 -0
  42. yt_agent-0.3.0/docs/agent-workflows.md +245 -0
  43. yt_agent-0.3.0/docs/architecture.md +651 -0
  44. yt_agent-0.3.0/docs/command-reference.md +88 -0
  45. yt_agent-0.3.0/docs/concepts.md +111 -0
  46. yt_agent-0.3.0/docs/faq.md +41 -0
  47. yt_agent-0.3.0/docs/getting-started.md +195 -0
  48. yt_agent-0.3.0/docs/recipes.md +189 -0
  49. yt_agent-0.3.0/docs/release-checklist.md +42 -0
  50. yt_agent-0.3.0/docs/roadmap.md +27 -0
  51. yt_agent-0.3.0/docs/shell-completion.md +105 -0
  52. yt_agent-0.3.0/docs/support-matrix.md +48 -0
  53. yt_agent-0.3.0/docs/troubleshooting.md +99 -0
  54. yt_agent-0.3.0/docs/workflow.md +88 -0
  55. yt_agent-0.3.0/examples/agents/antigraviti.md +16 -0
  56. yt_agent-0.3.0/examples/agents/approval-safe-download.md +29 -0
  57. yt_agent-0.3.0/examples/agents/claude-code.md +20 -0
  58. yt_agent-0.3.0/examples/agents/clip-hunter.md +34 -0
  59. yt_agent-0.3.0/examples/agents/codex.md +20 -0
  60. yt_agent-0.3.0/examples/agents/gemini-cli.md +16 -0
  61. yt_agent-0.3.0/examples/agents/library-curator.md +27 -0
  62. yt_agent-0.3.0/examples/agents/opencode.md +15 -0
  63. yt_agent-0.3.0/examples/agents/playlist-curator.md +24 -0
  64. yt_agent-0.3.0/examples/scripts/batch-clip-extract.sh +257 -0
  65. yt_agent-0.3.0/examples/scripts/batch-download-from-file.sh +9 -0
  66. yt_agent-0.3.0/examples/scripts/catalog-backup.sh +115 -0
  67. yt_agent-0.3.0/examples/scripts/daily-channel-check.sh +282 -0
  68. yt_agent-0.3.0/examples/scripts/library-cleanup-preview.sh +10 -0
  69. yt_agent-0.3.0/examples/scripts/library-report.sh +130 -0
  70. yt_agent-0.3.0/examples/scripts/playlist-curation-preview.sh +10 -0
  71. yt_agent-0.3.0/examples/scripts/remote-index-and-clip.sh +11 -0
  72. yt_agent-0.3.0/pyproject.toml +101 -0
  73. yt_agent-0.3.0/scripts/gen_screenshots.py +207 -0
  74. yt_agent-0.3.0/skills/yt-agent/SKILL.md +116 -0
  75. yt_agent-0.3.0/src/yt_agent/__init__.py +7 -0
  76. yt_agent-0.3.0/src/yt_agent/__main__.py +6 -0
  77. yt_agent-0.3.0/src/yt_agent/archive.py +29 -0
  78. yt_agent-0.3.0/src/yt_agent/catalog.py +1036 -0
  79. yt_agent-0.3.0/src/yt_agent/chapters.py +27 -0
  80. yt_agent-0.3.0/src/yt_agent/cli.py +1889 -0
  81. yt_agent-0.3.0/src/yt_agent/cli_download.py +493 -0
  82. yt_agent-0.3.0/src/yt_agent/cli_output.py +1340 -0
  83. yt_agent-0.3.0/src/yt_agent/clips.py +354 -0
  84. yt_agent-0.3.0/src/yt_agent/config.py +319 -0
  85. yt_agent-0.3.0/src/yt_agent/errors.py +155 -0
  86. yt_agent-0.3.0/src/yt_agent/indexer.py +312 -0
  87. yt_agent-0.3.0/src/yt_agent/library.py +129 -0
  88. yt_agent-0.3.0/src/yt_agent/manifest.py +44 -0
  89. yt_agent-0.3.0/src/yt_agent/models.py +399 -0
  90. yt_agent-0.3.0/src/yt_agent/py.typed +0 -0
  91. yt_agent-0.3.0/src/yt_agent/security.py +149 -0
  92. yt_agent-0.3.0/src/yt_agent/selector.py +119 -0
  93. yt_agent-0.3.0/src/yt_agent/transcripts.py +184 -0
  94. yt_agent-0.3.0/src/yt_agent/tui.py +326 -0
  95. yt_agent-0.3.0/src/yt_agent/yt_dlp.py +272 -0
  96. yt_agent-0.3.0/tests/conftest.py +30 -0
  97. yt_agent-0.3.0/tests/test_catalog.py +812 -0
  98. yt_agent-0.3.0/tests/test_catalog_bench.py +128 -0
  99. yt_agent-0.3.0/tests/test_catalog_prop.py +50 -0
  100. yt_agent-0.3.0/tests/test_cli.py +2270 -0
  101. yt_agent-0.3.0/tests/test_clips.py +434 -0
  102. yt_agent-0.3.0/tests/test_config.py +202 -0
  103. yt_agent-0.3.0/tests/test_indexer.py +347 -0
  104. yt_agent-0.3.0/tests/test_library.py +109 -0
  105. yt_agent-0.3.0/tests/test_manifest.py +43 -0
  106. yt_agent-0.3.0/tests/test_models_prop.py +79 -0
  107. yt_agent-0.3.0/tests/test_security.py +171 -0
  108. yt_agent-0.3.0/tests/test_selector.py +199 -0
  109. yt_agent-0.3.0/tests/test_transcripts.py +234 -0
  110. yt_agent-0.3.0/tests/test_transcripts_prop.py +64 -0
  111. yt_agent-0.3.0/tests/test_tui.py +533 -0
  112. yt_agent-0.3.0/tests/test_workflows.py +316 -0
  113. yt_agent-0.3.0/tests/test_yt_dlp.py +276 -0
  114. yt_agent-0.3.0/uv.lock +614 -0
@@ -0,0 +1,18 @@
1
+ .git
2
+ .github
3
+ .hypothesis
4
+ .mypy_cache
5
+ .pytest_cache
6
+ .ruff_cache
7
+ .tmp-py311
8
+ .tmp-uv-cache
9
+ .uv-cache
10
+ .venv
11
+ __pycache__/
12
+ assets
13
+ dist
14
+ docs
15
+ examples
16
+ output
17
+ tests
18
+ tmp
@@ -0,0 +1,41 @@
1
+ name: Bug report
2
+ description: Report a reproducible problem in yt-agent
3
+ title: "[Bug]: "
4
+ labels:
5
+ - bug
6
+ body:
7
+ - type: markdown
8
+ attributes:
9
+ value: |
10
+ Thanks for filing a bug. Please include a command, platform, and enough detail to reproduce the issue.
11
+ - type: input
12
+ id: platform
13
+ attributes:
14
+ label: Platform
15
+ placeholder: macOS 15, Ubuntu 24.04, Windows 11
16
+ validations:
17
+ required: true
18
+ - type: textarea
19
+ id: command
20
+ attributes:
21
+ label: Command
22
+ description: Paste the exact command you ran.
23
+ validations:
24
+ required: true
25
+ - type: textarea
26
+ id: expected
27
+ attributes:
28
+ label: Expected behavior
29
+ validations:
30
+ required: true
31
+ - type: textarea
32
+ id: actual
33
+ attributes:
34
+ label: Actual behavior
35
+ validations:
36
+ required: true
37
+ - type: textarea
38
+ id: diagnostics
39
+ attributes:
40
+ label: Diagnostics
41
+ description: Include `yt-agent doctor` output and relevant errors. Remove secrets, cookies, and private paths you do not want public.
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: true
2
+ contact_links:
3
+ - name: Security policy
4
+ url: https://github.com/jvogan/yt-agent/blob/main/SECURITY.md
5
+ about: Please do not report security vulnerabilities in public issues.
@@ -0,0 +1,24 @@
1
+ name: Feature request
2
+ description: Suggest an improvement to yt-agent
3
+ title: "[Feature]: "
4
+ labels:
5
+ - enhancement
6
+ body:
7
+ - type: textarea
8
+ id: problem
9
+ attributes:
10
+ label: Workflow problem
11
+ description: Describe the user workflow that is awkward or unsupported today.
12
+ validations:
13
+ required: true
14
+ - type: textarea
15
+ id: proposal
16
+ attributes:
17
+ label: Proposed behavior
18
+ validations:
19
+ required: true
20
+ - type: textarea
21
+ id: automation
22
+ attributes:
23
+ label: Human or agent use
24
+ description: Explain whether this is mainly for direct terminal use, coding-agent use, or both.
@@ -0,0 +1,16 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "github-actions"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ open-pull-requests-limit: 10
8
+ commit-message:
9
+ prefix: "ci:"
10
+ - package-ecosystem: "pip"
11
+ directory: "/"
12
+ schedule:
13
+ interval: "weekly"
14
+ open-pull-requests-limit: 10
15
+ commit-message:
16
+ prefix: "deps:"
@@ -0,0 +1,16 @@
1
+ ## Summary
2
+
3
+ - what changed
4
+ - why it changed
5
+
6
+ ## Validation
7
+
8
+ - [ ] `uv run ruff check .`
9
+ - [ ] `uv run pytest`
10
+ - [ ] `uv build`
11
+
12
+ ## Notes
13
+
14
+ - config or output changes
15
+ - docs changes
16
+ - compatibility or migration concerns
@@ -0,0 +1,109 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - "codex/**"
8
+ pull_request:
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ secrets:
15
+ name: Secret Scan
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
19
+ with:
20
+ fetch-depth: 0
21
+ - name: Install gitleaks
22
+ shell: bash
23
+ run: |
24
+ set -euo pipefail
25
+ version="8.30.0"
26
+ arch="$(uname -m)"
27
+ case "$arch" in
28
+ x86_64)
29
+ asset="gitleaks_${version}_linux_x64.tar.gz"
30
+ checksum="79a3ab579b53f71efd634f3aaf7e04a0fa0cf206b7ed434638d1547a2470a66e"
31
+ ;;
32
+ aarch64|arm64)
33
+ asset="gitleaks_${version}_linux_arm64.tar.gz"
34
+ checksum="b4cbbb6ddf7d1b2a603088cd03a4e3f7ce48ee7fd449b51f7de6ee2906f5fa2f"
35
+ ;;
36
+ *)
37
+ echo "Unsupported runner architecture: $arch"
38
+ exit 1
39
+ ;;
40
+ esac
41
+
42
+ mkdir -p "$RUNNER_TEMP/bin"
43
+ curl -fsSLo "$RUNNER_TEMP/$asset" "https://github.com/gitleaks/gitleaks/releases/download/v${version}/$asset"
44
+ echo "${checksum} $RUNNER_TEMP/$asset" | sha256sum -c -
45
+ tar -xzf "$RUNNER_TEMP/$asset" -C "$RUNNER_TEMP"
46
+ install -m 0755 "$RUNNER_TEMP/gitleaks" "$RUNNER_TEMP/bin/gitleaks"
47
+ echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
48
+ - name: Gitleaks
49
+ run: gitleaks git . --no-banner --redact
50
+
51
+ test:
52
+ name: Test (${{ matrix.os }}, py${{ matrix.python-version }})
53
+ runs-on: ${{ matrix.os }}
54
+ strategy:
55
+ fail-fast: false
56
+ matrix:
57
+ os:
58
+ - ubuntu-latest
59
+ - macos-latest
60
+ python-version:
61
+ - "3.11"
62
+ - "3.12"
63
+ - "3.13"
64
+ - "3.14"
65
+ steps:
66
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
67
+ - name: Hygiene
68
+ shell: bash
69
+ run: |
70
+ blocked_files="$(git ls-files | grep -E '(^|/)\.env(\..+)?$|(^|/)cookies[^/]*\.txt$|\.sqlite3?$|\.db$|\.jsonl$' || true)"
71
+ if [ -n "$blocked_files" ]; then
72
+ echo "Tracked files must not include local state or secret-looking artifacts:"
73
+ echo "$blocked_files"
74
+ exit 1
75
+ fi
76
+ - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
77
+ with:
78
+ python-version: ${{ matrix.python-version }}
79
+ - name: Install uv
80
+ uses: astral-sh/setup-uv@e06108dd0aef18192324c70427afc47652e63a82 # v7.5.0
81
+ - name: Sync
82
+ run: uv sync --dev
83
+ - name: Lint
84
+ run: uv run ruff check .
85
+ - name: Type check
86
+ run: uv run mypy
87
+ - name: Test
88
+ run: uv run pytest --cov --cov-report=term-missing
89
+ - name: CLI Smoke
90
+ run: |
91
+ uv run yt-agent --version
92
+ uv run yt-agent --help
93
+ build:
94
+ name: Build
95
+ runs-on: ubuntu-latest
96
+ steps:
97
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
98
+ - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
99
+ with:
100
+ python-version: "3.11"
101
+ - name: Install uv
102
+ uses: astral-sh/setup-uv@e06108dd0aef18192324c70427afc47652e63a82 # v7.5.0
103
+ - name: Build distributions
104
+ run: uv build
105
+ - name: Check distributions
106
+ run: uv run --with twine twine check dist/*
107
+ - name: Install smoke
108
+ run: |
109
+ uv tool run --from . yt-agent --help
@@ -0,0 +1,29 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ publish:
11
+ name: Publish to PyPI
12
+ runs-on: ubuntu-latest
13
+ environment: pypi
14
+ permissions:
15
+ contents: read
16
+ id-token: write
17
+ steps:
18
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
19
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
20
+ with:
21
+ python-version: "3.11"
22
+ - name: Install uv
23
+ uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86
24
+ - name: Build distributions
25
+ run: uv build
26
+ - name: Check distributions
27
+ run: uv run --with twine twine check dist/*
28
+ - name: Publish to PyPI
29
+ uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e
@@ -0,0 +1,25 @@
1
+ .pytest_cache/
2
+ .ruff_cache/
3
+ .venv/
4
+ .tmp-py311/
5
+ __pycache__/
6
+ *.py[cod]
7
+ *.egg-info/
8
+ build/
9
+ dist/
10
+ .DS_Store
11
+ coverage.xml
12
+ htmlcov/
13
+ output/
14
+ tmp/
15
+ assets/tmp/
16
+ .env
17
+ .env.*
18
+ cookies.txt
19
+ cookies*.txt
20
+ *.sqlite
21
+ *.sqlite3
22
+ *.db
23
+ *.jsonl
24
+ .claude/
25
+ .hypothesis/
@@ -0,0 +1,26 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.12.0
4
+ hooks:
5
+ - id: ruff
6
+ args:
7
+ - --fix
8
+ - id: ruff-format
9
+
10
+ - repo: https://github.com/pre-commit/mirrors-mypy
11
+ rev: v1.15.0
12
+ hooks:
13
+ - id: mypy
14
+ additional_dependencies:
15
+ - rich>=14.0.0
16
+ - textual>=2.1.2
17
+ - typer>=0.16.0
18
+ pass_filenames: false
19
+
20
+ - repo: https://github.com/pre-commit/pre-commit-hooks
21
+ rev: v5.0.0
22
+ hooks:
23
+ - id: trailing-whitespace
24
+ - id: end-of-file-fixer
25
+ - id: check-yaml
26
+ - id: check-toml
@@ -0,0 +1,57 @@
1
+ # yt-agent — Agent Guide
2
+
3
+ ## What this is
4
+ Terminal-first YouTube CLI built on yt-dlp. Search, download, catalog (SQLite+FTS5), clip extraction, Textual TUI.
5
+
6
+ ## Dev commands
7
+ - Install: `uv sync --dev`
8
+ - Run tests: `uv run pytest --cov` (fallback: `python -m pytest --cov`)
9
+ - Lint: `uv run ruff check .` (fallback: `python -m ruff check .`)
10
+ - Type check: `uv run mypy`
11
+ - Build: `uv build`
12
+
13
+ ## Key pattern and convention guide
14
+
15
+ ### SQL safety
16
+ - Always use `?` placeholders for SQL parameters
17
+ - LIKE queries use `ESCAPE '\'`
18
+ - FTS5 queries are sanitized per-token via `_fts_query()` in `catalog.py`
19
+
20
+ ### Security pattern
21
+ - All user-facing text goes through `sanitize_terminal_text()` from `security.py`
22
+ - File permissions: 0o700 dirs, 0o600 files on POSIX
23
+ - URL allowlisting via `ALLOWED_YOUTUBE_HOSTS` in `yt_dlp.py`
24
+ - Subprocess calls are list-based only, never `shell=True`
25
+
26
+ ### CLI convention
27
+ - Every command wraps logic in `_run_guarded()` which catches `YtAgentError`, `sqlite3.Error`, `KeyboardInterrupt`
28
+ - `dict[str, Any]` for JSON payloads in cli.py is intentional — do not replace with TypedDict
29
+ - Exit codes: OK=0, DEPENDENCY=3, INPUT=4, CONFIG=5, EXTERNAL=6, BUSY=7, STORAGE=8, INTERRUPTED=130
30
+ - `operation_lock()` prevents concurrent mutations — acquire for writes, not reads
31
+
32
+ ### Output convention
33
+ - Read commands support `--output table|json|plain`
34
+ - Mutation commands support `--output json`, `--dry-run`, `--quiet`
35
+ - JSON error envelopes: `{schema_version, status, exit_code, error_type, message}`
36
+
37
+ ### Model convention
38
+ - All models are `@dataclass(frozen=True)` — immutable
39
+ - `VideoInfo.from_yt_dlp()` handles coercion from raw yt-dlp JSON
40
+
41
+ ## Areas to watch with extra care
42
+
43
+ ### High risk areas
44
+ - `cli.py` (~2350 lines) is the densest module — be careful with imports and the `_run_guarded` pattern
45
+ - `catalog.py` schema changes must preserve backward compatibility
46
+ - Tests heavily use `monkeypatch.setattr("yt_agent.cli.<name>", ...)` — any symbol moved from cli.py must be re-exported so the monkeypatch path still resolves
47
+ - `_fts_query()` sanitization is security-critical — test adversarial inputs
48
+ - `operation_lock` is flock-based (POSIX) / msvcrt (Windows) — platform-specific behavior
49
+
50
+ ### Build verification
51
+ After any changes, verify the full chain:
52
+ ```bash
53
+ uv run ruff check .
54
+ uv run mypy
55
+ uv run pytest --cov
56
+ uv build
57
+ ```
@@ -0,0 +1,81 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is inspired by Keep a Changelog, and this project follows pre-1.0 semantic versioning.
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.3.0] - 2026-03-14
10
+
11
+ ### Added
12
+
13
+ - History-level secret scanning in CI with a pinned `gitleaks` CLI install and checksum verification, plus contributor and release-checklist guidance for local secret scans.
14
+ - Audio-only download mode via `--audio` flag on `download` and `grab`, backed by the `audio_format` and `default_mode` config keys.
15
+ - `--fetch-subs` and `--auto-subs` flags on `download` and `grab` to save subtitle files during download.
16
+ - `--from-file FILE` option on `download` for batch URL input from a text file.
17
+ - `yt-agent export` and `yt-agent import` for catalog portability.
18
+ - `yt-agent history` to inspect recent manifest-backed downloads.
19
+ - `yt-agent cleanup` to remove orphaned subtitle cache directories, empty channel directories, and leftover `.part` files.
20
+ - `yt-agent library channels` to list distinct channels in the catalog.
21
+ - `yt-agent library playlists` to list indexed playlists with video counts.
22
+ - `yt-agent library remove` to delete videos from the catalog by ID.
23
+ - `yt-agent config validate` to check a config file for errors.
24
+ - Shell completion setup support, `--verbose` / `-v` CLI logging, a TUI search/filter bar, and config environment variable overrides.
25
+ - Timestamped YouTube URLs (`?t=NNN`) in clip search and show output.
26
+
27
+ ### Changed
28
+
29
+ - Enabled SQLite WAL mode for the catalog to reduce contention during local mutations.
30
+ - Upgraded library search from `LIKE` matching to FTS5-backed queries for faster catalog browsing.
31
+ - Expanded architecture documentation with module roles and end-to-end data-flow diagrams.
32
+ - Polished package metadata and PyPI release readiness for the `0.3.x` line.
33
+
34
+ ### Fixed
35
+
36
+ - Replaced fragile `assert`-based validation paths in clip and CLI flows with explicit user-facing errors.
37
+ - Narrowed `grab` lock scope and removed duplicate catalog lookups in clip workflows.
38
+ - Added subprocess timeouts around subtitle sidecar fetches.
39
+ - Pruned stale subtitle cache directories when removing catalog entries.
40
+
41
+ ### CI
42
+
43
+ - Added a tag-triggered PyPI release workflow.
44
+ - Reworked CI with separate lint and security stages, expanded macOS coverage in the test matrix, Codecov uploads, and stricter build ordering.
45
+ - Raised the coverage floor to 85%, expanded property-based and module coverage, and enabled broader Ruff rule sets.
46
+
47
+ ### Documentation
48
+
49
+ - Expanded command reference, architecture, support-matrix, troubleshooting, workflow, recipe, and release-checklist docs.
50
+ - Improved getting-started guidance for shell completions and environment-driven configuration.
51
+ - Added broader module docstrings across the public API surface.
52
+
53
+ ## [0.2.0] - 2026-03-09
54
+
55
+ ### Added
56
+
57
+ - Public-readiness docs for getting started, concepts, and agent workflows.
58
+ - Public community files including contributing, security, support, code of conduct, issue templates, and a PR template.
59
+ - `yt-agent --version`, `yt-agent config init`, and `yt-agent config path`.
60
+ - `--output table|json|plain` for read-oriented commands.
61
+ - `--select 1,3` for non-interactive search and playlist selection.
62
+ - `yt-agent library stats`.
63
+ - Cross-platform local-media opening in the TUI.
64
+
65
+ ### Changed
66
+
67
+ - Lowered the supported Python floor to 3.11.
68
+ - Expanded CI to a multi-platform, multi-Python matrix and added distribution build checks.
69
+ - Reworked the README around quickstart, golden paths, support matrix, and responsible-use guidance.
70
+ - Clarified that the TUI is a read-mostly catalog browser.
71
+ - Shipped `youtube-cli` as a transitional alias for the `0.2.x` line (removed in `0.3.x`).
72
+
73
+ ### Removed
74
+
75
+ - The duplicate sample config file. `config/config.sample.toml` is now the single canonical example.
76
+
77
+ ## [0.1.0] - 2026-03-08
78
+
79
+ ### Added
80
+
81
+ - Initial private release of `yt-agent` with terminal search, download, catalog, clip, and TUI workflows.
@@ -0,0 +1 @@
1
+ * @jvogan
@@ -0,0 +1,19 @@
1
+ # Code of Conduct
2
+
3
+ This project follows a simple standard: be respectful, be precise, and do not waste other contributors' time.
4
+
5
+ ## Expected Behavior
6
+
7
+ - discuss technical tradeoffs directly and respectfully
8
+ - focus on reproducible reports and concrete improvements
9
+ - assume good faith unless there is clear evidence otherwise
10
+
11
+ ## Unacceptable Behavior
12
+
13
+ - harassment, insults, or personal attacks
14
+ - deliberately disruptive behavior
15
+ - sharing private data, credentials, cookies, or personal media without permission
16
+
17
+ ## Enforcement
18
+
19
+ Project maintainers may remove comments, close issues, or reject contributions that make the project harder to maintain or the discussion unsafe or unproductive.
@@ -0,0 +1,68 @@
1
+ # Contributing
2
+
3
+ Thanks for contributing to `yt-agent`.
4
+
5
+ ## Before You Start
6
+
7
+ - For larger changes, open an issue or start a discussion in the issue tracker first.
8
+ - Keep the project CLI-first. Agent integrations and docs are welcome, but they should not replace a solid terminal workflow.
9
+ - Do not commit cookies, exported browser sessions, downloaded media, subtitle caches, or personal local state.
10
+
11
+ ## Development Setup
12
+
13
+ ```bash
14
+ uv sync --dev
15
+ uv run ruff check .
16
+ uv run pytest
17
+ uv build
18
+ ```
19
+
20
+ ## Pre-commit Hooks
21
+
22
+ Install `pre-commit` locally, then enable the repository hooks:
23
+
24
+ ```bash
25
+ uv tool install pre-commit
26
+ pre-commit install
27
+ ```
28
+
29
+ To run the full hook suite on demand:
30
+
31
+ ```bash
32
+ pre-commit run --all-files
33
+ ```
34
+
35
+ ## Local Security Checks
36
+
37
+ Run a full-history secret scan before opening a PR or cutting a release:
38
+
39
+ ```bash
40
+ gitleaks git . --no-banner --redact
41
+ ```
42
+
43
+ If `gitleaks` is not installed locally yet, install it first. On macOS:
44
+
45
+ ```bash
46
+ brew install gitleaks
47
+ ```
48
+
49
+ If you want to inspect the current working tree, including untracked files, run:
50
+
51
+ ```bash
52
+ gitleaks dir . --no-banner --redact
53
+ ```
54
+
55
+ ## Expectations
56
+
57
+ - Preserve stable exit codes and documented command behavior.
58
+ - Prefer `--output json` support over table scraping when adding new read-oriented features.
59
+ - Keep docs in sync with command behavior.
60
+ - Add or update tests for user-facing changes.
61
+ - Keep the repo free of cookies, local state files, and secret-like artifacts.
62
+
63
+ ## Pull Requests
64
+
65
+ - Keep PRs focused.
66
+ - Mention user-visible behavior changes clearly.
67
+ - Call out config, output, or compatibility changes explicitly.
68
+ - If a change affects automation behavior, document the JSON/plain surface.
@@ -0,0 +1,37 @@
1
+ FROM python:3.12-slim AS builder
2
+
3
+ ENV PIP_NO_CACHE_DIR=1 \
4
+ PYTHONDONTWRITEBYTECODE=1 \
5
+ UV_LINK_MODE=copy
6
+
7
+ WORKDIR /app
8
+
9
+ RUN python -m pip install --upgrade pip uv
10
+
11
+ COPY LICENSE README.md pyproject.toml ./
12
+ COPY src ./src
13
+
14
+ RUN uv build
15
+
16
+
17
+ FROM python:3.12-slim
18
+
19
+ ENV PIP_NO_CACHE_DIR=1 \
20
+ PYTHONDONTWRITEBYTECODE=1 \
21
+ PYTHONUNBUFFERED=1
22
+
23
+ WORKDIR /work
24
+
25
+ RUN apt-get update \
26
+ && apt-get install --yes --no-install-recommends ffmpeg \
27
+ && rm -rf /var/lib/apt/lists/*
28
+
29
+ RUN python -m pip install --upgrade pip \
30
+ && python -m pip install yt-dlp
31
+
32
+ COPY --from=builder /app/dist/yt_agent-*.whl /tmp/
33
+
34
+ RUN python -m pip install /tmp/yt_agent-*.whl \
35
+ && rm -f /tmp/yt_agent-*.whl
36
+
37
+ ENTRYPOINT ["yt-agent"]
yt_agent-0.3.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jacob Vogan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.