{"id":50571738,"url":"https://github.com/nborwankar/tandc","last_synced_at":"2026-06-04T19:01:27.218Z","repository":{"id":359503066,"uuid":"1246357704","full_name":"nborwankar/tandc","owner":"nborwankar","description":"Terms \u0026 Conditions risk analyzer — CLI + local web UI for surfacing user-relevant risks in T\u0026Cs via the Anthropic Claude API","archived":false,"fork":false,"pushed_at":"2026-05-22T14:17:16.000Z","size":555,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-22T14:49:01.123Z","etag":null,"topics":["anthropic","claude","claude-api","consumer-protection","fastapi","llm-application","privacy-policy","python","risk-analysis","terms-of-service","text-analysis","typer"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nborwankar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-22T05:52:54.000Z","updated_at":"2026-05-22T14:17:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nborwankar/tandc","commit_stats":null,"previous_names":["nborwankar/tandc"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/nborwankar/tandc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nborwankar%2Ftandc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nborwankar%2Ftandc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nborwankar%2Ftandc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nborwankar%2Ftandc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nborwankar","download_url":"https://codeload.github.com/nborwankar/tandc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nborwankar%2Ftandc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33916321,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anthropic","claude","claude-api","consumer-protection","fastapi","llm-application","privacy-policy","python","risk-analysis","terms-of-service","text-analysis","typer"],"created_at":"2026-06-04T19:01:26.066Z","updated_at":"2026-06-04T19:01:27.203Z","avatar_url":"https://github.com/nborwankar.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tandc — Terms \u0026 Conditions risk analyzer\n\nSurfaces what's risky for users in a website or software T\u0026C /\nprivacy policy: personal-data use, missing PII protections,\nunilateral changes, arbitration / class-action waivers, and more.\n\n## Status\n\nStage 1 v1 (CLI) and v2 (local web UI) shipped 2026-05-21 on\n`main`. See [PLAN.md](PLAN.md) for the roadmap, [DONE.md](DONE.md)\nfor the ship log, and [docs/superpowers/specs/](docs/superpowers/specs/)\nfor the design history.\n\n## How it works\n\nA small pure-library core (`tandc.core`) does the analysis pipeline. Two front-ends share it: a `typer` CLI and a FastAPI local web UI. The web UI exposes a single `POST /analyze` JSON endpoint that a future Stage 2 Chrome extension will also call — same backend, different UX layer.\n\n```\n┌─ CLI ──────────────────┐      ┌─ Web UI ──────────────────────────────┐\n│ tandc analyze \u003cURL|-\u003e  │      │ browser tab @ 127.0.0.1:8765          │\n│ tandc analyze file.pdf │      │   form: URL / paste / file (HTML/PDF) │\n└──────────┬─────────────┘      └─────────────────┬─────────────────────┘\n           │                                      │ fetch()\n           │                                      ▼ POST /analyze\n           │                    ┌─────────────────────────────────────┐\n           │                    │  FastAPI  (tandc.web.app)           │\n           │                    │  POST /analyze  (api.py)            │\n           │                    │  GET  /        (static HTML/JS/CSS) │\n           │                    │  GET  /docs    (OpenAPI auto)       │\n           │                    └─────────────────┬───────────────────┘\n           ▼                                      ▼\n┌────────────────────────────────────────────────────────────────────────┐\n│              tandc.core.analyze()  /  analyze_prepared()               │\n│                                                                        │\n│   loader  →  cache  →  Claude (Sonnet/Opus)  →  schema  →  render      │\n│   (URL+httpx,  (SHA-256     (system-prompt    (Pydantic   (rich for    │\n│    PDF,        content-      caching,          v2,         CLI;        │\n│    paste)      hash file     2-retry on        Core 4 +    Markdown +  │\n│                cache at      malformed)        Flag 4)     JSON for    │\n│                ~/.tandc/)                                  files)      │\n└────────────────────────────────────────────────────────────────────────┘\n                                  │\n                                  ▼\n              ./reports/\u003chost-slug\u003e-\u003cdate\u003e/{input.txt,\n                                            fetch_meta.json,\n                                            report.json,\n                                            report.md}\n```\n\nReports follow a fixed taxonomy: **4 Core findings** (personal data, PII protection, continuity, liability/dispute) each with severity + verbatim evidence quotes, plus **4 Flags** (content licensing, account access, payment/subscription, jurisdictional) with presence + note.\n\n## Setup\n\nYou need: git, Python 3.11+, a virtual-env manager (conda or venv — both shown below), and an Anthropic API key from \u003chttps://console.anthropic.com/settings/keys\u003e.\n\n```bash\n# 1. Clone\ngit clone https://github.com/nborwankar/tandc.git\ncd tandc\n\n# 2. Create a virtual environment — pick ONE of the two:\n\n# (a) conda (recommended if you have it)\nconda create -n tandc python=3.11 -y\nconda activate tandc\n\n# (b) venv (stdlib, no extra install needed)\npython3.11 -m venv .venv\nsource .venv/bin/activate           # Windows: .venv\\Scripts\\activate\n\n# 3. Install the package\n#     Users (just want to run the tool):\npip install -e .\n#     Contributors (also need pytest, ruff, etc.):\npip install -e \".[dev]\"\n\n# 4. Set your API key (and add this line to ~/.zshrc or your shell rc file)\nexport ANTHROPIC_API_KEY=sk-ant-...   # get one at https://console.anthropic.com/settings/keys\n\n# 5. Verify\ntandc --help\n```\n\ntandc reads `ANTHROPIC_API_KEY` from the process environment — it does **not** load `.env` files automatically. If you keep secrets in `~/.env` or a per-project `.env`, source it before invoking (e.g. add `set -a; source ~/.env; set +a` to your shell rc, or to a wrapper script).\n\n## Usage — CLI (v1)\n\n```bash\ntandc analyze https://docs.github.com/en/site-policy/github-terms/github-terms-of-service\ncat policy.txt | tandc analyze -\ntandc analyze https://slack.com/terms-of-service/user --opus\ntandc cache list\n```\n\nReports are written under `./reports/\u003chost-slug\u003e-\u003cdate\u003e/`.\n\nThree more T\u0026C URLs known to fetch and analyze cleanly, if you want to try the tool against different services:\n\n- Dropbox — \u003chttps://www.dropbox.com/terms\u003e\n- Discord — \u003chttps://discord.com/terms\u003e\n- Wikimedia Foundation — \u003chttps://foundation.wikimedia.org/wiki/Terms_of_Use/en\u003e\n\n(Some sites — notably OpenAI's policy pages — return HTTP 403 to automated fetches and won't work directly; paste the text via stdin instead.)\n\n## Usage — local web UI (v2)\n\nThe recommended way to start the server is the launcher script — it\nsets up the conda PATH, checks the API key, and execs `tandc serve`:\n\n```bash\n./scripts/serve.sh                       # 127.0.0.1:8765 (default)\n./scripts/serve.sh --port 9000\n./scripts/serve.sh --host 0.0.0.0        # LAN-accessible (opt-in)\n./scripts/serve.sh --reload --debug      # dev mode\n```\n\nThen open `http://127.0.0.1:8765/` in any browser. Submit a URL,\npasted text, or upload an HTML / TXT / PDF file; the rendered\nreport appears inline. FastAPI-generated API docs live at\n`/docs`.\n\nExit codes (matches the CLI):\n\n| Code | Meaning |\n|------|---------|\n| 0 | clean shutdown |\n| 4 | `ANTHROPIC_API_KEY` not set |\n| 5 | port already in use |\n\n### Hitting the API directly\n\n```bash\ncurl -X POST http://127.0.0.1:8765/analyze \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"url\":\"https://example.com/terms\",\"use_cache\":true}'\n\ncurl -X POST http://127.0.0.1:8765/analyze \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"text\":\"...policy body...\",\"source_url\":\"https://...\"}'\n\ncurl -X POST http://127.0.0.1:8765/analyze \\\n  -F \"file=@policy.pdf;type=application/pdf\"\n```\n\nWeb mode writes the same `./reports/\u003cslug\u003e-\u003cdate\u003e/` bundle the CLI\ndoes. The response JSON includes `report_dir` (absolute path) and\n`cache_hit` (bool).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnborwankar%2Ftandc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnborwankar%2Ftandc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnborwankar%2Ftandc/lists"}