ruff-sync 0.1.6.dev4__tar.gz → 0.1.7.dev1__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.
- ruff_sync-0.1.7.dev1/.agents/cli_animation_plan.md +710 -0
- ruff_sync-0.1.7.dev1/.agents/workflows/update-recordings.md +72 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/PKG-INFO +5 -1
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/README.md +4 -0
- ruff_sync-0.1.7.dev1/docs/assets/recordings/check_drift.gif +0 -0
- ruff_sync-0.1.7.dev1/docs/assets/recordings/check_in_sync.gif +0 -0
- ruff_sync-0.1.7.dev1/docs/assets/recordings/help_overview.gif +0 -0
- ruff_sync-0.1.7.dev1/docs/assets/recordings/init_project.gif +0 -0
- ruff_sync-0.1.7.dev1/docs/assets/recordings/pull_basic.gif +0 -0
- ruff_sync-0.1.7.dev1/docs/assets/recordings/validate_strict.gif +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/ci-integration.md +6 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/index.md +4 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/usage.md +8 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/pyproject.toml +1 -1
- ruff_sync-0.1.7.dev1/tapes/_common.tape +21 -0
- ruff_sync-0.1.7.dev1/tapes/check_drift.tape +38 -0
- ruff_sync-0.1.7.dev1/tapes/check_in_sync.tape +20 -0
- ruff_sync-0.1.7.dev1/tapes/help_overview.tape +27 -0
- ruff_sync-0.1.7.dev1/tapes/init_project.tape +36 -0
- ruff_sync-0.1.7.dev1/tapes/pull_basic.tape +32 -0
- ruff_sync-0.1.7.dev1/tapes/validate_strict.tape +24 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tasks.py +55 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/uv.lock +1 -1
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/DEPENDENCIES.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/TESTING.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/args_refactor_plan.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/decisions/0001-type-refactoring-strategy.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/decisions/0002-tui-node-ast.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/decisions/0003-argument-resolution-layers.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/decisions/README.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/doc-fix.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/docs_update_plan.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/formatters-architecture.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/gitlab-reports.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/issue-102-context.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/plans/issue-100-roadmap-plan.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/plans/issue-116-config-validation.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/ruff.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/adr/SKILL.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/dirty-equals/SKILL.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/dirty-equals/references/common-matchers.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/dirty-equals/references/toml-matching.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/dirty-equals/trigger_eval.json +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/gh-issues/SKILL.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/mike/SKILL.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/mike/references/commands.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/mkdocs-generation/SKILL.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/mkdocs-generation/examples.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/mkdocs-generation/templates/api-reference.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/mkdocs-generation/templates/getting-started.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/mkdocs-generation/templates/index.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/mkdocs-generation/templates/mkdocs.yml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/release-notes-generation/SKILL.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/ruff-sync-usage/SKILL.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/ruff-sync-usage/references/ci-integration.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/ruff-sync-usage/references/configuration.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/ruff-sync-usage/references/troubleshooting.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/skill-creator/SKILL.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/skill-creator/references/best-practices.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/skill-creator/references/evaluating-skills.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/skill-creator/references/optimizing-descriptions.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/skill-creator/references/quickstart.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/skill-creator/references/sources.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/skill-creator/references/using-scripts.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/skill-creator/scripts/scaffold_skill.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/textual/SKILL.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/textual/examples/basic_app.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/textual/examples/reactive_example.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/textual/references/events.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/textual/references/styling.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/textual/references/testing.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/textual/references/widgets.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/type-checking/SKILL.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/type-checking/evals.json +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/type-checking/references/advanced-narrowing.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/type-checking/references/error-code-lookup.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/type-checking/references/generics.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/type-checking/references/naming.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/type-checking/references/protocol-patterns.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/type-checking/references/quickstart.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/type-checking/references/refactoring-patterns.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/type-checking/scripts/audit_types.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/skills/warnings-control/SKILL.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/tui_design.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/tui_requirements.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/tui_rule_browsing.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/tui_rule_browsing_design.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/workflows/add-test-case.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.agents/workflows/update-screenshots.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.git-blame-ignore-revs +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.github/dependabot.yml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.github/workflows/ci.yaml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.github/workflows/complexity.yaml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.gitignore +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.pre-commit-config.yaml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/.pre-commit-hooks.yaml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/AGENTS.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/CONTRIBUTING.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/LICENSE.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/codecov.yml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/configs/data-science-engineering/ruff.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/configs/fastapi/ruff.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/configs/kitchen-sink/ruff.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/agent-skill.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/assets/favicon.png +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/assets/github-job-summary.png +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/assets/github-pr-annotation.png +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/assets/inspect-main.png +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/assets/inspect-search.png +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/assets/logo.png +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/assets/ruff_sync_banner.png +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/assets/screenshots/dashboard.svg +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/assets/screenshots/legend_help.svg +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/assets/screenshots/rule_details.svg +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/assets/screenshots/screenshot_sample.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/assets/screenshots/search_omnibox.svg +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/best-practices.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/configuration.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/contributing.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/examples/advanced-config.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/examples/basic-config.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/gen_ref_pages.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/inspect.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/installation.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/overrides/main.html +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/overrides/partials/version_warning.html +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/pre-commit.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/pre-defined-configs.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/troubleshooting.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/docs/url-resolution.md +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/mkdocs.yml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/scripts/check_dogfood.sh +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/scripts/generate_tui_screenshots.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/scripts/gitclone_dogfood.sh +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/scripts/pull_dogfood.sh +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/skills-lock.json +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/__init__.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/__main__.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/cli.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/config_io.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/constants.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/core.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/dependencies.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/formatters.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/pre_commit.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/system.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/tui/__init__.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/tui/app.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/tui/constants.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/tui/screens.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/tui/themes.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/tui/types_.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/tui/widgets.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/types_.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/src/ruff_sync/validation.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/__init__.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/conftest.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/multi_upstream_final.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/multi_upstream_initial.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/multi_upstream_up1.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/multi_upstream_up2.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/no_changes_final.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/no_changes_initial.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/no_changes_upstream.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/no_dotted_keys_final.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/no_dotted_keys_initial.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/no_dotted_keys_upstream.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/no_ruff_cfg_final.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/no_ruff_cfg_initial.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/no_ruff_cfg_upstream.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/readme_excludes_final.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/readme_excludes_initial.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/readme_excludes_upstream.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/standard_final.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/standard_initial.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/lifecycle_tomls/standard_upstream.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/ruff.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_basic.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_check.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_ci_integration.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_ci_validation.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_config_io.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_config_validation.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_constants.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_corner_cases.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_dependencies.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_deprecation.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_e2e.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_formatters.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_git_fetch.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_minimal_imports.sh +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_pre_commit.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_project.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_rule_logic.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_scaffold.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_serialization.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_system.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_toml_operations.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_url_handling.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/test_whitespace.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/tui/__init__.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/tui/conftest.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/tui/test_themes.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/tui/test_tui.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/tui/test_tui_types.py +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/w_ruff_sync_cfg/pyproject.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/wo_ruff_cfg/pyproject.toml +0 -0
- {ruff_sync-0.1.6.dev4 → ruff_sync-0.1.7.dev1}/tests/wo_ruff_sync_cfg/pyproject.toml +0 -0
|
@@ -0,0 +1,710 @@
|
|
|
1
|
+
# CLI Animation Plan for ruff-sync Documentation
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Add polished terminal GIF animations to `README.md` and the MkDocs documentation site to showcase ruff-sync's key workflows visually. Use a tool that produces **deterministic, version-controlled, agent-automatable** recordings.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Tool Selection: Charmbracelet VHS
|
|
10
|
+
|
|
11
|
+
**[VHS](https://github.com/charmbracelet/vhs)** (19k+ ★) is the clear winner for this project. Here's why:
|
|
12
|
+
|
|
13
|
+
| Criterion | VHS | asciinema | terminalizer |
|
|
14
|
+
|---|---|---|---|
|
|
15
|
+
| Deterministic (code-as-config) | ✅ `.tape` files | ❌ records live | ❌ records live |
|
|
16
|
+
| GIF output | ✅ native | ⚠️ needs agg/svg-term | ✅ native |
|
|
17
|
+
| AI-agent friendly | ✅ simple DSL, text files | ❌ interactive recording | ❌ interactive recording |
|
|
18
|
+
| Version-controllable | ✅ tape files in git | ❌ JSON recordings | ❌ YAML recordings |
|
|
19
|
+
| Theming | ✅ built-in themes | ✅ | ⚠️ |
|
|
20
|
+
| CI-compatible | ✅ Docker image available | ⚠️ | ❌ |
|
|
21
|
+
|
|
22
|
+
### Why VHS is Agent-Friendly
|
|
23
|
+
|
|
24
|
+
VHS uses plain-text `.tape` files with a simple DSL (`Type`, `Enter`, `Sleep`, `Set`). An AI agent can:
|
|
25
|
+
|
|
26
|
+
1. **Write** tape files from scratch (just text)
|
|
27
|
+
2. **Edit** existing tape files to update commands when CLI behavior changes
|
|
28
|
+
3. **Run** `vhs <file>.tape` non-interactively to regenerate GIFs
|
|
29
|
+
4. **Validate** tape files syntactically with `vhs validate <file>.tape`
|
|
30
|
+
|
|
31
|
+
No UI interaction, no screen recording, no manual timing — everything is declarative.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Prerequisites
|
|
36
|
+
|
|
37
|
+
### Install VHS and its dependencies
|
|
38
|
+
|
|
39
|
+
VHS requires `ttyd` and `ffmpeg` to be installed alongside it.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
brew install vhs
|
|
43
|
+
# This also installs ttyd and ffmpeg as dependencies on macOS via Homebrew
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Verify the installation:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
vhs --version
|
|
50
|
+
which ttyd
|
|
51
|
+
which ffmpeg
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Install ruff-sync in the environment
|
|
55
|
+
|
|
56
|
+
The tape files will run `ruff-sync` commands, so it must be callable:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# From the project root:
|
|
60
|
+
uv pip install -e .
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Directory Structure
|
|
66
|
+
|
|
67
|
+
Create the following directory structure:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
docs/
|
|
71
|
+
assets/
|
|
72
|
+
recordings/ # ← NEW: output GIFs go here
|
|
73
|
+
pull_basic.gif
|
|
74
|
+
check_drift.gif
|
|
75
|
+
init_project.gif
|
|
76
|
+
check_in_sync.gif
|
|
77
|
+
validate_strict.gif
|
|
78
|
+
help_overview.gif
|
|
79
|
+
tapes/ # ← NEW: VHS tape source files
|
|
80
|
+
_common.tape # shared settings (sourced by all tapes)
|
|
81
|
+
pull_basic.tape
|
|
82
|
+
check_drift.tape
|
|
83
|
+
init_project.tape
|
|
84
|
+
check_in_sync.tape
|
|
85
|
+
validate_strict.tape
|
|
86
|
+
help_overview.tape
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Step-by-step directory creation
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
mkdir -p docs/assets/recordings
|
|
93
|
+
mkdir -p tapes
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Add `docs/assets/recordings/` to `.gitignore` (optional)
|
|
97
|
+
|
|
98
|
+
If GIFs should be tracked in git (recommended for docs), do NOT add them to `.gitignore`. If they should be regenerated in CI only, add:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
# .gitignore
|
|
102
|
+
docs/assets/recordings/*.gif
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
> [!IMPORTANT]
|
|
106
|
+
> **Recommendation**: Track the GIFs in git so they display on GitHub without CI. They are usually 200-500 KB each.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Tape Files
|
|
111
|
+
|
|
112
|
+
### Shared Settings: `tapes/_common.tape`
|
|
113
|
+
|
|
114
|
+
This file defines the visual settings reused by all tape files via VHS's `Source` command.
|
|
115
|
+
|
|
116
|
+
```tape
|
|
117
|
+
# tapes/_common.tape
|
|
118
|
+
# Shared VHS settings for ruff-sync documentation recordings.
|
|
119
|
+
#
|
|
120
|
+
# All individual tape files should `Source` this file at the top.
|
|
121
|
+
|
|
122
|
+
# ── Terminal appearance ──────────────────────────────────────────
|
|
123
|
+
Set Shell "bash"
|
|
124
|
+
Set FontFamily "JetBrains Mono"
|
|
125
|
+
Set FontSize 16
|
|
126
|
+
Set Width 1200
|
|
127
|
+
Set Height 600
|
|
128
|
+
Set LetterSpacing 1
|
|
129
|
+
Set LineHeight 1.2
|
|
130
|
+
Set Padding 20
|
|
131
|
+
Set Theme "Catppuccin Mocha"
|
|
132
|
+
|
|
133
|
+
# ── Typing behavior ─────────────────────────────────────────────
|
|
134
|
+
Set TypingSpeed 40ms
|
|
135
|
+
|
|
136
|
+
# ── Cursor ───────────────────────────────────────────────────────
|
|
137
|
+
Set CursorBlink false
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
> [!NOTE]
|
|
141
|
+
> The `Source` command in VHS lets tape files inherit settings from `_common.tape`. This keeps styling consistent and editable from one place.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### Tape 1: `tapes/pull_basic.tape` — Basic Sync
|
|
146
|
+
|
|
147
|
+
**Scenario**: Show the core workflow — pulling ruff config from an upstream repo.
|
|
148
|
+
|
|
149
|
+
**Demonstrates**: The primary use case, colorful terminal output, speed of the tool.
|
|
150
|
+
|
|
151
|
+
**Where it goes**: `README.md` hero section, `docs/index.md`, `docs/usage.md`
|
|
152
|
+
|
|
153
|
+
```tape
|
|
154
|
+
# tapes/pull_basic.tape
|
|
155
|
+
# Demonstrates: Basic ruff-sync pull from an upstream repository.
|
|
156
|
+
|
|
157
|
+
Source tapes/_common.tape
|
|
158
|
+
|
|
159
|
+
Require ruff-sync
|
|
160
|
+
|
|
161
|
+
Output docs/assets/recordings/pull_basic.gif
|
|
162
|
+
|
|
163
|
+
# Show the current state of pyproject.toml
|
|
164
|
+
Type "cat pyproject.toml | head -20"
|
|
165
|
+
Enter
|
|
166
|
+
Sleep 1.5s
|
|
167
|
+
|
|
168
|
+
# Run ruff-sync against the upstream
|
|
169
|
+
Type "ruff-sync https://github.com/Kilo59/ruff-sync -v"
|
|
170
|
+
Enter
|
|
171
|
+
Sleep 4s
|
|
172
|
+
|
|
173
|
+
# Show what changed
|
|
174
|
+
Type "git diff pyproject.toml | head -30"
|
|
175
|
+
Enter
|
|
176
|
+
Sleep 3s
|
|
177
|
+
|
|
178
|
+
# Clean up
|
|
179
|
+
Hide
|
|
180
|
+
Type "git checkout pyproject.toml"
|
|
181
|
+
Enter
|
|
182
|
+
Sleep 500ms
|
|
183
|
+
Show
|
|
184
|
+
|
|
185
|
+
Sleep 1s
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
### Tape 2: `tapes/check_drift.tape` — Detecting Configuration Drift
|
|
191
|
+
|
|
192
|
+
**Scenario**: Show `ruff-sync check` detecting drift, displaying a diff, and exiting non-zero.
|
|
193
|
+
|
|
194
|
+
**Demonstrates**: CI use case, colored diff output, exit code behavior.
|
|
195
|
+
|
|
196
|
+
**Where it goes**: `docs/usage.md` (Checking for Drift section), `docs/ci-integration.md`, `README.md` (CI section)
|
|
197
|
+
|
|
198
|
+
> [!IMPORTANT]
|
|
199
|
+
> This tape requires the local `pyproject.toml` to be intentionally out of sync with the upstream to produce a diff. The setup steps below use a temporary modification that is hidden from the recording.
|
|
200
|
+
|
|
201
|
+
```tape
|
|
202
|
+
# tapes/check_drift.tape
|
|
203
|
+
# Demonstrates: Catching configuration drift with `ruff-sync check`.
|
|
204
|
+
|
|
205
|
+
Source tapes/_common.tape
|
|
206
|
+
|
|
207
|
+
Require ruff-sync
|
|
208
|
+
|
|
209
|
+
Output docs/assets/recordings/check_drift.gif
|
|
210
|
+
|
|
211
|
+
# Silently introduce drift so the check fails
|
|
212
|
+
Hide
|
|
213
|
+
Type "cp pyproject.toml pyproject.toml.bak"
|
|
214
|
+
Enter
|
|
215
|
+
Sleep 300ms
|
|
216
|
+
# Remove a rule to simulate drift
|
|
217
|
+
Type `python3 -c "
|
|
218
|
+
t = open('pyproject.toml').read()
|
|
219
|
+
t = t.replace('\"PERF\",\n', '')
|
|
220
|
+
open('pyproject.toml', 'w').write(t)
|
|
221
|
+
"`
|
|
222
|
+
Enter
|
|
223
|
+
Sleep 500ms
|
|
224
|
+
Show
|
|
225
|
+
|
|
226
|
+
# Run the check command
|
|
227
|
+
Type "ruff-sync check --semantic -v"
|
|
228
|
+
Enter
|
|
229
|
+
Sleep 4s
|
|
230
|
+
|
|
231
|
+
# Show the exit code
|
|
232
|
+
Type "echo \"Exit code: $?\""
|
|
233
|
+
Enter
|
|
234
|
+
Sleep 2s
|
|
235
|
+
|
|
236
|
+
# Restore the original file (hidden)
|
|
237
|
+
Hide
|
|
238
|
+
Type "mv pyproject.toml.bak pyproject.toml"
|
|
239
|
+
Enter
|
|
240
|
+
Sleep 300ms
|
|
241
|
+
Show
|
|
242
|
+
|
|
243
|
+
Sleep 1s
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
### Tape 3: `tapes/init_project.tape` — Bootstrapping a New Project
|
|
249
|
+
|
|
250
|
+
**Scenario**: Show `ruff-sync --init` scaffolding a brand-new `pyproject.toml` in an empty directory.
|
|
251
|
+
|
|
252
|
+
**Demonstrates**: Zero-config bootstrapping, `--init` flag, the generated `[tool.ruff-sync]` section.
|
|
253
|
+
|
|
254
|
+
**Where it goes**: `docs/usage.md` (Initializing section), `docs/index.md` (Quick Start)
|
|
255
|
+
|
|
256
|
+
```tape
|
|
257
|
+
# tapes/init_project.tape
|
|
258
|
+
# Demonstrates: Bootstrapping a new project with --init.
|
|
259
|
+
|
|
260
|
+
Source tapes/_common.tape
|
|
261
|
+
|
|
262
|
+
Require ruff-sync
|
|
263
|
+
|
|
264
|
+
Output docs/assets/recordings/init_project.gif
|
|
265
|
+
|
|
266
|
+
# Create and enter a fresh directory
|
|
267
|
+
Type "mkdir /tmp/my-new-project && cd /tmp/my-new-project"
|
|
268
|
+
Enter
|
|
269
|
+
Sleep 500ms
|
|
270
|
+
|
|
271
|
+
Type "ls -la"
|
|
272
|
+
Enter
|
|
273
|
+
Sleep 1s
|
|
274
|
+
|
|
275
|
+
# Initialize from an upstream
|
|
276
|
+
Type "ruff-sync https://github.com/Kilo59/ruff-sync --init -v"
|
|
277
|
+
Enter
|
|
278
|
+
Sleep 4s
|
|
279
|
+
|
|
280
|
+
# Show the generated file
|
|
281
|
+
Type "cat pyproject.toml"
|
|
282
|
+
Enter
|
|
283
|
+
Sleep 3s
|
|
284
|
+
|
|
285
|
+
# Clean up (hidden)
|
|
286
|
+
Hide
|
|
287
|
+
Type "cd - && rm -rf /tmp/my-new-project"
|
|
288
|
+
Enter
|
|
289
|
+
Sleep 300ms
|
|
290
|
+
Show
|
|
291
|
+
|
|
292
|
+
Sleep 1s
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
### Tape 4: `tapes/check_in_sync.tape` — Config is In Sync
|
|
298
|
+
|
|
299
|
+
**Scenario**: Show `ruff-sync check` passing (exit 0) when config is already in sync.
|
|
300
|
+
|
|
301
|
+
**Demonstrates**: Happy-path CI result, green success output.
|
|
302
|
+
|
|
303
|
+
**Where it goes**: `docs/ci-integration.md`, `docs/usage.md`
|
|
304
|
+
|
|
305
|
+
```tape
|
|
306
|
+
# tapes/check_in_sync.tape
|
|
307
|
+
# Demonstrates: Happy path — config is already in sync.
|
|
308
|
+
|
|
309
|
+
Source tapes/_common.tape
|
|
310
|
+
|
|
311
|
+
Require ruff-sync
|
|
312
|
+
|
|
313
|
+
Output docs/assets/recordings/check_in_sync.gif
|
|
314
|
+
|
|
315
|
+
# Run the check — should pass since we're dogfooding our own config
|
|
316
|
+
Type "ruff-sync check --semantic -v"
|
|
317
|
+
Enter
|
|
318
|
+
Sleep 4s
|
|
319
|
+
|
|
320
|
+
# Confirm exit code
|
|
321
|
+
Type "echo \"Exit code: $?\""
|
|
322
|
+
Enter
|
|
323
|
+
Sleep 2s
|
|
324
|
+
|
|
325
|
+
Sleep 1s
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
### Tape 5: `tapes/validate_strict.tape` — Validation and Strict Mode
|
|
331
|
+
|
|
332
|
+
**Scenario**: Show `--validate` and `--strict` flags in action.
|
|
333
|
+
|
|
334
|
+
**Demonstrates**: Config validation, strict mode catching deprecated rules, error output.
|
|
335
|
+
|
|
336
|
+
**Where it goes**: `docs/usage.md` (Validating Before Writing section)
|
|
337
|
+
|
|
338
|
+
```tape
|
|
339
|
+
# tapes/validate_strict.tape
|
|
340
|
+
# Demonstrates: --validate and --strict flags.
|
|
341
|
+
|
|
342
|
+
Source tapes/_common.tape
|
|
343
|
+
|
|
344
|
+
Require ruff-sync
|
|
345
|
+
|
|
346
|
+
Output docs/assets/recordings/validate_strict.gif
|
|
347
|
+
|
|
348
|
+
# First show normal validation passing
|
|
349
|
+
Type "ruff-sync --validate -v"
|
|
350
|
+
Enter
|
|
351
|
+
Sleep 4s
|
|
352
|
+
|
|
353
|
+
Type ""
|
|
354
|
+
Enter
|
|
355
|
+
Sleep 500ms
|
|
356
|
+
|
|
357
|
+
# Now show strict mode
|
|
358
|
+
Type "ruff-sync --strict -v"
|
|
359
|
+
Enter
|
|
360
|
+
Sleep 4s
|
|
361
|
+
|
|
362
|
+
Sleep 2s
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
### Tape 6: `tapes/help_overview.tape` — Help Output
|
|
368
|
+
|
|
369
|
+
**Scenario**: Show the `--help` output for the tool and subcommands.
|
|
370
|
+
|
|
371
|
+
**Demonstrates**: Available commands, flags, general CLI structure.
|
|
372
|
+
|
|
373
|
+
**Where it goes**: `README.md`, `docs/usage.md` (Command Reference section)
|
|
374
|
+
|
|
375
|
+
```tape
|
|
376
|
+
# tapes/help_overview.tape
|
|
377
|
+
# Demonstrates: CLI help output overview.
|
|
378
|
+
|
|
379
|
+
Source tapes/_common.tape
|
|
380
|
+
|
|
381
|
+
Require ruff-sync
|
|
382
|
+
|
|
383
|
+
Output docs/assets/recordings/help_overview.gif
|
|
384
|
+
|
|
385
|
+
Set Height 700
|
|
386
|
+
|
|
387
|
+
# Main help
|
|
388
|
+
Type "ruff-sync --help"
|
|
389
|
+
Enter
|
|
390
|
+
Sleep 3s
|
|
391
|
+
|
|
392
|
+
# Pull help
|
|
393
|
+
Type "ruff-sync pull --help"
|
|
394
|
+
Enter
|
|
395
|
+
Sleep 3s
|
|
396
|
+
|
|
397
|
+
# Check help
|
|
398
|
+
Type "ruff-sync check --help"
|
|
399
|
+
Enter
|
|
400
|
+
Sleep 3s
|
|
401
|
+
|
|
402
|
+
Sleep 1s
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## Invoke Task for Regeneration
|
|
408
|
+
|
|
409
|
+
Add a new Invoke task to `tasks.py` so recordings can be regenerated with a single command.
|
|
410
|
+
|
|
411
|
+
### Task definition
|
|
412
|
+
|
|
413
|
+
Add the following task to `tasks.py`:
|
|
414
|
+
|
|
415
|
+
```python
|
|
416
|
+
@task(
|
|
417
|
+
help={
|
|
418
|
+
"tape": "Specific tape file to record (e.g. 'pull_basic'). Default: all tapes.",
|
|
419
|
+
},
|
|
420
|
+
)
|
|
421
|
+
def recordings(ctx, tape=None):
|
|
422
|
+
"""Regenerate CLI animation GIFs from VHS tape files."""
|
|
423
|
+
import pathlib
|
|
424
|
+
|
|
425
|
+
tapes_dir = pathlib.Path("tapes")
|
|
426
|
+
if not tapes_dir.exists():
|
|
427
|
+
print("❌ tapes/ directory not found. Run from the project root.")
|
|
428
|
+
raise SystemExit(1)
|
|
429
|
+
|
|
430
|
+
# Check VHS is installed
|
|
431
|
+
result = ctx.run("which vhs", hide=True, warn=True)
|
|
432
|
+
if not result.ok:
|
|
433
|
+
print("❌ VHS is not installed. Install with: brew install vhs")
|
|
434
|
+
raise SystemExit(1)
|
|
435
|
+
|
|
436
|
+
if tape:
|
|
437
|
+
tape_file = tapes_dir / f"{tape}.tape"
|
|
438
|
+
if not tape_file.exists():
|
|
439
|
+
print(f"❌ Tape file not found: {tape_file}")
|
|
440
|
+
raise SystemExit(1)
|
|
441
|
+
tape_files = [tape_file]
|
|
442
|
+
else:
|
|
443
|
+
# Process all tape files except _common.tape
|
|
444
|
+
tape_files = sorted(
|
|
445
|
+
f for f in tapes_dir.glob("*.tape") if not f.name.startswith("_")
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
if not tape_files:
|
|
449
|
+
print("⚠️ No tape files found in tapes/")
|
|
450
|
+
return
|
|
451
|
+
|
|
452
|
+
print(f"🎬 Recording {len(tape_files)} tape(s)...")
|
|
453
|
+
for tf in tape_files:
|
|
454
|
+
print(f" 📼 {tf.name}")
|
|
455
|
+
ctx.run(f"vhs {tf}")
|
|
456
|
+
|
|
457
|
+
print("\n🎉 All recordings complete!")
|
|
458
|
+
print(" Output: docs/assets/recordings/")
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
### Register the task alias
|
|
462
|
+
|
|
463
|
+
In the Invoke `ns` (namespace) collection at the bottom of `tasks.py`, add:
|
|
464
|
+
|
|
465
|
+
```python
|
|
466
|
+
ns.add_task(recordings)
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### Usage
|
|
470
|
+
|
|
471
|
+
```bash
|
|
472
|
+
# Regenerate all recordings
|
|
473
|
+
uv run invoke recordings
|
|
474
|
+
|
|
475
|
+
# Regenerate a specific recording
|
|
476
|
+
uv run invoke recordings --tape pull_basic
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
## Documentation Integration
|
|
482
|
+
|
|
483
|
+
### README.md
|
|
484
|
+
|
|
485
|
+
Add the hero GIF right after the banner image (line ~2):
|
|
486
|
+
|
|
487
|
+
```markdown
|
|
488
|
+
<p align="center">
|
|
489
|
+
<img src="https://raw.githubusercontent.com/Kilo59/ruff-sync/main/docs/assets/ruff_sync_banner.png" alt="ruff-sync banner" style="max-width: 600px; width: 100%; height: auto; margin-bottom: 1rem;">
|
|
490
|
+
<br>
|
|
491
|
+
<img src="https://raw.githubusercontent.com/Kilo59/ruff-sync/main/docs/assets/recordings/pull_basic.gif" alt="ruff-sync pull demo" style="max-width: 600px; width: 100%; height: auto;">
|
|
492
|
+
<br>
|
|
493
|
+
<!-- badges -->
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Add the check drift animation in the CI Integration section (~line 287):
|
|
497
|
+
|
|
498
|
+
```markdown
|
|
499
|
+
## CI Integration
|
|
500
|
+
|
|
501
|
+

|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
### docs/index.md
|
|
505
|
+
|
|
506
|
+
Add the hero GIF after the banner:
|
|
507
|
+
|
|
508
|
+
```markdown
|
|
509
|
+

|
|
510
|
+
|
|
511
|
+

|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
Add the init GIF in the Quick Start section:
|
|
515
|
+
|
|
516
|
+
```markdown
|
|
517
|
+
### 1. Initialize a new project (Optional)
|
|
518
|
+
|
|
519
|
+

|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
### docs/usage.md
|
|
523
|
+
|
|
524
|
+
Add animations inline with each section:
|
|
525
|
+
|
|
526
|
+
1. **The Basic Sync** → `pull_basic.gif`
|
|
527
|
+
2. **Checking for Drift** → `check_drift.gif`
|
|
528
|
+
3. **Validating Before Writing** → `validate_strict.gif`
|
|
529
|
+
|
|
530
|
+
Example:
|
|
531
|
+
|
|
532
|
+
```markdown
|
|
533
|
+
## 🌟 Common Workflows
|
|
534
|
+
|
|
535
|
+
### The Basic Sync
|
|
536
|
+
|
|
537
|
+

|
|
538
|
+
|
|
539
|
+
If you want to pull rules from a central repository...
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### docs/ci-integration.md
|
|
543
|
+
|
|
544
|
+
Add the check animations:
|
|
545
|
+
|
|
546
|
+
```markdown
|
|
547
|
+

|
|
548
|
+
|
|
549
|
+

|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
---
|
|
553
|
+
|
|
554
|
+
## Agent Workflow for Updating Recordings
|
|
555
|
+
|
|
556
|
+
Create a new workflow file at `.agents/workflows/update-recordings.md`:
|
|
557
|
+
|
|
558
|
+
```markdown
|
|
559
|
+
---
|
|
560
|
+
description: Regenerate CLI animation GIFs for documentation
|
|
561
|
+
---
|
|
562
|
+
|
|
563
|
+
Use this workflow to update the CLI animation GIFs when commands, output formatting, or CLI behavior changes.
|
|
564
|
+
|
|
565
|
+
### 1. Prerequisites
|
|
566
|
+
// turbo
|
|
567
|
+
1. Verify VHS is installed:
|
|
568
|
+
```bash
|
|
569
|
+
which vhs && vhs --version
|
|
570
|
+
```
|
|
571
|
+
If not installed: `brew install vhs`
|
|
572
|
+
|
|
573
|
+
### 2. Regenerate All Recordings
|
|
574
|
+
// turbo
|
|
575
|
+
1. Run the Invoke task:
|
|
576
|
+
```bash
|
|
577
|
+
uv run invoke recordings
|
|
578
|
+
```
|
|
579
|
+
*This processes all `.tape` files in `tapes/` and outputs GIFs to `docs/assets/recordings/`.*
|
|
580
|
+
|
|
581
|
+
### 3. Regenerate a Single Recording
|
|
582
|
+
// turbo
|
|
583
|
+
1. To regenerate only one:
|
|
584
|
+
```bash
|
|
585
|
+
uv run invoke recordings --tape pull_basic
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
### 4. Verify Output
|
|
589
|
+
1. Check the `docs/assets/recordings/` directory for updated `.gif` files.
|
|
590
|
+
2. Open each GIF to verify it looks correct and the terminal output is legible.
|
|
591
|
+
|
|
592
|
+
### 5. Commit Changes
|
|
593
|
+
1. Stage and commit:
|
|
594
|
+
```bash
|
|
595
|
+
git add docs/assets/recordings/*.gif tapes/*.tape
|
|
596
|
+
git commit -m "docs: update CLI animation recordings"
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
---
|
|
600
|
+
|
|
601
|
+
### Adding a New Recording
|
|
602
|
+
|
|
603
|
+
1. **Create a new tape file** in `tapes/` (e.g., `tapes/my_feature.tape`).
|
|
604
|
+
2. **Start with** `Source tapes/_common.tape` to inherit shared settings.
|
|
605
|
+
3. **Set the output** path: `Output docs/assets/recordings/my_feature.gif`
|
|
606
|
+
4. **Add the commands** using VHS syntax (`Type`, `Enter`, `Sleep`, etc.).
|
|
607
|
+
5. **Test it**: `vhs tapes/my_feature.tape`
|
|
608
|
+
6. **Embed** the GIF in the relevant docs markdown file.
|
|
609
|
+
|
|
610
|
+
### Editing an Existing Recording
|
|
611
|
+
|
|
612
|
+
1. Edit the `.tape` file in `tapes/`.
|
|
613
|
+
2. Run `uv run invoke recordings --tape <name>` to regenerate just that GIF.
|
|
614
|
+
3. Review the output GIF.
|
|
615
|
+
|
|
616
|
+
### VHS Quick Reference (for agents)
|
|
617
|
+
|
|
618
|
+
| Command | Example | What it does |
|
|
619
|
+
|---|---|---|
|
|
620
|
+
| `Source` | `Source tapes/_common.tape` | Include settings from another tape |
|
|
621
|
+
| `Output` | `Output out.gif` | Set output file path and format |
|
|
622
|
+
| `Require` | `Require ruff-sync` | Fail fast if a program is missing |
|
|
623
|
+
| `Set` | `Set FontSize 16` | Configure terminal settings |
|
|
624
|
+
| `Type` | `Type "ruff-sync --help"` | Type characters into the terminal |
|
|
625
|
+
| `Enter` | `Enter` | Press the Enter key |
|
|
626
|
+
| `Sleep` | `Sleep 2s` | Wait for a specified duration |
|
|
627
|
+
| `Hide` | `Hide` | Stop recording (for setup commands) |
|
|
628
|
+
| `Show` | `Show` | Resume recording |
|
|
629
|
+
| `Ctrl+c` | `Ctrl+C` | Send Ctrl+C |
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
---
|
|
633
|
+
|
|
634
|
+
## Optional: CI Workflow for Recording Validation
|
|
635
|
+
|
|
636
|
+
Add a GitHub Actions workflow that validates tape files (but doesn't regenerate GIFs) on every PR that touches `tapes/`:
|
|
637
|
+
|
|
638
|
+
```yaml
|
|
639
|
+
# .github/workflows/validate-tapes.yaml
|
|
640
|
+
name: Validate VHS Tapes
|
|
641
|
+
|
|
642
|
+
on:
|
|
643
|
+
pull_request:
|
|
644
|
+
paths:
|
|
645
|
+
- "tapes/**"
|
|
646
|
+
|
|
647
|
+
jobs:
|
|
648
|
+
validate:
|
|
649
|
+
runs-on: ubuntu-latest
|
|
650
|
+
steps:
|
|
651
|
+
- uses: actions/checkout@v4
|
|
652
|
+
- name: Install VHS
|
|
653
|
+
run: |
|
|
654
|
+
sudo mkdir -p /etc/apt/keyrings
|
|
655
|
+
curl -fsSL https://repo.charm.sh/apt/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/charm.gpg
|
|
656
|
+
echo "deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *" | sudo tee /etc/apt/sources.list.d/charm.list
|
|
657
|
+
sudo apt update && sudo apt install -y vhs
|
|
658
|
+
- name: Validate tape files
|
|
659
|
+
run: |
|
|
660
|
+
for tape in tapes/*.tape; do
|
|
661
|
+
if [[ "$(basename "$tape")" == _* ]]; then continue; fi
|
|
662
|
+
echo "Validating $tape..."
|
|
663
|
+
vhs validate "$tape"
|
|
664
|
+
done
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
> [!TIP]
|
|
668
|
+
> Full GIF regeneration can be done manually or in a separate CI job since it's slow and requires `ttyd` + `ffmpeg`. The validation-only step is fast and catches syntax errors early.
|
|
669
|
+
|
|
670
|
+
---
|
|
671
|
+
|
|
672
|
+
## Execution Checklist
|
|
673
|
+
|
|
674
|
+
| # | Step | Command / Action |
|
|
675
|
+
|---|---|---|
|
|
676
|
+
| 1 | Install VHS | `brew install vhs` |
|
|
677
|
+
| 2 | Create directories | `mkdir -p docs/assets/recordings tapes` |
|
|
678
|
+
| 3 | Create `tapes/_common.tape` | Copy from [Shared Settings](#shared-settings-tapes_commontape) above |
|
|
679
|
+
| 4 | Create all 6 tape files | Copy from [Tape Files](#tape-files) section above |
|
|
680
|
+
| 5 | Test one tape | `vhs tapes/help_overview.tape` (fastest, no side effects) |
|
|
681
|
+
| 6 | Add Invoke task to `tasks.py` | Copy from [Invoke Task](#invoke-task-for-regeneration) above |
|
|
682
|
+
| 7 | Generate all recordings | `uv run invoke recordings` |
|
|
683
|
+
| 8 | Review all GIFs | Open `docs/assets/recordings/*.gif` |
|
|
684
|
+
| 9 | Integrate into README.md | Follow [README.md](#readmemd) integration instructions |
|
|
685
|
+
| 10 | Integrate into MkDocs pages | Follow [docs/ integration](#documentation-integration) instructions |
|
|
686
|
+
| 11 | Create agent workflow | Copy to `.agents/workflows/update-recordings.md` |
|
|
687
|
+
| 12 | (Optional) Add CI validation | Copy [CI workflow](#optional-ci-workflow-for-recording-validation) to `.github/workflows/` |
|
|
688
|
+
| 13 | Commit everything | `git add tapes/ docs/assets/recordings/ .agents/workflows/update-recordings.md` |
|
|
689
|
+
|
|
690
|
+
---
|
|
691
|
+
|
|
692
|
+
## Notes for the Implementing Agent
|
|
693
|
+
|
|
694
|
+
1. **Run tapes from the project root.** VHS will execute commands in the current working directory. Tape files reference relative paths like `tapes/_common.tape`.
|
|
695
|
+
|
|
696
|
+
2. **The `check_drift.tape` needs intentional drift.** It uses `Hide`/`Show` to silently modify `pyproject.toml` before running the check, then restores it. The implementing agent must ensure the Python one-liner in the tape actually removes a rule that exists in the current file.
|
|
697
|
+
|
|
698
|
+
3. **Font availability.** The `JetBrains Mono` font is specified in `_common.tape`. If not installed on the system, VHS will fall back to a default monospace font. For consistent results, install it: `brew install --cask font-jetbrains-mono`.
|
|
699
|
+
|
|
700
|
+
4. **Timing tuning.** The `Sleep` durations in each tape are estimates. After generating, review the GIFs and adjust:
|
|
701
|
+
- Increase `Sleep` if output is cut off
|
|
702
|
+
- Decrease `Sleep` if there's too much dead time
|
|
703
|
+
- Adjust `TypingSpeed` in `_common.tape` for faster/slower typing animation
|
|
704
|
+
|
|
705
|
+
5. **Theme choice.** `Catppuccin Mocha` was chosen to match the dark-mode aesthetic of the MkDocs Material theme. If the project switches to a light theme, change to `Catppuccin Latte` or `One Light` in `_common.tape`.
|
|
706
|
+
|
|
707
|
+
6. **GIF file sizes.** Target under 500 KB per GIF. If a recording is too large:
|
|
708
|
+
- Reduce the terminal `Width`/`Height`
|
|
709
|
+
- Shorten `Sleep` durations
|
|
710
|
+
- Reduce the amount of output shown (pipe through `head`)
|