Metadata-Version: 2.4
Name: milo-awesome-list-pr-generator
Version: 0.1.0
Summary: Lightning-paywalled FastAPI service — niche: Ready-to-submit PR generator for awesome-lists
Author-email: Milo Antaeus <miloantaeus@gmail.com>
License: MIT
Keywords: fastapi,l402,lightning,m2m,paywall,x402
Classifier: Development Status :: 3 - Alpha
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.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Requires-Python: >=3.10
Requires-Dist: fastapi>=0.110
Requires-Dist: httpx>=0.27
Requires-Dist: milo-paywall-kit>=0.1.0
Requires-Dist: uvicorn[standard]>=0.30
Provides-Extra: test
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'test'
Requires-Dist: pytest>=7.0.0; extra == 'test'
Description-Content-Type: text/markdown

# milo-awesome-list-pr-generator

> **Paste your repo URL → get a ready-to-submit PR that adds your project to the right awesome-list.**

Correct H2 section. Correct alphabetical position. Correct format. Lightning-paywalled at 200 sats for the auto-open step. Diff + body are free.

[![Lightning](https://img.shields.io/badge/Lightning-200_sats-yellow)](#pricing)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Tests](https://img.shields.io/badge/tests-40_passing-brightgreen)](#tests)

## Why this exists

Every project that wants discovery via [sindresorhus/awesome](https://github.com/sindresorhus/awesome) and its 700+ descendants hits the same wall:

1. Find the right H2 section in a 2000-line README
2. Insert at the correct alphabetical position
3. Match the list's idiosyncratic format (link style, bullet char, separator, description length cap)
4. Open the PR with a body the maintainer can merge in < 30s

Manual = 20-40 min. Often rejected for format issues. This automates steps 1-4.

## Endpoint catalog

| Method  | Path        | Auth      | Description |
|---------|-------------|-----------|-------------|
| `GET`   | `/`         | free      | Service info + endpoint catalog + pricing |
| `POST`  | `/generate` | free, 10/60s/IP | PR diff + body + runnable `gh pr create` command |
| `POST`  | `/submit`   | 200 sats Lightning | Opens the PR if `X-Github-Token` provided; otherwise returns the prepared command |
| `GET`   | `/pro`      | $9 Lightning | Legacy paywall demo (worked example) |

### `POST /generate` example

```bash
curl -X POST http://127.0.0.1:8101/generate \
  -H 'content-type: application/json' \
  -d '{
    "awesome_repo": "bcongdon/awesome-lightning-network",
    "project": {
      "name": "my-cool-tool",
      "url": "https://github.com/me/my-cool-tool",
      "description": "LND channel rebalancing advisor with routing analytics.",
      "language": "Python",
      "license": "MIT",
      "tags": ["lnd", "rebalance", "tools"]
    }
  }'
```

Response (truncated):

```json
{
  "ok": true,
  "tier": "free",
  "pr": {
    "awesome_repo": "bcongdon/awesome-lightning-network",
    "suggested_section": "Tools",
    "section_match_score": 0.18,
    "entry_line": "- [my-cool-tool](https://github.com/me/my-cool-tool) - LND channel rebalancing advisor with routing analytics.",
    "diff": "--- a/README.md\n+++ b/README.md\n...",
    "pr_title": "Add my-cool-tool to Tools",
    "pr_body": "...",
    "gh_pr_create_command": "# 1. Fork + clone ...\n# 2. Apply the diff ...\ncat <<'BODY' | gh pr create ..."
  }
}
```

### `POST /submit` flow

1. **First call** returns 402 with a BOLT-11 invoice for 200 sats.
2. Pay it in any LN wallet (Phoenix, Alby, Wallet of Satoshi, Zeus).
3. **Second call** with `?payment_hash=<hash-from-402>`:
   - With `X-Github-Token: ghp_...` header → we run `gh pr create` on your behalf (token never stored, never logged, never echoed).
   - Without → response includes the fully-prepared command for you to run locally.

```bash
curl -X POST "http://127.0.0.1:8101/submit?payment_hash=$PH" \
  -H 'content-type: application/json' \
  -H "X-Github-Token: $GH_TOKEN" \
  -d '{ "awesome_repo": "...", "project": {...} }'
```

## Pricing

- `/generate` — **free**, 10 req / 60s per IP. Rate-limit response includes the `/submit` upgrade path.
- `/submit` — **200 sats** per PR. Either auto-open or fully-prepared command.
- `/pro` — **$9** legacy paywall demo (worked example of what `/submit` produces).

Why so cheap on `/submit`? Per market-truth doctrine: ship + measure. 200 sats keeps friction low while the niche proves itself.

## Quick start

```bash
pip install -e .
python -m milo_awesome_list_pr_generator.server --port 8101
```

Or via uvicorn:

```bash
uvicorn milo_awesome_list_pr_generator.server:app --port 8101
```

## Lightning provider setup (30s)

```bash
export MILO_LIGHTNING_INVOICE_KEY=<your-LNBits-invoice-key>
export MILO_LIGHTNING_BASE_URL=https://legend.lnbits.com  # or your self-host
```

Defaults to LNBits. To swap providers, see `_milo_paywall_kit/`.

## Architecture

- `domain.py` — pure-python; no HTTP outbound except `fetch_awesome_list` (injectable opener for tests)
- `server.py` — FastAPI; routes wired to `milo_paywall_kit` for L402-style 402 mediation
- `tests/` — 40 tests total: 24 domain + 10 endpoint + 6 baseline scaffold

## Security

- `X-Github-Token`, when supplied to `/submit`, is held only in the request-handler frame.
- We never log it, never persist it, never echo it in responses (test enforces this).
- Auto-submit is **disabled** by default. Production deployment must opt in via `MILO_AWESOME_LIST_PR_GENERATOR_ALLOW_AUTO_SUBMIT=1` AND inject a real `run_gh_pr_create` via DI.
- Per CLAUDE.md: this is a content **generator**, not a publisher. We don't auto-push to non-Milo repos without explicit caller auth + opt-in.

## README badge embed

Add to your project's README to show it was awesome-list-submitted with this tool:

```markdown
[![PR'd via milo](https://img.shields.io/badge/PR'd_via-milo--awesome--list--pr--generator-yellow)](https://github.com/miloantaeus/milo-awesome-list-pr-generator)
```

## 30-day kill criterion

Per market-truth doctrine: **< 50 GitHub stars + 0 paid submissions in 60 days → deprecate.**

Tracked metrics:
- GitHub stars on this repo
- Count of settled 200-sat invoices for `/submit`
- Count of `/generate` calls (proxy for free-tier interest)

If we hit the bar, Milo expands. If we don't, Milo kills it. No supervisor approval required for the kill — that's the doctrine.

## Tests

```bash
pip install -e ".[test]"
pytest -q
# ====== 40 passed in 0.17s ======
```

## Honest probability assessment

Build brief claimed:
- First `/generate` call within 30d: **30%**
- First paid `/submit` within 60d: **10%**

My take (see commit msg of launch post): I think first `/generate` is closer to **45%** (distribution is straightforward — HN Show, Stacker.News, the awesome-list's own PR thread) but first paid `/submit` is closer to **6%** because most awesome-list submitters are technical enough to copy-paste a `gh pr create` command, and Lightning payment friction (even at 200 sats) is non-trivial. The brief's numbers err on the conservative side for free + the optimistic side for paid.

## License

MIT.
