supsrc


Namesupsrc JSON
Version 0.2.0 PyPI version JSON
download
home_pageNone
SummaryAutomated Git commit/push utility based on filesystem events and rules.
upload_time2025-10-15 01:53:02
maintainerNone
docs_urlNone
authorNone
requires_python>=3.11
licenseNone
keywords git automation watchdog developer-tools vcs backup llm
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <div align="center">

# 🔼⚙️ `supsrc`

**Keep your work safe, effortlessly.**

Automated Git commit/push utility based on filesystem events and rules.

[![PyPI Version](https://img.shields.io/pypi/v/supsrc?style=flat-square)](https://pypi.org/project/supsrc/) <!-- Placeholder -->
[![Python Versions](https://img.shields.io/pypi/pyversions/supsrc?style=flat-square)](https://pypi.org/project/supsrc/)
[![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg?style=flat-square)](https://opensource.org/licenses/Apache-2.0)
[![Package Manager: uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/refs/heads/main/assets/badge/v0.json&style=flat-square)](https://github.com/astral-sh/uv)
[![Code style: ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json&style=flat-square)](https://github.com/astral-sh/ruff)
[![Powered by Structlog](https://img.shields.io/badge/powered%20by-structlog-lightgrey.svg?style=flat-square)](https://www.structlog.org/)

---

**Never forget to commit again!** `supsrc` watches your specified repositories for changes and automatically stages, commits, and (optionally) pushes them according to rules you define. Perfect for frequent checkpointing, synchronizing work-in-progress, or ensuring volatile experiments are saved.

</div>

## 🤔 Why `supsrc`?

*   **Automated Checkpoints:** Working on something complex or experimental? `supsrc` can automatically commit your changes after a period of inactivity or after a certain number of saves, creating a safety net without interrupting your flow.
*   **Effortless Syncing:** Keep a work-in-progress branch automatically pushed to a remote for backup or collaboration, without manual `git add/commit/push` steps.
*   **Simple Configuration:** Define your repositories and rules in a clear TOML file.
*   **Focused:** Designed specifically for the "watch and sync" workflow, aiming to be simpler than custom scripting or more complex backup solutions for this specific task.

## ✨ Features

*   **📂 Directory Monitoring:** Watches specified repository directories recursively for file changes using `watchdog`.
*   **📜 Rule-Based Triggers:**
    *   **Inactivity:** Trigger actions after a configurable period of no file changes (e.g., `30s`, `5m`).
    *   **Save Count:** Trigger actions after a specific number of file save events.
    *   **Manual:** Disable automatic triggers (useful for testing or specific setups).
*   **⚙️ Git Engine:**
    *   Interacts with Git repositories using `pygit2`.
    *   Automatically stages modified, added, and deleted files (respecting `.gitignore`).
    *   Performs commits with customizable message templates (including timestamps, save counts, and change summaries).
    *   Optionally pushes changes to a configured remote and branch.
    *   Handles SSH Agent authentication and basic HTTPS (user/token via env vars).
*   **📝 TOML Configuration:** Easy-to-understand configuration file (`supsrc.conf`).
*   **🕶️ `.gitignore` Respect:** Automatically ignores files specified in the repository's `.gitignore`.
*   **📊 Structured Logging:** Detailed logging using `structlog` for observability (JSON or colored console output).
*   **🖥️ Optional TUI:** An interactive Terminal User Interface (built with `textual`) for monitoring repository status and logs in real-time.
*   **📟 Tail Mode:** A headless, non-interactive mode for monitoring repositories without terminal control issues (useful for scripts and automation).

## 🚀 Installation

### Using uv (Recommended)

[uv](https://github.com/astral-sh/uv) is a fast Python package installer and resolver:

```bash
# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install supsrc
uv pip install supsrc

# Install with TUI support
uv pip install 'supsrc[tui]'

# Install with LLM support (Gemini and Ollama)
uv pip install 'supsrc[llm]'

# Install with all optional features
uv pip install 'supsrc[tui,llm]'
```

### Using pip

Ensure you have Python 3.11 or later installed:

```bash
pip install supsrc

# With TUI support
pip install 'supsrc[tui]'

# With LLM support
pip install 'supsrc[llm]'
```

## 💡 Usage

1.  **Create a Configuration File:** By default, `supsrc` looks for `supsrc.conf` in the current directory. See the [Configuration](#-configuration) section below for details.

2.  **Run the Watcher:**

    ```bash
    # Run with interactive dashboard (TUI mode)
    supsrc sui

    # Run in headless mode (non-interactive)
    supsrc watch

    # Specify a different config file
    supsrc sui -c /path/to/your/config.toml
    supsrc watch -c /path/to/your/config.toml

    # Increase log verbosity
    supsrc watch --log-level DEBUG
    ```

3.  **Check Configuration:** Validate and display the loaded configuration (including environment variable overrides):

    ```bash
    supsrc config show
    supsrc config show -c path/to/config.toml
    ```

4.  **Stop the Watcher:** Press `Ctrl+C` to stop the watcher gracefully.

## ⚙️ Configuration (`supsrc.conf`)

Create a file named `supsrc.conf` (or specify another path using `-c`). Here's an example:

```toml
# Example supsrc.conf

# Global settings (can be overridden by environment variables like SUPSRC_LOG_LEVEL)
[global]
log_level = "INFO" # DEBUG, INFO, WARNING, ERROR, CRITICAL

# Define repositories to monitor
[repositories]

  # Unique identifier for this repository monitoring task
  [repositories.my-project]
    # Path to the Git repository (use '~' for home directory)
    path = "~/dev/my-project"
    # Set to false to temporarily disable monitoring for this repo
    enabled = true

    # Define the rule that triggers actions
    [repositories.my-project.rule]
      # Trigger after 5 minutes of inactivity
      type = "supsrc.rules.inactivity" # Built-in rule type
      period = "5m" # Format: XhYmZs (e.g., "30s", "10m", "1h5m")

      # --- OR ---
      # Trigger after every 10 save events
      # type = "supsrc.rules.save_count"
      # count = 10

      # --- OR ---
      # Disable automatic triggers (requires external mechanism if actions are needed)
      # type = "supsrc.rules.manual"

    # Configure the repository engine (currently only Git)
    [repositories.my-project.repository]
      type = "supsrc.engines.git" # Must be specified

      # --- Git Engine Specific Options ---
      # Automatically push after successful commit? (Default: false)
      auto_push = true
      # Remote to push to (Default: 'origin')
      remote = "origin"
      # Branch to push (Default: uses the current checked-out branch)
      # branch = "main"
      # Commit message template (Go template syntax)
      # Available placeholders: {{timestamp}}, {{repo_id}}, {{save_count}}, {{change_summary}}
      commit_message_template = "feat: Auto-sync changes at {{timestamp}}\n\n{{change_summary}}"

  [repositories.another-repo]
    path = "/path/to/another/repo"
    enabled = true
    [repositories.another-repo.rule]
      type = "supsrc.rules.inactivity"
      period = "30s"
    [repositories.another-repo.repository]
      type = "supsrc.engines.git"
      auto_push = false # Keep commits local for this one
```

### Environment Variable Overrides

*   `SUPSRC_CONF`: Path to the configuration file.
*   `SUPSRC_LOG_LEVEL`: Sets the logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL).
*   `SUPSRC_LOG_FILE`: Path to write JSON logs to a file.
*   `SUPSRC_JSON_LOGS`: Set to `true`, `1`, `yes`, or `on` to output console logs as JSON.

## 🧠 LLM Configuration (Optional)

`supsrc` can use Large Language Models (LLMs) to automate tasks like generating commit messages, reviewing changes for obvious errors, and analyzing test failures. This requires the `supsrc[llm]` extra to be installed.

To enable LLM features for a specific repository, add an `[repositories.<repo_id>.llm]` section to your `supsrc.conf`.

```toml
# In your supsrc.conf file...

[repositories.my-llm-project]
  path = "~/dev/my-llm-project"
  enabled = true
  [repositories.my-llm-project.rule]
    type = "supsrc.rules.inactivity"
    period = "2m"
  [repositories.my-llm-project.repository]
    type = "supsrc.engines.git"
    auto_push = true

  # --- LLM Configuration Section ---
  [repositories.my-llm-project.llm]
    # Enable LLM features for this repo
    enabled = true

    # --- Provider Setup ---
    # Choose your LLM provider: "gemini" or "ollama"
    provider = "gemini"
    # Specify the model to use
    model = "gemini-1.5-flash" # For Gemini
    # model = "llama3" # Example for Ollama

    # (For Gemini) Specify the environment variable containing your API key
    api_key_env_var = "GEMINI_API_KEY"

    # --- Feature Flags ---
    # Automatically generate the commit message subject line
    generate_commit_message = true
    # Use Conventional Commits format for the generated message
    use_conventional_commit = true
    # Perform a quick review of changes and veto the commit on critical issues (e.g., secrets)
    review_changes = true
    # Run a test command before committing
    run_tests = true
    # If tests fail, use the LLM to analyze the failure output
    analyze_test_failures = true

    # --- Additional Settings ---
    # Specify the command to run for tests. If not set, supsrc tries to infer it.
    test_command = "pytest"
```

### Provider Details

*   **Gemini (`provider = "gemini"`)**
    *   Uses the Google Gemini API.
    *   Requires an API key. By default, it looks for the key in the `GEMINI_API_KEY` environment variable. You can change the variable name with `api_key_env_var`.
    *   **Setup:**
        1.  Get a Gemini API key from [Google AI Studio](https://aistudio.google.com/app/apikey).
        2.  Set the environment variable: `export GEMINI_API_KEY="your-api-key-here"`

*   **Ollama (`provider = "ollama"`)**
    *   Connects to a local [Ollama](https://ollama.ai/) instance.
    *   Does not require an API key.
    *   **Setup:**
        1.  Install and run Ollama on your machine.
        2.  Pull a model you want to use, e.g., `ollama pull llama3`.
        3.  Set `provider = "ollama"` and `model = "llama3"` (or your chosen model) in the config.

## 룰 Rules Explained

The `[repositories.*.rule]` section defines when `supsrc` should trigger its actions (stage, commit, push).

*   **`type = "supsrc.rules.inactivity"`**
    *   Triggers when no filesystem changes have been detected in the repository for the duration specified by `period`.
    *   `period`: A string defining the inactivity duration (e.g., `"30s"`, `"5m"`, `"1h"`).
*   **`type = "supsrc.rules.save_count"`**
    *   Triggers when the number of detected save events reaches the specified `count`. The count resets after a successful action sequence.
    *   `count`: A positive integer (e.g., `10`).
*   **`type = "supsrc.rules.manual"`**
    *   Disables automatic triggering by `supsrc`. Actions would need to be initiated externally if this rule is used (primarily for testing or advanced scenarios).

## 🔩 Engines

`supsrc` uses engines to interact with different types of repositories.

*   **`type = "supsrc.engines.git"`**
    *   The primary engine for interacting with Git repositories.
    *   Uses the `pygit2` library.
    *   Supports status checks, staging (respecting `.gitignore`), committing, and pushing.

### Git Engine Authentication

The Git engine currently supports:

1.  **SSH Agent:** If your remote URL is SSH-based (e.g., `git@github.com:...`), `supsrc` will attempt to use `pygit2.KeypairFromAgent` to authenticate via a running SSH agent. Ensure your agent is running and the correct key is loaded.
2.  **HTTPS (Environment Variables):** For HTTPS URLs (e.g., `https://github.com/...`), `supsrc` will look for the following environment variables:
    *   `GIT_USERNAME`: Your Git username.
    *   `GIT_PASSWORD`: Your Git password **or preferably a Personal Access Token (PAT)**.

*Note: Storing credentials directly is generally discouraged. Using an SSH agent or short-lived tokens is recommended.*

## 🖥️ Textual TUI (Optional)

If installed (`pip install 'supsrc[tui]'`) and run with `supsrc watch`, a terminal user interface provides:

*   A live-updating table showing the status, last change time, save count, and errors for each monitored repository.
*   A scrolling log view displaying messages from `supsrc`.


## 🤝 Contributing

Contributions are welcome! Please feel free to open an issue to report bugs, suggest features, or ask questions. Pull requests are greatly appreciated.

### Development Setup

We use `uv` for development:

```bash
# Clone the repository
git clone https://github.com/provide-io/supsrc.git
cd supsrc

# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh

# Create virtual environment and install dependencies
uv venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install in development mode with all optional features
uv pip install -e ".[tui,llm]"

# Install development tools
uv pip install pytest ruff mypy

# Run tests
uv run pytest

# Run linting
uv run ruff check .
uv run ruff format .
```

## 📜 License

This project is licensed under the **Apache License 2.0**. See the [LICENSE](LICENSE) file for details. <!-- Ensure LICENSE file exists -->

## 🙏 Acknowledgements

`supsrc` builds upon several fantastic open-source libraries, including:

*   [`pygit2`](https://www.pygit2.org/) for Git interactions.
*   [`watchdog`](https://github.com/gorakhargosh/watchdog) for filesystem monitoring.
*   [`structlog`](https://www.structlog.org/) for structured logging.
*   [`attrs`](https://www.attrs.org/) & [`cattrs`](https://catt.rs/) for data classes and configuration structuring.
*   [`click`](https://click.palletsprojects.com/) for the command-line interface.
*   [`textual`](https://github.com/Textualize/textual) for the optional TUI.
*   [`pathspec`](https://github.com/cpburnz/python-path-specification) for `.gitignore` handling.
test change

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "supsrc",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": "\"provide.io\" <code@provide.io>",
    "keywords": "git, automation, watchdog, developer-tools, vcs, backup, llm",
    "author": null,
    "author_email": "Tim Perkins <code@tim.life>",
    "download_url": "https://files.pythonhosted.org/packages/9e/13/8cce6ad50796c8a046590023fde0d86cd8f1b4837dbd97ab174afe7255f7/supsrc-0.2.0.tar.gz",
    "platform": null,
    "description": "<div align=\"center\">\n\n# \ud83d\udd3c\u2699\ufe0f `supsrc`\n\n**Keep your work safe, effortlessly.**\n\nAutomated Git commit/push utility based on filesystem events and rules.\n\n[![PyPI Version](https://img.shields.io/pypi/v/supsrc?style=flat-square)](https://pypi.org/project/supsrc/) <!-- Placeholder -->\n[![Python Versions](https://img.shields.io/pypi/pyversions/supsrc?style=flat-square)](https://pypi.org/project/supsrc/)\n[![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg?style=flat-square)](https://opensource.org/licenses/Apache-2.0)\n[![Package Manager: uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/refs/heads/main/assets/badge/v0.json&style=flat-square)](https://github.com/astral-sh/uv)\n[![Code style: ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json&style=flat-square)](https://github.com/astral-sh/ruff)\n[![Powered by Structlog](https://img.shields.io/badge/powered%20by-structlog-lightgrey.svg?style=flat-square)](https://www.structlog.org/)\n\n---\n\n**Never forget to commit again!** `supsrc` watches your specified repositories for changes and automatically stages, commits, and (optionally) pushes them according to rules you define. Perfect for frequent checkpointing, synchronizing work-in-progress, or ensuring volatile experiments are saved.\n\n</div>\n\n## \ud83e\udd14 Why `supsrc`?\n\n*   **Automated Checkpoints:** Working on something complex or experimental? `supsrc` can automatically commit your changes after a period of inactivity or after a certain number of saves, creating a safety net without interrupting your flow.\n*   **Effortless Syncing:** Keep a work-in-progress branch automatically pushed to a remote for backup or collaboration, without manual `git add/commit/push` steps.\n*   **Simple Configuration:** Define your repositories and rules in a clear TOML file.\n*   **Focused:** Designed specifically for the \"watch and sync\" workflow, aiming to be simpler than custom scripting or more complex backup solutions for this specific task.\n\n## \u2728 Features\n\n*   **\ud83d\udcc2 Directory Monitoring:** Watches specified repository directories recursively for file changes using `watchdog`.\n*   **\ud83d\udcdc Rule-Based Triggers:**\n    *   **Inactivity:** Trigger actions after a configurable period of no file changes (e.g., `30s`, `5m`).\n    *   **Save Count:** Trigger actions after a specific number of file save events.\n    *   **Manual:** Disable automatic triggers (useful for testing or specific setups).\n*   **\u2699\ufe0f Git Engine:**\n    *   Interacts with Git repositories using `pygit2`.\n    *   Automatically stages modified, added, and deleted files (respecting `.gitignore`).\n    *   Performs commits with customizable message templates (including timestamps, save counts, and change summaries).\n    *   Optionally pushes changes to a configured remote and branch.\n    *   Handles SSH Agent authentication and basic HTTPS (user/token via env vars).\n*   **\ud83d\udcdd TOML Configuration:** Easy-to-understand configuration file (`supsrc.conf`).\n*   **\ud83d\udd76\ufe0f `.gitignore` Respect:** Automatically ignores files specified in the repository's `.gitignore`.\n*   **\ud83d\udcca Structured Logging:** Detailed logging using `structlog` for observability (JSON or colored console output).\n*   **\ud83d\udda5\ufe0f Optional TUI:** An interactive Terminal User Interface (built with `textual`) for monitoring repository status and logs in real-time.\n*   **\ud83d\udcdf Tail Mode:** A headless, non-interactive mode for monitoring repositories without terminal control issues (useful for scripts and automation).\n\n## \ud83d\ude80 Installation\n\n### Using uv (Recommended)\n\n[uv](https://github.com/astral-sh/uv) is a fast Python package installer and resolver:\n\n```bash\n# Install uv if you haven't already\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Install supsrc\nuv pip install supsrc\n\n# Install with TUI support\nuv pip install 'supsrc[tui]'\n\n# Install with LLM support (Gemini and Ollama)\nuv pip install 'supsrc[llm]'\n\n# Install with all optional features\nuv pip install 'supsrc[tui,llm]'\n```\n\n### Using pip\n\nEnsure you have Python 3.11 or later installed:\n\n```bash\npip install supsrc\n\n# With TUI support\npip install 'supsrc[tui]'\n\n# With LLM support\npip install 'supsrc[llm]'\n```\n\n## \ud83d\udca1 Usage\n\n1.  **Create a Configuration File:** By default, `supsrc` looks for `supsrc.conf` in the current directory. See the [Configuration](#-configuration) section below for details.\n\n2.  **Run the Watcher:**\n\n    ```bash\n    # Run with interactive dashboard (TUI mode)\n    supsrc sui\n\n    # Run in headless mode (non-interactive)\n    supsrc watch\n\n    # Specify a different config file\n    supsrc sui -c /path/to/your/config.toml\n    supsrc watch -c /path/to/your/config.toml\n\n    # Increase log verbosity\n    supsrc watch --log-level DEBUG\n    ```\n\n3.  **Check Configuration:** Validate and display the loaded configuration (including environment variable overrides):\n\n    ```bash\n    supsrc config show\n    supsrc config show -c path/to/config.toml\n    ```\n\n4.  **Stop the Watcher:** Press `Ctrl+C` to stop the watcher gracefully.\n\n## \u2699\ufe0f Configuration (`supsrc.conf`)\n\nCreate a file named `supsrc.conf` (or specify another path using `-c`). Here's an example:\n\n```toml\n# Example supsrc.conf\n\n# Global settings (can be overridden by environment variables like SUPSRC_LOG_LEVEL)\n[global]\nlog_level = \"INFO\" # DEBUG, INFO, WARNING, ERROR, CRITICAL\n\n# Define repositories to monitor\n[repositories]\n\n  # Unique identifier for this repository monitoring task\n  [repositories.my-project]\n    # Path to the Git repository (use '~' for home directory)\n    path = \"~/dev/my-project\"\n    # Set to false to temporarily disable monitoring for this repo\n    enabled = true\n\n    # Define the rule that triggers actions\n    [repositories.my-project.rule]\n      # Trigger after 5 minutes of inactivity\n      type = \"supsrc.rules.inactivity\" # Built-in rule type\n      period = \"5m\" # Format: XhYmZs (e.g., \"30s\", \"10m\", \"1h5m\")\n\n      # --- OR ---\n      # Trigger after every 10 save events\n      # type = \"supsrc.rules.save_count\"\n      # count = 10\n\n      # --- OR ---\n      # Disable automatic triggers (requires external mechanism if actions are needed)\n      # type = \"supsrc.rules.manual\"\n\n    # Configure the repository engine (currently only Git)\n    [repositories.my-project.repository]\n      type = \"supsrc.engines.git\" # Must be specified\n\n      # --- Git Engine Specific Options ---\n      # Automatically push after successful commit? (Default: false)\n      auto_push = true\n      # Remote to push to (Default: 'origin')\n      remote = \"origin\"\n      # Branch to push (Default: uses the current checked-out branch)\n      # branch = \"main\"\n      # Commit message template (Go template syntax)\n      # Available placeholders: {{timestamp}}, {{repo_id}}, {{save_count}}, {{change_summary}}\n      commit_message_template = \"feat: Auto-sync changes at {{timestamp}}\\n\\n{{change_summary}}\"\n\n  [repositories.another-repo]\n    path = \"/path/to/another/repo\"\n    enabled = true\n    [repositories.another-repo.rule]\n      type = \"supsrc.rules.inactivity\"\n      period = \"30s\"\n    [repositories.another-repo.repository]\n      type = \"supsrc.engines.git\"\n      auto_push = false # Keep commits local for this one\n```\n\n### Environment Variable Overrides\n\n*   `SUPSRC_CONF`: Path to the configuration file.\n*   `SUPSRC_LOG_LEVEL`: Sets the logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL).\n*   `SUPSRC_LOG_FILE`: Path to write JSON logs to a file.\n*   `SUPSRC_JSON_LOGS`: Set to `true`, `1`, `yes`, or `on` to output console logs as JSON.\n\n## \ud83e\udde0 LLM Configuration (Optional)\n\n`supsrc` can use Large Language Models (LLMs) to automate tasks like generating commit messages, reviewing changes for obvious errors, and analyzing test failures. This requires the `supsrc[llm]` extra to be installed.\n\nTo enable LLM features for a specific repository, add an `[repositories.<repo_id>.llm]` section to your `supsrc.conf`.\n\n```toml\n# In your supsrc.conf file...\n\n[repositories.my-llm-project]\n  path = \"~/dev/my-llm-project\"\n  enabled = true\n  [repositories.my-llm-project.rule]\n    type = \"supsrc.rules.inactivity\"\n    period = \"2m\"\n  [repositories.my-llm-project.repository]\n    type = \"supsrc.engines.git\"\n    auto_push = true\n\n  # --- LLM Configuration Section ---\n  [repositories.my-llm-project.llm]\n    # Enable LLM features for this repo\n    enabled = true\n\n    # --- Provider Setup ---\n    # Choose your LLM provider: \"gemini\" or \"ollama\"\n    provider = \"gemini\"\n    # Specify the model to use\n    model = \"gemini-1.5-flash\" # For Gemini\n    # model = \"llama3\" # Example for Ollama\n\n    # (For Gemini) Specify the environment variable containing your API key\n    api_key_env_var = \"GEMINI_API_KEY\"\n\n    # --- Feature Flags ---\n    # Automatically generate the commit message subject line\n    generate_commit_message = true\n    # Use Conventional Commits format for the generated message\n    use_conventional_commit = true\n    # Perform a quick review of changes and veto the commit on critical issues (e.g., secrets)\n    review_changes = true\n    # Run a test command before committing\n    run_tests = true\n    # If tests fail, use the LLM to analyze the failure output\n    analyze_test_failures = true\n\n    # --- Additional Settings ---\n    # Specify the command to run for tests. If not set, supsrc tries to infer it.\n    test_command = \"pytest\"\n```\n\n### Provider Details\n\n*   **Gemini (`provider = \"gemini\"`)**\n    *   Uses the Google Gemini API.\n    *   Requires an API key. By default, it looks for the key in the `GEMINI_API_KEY` environment variable. You can change the variable name with `api_key_env_var`.\n    *   **Setup:**\n        1.  Get a Gemini API key from [Google AI Studio](https://aistudio.google.com/app/apikey).\n        2.  Set the environment variable: `export GEMINI_API_KEY=\"your-api-key-here\"`\n\n*   **Ollama (`provider = \"ollama\"`)**\n    *   Connects to a local [Ollama](https://ollama.ai/) instance.\n    *   Does not require an API key.\n    *   **Setup:**\n        1.  Install and run Ollama on your machine.\n        2.  Pull a model you want to use, e.g., `ollama pull llama3`.\n        3.  Set `provider = \"ollama\"` and `model = \"llama3\"` (or your chosen model) in the config.\n\n## \ub8f0 Rules Explained\n\nThe `[repositories.*.rule]` section defines when `supsrc` should trigger its actions (stage, commit, push).\n\n*   **`type = \"supsrc.rules.inactivity\"`**\n    *   Triggers when no filesystem changes have been detected in the repository for the duration specified by `period`.\n    *   `period`: A string defining the inactivity duration (e.g., `\"30s\"`, `\"5m\"`, `\"1h\"`).\n*   **`type = \"supsrc.rules.save_count\"`**\n    *   Triggers when the number of detected save events reaches the specified `count`. The count resets after a successful action sequence.\n    *   `count`: A positive integer (e.g., `10`).\n*   **`type = \"supsrc.rules.manual\"`**\n    *   Disables automatic triggering by `supsrc`. Actions would need to be initiated externally if this rule is used (primarily for testing or advanced scenarios).\n\n## \ud83d\udd29 Engines\n\n`supsrc` uses engines to interact with different types of repositories.\n\n*   **`type = \"supsrc.engines.git\"`**\n    *   The primary engine for interacting with Git repositories.\n    *   Uses the `pygit2` library.\n    *   Supports status checks, staging (respecting `.gitignore`), committing, and pushing.\n\n### Git Engine Authentication\n\nThe Git engine currently supports:\n\n1.  **SSH Agent:** If your remote URL is SSH-based (e.g., `git@github.com:...`), `supsrc` will attempt to use `pygit2.KeypairFromAgent` to authenticate via a running SSH agent. Ensure your agent is running and the correct key is loaded.\n2.  **HTTPS (Environment Variables):** For HTTPS URLs (e.g., `https://github.com/...`), `supsrc` will look for the following environment variables:\n    *   `GIT_USERNAME`: Your Git username.\n    *   `GIT_PASSWORD`: Your Git password **or preferably a Personal Access Token (PAT)**.\n\n*Note: Storing credentials directly is generally discouraged. Using an SSH agent or short-lived tokens is recommended.*\n\n## \ud83d\udda5\ufe0f Textual TUI (Optional)\n\nIf installed (`pip install 'supsrc[tui]'`) and run with `supsrc watch`, a terminal user interface provides:\n\n*   A live-updating table showing the status, last change time, save count, and errors for each monitored repository.\n*   A scrolling log view displaying messages from `supsrc`.\n\n\n## \ud83e\udd1d Contributing\n\nContributions are welcome! Please feel free to open an issue to report bugs, suggest features, or ask questions. Pull requests are greatly appreciated.\n\n### Development Setup\n\nWe use `uv` for development:\n\n```bash\n# Clone the repository\ngit clone https://github.com/provide-io/supsrc.git\ncd supsrc\n\n# Install uv if you haven't already\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Create virtual environment and install dependencies\nuv venv\nsource .venv/bin/activate  # On Windows: .venv\\Scripts\\activate\n\n# Install in development mode with all optional features\nuv pip install -e \".[tui,llm]\"\n\n# Install development tools\nuv pip install pytest ruff mypy\n\n# Run tests\nuv run pytest\n\n# Run linting\nuv run ruff check .\nuv run ruff format .\n```\n\n## \ud83d\udcdc License\n\nThis project is licensed under the **Apache License 2.0**. See the [LICENSE](LICENSE) file for details. <!-- Ensure LICENSE file exists -->\n\n## \ud83d\ude4f Acknowledgements\n\n`supsrc` builds upon several fantastic open-source libraries, including:\n\n*   [`pygit2`](https://www.pygit2.org/) for Git interactions.\n*   [`watchdog`](https://github.com/gorakhargosh/watchdog) for filesystem monitoring.\n*   [`structlog`](https://www.structlog.org/) for structured logging.\n*   [`attrs`](https://www.attrs.org/) & [`cattrs`](https://catt.rs/) for data classes and configuration structuring.\n*   [`click`](https://click.palletsprojects.com/) for the command-line interface.\n*   [`textual`](https://github.com/Textualize/textual) for the optional TUI.\n*   [`pathspec`](https://github.com/cpburnz/python-path-specification) for `.gitignore` handling.\ntest change\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Automated Git commit/push utility based on filesystem events and rules.",
    "version": "0.2.0",
    "project_urls": {
        "Homepage": "https://github.com/provide-io/supsrc",
        "Issues": "https://github.com/provide-io/supsrc/issues",
        "Repository": "https://github.com/provide-io/supsrc"
    },
    "split_keywords": [
        "git",
        " automation",
        " watchdog",
        " developer-tools",
        " vcs",
        " backup",
        " llm"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "30c4eff3243565932dc2bfe963b6d59720fa31855f55da076bc0f718ee999f07",
                "md5": "56f4307d90658bf287cf083a931993c7",
                "sha256": "fe2e39d296b7d7ebbf0e5589313d985f90bb5ec8738a21bb7711025ec98dfcfc"
            },
            "downloads": -1,
            "filename": "supsrc-0.2.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "56f4307d90658bf287cf083a931993c7",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 159347,
            "upload_time": "2025-10-15T01:53:01",
            "upload_time_iso_8601": "2025-10-15T01:53:01.460943Z",
            "url": "https://files.pythonhosted.org/packages/30/c4/eff3243565932dc2bfe963b6d59720fa31855f55da076bc0f718ee999f07/supsrc-0.2.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9e138cce6ad50796c8a046590023fde0d86cd8f1b4837dbd97ab174afe7255f7",
                "md5": "ea62cc2d8219e7ba98eb0db8174cec4e",
                "sha256": "3864000fbe0e2ab53b722df95a9d527c7471c406ff62ffbbb850b308616f92bc"
            },
            "downloads": -1,
            "filename": "supsrc-0.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "ea62cc2d8219e7ba98eb0db8174cec4e",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 127119,
            "upload_time": "2025-10-15T01:53:02",
            "upload_time_iso_8601": "2025-10-15T01:53:02.929237Z",
            "url": "https://files.pythonhosted.org/packages/9e/13/8cce6ad50796c8a046590023fde0d86cd8f1b4837dbd97ab174afe7255f7/supsrc-0.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-15 01:53:02",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "provide-io",
    "github_project": "supsrc",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "supsrc"
}
        
Elapsed time: 1.54549s