Metadata-Version: 2.4
Name: issuesort
Version: 0.1.0
Summary: Triage GitHub issues with AI: detect duplicates by meaning and suggest labels. CLI + GitHub Action. Zero dependencies.
Project-URL: Homepage, https://github.com/Sev7nOfNine/issuesort
Project-URL: Repository, https://github.com/Sev7nOfNine/issuesort
Project-URL: Issues, https://github.com/Sev7nOfNine/issuesort/issues
Author: Seven Of Nine
License: MIT
License-File: LICENSE
Keywords: automation,duplicate-detection,embeddings,github,github-action,issues,labels,llm,maintainer,triage
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Software Development :: Bug Tracking
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Provides-Extra: test
Requires-Dist: pytest>=7; extra == 'test'
Description-Content-Type: text/markdown

# issuesort

[![PyPI](https://img.shields.io/pypi/v/issuesort.svg)](https://pypi.org/project/issuesort/)
[![CI](https://github.com/Sev7nOfNine/issuesort/actions/workflows/ci.yml/badge.svg)](https://github.com/Sev7nOfNine/issuesort/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Python](https://img.shields.io/pypi/pyversions/issuesort.svg)](https://pypi.org/project/issuesort/)

**Triage GitHub issues with AI — find duplicates and suggest labels. Zero dependencies.**

When a new issue lands, `issuesort` compares it against the open issues by
*meaning* (embedding similarity) to surface likely duplicates, and asks a model
to pick fitting labels from your repository's own label set. It posts the result
as a comment, and can apply the labels for you.

Run it as a GitHub Action on every new issue, or invoke the CLI by hand. It uses
any OpenAI-compatible API — including a local server — and nothing but the Python
standard library.

## Example comment

```markdown
## issuesort triage

**Possible duplicates:**
- #128 App crashes when saving an empty file _(similarity 0.91)_
- #97 Save dialog throws on empty path _(similarity 0.86)_

**Suggested labels:** `bug`, `needs-repro`
```

## Install

```bash
pip install issuesort
```

Requires Python 3.8+.

## CLI usage

```bash
export OPENAI_API_KEY=sk-...
export GITHUB_TOKEN=ghp_...

# Print a triage for issue #42
issuesort --repo octocat/hello-world --issue 42

# Post it as a comment and apply the suggested labels
issuesort --repo octocat/hello-world --issue 42 --post --apply-labels
```

### Options

| Flag | Description |
| --- | --- |
| `--repo OWNER/NAME` | Repository (required). |
| `--issue N` | Issue number (required). |
| `--threshold X` | Duplicate similarity cutoff, 0-1 (default 0.83). |
| `--top N` | Max duplicates to report (default 5). |
| `--no-labels` | Skip LLM label suggestion (duplicates only). |
| `--post` | Post the triage as an issue comment. |
| `--apply-labels` | Apply the suggested labels. |
| `--model` / `--embed-model` | Chat and embedding models. |
| `--base-url` / `--api-key` | Provider configuration. |

## GitHub Action

Triage every newly opened issue. Store your provider key as a secret:

```yaml
name: issuesort
on:
  issues:
    types: [opened]

permissions:
  contents: read
  issues: write

jobs:
  triage:
    runs-on: ubuntu-latest
    steps:
      - uses: Sev7nOfNine/issuesort@v0.1.0
        with:
          api-key: ${{ secrets.OPENAI_API_KEY }}
          apply-labels: "false"
```

## How duplicate detection works

The issue's title and body are embedded and compared against every open issue by
cosine similarity. Anything at or above `--threshold` is reported, best match
first. Tune the threshold to taste: higher is stricter.

## Privacy note

Issue text is sent to whichever provider you configure. Prefer a self-hosted
model via `--base-url` for private repositories.

## Development

```bash
pip install -e ".[test]"
python -m pytest
```

Tests run offline; the network layers accept injectable fakes.

## License

MIT — see [LICENSE](LICENSE).
