{"id":37072810,"url":"https://github.com/fabiandistler/pypet","last_synced_at":"2026-01-14T08:32:53.616Z","repository":{"id":301192048,"uuid":"1003661581","full_name":"fabiandistler/pypet","owner":"fabiandistler","description":"A modern command-line snippet manager with Git sync and clipboard integration","archived":false,"fork":false,"pushed_at":"2025-11-12T20:33:57.000Z","size":305,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-12T22:18:28.247Z","etag":null,"topics":["cli","clipboard","git","productivity","python","snippets"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/pypet-cli/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fabiandistler.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-06-17T13:31:26.000Z","updated_at":"2025-11-09T13:09:56.000Z","dependencies_parsed_at":"2025-06-25T16:45:08.411Z","dependency_job_id":"0de22098-9e07-4830-b7c9-7dfb24cb7a41","html_url":"https://github.com/fabiandistler/pypet","commit_stats":null,"previous_names":["fabiandistler/pypet"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/fabiandistler/pypet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabiandistler%2Fpypet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabiandistler%2Fpypet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabiandistler%2Fpypet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabiandistler%2Fpypet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fabiandistler","download_url":"https://codeload.github.com/fabiandistler/pypet/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabiandistler%2Fpypet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28414238,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T08:31:27.429Z","status":"ssl_error","status_checked_at":"2026-01-14T08:31:19.098Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","clipboard","git","productivity","python","snippets"],"created_at":"2026-01-14T08:32:53.020Z","updated_at":"2026-01-14T08:32:53.602Z","avatar_url":"https://github.com/fabiandistler.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pypet - Command Line Snippet Manager\n\n`pypet` is a Python-based command-line snippet manager inspired by [pet](https://github.com/knqyf263/pet). It helps you organize and reuse command-line snippets efficiently, with a focus on simplicity and usability.\n\n## Features\n\n- Store command snippets with descriptions and tags\n- TOML-based storage (`~/.config/pypet/snippets.toml`)\n- List and search your snippets with rich terminal output\n- Interactive command execution with pre-execution editing\n- **Copy snippets to clipboard** for easy pasting into other applications\n- **Shell aliases** - create persistent bash/zsh aliases from snippets\n- **Git synchronization** for backup and sharing across devices\n- Parameterized snippets with default values\n- Automatic backup and restore functionality\n- Tag-based organization\n- Modern Python implementation with type hints\n- Comprehensive test coverage\n\n## Installation\n\n### PyPI (Recommended)\n\n```bash\npip install pypet-cli\n```\n\n### Development Installation\n\n```bash\n# Clone repository\ngit clone https://github.com/fabiandistler/pypet.git\ncd pypet\n\n# Install with uv (recommended)\nuv pip install -e .\n\n# Or with pip\npip install -e .\n```\n\n### Requirements\n\n- Python 3.10 or higher\n- Git (for synchronization features)\n\n## Usage\n\n### Basic Commands\n\n```bash\n# List all snippets\npypet list\n\n# Add a new snippet\npypet new \"git commit -m\" -d \"Create a git commit\" -t \"git,version-control\"\n\n# Save clipboard content as a snippet\npypet save-clipboard -d \"Description\" -t \"tag1,tag2\"\n\n# Save last command(s) from shell history\npypet save-last                    # Save last command\npypet save-last -n 3               # Save last 3 commands\n\n# Search snippets\npypet search \"git\"\n\n# Execute a snippet (interactive if no ID provided)\npypet exec [snippet-id]\n\n# Execute with editing\npypet exec [snippet-id] -e\n\n# Copy a snippet to clipboard\npypet copy [snippet-id]\n\n# Execute with copy to clipboard option\npypet exec [snippet-id] --copy\n\n# Edit a snippet\npypet edit \u003csnippet-id\u003e\n\n# Edit the snippets configuration file directly\npypet edit --file\n\n# Delete a snippet\npypet delete \u003csnippet-id\u003e\n\n# Alias management\npypet alias add \u003csnippet-id\u003e \u003calias-name\u003e    # Add alias to snippet\npypet alias list                              # List all aliases\npypet alias remove \u003csnippet-id\u003e               # Remove alias from snippet\npypet alias setup                             # Show setup instructions\n\n# Git synchronization\npypet sync init                    # Initialize Git repository\npypet sync remote \u003crepo-url\u003e       # Add/update remote repository\npypet sync status                  # Show sync status\npypet sync commit -m \"message\"     # Commit changes\npypet sync pull                    # Pull from remote\npypet sync push                    # Push to remote\npypet sync sync                    # Full sync (commit + pull + push)\n```\n\n### Parameterized Snippets\n\nYou can create snippets with customizable parameters:\n\n```bash\n# Create a snippet with parameters\npypet new \"docker run -p {port}:80 -v {path}:/app -e NODE_ENV={env=development} {image}\" \\\n    -d \"Run a Docker container with custom settings\" \\\n    -t \"docker,container\" \\\n    -p \"port:Host port to bind,path:Volume path,env=development:Node environment,image:Docker image name\"\n\n# Execute with parameter values\npypet exec \u003csnippet-id\u003e -P port=3000 -P path=$PWD -P image=node:18-alpine\n\n# Or execute interactively (will prompt for parameter values)\npypet exec \u003csnippet-id\u003e\n```\n\nParameters can have:\n\n- Required values: `{name}`\n- Default values: `{name=default}`\n- Descriptions (shown when prompting)\n\nExample TOML storage for a parameterized snippet:\n\n```toml\n[snippets.unique-id]\ncommand = \"docker run -p {port}:80 -v {path}:/app -e NODE_ENV={env=development} {image}\"\ndescription = \"Run a Docker container with custom settings\"\ntags = [\"docker\", \"container\"]\ncreated_at = \"2025-06-17T10:00:00+00:00\"\nupdated_at = \"2025-06-17T10:00:00+00:00\"\n\n[snippets.unique-id.parameters.port]\nname = \"port\"\ndescription = \"Host port to bind\"\n\n[snippets.unique-id.parameters.path]\nname = \"path\"\ndescription = \"Volume path\"\n\n[snippets.unique-id.parameters.env]\nname = \"env\"\ndefault = \"development\"\ndescription = \"Node environment\"\n\n[snippets.unique-id.parameters.image]\nname = \"image\"\ndescription = \"Docker image name\"\n```\n\n### Saving Snippets from Clipboard and History\n\n`pypet` provides convenient ways to save snippets from your clipboard or shell history:\n\n#### Save from Clipboard\n\n```bash\n# Save current clipboard content\npypet save-clipboard -d \"My command description\" -t \"docker,development\"\n\n# Interactive mode (prompts for description and tags)\npypet save-clipboard\n```\n\nThis command automatically detects parameters in the clipboard content and prompts you to add descriptions for them.\n\n#### Save from Shell History\n\n```bash\n# Save the last command from your shell history\npypet save-last\n\n# Save multiple commands (creates separate snippets)\npypet save-last -n 3\n\n# With description and tags\npypet save-last -d \"Build command\" -t \"build,make\"\n```\n\nThe `save-last` command works with bash, zsh, and other popular shells. It reads from your shell history file and lets you save recent commands as snippets.\n\n### Shell Aliases\n\n`pypet` can create persistent shell aliases from your snippets, making frequently-used commands instantly accessible without needing to run `pypet exec`.\n\n#### Adding Aliases to Snippets\n\n```bash\n# Create a new snippet with an alias\npypet new \"ls -la\" -d \"List all files\" -a ll\n\n# Add an alias to an existing snippet\npypet alias add \u003csnippet-id\u003e ll\n\n# List all snippets with aliases\npypet alias list\n\n# Show the generated alias definition\npypet alias show \u003csnippet-id\u003e\n\n# Remove an alias from a snippet\npypet alias remove \u003csnippet-id\u003e\n```\n\n#### Setting Up Aliases\n\nAfter creating aliases, you need to source the aliases file in your shell:\n\n```bash\n# Show setup instructions\npypet alias setup\n\n# Copy the source command to clipboard\npypet alias setup --copy\n```\n\nAdd this line to your shell profile (`~/.bashrc` for bash, `~/.zshrc` for zsh):\n\n```bash\nsource ~/.config/pypet/aliases.sh\n```\n\nThen reload your shell or run:\n\n```bash\nsource ~/.config/pypet/aliases.sh\n```\n\n#### How Aliases Work\n\n- **Simple snippets** (no parameters): Created as regular shell aliases\n  ```bash\n  pypet new \"ls -la\" -a ll\n  # Generates: alias ll='ls -la'\n  ```\n\n- **Parameterized snippets**: Created as shell functions that call `pypet exec`\n  ```bash\n  pypet new \"ssh {user}@{host}\" -a myssh\n  # Generates a function that prompts for parameters\n  ```\n\n#### Managing Aliases\n\n```bash\n# Regenerate the aliases file (useful after manual edits)\npypet alias update\n\n# View all aliases\npypet alias list\n```\n\nThe aliases are stored in `~/.config/pypet/aliases.sh` and are automatically updated whenever you add or remove aliases.\n\n### Interactive Mode\n\nWhen running `pypet exec` without a snippet ID, it enters interactive mode:\n\n1. Shows a table of all available snippets\n2. Lets you select a snippet by number\n3. Optionally allows editing the command before execution\n4. Asks for confirmation before running the command\n\n## Git Synchronization\n\n`pypet` supports Git-based synchronization to backup and share your snippets across devices.\n\n### Setup\n\n```bash\n# Initialize Git repository for snippets\npypet sync init\n\n# Initialize with remote repository\npypet sync init --remote https://github.com/username/pypet-snippets.git\n\n# Or add remote to existing repository\npypet sync remote https://github.com/username/pypet-snippets.git\n```\n\n### Basic Operations\n\n```bash\n# Check sync status\npypet sync status\n\n# Commit current changes\npypet sync commit -m \"Added new Docker snippets\"\n\n# Pull changes from remote\npypet sync pull\n\n# Push changes to remote\npypet sync push\n\n# Full sync (commit + pull + push)\npypet sync sync\n```\n\n### Backup Management\n\n```bash\n# List available backups\npypet sync backups\n\n# Restore from backup\npypet sync restore snippets_backup_20250101_120000.toml\n```\n\n**Automatic Cleanup**: `pypet` automatically manages your backups by keeping only the 5 most recent backup files. Old backups are cleaned up during sync operations to prevent disk space accumulation.\n\n### Workflow\n\n1. **Initial Setup**: Run `pypet sync init` to create a Git repository\n2. **Add Remote**: Use `--remote` option or manually configure Git remote\n3. **Regular Sync**: Use `pypet sync sync` to keep snippets synchronized\n4. **Automatic Backups**: Backups are created before pull operations\n\n## Development\n\nThis project uses `uv` for dependency management, `pytest` for testing, and includes pre-push git hooks for quality assurance.\n\n### Quick Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/fabiandistler/pypet.git\ncd pypet\n\n# Set up development environment with hooks (recommended)\nmake dev\n```\n\nThis installs the package in development mode and sets up pre-push git hooks that automatically run linting and tests before each push.\n\n### Manual Setup\n\n```bash\n# Create virtual environment\nuv venv\nsource .venv/bin/activate  # On Windows: .venv\\Scripts\\activate\n\n# Install package in development mode\nuv pip install -e \".[dev]\"\n\n# Install git hooks (optional but recommended)\nmake hooks\n```\n\n### Development Commands\n\n```bash\n# Format code with black\nmake format\n\n# Check linting with ruff\nmake lint\n\n# Run tests\nmake test\n\n# Run all checks (format + lint + test)\nmake all\n\n# Clean build artifacts\nmake clean\n```\n\n### Testing\n\n```bash\n# Run all tests\npytest\n\n# Run with verbose output\npytest -v\n\n# Run specific test file\npytest tests/test_cli.py\n\n# Run with coverage\npytest --cov=pypet\n```\n\n### Git Hooks\n\nPre-push hooks automatically run before each push:\n\n- Code formatting with `black`\n- Linting with `ruff`\n- Full test suite with `pytest`\n\nTo bypass hooks (use sparingly):\n\n```bash\ngit push --no-verify\n```\n\nTo skip only tests (for quick iterations):\n\n```bash\nSKIP_TESTS=1 git push\n```\n\n## Storage Format\n\nSnippets are stored in TOML format at `~/.config/pypet/snippets.toml`:\n\n```toml\n[snippets.unique-id]\ncommand = \"git status\"\ndescription = \"Check git status\"\ntags = [\"git\", \"status\"]\nalias = \"gs\"\ncreated_at = \"2025-06-17T10:00:00+00:00\"\nupdated_at = \"2025-06-17T10:00:00+00:00\"\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nMIT License - see the [LICENSE](LICENSE) file for details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffabiandistler%2Fpypet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffabiandistler%2Fpypet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffabiandistler%2Fpypet/lists"}