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.
- yt_agent-0.3.0/.dockerignore +18 -0
- yt_agent-0.3.0/.github/ISSUE_TEMPLATE/bug_report.yml +41 -0
- yt_agent-0.3.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- yt_agent-0.3.0/.github/ISSUE_TEMPLATE/feature_request.yml +24 -0
- yt_agent-0.3.0/.github/dependabot.yml +16 -0
- yt_agent-0.3.0/.github/pull_request_template.md +16 -0
- yt_agent-0.3.0/.github/workflows/ci.yml +109 -0
- yt_agent-0.3.0/.github/workflows/release.yml +29 -0
- yt_agent-0.3.0/.gitignore +25 -0
- yt_agent-0.3.0/.pre-commit-config.yaml +26 -0
- yt_agent-0.3.0/AGENTS.md +57 -0
- yt_agent-0.3.0/CHANGELOG.md +81 -0
- yt_agent-0.3.0/CODEOWNERS +1 -0
- yt_agent-0.3.0/CODE_OF_CONDUCT.md +19 -0
- yt_agent-0.3.0/CONTRIBUTING.md +68 -0
- yt_agent-0.3.0/Dockerfile +37 -0
- yt_agent-0.3.0/LICENSE +21 -0
- yt_agent-0.3.0/PKG-INFO +379 -0
- yt_agent-0.3.0/README.md +327 -0
- yt_agent-0.3.0/SECURITY.md +32 -0
- yt_agent-0.3.0/SUPPORT.md +13 -0
- yt_agent-0.3.0/THIRD_PARTY.md +34 -0
- yt_agent-0.3.0/assets/brand/yt-agent-hero.png +0 -0
- yt_agent-0.3.0/assets/screenshots/cleanup-dry-run.png +0 -0
- yt_agent-0.3.0/assets/screenshots/cleanup-dry-run.svg +65 -0
- yt_agent-0.3.0/assets/screenshots/clips-search.png +0 -0
- yt_agent-0.3.0/assets/screenshots/doctor-updated.png +0 -0
- yt_agent-0.3.0/assets/screenshots/doctor-updated.svg +129 -0
- yt_agent-0.3.0/assets/screenshots/doctor.png +0 -0
- yt_agent-0.3.0/assets/screenshots/export-json.png +0 -0
- yt_agent-0.3.0/assets/screenshots/export-json.svg +182 -0
- yt_agent-0.3.0/assets/screenshots/history.png +0 -0
- yt_agent-0.3.0/assets/screenshots/history.svg +100 -0
- yt_agent-0.3.0/assets/screenshots/library-channels.png +0 -0
- yt_agent-0.3.0/assets/screenshots/library-channels.svg +84 -0
- yt_agent-0.3.0/assets/screenshots/playlist-select.png +0 -0
- yt_agent-0.3.0/assets/screenshots/search.png +0 -0
- yt_agent-0.3.0/assets/screenshots/tui.png +0 -0
- yt_agent-0.3.0/assets/screenshots/verbose.png +0 -0
- yt_agent-0.3.0/assets/screenshots/verbose.svg +144 -0
- yt_agent-0.3.0/config/config.sample.toml +16 -0
- yt_agent-0.3.0/docs/agent-workflows.md +245 -0
- yt_agent-0.3.0/docs/architecture.md +651 -0
- yt_agent-0.3.0/docs/command-reference.md +88 -0
- yt_agent-0.3.0/docs/concepts.md +111 -0
- yt_agent-0.3.0/docs/faq.md +41 -0
- yt_agent-0.3.0/docs/getting-started.md +195 -0
- yt_agent-0.3.0/docs/recipes.md +189 -0
- yt_agent-0.3.0/docs/release-checklist.md +42 -0
- yt_agent-0.3.0/docs/roadmap.md +27 -0
- yt_agent-0.3.0/docs/shell-completion.md +105 -0
- yt_agent-0.3.0/docs/support-matrix.md +48 -0
- yt_agent-0.3.0/docs/troubleshooting.md +99 -0
- yt_agent-0.3.0/docs/workflow.md +88 -0
- yt_agent-0.3.0/examples/agents/antigraviti.md +16 -0
- yt_agent-0.3.0/examples/agents/approval-safe-download.md +29 -0
- yt_agent-0.3.0/examples/agents/claude-code.md +20 -0
- yt_agent-0.3.0/examples/agents/clip-hunter.md +34 -0
- yt_agent-0.3.0/examples/agents/codex.md +20 -0
- yt_agent-0.3.0/examples/agents/gemini-cli.md +16 -0
- yt_agent-0.3.0/examples/agents/library-curator.md +27 -0
- yt_agent-0.3.0/examples/agents/opencode.md +15 -0
- yt_agent-0.3.0/examples/agents/playlist-curator.md +24 -0
- yt_agent-0.3.0/examples/scripts/batch-clip-extract.sh +257 -0
- yt_agent-0.3.0/examples/scripts/batch-download-from-file.sh +9 -0
- yt_agent-0.3.0/examples/scripts/catalog-backup.sh +115 -0
- yt_agent-0.3.0/examples/scripts/daily-channel-check.sh +282 -0
- yt_agent-0.3.0/examples/scripts/library-cleanup-preview.sh +10 -0
- yt_agent-0.3.0/examples/scripts/library-report.sh +130 -0
- yt_agent-0.3.0/examples/scripts/playlist-curation-preview.sh +10 -0
- yt_agent-0.3.0/examples/scripts/remote-index-and-clip.sh +11 -0
- yt_agent-0.3.0/pyproject.toml +101 -0
- yt_agent-0.3.0/scripts/gen_screenshots.py +207 -0
- yt_agent-0.3.0/skills/yt-agent/SKILL.md +116 -0
- yt_agent-0.3.0/src/yt_agent/__init__.py +7 -0
- yt_agent-0.3.0/src/yt_agent/__main__.py +6 -0
- yt_agent-0.3.0/src/yt_agent/archive.py +29 -0
- yt_agent-0.3.0/src/yt_agent/catalog.py +1036 -0
- yt_agent-0.3.0/src/yt_agent/chapters.py +27 -0
- yt_agent-0.3.0/src/yt_agent/cli.py +1889 -0
- yt_agent-0.3.0/src/yt_agent/cli_download.py +493 -0
- yt_agent-0.3.0/src/yt_agent/cli_output.py +1340 -0
- yt_agent-0.3.0/src/yt_agent/clips.py +354 -0
- yt_agent-0.3.0/src/yt_agent/config.py +319 -0
- yt_agent-0.3.0/src/yt_agent/errors.py +155 -0
- yt_agent-0.3.0/src/yt_agent/indexer.py +312 -0
- yt_agent-0.3.0/src/yt_agent/library.py +129 -0
- yt_agent-0.3.0/src/yt_agent/manifest.py +44 -0
- yt_agent-0.3.0/src/yt_agent/models.py +399 -0
- yt_agent-0.3.0/src/yt_agent/py.typed +0 -0
- yt_agent-0.3.0/src/yt_agent/security.py +149 -0
- yt_agent-0.3.0/src/yt_agent/selector.py +119 -0
- yt_agent-0.3.0/src/yt_agent/transcripts.py +184 -0
- yt_agent-0.3.0/src/yt_agent/tui.py +326 -0
- yt_agent-0.3.0/src/yt_agent/yt_dlp.py +272 -0
- yt_agent-0.3.0/tests/conftest.py +30 -0
- yt_agent-0.3.0/tests/test_catalog.py +812 -0
- yt_agent-0.3.0/tests/test_catalog_bench.py +128 -0
- yt_agent-0.3.0/tests/test_catalog_prop.py +50 -0
- yt_agent-0.3.0/tests/test_cli.py +2270 -0
- yt_agent-0.3.0/tests/test_clips.py +434 -0
- yt_agent-0.3.0/tests/test_config.py +202 -0
- yt_agent-0.3.0/tests/test_indexer.py +347 -0
- yt_agent-0.3.0/tests/test_library.py +109 -0
- yt_agent-0.3.0/tests/test_manifest.py +43 -0
- yt_agent-0.3.0/tests/test_models_prop.py +79 -0
- yt_agent-0.3.0/tests/test_security.py +171 -0
- yt_agent-0.3.0/tests/test_selector.py +199 -0
- yt_agent-0.3.0/tests/test_transcripts.py +234 -0
- yt_agent-0.3.0/tests/test_transcripts_prop.py +64 -0
- yt_agent-0.3.0/tests/test_tui.py +533 -0
- yt_agent-0.3.0/tests/test_workflows.py +316 -0
- yt_agent-0.3.0/tests/test_yt_dlp.py +276 -0
- yt_agent-0.3.0/uv.lock +614 -0
|
@@ -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,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
|
yt_agent-0.3.0/AGENTS.md
ADDED
|
@@ -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.
|