Metadata-Version: 2.4
Name: interly
Version: 0.1.2
Summary: Developer-tool discovery pipeline and CLI for Interly.
Author: Ateno
Project-URL: Homepage, https://github.com/AtenoTech/Interly
Project-URL: Repository, https://github.com/AtenoTech/Interly
Project-URL: Issues, https://github.com/AtenoTech/Interly/issues
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: fastapi<1.0,>=0.115
Requires-Dist: feedparser<7.0,>=6.0
Requires-Dist: openai<2.0,>=1.86
Requires-Dist: pydantic<3.0,>=2.11
Requires-Dist: python-dotenv<2.0,>=1.0
Requires-Dist: requests<3.0,>=2.32
Requires-Dist: uvicorn<1.0,>=0.35

# Interly MVP

Interly is a developer-tool discovery pipeline layered into the existing TanStack Start app. The current UI keeps using the existing Interly shell and routes, while a small Python sidecar handles collection, deduplication, Grok classification, scoring, SQLite persistence, digest email, and the `/api/interly/*` backend.

## Multi-user Integrations (Firebase)

Interly now supports user-owned destination integrations for:

- Email
- Slack OAuth and Slack webhooks (advanced/manual)
- Discord OAuth bot integration and Discord webhooks (advanced/manual)
- Telegram chat delivery via deep-link bot connect

The integrations system is implemented in app server routes and uses Firebase as the source of truth:

- Protected APIs verify `Authorization: Bearer <Firebase ID token>` with Firebase Admin.
- Per-user data is stored under `users/{uid}/integrations/{integrationId}` and `users/{uid}/digestDeliveries/{deliveryId}`.
- Delivery logs are written to `users/{uid}/integrations/{integrationId}/deliveryLogs/{logId}`.
- Integration secrets are encrypted server-side with `ENCRYPTION_KEY` and stored under `users/{uid}/integrationSecrets/{integrationId}`.
- Telegram pairing uses `telegramConnectionCodes/{code}` and a webhook endpoint.

New UI:

- Integrations page: `/app/integrations`

Backend endpoints:

- `GET /api/interly/integrations`
- `POST /api/interly/integrations`
- `PATCH /api/interly/integrations/:integrationId`
- `DELETE /api/interly/integrations/:integrationId`
- `POST /api/interly/integrations/:integrationId/test`
- `GET /api/interly/integrations/:integrationId/logs`
- `POST /api/interly/send-digest`
- `GET /api/interly/slack/connect`
- `GET /api/interly/slack/callback`
- `POST /api/interly/slack/select-channel`
- `GET /api/interly/discord/connect`
- `GET /api/interly/discord/callback`
- `GET /api/interly/discord/guilds-or-channels`
- `POST /api/interly/discord/select-channel`
- `POST /api/interly/telegram/create-deep-link`
- `GET /api/interly/telegram/connection-status`
- `POST /api/interly/telegram/create-connection-code`
- `POST /api/interly/telegram/confirm-connection-code`
- `POST /api/telegram/webhook`
- `POST /api/gumroad/webhook`
- `POST /api/gumroad/reconcile`
- `POST /api/interly/ateno-search`
- `POST /api/interly/ateno-search-email`

## Required environment variables

Create a local `.env` file or export these before running the Python sidecar:

```bash
GROK_API_KEY=
ATENO_SEARCH_GROK_MODEL=grok-4.3
GITHUB_TOKEN=
GMAIL_USER=
GMAIL_APP_PASSWORD=
RECIPIENT_EMAIL=
DAYS_LOOKBACK=3
MIN_GITHUB_STARS=10
MAX_EMAIL_ITEMS=10
INTERLY_API_BASE_URL=http://127.0.0.1:8001

# Firebase Admin (server)
FIREBASE_ADMIN_PROJECT_ID=
FIREBASE_ADMIN_CLIENT_EMAIL=
FIREBASE_ADMIN_PRIVATE_KEY=
# Alternative for local development
# GOOGLE_APPLICATION_CREDENTIALS=/absolute/path/to/firebase-service-account.json

# Destination delivery
ENCRYPTION_KEY=
SMTP_USER=
SMTP_PASSWORD=
EMAIL_FROM=
TELEGRAM_BOT_TOKEN=
TELEGRAM_BOT_USERNAME=InterlyBot
TELEGRAM_WEBHOOK_SECRET=

# Gumroad payments
GUMROAD_CHECKOUT_URL=https://checkout.interly.ateno.co
GUMROAD_WEBHOOK_SECRET=

# Slack OAuth
SLACK_CLIENT_ID=
SLACK_CLIENT_SECRET=
SLACK_REDIRECT_URI=
SLACK_SIGNING_SECRET=

# Discord OAuth/bot
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
DISCORD_BOT_TOKEN=
DISCORD_REDIRECT_URI=
```

Notes:

- `GROK_API_KEY` powers Grok classification and summarization. If it is missing, the pipeline falls back conservatively and marks items as excluded.
- `ATENO_SEARCH_GROK_MODEL` powers the Ateno Search endpoint. It defaults to `grok-4.3` because this endpoint uses Grok web search.
- `GITHUB_TOKEN` avoids low anonymous GitHub rate limits.
- `INTERLY_API_BASE_URL` is read by the TanStack app on the server side and defaults to `http://127.0.0.1:8001`.
- `ENCRYPTION_KEY` is mandatory when creating webhook or Telegram integrations. Use a long random secret.
- `FIREBASE_ADMIN_*` credentials are used for ID token verification and Firestore writes.
- For local development, you can alternatively set `GOOGLE_APPLICATION_CREDENTIALS` to the absolute path of a Firebase service-account JSON key.
- In GCP runtimes with ADC, explicit Firebase Admin credentials can be omitted.
- Telegram webhook should be configured with `x-telegram-bot-api-secret-token` matching `TELEGRAM_WEBHOOK_SECRET`.
- Gumroad payment setup and deployment notes are in [`docs/payments.md`](docs/payments.md).

## Local setup

Install the frontend as usual, then create the Python virtualenv once:

```bash
/opt/homebrew/bin/python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
```

Start the Python API in one terminal:

```bash
npm run interly:api
```

Start the app in another terminal:

```bash
npm run dev
```

## CLI

Interly includes a local CLI that uses the project Python sidecar. After setup, run it through npm:

```bash
npm run interly
npm run interly -- --help
```

Common commands:

```bash
npm run interly -- init-db
npm run interly -- run
npm run interly -- run --send-email
npm run interly -- digest
npm run interly -- digest my code
npm run interly -- competitor analysis
npm run interly -- ask "what should I improve in this repo?"
npm run interly -- summary
npm run interly -- tools --min-score 7 --limit 5
npm run interly -- sources
npm run interly -- api --host 127.0.0.1 --port 8001
```

Published users can run the same assistant-style commands directly:

```bash
interly
interly digest my code
interly competitor analysis
interly ask "what should I improve in this repo?"
```

The npm scripts use the same CLI:

```bash
npm run interly:run
npm run interly:api
```

## Publishing the CLI

### npm

The npm package is configured as `@atenotech/interly`, matching the Ateno npm organization scope.

Check the package contents before publishing:

```bash
npm run publish:npm:dry-run
```

Publish from an npm account that belongs to the `atenotech` organization:

```bash
npm login
npm publish
```

After publish, users can run:

```bash
npx @atenotech/interly --help
npm install -g @atenotech/interly
interly --help
```

### PyPI

The Python package is configured as `interly` with the console command `interly`.

Build and publish from a PyPI account that owns the project, or from the approved Ateno organization once billing/approval is active:

```bash
.venv/bin/python -m pip install build twine
.venv/bin/python -m build --outdir py-dist
.venv/bin/python -m twine check py-dist/interly-0.1.2*
.venv/bin/python -m twine upload py-dist/interly-0.1.2*
```

This repo also has a frontend `dist/` directory, so keep Python release artifacts in `py-dist/`.

After publish, users can run:

```bash
pipx install interly
interly --help
```

Trigger the same flows from HTTP:

```bash
curl -X POST http://127.0.0.1:8001/api/interly/run
curl -X POST http://127.0.0.1:8001/api/interly/send-email
```

## Dashboard location

- Daily radar dashboard: `/app/radar`
- Digest preview and send controls: `/app/digest`
- Source health and sync status: `/app/sources`

The Radar page now reads live Interly summary and tool data from the Python backend and adds filters for category, source, minimum score, emailed state, open-source only, and AI-only.

## Current backend layout

- `interly_py/cli.py`: CLI entrypoint for `interly`, including assistant-style prompts plus run, digest, summary, tools, sources, and API commands
- `interly_py/assistant_cli.py`: terminal assistant commands for code digests, competitor analysis, and repository-aware prompts
- `main.py`: compatibility entrypoint for `python main.py`
- `interly_py/api.py`: FastAPI app exposing `/api/interly/summary`, `/api/interly/tools`, `/api/interly/sources`, `/api/interly/run`, `/api/interly/send-email`, and Ateno Search endpoints
- `interly_py/ateno_search.py`: Ateno Search style Grok web-search endpoint for finding tools from user query, interests, and allowed sites
- `interly_py/collectors/*`: GitHub Search, Hacker News Algolia, and RSS collectors
- `interly_py/grok_client.py`: Grok client and strict-JSON classification handling
- `interly_py/scoring.py`: scoring and rejection logic
- `interly_py/repository.py`: SQLite reads/writes for `tools`, `sources`, and `emails_sent`
- `data/interly.db`: local SQLite database

## Deployment options later

This repo currently deploys the frontend through Firebase Hosting, which does not run Python. The practical production options are:

1. Cloud Run service for the Python API plus a Cloud Run Job or Cloud Scheduler trigger for the daily run.
2. GitHub Actions on a schedule to run `main.py`, with the frontend pointing at the deployed Python API.
3. A VM or container with cron running `main.py` daily and `uvicorn interly_py.api:app` as the always-on API.

For all three options, keep the current TanStack app as the frontend and inject `INTERLY_API_BASE_URL` into the frontend server runtime.
