sakshamandClaude Sonnet 5 5b450f22cf Prefill notification email in Add Company wizard with the account's own email
Was always blank by default. Now prefilled from useCurrentUser() once it
loads (defaultValues can't do this since the query resolves after mount),
gated on the field not being dirty yet so it never clobbers something the
user already typed - still fully editable either way.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-05 21:07:32 -04:00

CI Agent — Competitive Intelligence Monitoring

CI Agent monitors companies you choose, collects publicly available information from multiple sources on a schedule, analyzes it with an LLM into an evidence-linked report, detects meaningful changes between runs, and alerts you by email (and optionally SMS) with a severity and confidence score.

See PLAN.md for the build strategy, ARCHITECTURE.md for system design, SECURITY.md for the threat model, TASKS.md for the live implementation checklist, KNOWN_LIMITATIONS.md for what's stubbed vs. fully live, and docs/FIREBASE_MIGRATION.md for a (skeptical) look at what moving to Firebase would take.

Quick start (Docker)

git clone <repository>
cd ci-agent
cp .env.example .env
docker compose up --build

Then visit:

Service URL
Frontend http://localhost:3000
Backend API http://localhost:8000
API docs (Swagger) http://localhost:8000/docs

The default .env.example runs in AUTH_MODE=local (no login required, fixed dev user) with LLM_PROVIDER=mock and SEARCH_PROVIDER=mock — the whole demo workflow works with zero paid API keys.

api, worker, and beat build from the same Dockerfile but are separate images — after adding a Python dependency, run docker compose build api worker beat (not just restart) or they'll crash with ModuleNotFoundError on stale images.

Similarly, after adding an npm dependency to apps/web, a plain rebuild isn't enough either — web's node_modules and .next are both persistent anonymous Docker volumes that survive docker compose build web and even a plain docker compose restart web. This means a new package can still 404, and — on Windows + Docker Desktop — an edited existing file can keep serving its pre-edit output after a restart, since the on-disk .next build cache isn't cleared by a restart. Run docker compose rm -f -s -v web && docker compose up -d web to actually pick up new packages or force a clean recompile.

Running without Docker

Backend:

cd apps/api
python -m venv .venv
./.venv/Scripts/activate   # or `source .venv/bin/activate` on macOS/Linux
pip install -e ".[dev]"
cp ../../.env.example ../../.env   # edit DATABASE_URL to the sqlite line if you don't have Postgres running
alembic upgrade head
uvicorn app.main:app --reload

Frontend:

cd apps/web
npm install
npm run dev

Common commands

# Database migrations
cd apps/api && alembic upgrade head
cd apps/api && alembic revision --autogenerate -m "description"

# Run a Celery worker + beat (only needed outside Docker)
cd apps/api && celery -A app.tasks.celery_app worker --loglevel=INFO -Q default,collection,analysis,notifications,maintenance
cd apps/api && celery -A app.tasks.celery_app beat --loglevel=INFO

# Backend tests / lint / format
cd apps/api && pytest
cd apps/api && ruff check app tests
cd apps/api && black app tests

# Frontend tests / lint / format / typecheck
cd apps/web && npm test
cd apps/web && npm run lint
cd apps/web && npm run format
cd apps/web && npm run typecheck

# End-to-end test (requires `docker compose up -d` already running)
cd apps/web && npx playwright install --with-deps chromium   # one-time
cd apps/web && npm run e2e

Configuration

All configuration is via environment variables — see .env.example for the full list with comments. Highlights:

  • AUTH_MODE=local|jwt — local single-user dev mode vs. real email/password accounts.
  • LLM_PROVIDER=mock|anthropic|ollama|gemini — set ANTHROPIC_API_KEY/ANTHROPIC_MODEL, OLLAMA_BASE_URL/OLLAMA_MODEL, or GEMINI_API_KEY/GEMINI_MODEL to go live. Gemini has a genuine free tier — grab a key at aistudio.google.com/apikey — so it's the cheapest provider to actually try against a real model.
  • SEARCH_PROVIDER=mock|brave — set BRAVE_SEARCH_API_KEY to go live.
  • SMTP_HOST/RESEND_API_KEY — no bundled local mail sink; point SMTP at a real relay or set RESEND_API_KEY to actually test email delivery (alerts and security email both use this).
  • NOTIFICATION_SMS_ENABLED=false by default — set to true and provide TWILIO_* to enable SMS.

Every paid/external provider defaults to a mock/console implementation. Automated tests always run against mocks and never call a paid API.

Known limitations

See KNOWN_LIMITATIONS.md.

S
Description
CI Agent - competitive intelligence monitoring
Readme
924 KiB
Languages
Python 72.3%
TypeScript 27.1%
Shell 0.4%