new-term-radar
Daily radar for new AI terms: names of new models, products and repos, caught on X, Hugging Face, GitHub and sitemaps before keyword tools list them.
Know which companies are ready to buy before your competitors do. Intent data for SMB sales teams at a fraction of enterprise pricing.
MarketingTypeScript · HTMLGitHub @abdorabeeOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗B2B sales intelligence platform that scores companies by purchase intent using time-bound evidence and AI reasoning.
The wiki expands every section below. Start at the wiki index.
VesperWise scores four purchase-intent triggers—funding, hiring, news, and technology changes—and keeps web authority and GitHub activity as supporting context. The versioned scoring model returns a 0–100 score, source coverage, freshness-adjusted contributions, and an AI-generated buying-stage analysis. A separate icp_fit_score measures fit against a verified workspace business profile without changing purchase intent.
Score bands: HOT (≥75) · WARM (50–74) · COLD (<50)
user_* id. There is no cookie-based Supabase auth client.background_jobs, not Redis)npm install
Create .env.local:
# Supabase
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
# Clerk
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
CLERK_SECRET_KEY=
# OpenRouter (bounded score reasoning; deterministic fallback if unset)
OPENROUTER_API_KEY=
# Chat model override (default anthropic/claude-sonnet-4)
# COPILOT_MODEL=
# Polar.sh billing
POLAR_ACCESS_TOKEN=
POLAR_WEBHOOK_SECRET=
POLAR_PRODUCT_STARTER=
POLAR_PRODUCT_PLUS=
POLAR_PRODUCT_GROWTH=
POLAR_PRODUCT_PRO=
POLAR_PRODUCT_TOPUP_25=
POLAR_PRODUCT_TOPUP_70=
POLAR_PRODUCT_TOPUP_140=
# Vercel Cron (daily free-plan credit refill; the route returns 503 if unset)
CRON_SECRET=
# Signal sources (only needed when MOCK_SIGNALS=false)
EXPLORIUM_API_KEY=
GNEWS_API_KEY=
BUILTWITH_API_KEY=
OPEN_PAGE_RANK_API_KEY=
GITHUB_TOKEN=
# Contact form (optional; logs to the console if unset)
RESEND_API_KEY=
# Skip real API calls during development
MOCK_SIGNALS=true
# Core scoring rollout (default true). Set false for the saturated four-trigger rollback engine.
SCORING_V2_ENABLED=true
# V3 remains opt-in and automation-disabled. Shadow comparison stores v3 beside active v2.
SCORING_V3_ENABLED=false
SCORING_V3_SHADOW_ENABLED=false
# Optional Postgres-backed cache/worker controls
CACHE_DISABLED=false
# Queue hiring/web-enrichment jobs in Postgres; enable only where a worker runs
BACKGROUND_JOBS_ENABLED=false
SCRAPLING_SHADOW_MODE=true
SCRAPLING_PROMOTED_ADAPTERS=
SCRAPLING_BROWSER_ENABLED=false
SCRAPLING_JOB_TIMEOUT_MS=90000
# PYTHON_BIN=python3
# Fresh public-web evidence worker (Firecrawl; shadow mode by default)
FIRECRAWL_API_KEY=
WEB_ENRICHMENT_SHADOW_MODE=true
WEB_ENRICHMENT_PROMOTED_SIGNALS=
WEB_ENRICHMENT_WATCHLIST_INTERVAL_MS=21600000
WEB_ENRICHMENT_DAILY_PAGE_BUDGET=1500
# Crawl funding only when the structured provider is missing/stale.
WEB_ENRICHMENT_FUNDING_FALLBACK=false
# treg fallback data layer (pay-per-call; shadow mode by default)
# Called only when a primary provider returns unavailable/not_found.
TREG_TOKEN=
TREG_FALLBACK_SHADOW_MODE=true
# Comma list of: funding,hiring,news,technology,firmographics
TREG_PROMOTED_SIGNALS=
Set MOCK_SIGNALS=true to use deterministic mock signals seeded by domain — no external API keys required for local dev.
npm run dev # localhost:3000
npm run build # production build
npm run lint # ESLint
npm test # Vitest, one run
npm run test:scoring-db # destructive only to an explicitly confirmed disposable Postgres database
npm run test:cache-queue-db # same class of reset, for the Postgres cache and queue
npm run test:watch
npm run dead-code # Knip production file and dependency check
app/api/v1/score/route.ts)| Source | Base weight | Composite role |
|---|---|---|
| Funding | 22 | Scored trigger |
| Hiring | 19 | Scored trigger |
| News | 18 | Scored trigger |
| Technology | 18 | Scored trigger |
| Web | — | Context only |
| GitHub | — | Context only |
The four trigger weights total 77. Each source score is normalized to 0–100, then decayed from its own verified observed_at timestamp:
normalized_i = 100 × clamp(source_score_i / source_max_i, 0, 1)
freshness_i = 0.85 ^ (max(age_days_i, 0) / 30)
coverage = Σ(base_weight_i × status_factor_i) / 77
intent_score = round(Σ(effective_weight_i × normalized_i × freshness_i)
/ Σ(effective_weight_i))
Coverage factors are 1 for ok and verified no_signal, 0.5 for stale, and 0 for not_found or unavailable. The effective weight is the base weight multiplied by that factor. Verified no_signal contributes zero score with full coverage.
| Coverage | score_status | Result |
|---|---|---|
1.0 | complete | Full score; eligible for automation after the baseline run |
0.6 to <1.0 | partial | Score returned with reduced source coverage |
<0.6 | unscorable | Null score and band; no credit charged |
There is no sigmoid or cross-signal boost. The freshness curve retains 85% of a trigger after 30 days, and the response exposes the calculation in contributions. Score bands remain HOT (≥75), WARM (50–74), and COLD (<50).
POST /api/v1/score is the canonical interface. Supply a domain and optionally the display name; use Idempotency-Key when a client may retry the same request.
curl -X POST http://localhost:3000/api/v1/score \
-H "Authorization: Bearer $VESPERWISE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: score-acme-2026-07-15" \
-d '{"domain":"acme.com","company":"Acme"}'
GET /api/v1/score?domain=acme.com&company=Acme remains available as a compatibility wrapper. New integrations should use POST. Reusing an idempotency key with the same request replays its terminal result; reusing it for different input is rejected.
Important response fields include scoring_version, scoring_policy_id, score_status, data_coverage, signal_coverage, contributions, source_status, cached, and charged. Each contribution records raw strength, recency, effective weight, score points, source, confidence, reason codes, and evidence URLs. icp_fit_score is returned separately when the workspace has a verified business profile; it is never blended into intent_score.
The in-app reference is /docs.
lib/route-access.ts is the auth allow-list. Unknown pages 404. API routes deny by default except /api/v1/*, /api/chat, /api/billing/webhook, and /api/contact.
| Group | Path | Purpose |
|---|---|---|
(auth) | /login, /signup | Unauthenticated layout |
| Marketing | /, /pricing, /about, /contact, /docs, /privacy, /terms | Public pages |
(dashboard) | /dashboard, /score, /analyze, /people, /bulk, /watchlist, /lists, /pipeline, /history, /inbox, /autopilot, /settings, /billing, /api-keys | Authenticated layout |
api/v1/ | /score, /score/bulk, /score/bulk-inline, /score/person, /score/history, /watchlist, /prioritize | Public REST API (key or session checked in the handler) |
api/billing/ | /checkout, /topup, /portal, /webhook | Polar.sh integration |
api/user/ | /api-keys, /profile, /account, /scoring-policy | Account, profile, and policy |
api/autopilot/ | /workflows, /runs, /execute, /test | Workflow engine |
api/chat/ | /, /sessions | Copilot |
/onboarding and /dev are public only when VERCEL_ENV is not production.
The dashboard shell has five zones: an icon rail, a per-page list column (⌘B), the main view, a right panel, and a status bar. Pages fill the list column and panel through ShellList / ShellPanel in components/dashboard/shell/. Clicking an account on Pipeline, History, Watchlist or a list opens the shared account panel (components/account-panel/), kept in the URL as ?account=<domain>.
lib/types.ts — shared types, PLAN_CREDITS, PLAN_WATCHLIST_LIMIT, PLAN_RATE_LIMITlib/plan-features.ts — plan prices, top-up packs, and marketing feature lineslib/supabase.ts — createSupabaseAdmin() (service role). Callers use the service role; Clerk is the identity provider.lib/user-provisioning.ts — ensureUserRecord upserts the users row for a Clerk id. Callers must handle { ok: false }.lib/cache.ts — Supabase-backed cache; no-ops when CACHE_DISABLED=truelib/score-service.ts — evidence reuse, personalized caching, idempotent runs, persistence, and charginglib/scorer.ts — versioned linear intent model, freshness, coverage, and bandslib/reasoning.ts — one bounded, schema-validated OpenRouter request with a deterministic fallbacklib/signals/mock.ts — deterministic mock signals for devlib/hiring-refresh-queue.ts — best-effort Postgres queue producer for first-party hiring refresheslib/web-enrichment-queue.ts — best-effort Postgres queue producer for Firecrawl evidencelib/route-access.ts — private page and public API rules used by middlewareproxy.ts — Next.js 16 middleware (named export proxy); refreshes the Clerk session and protects dashboard pathsPlans: free · starter · plus · growth · pro · agency (agency is not sold)
Credits reset on subscription change (Polar webhook subscription.created / subscription.updated). One-time top-ups increment credits without changing plan (order.paid). A single company score reserves one credit. A 6-hour cache hit does not. Prices are PLAN_PRICE in lib/plan-features.ts.
| Plan | Price | Credits/mo | Watchlist |
|---|---|---|---|
| Free | $0 | 20 | 5 |
| Starter | $10 | 100 | 25 |
| Plus | $29 | 400 | 75 |
| Growth | $79 | 1,200 | 250 |
| Pro | $199 | 3,000 | 1,000 |
| Agency | Contact us | 25,000 | unlimited |
Top-ups: 25 scores for $3, 70 for $8, 140 for $15.
Workflow engine with conditional triggers (score_above, score_below, score_change, band_change, signal_spike) and actions (email_draft, webhook, slack, pipeline_stage, notification). Condition logic is any or all. Schedules are daily or weekly. Run history is stored on the workflow.
/people)Scores individuals by email, LinkedIn URL, or name. Signals: career change (30 pts), seniority fit (20 pts), company intent (20 pts), news mentions (15 pts), social presence (15 pts). The live path builds the profile from those submitted fields in lib/pdl.ts. It does not call Apollo or People Data Labs. lib/apollo.ts still has an Apollo People Match client, and the person-score service does not use it.
The dashboard CSV flow (POST /api/v1/score/bulk-inline) scores up to 50 companies inline and uses the same per-company cache and atomic charging behavior. Free and Starter are blocked. The public bulk endpoint accepts up to 1,000 companies and three concurrent jobs. It scores in bounded batches, debits one credit per scored company, leaves cache hits free, and stops when credits run out. A job that stops making progress is marked failed so it releases the concurrency cap. Polling GET /api/v1/score/bulk?job_id= continues a processing job, and webhook_url is called when the job finishes. The hiring-refresh and web-enrichment workers do not process bulk scoring jobs.
Background jobs are only written when BACKGROUND_JOBS_ENABLED=true on the web app; set it wherever a worker is deployed. When Explorium hiring evidence is unavailable, not_found, or stale, the web app can enqueue a deduplicated hiring-refresh job. The worker crawls only the company's HTTPS careers pages and approved Greenhouse, Lever, Ashby, or Workable tenants, then stores hiring-v2 evidence in signal_evidence.
Scrapling evidence is written in shadow mode by default. Only evidence deliberately promoted with shadow=false can affect scoring, and it is used as a fallback—never added to fresh Explorium hiring evidence. See workers/hiring-refresh/README.md for deployment, safety constraints, and test commands.
The worker uses the Postgres-backed background_jobs queue and requires only Supabase credentials plus its crawler settings.
Every company score best-effort enqueues a deduplicated web-enrichment job.
The Firecrawl worker extracts dated hiring, company-announcement, and
technology-change evidence and maintains first-party page snapshots for
meaningful web-activity changes. Funding is excluded by default and is crawled
only when WEB_ENRICHMENT_FUNDING_FALLBACK=true and the structured source is
missing or stale. Scrapling remains a separate careers/ATS fallback worker.
Site maps are cached for seven days, each account scrape is capped at five
targeted pages, and a daily page budget stops new work before the configured
limit. web_enrichment_runs records latency, attempts, pages, and estimated
provider credits. The first snapshot creates a baseline and never creates
intent; only a later material content delta can produce web_activity.
New evidence is shadow-only by default. Promoted rows compete with provider
evidence through freshness, positive-event, entity-match, and confidence
selection; only one source is used for each trigger, so observations are never
double-counted. A crawl that finds no verified dated event is unavailable,
not zero intent. See
workers/web-enrichment/README.md for
deployment, promotion, and safety constraints.
V3 uses funding 25%, hiring 25%, news 20%, technology change 20%, and meaningful
web activity 10%, with per-signal half-lives of 180, 45, 30, 90, and 14 days.
It requires four signal-equivalents and 75% weighted coverage. Keep v2 active
and set SCORING_V3_SHADOW_ENABLED=true to persist comparable v3 results in
score_shadow_results. SCORING_V3_ENABLED=true makes v3 user-facing, but v3
automation remains database-disabled until a separate promotion migration.
Custom organization, ICP, or vertical policies can be managed through
/api/user/scoring-policy. Pipeline users can attach closed_won,
closed_lost, no_decision, or disqualified to the exact score snapshot;
these labels are stored in score_outcomes.
Real-time chat with embedded score cards. Claude is routed through OpenRouter (COPILOT_MODEL, default anthropic/claude-sonnet-4). Conversation history is persisted to chat_sessions / chat_messages. Chats cost 0.25 credits per message.
Located in supabase/migrations/. Run via Supabase CLI:
supabase db push
Before deploying scoring v2, apply the migration to a disposable Postgres database and exercise the real transactional RPCs. The integration suite refuses ordinary database names and requires the reset confirmation to exactly match the disposable database name:
SCORING_V2_TEST_DATABASE_URL=postgres://localhost/scoring_v2_test \
SCORING_V2_TEST_ALLOW_RESET=scoring_v2_test \
npm run test:scoring-db
The suite resets that database's public schema, then verifies concurrent
last-credit reservations, cross-user/profile cache isolation, idempotent replay,
persistence-failure refunds, and stale-run recovery against the migration itself.
Enable the Supabase Cron Postgres module before applying the production
migration. The migration then installs the named scoring-v2-stale-run-reaper
job every five minutes; it refunds reservations left running for more than 15
minutes. If Cron is intentionally disabled, invoke
reap_stale_score_runs(100) from a service-role scheduler at the same cadence.
The wiki lists every migration file. Notable ones:
background_jobs (Redis replacement)Deploy to Vercel. Set all environment variables in the Vercel dashboard. The Polar webhook endpoint (/api/billing/webhook) must be registered in the Polar dashboard with the correct signing secret. Enable BACKGROUND_JOBS_ENABLED only on a deployment that runs the hiring refresh or web enrichment worker. Leave both workers in shadow mode until an adapter or signal is explicitly promoted.