@@ -0,0 +1,48 @@
+# llm-fragments-repomix
+
+A plugin for [LLM](https://llm.datasette.io/) that loads repository contents as fragments using [Repomix](https://github.com/yamadashy/repomix).
+
+## Installation
+
+First, install the plugin:
+
+```bash
+pip install llm-fragments-repomix
+```
+
+Make sure you have `repomix` installed:
+
+```bash
+npm install -g repomix
+```
+
+## Usage
+
+Use the `repomix:` prefix with a full git repository URL:
+
+```bash
+llm -f repomix:https://git.sr.ht/~amolith/willow "Tell me about this project"
+```
+
+```bash
+llm -f repomix:ssh://git.sr.ht:~amolith/willow "Analyze the code structure"
+```
+
+The plugin will:
+1. Clone the repository to a temporary directory
+2. Run repomix on the cloned repository
+3. Return the repomix output as a single fragment
+4. Clean up the temporary directory
+
+## Requirements
+
+- Python 3.9+
+- `git` command available in PATH
+- `repomix` command available in PATH
+
+## Future Work
+
+Future versions may support:
+- Passing repomix arguments (e.g., `--compress`, `--ignore`)
+- Integration with other fragment loaders for repository shortcuts
+- Configuration options for repomix behavior
@@ -0,0 +1,85 @@
+from typing import List
+import llm
+import os
+import pathlib
+import subprocess
+import tempfile
+import shutil
+
+
+@llm.hookimpl
+def register_fragment_loaders(register):
+ register("repomix", repomix_loader)
+
+
+def repomix_loader(argument: str) -> List[llm.Fragment]:
+ """
+ Load repository contents as fragments using Repomix
+
+ Argument is a git repository URL (https:// or ssh://)
+ Examples:
+ repomix:https://git.sr.ht/~amolith/willow
+ repomix:ssh://git.sr.ht:~amolith/willow
+ """
+ if not argument.startswith(("https://", "ssh://", "git@")):
+ raise ValueError(
+ f"Repository URL must start with https://, ssh://, or git@ - got: {argument}"
+ )
+
+ # Check if repomix is available
+ if not shutil.which("repomix"):
+ raise ValueError(
+ "repomix command not found. Please install repomix first: "
+ "https://github.com/yamadashy/repomix"
+ )
+
+ # Create a temporary directory for the cloned repository
+ with tempfile.TemporaryDirectory() as temp_dir:
+ repo_path = pathlib.Path(temp_dir) / "repo"
+
+ try:
+ # Clone the repository
+ subprocess.run(
+ ["git", "clone", "--depth=1", argument, str(repo_path)],
+ check=True,
+ capture_output=True,
+ text=True,
+ )
+
+ # Run repomix on the cloned repository
+ result = subprocess.run(
+ ["repomix", "--stdout", str(repo_path)],
+ check=True,
+ capture_output=True,
+ text=True,
+ )
+
+ # Create a single fragment with the repomix output
+ fragments = [
+ llm.Fragment(
+ content=result.stdout,
+ source=f"repomix:{argument}"
+ )
+ ]
+
+ return fragments
+
+ except subprocess.CalledProcessError as e:
+ # Handle Git or repomix errors
+ if "git" in str(e.cmd):
+ raise ValueError(
+ f"Failed to clone repository {argument}: {e.stderr}"
+ )
+ elif "repomix" in str(e.cmd):
+ raise ValueError(
+ f"Failed to run repomix on {argument}: {e.stderr}"
+ )
+ else:
+ raise ValueError(
+ f"Command failed: {e.stderr}"
+ )
+ except Exception as e:
+ # Handle other errors
+ raise ValueError(
+ f"Error processing repository {argument}: {str(e)}"
+ )
@@ -0,0 +1,26 @@
+[project]
+name = "llm-fragments-repomix"
+version = "0.1.0"
+description = "Load repository contents as LLM fragments using Repomix"
+readme = "README.md"
+authors = [{name = "Amolith"}]
+license = "Apache-2.0"
+requires-python = ">=3.9"
+dependencies = [
+ "llm"
+]
+
+[build-system]
+requires = ["setuptools"]
+build-backend = "setuptools.build_meta"
+
+[project.urls]
+Homepage = "https://git.sr.ht/~amolith/llm-fragments-repomix"
+Changelog = "https://git.sr.ht/~amolith/llm-fragments-repomix/refs"
+Issues = "https://todo.sr.ht/~amolith/public-tracker"
+
+[project.entry-points.llm]
+fragments_repomix = "llm_fragments_repomix"
+
+[project.optional-dependencies]
+test = ["pytest"]