Metadata-Version: 2.4
Name: dogfu
Version: 0.4.0
Summary: Internal admin/marketing CLI — discovery, enrichment, outreach, and CRM over one interface.
Requires-Python: >=3.11
Requires-Dist: click>=8.1
Requires-Dist: requests>=2.31
Requires-Dist: rich>=13.7
Provides-Extra: dev
Requires-Dist: black>=24.0.0; extra == 'dev'
Requires-Dist: isort>=5.13.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: responses>=0.25.0; extra == 'dev'
Description-Content-Type: text/markdown

# dogfu

Internal admin CLI + SDK for Agent Berlin staff (`admin_users`). One
interface over LinkedIn, X, Google, ChatGPT, SEO (the dogfu data API) and the
Close CRM (via the admin CRM proxy). The sibling of `backend/sdk-python` — same
transport posture (a single Bearer token against the Berlin backend, retry with
backoff, a typed exception hierarchy, config-file session), scoped to the
internal admin surface instead of a customer project.

## Auth

dogfu authenticates with a single **session token** (a short-lived JWT, 24h),
minted by exchanging a one-time OTP from the dogfu MCP's `get_setup_instructions`:

```bash
dogfu configure --otp <OTP> --title "<what this session is for>"
```

This `POST`s `{otp, title}` to `/dogfucli/exchange-otp` and saves the returned
token to `~/.dogfu/config.json`. Subsequent commands resolve the token from
`DOGFU_TOKEN` first, then that file. There is no refresh endpoint — on an auth
failure, run `get_setup_instructions` again for a fresh OTP and re-`configure`.

dogfu is **not project-scoped** (no `--domain`); access is platform-wide for
staff.

## Endpoints

Everything goes through the Berlin backend (`https://backend.agentberlin.ai` by
default; override with `--base-url` / `DOGFU_BASE_URL`):

| Group | Backend route |
| --- | --- |
| `linkedin` / `x` / `google` / `chatgpt` / `seo` | `/api/v1/admin/dogfu/*` |
| `crm` | `/api/v1/admin/crm/*` — allowlisted proxy to Close CRM |

The CRM proxy holds the per-admin Close key server-side (configured from the
admin Console), so dogfu never sees a Close credential — it forwards Close
sub-paths under the dogfu session token.

## Usage

```bash
dogfu --help                  # list groups
dogfu <group> --help          # list a group's commands
dogfu <group> <cmd> --help    # flags + the Output: data shape

dogfu seo domain-overview --target acme.com
dogfu crm lead create --name "Acme" --url https://acme.com
```

Output is canonical JSON by default (`-f table` for humans, `-o FILE` to write).

## Programmatic use

```python
from dogfu import Dogfu
dx = Dogfu()                                  # resolves DOGFU_TOKEN / config file
dx.seo.domain_overview(target="acme.com")     # -> DomainOverview
dx.crm.create_lead(name="Acme")
```

## Develop

```bash
uv run python tests/smoke.py   # offline checks (normalizers, models, SDK wiring)
```
