lurqrun 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../node_modules/tsup/assets/esm_shims.js","../../src/core/constants.ts","../../src/core/types.ts","../../src/core/config.ts","../../src/db/schema.ts","../../src/db/client.ts","../../src/core/logger.ts","../../src/core/http.ts","../../src/ingestion/sources/npmRegistry.ts","../../src/ingestion/sources/npmSearch.ts","../../src/ingestion/sources/npmDownloads.ts","../../src/ingestion/sources/github.ts","../../src/ingestion/sources/depsDev.ts","../../src/ingestion/sources/bundlephobia.ts","../../src/ingestion/sources/index.ts","../../src/ingestion/sources/githubReadme.ts","../../src/ingestion/summarize.ts","../../src/ingestion/collect.ts","../../src/search/categoryInference.ts","../../src/core/paths.ts","../../src/scoring/weights.ts","../../src/scoring/score.ts","../../src/scoring/index.ts","../../src/search/embeddings.ts","../../src/db/packages.ts","../../src/core/concurrency.ts","../../src/pipeline/sync.ts","../../src/pipeline/single.ts","../../src/search/recommend.ts","../../src/mcp/handlers.ts","../../src/mcp/diagram.ts","../../src/mcp/server.ts","../../src/auth/apiKeys.ts","../../src/mcp/http.ts","../../src/pipeline/rescore.ts","../../src/db/discovery.ts","../../src/pipeline/discovery.ts","../../src/pipeline/index.ts","../../src/cli/format.ts","../../src/cli/commands.ts","../../src/cli/installSkill.ts","../../src/cli/install.ts","../../src/cli/keys.ts","../../src/db/seed.ts","../../src/db/migrate.ts","../../src/bin/lurq.ts","../../src/cli/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","/** Static identifiers shared across the CLI and MCP server. */\nexport const SERVER_NAME = 'lurq';\n/** Published npm package name (the CLI command and MCP nickname stay `lurq`).\n * Keep in sync with package.json \"name\". */\nexport const PACKAGE_NAME = 'lurqrun';\n/** Keep in sync with package.json \"version\". */\nexport const VERSION = '0.0.2';\n\n/** Default hosted endpoint the install wizard writes into agent configs. The\n * marketing site is `lurq.run`; the MCP service lives on the `api.` subdomain.\n * Overridable per-invocation with `lurq install --url …` or `LURQ_ENDPOINT`. */\nexport const DEFAULT_ENDPOINT = 'https://api.lurq.run/mcp';\n\n/** Prefix for issued API keys (the rest is high-entropy random). */\nexport const API_KEY_PREFIX = 'lurq_live_';\n\n/** Embedding vector dimensionality (OpenAI text-embedding-3-small). The local\n * fallback embedder produces vectors of the same length so the DB column and\n * pgvector index never need to change. */\nexport const EMBEDDING_DIM = 1536;\n\n/** A package row is flagged `stale: true` in tool responses once its data is\n * older than this (§17). */\nexport const STALENESS_DAYS = 7;\n\nconst HOUR = 60 * 60 * 1000;\nconst DAY = 24 * HOUR;\n\n/** Per-source persistent-cache TTLs (§17). */\nexport const CACHE_TTL = {\n npmRegistry: 6 * HOUR,\n npmDownloads: 12 * HOUR,\n github: 12 * HOUR,\n depsDev: 24 * HOUR,\n bundlephobia: 7 * DAY,\n} as const;\n","/**\n * Shared domain types and the v1 category taxonomy (§8.3).\n * These are the stable contracts the rest of the system builds on.\n */\n\n/** Category taxonomy for the JS/TS web stack (§8.3). `other` is the fallback. */\nexport const CATEGORIES = [\n 'framework',\n 'meta-framework',\n 'state-management',\n 'routing',\n 'orm',\n 'database-client',\n 'ui-component-library',\n 'styling',\n 'forms',\n 'validation',\n 'data-fetching',\n 'http-client',\n 'auth',\n 'testing',\n 'build-tool',\n 'bundler',\n 'linting',\n 'date-time',\n 'animation',\n 'charts',\n 'i18n',\n 'utility',\n 'other',\n] as const;\n\nexport type Category = (typeof CATEGORIES)[number];\n\nexport function isCategory(value: string): value is Category {\n return (CATEGORIES as readonly string[]).includes(value);\n}\n\n/** Provenance of a package's stored category (§2A). `curated` comes from the\n * seed file or a manual arg; `inferred` was assigned automatically at ingest\n * and is safe for a later curation pass to override. */\nexport type CategorySource = 'curated' | 'inferred';\n\n/** How a candidate entered the discovery queue (§2B). `dependency-graph` and\n * `recent` are the long-tail channels; `category-search` is keyword-seeded;\n * `reactive` is an on-demand query that wasn't tracked yet. */\nexport type DiscoverySource = 'dependency-graph' | 'category-search' | 'recent' | 'reactive';\n\n/** Lifecycle of a discovery-queue candidate (§2B). */\nexport type DiscoveryStatus = 'pending' | 'ingested' | 'rejected';\n\n/**\n * Categories for which bundle size is meaningful and Bundlephobia is consulted\n * (§9.5). Backend-only categories get a null bundle size, and their efficiency\n * weight is redistributed (§10, see scoring).\n */\nexport const FRONTEND_CATEGORIES = [\n 'ui-component-library',\n 'styling',\n 'state-management',\n 'forms',\n 'validation',\n 'data-fetching',\n 'charts',\n 'animation',\n 'date-time',\n 'utility',\n] as const;\n\nexport function isFrontendCategory(category: Category | null | undefined): boolean {\n return category != null && (FRONTEND_CATEGORIES as readonly string[]).includes(category);\n}\n\n/**\n * Evidence-trustworthiness label, independent of the numeric score (§10, §1).\n * Two-dimensional: `proven`/`emerging` are adoption ladders; `promising` is\n * adoption-independent (high intrinsic quality, new package).\n */\nexport type Confidence = 'proven' | 'emerging' | 'promising' | 'unproven';\n\nexport type Runtime = 'browser' | 'node' | 'both';\n\nexport type AdvisorySeverity = 'critical' | 'high' | 'moderate' | 'low' | 'info';\n\nexport interface Advisory {\n id: string;\n severity: AdvisorySeverity;\n summary: string;\n}\n\n/** Sub-scores composing the health score (§10). `efficiency` is null when not\n * size-based (backend categories) — its weight is redistributed.\n * `quality` (§1) is a standalone, adoption-independent axis — it does NOT feed\n * the health composite; it blends with health only at ranking time. Null when\n * no manifest signals were available. */\nexport interface ScoreBreakdown {\n maintenance: number;\n adoption: number;\n reliability: number;\n efficiency: number | null;\n quality: number | null;\n}\n\n/**\n * Structured usage guide generated at ingest (product refinement: lurq explains,\n * not just ranks). Grounded in the package README/description — never fabricated.\n * Exact current API specifics are deferred to Context7 via `context7Hint`.\n */\nexport interface UsageGuide {\n whatItIs: string;\n whenToUse: string;\n whenNotToUse?: string;\n whereItFits: string;\n howToWireIn?: string;\n context7Hint?: string;\n}\n\n/** A single recommendation candidate (§12.3.1). Intentionally compact. */\nexport interface Candidate {\n name: string;\n category: Category | null;\n healthScore: number;\n qualityScore: number | null;\n confidence: Confidence;\n why: string;\n latestVersion: string | null;\n weeklyDownloads: number | null;\n lastReleaseAt: string | null;\n repoUrl: string | null;\n}\n\n/** Full evidence read for one package (§12.3.2). */\nexport interface EvaluateOutput {\n dataAsOf: string;\n stale?: boolean;\n name: string;\n category: Category | null;\n healthScore: number;\n qualityScore: number | null;\n confidence: Confidence;\n scoreBreakdown: ScoreBreakdown;\n latestVersion: string | null;\n lastReleaseAt: string | null;\n weeklyDownloads: number | null;\n downloadGrowth90d: number | null;\n dependentsCount: number | null;\n scorecard: number | null;\n bundleMinGzipKb: number | null;\n deprecated: boolean;\n archived: boolean;\n advisories: Advisory[];\n summary: string | null;\n usageGuide: UsageGuide | null;\n repoUrl: string | null;\n}\n\n/** `verify` output (§12.3.4). */\nexport interface VerifyOutput {\n exists: boolean;\n tracked: boolean;\n deprecated: boolean;\n archived: boolean;\n latestVersion: string | null;\n weeklyDownloads: number | null;\n riskFlags: string[];\n confidence: Confidence | null;\n advisoryCount: number;\n}\n","/**\n * Environment configuration (§15). Validated with zod. Most vars are optional\n * so the CLI can run partially (e.g. `lurq --help`) without a full setup;\n * commands that need a specific var call `requireConfig` to fail fast with a\n * clear message.\n */\nimport { config as dotenvConfig } from 'dotenv';\nimport { z } from 'zod';\n\nlet envLoaded = false;\n\n/** Load `.env` into process.env exactly once. Safe to call repeatedly. */\nexport function loadEnv(): void {\n if (envLoaded) return;\n dotenvConfig();\n envLoaded = true;\n}\n\nconst EnvSchema = z.object({\n DATABASE_URL: z.string().min(1).optional(),\n GITHUB_TOKEN: z.string().min(1).optional(),\n\n EMBEDDING_PROVIDER: z.enum(['openai', 'local']).default('openai'),\n EMBEDDING_API_KEY: z.string().min(1).optional(),\n EMBEDDING_MODEL: z.string().min(1).default('text-embedding-3-small'),\n\n SUMMARY_PROVIDER: z.enum(['openai', 'none']).default('openai'),\n SUMMARY_API_KEY: z.string().min(1).optional(),\n SUMMARY_MODEL: z.string().min(1).default('gpt-4o-mini'),\n\n LURQ_SYNC_CONCURRENCY: z.coerce.number().int().positive().max(50).default(5),\n LOG_LEVEL: z.enum(['error', 'warn', 'info', 'debug']).default('info'),\n\n // Hosted HTTP service (`serve-http`). Server-side only.\n PORT: z.coerce.number().int().positive().default(8080),\n /** Per-API-key rate limit: max requests per window. */\n LURQ_RATE_LIMIT_MAX: z.coerce.number().int().positive().default(120),\n /** Coarser per-IP rate limit (blunts unauthenticated floods before auth). */\n LURQ_IP_RATE_LIMIT_MAX: z.coerce.number().int().positive().default(240),\n /** Rate-limit window, milliseconds (applies to both limiters). */\n LURQ_RATE_LIMIT_WINDOW_MS: z.coerce.number().int().positive().default(60_000),\n\n // Client-side (install wizard / CLI talking to a remote endpoint).\n LURQ_ENDPOINT: z.string().url().optional(),\n LURQ_API_KEY: z.string().min(1).optional(),\n});\n\nexport type Config = z.infer<typeof EnvSchema>;\n\nexport class ConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ConfigError';\n }\n}\n\nlet cached: Config | undefined;\n\n/** Parse + validate the environment. Throws ConfigError on malformed values. */\nexport function getConfig(): Config {\n if (cached) return cached;\n loadEnv();\n const parsed = EnvSchema.safeParse(process.env);\n if (!parsed.success) {\n const issues = parsed.error.issues\n .map((i) => ` - ${i.path.join('.')}: ${i.message}`)\n .join('\\n');\n throw new ConfigError(`Invalid environment configuration:\\n${issues}`);\n }\n cached = parsed.data;\n return cached;\n}\n\n/** For tests: clear the memoized config so a fresh getConfig() re-reads\n * process.env. Does not force a `.env` reload (loadEnv stays idempotent). */\nexport function resetConfigCache(): void {\n cached = undefined;\n}\n\n/**\n * Return the config but fail fast if any of the named required keys are absent.\n * Use in command handlers that genuinely need them (e.g. sync needs DATABASE_URL).\n */\nexport function requireConfig<K extends keyof Config>(keys: K[]): Config {\n const config = getConfig();\n const missing = keys.filter((k) => config[k] === undefined || config[k] === '');\n if (missing.length > 0) {\n throw new ConfigError(\n `Missing required environment variable(s): ${missing.join(', ')}.\\n` +\n `See .env.example for setup. Tip: copy it to .env and fill in the values.`,\n );\n }\n return config;\n}\n","/**\n * Drizzle schema (§8). One denormalized `packages` table feeds all reads (§8.2),\n * plus `sync_runs` (ingestion audit) and `seed_packages` (curated bootstrap list).\n *\n * The `vector` extension must exist before these migrations apply — `db migrate`\n * runs `CREATE EXTENSION IF NOT EXISTS vector` first (pgvector is not created\n * automatically by Drizzle).\n */\nimport { sql } from 'drizzle-orm';\nimport {\n bigint,\n boolean,\n customType,\n index,\n integer,\n jsonb,\n pgTable,\n real,\n serial,\n text,\n timestamp,\n vector,\n} from 'drizzle-orm/pg-core';\nimport { EMBEDDING_DIM } from '../core/constants';\n\n/** Postgres full-text `tsvector` type for hybrid lexical search (§3). */\nconst tsvector = customType<{ data: string; driverData: string }>({\n dataType() {\n return 'tsvector';\n },\n});\nimport type {\n Advisory,\n Category,\n CategorySource,\n Confidence,\n DiscoverySource,\n DiscoveryStatus,\n ScoreBreakdown,\n UsageGuide,\n} from '../core/types';\n\nconst ts = (name: string) => timestamp(name, { withTimezone: true, mode: 'date' });\n\n/** One row per tracked npm package. */\nexport const packages = pgTable(\n 'packages',\n {\n id: serial('id').primaryKey(),\n name: text('name').notNull().unique(),\n ecosystem: text('ecosystem').notNull().default('npm'),\n\n // Classification + descriptive text\n category: text('category').$type<Category>(),\n /** Whether `category` was hand-curated or inferred at ingest (§2A). */\n categorySource: text('category_source').$type<CategorySource>(),\n description: text('description'),\n summary: text('summary'),\n repoUrl: text('repo_url'),\n homepage: text('homepage'),\n latestVersion: text('latest_version'),\n license: text('license'),\n\n // Lifecycle flags\n deprecated: boolean('deprecated').notNull().default(false),\n archived: boolean('archived').notNull().default(false),\n\n // Age / maintenance signals\n firstPublishedAt: ts('first_published_at'),\n lastReleaseAt: ts('last_release_at'),\n\n // Adoption signals\n weeklyDownloads: bigint('weekly_downloads', { mode: 'number' }),\n downloadGrowth90d: real('download_growth_90d'),\n dependentsCount: integer('dependents_count'),\n stars: integer('stars'),\n openIssues: integer('open_issues'),\n closedIssues: integer('closed_issues'),\n\n // Reliability / efficiency signals\n scorecard: real('scorecard'),\n bundleMinGzipKb: real('bundle_min_gzip_kb'),\n advisories: jsonb('advisories').$type<Advisory[]>(),\n\n // Computed outputs\n healthScore: integer('health_score'),\n /** Intrinsic-quality axis (§1), adoption-independent. Blends with health at\n * ranking time (composite); never folded into health_score itself. */\n qualityScore: integer('quality_score'),\n confidence: text('confidence').$type<Confidence>(),\n scoreBreakdown: jsonb('score_breakdown').$type<ScoreBreakdown>(),\n usageGuide: jsonb('usage_guide').$type<UsageGuide>(),\n embedding: vector('embedding', { dimensions: EMBEDDING_DIM }),\n\n // Lexical search vector (§3): name weighted highest (A), then category (B),\n // then summary/description (C). Generated + STORED so it stays in sync with\n // the row automatically; indexed with GIN for fast `@@` matching.\n searchVector: tsvector('search_vector').generatedAlwaysAs(\n sql`setweight(to_tsvector('english', coalesce(name, '')), 'A') || setweight(to_tsvector('english', coalesce(category, '')), 'B') || setweight(to_tsvector('english', coalesce(summary, description, '')), 'C')`,\n ),\n\n // Freshness + bookkeeping\n dataAsOf: timestamp('data_as_of', { withTimezone: true, mode: 'date' }),\n createdAt: ts('created_at').notNull().defaultNow(),\n updatedAt: ts('updated_at').notNull().defaultNow(),\n },\n (table) => [\n index('packages_category_idx').on(table.category),\n index('packages_health_score_idx').on(table.healthScore),\n // pgvector HNSW index for cosine similarity search (§11).\n index('packages_embedding_idx').using('hnsw', table.embedding.op('vector_cosine_ops')),\n // GIN index for lexical full-text search (§3).\n index('packages_search_vector_idx').using('gin', table.searchVector),\n ],\n);\n\n/** Ingestion audit trail (§8.1). */\nexport const syncRuns = pgTable('sync_runs', {\n id: serial('id').primaryKey(),\n startedAt: ts('started_at').notNull().defaultNow(),\n finishedAt: ts('finished_at'),\n packagesSeen: integer('packages_seen').notNull().default(0),\n packagesUpdated: integer('packages_updated').notNull().default(0),\n errors: jsonb('errors').$type<SyncError[]>().notNull().default([]),\n status: text('status').$type<SyncStatus>().notNull().default('running'),\n});\n\n/** Curated v1 seed list (§16), loaded from seed.json. */\nexport const seedPackages = pgTable('seed_packages', {\n name: text('name').primaryKey(),\n category: text('category').$type<Category>(),\n addedAt: ts('added_at').notNull().defaultNow(),\n});\n\n/**\n * Proactive-discovery candidate queue (§2B). Operator-side: the crawler enqueues\n * adjacency-graph / category-search / recent candidates here, a merit gate\n * pre-scores them on quality signals only (downloads excluded), and survivors\n * graduate to full ingestion. Keeps cost bounded and the DB free of toy packages.\n */\nexport const discoveryQueue = pgTable(\n 'discovery_queue',\n {\n id: serial('id').primaryKey(),\n name: text('name').notNull().unique(),\n discoveredVia: text('discovered_via').$type<DiscoverySource>().notNull(),\n /** Lightweight quality-only pre-score (§2B). Null until the gate runs. */\n preScore: integer('pre_score'),\n status: text('status').$type<DiscoveryStatus>().notNull().default('pending'),\n discoveredAt: ts('discovered_at').notNull().defaultNow(),\n },\n (table) => [index('discovery_queue_status_idx').on(table.status)],\n);\n\n/**\n * API keys for the hosted HTTP service (docs/lurq-hosted-deployment.md §5). Each\n * user/org gets a key; only its sha256 hash is persisted, so a DB leak never\n * exposes a usable key — the plaintext is shown exactly once at creation.\n * `ownerId` is reserved for future self-serve issuance via the Clerk dashboard.\n */\nexport const apiKeys = pgTable(\n 'api_keys',\n {\n id: serial('id').primaryKey(),\n /** sha256 hex of the full key — the only form persisted. */\n keyHash: text('key_hash').notNull().unique(),\n /** Identifiable display prefix, e.g. `lurq_live_ab12cd` (safe to show/log). */\n prefix: text('prefix').notNull(),\n /** Free-text label (owner / org / purpose). */\n label: text('label'),\n /** Reserved for self-serve issuance: maps to a Clerk user id. */\n ownerId: text('owner_id'),\n tier: text('tier').notNull().default('free'),\n createdAt: ts('created_at').notNull().defaultNow(),\n lastUsedAt: ts('last_used_at'),\n revokedAt: ts('revoked_at'),\n },\n (table) => [index('api_keys_owner_idx').on(table.ownerId)],\n);\n\nexport type SyncStatus = 'running' | 'success' | 'partial' | 'failed';\n\nexport interface SyncError {\n package: string;\n source: string;\n message: string;\n}\n\nexport type PackageRow = typeof packages.$inferSelect;\nexport type NewPackageRow = typeof packages.$inferInsert;\nexport type SeedPackageRow = typeof seedPackages.$inferSelect;\nexport type SyncRunRow = typeof syncRuns.$inferSelect;\nexport type DiscoveryQueueRow = typeof discoveryQueue.$inferSelect;\nexport type ApiKeyRow = typeof apiKeys.$inferSelect;\nexport type NewApiKeyRow = typeof apiKeys.$inferInsert;\n","/**\n * Database client factory. Uses postgres.js + Drizzle. Callers own the lifecycle:\n * create, use, then `await close()` (CLI commands are short-lived processes).\n */\nimport { drizzle, type PostgresJsDatabase } from 'drizzle-orm/postgres-js';\nimport postgres from 'postgres';\nimport { requireConfig } from '../core/config';\nimport * as schema from './schema';\n\nexport type Database = PostgresJsDatabase<typeof schema>;\n\nexport interface DbHandle {\n db: Database;\n /** Underlying postgres.js client, for raw SQL (e.g. CREATE EXTENSION). */\n sql: postgres.Sql;\n /** Close the connection pool. Always call when done. */\n close: () => Promise<void>;\n}\n\nexport function createDb(opts: { max?: number } = {}): DbHandle {\n const { DATABASE_URL } = requireConfig(['DATABASE_URL']);\n const sql = postgres(DATABASE_URL!, { max: opts.max ?? 10, onnotice: () => {} });\n const db = drizzle(sql, { schema });\n return { db, sql, close: () => sql.end() };\n}\n\nexport { schema };\n","/**\n * Minimal leveled logger.\n *\n * IMPORTANT: all output goes to **stderr**. The MCP server communicates over\n * stdio (stdout is the protocol channel), so anything written to stdout would\n * corrupt the JSON-RPC stream. Never log to stdout.\n */\n\nconst LEVELS = { error: 0, warn: 1, info: 2, debug: 3 } as const;\nexport type LogLevel = keyof typeof LEVELS;\n\nfunction currentLevel(): number {\n const raw = process.env.LOG_LEVEL as LogLevel | undefined;\n return raw && raw in LEVELS ? LEVELS[raw] : LEVELS.info;\n}\n\nfunction emit(level: LogLevel, args: unknown[]): void {\n if (LEVELS[level] > currentLevel()) return;\n const parts = args.map((a) =>\n typeof a === 'string' ? a : a instanceof Error ? (a.stack ?? a.message) : safeStringify(a),\n );\n process.stderr.write(`[lurq] ${level.toUpperCase()} ${parts.join(' ')}\\n`);\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nexport const logger = {\n error: (...args: unknown[]) => emit('error', args),\n warn: (...args: unknown[]) => emit('warn', args),\n info: (...args: unknown[]) => emit('info', args),\n debug: (...args: unknown[]) => emit('debug', args),\n};\n","/**\n * Shared HTTP layer (§17). One wrapper for every external call:\n * - per-host rate limiting (max concurrency + minimum gap between starts),\n * - exponential backoff on 429 / 5xx (respecting Retry-After),\n * - in-run (memory) cache + persistent on-disk cache with per-source TTLs.\n *\n * Source clients pass a `ttlMs` (the per-source TTL from §17) and a `host`\n * bucket. `ttlMs: 0` disables caching (used for liveness checks like `verify`).\n */\nimport { createHash } from 'node:crypto';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { logger } from './logger';\n\nexport class HttpError extends Error {\n constructor(\n message: string,\n readonly status: number,\n readonly url: string,\n ) {\n super(message);\n this.name = 'HttpError';\n }\n}\n\nexport interface HttpOptions {\n /** Rate-limit bucket key, usually the hostname. */\n host: string;\n /** Persistent cache TTL in ms. 0 disables read+write caching. */\n ttlMs: number;\n method?: 'GET' | 'POST';\n headers?: Record<string, string>;\n body?: string;\n accept?: 'json' | 'text';\n timeoutMs?: number;\n retries?: number;\n /** Override the cache key (e.g. to keep auth tokens out of the key). */\n cacheKey?: string;\n /** Injected for tests. Defaults to global fetch. */\n fetchImpl?: typeof fetch;\n}\n\nexport interface HttpResponse<T> {\n status: number;\n data: T;\n fromCache: boolean;\n}\n\n// ── Per-host rate limiting ──────────────────────────────────────────────────\n\ninterface HostConfig {\n maxConcurrent: number;\n minIntervalMs: number;\n}\n\nconst DEFAULT_HOST_CONFIG: HostConfig = { maxConcurrent: 6, minIntervalMs: 0 };\n\nconst HOST_CONFIG: Record<string, HostConfig> = {\n 'api.github.com': { maxConcurrent: 4, minIntervalMs: 50 },\n 'registry.npmjs.org': { maxConcurrent: 4, minIntervalMs: 50 },\n // The downloads API rate-limits aggressively — serialize with a steady gap.\n // Weekly downloads go through the bulk endpoint; only growth hits this often.\n 'api.npmjs.org': { maxConcurrent: 1, minIntervalMs: 250 },\n 'api.deps.dev': { maxConcurrent: 4, minIntervalMs: 40 },\n 'raw.githubusercontent.com': { maxConcurrent: 4, minIntervalMs: 30 },\n // Bundlephobia is slow/flaky — be gentle (§9.5).\n 'bundlephobia.com': { maxConcurrent: 2, minIntervalMs: 200 },\n};\n\nclass HostLimiter {\n private active = 0;\n private nextAvailable = 0;\n private queue: Array<() => void> = [];\n\n constructor(private readonly config: HostConfig) {}\n\n async acquire(): Promise<void> {\n if (this.active >= this.config.maxConcurrent) {\n await new Promise<void>((resolve) => this.queue.push(resolve));\n }\n this.active++;\n const now = Date.now();\n const wait = Math.max(0, this.nextAvailable - now);\n this.nextAvailable = Math.max(now, this.nextAvailable) + this.config.minIntervalMs;\n if (wait > 0) await delay(wait);\n }\n\n release(): void {\n this.active--;\n const next = this.queue.shift();\n if (next) next();\n }\n}\n\nconst limiters = new Map<string, HostLimiter>();\n\nfunction limiterFor(host: string): HostLimiter {\n let limiter = limiters.get(host);\n if (!limiter) {\n limiter = new HostLimiter(HOST_CONFIG[host] ?? DEFAULT_HOST_CONFIG);\n limiters.set(host, limiter);\n }\n return limiter;\n}\n\n// ── Caching ─────────────────────────────────────────────────────────────────\n\ninterface CacheEntry {\n fetchedAt: number;\n status: number;\n body: string;\n}\n\nconst memoryCache = new Map<string, CacheEntry>();\n\n/** When true, cache reads are skipped (writes still happen). Used by `sync --full`. */\nlet bypassCacheRead = false;\n\n/** Force fresh fetches (ignore cache TTLs) while still refreshing the cache. */\nexport function setCacheBypassRead(value: boolean): void {\n bypassCacheRead = value;\n}\n\nfunction cacheDir(): string {\n return process.env.LURQ_CACHE_DIR ?? join(homedir(), '.cache', 'lurq', 'http');\n}\n\nfunction cacheFile(key: string): string {\n const hash = createHash('sha256').update(key).digest('hex');\n return join(cacheDir(), `${hash}.json`);\n}\n\nasync function readCache(key: string, ttlMs: number): Promise<CacheEntry | undefined> {\n const now = Date.now();\n const mem = memoryCache.get(key);\n if (mem && now - mem.fetchedAt < ttlMs) return mem;\n\n const file = cacheFile(key);\n if (!existsSync(file)) return undefined;\n try {\n const entry = JSON.parse(await readFile(file, 'utf8')) as CacheEntry;\n if (now - entry.fetchedAt < ttlMs) {\n memoryCache.set(key, entry);\n return entry;\n }\n } catch {\n /* corrupt cache file — ignore and refetch */\n }\n return undefined;\n}\n\nasync function writeCache(key: string, entry: CacheEntry): Promise<void> {\n memoryCache.set(key, entry);\n const file = cacheFile(key);\n try {\n await mkdir(dirname(file), { recursive: true });\n await writeFile(file, JSON.stringify(entry), 'utf8');\n } catch (err) {\n logger.debug(`http cache write failed: ${(err as Error).message}`);\n }\n}\n\n// ── Core request ────────────────────────────────────────────────────────────\n\nconst RETRYABLE = new Set([429, 500, 502, 503, 504]);\n\nexport async function httpRequest<T = unknown>(\n url: string,\n opts: HttpOptions,\n): Promise<HttpResponse<T>> {\n const {\n host,\n ttlMs,\n method = 'GET',\n headers = {},\n body,\n accept = 'json',\n timeoutMs = 15_000,\n retries = 3,\n fetchImpl = fetch,\n } = opts;\n const key = opts.cacheKey ?? `${method} ${url} ${body ?? ''}`;\n\n if (ttlMs > 0 && !bypassCacheRead) {\n const cached = await readCache(key, ttlMs);\n if (cached) {\n return { status: cached.status, data: decode<T>(cached.body, accept), fromCache: true };\n }\n }\n\n const limiter = limiterFor(host);\n let lastErr: unknown;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n await limiter.acquire();\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetchImpl(url, { method, headers, body, signal: controller.signal });\n const text = await res.text();\n\n if (res.ok) {\n if (ttlMs > 0) await writeCache(key, { fetchedAt: Date.now(), status: res.status, body: text });\n return { status: res.status, data: decode<T>(text, accept), fromCache: false };\n }\n\n // Non-2xx\n if (RETRYABLE.has(res.status) && attempt < retries) {\n const retryAfter = parseRetryAfter(res.headers.get('retry-after'));\n await delay(retryAfter ?? backoff(attempt));\n lastErr = new HttpError(`HTTP ${res.status} for ${url}`, res.status, url);\n continue;\n }\n throw new HttpError(`HTTP ${res.status} for ${url}`, res.status, url);\n } catch (err) {\n lastErr = err;\n const isAbort = err instanceof Error && err.name === 'AbortError';\n const isHttp = err instanceof HttpError;\n // Retry network/timeout errors; don't retry non-retryable HTTP statuses.\n if (isHttp && !RETRYABLE.has(err.status)) throw err;\n if (attempt < retries) {\n await delay(backoff(attempt));\n continue;\n }\n if (isAbort) throw new HttpError(`Timeout after ${timeoutMs}ms for ${url}`, 0, url);\n } finally {\n clearTimeout(timer);\n limiter.release();\n }\n }\n throw lastErr instanceof Error ? lastErr : new HttpError(`Request failed for ${url}`, 0, url);\n}\n\nexport async function httpGetJson<T = unknown>(\n url: string,\n opts: Omit<HttpOptions, 'accept' | 'method'>,\n): Promise<HttpResponse<T>> {\n return httpRequest<T>(url, { ...opts, method: 'GET', accept: 'json' });\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction decode<T>(text: string, accept: 'json' | 'text'): T {\n if (accept === 'text') return text as unknown as T;\n return (text ? JSON.parse(text) : null) as T;\n}\n\nfunction backoff(attempt: number): number {\n const base = 500 * 2 ** attempt;\n return base + Math.floor(((attempt * 137) % 100) * 3); // small deterministic jitter\n}\n\nfunction parseRetryAfter(value: string | null): number | undefined {\n if (!value) return undefined;\n const seconds = Number(value);\n if (!Number.isNaN(seconds)) return seconds * 1000;\n const date = Date.parse(value);\n return Number.isNaN(date) ? undefined : Math.max(0, date - Date.now());\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** Test helper: clear the in-memory cache and per-host limiters. */\nexport function __resetHttpStateForTests(): void {\n memoryCache.clear();\n limiters.clear();\n}\n","/**\n * npm registry client (§9.1). Base metadata: version, description, license,\n * repository, publish times, deprecation, maintainers, README.\n */\nimport { CACHE_TTL } from '../../core/constants';\nimport { httpGetJson } from '../../core/http';\nimport type { NpmRegistryData } from '../types';\n\nconst HOST = 'registry.npmjs.org';\n\n/** Encode a package name for a registry URL (scoped names need `/` → `%2F`). */\nexport function encodeNpmName(name: string): string {\n return name.startsWith('@') ? name.replace('/', '%2F') : name;\n}\n\n/** Extract `{ owner, repo }` from any GitHub repository URL form. */\nexport function parseGithubRepo(\n url: string | null | undefined,\n): { owner: string; repo: string } | null {\n if (!url) return null;\n const match = url.match(/github\\.com[/:]([^/]+)\\/([^/#?]+?)(?:\\.git)?(?:[/#?].*)?$/i);\n if (!match) return null;\n const owner = match[1];\n const repo = match[2];\n if (!owner || !repo) return null;\n return { owner, repo };\n}\n\nfunction normalizeRepoUrl(\n repository: unknown,\n homepage: string | null,\n): { repoUrl: string | null; repo: { owner: string; repo: string } | null } {\n let raw: string | null = null;\n if (typeof repository === 'string') raw = repository;\n else if (repository && typeof repository === 'object' && 'url' in repository) {\n raw = String((repository as { url: unknown }).url);\n }\n const repo = parseGithubRepo(raw) ?? parseGithubRepo(homepage);\n const repoUrl = repo ? `https://github.com/${repo.owner}/${repo.repo}` : (cleanUrl(raw) ?? null);\n return { repoUrl, repo };\n}\n\nfunction cleanUrl(url: string | null): string | null {\n if (!url) return null;\n return url\n .replace(/^git\\+/, '')\n .replace(/^git:\\/\\//, 'https://')\n .replace(/\\.git$/, '');\n}\n\nfunction pickLicense(value: unknown): string | null {\n if (!value) return null;\n if (typeof value === 'string') return value;\n if (typeof value === 'object' && 'type' in value) return String((value as { type: unknown }).type);\n return null;\n}\n\nfunction toDate(value: unknown): Date | null {\n if (typeof value !== 'string') return null;\n const ms = Date.parse(value);\n return Number.isNaN(ms) ? null : new Date(ms);\n}\n\nexport function parseNpmRegistry(json: any): NpmRegistryData {\n const latest: string | null = json?.['dist-tags']?.latest ?? null;\n const latestManifest = latest ? (json?.versions?.[latest] ?? {}) : {};\n const time = json?.time ?? {};\n\n const repository = json?.repository ?? latestManifest?.repository;\n const homepage = json?.homepage ?? latestManifest?.homepage ?? null;\n const { repoUrl, repo } = normalizeRepoUrl(repository, homepage);\n\n const deprecated = Boolean(latestManifest?.deprecated ?? json?.deprecated);\n const maintainers = Array.isArray(json?.maintainers) ? json.maintainers.length : null;\n const name: string = json?.name ?? '';\n\n return {\n name,\n description: json?.description ?? latestManifest?.description ?? null,\n latestVersion: latest,\n license: pickLicense(json?.license ?? latestManifest?.license),\n homepage,\n repo,\n repoUrl,\n firstPublishedAt: toDate(time?.created),\n lastReleaseAt: toDate(latest ? time?.[latest] : null) ?? toDate(time?.modified),\n deprecated,\n maintainersCount: maintainers,\n readme: typeof json?.readme === 'string' ? json.readme : null,\n keywords: parseKeywords(json?.keywords ?? latestManifest?.keywords),\n hasTypes: detectTypes(name, latestManifest),\n hasTestScript: detectTestScript(latestManifest),\n directDependenciesCount: countDeps(latestManifest?.dependencies),\n hasProvenance: detectProvenance(latestManifest),\n };\n}\n\nfunction parseKeywords(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((k): k is string => typeof k === 'string');\n}\n\n/** Ships types if the manifest declares `types`/`typings`, or it IS an @types pkg. */\nfunction detectTypes(name: string, manifest: any): boolean {\n if (typeof manifest?.types === 'string' || typeof manifest?.typings === 'string') return true;\n if (name.startsWith('@types/')) return true;\n // `exports` map with a `types` condition (modern dual-package layout).\n const exportsField = manifest?.exports;\n if (exportsField && typeof exportsField === 'object') {\n const serialized = JSON.stringify(exportsField);\n if (serialized.includes('\"types\"')) return true;\n }\n return false;\n}\n\n/** A real test script — npm's `init` leaves a placeholder we must not count. */\nfunction detectTestScript(manifest: any): boolean {\n const test = manifest?.scripts?.test;\n if (typeof test !== 'string' || test.trim() === '') return false;\n return !/no test specified/i.test(test);\n}\n\nfunction countDeps(deps: unknown): number | null {\n if (!deps || typeof deps !== 'object') return 0;\n return Object.keys(deps as Record<string, unknown>).length;\n}\n\n/** npm provenance leaves a signed attestation on the published dist. */\nfunction detectProvenance(manifest: any): boolean {\n return Boolean(manifest?.dist?.attestations);\n}\n\nexport async function fetchNpmRegistry(\n name: string,\n fetchImpl?: typeof fetch,\n): Promise<NpmRegistryData> {\n const url = `https://${HOST}/${encodeNpmName(name)}`;\n const { data } = await httpGetJson<any>(url, {\n host: HOST,\n ttlMs: CACHE_TTL.npmRegistry,\n fetchImpl,\n });\n return parseNpmRegistry(data);\n}\n\n/** Live existence check for `verify` (§12.3.4) — bypasses cache. */\nexport async function npmPackageExists(name: string, fetchImpl?: typeof fetch): Promise<boolean> {\n const url = `https://${HOST}/${encodeNpmName(name)}`;\n try {\n const { status } = await httpGetJson<any>(url, {\n host: HOST,\n ttlMs: 0,\n retries: 1,\n fetchImpl,\n });\n return status === 200;\n } catch (err) {\n if (err && typeof err === 'object' && 'status' in err && (err as any).status === 404) {\n return false;\n }\n throw err;\n }\n}\n","/**\n * npm registry search client (§2B). Seeds the discovery crawler's long-tail\n * channels: keyword/category search and a recently-published sweep. This is the\n * niche workhorse — the dependency graph structurally can't find niche\n * *alternatives* (a new package shares no edge with the incumbent it competes\n * with), so that job lives here.\n */\nimport { CACHE_TTL } from '../../core/constants';\nimport { httpGetJson } from '../../core/http';\n\nconst HOST = 'registry.npmjs.org';\n\nexport interface NpmSearchHit {\n name: string;\n /** ISO publish date of the matched version, if reported. */\n date: string | null;\n}\n\n/**\n * Run an npm registry search. `query` uses npm's search qualifier syntax, e.g.\n * `keywords:orm` or `orm typescript`. Returns name + publish date per hit.\n * Best-effort: returns [] on any failure.\n */\nexport async function searchNpm(\n query: string,\n size = 20,\n fetchImpl?: typeof fetch,\n): Promise<NpmSearchHit[]> {\n const url = `https://${HOST}/-/v1/search?text=${encodeURIComponent(query)}&size=${size}`;\n try {\n const { data } = await httpGetJson<any>(url, {\n host: HOST,\n ttlMs: CACHE_TTL.npmRegistry,\n fetchImpl,\n });\n const objects: any[] = Array.isArray(data?.objects) ? data.objects : [];\n return objects\n .map((o) => ({ name: o?.package?.name, date: o?.package?.date ?? null }))\n .filter((h): h is NpmSearchHit => typeof h.name === 'string');\n } catch {\n return [];\n }\n}\n","/**\n * npm downloads client (§9.2). Weekly downloads + 90-day growth.\n *\n * Weekly downloads is fetched in BULK at the pipeline level — npm's point API\n * accepts up to 128 comma-separated packages per call, which avoids the harsh\n * rate-limiting that per-package bursts trigger. The range (growth) API has no\n * bulk form, so growth is a per-package best-effort secondary signal.\n *\n * Bulk does not support scoped (@scope/name) packages; those are fetched singly.\n */\nimport { CACHE_TTL } from '../../core/constants';\nimport { httpGetJson, HttpError } from '../../core/http';\nimport type { NpmDownloadsData } from '../types';\n\nconst HOST = 'api.npmjs.org';\nconst BULK_CHUNK = 128;\n\nexport function parseWeeklyDownloads(json: any): number | null {\n const value = json?.downloads;\n return typeof value === 'number' ? value : null;\n}\n\ninterface RangePoint {\n day: string;\n downloads: number;\n}\n\n/** Compute the 90d growth fraction from a daily-downloads range. */\nexport function parseDownloadGrowth(json: any): number | null {\n const points: RangePoint[] = Array.isArray(json?.downloads) ? json.downloads : [];\n if (points.length < 60) return null;\n const tail = points.slice(-60);\n const prior = tail.slice(0, 30);\n const recent = tail.slice(30);\n const sum = (arr: RangePoint[]) => arr.reduce((acc, p) => acc + (p.downloads || 0), 0);\n const priorAvg = sum(prior) / prior.length;\n const recentAvg = sum(recent) / recent.length;\n if (priorAvg <= 0) return recentAvg > 0 ? 1 : 0;\n return (recentAvg - priorAvg) / priorAvg;\n}\n\n/** Format a Date as YYYY-MM-DD (UTC) for the npm range API. */\nfunction ymd(date: Date): string {\n return date.toISOString().slice(0, 10);\n}\n\n/** Build a `start:end` range string covering the last 90 days. */\nexport function last90DayRange(now: Date = new Date()): string {\n const end = now;\n const start = new Date(end.getTime() - 90 * 24 * 60 * 60 * 1000);\n return `${ymd(start)}:${ymd(end)}`;\n}\n\n/** Parse a bulk point response into a name→downloads map (handles single + multi forms). */\nexport function parseBulkWeekly(json: any, requested: string[]): Map<string, number | null> {\n const map = new Map<string, number | null>();\n // A single-package request returns the object directly, not keyed by name.\n if (json && typeof json.downloads === 'number' && typeof json.package === 'string') {\n map.set(json.package, json.downloads);\n return map;\n }\n for (const name of requested) {\n const entry = json?.[name];\n map.set(name, entry && typeof entry.downloads === 'number' ? entry.downloads : null);\n }\n return map;\n}\n\nfunction chunk<T>(items: T[], size: number): T[][] {\n const out: T[][] = [];\n for (let i = 0; i < items.length; i += size) out.push(items.slice(i, i + size));\n return out;\n}\n\n/** Single-package weekly downloads. 404 → null (no per-package data). */\nexport async function fetchWeeklyDownloads(\n name: string,\n fetchImpl?: typeof fetch,\n): Promise<number | null> {\n try {\n const { data } = await httpGetJson<any>(\n `https://${HOST}/downloads/point/last-week/${name}`,\n { host: HOST, ttlMs: CACHE_TTL.npmDownloads, retries: 5, fetchImpl },\n );\n return parseWeeklyDownloads(data);\n } catch (err) {\n if (err instanceof HttpError && err.status === 404) return null;\n throw err;\n }\n}\n\n/** Per-package 90d growth (best-effort secondary signal). */\nexport async function fetchDownloadGrowth(\n name: string,\n fetchImpl?: typeof fetch,\n): Promise<number | null> {\n try {\n const { data } = await httpGetJson<any>(\n `https://${HOST}/downloads/range/${last90DayRange()}/${name}`,\n { host: HOST, ttlMs: CACHE_TTL.npmDownloads, retries: 3, fetchImpl },\n );\n return parseDownloadGrowth(data);\n } catch {\n return null;\n }\n}\n\n/**\n * Bulk-fetch weekly downloads for many packages. Unscoped packages go through\n * the 128-at-a-time bulk endpoint; scoped packages are fetched individually.\n */\nexport async function fetchBulkWeeklyDownloads(\n names: string[],\n fetchImpl?: typeof fetch,\n): Promise<Map<string, number | null>> {\n const result = new Map<string, number | null>();\n const unscoped = names.filter((n) => !n.startsWith('@'));\n const scoped = names.filter((n) => n.startsWith('@'));\n\n for (const batch of chunk(unscoped, BULK_CHUNK)) {\n try {\n const { data } = await httpGetJson<any>(\n `https://${HOST}/downloads/point/last-week/${batch.join(',')}`,\n { host: HOST, ttlMs: CACHE_TTL.npmDownloads, retries: 5, fetchImpl },\n );\n for (const [k, v] of parseBulkWeekly(data, batch)) result.set(k, v);\n } catch {\n // Leave this batch absent; per-package fallback will retry it.\n }\n }\n\n for (const name of scoped) {\n try {\n result.set(name, await fetchWeeklyDownloads(name, fetchImpl));\n } catch {\n /* leave absent → per-package fallback */\n }\n }\n\n return result;\n}\n\n/** Combined per-package fetch (used when no bulk pre-fetch is available). */\nexport async function fetchNpmDownloads(\n name: string,\n fetchImpl?: typeof fetch,\n): Promise<NpmDownloadsData> {\n const weeklyDownloads = await fetchWeeklyDownloads(name, fetchImpl);\n const downloadGrowth90d = await fetchDownloadGrowth(name, fetchImpl);\n return { weeklyDownloads, downloadGrowth90d };\n}\n","/**\n * GitHub client (§9.3). One GraphQL call per repo fetches stars, issue counts,\n * archived flag, and recent releases (latest date + 12-month cadence).\n * Requires GITHUB_TOKEN; without it, the pipeline skips this source.\n */\nimport { CACHE_TTL } from '../../core/constants';\nimport { httpRequest } from '../../core/http';\nimport type { GithubRepoData } from '../types';\n\nconst HOST = 'api.github.com';\nconst ENDPOINT = `https://${HOST}/graphql`;\n\nconst QUERY = `query($owner:String!, $name:String!) {\n repository(owner:$owner, name:$name) {\n stargazerCount\n isArchived\n openIssues: issues(states:OPEN) { totalCount }\n closedIssues: issues(states:CLOSED) { totalCount }\n releases(first: 50, orderBy: {field: CREATED_AT, direction: DESC}) {\n nodes { createdAt }\n }\n }\n}`;\n\nconst ONE_YEAR_MS = 365 * 24 * 60 * 60 * 1000;\n\nexport function parseGithub(json: any, now: Date = new Date()): GithubRepoData | null {\n const repo = json?.data?.repository;\n if (!repo) return null;\n\n const releaseNodes: { createdAt: string }[] = repo.releases?.nodes ?? [];\n const releaseDates = releaseNodes\n .map((n) => Date.parse(n.createdAt))\n .filter((ms) => !Number.isNaN(ms));\n const cutoff = now.getTime() - ONE_YEAR_MS;\n\n return {\n stars: typeof repo.stargazerCount === 'number' ? repo.stargazerCount : null,\n openIssues: repo.openIssues?.totalCount ?? null,\n closedIssues: repo.closedIssues?.totalCount ?? null,\n archived: Boolean(repo.isArchived),\n lastReleaseAt: releaseDates.length ? new Date(Math.max(...releaseDates)) : null,\n releasesLast12mo: releaseDates.filter((ms) => ms >= cutoff).length,\n };\n}\n\nexport async function fetchGithubRepo(\n owner: string,\n repo: string,\n token: string,\n fetchImpl?: typeof fetch,\n): Promise<GithubRepoData | null> {\n const body = JSON.stringify({ query: QUERY, variables: { owner, name: repo } });\n const { data } = await httpRequest<any>(ENDPOINT, {\n host: HOST,\n ttlMs: CACHE_TTL.github,\n method: 'POST',\n headers: {\n Authorization: `bearer ${token}`,\n 'Content-Type': 'application/json',\n 'User-Agent': 'lurq',\n },\n body,\n // Keep the auth token out of the cache key.\n cacheKey: `POST ${ENDPOINT} ${owner}/${repo}`,\n fetchImpl,\n });\n return parseGithub(data);\n}\n","/**\n * deps.dev client (§9.4). Primary source for OpenSSF Scorecard and security\n * advisories.\n * - Scorecard comes from the project endpoint (keyed by github.com/owner/repo).\n * - Advisories: the version endpoint lists advisoryKeys; we fetch each (capped)\n * and derive a severity bucket from its CVSS score.\n */\nimport { CACHE_TTL } from '../../core/constants';\nimport { httpGetJson, type HttpResponse } from '../../core/http';\nimport type { Advisory, AdvisorySeverity } from '../../core/types';\nimport type { DepsDevData } from '../types';\n\nconst HOST = 'api.deps.dev';\nconst MAX_ADVISORIES = 10;\n\nfunction encodeName(name: string): string {\n return encodeURIComponent(name);\n}\n\nexport function severityFromCvss(score: number | null | undefined): AdvisorySeverity {\n if (score == null) return 'moderate';\n if (score >= 9) return 'critical';\n if (score >= 7) return 'high';\n if (score >= 4) return 'moderate';\n if (score > 0) return 'low';\n return 'info';\n}\n\nexport function parseScorecard(json: any): number | null {\n const score = json?.scorecard?.overallScore;\n return typeof score === 'number' ? score : null;\n}\n\nexport function parseAdvisoryKeys(versionJson: any): string[] {\n const keys = versionJson?.advisoryKeys;\n if (!Array.isArray(keys)) return [];\n return keys\n .map((k: any) => (typeof k === 'string' ? k : k?.id))\n .filter((id: unknown): id is string => typeof id === 'string');\n}\n\nexport function parseAdvisoryDetail(json: any): Advisory {\n return {\n id: json?.advisoryKey?.id ?? json?.advisoryKey ?? 'unknown',\n severity: severityFromCvss(json?.cvss3Score),\n summary: json?.title ?? '',\n };\n}\n\nexport async function fetchScorecard(\n owner: string,\n repo: string,\n fetchImpl?: typeof fetch,\n): Promise<number | null> {\n const projectKey = encodeURIComponent(`github.com/${owner}/${repo}`);\n const url = `https://${HOST}/v3/projects/${projectKey}`;\n try {\n const { data } = await httpGetJson<any>(url, {\n host: HOST,\n ttlMs: CACHE_TTL.depsDev,\n fetchImpl,\n });\n return parseScorecard(data);\n } catch {\n return null;\n }\n}\n\nexport async function fetchAdvisories(\n name: string,\n version: string,\n fetchImpl?: typeof fetch,\n): Promise<Advisory[]> {\n const versionUrl = `https://${HOST}/v3/systems/npm/packages/${encodeName(name)}/versions/${encodeURIComponent(version)}`;\n let keys: string[] = [];\n try {\n const { data } = await httpGetJson<any>(versionUrl, {\n host: HOST,\n ttlMs: CACHE_TTL.depsDev,\n fetchImpl,\n });\n keys = parseAdvisoryKeys(data).slice(0, MAX_ADVISORIES);\n } catch {\n return [];\n }\n\n const details = await Promise.allSettled(\n keys.map((key) =>\n httpGetJson<any>(`https://${HOST}/v3/advisories/${encodeURIComponent(key)}`, {\n host: HOST,\n ttlMs: CACHE_TTL.depsDev,\n fetchImpl,\n }),\n ),\n );\n return details\n .filter(\n (d): d is PromiseFulfilledResult<HttpResponse<any>> => d.status === 'fulfilled',\n )\n .map((d) => parseAdvisoryDetail(d.value.data));\n}\n\n/**\n * Direct dependency names from the deps.dev graph (§2B). These are the packages\n * a seed is *built on* — the adjacent foundations. Best-effort: returns [] on any\n * failure. We deliberately do NOT rank by dependent count (that re-introduces the\n * popularity bias §2B exists to avoid); the caller gates on quality instead.\n */\nexport async function fetchDependencyNames(\n name: string,\n version: string,\n fetchImpl?: typeof fetch,\n): Promise<string[]> {\n const url = `https://${HOST}/v3/systems/npm/packages/${encodeName(name)}/versions/${encodeURIComponent(version)}:dependencies`;\n try {\n const { data } = await httpGetJson<any>(url, {\n host: HOST,\n ttlMs: CACHE_TTL.depsDev,\n fetchImpl,\n });\n const nodes: any[] = Array.isArray(data?.nodes) ? data.nodes : [];\n const names = nodes\n .map((n) => n?.versionKey?.name)\n .filter((n: unknown): n is string => typeof n === 'string' && n !== name);\n return [...new Set(names)];\n } catch {\n return [];\n }\n}\n\nexport async function fetchDepsDev(\n name: string,\n version: string | null,\n repo: { owner: string; repo: string } | null,\n fetchImpl?: typeof fetch,\n): Promise<DepsDevData> {\n const [scorecard, advisories] = await Promise.all([\n repo ? fetchScorecard(repo.owner, repo.repo, fetchImpl) : Promise.resolve(null),\n version ? fetchAdvisories(name, version, fetchImpl) : Promise.resolve([]),\n ]);\n return { scorecard, advisories };\n}\n","/**\n * Bundlephobia client (§9.5). Minified + gzipped size for frontend packages.\n * Strictly best-effort: this API is slow and flaky, so failures degrade to null\n * and never block ingestion (per R1 build decision). Cached aggressively (7d).\n */\nimport { CACHE_TTL } from '../../core/constants';\nimport { httpGetJson } from '../../core/http';\nimport { isFrontendCategory, type Category } from '../../core/types';\nimport type { BundlephobiaData } from '../types';\n\nconst HOST = 'bundlephobia.com';\n\nexport function parseBundleSize(json: any): number | null {\n const gzipBytes = json?.gzip;\n if (typeof gzipBytes !== 'number') return null;\n return Math.round((gzipBytes / 1024) * 10) / 10; // KB, 1 decimal\n}\n\n/**\n * Fetch bundle size — only for frontend categories (§9.5); returns null for\n * backend-only packages without making a request.\n */\nexport async function fetchBundlephobia(\n name: string,\n category: Category | null,\n fetchImpl?: typeof fetch,\n): Promise<BundlephobiaData> {\n if (!isFrontendCategory(category)) return { bundleMinGzipKb: null };\n\n const url = `https://${HOST}/api/size?package=${encodeURIComponent(name)}`;\n try {\n const { data } = await httpGetJson<any>(url, {\n host: HOST,\n ttlMs: CACHE_TTL.bundlephobia,\n timeoutMs: 12_000,\n retries: 1,\n fetchImpl,\n });\n return { bundleMinGzipKb: parseBundleSize(data) };\n } catch {\n return { bundleMinGzipKb: null };\n }\n}\n","export * from './npmRegistry';\nexport * from './npmSearch';\nexport * from './npmDownloads';\nexport * from './github';\nexport * from './depsDev';\nexport * from './bundlephobia';\n","/**\n * GitHub raw README fallback (§9.6). The npm packument `readme` field is often\n * empty (e.g. zod), so we fetch the repo README directly when needed. Public\n * raw content needs no token.\n */\nimport { CACHE_TTL } from '../../core/constants';\nimport { httpRequest } from '../../core/http';\n\nconst HOST = 'raw.githubusercontent.com';\nconst CANDIDATES = ['README.md', 'readme.md', 'README.markdown', 'README'];\n\nexport async function fetchGithubReadme(\n owner: string,\n repo: string,\n fetchImpl?: typeof fetch,\n): Promise<string | null> {\n for (const file of CANDIDATES) {\n const url = `https://${HOST}/${owner}/${repo}/HEAD/${file}`;\n try {\n const { data } = await httpRequest<string>(url, {\n host: HOST,\n ttlMs: CACHE_TTL.github,\n accept: 'text',\n retries: 0,\n fetchImpl,\n });\n if (data && data.trim().length > 0) return data;\n } catch {\n /* try the next candidate */\n }\n }\n return null;\n}\n","/**\n * Summary + usage-guide generation (§9.6 + R1 explainer refinement).\n *\n * lurq generates its OWN guide grounded in the package's README/description —\n * it never depends on Context7. When a summary LLM key is configured we use it;\n * otherwise we fall back to the npm description + a category-derived guide,\n * fabricating nothing. The exact current API is deferred to Context7 via a hint.\n */\nimport { CATEGORIES, isCategory, type Category, type UsageGuide } from '../core/types';\nimport { getConfig } from '../core/config';\nimport { httpRequest } from '../core/http';\nimport { logger } from '../core/logger';\nimport { fetchGithubReadme } from './sources/githubReadme';\nimport type { RawPackageSignals } from './types';\n\nexport interface SummaryInput {\n name: string;\n description: string | null;\n category: Category | null;\n readme: string | null;\n repoUrl: string | null;\n}\n\nexport interface SummaryResult {\n summary: string | null;\n usageGuide: UsageGuide;\n /** Taxonomy category the LLM classified the package into (§2A), or null\n * (always null for the fallback provider — it does no classification). */\n inferredCategory: Category | null;\n}\n\nexport interface SummaryProvider {\n readonly kind: 'openai' | 'fallback';\n generate(input: SummaryInput): Promise<SummaryResult>;\n}\n\n/** Human-readable architectural role per category (generic — lurq has no code context). */\nconst CATEGORY_ROLE: Record<string, string> = {\n framework: 'the core application framework your app is built on',\n 'meta-framework': 'the full-stack framework wrapping routing, rendering, and build',\n 'state-management': 'the client state layer shared across components',\n routing: 'the routing layer mapping URLs to views',\n orm: 'the data-access layer between your code and the database',\n 'database-client': 'the low-level driver that talks to your database',\n 'ui-component-library': 'the prebuilt UI component layer',\n styling: 'the styling layer for your components',\n forms: 'form state and submission handling',\n validation: 'input/schema validation at your boundaries',\n 'data-fetching': 'the server-state/data-fetching layer',\n 'http-client': 'the HTTP request layer for calling APIs',\n auth: 'authentication and session handling',\n testing: 'the test tooling layer',\n 'build-tool': 'the build/dev pipeline',\n bundler: 'the module bundling step',\n linting: 'code-quality and formatting checks',\n 'date-time': 'date and time handling',\n animation: 'UI animation and motion',\n charts: 'data visualization and charts',\n i18n: 'internationalization and localization',\n utility: 'a focused helper you compose into your app',\n other: 'a supporting library in your app',\n};\n\nfunction context7Hint(name: string): string {\n return `For the exact current API of \"${name}\", resolve it via Context7 (resolve-library-id → query-docs).`;\n}\n\n/** Keep text to ~`max` sentences. */\nexport function truncateSentences(text: string, max = 3): string {\n const clean = text.replace(/\\s+/g, ' ').trim();\n if (!clean) return '';\n // Match full sentences, plus a trailing fragment with no terminal punctuation\n // (so descriptions without a period return the whole text, not just the last word).\n const sentences = clean.match(/[^.!?]+[.!?]+|[^.!?]+$/g) ?? [clean];\n return sentences\n .slice(0, max)\n .map((s) => s.trim())\n .join(' ')\n .trim();\n}\n\n// ── Fallback provider (no LLM key) ──────────────────────────────────────────\n\nexport class FallbackSummaryProvider implements SummaryProvider {\n readonly kind = 'fallback' as const;\n\n async generate(input: SummaryInput): Promise<SummaryResult> {\n const description = input.description?.trim() || null;\n const role = CATEGORY_ROLE[input.category ?? 'other'] ?? CATEGORY_ROLE.other!;\n const summary = description ? truncateSentences(description, 3) : null;\n const guide: UsageGuide = {\n whatItIs: description ? truncateSentences(description, 2) : input.name,\n whenToUse: `Reach for ${input.name} when you need ${role}.`,\n whereItFits: `Sits at ${role}.`,\n context7Hint: context7Hint(input.name),\n };\n return { summary, usageGuide: guide, inferredCategory: null };\n }\n}\n\n// ── OpenAI provider (raw fetch, no SDK dependency) ──────────────────────────\n\nconst SYSTEM_PROMPT =\n 'You summarize npm packages factually for an AI coding agent choosing dependencies. ' +\n 'Use ONLY the provided README/description. Never invent capabilities or APIs. ' +\n 'Be concise and concrete. Respond with a JSON object.';\n\nfunction buildUserPrompt(input: SummaryInput): string {\n const readme = (input.readme ?? '').slice(0, 4000);\n // Ask the model to classify only when we don't already have a curated category\n // (§2A) — otherwise the curated value wins and we save the model the choice.\n const needsCategory = input.category == null;\n return [\n `Package: ${input.name}`,\n `Category: ${input.category ?? 'unknown'}`,\n `Description: ${input.description ?? '(none)'}`,\n `README (truncated):\\n${readme || '(none)'}`,\n '',\n 'Return JSON with keys:',\n '- \"summary\": 2-3 sentences: what it is, when to use it, how it fits an app.',\n '- \"whatItIs\": one sentence.',\n '- \"whenToUse\": one sentence on the ideal use case.',\n '- \"whenNotToUse\": one sentence on when to pick something else (or \"\").',\n '- \"whereItFits\": one sentence on its architectural role.',\n '- \"howToWireIn\": one short sentence on the minimal setup (install + entry point), or \"\".',\n ...(needsCategory\n ? [`- \"category\": the single best fit from this list: ${CATEGORIES.join(', ')}.`]\n : []),\n ].join('\\n');\n}\n\nexport class OpenAISummaryProvider implements SummaryProvider {\n readonly kind = 'openai' as const;\n\n constructor(\n private readonly apiKey: string,\n private readonly model: string,\n private readonly fetchImpl?: typeof fetch,\n ) {}\n\n async generate(input: SummaryInput): Promise<SummaryResult> {\n try {\n const body = JSON.stringify({\n model: this.model,\n messages: [\n { role: 'system', content: SYSTEM_PROMPT },\n { role: 'user', content: buildUserPrompt(input) },\n ],\n response_format: { type: 'json_object' },\n temperature: 0.2,\n });\n const { data } = await httpRequest<any>('https://api.openai.com/v1/chat/completions', {\n host: 'api.openai.com',\n method: 'POST',\n ttlMs: 30 * 24 * 60 * 60 * 1000, // cache summaries 30d to control cost\n cacheKey: `openai-summary ${this.model} ${input.name} ${(input.readme ?? '').length}`,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n },\n body,\n fetchImpl: this.fetchImpl,\n });\n const content = data?.choices?.[0]?.message?.content;\n const parsed = content ? JSON.parse(content) : {};\n const guide: UsageGuide = {\n whatItIs: str(parsed.whatItIs) || input.name,\n whenToUse: str(parsed.whenToUse),\n whenNotToUse: str(parsed.whenNotToUse) || undefined,\n whereItFits: str(parsed.whereItFits),\n howToWireIn: str(parsed.howToWireIn) || undefined,\n context7Hint: context7Hint(input.name),\n };\n const rawCategory = str(parsed.category);\n const inferredCategory = rawCategory && isCategory(rawCategory) ? rawCategory : null;\n return {\n summary: str(parsed.summary) ? truncateSentences(parsed.summary, 3) : null,\n usageGuide: guide,\n inferredCategory,\n };\n } catch (err) {\n logger.warn(`summary LLM failed for ${input.name}, using fallback: ${(err as Error).message}`);\n return new FallbackSummaryProvider().generate(input);\n }\n }\n}\n\nfunction str(value: unknown): string {\n return typeof value === 'string' ? value.trim() : '';\n}\n\n// ── Factory + input assembly ────────────────────────────────────────────────\n\nexport function createSummaryProvider(fetchImpl?: typeof fetch): SummaryProvider {\n const config = getConfig();\n if (config.SUMMARY_PROVIDER === 'openai' && config.SUMMARY_API_KEY) {\n return new OpenAISummaryProvider(config.SUMMARY_API_KEY, config.SUMMARY_MODEL, fetchImpl);\n }\n return new FallbackSummaryProvider();\n}\n\n/** Assemble the summary input, fetching the GitHub-raw README when npm's is empty. */\nexport async function buildSummaryInput(\n signals: RawPackageSignals,\n category: Category | null,\n fetchImpl?: typeof fetch,\n): Promise<SummaryInput> {\n const registry = signals.registry;\n let readme = registry?.readme?.trim() || null;\n if (!readme && registry?.repo) {\n readme = await fetchGithubReadme(registry.repo.owner, registry.repo.repo, fetchImpl).catch(\n () => null,\n );\n }\n return {\n name: signals.name,\n description: registry?.description ?? null,\n category,\n readme,\n repoUrl: registry?.repoUrl ?? null,\n };\n}\n","/**\n * Gather all source signals for one package (§9.7 steps 1–5). Fault-isolated:\n * each source is wrapped so a single failure records an error and degrades that\n * signal to null rather than failing the package (§17).\n */\nimport { logger } from '../core/logger';\nimport type { Category } from '../core/types';\nimport { fetchBundlephobia } from './sources/bundlephobia';\nimport { fetchDepsDev } from './sources/depsDev';\nimport { fetchGithubRepo } from './sources/github';\nimport { fetchDownloadGrowth, fetchWeeklyDownloads } from './sources/npmDownloads';\nimport { fetchNpmRegistry } from './sources/npmRegistry';\nimport type { NpmDownloadsData, RawPackageSignals } from './types';\n\nexport interface CollectDeps {\n githubToken?: string;\n fetchImpl?: typeof fetch;\n /**\n * Pre-fetched weekly downloads (from the bulk endpoint). When provided (even\n * as null), the per-package weekly fetch is skipped — avoiding the downloads\n * API's harsh rate limits during a full sync.\n */\n prefetchedWeekly?: number | null;\n}\n\nasync function attempt<T>(\n source: string,\n errors: { source: string; message: string }[],\n fn: () => Promise<T>,\n): Promise<T | null> {\n try {\n return await fn();\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n errors.push({ source, message });\n logger.debug(`[${source}] ${message}`);\n return null;\n }\n}\n\nexport async function collectSignals(\n name: string,\n category: Category | null,\n deps: CollectDeps = {},\n): Promise<RawPackageSignals> {\n const { githubToken, fetchImpl } = deps;\n const errors: { source: string; message: string }[] = [];\n\n // 1. Registry first — it provides the repo + version the other sources need.\n const registry = await attempt('npm-registry', errors, () => fetchNpmRegistry(name, fetchImpl));\n\n const repo = registry?.repo ?? null;\n const version = registry?.latestVersion ?? null;\n\n // 2–5. The rest run concurrently.\n const [downloads, github, depsDev, bundle] = await Promise.all([\n attempt('npm-downloads', errors, async (): Promise<NpmDownloadsData> => {\n const weeklyDownloads =\n deps.prefetchedWeekly !== undefined\n ? deps.prefetchedWeekly\n : await fetchWeeklyDownloads(name, fetchImpl);\n const downloadGrowth90d = await fetchDownloadGrowth(name, fetchImpl);\n return { weeklyDownloads, downloadGrowth90d };\n }),\n repo && githubToken\n ? attempt('github', errors, () => fetchGithubRepo(repo.owner, repo.repo, githubToken, fetchImpl))\n : Promise.resolve(null),\n attempt('deps-dev', errors, () => fetchDepsDev(name, version, repo, fetchImpl)),\n attempt('bundlephobia', errors, () => fetchBundlephobia(name, category, fetchImpl)),\n ]);\n\n return { name, registry, downloads, github, depsDev, bundle, errors };\n}\n","/**\n * Lightweight category inference (§11). Maps a natural-language need to a\n * taxonomy category via keyword matching. Returns null when uncertain, so the\n * caller searches across all categories rather than over-filtering.\n */\nimport type { Category } from '../core/types';\nimport type { RawPackageSignals } from '../ingestion/types';\n\nconst RULES: { category: Category; patterns: RegExp }[] = [\n { category: 'meta-framework', patterns: /\\b(meta-?framework|next\\.?js|nuxt|remix|astro|gatsby|sveltekit|full-?stack framework)\\b/ },\n { category: 'state-management', patterns: /\\b(state management|global state|store|redux|zustand|jotai|mobx|atoms?)\\b/ },\n { category: 'routing', patterns: /\\b(rout(e|er|ing)|navigation|url matching)\\b/ },\n { category: 'orm', patterns: /\\b(orm|object-?relational|query builder|prisma|drizzle|sequelize|typeorm)\\b/ },\n { category: 'database-client', patterns: /\\b(database (driver|client)|postgres|mysql|mongo(db)?|redis|sqlite|db driver)\\b/ },\n { category: 'ui-component-library', patterns: /\\b(component library|ui kit|ui components?|design system|buttons?|modal|dialog)\\b/ },\n { category: 'styling', patterns: /\\b(styl(e|ing)|css|tailwind|sass|scss|class ?names?|theme)\\b/ },\n { category: 'forms', patterns: /\\b(forms?|form (state|library|handling)|input handling)\\b/ },\n { category: 'validation', patterns: /\\b(validat(e|ion|or)|schema|parse input|type ?safe parsing)\\b/ },\n { category: 'data-fetching', patterns: /\\b(data fetching|server state|react query|swr|graphql client|caching queries)\\b/ },\n { category: 'http-client', patterns: /\\b(http client|fetch wrapper|rest client|make (a )?request|ajax|api calls?)\\b/ },\n { category: 'auth', patterns: /\\b(auth(entication|orization)?|login|session|jwt|oauth|password hashing)\\b/ },\n { category: 'testing', patterns: /\\b(test(ing|s)?|unit test|e2e|assertion|mocking|test runner)\\b/ },\n { category: 'bundler', patterns: /\\b(bundler|bundle (modules?|code)|webpack|rollup|esbuild|parcel)\\b/ },\n { category: 'build-tool', patterns: /\\b(build tool|dev server|monorepo|task runner|compile|transpile)\\b/ },\n // date-time precedes linting: \"date formatting\" must not be captured by linting's\n // bare \"formatting\" token before the date rule is reached (first-match-wins).\n { category: 'date-time', patterns: /\\b(dates?|date ?time|time(zone)?s?|calendar|parse dates?|format dates?)\\b/ },\n { category: 'linting', patterns: /\\b(lint(er|ing)?|formatter|formatting|code (quality|style|format)|prettier|eslint)\\b/ },\n { category: 'animation', patterns: /\\b(animat(e|ion)|motion|transition|spring|gsap|3d)\\b/ },\n { category: 'charts', patterns: /\\b(charts?|graphs?|data ?vis(ualization)?|plots?|dashboards?)\\b/ },\n { category: 'i18n', patterns: /\\b(i18n|internationali[sz]ation|localization|translat(e|ion)|locale)\\b/ },\n { category: 'framework', patterns: /\\b(framework|react|vue|svelte|angular|web server|backend framework)\\b/ },\n { category: 'utility', patterns: /\\b(debounce|throttle|deep ?clone|slugify|uuid|util(ity|ities)?|helper|lodash|retry)\\b/ },\n];\n\nexport function inferCategory(need: string): Category | null {\n const text = need.toLowerCase();\n for (const rule of RULES) {\n if (rule.patterns.test(text)) return rule.category;\n }\n return null;\n}\n\n/**\n * Categorize-on-ingest (§2A): infer a category from a package's *own* text —\n * name, keywords, description, and the README head — instead of a user query.\n * Keywords are repeated to give them extra weight (they're the most reliable\n * categorical signal). Returns null when no rule matches; the caller then falls\n * back to the LLM classifier or leaves the category null.\n */\nexport function inferCategoryFromSignals(signals: RawPackageSignals): Category | null {\n const r = signals.registry;\n const keywords = (r?.keywords ?? []).join(' ');\n const text = [\n signals.name,\n keywords,\n keywords, // weight keywords higher via repetition\n r?.description ?? '',\n (r?.readme ?? '').slice(0, 600),\n ]\n .filter(Boolean)\n .join(' ');\n return inferCategory(text);\n}\n","/**\n * Locate package-relative resources at runtime. Works in dev (tsx, source under\n * src/) and when published (bundled under dist/), by walking up from this module\n * until a directory containing package.json is found.\n */\nimport { existsSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nlet cachedRoot: string | undefined;\n\n/** Absolute path to the installed lurq package root (the dir with package.json). */\nexport function packageRoot(): string {\n if (cachedRoot) return cachedRoot;\n let dir = dirname(fileURLToPath(import.meta.url));\n // Walk up to the filesystem root looking for our package.json.\n for (;;) {\n if (existsSync(join(dir, 'package.json'))) {\n cachedRoot = dir;\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n // Fallback: current working directory.\n cachedRoot = process.cwd();\n return cachedRoot;\n}\n\n/** Folder holding generated Drizzle migrations. */\nexport function migrationsDir(): string {\n return join(packageRoot(), 'drizzle');\n}\n\n/** The curated seed list shipped with the package. */\nexport function seedJsonPath(): string {\n return join(packageRoot(), 'src', 'data', 'seed.json');\n}\n\n/** User-level weight-override config (§4): `~/.config/lurq/weights.json`. */\nexport function userWeightsPath(): string {\n const base = process.env.XDG_CONFIG_HOME || join(homedir(), '.config');\n return join(base, 'lurq', 'weights.json');\n}\n\n/** Project-local weight-override config (§4): `.lurq/weights.json` in the cwd.\n * Takes precedence over the user-level file when present. */\nexport function projectWeightsPath(): string {\n return join(process.cwd(), '.lurq', 'weights.json');\n}\n","/**\n * All scoring weights and thresholds in one tunable file (§10).\n * Changing the model means editing this file only.\n */\n\n/** Composite health-score weights. Must sum to 1.0. */\nexport const HEALTH_WEIGHTS = {\n maintenance: 0.35,\n adoption: 0.3,\n reliability: 0.25,\n efficiency: 0.1,\n} as const;\n\n/**\n * Health↔Quality blend for the default composite sort (§1). Quality is a\n * standalone, adoption-independent axis — NOT a member of HEALTH_WEIGHTS. The\n * two only blend here, for ranking/sort: composite = (1−λ)·health + λ·quality.\n * λ is the single most impactful knob `edit-weights` exposes.\n */\nexport const COMPOSITE = {\n lambda: 0.35,\n} as const;\n\n/**\n * Quality sub-score component weights (of the *available* components — missing\n * signals are dropped, not zeroed, via weightedAverage). All inputs are\n * adoption-independent: they measure how well-built a package is, not how many\n * people use it.\n */\nexport const QUALITY_WEIGHTS = {\n types: 0.25,\n tests: 0.2,\n docs: 0.2,\n changelog: 0.1,\n deps: 0.1,\n license: 0.1,\n provenance: 0.05,\n} as const;\n\nexport const QUALITY = {\n /** README at/above this many characters scores full marks on doc length. */\n docsFullLengthChars: 1200,\n /** Direct-dependency count at/above this scores 0 on the deps component (log-scaled). */\n depsLogMax: 30,\n /** A license string present but not OSI-recognized scores this (vs 100 / 0). */\n licenseUnrecognizedScore: 60,\n} as const;\n\n/** Maintenance sub-score component weights (of the available components). */\nexport const MAINTENANCE_WEIGHTS = {\n recency: 0.5,\n cadence: 0.25,\n closeRatio: 0.25,\n} as const;\n\nexport const MAINTENANCE = {\n /** A release within this many days scores full recency. */\n freshDays: 30,\n /** Recency decays linearly to 0 by this many days (~24 months). */\n staleDays: 730,\n /** Releases/12mo at or above this cap full cadence. */\n cadenceCap: 12,\n /** deprecated/archived hard-cap maintenance at this value. */\n deadCap: 15,\n} as const;\n\nexport const ADOPTION = {\n /** log10(weekly downloads): this maps to 0. */\n downloadsLogMin: 1, // 10/wk\n /** log10(weekly downloads): this maps to 100. */\n downloadsLogMax: 7, // 10M/wk\n /** log10(stars) that maps to 100. */\n starsLogMax: 5, // 100k stars\n /** Weight of the stars component when available (downloads gets the rest). */\n starsWeight: 0.2,\n /** Growth bonus: growth fraction × this, clamped to ±cap. */\n growthMultiplier: 30,\n growthBonusCap: 20,\n} as const;\n\nexport const RELIABILITY = {\n /** Used when no Scorecard is available (unknown security posture). */\n neutralWhenUnknown: 50,\n /** Advisory penalties by severity. */\n penalty: {\n critical: 40,\n high: 20,\n moderate: 8,\n low: 3,\n info: 0,\n },\n} as const;\n\nexport const EFFICIENCY = {\n /** Bundle size at the category median maps to this score; smaller → higher. */\n medianScore: 50,\n} as const;\n\n/** Proactive-discovery crawler tuning (§2B). The gate is quality-only — downloads\n * are deliberately excluded so merit, not popularity, decides what graduates. */\nexport const DISCOVERY = {\n /** A queued candidate must clear this quality pre-score to graduate to ingest. */\n minPreScore: 45,\n /** Max candidates fully ingested per crawler run (cost bound). */\n perRunCap: 25,\n /** npm-search hits to pull per category keyword. */\n searchSizePerCategory: 10,\n /** Max dependency-graph neighbors to enqueue per tracked seed. */\n graphNeighborsPerSeed: 20,\n} as const;\n\n// ── Tunable weight model: defaults ← user-config ← env (§4) ──────────────────\n\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { projectWeightsPath, userWeightsPath } from '../core/paths';\n\n/** The user-tunable slice of the model (§4). Sub-component weights and\n * thresholds stay fixed; these are the knobs `edit-weights` exposes. */\nexport interface WeightConfig {\n health: {\n maintenance: number;\n adoption: number;\n reliability: number;\n efficiency: number;\n };\n /** Health↔Quality blend λ for the default sort composite. */\n composite: { lambda: number };\n}\n\nexport const DEFAULT_WEIGHTS: WeightConfig = {\n health: { ...HEALTH_WEIGHTS },\n composite: { ...COMPOSITE },\n};\n\nexport type WeightSource = 'defaults' | 'user-config' | 'project-config';\n\n/** Where overrides are read from, if anywhere — for `lurq weights` to report. */\nexport function activeWeightsPath(): { path: string; source: WeightSource } | null {\n if (existsSync(projectWeightsPath())) return { path: projectWeightsPath(), source: 'project-config' };\n if (existsSync(userWeightsPath())) return { path: userWeightsPath(), source: 'user-config' };\n return null;\n}\n\nlet cachedWeights: WeightConfig | undefined;\n\n/**\n * Resolve the effective weight model: defaults, overlaid by a config file\n * (project-local wins over user-level), overlaid by env (`LURQ_COMPOSITE_LAMBDA`).\n * Always returns a validated, sum-to-1 health block. Memoized; call\n * `resetWeightsCache()` after a write or in tests.\n */\nexport function loadWeights(): WeightConfig {\n if (cachedWeights) return cachedWeights;\n\n let merged: WeightConfig = structuredClone(DEFAULT_WEIGHTS);\n const active = activeWeightsPath();\n if (active) {\n try {\n const fromFile = JSON.parse(readFileSync(active.path, 'utf8')) as Partial<WeightConfig>;\n merged = mergeWeights(merged, fromFile);\n } catch {\n // A corrupt override file must never break scoring — fall back to defaults.\n }\n }\n\n const envLambda = process.env.LURQ_COMPOSITE_LAMBDA;\n if (envLambda !== undefined && envLambda !== '') {\n const n = Number(envLambda);\n if (Number.isFinite(n)) merged.composite.lambda = n;\n }\n\n cachedWeights = validateWeights(merged).weights;\n return cachedWeights;\n}\n\nexport function resetWeightsCache(): void {\n cachedWeights = undefined;\n}\n\nfunction mergeWeights(base: WeightConfig, over: Partial<WeightConfig>): WeightConfig {\n return {\n health: { ...base.health, ...(over.health ?? {}) },\n composite: { ...base.composite, ...(over.composite ?? {}) },\n };\n}\n\nexport interface WeightValidation {\n weights: WeightConfig;\n /** True if the health block was renormalized to sum to 1.0. */\n normalized: boolean;\n}\n\n/**\n * Clamp λ to [0,1] and renormalize the health block to sum to 1.0 (§4 invariant,\n * weights.ts:6). Returns the cleaned weights and whether normalization happened\n * so the CLI can report it.\n */\nexport function validateWeights(w: WeightConfig): WeightValidation {\n const lambda = Math.max(0, Math.min(1, w.composite.lambda));\n const h = w.health;\n const sum = h.maintenance + h.adoption + h.reliability + h.efficiency;\n let normalized = false;\n let health = h;\n if (sum <= 0) {\n health = { ...DEFAULT_WEIGHTS.health };\n normalized = true;\n } else if (Math.abs(sum - 1) > 1e-6) {\n health = {\n maintenance: h.maintenance / sum,\n adoption: h.adoption / sum,\n reliability: h.reliability / sum,\n efficiency: h.efficiency / sum,\n };\n normalized = true;\n }\n return { weights: { health, composite: { lambda } }, normalized };\n}\n\n/** Keys settable via `edit-weights --set` and their slot in the config. */\nconst SETTABLE: Record<string, (w: WeightConfig, v: number) => void> = {\n 'health.maintenance': (w, v) => (w.health.maintenance = v),\n 'health.adoption': (w, v) => (w.health.adoption = v),\n 'health.reliability': (w, v) => (w.health.reliability = v),\n 'health.efficiency': (w, v) => (w.health.efficiency = v),\n 'composite.lambda': (w, v) => (w.composite.lambda = v),\n};\n\nexport function settableKeys(): string[] {\n return Object.keys(SETTABLE);\n}\n\n/** Apply `key=value` overrides to a config, returning a new config. Throws on an\n * unknown key or non-numeric value. */\nexport function applyOverrides(base: WeightConfig, sets: string[]): WeightConfig {\n const next = structuredClone(base);\n for (const entry of sets) {\n const eq = entry.indexOf('=');\n if (eq < 0) throw new Error(`Invalid --set \"${entry}\" (expected key=value).`);\n const key = entry.slice(0, eq).trim();\n const value = Number(entry.slice(eq + 1).trim());\n const apply = SETTABLE[key];\n if (!apply) {\n throw new Error(`Unknown weight key \"${key}\". Settable: ${settableKeys().join(', ')}.`);\n }\n if (!Number.isFinite(value)) throw new Error(`Value for \"${key}\" must be a number.`);\n apply(next, value);\n }\n return next;\n}\n\n/** Persist a config to the override file and bust the cache. */\nexport function saveWeights(w: WeightConfig, scope: 'user' | 'project' = 'user'): string {\n const path = scope === 'project' ? projectWeightsPath() : userWeightsPath();\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(w, null, 2) + '\\n', 'utf8');\n resetWeightsCache();\n return path;\n}\n\n/** Remove any override files, restoring defaults. Returns the paths removed. */\nexport function resetWeights(): string[] {\n const removed: string[] = [];\n for (const path of [projectWeightsPath(), userWeightsPath()]) {\n if (existsSync(path)) {\n rmSync(path);\n removed.push(path);\n }\n }\n resetWeightsCache();\n return removed;\n}\n\n/** Human-readable explanation per health component / knob (§4 `--explain`). */\nexport const WEIGHT_EXPLANATIONS: Record<string, string> = {\n maintenance: 'release recency, cadence, and issue close-ratio (weights.ts MAINTENANCE_WEIGHTS).',\n adoption: 'weekly downloads (log-scaled), stars, and 90-day growth (weights.ts ADOPTION).',\n reliability: 'OpenSSF Scorecard scaled 0–100, minus advisory penalties (weights.ts RELIABILITY).',\n efficiency: 'bundle size vs the category median; frontend categories only (weights.ts EFFICIENCY).',\n quality:\n 'intrinsic, adoption-independent: types, tests, docs, changelog, deps, license, provenance (weights.ts QUALITY_WEIGHTS). A standalone axis — it does NOT feed health.',\n lambda: 'how much the default sort composite favors quality over health: (1−λ)·health + λ·quality.',\n};\n\n/** Confidence-label thresholds (§10, §1). */\nexport const CONFIDENCE = {\n proven: {\n minWeeklyDownloads: 100_000,\n minAgeMonths: 12,\n maxLastReleaseMonths: 6,\n },\n emerging: {\n minWeeklyDownloads: 5_000,\n strongGrowth: 0.5,\n maxLastReleaseMonths: 9,\n },\n /** `promising` (§1): new but intrinsically high-quality, regardless of adoption. */\n promising: {\n minQuality: 70,\n maxLastReleaseMonths: 12,\n },\n} as const;\n","/**\n * Scoring & confidence model (§10). All functions are pure and take an explicit\n * `now` for deterministic testing.\n *\n * Two-pass design: maintenance / adoption / reliability / confidence depend only\n * on a single package, so they're computed in pass 1. Efficiency needs the\n * category median bundle size (§10), so it — and the composite health score —\n * are computed in pass 2 once all packages are collected.\n */\nimport type { Advisory, Category, Confidence, ScoreBreakdown } from '../core/types';\nimport { isFrontendCategory } from '../core/types';\nimport type { RawPackageSignals } from '../ingestion/types';\nimport {\n ADOPTION,\n COMPOSITE,\n CONFIDENCE,\n EFFICIENCY,\n HEALTH_WEIGHTS,\n MAINTENANCE,\n MAINTENANCE_WEIGHTS,\n QUALITY,\n QUALITY_WEIGHTS,\n RELIABILITY,\n} from './weights';\n\nexport interface ScoringInput {\n weeklyDownloads: number | null;\n downloadGrowth90d: number | null;\n stars: number | null;\n dependentsCount: number | null;\n firstPublishedAt: Date | null;\n lastReleaseAt: Date | null;\n releasesLast12mo: number | null;\n openIssues: number | null;\n closedIssues: number | null;\n scorecard: number | null;\n advisories: Advisory[];\n deprecated: boolean;\n archived: boolean;\n bundleMinGzipKb: number | null;\n category: Category | null;\n // ── Intrinsic-quality signals (§1), adoption-independent ──\n hasTypes: boolean | null;\n hasTestScript: boolean | null;\n readmeLength: number | null;\n hasExamples: boolean | null;\n hasHomepage: boolean | null;\n hasReleaseNotes: boolean | null;\n directDependenciesCount: number | null;\n license: string | null;\n hasProvenance: boolean | null;\n}\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\nconst MONTH_MS = 30 * DAY_MS;\n\nconst clamp = (n: number, lo = 0, hi = 100): number => Math.max(lo, Math.min(hi, n));\nconst daysSince = (date: Date | null, now: Date): number | null =>\n date ? (now.getTime() - date.getTime()) / DAY_MS : null;\nconst monthsSince = (date: Date | null, now: Date): number | null =>\n date ? (now.getTime() - date.getTime()) / MONTH_MS : null;\n\n/** Build a ScoringInput from collected raw signals. */\nexport function toScoringInput(signals: RawPackageSignals, category: Category | null): ScoringInput {\n const { registry, downloads, github, depsDev, bundle } = signals;\n const readme = registry?.readme ?? null;\n return {\n weeklyDownloads: downloads?.weeklyDownloads ?? null,\n downloadGrowth90d: downloads?.downloadGrowth90d ?? null,\n stars: github?.stars ?? null,\n dependentsCount: null, // not collected in v1 (see spec R1 note)\n firstPublishedAt: registry?.firstPublishedAt ?? null,\n lastReleaseAt: github?.lastReleaseAt ?? registry?.lastReleaseAt ?? null,\n releasesLast12mo: github?.releasesLast12mo ?? null,\n openIssues: github?.openIssues ?? null,\n closedIssues: github?.closedIssues ?? null,\n scorecard: depsDev?.scorecard ?? null,\n advisories: depsDev?.advisories ?? [],\n deprecated: registry?.deprecated ?? false,\n archived: github?.archived ?? false,\n bundleMinGzipKb: bundle?.bundleMinGzipKb ?? null,\n category,\n // Quality signals — null (not false) when the manifest itself is missing, so\n // weightedAverage drops the component rather than scoring it 0.\n hasTypes: registry ? registry.hasTypes : null,\n hasTestScript: registry ? registry.hasTestScript : null,\n readmeLength: readme !== null ? readme.length : null,\n hasExamples: readme !== null ? /```/.test(readme) : null,\n hasHomepage: registry ? registry.homepage !== null : null,\n hasReleaseNotes: github?.releasesLast12mo != null ? github.releasesLast12mo > 0 : null,\n directDependenciesCount: registry?.directDependenciesCount ?? null,\n license: registry?.license ?? null,\n hasProvenance: registry ? registry.hasProvenance : null,\n };\n}\n\n// ── Maintenance ─────────────────────────────────────────────────────────────\n\nexport function computeMaintenance(input: ScoringInput, now: Date): number {\n if (input.deprecated || input.archived) return MAINTENANCE.deadCap;\n\n const components: { value: number; weight: number }[] = [];\n\n const days = daysSince(input.lastReleaseAt, now);\n if (days !== null) {\n const recency =\n days <= MAINTENANCE.freshDays\n ? 100\n : clamp((100 * (MAINTENANCE.staleDays - days)) / (MAINTENANCE.staleDays - MAINTENANCE.freshDays));\n components.push({ value: recency, weight: MAINTENANCE_WEIGHTS.recency });\n }\n\n if (input.releasesLast12mo !== null) {\n const cadence = clamp((Math.min(input.releasesLast12mo, MAINTENANCE.cadenceCap) / MAINTENANCE.cadenceCap) * 100);\n components.push({ value: cadence, weight: MAINTENANCE_WEIGHTS.cadence });\n }\n\n if (input.openIssues !== null && input.closedIssues !== null) {\n const total = input.openIssues + input.closedIssues;\n if (total > 0) {\n components.push({ value: (input.closedIssues / total) * 100, weight: MAINTENANCE_WEIGHTS.closeRatio });\n }\n }\n\n return weightedAverage(components);\n}\n\n// ── Adoption ────────────────────────────────────────────────────────────────\n\nexport function computeAdoption(input: ScoringInput): number {\n const dl = input.weeklyDownloads ?? 0;\n const downloadsScore = clamp(\n ((Math.log10(Math.max(dl, 1)) - ADOPTION.downloadsLogMin) /\n (ADOPTION.downloadsLogMax - ADOPTION.downloadsLogMin)) *\n 100,\n );\n\n let base = downloadsScore;\n if (input.stars !== null) {\n const starsScore = clamp((Math.log10(Math.max(input.stars, 1)) / ADOPTION.starsLogMax) * 100);\n base = (1 - ADOPTION.starsWeight) * downloadsScore + ADOPTION.starsWeight * starsScore;\n }\n\n if (input.downloadGrowth90d !== null) {\n const bonus = clamp(\n input.downloadGrowth90d * ADOPTION.growthMultiplier,\n -ADOPTION.growthBonusCap,\n ADOPTION.growthBonusCap,\n );\n base += bonus;\n }\n\n return clamp(base);\n}\n\n// ── Reliability ─────────────────────────────────────────────────────────────\n\nexport function computeReliability(input: ScoringInput): number {\n const base = input.scorecard !== null ? input.scorecard * 10 : RELIABILITY.neutralWhenUnknown;\n const penalty = input.advisories.reduce(\n (sum, adv) => sum + (RELIABILITY.penalty[adv.severity] ?? 0),\n 0,\n );\n return clamp(base - penalty);\n}\n\n// ── Efficiency (pass 2 — needs the category median) ─────────────────────────\n\n/**\n * Efficiency for frontend categories: smaller-than-median bundle → higher score\n * (median maps to 50). Returns null for backend categories / missing data; the\n * null signals the composite to redistribute the efficiency weight (§10, R1).\n */\nexport function computeEfficiency(\n bundleMinGzipKb: number | null,\n category: Category | null,\n categoryMedian: number | null,\n): number | null {\n if (!isFrontendCategory(category) || bundleMinGzipKb === null || !categoryMedian || categoryMedian <= 0) {\n return null;\n }\n const ratio = bundleMinGzipKb / categoryMedian;\n return clamp(100 - ratio * EFFICIENCY.medianScore);\n}\n\n// ── Quality (pass 1 — intrinsic, adoption-independent §1) ────────────────────\n\n/** A small set of OSI-recognized SPDX license IDs (prefix-matched, case-insensitive). */\nconst RECOGNIZED_LICENSES = [\n 'mit',\n 'isc',\n 'apache-2.0',\n 'bsd-2-clause',\n 'bsd-3-clause',\n 'mpl-2.0',\n 'lgpl',\n 'gpl',\n 'agpl',\n 'unlicense',\n '0bsd',\n 'cc0-1.0',\n];\n\nexport function isRecognizedLicense(license: string | null): boolean {\n if (!license) return false;\n const id = license.trim().toLowerCase();\n return RECOGNIZED_LICENSES.some((l) => id === l || id.startsWith(l));\n}\n\n/**\n * Intrinsic-quality score (§1): how well-built a package is, independent of\n * adoption. A weighted average over the *available* components, so a missing\n * signal is dropped rather than penalized. Returns null only when no signal is\n * available at all (e.g. the registry manifest itself failed to load).\n */\nexport function computeQuality(input: ScoringInput): number | null {\n const components: { value: number; weight: number }[] = [];\n\n if (input.hasTypes !== null) {\n components.push({ value: input.hasTypes ? 100 : 0, weight: QUALITY_WEIGHTS.types });\n }\n if (input.hasTestScript !== null) {\n components.push({ value: input.hasTestScript ? 100 : 0, weight: QUALITY_WEIGHTS.tests });\n }\n if (input.readmeLength !== null || input.hasHomepage !== null) {\n const lenScore = Math.min((input.readmeLength ?? 0) / QUALITY.docsFullLengthChars, 1) * 60;\n const examples = input.hasExamples ? 25 : 0;\n const homepage = input.hasHomepage ? 15 : 0;\n components.push({ value: clamp(lenScore + examples + homepage), weight: QUALITY_WEIGHTS.docs });\n }\n if (input.hasReleaseNotes !== null) {\n components.push({ value: input.hasReleaseNotes ? 100 : 0, weight: QUALITY_WEIGHTS.changelog });\n }\n if (input.directDependenciesCount !== null) {\n const deps = input.directDependenciesCount;\n const depsScore = clamp(\n 100 - (Math.log10(deps + 1) / Math.log10(QUALITY.depsLogMax + 1)) * 100,\n );\n components.push({ value: depsScore, weight: QUALITY_WEIGHTS.deps });\n }\n if (input.license !== null) {\n components.push({\n value: isRecognizedLicense(input.license) ? 100 : QUALITY.licenseUnrecognizedScore,\n weight: QUALITY_WEIGHTS.license,\n });\n }\n // Provenance is a pure bonus — only counted when present, never penalizing.\n if (input.hasProvenance) {\n components.push({ value: 100, weight: QUALITY_WEIGHTS.provenance });\n }\n\n if (components.length === 0) return null;\n return weightedAverage(components);\n}\n\n// ── Composite ───────────────────────────────────────────────────────────────\n\n/** Compose the health score, redistributing efficiency's weight when null.\n * Weights default to HEALTH_WEIGHTS but can be overridden (§4 rescore). */\nexport function computeHealthScore(\n breakdown: ScoreBreakdown,\n weights: typeof HEALTH_WEIGHTS | { maintenance: number; adoption: number; reliability: number; efficiency: number } = HEALTH_WEIGHTS,\n): number {\n const { maintenance, adoption, reliability, efficiency } = breakdown;\n const w = weights;\n if (efficiency === null) {\n const denom = w.maintenance + w.adoption + w.reliability;\n return Math.round(\n (w.maintenance * maintenance + w.adoption * adoption + w.reliability * reliability) / denom,\n );\n }\n return Math.round(\n w.maintenance * maintenance +\n w.adoption * adoption +\n w.reliability * reliability +\n w.efficiency * efficiency,\n );\n}\n\n/**\n * Default sort composite (§1): blend the popularity-tilted health score with the\n * adoption-independent quality axis. `lambda` (default COMPOSITE.lambda) is the\n * tunable knob `edit-weights` exposes. Falls back to pure health when quality is\n * unavailable, so a missing manifest never drags a package down.\n */\nexport function computeComposite(\n healthScore: number,\n qualityScore: number | null,\n lambda: number = COMPOSITE.lambda,\n): number {\n if (qualityScore === null) return healthScore;\n return Math.round((1 - lambda) * healthScore + lambda * qualityScore);\n}\n\n// ── Confidence ──────────────────────────────────────────────────────────────\n\nexport function hasCriticalOrHighAdvisory(advisories: Advisory[]): boolean {\n return advisories.some((a) => a.severity === 'critical' || a.severity === 'high');\n}\n\nexport function computeConfidence(\n input: ScoringInput,\n now: Date,\n qualityScore: number | null = null,\n): Confidence {\n const dl = input.weeklyDownloads ?? 0;\n const ageMonths = monthsSince(input.firstPublishedAt, now);\n const lastReleaseMonths = monthsSince(input.lastReleaseAt, now);\n const growth = input.downloadGrowth90d ?? 0;\n\n const provenReleaseOk =\n lastReleaseMonths !== null && lastReleaseMonths <= CONFIDENCE.proven.maxLastReleaseMonths;\n const provenAgeOk = ageMonths !== null && ageMonths >= CONFIDENCE.proven.minAgeMonths;\n\n if (\n dl >= CONFIDENCE.proven.minWeeklyDownloads &&\n provenAgeOk &&\n provenReleaseOk &&\n !hasCriticalOrHighAdvisory(input.advisories) &&\n !input.deprecated &&\n !input.archived\n ) {\n return 'proven';\n }\n\n const emergingReleaseOk =\n lastReleaseMonths !== null && lastReleaseMonths <= CONFIDENCE.emerging.maxLastReleaseMonths;\n const emergingAdoptionOk =\n dl >= CONFIDENCE.emerging.minWeeklyDownloads || growth >= CONFIDENCE.emerging.strongGrowth;\n\n if (emergingAdoptionOk && emergingReleaseOk && !input.deprecated && !input.archived) {\n return 'emerging';\n }\n\n // `promising` (§1): adoption-independent — high intrinsic quality on a package\n // that hasn't yet earned adoption traction. This is how new-but-good packages\n // surface on merit instead of sinking to `unproven`.\n const promisingReleaseOk =\n lastReleaseMonths !== null && lastReleaseMonths <= CONFIDENCE.promising.maxLastReleaseMonths;\n if (\n qualityScore !== null &&\n qualityScore >= CONFIDENCE.promising.minQuality &&\n promisingReleaseOk &&\n !hasCriticalOrHighAdvisory(input.advisories) &&\n !input.deprecated &&\n !input.archived\n ) {\n return 'promising';\n }\n\n return 'unproven';\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction weightedAverage(components: { value: number; weight: number }[]): number {\n if (components.length === 0) return 0;\n const totalWeight = components.reduce((s, c) => s + c.weight, 0);\n if (totalWeight === 0) return 0;\n return Math.round(components.reduce((s, c) => s + c.value * c.weight, 0) / totalWeight);\n}\n\n/** Median of a numeric list, or null if empty. */\nexport function median(values: number[]): number | null {\n if (values.length === 0) return null;\n const sorted = [...values].sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!;\n}\n","export * from './score';\nexport * from './weights';\n","/**\n * Embedding providers (§11). A pluggable interface with two implementations:\n * - OpenAI (`text-embedding-3-small`, 1536-dim) — the default when a key is set.\n * - Local deterministic embedder (no key) — a hashing bag-of-words that captures\n * lexical overlap. Crude but real: it makes `recommend` and tests work with\n * zero credentials (R1 decision). Both emit EMBEDDING_DIM-length unit vectors,\n * so the DB column and pgvector index never change.\n */\nimport { createHash } from 'node:crypto';\nimport { getConfig } from '../core/config';\nimport { EMBEDDING_DIM } from '../core/constants';\nimport { httpRequest } from '../core/http';\nimport { logger } from '../core/logger';\nimport type { Category } from '../core/types';\n\nexport interface EmbeddingProvider {\n readonly kind: 'openai' | 'local';\n readonly dimensions: number;\n embed(texts: string[]): Promise<number[][]>;\n}\n\n/** Normalized text blob embedded per package (§8.2). */\nexport function buildEmbeddingText(input: {\n name: string;\n category: Category | null;\n summary: string | null;\n description: string | null;\n}): string {\n const body = input.summary || input.description || '';\n return `${input.name}. ${input.category ?? ''}. ${body}`.trim();\n}\n\n// ── Local deterministic embedder ────────────────────────────────────────────\n\nfunction tokenize(text: string): string[] {\n return text\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((t) => t.length > 1);\n}\n\n/** FNV-1a 32-bit hash. */\nfunction fnv1a(str: string): number {\n let h = 0x811c9dc5;\n for (let i = 0; i < str.length; i++) {\n h ^= str.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return h >>> 0;\n}\n\nexport function localEmbed(text: string, dim = EMBEDDING_DIM): number[] {\n const vec = new Float64Array(dim);\n const tokens = tokenize(text);\n const add = (token: string, weight: number) => {\n const idx = fnv1a(token) % dim;\n const sign = fnv1a('s:' + token) & 1 ? 1 : -1;\n vec[idx]! += weight * sign;\n };\n for (const t of tokens) add(t, 1);\n for (let i = 0; i < tokens.length - 1; i++) add(`${tokens[i]} ${tokens[i + 1]}`, 0.5);\n\n // L2-normalize to a unit vector (cosine-friendly).\n let norm = 0;\n for (let i = 0; i < dim; i++) norm += vec[i]! * vec[i]!;\n norm = Math.sqrt(norm) || 1;\n const out = new Array<number>(dim);\n for (let i = 0; i < dim; i++) out[i] = vec[i]! / norm;\n return out;\n}\n\nexport class LocalEmbeddingProvider implements EmbeddingProvider {\n readonly kind = 'local' as const;\n readonly dimensions = EMBEDDING_DIM;\n async embed(texts: string[]): Promise<number[][]> {\n return texts.map((t) => localEmbed(t));\n }\n}\n\n// ── OpenAI embedder ─────────────────────────────────────────────────────────\n\nconst OPENAI_BATCH = 96;\n\nexport class OpenAIEmbeddingProvider implements EmbeddingProvider {\n readonly kind = 'openai' as const;\n readonly dimensions = EMBEDDING_DIM;\n\n constructor(\n private readonly apiKey: string,\n private readonly model: string,\n private readonly fetchImpl?: typeof fetch,\n ) {}\n\n async embed(texts: string[]): Promise<number[][]> {\n const out: number[][] = [];\n for (let i = 0; i < texts.length; i += OPENAI_BATCH) {\n const batch = texts.slice(i, i + OPENAI_BATCH);\n const body = JSON.stringify({ model: this.model, input: batch });\n const { data } = await httpRequest<any>('https://api.openai.com/v1/embeddings', {\n host: 'api.openai.com',\n method: 'POST',\n ttlMs: 30 * 24 * 60 * 60 * 1000, // cache embeddings 30d to control cost\n cacheKey: `openai-embed ${this.model} ${createHash('sha256').update(body).digest('hex')}`,\n headers: { Authorization: `Bearer ${this.apiKey}`, 'Content-Type': 'application/json' },\n body,\n fetchImpl: this.fetchImpl,\n });\n const vectors: { embedding: number[]; index: number }[] = data?.data ?? [];\n vectors.sort((a, b) => a.index - b.index);\n for (const v of vectors) out.push(v.embedding);\n }\n return out;\n }\n}\n\n// ── Factory ─────────────────────────────────────────────────────────────────\n\nexport function createEmbeddingProvider(fetchImpl?: typeof fetch): EmbeddingProvider {\n const config = getConfig();\n if (config.EMBEDDING_PROVIDER === 'openai' && config.EMBEDDING_API_KEY) {\n return new OpenAIEmbeddingProvider(config.EMBEDDING_API_KEY, config.EMBEDDING_MODEL, fetchImpl);\n }\n if (config.EMBEDDING_PROVIDER === 'openai' && !config.EMBEDDING_API_KEY) {\n logger.warn('EMBEDDING_API_KEY not set — falling back to the local embedder.');\n }\n return new LocalEmbeddingProvider();\n}\n","/**\n * Read/write helpers for the `packages` table. All recommendation/eval reads use\n * this single denormalized table (§8.2).\n */\nimport { eq, sql } from 'drizzle-orm';\nimport type { Category } from '../core/types';\nimport type { Database } from './client';\nimport { packages, seedPackages, syncRuns, type NewPackageRow, type SyncError } from './schema';\n\nexport async function getSeedTargets(\n db: Database,\n): Promise<{ name: string; category: Category | null }[]> {\n const rows = await db\n .select({ name: seedPackages.name, category: seedPackages.category })\n .from(seedPackages);\n return rows.map((r) => ({ name: r.name, category: r.category ?? null }));\n}\n\nexport async function getPackageByName(db: Database, name: string) {\n const rows = await db.select().from(packages).where(eq(packages.name, name)).limit(1);\n return rows[0] ?? null;\n}\n\n/**\n * Promote a package into the curated seed list so future `sync` runs keep it\n * fresh. Used by the on-demand path (§12.5) to make organically-discovered\n * packages durable. No-op if already seeded — preserves the original category\n * and `added_at` rather than overwriting a hand-curated entry.\n */\nexport async function ensureSeedEntry(\n db: Database,\n name: string,\n category: Category | null,\n): Promise<void> {\n await db\n .insert(seedPackages)\n .values({ name, category })\n .onConflictDoNothing({ target: seedPackages.name });\n}\n\n/** Upsert a fully-computed package row, refreshing every field on conflict. */\nexport async function upsertPackage(db: Database, row: NewPackageRow): Promise<void> {\n const { name: _name, createdAt: _createdAt, ...mutable } = row;\n await db\n .insert(packages)\n .values(row)\n .onConflictDoUpdate({\n target: packages.name,\n set: { ...mutable, updatedAt: new Date() },\n });\n}\n\n// ── sync_runs audit ─────────────────────────────────────────────────────────\n\nexport async function startSyncRun(db: Database): Promise<number> {\n const [row] = await db\n .insert(syncRuns)\n .values({ status: 'running' })\n .returning({ id: syncRuns.id });\n return row!.id;\n}\n\nexport async function finishSyncRun(\n db: Database,\n id: number,\n data: {\n packagesSeen: number;\n packagesUpdated: number;\n errors: SyncError[];\n status: 'success' | 'partial' | 'failed';\n },\n): Promise<void> {\n await db\n .update(syncRuns)\n .set({\n finishedAt: new Date(),\n packagesSeen: data.packagesSeen,\n packagesUpdated: data.packagesUpdated,\n errors: data.errors,\n status: data.status,\n })\n .where(eq(syncRuns.id, id));\n}\n\n/** Count tracked packages — handy for CLI/diagnostics. */\nexport async function countPackages(db: Database): Promise<number> {\n const [row] = await db.select({ n: sql<number>`count(*)::int` }).from(packages);\n return row?.n ?? 0;\n}\n","/** Map over items with bounded concurrency, preserving input order. */\nexport async function pMap<T, R>(\n items: readonly T[],\n mapper: (item: T, index: number) => Promise<R>,\n concurrency: number,\n): Promise<R[]> {\n const results = new Array<R>(items.length);\n let cursor = 0;\n const workerCount = Math.max(1, Math.min(concurrency, items.length));\n const workers = Array.from({ length: workerCount }, async () => {\n while (cursor < items.length) {\n const index = cursor++;\n results[index] = await mapper(items[index]!, index);\n }\n });\n await Promise.all(workers);\n return results;\n}\n","/**\n * `lurq sync` pipeline (§9.7). End-to-end ingestion for the seed list (or one\n * package): collect signals → score → summarize → upsert, recording a sync_runs\n * row. Idempotent, concurrent, and tolerant of individual source failures (§17).\n *\n * Two-pass for efficiency (§10): pass 1 collects + scores everything that's\n * per-package; then category medians are computed; pass 2 finalizes efficiency\n * and the composite health score. Embeddings are added in M4.\n */\nimport { getConfig } from '../core/config';\nimport { pMap } from '../core/concurrency';\nimport { setCacheBypassRead } from '../core/http';\nimport { logger } from '../core/logger';\nimport type { Category, CategorySource, ScoreBreakdown } from '../core/types';\nimport { collectSignals } from '../ingestion/collect';\nimport { fetchBulkWeeklyDownloads } from '../ingestion/sources/npmDownloads';\nimport { buildSummaryInput, createSummaryProvider } from '../ingestion/summarize';\nimport { inferCategoryFromSignals } from '../search/categoryInference';\nimport { buildEmbeddingText, createEmbeddingProvider } from '../search/embeddings';\nimport type { RawPackageSignals } from '../ingestion/types';\nimport {\n computeAdoption,\n computeConfidence,\n computeEfficiency,\n computeHealthScore,\n computeMaintenance,\n computeQuality,\n computeReliability,\n median,\n toScoringInput,\n type ScoringInput,\n} from '../scoring';\nimport { createDb, type Database } from '../db/client';\nimport {\n finishSyncRun,\n getSeedTargets,\n startSyncRun,\n upsertPackage,\n} from '../db/packages';\nimport { isFrontendCategory } from '../core/types';\nimport type { NewPackageRow, SyncError } from '../db/schema';\n\nexport interface SyncOptions {\n full?: boolean;\n packageName?: string;\n}\n\nexport interface SyncSummary {\n seen: number;\n updated: number;\n errors: number;\n status: 'success' | 'partial' | 'failed';\n}\n\ninterface Target {\n name: string;\n category: Category | null;\n}\n\n/** Per-package state carried from pass 1 to pass 2. */\ninterface Computed {\n target: Target;\n /** Final resolved category (curated or inferred at ingest, §2A). */\n category: Category | null;\n categorySource: CategorySource | null;\n signals: RawPackageSignals;\n input: ScoringInput;\n maintenance: number;\n adoption: number;\n reliability: number;\n quality: number | null;\n confidence: ReturnType<typeof computeConfidence>;\n summary: string | null;\n usageGuide: NewPackageRow['usageGuide'];\n}\n\nexport async function runSync(opts: SyncOptions = {}): Promise<SyncSummary> {\n const config = getConfig();\n const now = new Date();\n if (opts.full) setCacheBypassRead(true);\n\n const handle = createDb({ max: Math.max(4, config.LURQ_SYNC_CONCURRENCY) });\n const provider = createSummaryProvider();\n logger.info(`Summary provider: ${provider.kind}`);\n\n const runId = await startSyncRun(handle.db);\n const allErrors: SyncError[] = [];\n\n try {\n const targets = await resolveTargets(handle.db, opts);\n logger.info(`Syncing ${targets.length} package(s) with concurrency ${config.LURQ_SYNC_CONCURRENCY}…`);\n\n // Bulk-fetch weekly downloads up front (one call per 128 packages) to avoid\n // the downloads API rate limit that per-package bursts trigger.\n logger.info('Fetching weekly downloads in bulk…');\n const weeklyMap = await fetchBulkWeeklyDownloads(targets.map((t) => t.name));\n\n // ── Pass 1: collect + per-package scoring + summary ──────────────────────\n let done = 0;\n const computed = await pMap(\n targets,\n async (target): Promise<Computed | null> => {\n try {\n const signals = await collectSignals(target.name, target.category, {\n githubToken: config.GITHUB_TOKEN,\n prefetchedWeekly: weeklyMap.has(target.name) ? weeklyMap.get(target.name)! : undefined,\n });\n for (const e of signals.errors) allErrors.push({ package: target.name, ...e });\n\n const summaryInput = await buildSummaryInput(signals, target.category);\n const { summary, usageGuide, inferredCategory } = await provider.generate(summaryInput);\n\n // Categorize-on-ingest (§2A): curated category wins; otherwise infer\n // from the package's own text, then fall back to the LLM classifier.\n let category = target.category;\n let categorySource: CategorySource | null = target.category ? 'curated' : null;\n if (!category) {\n category = inferCategoryFromSignals(signals) ?? inferredCategory ?? null;\n categorySource = category ? 'inferred' : null;\n }\n\n const input = toScoringInput(signals, category);\n const quality = computeQuality(input);\n if (++done % 25 === 0) logger.info(` …${done}/${targets.length}`);\n return {\n target,\n category,\n categorySource,\n signals,\n input,\n maintenance: computeMaintenance(input, now),\n adoption: computeAdoption(input),\n reliability: computeReliability(input),\n quality,\n confidence: computeConfidence(input, now, quality),\n summary,\n usageGuide,\n };\n } catch (err) {\n allErrors.push({\n package: target.name,\n source: 'pipeline',\n message: err instanceof Error ? err.message : String(err),\n });\n return null;\n }\n },\n config.LURQ_SYNC_CONCURRENCY,\n );\n\n const ok = computed.filter((c): c is Computed => c !== null);\n\n // ── Category medians for efficiency (§10) ────────────────────────────────\n const medians = computeCategoryMedians(ok);\n\n // ── Embeddings (§11): embed the normalized text blob for each package ─────\n const embProvider = createEmbeddingProvider();\n logger.info(`Embedding provider: ${embProvider.kind}`);\n const embeddings = await embProvider.embed(\n ok.map((c) =>\n buildEmbeddingText({\n name: c.target.name,\n category: c.category,\n summary: c.summary,\n description: c.signals.registry?.description ?? null,\n }),\n ),\n );\n\n // ── Pass 2: efficiency + composite + upsert ──────────────────────────────\n let updated = 0;\n for (let i = 0; i < ok.length; i++) {\n const c = ok[i]!;\n const efficiency = computeEfficiency(\n c.input.bundleMinGzipKb,\n c.category,\n c.category ? (medians.get(c.category) ?? null) : null,\n );\n const breakdown: ScoreBreakdown = {\n maintenance: c.maintenance,\n adoption: c.adoption,\n reliability: c.reliability,\n efficiency,\n quality: c.quality,\n };\n const healthScore = computeHealthScore(breakdown);\n await upsertPackage(\n handle.db,\n assemblePackageRow({\n name: c.target.name,\n category: c.category,\n categorySource: c.categorySource,\n signals: c.signals,\n input: c.input,\n summary: c.summary,\n usageGuide: c.usageGuide,\n confidence: c.confidence,\n breakdown,\n healthScore,\n qualityScore: c.quality,\n embedding: embeddings[i] ?? null,\n now,\n }),\n );\n updated++;\n }\n\n const status: SyncSummary['status'] =\n updated === 0 ? 'failed' : allErrors.length > 0 ? 'partial' : 'success';\n await finishSyncRun(handle.db, runId, {\n packagesSeen: targets.length,\n packagesUpdated: updated,\n errors: allErrors,\n status,\n });\n\n logger.info(`Sync ${status}: ${updated}/${targets.length} updated, ${allErrors.length} source errors.`);\n return { seen: targets.length, updated, errors: allErrors.length, status };\n } catch (err) {\n await finishSyncRun(handle.db, runId, {\n packagesSeen: 0,\n packagesUpdated: 0,\n errors: [{ package: '*', source: 'pipeline', message: (err as Error).message }],\n status: 'failed',\n });\n throw err;\n } finally {\n if (opts.full) setCacheBypassRead(false);\n await handle.close();\n }\n}\n\nasync function resolveTargets(db: Database, opts: SyncOptions): Promise<Target[]> {\n if (opts.packageName) {\n const seeds = await getSeedTargets(db);\n const found = seeds.find((s) => s.name === opts.packageName);\n return [{ name: opts.packageName, category: found?.category ?? null }];\n }\n return getSeedTargets(db);\n}\n\nfunction computeCategoryMedians(computed: Computed[]): Map<Category, number> {\n const byCategory = new Map<Category, number[]>();\n for (const c of computed) {\n const cat = c.category;\n const kb = c.input.bundleMinGzipKb;\n if (cat && isFrontendCategory(cat) && kb !== null) {\n const list = byCategory.get(cat) ?? [];\n list.push(kb);\n byCategory.set(cat, list);\n }\n }\n const medians = new Map<Category, number>();\n for (const [cat, list] of byCategory) {\n const m = median(list);\n if (m !== null) medians.set(cat, m);\n }\n return medians;\n}\n\n/** Assemble a fully-scored package row. Shared by the bulk sync and the\n * on-demand single-package path (§12.5). */\nexport function assemblePackageRow(p: {\n name: string;\n category: Category | null;\n categorySource: CategorySource | null;\n signals: RawPackageSignals;\n input: ScoringInput;\n summary: string | null;\n usageGuide: NewPackageRow['usageGuide'];\n confidence: NewPackageRow['confidence'];\n breakdown: ScoreBreakdown;\n healthScore: number;\n qualityScore: number | null;\n embedding: number[] | null;\n now: Date;\n}): NewPackageRow {\n const r = p.signals.registry;\n return {\n name: p.name,\n ecosystem: 'npm',\n category: p.category,\n categorySource: p.categorySource,\n description: r?.description ?? null,\n summary: p.summary,\n repoUrl: r?.repoUrl ?? null,\n homepage: r?.homepage ?? null,\n latestVersion: r?.latestVersion ?? null,\n license: r?.license ?? null,\n deprecated: p.input.deprecated,\n archived: p.input.archived,\n firstPublishedAt: p.input.firstPublishedAt,\n lastReleaseAt: p.input.lastReleaseAt,\n weeklyDownloads: p.input.weeklyDownloads,\n downloadGrowth90d: p.input.downloadGrowth90d,\n dependentsCount: p.input.dependentsCount,\n stars: p.input.stars,\n openIssues: p.input.openIssues,\n closedIssues: p.input.closedIssues,\n scorecard: p.input.scorecard,\n bundleMinGzipKb: p.input.bundleMinGzipKb,\n advisories: p.input.advisories,\n healthScore: p.healthScore,\n qualityScore: p.qualityScore,\n confidence: p.confidence,\n scoreBreakdown: p.breakdown,\n usageGuide: p.usageGuide,\n embedding: p.embedding,\n dataAsOf: p.now,\n };\n}\n","/**\n * Single-package ingestion + the on-demand path (§12.5). When a queried package\n * isn't tracked but exists on npm, lurq fetches, scores, embeds, stores, and\n * returns it — organically growing coverage beyond the seed list.\n */\nimport { and, eq, isNotNull, sql } from 'drizzle-orm';\nimport { getConfig } from '../core/config';\nimport type { Category, CategorySource, ScoreBreakdown } from '../core/types';\nimport { collectSignals } from '../ingestion/collect';\nimport { fetchWeeklyDownloads, npmPackageExists } from '../ingestion/sources';\nimport { buildSummaryInput, createSummaryProvider } from '../ingestion/summarize';\nimport { inferCategoryFromSignals } from '../search/categoryInference';\nimport {\n computeAdoption,\n computeConfidence,\n computeEfficiency,\n computeHealthScore,\n computeMaintenance,\n computeQuality,\n computeReliability,\n toScoringInput,\n} from '../scoring';\nimport { buildEmbeddingText, createEmbeddingProvider } from '../search/embeddings';\nimport type { Database } from '../db/client';\nimport { ensureSeedEntry, getPackageByName, upsertPackage } from '../db/packages';\nimport { packages, seedPackages, type PackageRow } from '../db/schema';\nimport { assemblePackageRow } from './sync';\n\nasync function getSeedCategory(db: Database, name: string): Promise<Category | null> {\n const [row] = await db\n .select({ category: seedPackages.category })\n .from(seedPackages)\n .where(eq(seedPackages.name, name))\n .limit(1);\n return row?.category ?? null;\n}\n\n/** Median bundle size across already-tracked packages in a category (for efficiency). */\nasync function getCategoryMedianBundle(db: Database, category: Category): Promise<number | null> {\n const [row] = await db\n .select({\n m: sql<number | null>`percentile_cont(0.5) within group (order by ${packages.bundleMinGzipKb})`,\n })\n .from(packages)\n .where(and(eq(packages.category, category), isNotNull(packages.bundleMinGzipKb)));\n return row?.m ?? null;\n}\n\n/** Fetch, score, embed, and upsert a single package; returns the stored row. */\nexport async function syncOnePackage(\n db: Database,\n name: string,\n opts: { category?: Category | null } = {},\n): Promise<PackageRow> {\n const config = getConfig();\n const now = new Date();\n\n const existing = await getPackageByName(db, name);\n // The curated category (from a manual arg or the seed list) wins. We resolve\n // the final category *after* ingest so a discovered package can be classified\n // from its own text rather than stored as a second-class `null` (§2A).\n const curatedCategory = opts.category ?? (await getSeedCategory(db, name)) ?? null;\n const initialCategory = curatedCategory ?? existing?.category ?? null;\n\n const prefetchedWeekly = await fetchWeeklyDownloads(name).catch(() => null);\n const signals = await collectSignals(name, initialCategory, {\n githubToken: config.GITHUB_TOKEN,\n prefetchedWeekly,\n });\n\n const summaryInput = await buildSummaryInput(signals, initialCategory);\n const { summary, usageGuide, inferredCategory } =\n await createSummaryProvider().generate(summaryInput);\n\n let category: Category | null;\n let categorySource: CategorySource | null;\n if (curatedCategory) {\n category = curatedCategory;\n categorySource = 'curated';\n } else if (existing?.category) {\n category = existing.category;\n categorySource = existing.categorySource ?? 'inferred';\n } else {\n category = inferCategoryFromSignals(signals) ?? inferredCategory ?? null;\n categorySource = category ? 'inferred' : null;\n }\n\n const input = toScoringInput(signals, category);\n\n const median = category ? await getCategoryMedianBundle(db, category) : null;\n const quality = computeQuality(input);\n const breakdown: ScoreBreakdown = {\n maintenance: computeMaintenance(input, now),\n adoption: computeAdoption(input),\n reliability: computeReliability(input),\n efficiency: computeEfficiency(input.bundleMinGzipKb, category, median),\n quality,\n };\n const healthScore = computeHealthScore(breakdown);\n const confidence = computeConfidence(input, now, quality);\n\n const [embedding] = await createEmbeddingProvider().embed([\n buildEmbeddingText({ name, category, summary, description: signals.registry?.description ?? null }),\n ]);\n\n await upsertPackage(\n db,\n assemblePackageRow({\n name,\n category,\n categorySource,\n signals,\n input,\n summary,\n usageGuide,\n confidence,\n breakdown,\n healthScore,\n qualityScore: quality,\n embedding: embedding ?? null,\n now,\n }),\n );\n return (await getPackageByName(db, name))!;\n}\n\nexport interface GetOrFetchResult {\n row: PackageRow | null;\n /** True if the package was already in the index before this call. */\n wasTracked: boolean;\n existsOnNpm: boolean;\n}\n\n/**\n * Return a tracked package, or fetch+store it on demand if it's a real npm\n * package not yet in the index (§12.5). Returns row=null when it doesn't exist.\n */\nexport async function getOrFetchPackage(db: Database, name: string): Promise<GetOrFetchResult> {\n const existing = await getPackageByName(db, name);\n if (existing) return { row: existing, wasTracked: true, existsOnNpm: true };\n\n const exists = await npmPackageExists(name);\n if (!exists) return { row: null, wasTracked: false, existsOnNpm: false };\n\n const row = await syncOnePackage(db, name);\n // Persist the discovery into the seed list so future syncs keep it fresh.\n await ensureSeedEntry(db, name, row.category);\n return { row, wasTracked: false, existsOnNpm: true };\n}\n","/**\n * Hybrid recommendation (§3, §11). Two retrievals run over the same candidate\n * table — vector cosine (semantic) and `tsvector` lexical (exact name/keyword) —\n * fused with Reciprocal Rank Fusion (RRF), then re-ranked by a blend of fused\n * relevance and the quality-aware composite (§1). Pure vector search misses\n * exact-name hits (especially the keyless local embedder); the lexical leg fixes\n * that, and RRF avoids having to normalize two incomparable score scales.\n */\nimport { and, cosineDistance, eq, isNotNull, lte, sql } from 'drizzle-orm';\nimport type { Candidate, Category, Confidence, Runtime } from '../core/types';\nimport type { Database } from '../db/client';\nimport { packages } from '../db/schema';\nimport { computeComposite } from '../scoring';\nimport { loadWeights } from '../scoring/weights';\nimport { inferCategory } from './categoryInference';\nimport { createEmbeddingProvider, type EmbeddingProvider } from './embeddings';\n\nexport interface RecommendConstraints {\n runtime?: Runtime;\n license?: string;\n maxBundleKb?: number;\n minConfidence?: Confidence;\n}\n\nexport interface RecommendOptions {\n need: string;\n category?: Category;\n constraints?: RecommendConstraints;\n limit?: number;\n}\n\nconst CONFIDENCE_RANK: Record<Confidence, number> = {\n unproven: 0,\n promising: 1,\n emerging: 2,\n proven: 3,\n};\n/** Fused-relevance vs composite blend (§3, §11). The second term is the\n * quality-aware composite (§1), not raw health — so a well-built package isn't\n * buried by a popularity-tilted score. */\nconst RELEVANCE_WEIGHT = 0.6;\nconst COMPOSITE_WEIGHT = 0.4;\n/** RRF damping constant — standard value from the original RRF paper (§3). */\nconst RRF_K = 60;\n\ninterface Row {\n name: string;\n category: Category | null;\n healthScore: number | null;\n qualityScore: number | null;\n confidence: Confidence | null;\n latestVersion: string | null;\n weeklyDownloads: number | null;\n lastReleaseAt: Date | null;\n repoUrl: string | null;\n}\n\nexport async function recommend(\n db: Database,\n opts: RecommendOptions,\n provider: EmbeddingProvider = createEmbeddingProvider(),\n): Promise<Candidate[]> {\n const limit = Math.min(Math.max(opts.limit ?? 3, 1), 5);\n const [queryVec] = await provider.embed([opts.need]);\n if (!queryVec) return [];\n\n const category = opts.category ?? inferCategory(opts.need);\n const pool = Math.max(limit * 5, 25);\n\n // Primary search (category-filtered when we have one).\n let fused = await hybridSearch(db, queryVec, opts.need, opts.constraints, category, pool);\n // If a category filter starved the results, broaden to all categories.\n if (category && fused.length < limit) {\n const broad = await hybridSearch(db, queryVec, opts.need, opts.constraints, null, pool);\n const seen = new Set(fused.map((f) => f.row.name));\n fused = fused.concat(broad.filter((f) => !seen.has(f.row.name)));\n }\n if (fused.length === 0) return [];\n\n // Re-rank: blend normalized fused relevance (RRF) with the quality-aware\n // composite (§1). RRF rank-fusion already absorbs both retrieval legs, so the\n // relevance term rewards exact lexical hits the vector leg alone would miss.\n const lambda = loadWeights().composite.lambda;\n const maxRrf = Math.max(...fused.map((f) => f.rrf));\n const ranked = fused\n .map((f) => {\n const relevance = maxRrf > 0 ? f.rrf / maxRrf : 0;\n const composite = computeComposite(f.row.healthScore ?? 0, f.row.qualityScore, lambda) / 100;\n return { row: f.row, score: RELEVANCE_WEIGHT * relevance + COMPOSITE_WEIGHT * composite };\n })\n .sort((a, b) => b.score - a.score)\n .slice(0, limit);\n\n return ranked.map(({ row }) => toCandidate(row));\n}\n\ninterface Fused {\n row: Row;\n rrf: number;\n}\n\n/**\n * Run the vector and lexical retrievals and fuse them with RRF (§3). Each leg\n * independently ranks the candidate set; a doc's fused score is the sum of\n * 1/(k+rank) across the legs it appears in — so documents both legs agree on\n * rise, and exact-name hits the vector leg ranks poorly still surface.\n */\nasync function hybridSearch(\n db: Database,\n queryVec: number[],\n need: string,\n constraints: RecommendConstraints | undefined,\n category: Category | null,\n pool: number,\n): Promise<Fused[]> {\n const [vectorRows, lexicalRows] = await Promise.all([\n runVectorQuery(db, queryVec, constraints, category, pool),\n runLexicalQuery(db, need, constraints, category, pool),\n ]);\n return rrfFuse([vectorRows, lexicalRows]);\n}\n\n/**\n * Reciprocal Rank Fusion over N ranked lists (§3). A document's fused score is\n * Σ 1/(k + rank) across the lists it appears in — using only ranks, never raw\n * scores, so two incomparable scales (cosine distance vs ts_rank) never need\n * normalizing. Generic over `{ name }` so the fusion math is unit-testable.\n */\nexport function rrfFuse<T extends { name: string }>(\n lists: T[][],\n k = RRF_K,\n): { row: T; rrf: number }[] {\n const fused = new Map<string, { row: T; rrf: number }>();\n for (const list of lists) {\n list.forEach((row, idx) => {\n const contribution = 1 / (k + idx + 1); // rank is 1-based\n const prev = fused.get(row.name);\n if (prev) prev.rrf += contribution;\n else fused.set(row.name, { row, rrf: contribution });\n });\n }\n return [...fused.values()].sort((a, b) => b.rrf - a.rrf);\n}\n\nconst ROW_COLUMNS = {\n name: packages.name,\n category: packages.category,\n healthScore: packages.healthScore,\n qualityScore: packages.qualityScore,\n confidence: packages.confidence,\n latestVersion: packages.latestVersion,\n weeklyDownloads: packages.weeklyDownloads,\n lastReleaseAt: packages.lastReleaseAt,\n repoUrl: packages.repoUrl,\n} as const;\n\n/** Shared filter conditions (category + constraints) for both retrieval legs. */\nfunction buildConditions(\n constraints: RecommendConstraints | undefined,\n category: Category | null,\n) {\n const conditions = [];\n if (category) conditions.push(eq(packages.category, category));\n if (constraints?.license) conditions.push(eq(packages.license, constraints.license));\n if (constraints?.maxBundleKb !== undefined) {\n conditions.push(lte(packages.bundleMinGzipKb, constraints.maxBundleKb));\n }\n if (constraints?.minConfidence) {\n const allowed = (['proven', 'emerging', 'promising', 'unproven'] as Confidence[]).filter(\n (c) => CONFIDENCE_RANK[c] >= CONFIDENCE_RANK[constraints.minConfidence!],\n );\n conditions.push(\n sql`${packages.confidence} in ${sql.raw(`(${allowed.map((c) => `'${c}'`).join(',')})`)}`,\n );\n }\n return conditions;\n}\n\n/** Semantic leg: pgvector cosine, ordered by ascending distance. */\nasync function runVectorQuery(\n db: Database,\n queryVec: number[],\n constraints: RecommendConstraints | undefined,\n category: Category | null,\n pool: number,\n): Promise<Row[]> {\n const distance = cosineDistance(packages.embedding, queryVec);\n const conditions = [isNotNull(packages.embedding), ...buildConditions(constraints, category)];\n return db\n .select(ROW_COLUMNS)\n .from(packages)\n .where(and(...conditions))\n .orderBy(distance)\n .limit(pool);\n}\n\n/** Lexical leg: full-text `tsvector` match, ranked by `ts_rank` (§3). */\nasync function runLexicalQuery(\n db: Database,\n need: string,\n constraints: RecommendConstraints | undefined,\n category: Category | null,\n pool: number,\n): Promise<Row[]> {\n const tsquery = sql`websearch_to_tsquery('english', ${need})`;\n const rank = sql<number>`ts_rank(${packages.searchVector}, ${tsquery})`;\n const conditions = [sql`${packages.searchVector} @@ ${tsquery}`, ...buildConditions(constraints, category)];\n return db\n .select(ROW_COLUMNS)\n .from(packages)\n .where(and(...conditions))\n .orderBy(sql`${rank} desc`)\n .limit(pool);\n}\n\nfunction toCandidate(row: Row): Candidate {\n return {\n name: row.name,\n category: row.category,\n healthScore: row.healthScore ?? 0,\n qualityScore: row.qualityScore,\n confidence: row.confidence ?? 'unproven',\n why: buildWhy(row),\n latestVersion: row.latestVersion,\n weeklyDownloads: row.weeklyDownloads,\n lastReleaseAt: row.lastReleaseAt ? row.lastReleaseAt.toISOString() : null,\n repoUrl: row.repoUrl,\n };\n}\n\n/** A ≤1-sentence rationale (§12.3.1). */\nfunction buildWhy(row: Row): string {\n const parts: string[] = [];\n if (row.confidence) parts.push(row.confidence);\n if (row.weeklyDownloads) parts.push(`${formatDownloads(row.weeklyDownloads)} weekly downloads`);\n if (row.healthScore !== null) parts.push(`health ${row.healthScore}`);\n return parts.join(', ') || 'tracked package';\n}\n\nfunction formatDownloads(n: number): string {\n if (n >= 1_000_000) return `${Math.round(n / 100_000) / 10}M`;\n if (n >= 1_000) return `${Math.round(n / 1_000)}k`;\n return String(n);\n}\n","/**\n * MCP tool handlers (§12.3). Pure functions over a Database — the transport\n * layer (server.ts) just wires zod schemas to these. Responses are kept compact\n * (§12.4): summaries truncated, advisories capped, no raw payloads, always a\n * `dataAsOf` and a `stale` hint when data is old (§17).\n */\nimport { sql } from 'drizzle-orm';\nimport { STALENESS_DAYS } from '../core/constants';\nimport type {\n Advisory,\n AdvisorySeverity,\n Category,\n Confidence,\n EvaluateOutput,\n VerifyOutput,\n} from '../core/types';\nimport type { Database } from '../db/client';\nimport { packages, type PackageRow } from '../db/schema';\nimport { fetchNpmRegistry, npmPackageExists } from '../ingestion/sources';\nimport { truncateSentences } from '../ingestion/summarize';\nimport { getOrFetchPackage } from '../pipeline/single';\nimport { recommend, type RecommendOptions } from '../search/recommend';\n\nconst SEVERITY_RANK: Record<AdvisorySeverity, number> = {\n critical: 4,\n high: 3,\n moderate: 2,\n low: 1,\n info: 0,\n};\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nfunction isStale(dataAsOf: Date | null): boolean {\n if (!dataAsOf) return true;\n return Date.now() - dataAsOf.getTime() > STALENESS_DAYS * DAY_MS;\n}\n\nfunction withinDays(date: Date | null, days: number): boolean {\n return date ? Date.now() - date.getTime() <= days * DAY_MS : false;\n}\n\n/** Top advisories by severity, capped (§12.4). */\nfunction topAdvisories(advisories: Advisory[] | null, max = 5): Advisory[] {\n if (!advisories?.length) return [];\n return [...advisories]\n .sort((a, b) => SEVERITY_RANK[b.severity] - SEVERITY_RANK[a.severity])\n .slice(0, max);\n}\n\n/** Map a stored row to the compact EvaluateOutput shape (§12.3.2). */\nexport function rowToEvaluate(row: PackageRow): EvaluateOutput {\n const breakdown = row.scoreBreakdown ?? {\n maintenance: 0,\n adoption: 0,\n reliability: 0,\n efficiency: null,\n quality: null,\n };\n return {\n dataAsOf: (row.dataAsOf ?? new Date()).toISOString(),\n stale: isStale(row.dataAsOf) || undefined,\n name: row.name,\n category: row.category,\n healthScore: row.healthScore ?? 0,\n qualityScore: row.qualityScore ?? null,\n confidence: (row.confidence as Confidence) ?? 'unproven',\n scoreBreakdown: breakdown,\n latestVersion: row.latestVersion,\n lastReleaseAt: row.lastReleaseAt ? row.lastReleaseAt.toISOString() : null,\n weeklyDownloads: row.weeklyDownloads,\n downloadGrowth90d: row.downloadGrowth90d,\n dependentsCount: row.dependentsCount,\n scorecard: row.scorecard,\n bundleMinGzipKb: row.bundleMinGzipKb,\n deprecated: row.deprecated,\n archived: row.archived,\n advisories: topAdvisories(row.advisories),\n summary: row.summary ? truncateSentences(row.summary, 3) : null,\n usageGuide: row.usageGuide ?? null,\n repoUrl: row.repoUrl,\n };\n}\n\nasync function latestDataAsOf(db: Database): Promise<string> {\n const [row] = await db\n .select({ m: sql<string | null>`max(${packages.dataAsOf})` })\n .from(packages);\n return new Date(row?.m ?? Date.now()).toISOString();\n}\n\n// ── recommend ───────────────────────────────────────────────────────────────\n\nexport interface RecommendInput {\n need: string;\n category?: Category;\n constraints?: RecommendOptions['constraints'];\n}\n\nexport async function handleRecommend(db: Database, input: RecommendInput) {\n const candidates = await recommend(db, {\n need: input.need,\n category: input.category,\n constraints: input.constraints,\n limit: 5,\n });\n return { dataAsOf: await latestDataAsOf(db), candidates };\n}\n\n// ── evaluate ────────────────────────────────────────────────────────────────\n\nexport async function handleEvaluate(\n db: Database,\n input: { package: string },\n): Promise<EvaluateOutput | { tracked: false; suggestion: string }> {\n const { row, existsOnNpm } = await getOrFetchPackage(db, input.package);\n if (!row) {\n return {\n tracked: false,\n suggestion: existsOnNpm\n ? `\"${input.package}\" exists on npm but could not be scored right now; try again.`\n : `\"${input.package}\" was not found on the npm registry. Check the package name.`,\n };\n }\n return rowToEvaluate(row);\n}\n\n// ── compare ─────────────────────────────────────────────────────────────────\n\nexport async function handleCompare(db: Database, input: { packages: string[] }) {\n const results = await Promise.all(input.packages.map((name) => getOrFetchPackage(db, name)));\n const rows = results\n .map((r) => r.row)\n .filter((row): row is PackageRow => row !== null)\n .map(rowToEvaluate)\n .sort((a, b) => b.healthScore - a.healthScore);\n const missing = input.packages.filter(\n (name) => !rows.some((r) => r.name === name),\n );\n return { dataAsOf: await latestDataAsOf(db), rows, ...(missing.length ? { missing } : {}) };\n}\n\n// ── verify ──────────────────────────────────────────────────────────────────\n\nexport async function handleVerify(\n db: Database,\n input: { package: string },\n): Promise<VerifyOutput> {\n const name = input.package;\n const exists = await npmPackageExists(name);\n if (!exists) {\n return {\n exists: false,\n tracked: false,\n deprecated: false,\n archived: false,\n latestVersion: null,\n weeklyDownloads: null,\n riskFlags: ['not-found-on-registry'],\n confidence: null,\n advisoryCount: 0,\n };\n }\n\n const registry = await fetchNpmRegistry(name).catch(() => null);\n const { row, wasTracked } = await getOrFetchPackage(db, name);\n\n const weeklyDownloads = row?.weeklyDownloads ?? null;\n const advisoryCount = row?.advisories?.length ?? 0;\n const deprecated = Boolean(row?.deprecated || registry?.deprecated);\n const archived = Boolean(row?.archived);\n\n const riskFlags: string[] = [];\n if (weeklyDownloads === null || weeklyDownloads === 0) riskFlags.push('zero-downloads');\n else if (weeklyDownloads < 1000) riskFlags.push('low-downloads');\n if (withinDays(registry?.firstPublishedAt ?? null, 7)) riskFlags.push('published-within-7-days');\n if (registry?.maintainersCount === 1) riskFlags.push('single-maintainer');\n if (advisoryCount > 0) riskFlags.push('has-known-advisory');\n if (deprecated) riskFlags.push('deprecated');\n if (archived) riskFlags.push('archived');\n\n return {\n exists: true,\n tracked: wasTracked,\n deprecated,\n archived,\n latestVersion: registry?.latestVersion ?? row?.latestVersion ?? null,\n weeklyDownloads,\n riskFlags,\n confidence: (row?.confidence as Confidence) ?? null,\n advisoryCount,\n };\n}\n","/**\n * Optional `diagram` tool (§12.3.5). Emits a reference-architecture Mermaid\n * diagram for a stack the caller has *already chosen* (package names), using\n * built-in layer patterns. Input is stack-only by design: inferring an\n * architecture from a freeform description is the \"architecture oracle\" behavior\n * that the master spec (§4) and roadmap (§1) declare a non-goal. lurq labels a\n * stack you name; it does not design one. A starting point, not a validator.\n *\n * Honesty over completeness:\n * - A package we can't classify (not in the index AND no category match) is\n * placed in an explicit `Unclassified` bucket — never silently dropped into a\n * default layer. The note lists what couldn't be placed. Partial, not\n * authoritative.\n * - KNOWN LIMITATION — front/back framework ambiguity: the taxonomy has a single\n * `framework` category, so a `framework` package can't be told apart as\n * frontend vs backend from its category alone. BACKEND_FRAMEWORKS is a\n * hand-maintained band-aid that re-routes the common backend frameworks to the\n * Backend layer; it degrades as the ecosystem adds new ones (an unlisted\n * backend framework will be drawn in Presentation). The real fix is a taxonomy\n * change (a distinct backend-framework category or a runtime/target flag on\n * packages), which is out of scope for v1. Documented, not solved.\n */\nimport { inArray } from 'drizzle-orm';\nimport type { Category } from '../core/types';\nimport { inferCategory } from '../search/categoryInference';\nimport type { Database } from '../db/client';\nimport { packages } from '../db/schema';\n\n/** Bucket for packages we cannot place: unknown category, or a category with no\n * real architectural home (e.g. `other`). Rendered, but kept out of the flow. */\nconst UNCLASSIFIED = 'Unclassified';\n\n/** Which architectural layer each category sits in. Categories with no honest\n * architectural home (e.g. `other`) are intentionally absent: layerFor routes\n * anything unmapped to UNCLASSIFIED rather than faking a layer. */\nconst LAYER_OF: Partial<Record<Category, string>> = {\n framework: 'Presentation',\n 'meta-framework': 'Presentation',\n 'ui-component-library': 'Presentation',\n styling: 'Presentation',\n animation: 'Presentation',\n charts: 'Presentation',\n 'state-management': 'Client Logic',\n routing: 'Client Logic',\n forms: 'Client Logic',\n validation: 'Client Logic',\n 'data-fetching': 'Client Logic',\n 'http-client': 'Client Logic',\n i18n: 'Client Logic',\n 'date-time': 'Client Logic',\n utility: 'Client Logic',\n auth: 'Backend',\n orm: 'Data',\n 'database-client': 'Data',\n 'build-tool': 'Tooling',\n bundler: 'Tooling',\n linting: 'Tooling',\n testing: 'Tooling',\n};\n\nconst FLOW_LAYERS = ['Presentation', 'Client Logic', 'Backend', 'Data'];\n\n/** Band-aid for the front/back framework ambiguity (see file header). Category\n * `framework` alone can't distinguish frontend from backend, so these common\n * backend frameworks are re-routed to the Backend layer. Hand-maintained;\n * unlisted backend frameworks will be mis-drawn in Presentation. Not a real fix. */\nconst BACKEND_FRAMEWORKS = new Set([\n 'express',\n 'fastify',\n 'koa',\n 'hono',\n '@nestjs/core',\n '@hapi/hapi',\n]);\n\ninterface Item {\n label: string;\n /** null = could not be classified (not in index, no category match). */\n category: Category | null;\n}\n\nfunction layerFor(item: Item): string {\n if (!item.category) return UNCLASSIFIED;\n if (item.category === 'framework' && BACKEND_FRAMEWORKS.has(item.label)) return 'Backend';\n return LAYER_OF[item.category] ?? UNCLASSIFIED;\n}\n\nfunction nodeId(label: string, i: number): string {\n return `n${i}_${label.replace(/[^a-zA-Z0-9]/g, '_')}`;\n}\n\nexport function buildMermaid(items: Item[]): string {\n const byLayer = new Map<string, Item[]>();\n for (const item of items) {\n const layer = layerFor(item);\n const list = byLayer.get(layer) ?? [];\n list.push(item);\n byLayer.set(layer, list);\n }\n\n const lines = ['flowchart TD', ' user([User])'];\n const ids = new Map<string, string>(); // label → node id\n let counter = 0;\n const repNode = new Map<string, string>(); // layer → first node id\n\n const emitLayer = (layer: string) => {\n const list = byLayer.get(layer);\n if (!list?.length) return;\n lines.push(` subgraph ${layer.replace(/\\s+/g, '_')}[\"${layer}\"]`);\n for (const item of list) {\n const id = nodeId(item.label, counter++);\n ids.set(item.label, id);\n if (!repNode.has(layer)) repNode.set(layer, id);\n // Unclassified nodes carry no category prefix — we don't claim one we lack.\n const text = layer === UNCLASSIFIED ? item.label : `${item.category}: ${item.label}`;\n lines.push(` ${id}[\"${text}\"]`);\n }\n lines.push(' end');\n };\n\n for (const layer of FLOW_LAYERS) emitLayer(layer);\n emitLayer('Tooling');\n emitLayer(UNCLASSIFIED);\n\n // Connect the flow layers that are present, top to bottom.\n const present = FLOW_LAYERS.filter((l) => byLayer.has(l));\n let prev = 'user';\n for (const layer of present) {\n lines.push(` ${prev} --> ${repNode.get(layer)}`);\n prev = repNode.get(layer)!;\n }\n if (byLayer.has('Data')) lines.push(` ${repNode.get('Data')} --> db[(Database)]`);\n\n return lines.join('\\n');\n}\n\nexport interface DiagramInput {\n stack?: string[];\n}\n\nexport async function handleDiagram(\n db: Database,\n input: DiagramInput,\n): Promise<{ mermaid: string; note: string }> {\n if (!input.stack?.length) {\n return {\n mermaid: 'flowchart TD\\n user([User]) --> app[Application]',\n note: 'Provide a `stack` of package names to diagram. lurq labels a stack you choose; it does not infer an architecture from a description.',\n };\n }\n\n const rows = await db\n .select({ name: packages.name, category: packages.category })\n .from(packages)\n .where(inArray(packages.name, input.stack));\n const known = new Map(rows.map((r) => [r.name, r.category]));\n // inferCategory is best-effort on a bare package name (it was built for NL\n // needs); a miss yields null, not a faked category. No silent 'other'.\n const items: Item[] = input.stack.map((name) => ({\n label: name,\n category: known.get(name) ?? inferCategory(name),\n }));\n\n const unclassified = items.filter((i) => layerFor(i) === UNCLASSIFIED).map((i) => i.label);\n const note = unclassified.length\n ? `Reference pattern derived from the provided stack — partial, not authoritative. Could not place ${unclassified.length} package(s): ${unclassified.join(', ')} (not in lurq's index and no category match) — shown under Unclassified, outside the flow.`\n : 'Reference pattern derived from the provided stack. A labeled starting point, not a validated architecture.';\n\n return { mermaid: buildMermaid(items), note };\n}\n","/**\n * MCP server (§12). Exposes recommend / evaluate / compare / verify over stdio.\n * Inputs are validated with zod; outputs are compact JSON text (§12.4).\n */\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\nimport { SERVER_NAME, VERSION } from '../core/constants';\nimport { CATEGORIES, type Category } from '../core/types';\nimport { createDb } from '../db/client';\nimport { logger } from '../core/logger';\nimport { handleCompare, handleEvaluate, handleRecommend, handleVerify } from './handlers';\nimport { handleDiagram } from './diagram';\n\nconst categoryEnum = z.enum(CATEGORIES as unknown as [Category, ...Category[]]);\nconst confidenceEnum = z.enum(['proven', 'emerging', 'promising', 'unproven']);\n\nconst constraintsSchema = z\n .object({\n runtime: z.enum(['browser', 'node', 'both']).optional(),\n license: z.string().optional(),\n maxBundleKb: z.number().positive().optional(),\n minConfidence: confidenceEnum.optional(),\n })\n .optional();\n\n/** Wrap any result object as a compact MCP text response. */\nfunction json(obj: unknown) {\n return { content: [{ type: 'text' as const, text: JSON.stringify(obj) }] };\n}\n\nexport function buildMcpServer(db: ReturnType<typeof createDb>['db']): McpServer {\n const server = new McpServer({ name: SERVER_NAME, version: VERSION });\n\n server.registerTool(\n 'recommend',\n {\n title: 'Recommend packages',\n description:\n 'Recommend the best current npm packages for a described need — fresh, objectively scored, with confidence labels. Call before choosing or hand-rolling a dependency.',\n inputSchema: {\n need: z.string().min(1).describe('Natural-language description of what you need'),\n category: categoryEnum.optional().describe('Optional taxonomy category to restrict to'),\n constraints: constraintsSchema,\n },\n },\n async (args) => json(await handleRecommend(db, args)),\n );\n\n server.registerTool(\n 'evaluate',\n {\n title: 'Evaluate a package',\n description:\n 'Full evidence read for one npm package: scores, signals, advisories, summary, and a usage guide. Fetches & scores on demand if not yet tracked.',\n inputSchema: {\n package: z.string().min(1).describe('npm package name'),\n },\n },\n async (args) => json(await handleEvaluate(db, args)),\n );\n\n server.registerTool(\n 'compare',\n {\n title: 'Compare packages',\n description: 'Side-by-side comparison of 2–5 npm packages, ranked by health score.',\n inputSchema: {\n packages: z.array(z.string().min(1)).min(2).max(5).describe('2–5 npm package names'),\n },\n },\n async (args) => json(await handleCompare(db, args)),\n );\n\n server.registerTool(\n 'verify',\n {\n title: 'Verify a package',\n description:\n 'Confirm an npm package is real, healthy, and not risky before installing — guards against hallucinated or typosquatted dependency names. Checks the live registry.',\n inputSchema: {\n package: z.string().min(1).describe('npm package name to verify'),\n },\n },\n async (args) => json(await handleVerify(db, args)),\n );\n\n server.registerTool(\n 'diagram',\n {\n title: 'Reference architecture diagram',\n description:\n 'Emit a reference-architecture Mermaid diagram for a stack you have already chosen (package names). A labeled starting point keyed by layer — not a validated architecture, and not an architecture designer.',\n inputSchema: {\n stack: z\n .array(z.string())\n .optional()\n .describe('Package names that make up the stack; omit or empty to get usage guidance'),\n },\n },\n async (args) => json(await handleDiagram(db, args)),\n );\n\n return server;\n}\n\nexport async function startMcpServer(): Promise<void> {\n const { db, close } = createDb();\n const server = buildMcpServer(db);\n\n const shutdown = async () => {\n try {\n await close();\n } finally {\n process.exit(0);\n }\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n logger.info(`${SERVER_NAME} MCP server v${VERSION} running on stdio.`);\n}\n","/**\n * API-key generation, hashing, and lifecycle for the hosted HTTP service\n * (docs/lurq-hosted-deployment.md §5). Keys are high-entropy random strings; only\n * their sha256 hash is persisted, so a DB leak never exposes a usable key. The\n * plaintext is returned exactly once (at creation) and never stored or logged.\n */\nimport { createHash, randomBytes } from 'node:crypto';\nimport { and, desc, eq, isNull } from 'drizzle-orm';\nimport { API_KEY_PREFIX } from '../core/constants';\nimport type { Database } from '../db/client';\nimport { apiKeys, type ApiKeyRow } from '../db/schema';\n\n/** Chars of the random body kept in the display prefix (`lurq_live_<6>`). */\nconst DISPLAY_BODY = 6;\n\n/** sha256 hex of a key — the only form ever persisted or compared. */\nexport function hashKey(key: string): string {\n return createHash('sha256').update(key).digest('hex');\n}\n\nexport interface GeneratedKey {\n /** The full plaintext key — show once, never store. */\n key: string;\n /** sha256 hash to persist. */\n hash: string;\n /** Identifiable, safe-to-display prefix. */\n prefix: string;\n}\n\nexport function generateApiKey(): GeneratedKey {\n // 24 random bytes → 32-char base64url body: unbiased, URL/header-safe.\n const body = randomBytes(24).toString('base64url');\n const key = API_KEY_PREFIX + body;\n return { key, hash: hashKey(key), prefix: API_KEY_PREFIX + body.slice(0, DISPLAY_BODY) };\n}\n\nexport interface CreateKeyInput {\n label?: string;\n tier?: string;\n ownerId?: string;\n}\n\n/** Create and persist a key. Returns the plaintext ONCE plus the stored row. */\nexport async function createKey(\n db: Database,\n input: CreateKeyInput = {},\n): Promise<{ key: string; row: ApiKeyRow }> {\n const { key, hash, prefix } = generateApiKey();\n const [row] = await db\n .insert(apiKeys)\n .values({\n keyHash: hash,\n prefix,\n label: input.label,\n tier: input.tier ?? 'free',\n ownerId: input.ownerId,\n })\n .returning();\n return { key, row: row! };\n}\n\n/**\n * Look up an active (non-revoked) key by its plaintext form. Returns null if the\n * key is unknown or revoked. Stamps `lastUsedAt` best-effort without blocking.\n */\nexport async function lookupActiveKey(db: Database, key: string): Promise<ApiKeyRow | null> {\n const hash = hashKey(key);\n const [row] = await db\n .select()\n .from(apiKeys)\n .where(and(eq(apiKeys.keyHash, hash), isNull(apiKeys.revokedAt)))\n .limit(1);\n if (!row) return null;\n // Fire-and-forget usage stamp; failures must never affect the request.\n db.update(apiKeys)\n .set({ lastUsedAt: new Date() })\n .where(eq(apiKeys.id, row.id))\n .then(undefined, () => {});\n return row;\n}\n\nexport async function listKeys(db: Database): Promise<ApiKeyRow[]> {\n return db.select().from(apiKeys).orderBy(desc(apiKeys.createdAt));\n}\n\n/**\n * Revoke a key by display prefix or numeric id. Returns how many active keys were\n * revoked (0 if none matched or it was already revoked).\n */\nexport async function revokeKey(db: Database, prefixOrId: string): Promise<number> {\n const asId = Number(prefixOrId);\n const match =\n Number.isInteger(asId) && String(asId) === prefixOrId.trim()\n ? eq(apiKeys.id, asId)\n : eq(apiKeys.prefix, prefixOrId);\n const rows = await db\n .update(apiKeys)\n .set({ revokedAt: new Date() })\n .where(and(match, isNull(apiKeys.revokedAt)))\n .returning({ id: apiKeys.id });\n return rows.length;\n}\n","/**\n * Hosted HTTP transport for the MCP server (docs/lurq-hosted-deployment.md §4–5).\n *\n * Stateless Streamable HTTP: one shared DB pool created at startup, a fresh MCP\n * server+transport per request, fronted by helmet + rate limiting + API-key auth.\n * The DB credentials stay server-side; users connect with only a URL + Bearer key.\n * `buildMcpServer` is reused verbatim from the stdio path — the tools are\n * transport-agnostic.\n *\n * express/helmet/express-rate-limit are imported dynamically so the CLI and the\n * install wizard never pull server-only deps into their startup path.\n */\nimport type { NextFunction, Request, Response } from 'express';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { getConfig } from '../core/config';\nimport { logger } from '../core/logger';\nimport { lookupActiveKey } from '../auth/apiKeys';\nimport { createDb } from '../db/client';\nimport type { ApiKeyRow } from '../db/schema';\nimport { buildMcpServer } from './server';\n\ninterface AuthedRequest extends Request {\n lurqKey?: ApiKeyRow;\n}\n\n/** JSON-RPC-shaped error envelope for HTTP-level rejections. */\nfunction rpcError(code: number, message: string) {\n return { jsonrpc: '2.0' as const, error: { code, message }, id: null };\n}\n\nexport async function startHttpServer(opts: { port?: number } = {}): Promise<void> {\n const config = getConfig();\n const port = opts.port ?? config.PORT;\n\n const [{ default: express }, { default: helmet }, { rateLimit, ipKeyGenerator }] =\n await Promise.all([import('express'), import('helmet'), import('express-rate-limit')]);\n\n // The DB pool is the expensive resource — created once, shared by all requests.\n const { db } = createDb({ max: 20 });\n\n const app = express();\n app.set('trust proxy', 1); // Railway terminates TLS at the edge.\n app.use(helmet());\n app.use(express.json({ limit: '1mb' }));\n\n // Unauthenticated, no DB hit — for Railway's healthcheck.\n app.get('/healthz', (_req: Request, res: Response) => {\n res.status(200).json({ status: 'ok' });\n });\n\n // Coarse per-IP limiter to blunt unauthenticated floods before the auth lookup.\n const ipLimiter = rateLimit({\n windowMs: config.LURQ_RATE_LIMIT_WINDOW_MS,\n limit: config.LURQ_IP_RATE_LIMIT_MAX,\n standardHeaders: 'draft-7',\n legacyHeaders: false,\n message: rpcError(-32029, 'Rate limit exceeded.'),\n });\n\n // Bearer API-key auth: resolve and attach the key, or 401.\n const auth = async (req: AuthedRequest, res: Response, next: NextFunction): Promise<void> => {\n const header = req.headers.authorization;\n const token = header?.startsWith('Bearer ') ? header.slice(7).trim() : '';\n if (!token) {\n res.status(401).json(rpcError(-32001, 'Missing API key. Pass Authorization: Bearer <key>.'));\n return;\n }\n try {\n const row = await lookupActiveKey(db, token);\n if (!row) {\n res.status(401).json(rpcError(-32001, 'Invalid or revoked API key.'));\n return;\n }\n req.lurqKey = row;\n next();\n } catch (err) {\n logger.error('auth lookup failed:', err instanceof Error ? err.message : String(err));\n res.status(500).json(rpcError(-32603, 'Internal error.'));\n }\n };\n\n // Per-key limiter (runs after auth so it can key on the resolved API key).\n const keyLimiter = rateLimit({\n windowMs: config.LURQ_RATE_LIMIT_WINDOW_MS,\n limit: config.LURQ_RATE_LIMIT_MAX,\n standardHeaders: 'draft-7',\n legacyHeaders: false,\n // Key on the resolved API key (always present — auth runs first). The IP\n // fallback uses express-rate-limit's ipKeyGenerator so IPv6 addresses are\n // normalized correctly (v8 throws ERR_ERL_KEY_GEN_IPV6 on a raw req.ip).\n keyGenerator: (req: Request) =>\n (req as AuthedRequest).lurqKey?.prefix ?? ipKeyGenerator(req.ip ?? '0.0.0.0'),\n message: rpcError(-32029, 'Rate limit exceeded.'),\n });\n\n app.post('/mcp', ipLimiter, auth, keyLimiter, async (req: Request, res: Response) => {\n // Stateless: a fresh server+transport per request, sharing the one DB pool.\n const server = buildMcpServer(db);\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n enableJsonResponse: true,\n });\n res.on('close', () => {\n void transport.close();\n void server.close();\n });\n try {\n await server.connect(transport);\n await transport.handleRequest(req, res, req.body);\n } catch (err) {\n logger.error('mcp request failed:', err instanceof Error ? err.message : String(err));\n if (!res.headersSent) res.status(500).json(rpcError(-32603, 'Internal error'));\n }\n });\n\n // Stateless server: no session GET/DELETE handling.\n app.all('/mcp', (_req: Request, res: Response) => {\n res.status(405).json(rpcError(-32000, 'Method not allowed.'));\n });\n\n app.listen(port, () => {\n logger.info(`lurq HTTP MCP server listening on :${port}/mcp`);\n });\n}\n","/**\n * `lurq rescore` (§4). Re-derive health scores from each package's *cached*\n * `scoreBreakdown` using the currently-loaded weight model — no re-ingestion,\n * no network. This is the payoff of storing the breakdown per package: a weight\n * edit (`edit-weights`) applies to the whole DB in one cheap pass.\n *\n * Only health weights change a stored value (`health_score`). The composite\n * (health↔quality blend) and its λ are applied at read time in `recommend`, so\n * a λ-only edit needs no rescore — but running it is harmless and idempotent.\n */\nimport { isNotNull } from 'drizzle-orm';\nimport { logger } from '../core/logger';\nimport { createDb } from '../db/client';\nimport { packages } from '../db/schema';\nimport { computeHealthScore } from '../scoring';\nimport { loadWeights } from '../scoring/weights';\nimport { eq } from 'drizzle-orm';\n\nexport interface RescoreSummary {\n seen: number;\n updated: number;\n}\n\nexport async function runRescore(): Promise<RescoreSummary> {\n const weights = loadWeights();\n const handle = createDb({ max: 4 });\n try {\n const rows = await handle.db\n .select({ id: packages.id, breakdown: packages.scoreBreakdown, healthScore: packages.healthScore })\n .from(packages)\n .where(isNotNull(packages.scoreBreakdown));\n\n let updated = 0;\n for (const row of rows) {\n if (!row.breakdown) continue;\n const health = computeHealthScore(row.breakdown, weights.health);\n if (health !== row.healthScore) {\n await handle.db\n .update(packages)\n .set({ healthScore: health, updatedAt: new Date() })\n .where(eq(packages.id, row.id));\n updated++;\n }\n }\n\n logger.info(`Rescored ${rows.length} package(s); ${updated} health score(s) changed.`);\n return { seen: rows.length, updated };\n } finally {\n await handle.close();\n }\n}\n","/**\n * Read/write helpers for the `discovery_queue` table (§2B). The crawler enqueues\n * candidates here; the merit gate pre-scores and graduates them.\n */\nimport { eq, inArray, sql } from 'drizzle-orm';\nimport type { DiscoverySource, DiscoveryStatus } from '../core/types';\nimport type { Database } from './client';\nimport { discoveryQueue, packages, type DiscoveryQueueRow } from './schema';\n\nexport interface DiscoveryCandidate {\n name: string;\n via: DiscoverySource;\n}\n\n/** Names already tracked (in `packages`) or already queued — never re-enqueue. */\nexport async function getKnownNames(db: Database): Promise<Set<string>> {\n const [tracked, queued] = await Promise.all([\n db.select({ name: packages.name }).from(packages),\n db.select({ name: discoveryQueue.name }).from(discoveryQueue),\n ]);\n return new Set([...tracked.map((r) => r.name), ...queued.map((r) => r.name)]);\n}\n\n/** Insert new candidates, ignoring any that race in concurrently. Returns count inserted. */\nexport async function enqueueCandidates(\n db: Database,\n candidates: DiscoveryCandidate[],\n): Promise<number> {\n if (candidates.length === 0) return 0;\n const rows = candidates.map((c) => ({ name: c.name, discoveredVia: c.via }));\n const inserted = await db\n .insert(discoveryQueue)\n .values(rows)\n .onConflictDoNothing({ target: discoveryQueue.name })\n .returning({ id: discoveryQueue.id });\n return inserted.length;\n}\n\nexport async function getPendingCandidates(\n db: Database,\n limit: number,\n): Promise<DiscoveryQueueRow[]> {\n return db\n .select()\n .from(discoveryQueue)\n .where(eq(discoveryQueue.status, 'pending'))\n .limit(limit);\n}\n\nexport async function setDiscoveryStatus(\n db: Database,\n name: string,\n data: { status: DiscoveryStatus; preScore?: number | null },\n): Promise<void> {\n await db\n .update(discoveryQueue)\n .set({ status: data.status, ...(data.preScore !== undefined ? { preScore: data.preScore } : {}) })\n .where(eq(discoveryQueue.name, name));\n}\n\n/** Bulk-mark a set of names rejected (used when the per-run cap drops the tail). */\nexport async function rejectNames(db: Database, names: string[]): Promise<void> {\n if (names.length === 0) return;\n await db\n .update(discoveryQueue)\n .set({ status: 'rejected' })\n .where(inArray(discoveryQueue.name, names));\n}\n\nexport async function countByStatus(db: Database): Promise<Record<DiscoveryStatus, number>> {\n const rows = await db\n .select({ status: discoveryQueue.status, n: sql<number>`count(*)::int` })\n .from(discoveryQueue)\n .groupBy(discoveryQueue.status);\n const out: Record<DiscoveryStatus, number> = { pending: 0, ingested: 0, rejected: 0 };\n for (const r of rows) out[r.status] = r.n;\n return out;\n}\n","/**\n * Proactive multi-channel discovery crawler (§2B). OPERATOR-SIDE: this is a\n * scheduled job against the central index, never triggered by a user query.\n *\n * Three channels feed one queue, then a *merit* gate decides what graduates:\n * 1. Dependency-graph adjacency (deps.dev) — surfaced wholesale, NOT ranked by\n * dependent count (that re-introduces popularity bias).\n * 2. Category-keyword + recency (npm search) — the niche workhorse; the graph\n * structurally can't find niche alternatives.\n * 3. Merit gate — pre-scores candidates on QUALITY signals only. Downloads are\n * deliberately excluded so merit, not popularity, decides what's ingested.\n *\n * Cost is bounded by a per-run cap; anything dropped is logged (no silent\n * truncation), and the tail stays queued for the next run.\n */\nimport { isNotNull } from 'drizzle-orm';\nimport { logger } from '../core/logger';\nimport { CATEGORIES } from '../core/types';\nimport { createDb, type Database } from '../db/client';\nimport {\n enqueueCandidates,\n getKnownNames,\n getPendingCandidates,\n setDiscoveryStatus,\n type DiscoveryCandidate,\n} from '../db/discovery';\nimport { packages } from '../db/schema';\nimport { fetchDependencyNames } from '../ingestion/sources/depsDev';\nimport { fetchNpmRegistry } from '../ingestion/sources/npmRegistry';\nimport { searchNpm } from '../ingestion/sources/npmSearch';\nimport type { RawPackageSignals } from '../ingestion/types';\nimport { computeQuality, toScoringInput } from '../scoring';\nimport { DISCOVERY } from '../scoring/weights';\nimport { syncOnePackage } from './single';\n\nexport interface DiscoverOptions {\n /** Max candidates to fully ingest this run (defaults to DISCOVERY.perRunCap). */\n perRunCap?: number;\n /** Discover + queue + gate, but don't ingest survivors (preview). */\n dryRun?: boolean;\n}\n\nexport interface DiscoverSummary {\n enqueued: number;\n gated: number;\n passed: number;\n ingested: number;\n droppedToNextRun: number;\n}\n\n// ── Pure helpers (unit-tested) ───────────────────────────────────────────────\n\n/** Dedupe raw candidates by name (first channel wins), dropping anything already\n * known or with an invalid name. */\nexport function selectCandidates(\n raw: DiscoveryCandidate[],\n known: Set<string>,\n): DiscoveryCandidate[] {\n const seen = new Set<string>(known);\n const out: DiscoveryCandidate[] = [];\n for (const c of raw) {\n const name = c.name?.trim();\n if (!name || seen.has(name)) continue;\n seen.add(name);\n out.push({ name, via: c.via });\n }\n return out;\n}\n\n/** The merit gate: quality-only pre-score must clear the bar (§2B). */\nexport function passesGate(preScore: number | null): boolean {\n return preScore !== null && preScore >= DISCOVERY.minPreScore;\n}\n\n/**\n * Quality-only pre-score from a single cheap registry fetch (§2B). Reuses the\n * §1 quality model but with only manifest signals — no downloads, no GitHub —\n * so the gate is adoption-independent by construction.\n */\nexport async function preScorePackage(\n name: string,\n fetchImpl?: typeof fetch,\n): Promise<number | null> {\n try {\n const registry = await fetchNpmRegistry(name, fetchImpl);\n const signals: RawPackageSignals = {\n name,\n registry,\n downloads: null,\n github: null,\n depsDev: null,\n bundle: null,\n errors: [],\n };\n return computeQuality(toScoringInput(signals, null));\n } catch {\n return null;\n }\n}\n\n// ── Channels ─────────────────────────────────────────────────────────────────\n\n/** Dependency-graph neighbors of tracked packages (adjacency, not ranking). */\nasync function graphChannel(db: Database): Promise<DiscoveryCandidate[]> {\n const tracked = await db\n .select({ name: packages.name, version: packages.latestVersion })\n .from(packages)\n .where(isNotNull(packages.latestVersion));\n\n const out: DiscoveryCandidate[] = [];\n for (const t of tracked) {\n if (!t.version) continue;\n const deps = (await fetchDependencyNames(t.name, t.version)).slice(\n 0,\n DISCOVERY.graphNeighborsPerSeed,\n );\n for (const name of deps) out.push({ name, via: 'dependency-graph' });\n }\n return out;\n}\n\n/** Category-keyword + recency channel via npm search (the niche workhorse). */\nasync function searchChannel(): Promise<DiscoveryCandidate[]> {\n const out: DiscoveryCandidate[] = [];\n for (const category of CATEGORIES) {\n if (category === 'other') continue;\n const hits = await searchNpm(`keywords:${category}`, DISCOVERY.searchSizePerCategory);\n for (const hit of hits) {\n const via = isRecent(hit.date) ? 'recent' : 'category-search';\n out.push({ name: hit.name, via });\n }\n }\n return out;\n}\n\n/** Published within ~90 days counts as a \"recent\" entrant. */\nfunction isRecent(date: string | null): boolean {\n if (!date) return false;\n const ms = Date.parse(date);\n if (Number.isNaN(ms)) return false;\n return Date.now() - ms <= 90 * 24 * 60 * 60 * 1000;\n}\n\n// ── Orchestration ────────────────────────────────────────────────────────────\n\nexport async function runDiscovery(opts: DiscoverOptions = {}): Promise<DiscoverSummary> {\n const cap = opts.perRunCap ?? DISCOVERY.perRunCap;\n const handle = createDb({ max: 6 });\n try {\n logger.info('Discovery: gathering candidates from graph + search channels…');\n const [graph, search] = await Promise.all([graphChannel(handle.db), searchChannel()]);\n const known = await getKnownNames(handle.db);\n const fresh = selectCandidates([...graph, ...search], known);\n const enqueued = await enqueueCandidates(handle.db, fresh);\n logger.info(\n `Discovery: ${graph.length} graph + ${search.length} search candidates → ${enqueued} new queued.`,\n );\n\n // ── Merit gate: pre-score pending candidates on quality only ──────────────\n const pending = await getPendingCandidates(handle.db, cap * 4);\n const scored: { name: string; preScore: number }[] = [];\n for (const cand of pending) {\n const preScore = await preScorePackage(cand.name);\n await setDiscoveryStatus(handle.db, cand.name, {\n status: passesGate(preScore) ? 'pending' : 'rejected',\n preScore: preScore ?? null,\n });\n if (passesGate(preScore)) scored.push({ name: cand.name, preScore: preScore! });\n }\n logger.info(`Discovery: gated ${pending.length}; ${scored.length} cleared the quality bar.`);\n\n // ── Graduate the best, capped; log (don't silently drop) the tail ─────────\n scored.sort((a, b) => b.preScore - a.preScore);\n const toIngest = scored.slice(0, cap);\n const deferred = scored.slice(cap);\n if (deferred.length > 0) {\n logger.info(\n `Discovery: per-run cap ${cap} reached — ${deferred.length} eligible candidate(s) deferred to the next run: ${deferred.map((d) => d.name).join(', ')}`,\n );\n }\n\n let ingested = 0;\n if (!opts.dryRun) {\n for (const cand of toIngest) {\n try {\n await syncOnePackage(handle.db, cand.name);\n await setDiscoveryStatus(handle.db, cand.name, { status: 'ingested' });\n ingested++;\n } catch (err) {\n logger.warn(`Discovery: failed to ingest ${cand.name}: ${(err as Error).message}`);\n }\n }\n }\n\n logger.info(`Discovery: ingested ${ingested}/${toIngest.length} candidate(s).`);\n return {\n enqueued,\n gated: pending.length,\n passed: scored.length,\n ingested,\n droppedToNextRun: deferred.length,\n };\n } finally {\n await handle.close();\n }\n}\n","export { runSync, type SyncOptions, type SyncSummary } from './sync';\nexport { runRescore, type RescoreSummary } from './rescore';\nexport { runDiscovery, type DiscoverOptions, type DiscoverSummary } from './discovery';\n","/**\n * Dependency-free formatting helpers for human-facing CLI output. Compact tables\n * and labeled detail views; `--json` paths bypass these entirely.\n */\n\nconst ESC = '\u001b[';\nconst wrap = (code: string, s: string) => `${ESC}${code}m${s}${ESC}0m`;\n\nexport const bold = (s: string) => wrap('1', s);\nexport const dim = (s: string) => wrap('2', s);\nexport const red = (s: string) => wrap('31', s);\nexport const green = (s: string) => wrap('32', s);\nexport const yellow = (s: string) => wrap('33', s);\n\n// eslint-disable-next-line no-control-regex\nconst ANSI_RE = /\u001b\\[[0-9;]*m/g;\nconst width = (s: string) => s.replace(ANSI_RE, '').length;\n\n/** Render a simple aligned table. */\nexport function table(headers: string[], rows: string[][]): string {\n const widths = headers.map((h, i) => Math.max(width(h), ...rows.map((r) => width(r[i] ?? ''))));\n const pad = (s: string, w: number) => s + ' '.repeat(Math.max(0, w - width(s)));\n const line = (cells: string[]) => cells.map((c, i) => pad(c, widths[i]!)).join(' ');\n const out = [bold(line(headers)), dim(widths.map((w) => '─'.repeat(w)).join(' '))];\n for (const r of rows) out.push(line(r));\n return out.join('\\n');\n}\n\n/** Render a labeled key/value detail block. */\nexport function detail(pairs: [string, string][]): string {\n const labelWidth = Math.max(...pairs.map(([k]) => k.length));\n return pairs.map(([k, v]) => `${dim((k + ':').padEnd(labelWidth + 1))} ${v}`).join('\\n');\n}\n\n/** Compact number formatting: 1.2M, 34k, 950. */\nexport function formatNumber(n: number | null | undefined): string {\n if (n == null) return '—';\n if (n >= 1_000_000) return `${Math.round(n / 100_000) / 10}M`;\n if (n >= 1_000) return `${Math.round(n / 100) / 10}k`;\n return String(n);\n}\n\nexport function formatDate(iso: string | null): string {\n return iso ? iso.slice(0, 10) : '—';\n}\n\nexport function formatPercent(fraction: number | null | undefined): string {\n if (fraction == null) return '—';\n const pct = Math.round(fraction * 1000) / 10;\n return `${pct > 0 ? '+' : ''}${pct}%`;\n}\n\n/** Color a confidence label. */\nexport function confidenceLabel(c: string): string {\n if (c === 'proven') return green(c);\n if (c === 'emerging') return yellow(c);\n // `promising` (§1): high intrinsic quality, adoption-independent.\n if (c === 'promising') return green(c);\n return red(c);\n}\n","/**\n * Human-facing CLI command implementations (§13). Each reuses the MCP handlers\n * against a DB connection, then renders a compact table/detail view — or raw\n * JSON with `--json`.\n */\nimport { requireConfig } from '../core/config';\nimport { isCategory, type Category, type Confidence } from '../core/types';\nimport { createDb } from '../db/client';\nimport { handleCompare, handleEvaluate, handleRecommend, handleVerify } from '../mcp/handlers';\nimport { CONFIDENCE, QUALITY_WEIGHTS } from '../scoring/weights';\nimport {\n activeWeightsPath,\n applyOverrides,\n loadWeights,\n resetWeights,\n saveWeights,\n settableKeys,\n validateWeights,\n WEIGHT_EXPLANATIONS,\n} from '../scoring/weights';\nimport {\n bold,\n confidenceLabel,\n detail,\n dim,\n formatDate,\n formatNumber,\n formatPercent,\n green,\n red,\n table,\n yellow,\n} from './format';\n\nasync function withDb<T>(fn: (db: ReturnType<typeof createDb>['db']) => Promise<T>): Promise<T> {\n requireConfig(['DATABASE_URL']);\n const handle = createDb();\n try {\n return await fn(handle.db);\n } finally {\n await handle.close();\n }\n}\n\nexport interface RecommendCliOpts {\n category?: string;\n minConfidence?: string;\n json?: boolean;\n}\n\nexport async function runRecommend(need: string, opts: RecommendCliOpts): Promise<void> {\n if (opts.category && !isCategory(opts.category)) {\n throw new Error(`Unknown category \"${opts.category}\".`);\n }\n await withDb(async (db) => {\n const res = await handleRecommend(db, {\n need,\n category: opts.category as Category | undefined,\n constraints: opts.minConfidence\n ? { minConfidence: opts.minConfidence as Confidence }\n : undefined,\n });\n if (opts.json) return console.log(JSON.stringify(res, null, 2));\n if (res.candidates.length === 0) {\n console.log('No matching packages found.');\n return;\n }\n console.log(\n table(\n ['Package', 'Health', 'Quality', 'Confidence', 'Weekly', 'Latest', 'Category'],\n res.candidates.map((c) => [\n c.name,\n String(c.healthScore),\n c.qualityScore != null ? String(c.qualityScore) : '—',\n confidenceLabel(c.confidence),\n formatNumber(c.weeklyDownloads),\n c.latestVersion ?? '—',\n c.category ?? '—',\n ]),\n ),\n );\n console.log(dim(`\\ndata as of ${formatDate(res.dataAsOf)}`));\n });\n}\n\nexport async function runEvaluate(pkg: string, opts: { json?: boolean }): Promise<void> {\n await withDb(async (db) => {\n const res = await handleEvaluate(db, { package: pkg });\n if (opts.json) return console.log(JSON.stringify(res, null, 2));\n if ('tracked' in res) {\n console.log(res.suggestion);\n return;\n }\n console.log(bold(res.name) + (res.category ? dim(` (${res.category})`) : ''));\n const b = res.scoreBreakdown;\n console.log(\n detail([\n ['health', `${res.healthScore} ${confidenceLabel(res.confidence)}`],\n ['quality', res.qualityScore != null ? String(res.qualityScore) : '—'],\n [\n 'breakdown',\n `maint ${b.maintenance} · adopt ${b.adoption} · rel ${b.reliability} · eff ${b.efficiency ?? '—'} · qual ${b.quality ?? '—'}`,\n ],\n ['version', res.latestVersion ?? '—'],\n ['weekly dl', `${formatNumber(res.weeklyDownloads)} (${formatPercent(res.downloadGrowth90d)} 90d)`],\n ['scorecard', res.scorecard != null ? String(res.scorecard) : '—'],\n ['bundle', res.bundleMinGzipKb != null ? `${res.bundleMinGzipKb} KB gzip` : '—'],\n ['released', formatDate(res.lastReleaseAt)],\n ['flags', [res.deprecated && 'deprecated', res.archived && 'archived'].filter(Boolean).join(', ') || 'none'],\n ['advisories', res.advisories.length ? res.advisories.map((a) => `${a.severity}`).join(', ') : 'none'],\n ['repo', res.repoUrl ?? '—'],\n ]),\n );\n if (res.summary) console.log('\\n' + res.summary);\n if (res.usageGuide) {\n const g = res.usageGuide;\n console.log(\n '\\n' +\n detail(\n [\n ['what', g.whatItIs],\n ['when', g.whenToUse],\n g.whenNotToUse ? (['when not', g.whenNotToUse] as [string, string]) : null,\n ['fits', g.whereItFits],\n g.howToWireIn ? (['wire-in', g.howToWireIn] as [string, string]) : null,\n ].filter(Boolean) as [string, string][],\n ),\n );\n }\n console.log(dim(`\\ndata as of ${formatDate(res.dataAsOf)}${res.stale ? ' (stale)' : ''}`));\n });\n}\n\nexport async function runCompare(pkgs: string[], opts: { json?: boolean }): Promise<void> {\n await withDb(async (db) => {\n const res = await handleCompare(db, { packages: pkgs });\n if (opts.json) return console.log(JSON.stringify(res, null, 2));\n console.log(\n table(\n ['Package', 'Health', 'Confidence', 'Weekly', '90d', 'Scorecard', 'Released'],\n res.rows.map((r) => [\n r.name,\n String(r.healthScore),\n confidenceLabel(r.confidence),\n formatNumber(r.weeklyDownloads),\n formatPercent(r.downloadGrowth90d),\n r.scorecard != null ? String(r.scorecard) : '—',\n formatDate(r.lastReleaseAt),\n ]),\n ),\n );\n if (res.missing?.length) console.log(dim(`\\nnot found: ${res.missing.join(', ')}`));\n console.log(dim(`data as of ${formatDate(res.dataAsOf)}`));\n });\n}\n\n// ── weights / edit-weights (§4) ──────────────────────────────────────────────\n\n/** `lurq weights` — show + explain the score model (no DB needed). */\nexport function runWeights(opts: { json?: boolean } = {}): void {\n const w = loadWeights();\n const active = activeWeightsPath();\n if (opts.json) {\n console.log(JSON.stringify({ ...w, source: active?.source ?? 'defaults' }, null, 2));\n return;\n }\n const pct = (n: number) => n.toFixed(2);\n console.log(bold('Two axes, blended for default sort:'));\n console.log(` composite = (1−λ)·health + λ·quality λ = ${pct(w.composite.lambda)}\\n`);\n console.log(bold('Health (proven-ness) — weighted sum of 4 components:'));\n console.log(\n detail([\n ['maintenance', `${pct(w.health.maintenance)} ${dim('— ' + WEIGHT_EXPLANATIONS.maintenance!)}`],\n ['adoption', `${pct(w.health.adoption)} ${dim('— ' + WEIGHT_EXPLANATIONS.adoption!)}`],\n ['reliability', `${pct(w.health.reliability)} ${dim('— ' + WEIGHT_EXPLANATIONS.reliability!)}`],\n ['efficiency', `${pct(w.health.efficiency)} ${dim('— ' + WEIGHT_EXPLANATIONS.efficiency!)}`],\n ]),\n );\n console.log('\\n' + bold('Quality (intrinsic, adoption-independent):'));\n console.log(' ' + dim(Object.keys(QUALITY_WEIGHTS).join(', ')));\n console.log('\\n' + bold('Confidence thresholds:'));\n console.log(\n detail([\n ['proven', `≥ ${formatNumber(CONFIDENCE.proven.minWeeklyDownloads)} weekly dl, ≥ ${CONFIDENCE.proven.minAgeMonths}mo old`],\n ['emerging', `≥ ${formatNumber(CONFIDENCE.emerging.minWeeklyDownloads)} weekly dl OR ≥ ${CONFIDENCE.emerging.strongGrowth * 100}% 90d growth`],\n ['promising', `≥ ${CONFIDENCE.promising.minQuality} quality score (adoption-independent)`],\n ]),\n );\n console.log(dim(`\\nSource: ${active ? `${active.source} (${active.path})` : 'defaults (no user overrides)'}`));\n}\n\nexport interface EditWeightsOpts {\n set?: string[];\n reset?: boolean;\n explain?: string;\n project?: boolean;\n json?: boolean;\n}\n\n/** `lurq edit-weights` — override / reset / explain the model (no DB needed). */\nexport function runEditWeights(opts: EditWeightsOpts): void {\n if (opts.reset) {\n const removed = resetWeights();\n console.log(removed.length ? `Removed overrides:\\n ${removed.join('\\n ')}` : 'No overrides to remove; already on defaults.');\n return;\n }\n\n if (opts.explain) {\n const key = opts.explain;\n const text = WEIGHT_EXPLANATIONS[key];\n if (!text) {\n throw new Error(`No explanation for \"${key}\". Known: ${Object.keys(WEIGHT_EXPLANATIONS).join(', ')}.`);\n }\n console.log(`${bold(key)} — ${text}`);\n return;\n }\n\n if (opts.set && opts.set.length > 0) {\n const next = applyOverrides(loadWeights(), opts.set);\n const { weights, normalized } = validateWeights(next);\n const path = saveWeights(weights, opts.project ? 'project' : 'user');\n console.log(`Saved overrides to ${path}`);\n if (normalized) {\n console.log(\n yellow('Health weights did not sum to 1.0 — renormalized to: ') +\n `maint ${weights.health.maintenance.toFixed(3)}, adopt ${weights.health.adoption.toFixed(3)}, rel ${weights.health.reliability.toFixed(3)}, eff ${weights.health.efficiency.toFixed(3)}`,\n );\n }\n console.log(dim('\\nRun `lurq rescore` to apply the new health weights to the stored index.'));\n return;\n }\n\n // No action flags → behave like `lurq weights`.\n console.log(dim(`No changes. Settable keys: ${settableKeys().join(', ')}.\\n`));\n runWeights(opts);\n}\n\nexport async function runVerify(pkg: string, opts: { json?: boolean }): Promise<void> {\n await withDb(async (db) => {\n const res = await handleVerify(db, { package: pkg });\n if (opts.json) return console.log(JSON.stringify(res, null, 2));\n const verdict = !res.exists\n ? red('✗ NOT FOUND on npm')\n : res.deprecated || res.archived || res.advisoryCount > 0\n ? yellow('⚠ exists, but risky')\n : green('✓ looks safe');\n console.log(`${bold(pkg)} ${verdict}`);\n console.log(\n detail([\n ['version', res.latestVersion ?? '—'],\n ['weekly dl', formatNumber(res.weeklyDownloads)],\n ['confidence', res.confidence ? confidenceLabel(res.confidence) : '—'],\n ['advisories', String(res.advisoryCount)],\n ['risk flags', res.riskFlags.length ? yellow(res.riskFlags.join(', ')) : 'none'],\n ]),\n );\n });\n}\n","/**\n * Agent skill installer (§14). Registers lurq as an MCP server in supported\n * assistants by MERGING a single `lurq` entry into each agent's config — never\n * overwriting unrelated config — and drops the skill-instructions file.\n *\n * Two modes:\n * - **remote** (hosted, default for real users): writes a keyed HTTP entry\n * pointing at the lurq service. No DATABASE_URL ever touches a user's machine.\n * - **local** (self-host / contributors): writes the legacy stdio entry that\n * runs `lurq serve` locally against the user's own DB.\n *\n * MCP config formats move fast and differ per agent; this writes the current\n * widely-supported shapes and prints exactly what it did, so a stale path is\n * obvious rather than silent. Remote shapes verified against current agent docs\n * (2026-06): Claude Code / VS Code use `{ type:\"http\", url, headers }`; Cursor\n * uses `{ url, headers }`; Windsurf uses `{ serverUrl, headers }`; Codex (TOML)\n * uses `url` + an inline `http_headers` table.\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { copyFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { DEFAULT_ENDPOINT, PACKAGE_NAME } from '../core/constants';\nimport { logger } from '../core/logger';\nimport { packageRoot } from '../core/paths';\n\nconst ENV_KEYS = [\n 'DATABASE_URL',\n 'GITHUB_TOKEN',\n 'EMBEDDING_PROVIDER',\n 'EMBEDDING_API_KEY',\n 'EMBEDDING_MODEL',\n 'SUMMARY_PROVIDER',\n 'SUMMARY_API_KEY',\n 'SUMMARY_MODEL',\n] as const;\n\nexport type ConfigFormat = 'mcpServers' | 'servers' | 'toml';\n\nexport interface AgentSpec {\n id: string;\n label: string;\n format: ConfigFormat;\n /** Absolute config file path. */\n path: string;\n /** Whether this agent appears installed (used by `--agent all` and the wizard). */\n detected: boolean;\n}\n\nfunction home(...p: string[]): string {\n return join(homedir(), ...p);\n}\n\nexport function agentSpecs(): AgentSpec[] {\n return [\n {\n id: 'claude-code',\n label: 'Claude Code',\n format: 'mcpServers',\n path: home('.claude.json'),\n detected: existsSync(home('.claude.json')) || existsSync(home('.claude')),\n },\n {\n id: 'cursor',\n label: 'Cursor',\n format: 'mcpServers',\n path: home('.cursor', 'mcp.json'),\n detected: existsSync(home('.cursor')),\n },\n {\n id: 'windsurf',\n label: 'Windsurf',\n format: 'mcpServers',\n path: home('.codeium', 'windsurf', 'mcp_config.json'),\n detected: existsSync(home('.codeium')),\n },\n {\n id: 'copilot',\n label: 'VS Code / GitHub Copilot',\n format: 'servers',\n path: home('Library', 'Application Support', 'Code', 'User', 'mcp.json'),\n detected: existsSync(home('Library', 'Application Support', 'Code', 'User')),\n },\n {\n id: 'codex',\n label: 'OpenAI Codex CLI',\n format: 'toml',\n path: home('.codex', 'config.toml'),\n detected: existsSync(home('.codex')),\n },\n ];\n}\n\nexport const SUPPORTED_AGENTS = ['claude-code', 'cursor', 'windsurf', 'copilot', 'codex'] as const;\n\n/** How to wire the lurq entry: hosted HTTP endpoint, or local stdio process. */\nexport type InstallMode =\n | { kind: 'remote'; url: string; apiKey: string }\n | { kind: 'local'; env: Record<string, string> };\n\nfunction collectEnv(): Record<string, string> {\n const env: Record<string, string> = {};\n for (const key of ENV_KEYS) {\n const value = process.env[key];\n if (value) env[key] = value;\n }\n return env;\n}\n\nexport interface InstallResult {\n agent: string;\n path: string;\n status: 'installed' | 'skipped' | 'error';\n message?: string;\n}\n\nfunction readJsonObject(path: string): Record<string, any> {\n if (!existsSync(path)) return {};\n const text = readFileSync(path, 'utf8').trim();\n if (!text) return {};\n return JSON.parse(text);\n}\n\nfunction writeJson(path: string, obj: unknown): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(obj, null, 2) + '\\n', 'utf8');\n}\n\n/** Local (stdio) lurq server entry for JSON configs. */\nexport function buildServerEntry(env: Record<string, string>, withType: boolean): Record<string, any> {\n const entry: Record<string, any> = { command: 'npx', args: ['-y', PACKAGE_NAME, 'serve'] };\n if (withType) entry.type = 'stdio';\n if (Object.keys(env).length) entry.env = env;\n return entry;\n}\n\n/**\n * Remote (hosted) lurq server entry for JSON configs. Per-agent shape differs:\n * Claude Code & VS Code take `type:\"http\"`; Cursor & Windsurf infer transport\n * from the URL (Windsurf names the field `serverUrl`).\n */\nexport function buildRemoteServerEntry(\n agentId: string,\n opts: { url: string; apiKey: string },\n): Record<string, any> {\n const headers = { Authorization: `Bearer ${opts.apiKey}` };\n switch (agentId) {\n case 'cursor':\n return { url: opts.url, headers };\n case 'windsurf':\n return { serverUrl: opts.url, headers };\n case 'claude-code':\n case 'copilot':\n default:\n return { type: 'http', url: opts.url, headers };\n }\n}\n\n/** Local (stdio) TOML block for the Codex config. */\nexport function buildTomlBlock(env: Record<string, string>): string {\n const lines = ['[mcp_servers.lurq]', 'command = \"npx\"', `args = [\"-y\", \"${PACKAGE_NAME}\", \"serve\"]`];\n if (Object.keys(env).length) {\n lines.push('', '[mcp_servers.lurq.env]');\n for (const [k, v] of Object.entries(env)) lines.push(`${k} = ${JSON.stringify(v)}`);\n }\n return lines.join('\\n') + '\\n';\n}\n\n/**\n * Remote (hosted) TOML block for the Codex config. Codex parses with\n * `deny_unknown_fields`: literal headers go in an inline `http_headers` table,\n * NOT a `[mcp_servers.lurq.headers]` subtable (verified against the openai/codex\n * StreamableHttp config schema).\n */\nexport function buildRemoteTomlBlock(opts: { url: string; apiKey: string }): string {\n return (\n [\n '[mcp_servers.lurq]',\n `url = ${JSON.stringify(opts.url)}`,\n `http_headers = { Authorization = ${JSON.stringify(`Bearer ${opts.apiKey}`)} }`,\n ].join('\\n') + '\\n'\n );\n}\n\nfunction installJsonEntry(spec: AgentSpec, entry: Record<string, any>): InstallResult {\n const key = spec.format === 'servers' ? 'servers' : 'mcpServers';\n const config = readJsonObject(spec.path);\n if (typeof config[key] !== 'object' || config[key] === null) config[key] = {};\n config[key].lurq = entry;\n writeJson(spec.path, config);\n return { agent: spec.id, path: spec.path, status: 'installed' };\n}\n\nfunction installTomlBlock(spec: AgentSpec, block: string): InstallResult {\n const existing = existsSync(spec.path) ? readFileSync(spec.path, 'utf8') : '';\n if (existing.includes('[mcp_servers.lurq]')) {\n return {\n agent: spec.id,\n path: spec.path,\n status: 'skipped',\n message: 'lurq already present; edit manually to change it.',\n };\n }\n mkdirSync(dirname(spec.path), { recursive: true });\n const sep = existing && !existing.endsWith('\\n') ? '\\n\\n' : existing ? '\\n' : '';\n writeFileSync(spec.path, existing + sep + block, 'utf8');\n return { agent: spec.id, path: spec.path, status: 'installed' };\n}\n\n/** Apply the lurq entry to one agent's config, in the given mode. */\nexport function installAgent(spec: AgentSpec, mode: InstallMode): InstallResult {\n try {\n if (spec.format === 'toml') {\n const block =\n mode.kind === 'remote'\n ? buildRemoteTomlBlock(mode)\n : buildTomlBlock(mode.env);\n return installTomlBlock(spec, block);\n }\n const entry =\n mode.kind === 'remote'\n ? buildRemoteServerEntry(spec.id, mode)\n : buildServerEntry(mode.env, spec.format === 'servers');\n return installJsonEntry(spec, entry);\n } catch (err) {\n return {\n agent: spec.id,\n path: spec.path,\n status: 'error',\n message: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\n/** Copy the skill-instructions template to ~/.lurq. Returns the path, or null. */\nexport function installInstructionsFile(): string | null {\n const src = join(packageRoot(), 'templates', 'skill-instructions.md');\n if (!existsSync(src)) return null;\n const destDir = home('.lurq');\n const dest = join(destDir, 'skill-instructions.md');\n mkdirSync(destDir, { recursive: true });\n copyFileSync(src, dest);\n return dest;\n}\n\n/** Resolve `--agent <id|all>` to the set of agent specs to write. */\nexport function resolveAgents(target: string): AgentSpec[] {\n const specs = agentSpecs();\n if (target === 'all') return specs.filter((s) => s.detected);\n const spec = specs.find((s) => s.id === target);\n if (!spec) {\n throw new Error(`Unknown agent \"${target}\". Supported: ${SUPPORTED_AGENTS.join(', ')}, all.`);\n }\n return [spec];\n}\n\n/** Print the per-agent registration report + next steps. Shared by both paths. */\nexport function printInstallReport(\n results: InstallResult[],\n instructionsPath: string | null,\n mode: InstallMode,\n): void {\n const specs = agentSpecs();\n console.log('lurq MCP server registration:');\n for (const r of results) {\n const spec = specs.find((s) => s.id === r.agent)!;\n const mark = r.status === 'installed' ? '✓' : r.status === 'skipped' ? '•' : '✗';\n console.log(` ${mark} ${spec.label.padEnd(26)} ${r.path}${r.message ? ` (${r.message})` : ''}`);\n }\n if (instructionsPath) console.log(`\\nSkill instructions written to ${instructionsPath}`);\n console.log('\\nNext steps:');\n if (mode.kind === 'local') {\n console.log(' 1. Ensure DATABASE_URL (and any API keys) are set in the config env above.');\n console.log(' 2. Restart the agent so it picks up the new MCP server.');\n } else {\n console.log(' 1. Restart the agent so it picks up the new MCP server.');\n }\n console.log(' • Ask it to recommend a library — it should call lurq.');\n}\n\nexport interface InstallSkillOptions {\n agent?: string;\n /** Hosted endpoint URL (defaults to LURQ_ENDPOINT or the built-in default). */\n url?: string;\n /** API key for the hosted endpoint. Presence selects remote mode. */\n apiKey?: string;\n /** Force the legacy local/stdio entry (self-host). */\n local?: boolean;\n}\n\nexport async function runInstallSkill(opts: InstallSkillOptions): Promise<void> {\n const selected = resolveAgents(opts.agent ?? 'claude-code');\n if (selected.length === 0) {\n console.log('No supported agents detected on this machine.');\n return;\n }\n\n // Remote unless explicitly --local. Remote requires an API key.\n const remote = !opts.local;\n let mode: InstallMode;\n if (remote) {\n const apiKey = opts.apiKey ?? process.env.LURQ_API_KEY;\n if (!apiKey) {\n throw new Error(\n 'An API key is required for a hosted install. Pass --api-key <key> (or set LURQ_API_KEY), ' +\n 'or use `lurq install` for the guided setup, or --local to self-host.',\n );\n }\n const url = opts.url ?? process.env.LURQ_ENDPOINT ?? DEFAULT_ENDPOINT;\n mode = { kind: 'remote', url, apiKey };\n } else {\n const env = collectEnv();\n if (!env.DATABASE_URL) {\n logger.warn(\n 'DATABASE_URL is not set — the local server entry will have no DATABASE_URL. ' +\n 'Set it (in .env) and re-run, or edit the config.',\n );\n }\n mode = { kind: 'local', env };\n }\n\n const results = selected.map((spec) => installAgent(spec, mode));\n const instructionsPath = installInstructionsFile();\n printInstallReport(results, instructionsPath, mode);\n}\n","/**\n * Guided install wizard (`lurq install`, i.e. `npx lurqrun install`). Walks a user\n * through connecting lurq's hosted MCP service to their AI assistant(s): collects\n * the API key, optionally validates it against the endpoint, detects installed\n * agents, and writes the keyed remote config — no DATABASE_URL ever on their\n * machine. Fully non-interactive with `--yes` + flags/env for scripting.\n */\nimport { DEFAULT_ENDPOINT } from '../core/constants';\nimport {\n agentSpecs,\n installAgent,\n installInstructionsFile,\n printInstallReport,\n resolveAgents,\n type AgentSpec,\n type InstallMode,\n} from './installSkill';\n\nexport interface WizardOptions {\n apiKey?: string;\n url?: string;\n agent?: string;\n yes?: boolean;\n}\n\n/** Where users obtain a key (operator-issued for now; self-serve dashboard later). */\nconst GET_KEY_URL = 'https://lurq.run';\n\n/** Lightweight MCP `tools/list` ping to confirm the key authenticates. */\nasync function validateKey(url: string, apiKey: string): Promise<boolean> {\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json, text/event-stream',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/list' }),\n });\n return res.ok;\n } catch {\n return false;\n }\n}\n\nexport async function runInstallWizard(opts: WizardOptions): Promise<void> {\n const interactive = !opts.yes;\n const url = opts.url ?? process.env.LURQ_ENDPOINT ?? DEFAULT_ENDPOINT;\n let apiKey = (opts.apiKey ?? process.env.LURQ_API_KEY)?.trim();\n\n if (interactive) {\n const { input, checkbox, confirm } = await import('@inquirer/prompts');\n\n console.log('\\n lurq — connect your coding agent to the hosted package index.\\n');\n\n if (!apiKey) {\n console.log(` Need a key? Get one at ${GET_KEY_URL}\\n`);\n apiKey = (\n await input({\n message: 'Paste your lurq API key',\n validate: (v) =>\n v.trim().startsWith('lurq_') ? true : 'Keys look like lurq_live_… ',\n })\n ).trim();\n }\n\n process.stdout.write(' Validating key… ');\n const ok = await validateKey(url, apiKey);\n console.log(ok ? 'ok' : 'could not reach endpoint');\n if (!ok) {\n const proceed = await confirm({\n message: `Couldn't validate the key against ${url}. Continue anyway?`,\n default: false,\n });\n if (!proceed) {\n console.log('Aborted. No config was changed.');\n return;\n }\n }\n\n let selected: AgentSpec[];\n if (opts.agent) {\n selected = resolveAgents(opts.agent);\n } else {\n const specs = agentSpecs();\n const ids = await checkbox({\n message: 'Which assistant(s) should I configure?',\n choices: specs.map((s) => ({\n name: `${s.label}${s.detected ? ' (detected)' : ''}`,\n value: s.id,\n checked: s.detected,\n })),\n });\n selected = specs.filter((s) => ids.includes(s.id));\n }\n await finish(selected, { url, apiKey });\n return;\n }\n\n // Non-interactive (--yes): require a key, use flags/env + detected agents.\n if (!apiKey) {\n throw new Error(\n 'No API key. Pass --api-key <key> or set LURQ_API_KEY (or drop --yes to be prompted).',\n );\n }\n const selected = opts.agent\n ? resolveAgents(opts.agent)\n : agentSpecs().filter((s) => s.detected);\n await finish(selected, { url, apiKey });\n}\n\nasync function finish(\n selected: AgentSpec[],\n remote: { url: string; apiKey: string },\n): Promise<void> {\n if (selected.length === 0) {\n console.log(\n '\\nNo agents selected or detected. Re-run with --agent <id>, or install an assistant first.',\n );\n return;\n }\n const mode: InstallMode = { kind: 'remote', ...remote };\n const results = selected.map((s) => installAgent(s, mode));\n const instructionsPath = installInstructionsFile();\n console.log('');\n printInstallReport(results, instructionsPath, mode);\n}\n","/**\n * Operator-only API-key management for the hosted service (`lurq keys …`).\n * Requires DATABASE_URL — these commands run where the central DB lives, never on\n * a user's machine. New keys are printed in plaintext exactly once; only hashes\n * are stored, and list/JSON output never includes the hash.\n */\nimport { requireConfig } from '../core/config';\nimport { logger } from '../core/logger';\nimport { createKey, listKeys, revokeKey } from '../auth/apiKeys';\nimport { createDb } from '../db/client';\nimport { bold, dim, green, table } from './format';\n\nconst isoDay = (d: Date | null) => (d ? d.toISOString().slice(0, 10) : '—');\n\n/** Block until the operator presses Enter (resolves immediately if not a TTY). */\nfunction waitForEnter(prompt: string): Promise<void> {\n return new Promise((resolve) => {\n process.stdout.write(prompt);\n process.stdin.resume();\n process.stdin.once('data', () => {\n process.stdin.pause();\n resolve();\n });\n });\n}\n\nexport async function runKeysCreate(opts: {\n label?: string;\n tier?: string;\n json?: boolean;\n}): Promise<void> {\n requireConfig(['DATABASE_URL']);\n const { db, close } = createDb({ max: 1 });\n try {\n const { key, row } = await createKey(db, { label: opts.label, tier: opts.tier });\n\n // Machine-readable path: print once, no interactivity (scripts/CI).\n if (opts.json) {\n console.log(JSON.stringify({ key, prefix: row.prefix, tier: row.tier, label: row.label }));\n return;\n }\n\n const meta = `prefix=${row.prefix} tier=${row.tier}${row.label ? ` label=${row.label}` : ''}`;\n const block = [bold('API key created.'), '', ` ${green(key)}`, '', dim(meta)];\n const interactive = Boolean(process.stdout.isTTY && process.stdin.isTTY);\n\n console.log(block.join('\\n'));\n\n if (interactive) {\n // Show the key, then wipe it from the terminal (screen + scrollback) once\n // the operator confirms they've copied it — so it doesn't linger on screen\n // or in scroll-back history.\n await waitForEnter(dim('Copy it now, then press Enter to erase it from the terminal… '));\n // Move to the top of the printed block (block lines + the prompt line the\n // Enter advanced past), clear to end of screen, and clear scroll-back.\n process.stdout.write(`\\x1b[${block.length + 1}F\\x1b[0J\\x1b[3J`);\n console.log(\n dim(`API key created (prefix ${row.prefix}) — value erased from the terminal. ` +\n `It is stored only as a hash and cannot be recovered, so make sure you saved it.`),\n );\n } else {\n // Non-TTY (piped, or over a non-interactive SSH exec): can't erase, so just\n // warn. Operator is responsible for clearing their buffer.\n console.log(dim('Store it now — shown only once, stored hashed, cannot be recovered.'));\n }\n } finally {\n await close();\n }\n}\n\nexport async function runKeysList(opts: { json?: boolean }): Promise<void> {\n requireConfig(['DATABASE_URL']);\n const { db, close } = createDb({ max: 1 });\n try {\n const rows = await listKeys(db);\n if (opts.json) {\n // Deliberately omit keyHash from machine output.\n console.log(\n JSON.stringify(\n rows.map((r) => ({\n id: r.id,\n prefix: r.prefix,\n label: r.label,\n tier: r.tier,\n ownerId: r.ownerId,\n createdAt: r.createdAt,\n lastUsedAt: r.lastUsedAt,\n revokedAt: r.revokedAt,\n })),\n null,\n 2,\n ),\n );\n return;\n }\n if (rows.length === 0) {\n console.log('No API keys yet. Create one with `lurq keys create --label <name>`.');\n return;\n }\n console.log(\n table(\n ['prefix', 'label', 'tier', 'created', 'last used', 'status'],\n rows.map((r) => [\n r.prefix,\n r.label ?? '—',\n r.tier,\n isoDay(r.createdAt),\n isoDay(r.lastUsedAt),\n r.revokedAt ? 'revoked' : 'active',\n ]),\n ),\n );\n } finally {\n await close();\n }\n}\n\nexport async function runKeysRevoke(prefixOrId: string): Promise<void> {\n requireConfig(['DATABASE_URL']);\n const { db, close } = createDb({ max: 1 });\n try {\n const n = await revokeKey(db, prefixOrId);\n if (n === 0) {\n logger.warn(`No active key matched \"${prefixOrId}\".`);\n process.exitCode = 1;\n return;\n }\n console.log(`Revoked ${n} key(s) matching \"${prefixOrId}\".`);\n } finally {\n await close();\n }\n}\n","/**\n * Load the curated seed list (§16) into `seed_packages`. Idempotent: re-running\n * upserts category and leaves `added_at` intact for existing rows.\n */\nimport { readFileSync } from 'node:fs';\nimport { sql } from 'drizzle-orm';\nimport { z } from 'zod';\nimport { CATEGORIES, type Category } from '../core/types';\nimport { logger } from '../core/logger';\nimport { seedJsonPath } from '../core/paths';\nimport type { Database } from './client';\nimport { seedPackages } from './schema';\n\nconst SeedEntrySchema = z.object({\n name: z.string().min(1),\n category: z.enum(CATEGORIES as unknown as [Category, ...Category[]]).optional(),\n});\nconst SeedFileSchema = z.array(SeedEntrySchema);\n\nexport interface SeedEntry {\n name: string;\n category?: Category;\n}\n\nexport function loadSeedFile(path = seedJsonPath()): SeedEntry[] {\n const raw = JSON.parse(readFileSync(path, 'utf8'));\n const parsed = SeedFileSchema.parse(raw);\n // De-duplicate by name (first occurrence wins) so a package can't be seeded twice.\n const byName = new Map<string, SeedEntry>();\n for (const entry of parsed) {\n if (!byName.has(entry.name)) byName.set(entry.name, entry);\n }\n return [...byName.values()];\n}\n\nexport async function loadSeedPackages(db: Database, path?: string): Promise<number> {\n const entries = loadSeedFile(path);\n if (entries.length === 0) return 0;\n await db\n .insert(seedPackages)\n .values(entries.map((e) => ({ name: e.name, category: e.category ?? null })))\n .onConflictDoUpdate({\n target: seedPackages.name,\n // Refresh category to the incoming value on conflict (EXCLUDED.category).\n set: { category: sql`excluded.category` },\n });\n logger.info(`Loaded ${entries.length} packages into seed_packages.`);\n return entries.length;\n}\n","/**\n * Schema management for `lurq db migrate` / `lurq db reset`.\n *\n * `migrate` ensures the pgvector extension exists (Drizzle does not create it),\n * applies generated migrations, then loads the curated seed list (§18 M1).\n * `reset` drops the public schema and re-runs migrate — destructive.\n */\nimport { migrate } from 'drizzle-orm/postgres-js/migrator';\nimport { logger } from '../core/logger';\nimport { migrationsDir } from '../core/paths';\nimport { createDb, type DbHandle } from './client';\nimport { loadSeedPackages } from './seed';\n\nasync function ensureVectorExtension(handle: DbHandle): Promise<void> {\n // Non-fatal: if the extension already exists (it must, once migration 0000's\n // `vector` column is in place) this is a no-op, and a transient hiccup here\n // must NOT abort the migrator and leave later migrations (0001+) unapplied.\n try {\n await handle.sql`CREATE EXTENSION IF NOT EXISTS vector`;\n } catch (err) {\n logger.warn(\n `CREATE EXTENSION vector did not run cleanly (continuing to migrations): ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n}\n\nexport async function runMigrate(): Promise<void> {\n // A single, non-pooled connection is best for migrations.\n const handle = createDb({ max: 1 });\n try {\n logger.info('Ensuring pgvector extension…');\n await ensureVectorExtension(handle);\n\n logger.info('Applying migrations…');\n await migrate(handle.db, { migrationsFolder: migrationsDir() });\n\n logger.info('Loading seed list…');\n await loadSeedPackages(handle.db);\n\n logger.info('Migration complete.');\n } finally {\n await handle.close();\n }\n}\n\nexport async function runReset(): Promise<void> {\n const handle = createDb({ max: 1 });\n try {\n logger.warn('Dropping schema `public` (destructive)…');\n await handle.sql.unsafe('DROP SCHEMA IF EXISTS public CASCADE; CREATE SCHEMA public;');\n // Drizzle tracks applied migrations in its own schema; clear it too.\n await handle.sql`DROP SCHEMA IF EXISTS drizzle CASCADE`;\n } finally {\n await handle.close();\n }\n // Re-apply everything from scratch.\n await runMigrate();\n logger.info('Reset complete.');\n}\n","#!/usr/bin/env node\n/**\n * lurq CLI entry point. Runnable via `npx lurq <command>` (§7, §13).\n */\nimport { buildProgram } from '../cli/index';\nimport { loadEnv } from '../core/config';\nimport { logger } from '../core/logger';\n\nloadEnv();\n\nbuildProgram()\n .parseAsync(process.argv)\n .catch((err) => {\n logger.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n });\n","/**\n * CLI command wiring (§13). Built with commander. Each command mirrors an MCP\n * tool or an operational task. Handlers are filled in across milestones M1–M7;\n * the command/option surface here is the final, stable shape.\n *\n * Every command supports `--json` for machine-readable output.\n */\nimport { Command } from 'commander';\nimport { SERVER_NAME, VERSION } from '../core/constants';\n\nexport function buildProgram(): Command {\n const program = new Command();\n\n program\n .name(SERVER_NAME)\n .description(\n 'lurq - a fresh, objectively-scored index of JS/TS packages for AI coding agents.',\n )\n .version(VERSION, '-v, --version', 'output the lurq version');\n\n program\n .command('serve')\n .description('start the MCP server over stdio (for agent integration)')\n .action(async () => {\n const { startMcpServer } = await import('../mcp/server');\n await startMcpServer();\n });\n\n program\n .command('serve-http')\n .description('start the hosted MCP server over HTTP with API-key auth')\n .option('--port <n>', 'port to listen on (default: $PORT or 8080)', (v) => parseInt(v, 10))\n .action(async (opts: { port?: number }) => {\n const { startHttpServer } = await import('../mcp/http');\n await startHttpServer({ port: opts.port });\n });\n\n program\n .command('sync')\n .description('run ingestion: refresh scores for the seed list (or one package)')\n .option('--full', 'force a full re-sync, ignoring cache TTLs')\n .option('--package <name>', 'sync a single package by name')\n .option('--json', 'output the run summary as JSON')\n .action(async (opts: { full?: boolean; package?: string; json?: boolean }) => {\n const { runSync } = await import('../pipeline/index');\n const summary = await runSync({ full: opts.full, packageName: opts.package });\n if (opts.json) console.log(JSON.stringify(summary, null, 2));\n if (summary.status === 'failed') process.exitCode = 1;\n });\n\n program\n .command('recommend')\n .argument('<need>', 'natural-language description of what you need')\n .description('recommend the best current packages for a described need')\n .option('--category <category>', 'restrict to a taxonomy category')\n .option('--min-confidence <level>', 'proven | emerging | promising | unproven')\n .option('--json', 'output JSON instead of a table')\n .action(async (need: string, opts: { category?: string; minConfidence?: string; json?: boolean }) => {\n const { runRecommend } = await import('./commands');\n await runRecommend(need, opts);\n });\n\n program\n .command('evaluate')\n .argument('<package>', 'npm package name')\n .description('full evidence read for one package (scores, signals, usage guide)')\n .option('--json', 'output JSON instead of a table')\n .action(async (pkg: string, opts: { json?: boolean }) => {\n const { runEvaluate } = await import('./commands');\n await runEvaluate(pkg, opts);\n });\n\n program\n .command('compare')\n .argument('<packages...>', '2–5 npm package names')\n .description('side-by-side comparison of packages, ranked by health')\n .option('--json', 'output JSON instead of a table')\n .action(async (pkgs: string[], opts: { json?: boolean }) => {\n const { runCompare } = await import('./commands');\n await runCompare(pkgs, opts);\n });\n\n program\n .command('verify')\n .argument('<package>', 'npm package name')\n .description('safety check: is this package real, healthy, and not risky?')\n .option('--json', 'output JSON instead of a table')\n .action(async (pkg: string, opts: { json?: boolean }) => {\n const { runVerify } = await import('./commands');\n await runVerify(pkg, opts);\n });\n\n program\n .command('weights')\n .description('show and explain the scoring weight model (health, quality, composite λ)')\n .option('--json', 'output the weight model as JSON')\n .action(async (opts: { json?: boolean }) => {\n const { runWeights } = await import('./commands');\n runWeights(opts);\n });\n\n program\n .command('edit-weights')\n .description('override, reset, or explain the scoring weights (layered over defaults)')\n .option('--set <pair>', 'override key=value, e.g. composite.lambda=0.5 (repeatable)', (v: string, acc: string[]) => acc.concat(v), [])\n .option('--reset', 'remove all overrides and restore defaults')\n .option('--explain <component>', 'explain a component (e.g. adoption, quality, lambda)')\n .option('--project', 'write to project-local .lurq/weights.json instead of the user config')\n .action(async (opts: { set?: string[]; reset?: boolean; explain?: string; project?: boolean }) => {\n const { runEditWeights } = await import('./commands');\n runEditWeights(opts);\n });\n\n program\n .command('discover')\n .description('operator-side: proactively crawl for new packages and queue/gate them (§2B)')\n .option('--cap <n>', 'max candidates to fully ingest this run', (v) => parseInt(v, 10))\n .option('--dry-run', 'discover, queue, and gate, but do not ingest survivors')\n .option('--json', 'output the discovery summary as JSON')\n .action(async (opts: { cap?: number; dryRun?: boolean; json?: boolean }) => {\n const { requireConfig } = await import('../core/config');\n requireConfig(['DATABASE_URL']);\n const { runDiscovery } = await import('../pipeline/index');\n const summary = await runDiscovery({ perRunCap: opts.cap, dryRun: opts.dryRun });\n if (opts.json) console.log(JSON.stringify(summary, null, 2));\n });\n\n program\n .command('rescore')\n .description('re-derive health scores from cached breakdowns using current weights (no re-ingest)')\n .option('--json', 'output the rescore summary as JSON')\n .action(async (opts: { json?: boolean }) => {\n const { requireConfig } = await import('../core/config');\n requireConfig(['DATABASE_URL']);\n const { runRescore } = await import('../pipeline/index');\n const summary = await runRescore();\n if (opts.json) console.log(JSON.stringify(summary, null, 2));\n });\n\n program\n .command('install')\n .description('guided setup: connect lurq to your AI assistant(s)')\n .option('--api-key <key>', 'hosted API key (skips the prompt)')\n .option('--url <url>', 'hosted endpoint URL (defaults to the lurq service)')\n .option('--agent <agent>', 'claude-code | cursor | copilot | windsurf | codex | all')\n .option('--yes', 'non-interactive: use flags/env and detected agents without prompting')\n .action(async (opts: { apiKey?: string; url?: string; agent?: string; yes?: boolean }) => {\n const { runInstallWizard } = await import('./install');\n await runInstallWizard(opts);\n });\n\n program\n .command('install-skill')\n .description('register lurq as an MCP server in supported AI assistants (scriptable)')\n .option(\n '--agent <agent>',\n 'claude-code | cursor | copilot | windsurf | codex | all',\n 'claude-code',\n )\n .option('--api-key <key>', 'hosted API key (remote install; default mode)')\n .option('--url <url>', 'hosted endpoint URL (defaults to the lurq service)')\n .option('--local', 'self-host: write a local stdio entry using your own DATABASE_URL')\n .action(async (opts: { agent?: string; apiKey?: string; url?: string; local?: boolean }) => {\n const { runInstallSkill } = await import('./installSkill');\n await runInstallSkill(opts);\n });\n\n const keys = program\n .command('keys')\n .description('manage API keys for the hosted service (operator; needs DATABASE_URL)');\n keys\n .command('create')\n .description('create a new API key (shown once; erased from the terminal after you copy it)')\n .option('--label <label>', 'human label (owner / org / purpose)')\n .option('--tier <tier>', 'tier name', 'free')\n .option('--json', 'print the key as JSON and skip the interactive erase (for scripts)')\n .action(async (opts: { label?: string; tier?: string; json?: boolean }) => {\n const { runKeysCreate } = await import('./keys');\n await runKeysCreate(opts);\n });\n keys\n .command('list')\n .description('list issued API keys (hashes are never shown)')\n .option('--json', 'output as JSON')\n .action(async (opts: { json?: boolean }) => {\n const { runKeysList } = await import('./keys');\n await runKeysList(opts);\n });\n keys\n .command('revoke')\n .argument('<prefixOrId>', 'key prefix (e.g. lurq_live_ab12cd) or numeric id')\n .description('revoke an API key')\n .action(async (prefixOrId: string) => {\n const { runKeysRevoke } = await import('./keys');\n await runKeysRevoke(prefixOrId);\n });\n\n const db = program.command('db').description('database management');\n db.command('migrate')\n .description('apply database migrations and load the seed list')\n .action(async () => {\n const { runMigrate } = await import('../db/migrate');\n await runMigrate();\n });\n db.command('reset')\n .description('drop and recreate the schema (destructive)')\n .option('--yes', 'skip the confirmation prompt')\n .action(async (opts: { yes?: boolean }) => {\n if (!opts.yes) {\n console.error(\n 'Refusing to reset without confirmation. Re-run with `--yes` to drop and recreate the schema.',\n );\n process.exitCode = 1;\n return;\n }\n const { runReset } = await import('../db/migrate');\n await runReset();\n });\n\n return program;\n}\n"],"mappings":"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","names":["table","sql","cached","attempt","text","json","HOST","json","HOST","json","HOST","json","HOST","json","HOST","HOST","text","text","existsSync","homedir","dirname","join","fileURLToPath","existsSync","dirname","eq","path","createHash","text","str","dim","sql","index","eq","sql","median","and","eq","isNotNull","sql","sql","DAY_MS","text","z","createHash","and","eq","init_http","isNotNull","eq","eq","inArray","sql","isNotNull","init_discovery","init_discovery","text","path","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","dirname","join","path","text","selected","readFileSync","sql","z","path","startMcpServer","startHttpServer","runSync","runRecommend","runEvaluate","runCompare","runVerify","runWeights","runEditWeights","requireConfig","runDiscovery","runRescore","runInstallWizard","runInstallSkill","runKeysCreate","runKeysList","runKeysRevoke","runMigrate","runReset"]}
1
+ {"version":3,"sources":["../../node_modules/tsup/assets/esm_shims.js","../../src/core/constants.ts","../../src/core/types.ts","../../src/core/config.ts","../../src/db/schema.ts","../../src/db/client.ts","../../src/core/logger.ts","../../src/core/cache.ts","../../src/db/compat.ts","../../src/core/http.ts","../../src/ingestion/sources/npmRegistry.ts","../../src/ingestion/sources/npmSearch.ts","../../src/ingestion/sources/npmDownloads.ts","../../src/ingestion/sources/github.ts","../../src/ingestion/sources/depsDev.ts","../../src/ingestion/sources/bundlephobia.ts","../../src/ingestion/sources/index.ts","../../src/compat/members.ts","../../src/compat/peerCompat.ts","../../src/compat/check.ts","../../src/db/packages.ts","../../src/db/verification.ts","../../src/db/outcomes.ts","../../src/data/successors.json","../../src/core/successors.ts","../../src/ingestion/sources/githubReadme.ts","../../src/ingestion/summarize.ts","../../src/ingestion/collect.ts","../../src/search/categoryInference.ts","../../src/core/paths.ts","../../src/scoring/weights.ts","../../src/scoring/score.ts","../../src/scoring/index.ts","../../src/search/embeddings.ts","../../src/core/concurrency.ts","../../src/pipeline/sync.ts","../../src/pipeline/ingestQueue.ts","../../src/pipeline/single.ts","../../src/search/recommend.ts","../../src/security/risk.ts","../../src/data/popular-packages.json","../../src/security/typosquat.ts","../../src/mcp/handlers.ts","../../src/mcp/diagram.ts","../../src/compat/optimize.ts","../../src/mcp/plan.ts","../../src/mcp/metrics.ts","../../src/mcp/compact.ts","../../src/mcp/server.ts","../../src/auth/apiKeys.ts","../../src/mcp/http.ts","../../src/pipeline/rescore.ts","../../src/db/discovery.ts","../../src/pipeline/discovery.ts","../../src/pipeline/index.ts","../../src/cli/format.ts","../../src/cli/planView.ts","../../src/db/watch.ts","../../src/pipeline/watch.ts","../../src/sandbox/types.ts","../../src/sandbox/local.ts","../../src/sandbox/e2b.ts","../../src/sandbox/index.ts","../../src/pipeline/sandbox.ts","../../src/pipeline/compat.ts","../../src/cli/commands.ts","../../src/cli/installSkill.ts","../../src/cli/install.ts","../../src/cli/keys.ts","../../src/db/seed.ts","../../src/db/migrate.ts","../../src/bin/lurq.ts","../../src/cli/index.ts","../../src/core/gate.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","/** Static identifiers shared across the CLI and MCP server. */\nexport const SERVER_NAME = 'lurq';\n/** Published npm package name (the CLI command and MCP nickname stay `lurq`).\n * Keep in sync with package.json \"name\". */\nexport const PACKAGE_NAME = 'lurqrun';\n/** Keep in sync with package.json \"version\". */\nexport const VERSION = '0.0.4';\n\n/** Default hosted endpoint the install wizard writes into agent configs. The\n * marketing site is `lurq.run`; the MCP service lives on the `api.` subdomain.\n * Overridable per-invocation with `lurq install --url …` or `LURQ_ENDPOINT`. */\nexport const DEFAULT_ENDPOINT = 'https://api.lurq.run/mcp';\n\n/** Prefix for issued API keys (the rest is high-entropy random). */\nexport const API_KEY_PREFIX = 'lurq_live_';\n\n/** Embedding vector dimensionality (OpenAI text-embedding-3-small). The local\n * fallback embedder produces vectors of the same length so the DB column and\n * pgvector index never need to change. */\nexport const EMBEDDING_DIM = 1536;\n\n/** A package row is flagged `stale: true` in tool responses once its data is\n * older than this (§17). */\nexport const STALENESS_DAYS = 7;\n\nconst HOUR = 60 * 60 * 1000;\nconst DAY = 24 * HOUR;\n\n/** Per-source persistent-cache TTLs (§17). */\nexport const CACHE_TTL = {\n npmRegistry: 6 * HOUR,\n npmDownloads: 12 * HOUR,\n github: 12 * HOUR,\n depsDev: 24 * HOUR,\n bundlephobia: 7 * DAY,\n} as const;\n","/**\n * Shared domain types and the v1 category taxonomy (§8.3).\n * These are the stable contracts the rest of the system builds on.\n */\n\n/** Category taxonomy for the JS/TS web stack (§8.3). `other` is the fallback. */\nexport const CATEGORIES = [\n 'framework',\n 'meta-framework',\n 'state-management',\n 'routing',\n 'orm',\n 'database-client',\n 'ui-component-library',\n 'styling',\n 'forms',\n 'validation',\n 'data-fetching',\n 'http-client',\n 'auth',\n 'testing',\n 'build-tool',\n 'bundler',\n 'linting',\n 'date-time',\n 'animation',\n 'charts',\n 'i18n',\n 'utility',\n 'other',\n] as const;\n\nexport type Category = (typeof CATEGORIES)[number];\n\nexport function isCategory(value: string): value is Category {\n return (CATEGORIES as readonly string[]).includes(value);\n}\n\n/** Provenance of a package's stored category (§2A). `curated` comes from the\n * seed file or a manual arg; `inferred` was assigned automatically at ingest\n * and is safe for a later curation pass to override. */\nexport type CategorySource = 'curated' | 'inferred';\n\n/** How a candidate entered the discovery queue (§2B). `dependency-graph` and\n * `recent` are the long-tail channels; `category-search` is keyword-seeded;\n * `reactive` is an on-demand query that wasn't tracked yet. */\nexport type DiscoverySource = 'dependency-graph' | 'category-search' | 'recent' | 'reactive';\n\n/** Lifecycle of a discovery-queue candidate (§2B). */\nexport type DiscoveryStatus = 'pending' | 'ingested' | 'rejected';\n\n/**\n * Categories for which bundle size is meaningful and Bundlephobia is consulted\n * (§9.5). Backend-only categories get a null bundle size, and their efficiency\n * weight is redistributed (§10, see scoring).\n */\nexport const FRONTEND_CATEGORIES = [\n 'ui-component-library',\n 'styling',\n 'state-management',\n 'forms',\n 'validation',\n 'data-fetching',\n 'charts',\n 'animation',\n 'date-time',\n 'utility',\n] as const;\n\nexport function isFrontendCategory(category: Category | null | undefined): boolean {\n return category != null && (FRONTEND_CATEGORIES as readonly string[]).includes(category);\n}\n\n/**\n * Evidence-trustworthiness label, independent of the numeric score (§10, §1).\n * Two-dimensional: `proven`/`emerging` are adoption ladders; `promising` is\n * adoption-independent (high intrinsic quality, new package).\n */\nexport type Confidence = 'proven' | 'emerging' | 'promising' | 'unproven';\n\nexport type Runtime = 'browser' | 'node' | 'both';\n\n/** Result of co-installing two package versions in the sandbox (compat matrix). */\nexport type CompatStatus = 'compatible' | 'conflict';\n\n/** Coarse post-install result an agent reports back via `report_outcome` — never\n * source code, just whether the recommended package installed / compiled /\n * passed tests, or failed. Feeds the recommendation→outcome flywheel (§3.1). */\nexport type BuildSignal = 'installed' | 'compiled' | 'tests_passed' | 'failed';\n\n/** Sandbox verdict surfaced to agents: did this version actually install + load? */\nexport interface BuildVerified {\n version: string;\n installed: boolean;\n loaded: boolean | null;\n driver: string;\n ranAt: string;\n}\n\n/** A map of dependency/peer/engine name → semver range (from a manifest). */\nexport type DependencyRanges = Record<string, string>;\n/** `peerDependenciesMeta`: per-peer flags, notably `{ optional: true }`. */\nexport type PeerMeta = Record<string, { optional?: boolean }>;\n\n/** One incompatibility found across a set of packages. */\nexport interface CompatConflict {\n /** Where the conflict came from. `peer-deps`/`engines` are Tier-1 (metadata,\n * instant, deterministic); `sandbox` is Tier-2 (empirical co-install). */\n source: 'peer-deps' | 'engines' | 'sandbox';\n /** The packages involved in the conflict. */\n packages: string[];\n detail: string;\n}\n\n/**\n * `compat` output: whole-architecture compatibility for a set of packages.\n * Tier-1 peer-dependency/engine analysis + any Tier-2 sandbox conflicts.\n */\nexport interface CompatOutput {\n packages: string[];\n overall: 'compatible' | 'conflict' | 'unknown';\n conflicts: CompatConflict[];\n /** Packages lurq has no compatibility metadata for (counted toward `unknown`). */\n unverified: string[];\n /** The exact members the check ran over, name + resolved version. Versions are\n * always surfaced here, and the structure is stable for later scraping. */\n checked: { name: string; version: string | null }[];\n}\n\nexport type AdvisorySeverity = 'critical' | 'high' | 'moderate' | 'low' | 'info';\n\nexport interface Advisory {\n id: string;\n severity: AdvisorySeverity;\n summary: string;\n}\n\n/** Sub-scores composing the health score (§10). `efficiency` is null when not\n * size-based (backend categories) — its weight is redistributed.\n * `quality` (§1) is a standalone, adoption-independent axis — it does NOT feed\n * the health composite; it blends with health only at ranking time. Null when\n * no manifest signals were available. */\nexport interface ScoreBreakdown {\n maintenance: number;\n adoption: number;\n reliability: number;\n efficiency: number | null;\n quality: number | null;\n}\n\n/**\n * Structured usage guide generated at ingest (product refinement: lurq explains,\n * not just ranks). Grounded in the package README/description — never fabricated.\n * Exact current API specifics are deferred to Context7 via `context7Hint`.\n */\nexport interface UsageGuide {\n whatItIs: string;\n whenToUse: string;\n whenNotToUse?: string;\n whereItFits: string;\n howToWireIn?: string;\n context7Hint?: string;\n}\n\n/** A single recommendation candidate (§12.3.1). Intentionally compact. */\nexport interface Candidate {\n name: string;\n category: Category | null;\n healthScore: number;\n qualityScore: number | null;\n confidence: Confidence;\n why: string;\n latestVersion: string | null;\n weeklyDownloads: number | null;\n lastReleaseAt: string | null;\n repoUrl: string | null;\n}\n\n/** Full evidence read for one package (§12.3.2). */\nexport interface EvaluateOutput {\n dataAsOf: string;\n stale?: boolean;\n name: string;\n category: Category | null;\n healthScore: number;\n qualityScore: number | null;\n confidence: Confidence;\n scoreBreakdown: ScoreBreakdown;\n latestVersion: string | null;\n lastReleaseAt: string | null;\n weeklyDownloads: number | null;\n downloadGrowth90d: number | null;\n scorecard: number | null;\n bundleMinGzipKb: number | null;\n deprecated: boolean;\n archived: boolean;\n advisories: Advisory[];\n summary: string | null;\n usageGuide: UsageGuide | null;\n repoUrl: string | null;\n /** If this package is superseded, the recommended migration target (§1.2). */\n replacedBy?: { name: string; reason: string } | null;\n /** Latest sandbox verdict for this package, if one has been run. */\n buildVerified?: BuildVerified | null;\n}\n\n/** `verify` output (§12.3.4). */\n/** Supply-chain risk gate: high = review before installing (see security/risk). */\nexport type RiskLevel = 'low' | 'medium' | 'high';\n\nexport interface VerifyOutput {\n exists: boolean;\n tracked: boolean;\n deprecated: boolean;\n archived: boolean;\n latestVersion: string | null;\n weeklyDownloads: number | null;\n riskFlags: string[];\n /** Overall supply-chain risk, rolled up from riskFlags. */\n risk: RiskLevel;\n /** Suspected typosquat target — a popular package this name closely mimics. */\n typosquatOf: string | null;\n confidence: Confidence | null;\n advisoryCount: number;\n}\n","/**\n * Environment configuration (§15). Validated with zod. Most vars are optional\n * so the CLI can run partially (e.g. `lurq --help`) without a full setup;\n * commands that need a specific var call `requireConfig` to fail fast with a\n * clear message.\n */\nimport { config as dotenvConfig } from 'dotenv';\nimport { z } from 'zod';\n\nlet envLoaded = false;\n\n/** Load `.env` into process.env exactly once. Safe to call repeatedly. */\nexport function loadEnv(): void {\n if (envLoaded) return;\n dotenvConfig();\n envLoaded = true;\n}\n\nconst EnvSchema = z.object({\n DATABASE_URL: z.string().min(1).optional(),\n GITHUB_TOKEN: z.string().min(1).optional(),\n\n // 'openai' here means \"OpenAI-compatible\" — any provider exposing /v1/embeddings\n // + Bearer auth (OpenAI, Together, Fireworks, HF TEI, …). Point *_BASE_URL at it.\n EMBEDDING_PROVIDER: z.enum(['openai', 'local']).default('openai'),\n EMBEDDING_API_KEY: z.string().min(1).optional(),\n EMBEDDING_MODEL: z.string().min(1).default('text-embedding-3-small'),\n EMBEDDING_BASE_URL: z.string().url().default('https://api.openai.com/v1'),\n\n // 'openai' means \"OpenAI-compatible /v1/chat/completions\": OpenAI, Groq, Together,\n // Fireworks, xAI (Grok), etc. Swap provider by setting SUMMARY_BASE_URL + key + model.\n SUMMARY_PROVIDER: z.enum(['openai', 'none']).default('openai'),\n SUMMARY_API_KEY: z.string().min(1).optional(),\n SUMMARY_MODEL: z.string().min(1).default('gpt-4o-mini'),\n SUMMARY_BASE_URL: z.string().url().default('https://api.openai.com/v1'),\n\n LURQ_SYNC_CONCURRENCY: z.coerce.number().int().positive().max(50).default(5),\n LOG_LEVEL: z.enum(['error', 'warn', 'info', 'debug']).default('info'),\n\n // Hosted HTTP service (`serve-http`). Server-side only.\n PORT: z.coerce.number().int().positive().default(8080),\n /** Per-API-key rate limit: max requests per window. */\n LURQ_RATE_LIMIT_MAX: z.coerce.number().int().positive().default(120),\n /** Coarser per-IP rate limit (blunts unauthenticated floods before auth). */\n LURQ_IP_RATE_LIMIT_MAX: z.coerce.number().int().positive().default(240),\n /** Rate-limit window, milliseconds (applies to both limiters). */\n LURQ_RATE_LIMIT_WINDOW_MS: z.coerce.number().int().positive().default(60_000),\n /** Bearer token guarding `/metrics`. Unset → the endpoint is disabled (404). */\n LURQ_METRICS_TOKEN: z.string().min(1).optional(),\n /** Shared secret for self-serve key issuance (`POST /keys`). The Clerk-\n * authenticated web app presents it to mint a key for a signed-in user. Unset\n * → the endpoint is disabled (404). Keep it server-side, never in the client. */\n LURQ_ISSUER_SECRET: z.string().min(1).optional(),\n\n // Client-side (install wizard / CLI talking to a remote endpoint).\n LURQ_ENDPOINT: z.string().url().optional(),\n LURQ_API_KEY: z.string().min(1).optional(),\n\n // Sandbox verification. With E2B_API_KEY set, package install + smoke-load\n // runs in an isolated E2B cloud sandbox (safe for UNTRUSTED packages);\n // without it, the local child-process driver is used (trusted packages only).\n E2B_API_KEY: z.string().min(1).optional(),\n // E2B template to launch. Must provide node + npm on PATH; omit for E2B's\n // default. Provision a Node-versioned template here for reproducible runs.\n E2B_TEMPLATE: z.string().min(1).optional(),\n});\n\nexport type Config = z.infer<typeof EnvSchema>;\n\nexport class ConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ConfigError';\n }\n}\n\nlet cached: Config | undefined;\n\n/** Parse + validate the environment. Throws ConfigError on malformed values. */\nexport function getConfig(): Config {\n if (cached) return cached;\n loadEnv();\n const parsed = EnvSchema.safeParse(process.env);\n if (!parsed.success) {\n const issues = parsed.error.issues\n .map((i) => ` - ${i.path.join('.')}: ${i.message}`)\n .join('\\n');\n throw new ConfigError(`Invalid environment configuration:\\n${issues}`);\n }\n cached = parsed.data;\n return cached;\n}\n\n/** For tests: clear the memoized config so a fresh getConfig() re-reads\n * process.env. Does not force a `.env` reload (loadEnv stays idempotent). */\nexport function resetConfigCache(): void {\n cached = undefined;\n}\n\n/**\n * Return the config but fail fast if any of the named required keys are absent.\n * Use in command handlers that genuinely need them (e.g. sync needs DATABASE_URL).\n */\nexport function requireConfig<K extends keyof Config>(keys: K[]): Config {\n const config = getConfig();\n const missing = keys.filter((k) => config[k] === undefined || config[k] === '');\n if (missing.length > 0) {\n throw new ConfigError(\n `Missing required environment variable(s): ${missing.join(', ')}.\\n` +\n `See .env.example for setup. Tip: copy it to .env and fill in the values.`,\n );\n }\n return config;\n}\n","/**\n * Drizzle schema (§8). One denormalized `packages` table feeds all reads (§8.2),\n * plus `sync_runs` (ingestion audit) and `seed_packages` (curated bootstrap list).\n *\n * The `vector` extension must exist before these migrations apply — `db migrate`\n * runs `CREATE EXTENSION IF NOT EXISTS vector` first (pgvector is not created\n * automatically by Drizzle).\n */\nimport { sql } from 'drizzle-orm';\nimport {\n bigint,\n boolean,\n customType,\n index,\n integer,\n jsonb,\n pgTable,\n primaryKey,\n real,\n serial,\n text,\n timestamp,\n uniqueIndex,\n vector,\n} from 'drizzle-orm/pg-core';\nimport { EMBEDDING_DIM } from '../core/constants';\n\n/** Postgres full-text `tsvector` type for hybrid lexical search (§3). */\nconst tsvector = customType<{ data: string; driverData: string }>({\n dataType() {\n return 'tsvector';\n },\n});\nimport type {\n Advisory,\n BuildSignal,\n Category,\n CategorySource,\n CompatStatus,\n Confidence,\n DependencyRanges,\n DiscoverySource,\n DiscoveryStatus,\n PeerMeta,\n ScoreBreakdown,\n UsageGuide,\n} from '../core/types';\n\nconst ts = (name: string) => timestamp(name, { withTimezone: true, mode: 'date' });\n\n/** One row per tracked npm package. */\nexport const packages = pgTable(\n 'packages',\n {\n id: serial('id').primaryKey(),\n name: text('name').notNull().unique(),\n ecosystem: text('ecosystem').notNull().default('npm'),\n\n // Classification + descriptive text\n category: text('category').$type<Category>(),\n /** Whether `category` was hand-curated or inferred at ingest (§2A). */\n categorySource: text('category_source').$type<CategorySource>(),\n description: text('description'),\n summary: text('summary'),\n repoUrl: text('repo_url'),\n homepage: text('homepage'),\n latestVersion: text('latest_version'),\n license: text('license'),\n\n // Lifecycle flags\n deprecated: boolean('deprecated').notNull().default(false),\n archived: boolean('archived').notNull().default(false),\n\n // Age / maintenance signals\n firstPublishedAt: ts('first_published_at'),\n lastReleaseAt: ts('last_release_at'),\n\n // Adoption signals\n weeklyDownloads: bigint('weekly_downloads', { mode: 'number' }),\n downloadGrowth90d: real('download_growth_90d'),\n stars: integer('stars'),\n openIssues: integer('open_issues'),\n closedIssues: integer('closed_issues'),\n\n // Reliability / efficiency signals\n scorecard: real('scorecard'),\n bundleMinGzipKb: real('bundle_min_gzip_kb'),\n advisories: jsonb('advisories').$type<Advisory[]>(),\n\n // Compatibility metadata (Tier-1): declared peer-deps + engines of the\n // latest version, so a whole-stack peer-range check is one indexed query.\n peerDependencies: jsonb('peer_dependencies').$type<DependencyRanges>(),\n peerDependenciesMeta: jsonb('peer_dependencies_meta').$type<PeerMeta>(),\n engines: jsonb('engines').$type<DependencyRanges>(),\n\n // Computed outputs\n healthScore: integer('health_score'),\n /** Intrinsic-quality axis (§1), adoption-independent. Blends with health at\n * ranking time (composite); never folded into health_score itself. */\n qualityScore: integer('quality_score'),\n confidence: text('confidence').$type<Confidence>(),\n scoreBreakdown: jsonb('score_breakdown').$type<ScoreBreakdown>(),\n usageGuide: jsonb('usage_guide').$type<UsageGuide>(),\n embedding: vector('embedding', { dimensions: EMBEDDING_DIM }),\n // Identity of the vector space `embedding` was produced in (e.g.\n // `openai:text-embedding-3-small`, `local`). Vector search filters on the\n // active provider so switching models can't compare incompatible spaces.\n embeddingProvider: text('embedding_provider'),\n\n // Lexical search vector (§3): name weighted highest (A), then category (B),\n // then summary/description (C). Generated + STORED so it stays in sync with\n // the row automatically; indexed with GIN for fast `@@` matching.\n searchVector: tsvector('search_vector').generatedAlwaysAs(\n sql`setweight(to_tsvector('english', coalesce(name, '')), 'A') || setweight(to_tsvector('english', coalesce(category, '')), 'B') || setweight(to_tsvector('english', coalesce(summary, description, '')), 'C')`,\n ),\n\n // Freshness + bookkeeping\n dataAsOf: timestamp('data_as_of', { withTimezone: true, mode: 'date' }),\n createdAt: ts('created_at').notNull().defaultNow(),\n updatedAt: ts('updated_at').notNull().defaultNow(),\n },\n (table) => [\n index('packages_category_idx').on(table.category),\n index('packages_health_score_idx').on(table.healthScore),\n // pgvector HNSW index for cosine similarity search (§11).\n index('packages_embedding_idx').using('hnsw', table.embedding.op('vector_cosine_ops')),\n // GIN index for lexical full-text search (§3).\n index('packages_search_vector_idx').using('gin', table.searchVector),\n ],\n);\n\n/** Ingestion audit trail (§8.1). */\nexport const syncRuns = pgTable('sync_runs', {\n id: serial('id').primaryKey(),\n startedAt: ts('started_at').notNull().defaultNow(),\n finishedAt: ts('finished_at'),\n packagesSeen: integer('packages_seen').notNull().default(0),\n packagesUpdated: integer('packages_updated').notNull().default(0),\n errors: jsonb('errors').$type<SyncError[]>().notNull().default([]),\n status: text('status').$type<SyncStatus>().notNull().default('running'),\n});\n\n/** Curated v1 seed list (§16), loaded from seed.json. */\nexport const seedPackages = pgTable('seed_packages', {\n name: text('name').primaryKey(),\n category: text('category').$type<Category>(),\n addedAt: ts('added_at').notNull().defaultNow(),\n});\n\n/**\n * Proactive-discovery candidate queue (§2B). Operator-side: the crawler enqueues\n * adjacency-graph / category-search / recent candidates here, a merit gate\n * pre-scores them on quality signals only (downloads excluded), and survivors\n * graduate to full ingestion. Keeps cost bounded and the DB free of toy packages.\n */\nexport const discoveryQueue = pgTable(\n 'discovery_queue',\n {\n id: serial('id').primaryKey(),\n name: text('name').notNull().unique(),\n discoveredVia: text('discovered_via').$type<DiscoverySource>().notNull(),\n /** Lightweight quality-only pre-score (§2B). Null until the gate runs. */\n preScore: integer('pre_score'),\n status: text('status').$type<DiscoveryStatus>().notNull().default('pending'),\n discoveredAt: ts('discovered_at').notNull().defaultNow(),\n },\n (table) => [index('discovery_queue_status_idx').on(table.status)],\n);\n\n/**\n * API keys for the hosted HTTP service (docs/lurq-hosted-deployment.md §5). Each\n * user/org gets a key; only its sha256 hash is persisted, so a DB leak never\n * exposes a usable key — the plaintext is shown exactly once at creation.\n * `ownerId` is reserved for future self-serve issuance via the Clerk dashboard.\n */\nexport const apiKeys = pgTable(\n 'api_keys',\n {\n id: serial('id').primaryKey(),\n /** sha256 hex of the full key — the only form persisted. */\n keyHash: text('key_hash').notNull().unique(),\n /** Identifiable display prefix, e.g. `lurq_live_ab12cd` (safe to show/log). */\n prefix: text('prefix').notNull(),\n /** Free-text label (owner / org / purpose). */\n label: text('label'),\n /** Reserved for self-serve issuance: maps to a Clerk user id. */\n ownerId: text('owner_id'),\n tier: text('tier').notNull().default('free'),\n createdAt: ts('created_at').notNull().defaultNow(),\n lastUsedAt: ts('last_used_at'),\n revokedAt: ts('revoked_at'),\n },\n (table) => [index('api_keys_owner_idx').on(table.ownerId)],\n);\n\n/**\n * Per-package version timeline (versions + publish dates), ingested from the npm\n * packument on every sync. Foundation for upgrade/migration intelligence and the\n * compatibility matrix; refreshed reactively by the `_changes` follower.\n */\nexport const packageVersions = pgTable(\n 'package_versions',\n {\n packageName: text('package_name').notNull(),\n version: text('version').notNull(),\n publishedAt: ts('published_at'),\n },\n (table) => [\n primaryKey({ columns: [table.packageName, table.version] }),\n index('package_versions_name_published_idx').on(table.packageName, table.publishedAt),\n ],\n);\n\n/** One row per replication feed: the cursor the npm `_changes` follower resumes\n * from, so a restart doesn't replay the whole registry history. */\nexport const watchState = pgTable('watch_state', {\n id: text('id').primaryKey(),\n seq: text('seq').notNull(),\n updatedAt: ts('updated_at'),\n});\n\n/**\n * Sandbox verification results: did this package version actually install and\n * load? Evidence beyond static signals. The query path reads the latest run.\n */\nexport const verificationRuns = pgTable(\n 'verification_runs',\n {\n id: serial('id').primaryKey(),\n packageName: text('package_name').notNull(),\n version: text('version').notNull(),\n driver: text('driver').notNull(),\n moduleSystem: text('module_system').notNull(),\n installed: boolean('installed').notNull(),\n imported: boolean('imported'),\n ranScripts: boolean('ran_scripts').notNull().default(false),\n durationMs: integer('duration_ms'),\n error: text('error'),\n ranAt: ts('ran_at'),\n },\n (table) => [index('verification_runs_pkg_idx').on(table.packageName, table.version)],\n);\n\n/**\n * Compatibility edges from co-installing two package versions in the sandbox.\n * A successful co-install is positive proof they coexist; a 2-package failure is\n * proof they conflict. Pairs are stored canonically (packageA name < packageB).\n */\nexport const compatEdges = pgTable(\n 'compat_edges',\n {\n id: serial('id').primaryKey(),\n packageA: text('package_a').notNull(),\n versionA: text('version_a').notNull(),\n packageB: text('package_b').notNull(),\n versionB: text('version_b').notNull(),\n status: text('status').$type<CompatStatus>().notNull(),\n driver: text('driver').notNull(),\n ranAt: ts('ran_at'),\n },\n (table) => [\n uniqueIndex('compat_edges_pair_idx').on(\n table.packageA,\n table.versionA,\n table.packageB,\n table.versionB,\n ),\n ],\n);\n\n/**\n * Recommendation → outcome capture (§3.1): the flywheel asset. lurq sits inside\n * the agent loop at the choice moment, so a lightweight opt-in callback yields a\n * recommendation→outcome dataset no downstream scanner can reconstruct (they see\n * deployed deps, not the decision). Privacy: no source code — only which package,\n * accepted or not, and a coarse build signal. Cheap to capture, compounds with use.\n */\nexport const recommendationOutcomes = pgTable(\n 'recommendation_outcomes',\n {\n id: serial('id').primaryKey(),\n /** The org this outcome belongs to (api_keys.owner_id). Null for anonymous /\n * operator-issued keys. This is what turns the flywheel from a global blob\n * into a per-org asset — \"what did *this* org succeed with.\" Server-injected\n * from the authenticated key, never caller-supplied. */\n ownerId: text('owner_id'),\n packageName: text('package_name').notNull(),\n accepted: boolean('accepted').notNull(),\n buildSignal: text('build_signal').$type<BuildSignal>(),\n /** The original need text the recommendation was for — ties outcome back to\n * the ask. Optional, length-capped at the trust boundary; never source code. */\n need: text('need'),\n createdAt: ts('created_at').notNull().defaultNow(),\n },\n (table) => [\n index('recommendation_outcomes_pkg_idx').on(table.packageName),\n index('recommendation_outcomes_owner_idx').on(table.ownerId),\n ],\n);\n\nexport type SyncStatus = 'running' | 'success' | 'partial' | 'failed';\n\nexport interface SyncError {\n package: string;\n source: string;\n message: string;\n}\n\nexport type PackageRow = typeof packages.$inferSelect;\nexport type NewPackageRow = typeof packages.$inferInsert;\nexport type SeedPackageRow = typeof seedPackages.$inferSelect;\nexport type SyncRunRow = typeof syncRuns.$inferSelect;\nexport type DiscoveryQueueRow = typeof discoveryQueue.$inferSelect;\nexport type ApiKeyRow = typeof apiKeys.$inferSelect;\nexport type NewApiKeyRow = typeof apiKeys.$inferInsert;\nexport type PackageVersionRow = typeof packageVersions.$inferSelect;\nexport type NewPackageVersionRow = typeof packageVersions.$inferInsert;\nexport type VerificationRunRow = typeof verificationRuns.$inferSelect;\nexport type NewVerificationRunRow = typeof verificationRuns.$inferInsert;\nexport type CompatEdgeRow = typeof compatEdges.$inferSelect;\nexport type NewCompatEdgeRow = typeof compatEdges.$inferInsert;\nexport type RecommendationOutcomeRow = typeof recommendationOutcomes.$inferSelect;\nexport type NewRecommendationOutcomeRow = typeof recommendationOutcomes.$inferInsert;\n","/**\n * Database client factory. Uses postgres.js + Drizzle. Callers own the lifecycle:\n * create, use, then `await close()` (CLI commands are short-lived processes).\n */\nimport { drizzle, type PostgresJsDatabase } from 'drizzle-orm/postgres-js';\nimport postgres from 'postgres';\nimport { requireConfig } from '../core/config';\nimport * as schema from './schema';\n\nexport type Database = PostgresJsDatabase<typeof schema>;\n\nexport interface DbHandle {\n db: Database;\n /** Underlying postgres.js client, for raw SQL (e.g. CREATE EXTENSION). */\n sql: postgres.Sql;\n /** Close the connection pool. Always call when done. */\n close: () => Promise<void>;\n}\n\nexport function createDb(opts: { max?: number } = {}): DbHandle {\n const { DATABASE_URL } = requireConfig(['DATABASE_URL']);\n const sql = postgres(DATABASE_URL!, { max: opts.max ?? 10, onnotice: () => {} });\n const db = drizzle(sql, { schema });\n return { db, sql, close: () => sql.end() };\n}\n\nexport { schema };\n","/**\n * Minimal leveled logger.\n *\n * IMPORTANT: all output goes to **stderr**. The MCP server communicates over\n * stdio (stdout is the protocol channel), so anything written to stdout would\n * corrupt the JSON-RPC stream. Never log to stdout.\n */\n\nconst LEVELS = { error: 0, warn: 1, info: 2, debug: 3 } as const;\nexport type LogLevel = keyof typeof LEVELS;\n\nfunction currentLevel(): number {\n const raw = process.env.LOG_LEVEL as LogLevel | undefined;\n return raw && raw in LEVELS ? LEVELS[raw] : LEVELS.info;\n}\n\nfunction emit(level: LogLevel, args: unknown[]): void {\n if (LEVELS[level] > currentLevel()) return;\n const parts = args.map((a) =>\n typeof a === 'string' ? a : a instanceof Error ? (a.stack ?? a.message) : safeStringify(a),\n );\n process.stderr.write(`[lurq] ${level.toUpperCase()} ${parts.join(' ')}\\n`);\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nexport const logger = {\n error: (...args: unknown[]) => emit('error', args),\n warn: (...args: unknown[]) => emit('warn', args),\n info: (...args: unknown[]) => emit('info', args),\n debug: (...args: unknown[]) => emit('debug', args),\n};\n","/**\n * Optional Redis response cache for the read-heavy tools (recommend / evaluate /\n * compare). The index only changes when `sync`/`rescore` run, so identical\n * queries can be served from Redis instead of re-running the hybrid search.\n *\n * Zero-config by design: with no `REDIS_URL` (the default, and every end-user's\n * machine), `cached()` is a transparent pass-through and `invalidateCache()` a\n * no-op — nothing to provision, nothing breaks. Point `REDIS_URL` at an Upstash\n * (or any) Redis on the hosted server to turn it on. Any Redis error degrades to\n * computing directly; the cache never takes the request path down.\n *\n * Invalidation is version-based: every key embeds a namespace version read from\n * `lurq:cachever`. A successful sync `INCR`s it, so all prior keys become\n * unreachable at once (and age out via TTL) — no SCAN/DEL sweep.\n */\nimport { logger } from './logger';\n\ninterface RedisLike {\n get(key: string): Promise<string | null>;\n set(key: string, value: string, mode: 'EX', ttlSeconds: number): Promise<unknown>;\n incr(key: string): Promise<number>;\n}\n\nconst VERSION_KEY = 'lurq:cachever';\nconst DEFAULT_TTL_SEC = 3600;\n/** In-process memo for the namespace version, to avoid a round-trip per call.\n * Bounded so a sync's INCR is picked up within seconds. */\nconst VERSION_MEMO_MS = 10_000;\n\nlet clientPromise: Promise<RedisLike | null> | null = null;\nlet versionMemo: { value: string; at: number } | null = null;\n\nfunction ttlSeconds(): number {\n const n = Number(process.env.LURQ_CACHE_TTL_SEC);\n return Number.isFinite(n) && n > 0 ? n : DEFAULT_TTL_SEC;\n}\n\n/** Lazily connect to Redis once. Returns null (cache disabled) when REDIS_URL is\n * unset or the client can't be created. */\nasync function getClient(): Promise<RedisLike | null> {\n if (!process.env.REDIS_URL) return null;\n if (!clientPromise) {\n clientPromise = (async () => {\n try {\n const { default: Redis } = await import('ioredis');\n const client = new Redis(process.env.REDIS_URL!, {\n maxRetriesPerRequest: 1,\n enableOfflineQueue: false,\n lazyConnect: false,\n // Railway's private network (redis.railway.internal) is IPv6-only and\n // ioredis defaults to IPv4 — family:0 lets it resolve either stack, so\n // both the private URL and a public/Upstash URL work unchanged.\n family: 0,\n });\n client.on('error', (err: Error) => logger.warn(`redis: ${err.message}`));\n logger.info('Response cache enabled (REDIS_URL set).');\n return client as unknown as RedisLike;\n } catch (err) {\n logger.warn(`redis disabled (init failed): ${(err as Error).message}`);\n return null;\n }\n })();\n }\n return clientPromise;\n}\n\nasync function namespaceVersion(client: RedisLike): Promise<string> {\n if (versionMemo && Date.now() - versionMemo.at < VERSION_MEMO_MS) return versionMemo.value;\n const value = (await client.get(VERSION_KEY).catch(() => null)) ?? '0';\n versionMemo = { value, at: Date.now() };\n return value;\n}\n\n/**\n * Get-or-compute with optional caching. When the cache is off or unreachable,\n * `compute()` runs directly. `skipCache(value)` lets the caller avoid caching\n * unhelpful results (e.g. empty recommendations or not-found lookups).\n */\nexport async function cached<T>(\n namespace: string,\n key: string,\n compute: () => Promise<T>,\n opts: { skipCache?: (value: T) => boolean } = {},\n): Promise<T> {\n const client = await getClient();\n if (!client) return compute();\n\n let fullKey: string;\n try {\n const version = await namespaceVersion(client);\n fullKey = `lurq:${namespace}:${version}:${key}`;\n const hit = await client.get(fullKey);\n if (hit != null) return JSON.parse(hit) as T;\n } catch (err) {\n logger.warn(`redis read failed, bypassing cache: ${(err as Error).message}`);\n return compute();\n }\n\n const value = await compute();\n if (!opts.skipCache?.(value)) {\n // Fire-and-forget write; a cache-write failure must never affect the response.\n client.set(fullKey, JSON.stringify(value), 'EX', ttlSeconds()).catch(() => {});\n }\n return value;\n}\n\n/** Invalidate every cached read by bumping the namespace version. Call after a\n * successful sync/rescore. No-op when the cache is off. */\nexport async function invalidateCache(): Promise<void> {\n const client = await getClient();\n if (!client) return;\n try {\n await client.incr(VERSION_KEY);\n versionMemo = null; // force the next read to pick up the new version\n } catch (err) {\n logger.warn(`redis invalidate failed: ${(err as Error).message}`);\n }\n}\n","/** Read/write helpers for the compatibility matrix (`compat_edges`). */\nimport { and, inArray } from 'drizzle-orm';\nimport type { DependencyRanges, PeerMeta } from '../core/types';\nimport type { Database } from './client';\nimport {\n compatEdges,\n packages,\n type CompatEdgeRow,\n type NewCompatEdgeRow,\n} from './schema';\n\nexport interface CompatMetadataRow {\n name: string;\n latestVersion: string | null;\n peerDependencies: DependencyRanges | null;\n peerDependenciesMeta: PeerMeta | null;\n engines: DependencyRanges | null;\n}\n\n/** Tier-1 compatibility metadata for a set of packages — one indexed query. */\nexport async function getCompatMetadata(\n db: Database,\n names: string[],\n): Promise<CompatMetadataRow[]> {\n if (names.length === 0) return [];\n return db\n .select({\n name: packages.name,\n latestVersion: packages.latestVersion,\n peerDependencies: packages.peerDependencies,\n peerDependenciesMeta: packages.peerDependenciesMeta,\n engines: packages.engines,\n })\n .from(packages)\n .where(inArray(packages.name, names));\n}\n\n/** Order a pair canonically by package name so (A,B) and (B,A) dedupe to one row. */\nexport function canonicalPair(\n a: { name: string; version: string },\n b: { name: string; version: string },\n): { packageA: string; versionA: string; packageB: string; versionB: string } {\n const [low, high] = a.name <= b.name ? [a, b] : [b, a];\n return { packageA: low.name, versionA: low.version, packageB: high.name, versionB: high.version };\n}\n\nexport async function upsertCompatEdge(db: Database, edge: NewCompatEdgeRow): Promise<void> {\n await db\n .insert(compatEdges)\n .values(edge)\n .onConflictDoUpdate({\n target: [\n compatEdges.packageA,\n compatEdges.versionA,\n compatEdges.packageB,\n compatEdges.versionB,\n ],\n set: { status: edge.status, driver: edge.driver, ranAt: edge.ranAt },\n });\n}\n\n/** All stored edges whose both endpoints are within the given package names. */\nexport async function getCompatEdges(db: Database, names: string[]): Promise<CompatEdgeRow[]> {\n if (names.length === 0) return [];\n return db\n .select()\n .from(compatEdges)\n .where(and(inArray(compatEdges.packageA, names), inArray(compatEdges.packageB, names)));\n}\n","/**\n * Shared HTTP layer (§17). One wrapper for every external call:\n * - per-host rate limiting (max concurrency + minimum gap between starts),\n * - exponential backoff on 429 / 5xx (respecting Retry-After),\n * - in-run (memory) cache + persistent on-disk cache with per-source TTLs.\n *\n * Source clients pass a `ttlMs` (the per-source TTL from §17) and a `host`\n * bucket. `ttlMs: 0` disables caching (used for liveness checks like `verify`).\n */\nimport { createHash } from 'node:crypto';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { logger } from './logger';\n\nexport class HttpError extends Error {\n constructor(\n message: string,\n readonly status: number,\n readonly url: string,\n ) {\n super(message);\n this.name = 'HttpError';\n }\n}\n\nexport interface HttpOptions {\n /** Rate-limit bucket key, usually the hostname. */\n host: string;\n /** Persistent cache TTL in ms. 0 disables read+write caching. */\n ttlMs: number;\n method?: 'GET' | 'POST';\n headers?: Record<string, string>;\n body?: string;\n accept?: 'json' | 'text';\n timeoutMs?: number;\n retries?: number;\n /** Override the cache key (e.g. to keep auth tokens out of the key). */\n cacheKey?: string;\n /** Injected for tests. Defaults to global fetch. */\n fetchImpl?: typeof fetch;\n}\n\nexport interface HttpResponse<T> {\n status: number;\n data: T;\n fromCache: boolean;\n}\n\n// ── Per-host rate limiting ──────────────────────────────────────────────────\n\ninterface HostConfig {\n maxConcurrent: number;\n minIntervalMs: number;\n}\n\nconst DEFAULT_HOST_CONFIG: HostConfig = { maxConcurrent: 6, minIntervalMs: 0 };\n\nconst HOST_CONFIG: Record<string, HostConfig> = {\n 'api.github.com': { maxConcurrent: 4, minIntervalMs: 50 },\n 'registry.npmjs.org': { maxConcurrent: 4, minIntervalMs: 50 },\n // The downloads API rate-limits aggressively — serialize with a steady gap.\n // Weekly downloads go through the bulk endpoint; only growth hits this often.\n 'api.npmjs.org': { maxConcurrent: 1, minIntervalMs: 250 },\n 'api.deps.dev': { maxConcurrent: 4, minIntervalMs: 40 },\n 'raw.githubusercontent.com': { maxConcurrent: 4, minIntervalMs: 30 },\n // Bundlephobia is slow/flaky — be gentle (§9.5).\n 'bundlephobia.com': { maxConcurrent: 2, minIntervalMs: 200 },\n};\n\nclass HostLimiter {\n private active = 0;\n private nextAvailable = 0;\n private queue: Array<() => void> = [];\n\n constructor(private readonly config: HostConfig) {}\n\n async acquire(): Promise<void> {\n if (this.active >= this.config.maxConcurrent) {\n await new Promise<void>((resolve) => this.queue.push(resolve));\n }\n this.active++;\n const now = Date.now();\n const wait = Math.max(0, this.nextAvailable - now);\n this.nextAvailable = Math.max(now, this.nextAvailable) + this.config.minIntervalMs;\n if (wait > 0) await delay(wait);\n }\n\n release(): void {\n this.active--;\n const next = this.queue.shift();\n if (next) next();\n }\n}\n\nconst limiters = new Map<string, HostLimiter>();\n\nfunction limiterFor(host: string): HostLimiter {\n let limiter = limiters.get(host);\n if (!limiter) {\n limiter = new HostLimiter(HOST_CONFIG[host] ?? DEFAULT_HOST_CONFIG);\n limiters.set(host, limiter);\n }\n return limiter;\n}\n\n// ── Caching ─────────────────────────────────────────────────────────────────\n\ninterface CacheEntry {\n fetchedAt: number;\n status: number;\n body: string;\n}\n\nconst memoryCache = new Map<string, CacheEntry>();\n\n/** When true, cache reads are skipped (writes still happen). Used by `sync --full`. */\nlet bypassCacheRead = false;\n\n/** Force fresh fetches (ignore cache TTLs) while still refreshing the cache. */\nexport function setCacheBypassRead(value: boolean): void {\n bypassCacheRead = value;\n}\n\nfunction cacheDir(): string {\n return process.env.LURQ_CACHE_DIR ?? join(homedir(), '.cache', 'lurq', 'http');\n}\n\nfunction cacheFile(key: string): string {\n const hash = createHash('sha256').update(key).digest('hex');\n return join(cacheDir(), `${hash}.json`);\n}\n\nasync function readCache(key: string, ttlMs: number): Promise<CacheEntry | undefined> {\n const now = Date.now();\n const mem = memoryCache.get(key);\n if (mem && now - mem.fetchedAt < ttlMs) return mem;\n\n const file = cacheFile(key);\n if (!existsSync(file)) return undefined;\n try {\n const entry = JSON.parse(await readFile(file, 'utf8')) as CacheEntry;\n if (now - entry.fetchedAt < ttlMs) {\n memoryCache.set(key, entry);\n return entry;\n }\n } catch {\n /* corrupt cache file — ignore and refetch */\n }\n return undefined;\n}\n\nasync function writeCache(key: string, entry: CacheEntry): Promise<void> {\n memoryCache.set(key, entry);\n const file = cacheFile(key);\n try {\n await mkdir(dirname(file), { recursive: true });\n await writeFile(file, JSON.stringify(entry), 'utf8');\n } catch (err) {\n logger.debug(`http cache write failed: ${(err as Error).message}`);\n }\n}\n\n// ── Core request ────────────────────────────────────────────────────────────\n\nconst RETRYABLE = new Set([429, 500, 502, 503, 504]);\n\nexport async function httpRequest<T = unknown>(\n url: string,\n opts: HttpOptions,\n): Promise<HttpResponse<T>> {\n const {\n host,\n ttlMs,\n method = 'GET',\n headers = {},\n body,\n accept = 'json',\n timeoutMs = 15_000,\n retries = 3,\n fetchImpl = fetch,\n } = opts;\n const key = opts.cacheKey ?? `${method} ${url} ${body ?? ''}`;\n\n if (ttlMs > 0 && !bypassCacheRead) {\n const cached = await readCache(key, ttlMs);\n if (cached) {\n return { status: cached.status, data: decode<T>(cached.body, accept), fromCache: true };\n }\n }\n\n const limiter = limiterFor(host);\n let lastErr: unknown;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n await limiter.acquire();\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetchImpl(url, { method, headers, body, signal: controller.signal });\n const text = await res.text();\n\n if (res.ok) {\n if (ttlMs > 0) await writeCache(key, { fetchedAt: Date.now(), status: res.status, body: text });\n return { status: res.status, data: decode<T>(text, accept), fromCache: false };\n }\n\n // Non-2xx\n if (RETRYABLE.has(res.status) && attempt < retries) {\n const retryAfter = parseRetryAfter(res.headers.get('retry-after'));\n await delay(retryAfter ?? backoff(attempt));\n lastErr = new HttpError(`HTTP ${res.status} for ${url}`, res.status, url);\n continue;\n }\n throw new HttpError(`HTTP ${res.status} for ${url}`, res.status, url);\n } catch (err) {\n lastErr = err;\n const isAbort = err instanceof Error && err.name === 'AbortError';\n const isHttp = err instanceof HttpError;\n // Retry network/timeout errors; don't retry non-retryable HTTP statuses.\n if (isHttp && !RETRYABLE.has(err.status)) throw err;\n if (attempt < retries) {\n await delay(backoff(attempt));\n continue;\n }\n if (isAbort) throw new HttpError(`Timeout after ${timeoutMs}ms for ${url}`, 0, url);\n } finally {\n clearTimeout(timer);\n limiter.release();\n }\n }\n throw lastErr instanceof Error ? lastErr : new HttpError(`Request failed for ${url}`, 0, url);\n}\n\nexport async function httpGetJson<T = unknown>(\n url: string,\n opts: Omit<HttpOptions, 'accept' | 'method'>,\n): Promise<HttpResponse<T>> {\n return httpRequest<T>(url, { ...opts, method: 'GET', accept: 'json' });\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction decode<T>(text: string, accept: 'json' | 'text'): T {\n if (accept === 'text') return text as unknown as T;\n return (text ? JSON.parse(text) : null) as T;\n}\n\nfunction backoff(attempt: number): number {\n const base = 500 * 2 ** attempt;\n return base + Math.floor(((attempt * 137) % 100) * 3); // small deterministic jitter\n}\n\nfunction parseRetryAfter(value: string | null): number | undefined {\n if (!value) return undefined;\n const seconds = Number(value);\n if (!Number.isNaN(seconds)) return seconds * 1000;\n const date = Date.parse(value);\n return Number.isNaN(date) ? undefined : Math.max(0, date - Date.now());\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** Test helper: clear the in-memory cache and per-host limiters. */\nexport function __resetHttpStateForTests(): void {\n memoryCache.clear();\n limiters.clear();\n}\n","/**\n * npm registry client (§9.1). Base metadata: version, description, license,\n * repository, publish times, deprecation, maintainers, README.\n */\nimport { CACHE_TTL } from '../../core/constants';\nimport { httpGetJson } from '../../core/http';\nimport type { NpmRegistryData } from '../types';\n\nconst HOST = 'registry.npmjs.org';\n\n/** Encode a package name for a registry URL (scoped names need `/` → `%2F`). */\nexport function encodeNpmName(name: string): string {\n return name.startsWith('@') ? name.replace('/', '%2F') : name;\n}\n\n/** Extract `{ owner, repo }` from any GitHub repository URL form. */\nexport function parseGithubRepo(\n url: string | null | undefined,\n): { owner: string; repo: string } | null {\n if (!url) return null;\n const match = url.match(/github\\.com[/:]([^/]+)\\/([^/#?]+?)(?:\\.git)?(?:[/#?].*)?$/i);\n if (!match) return null;\n const owner = match[1];\n const repo = match[2];\n if (!owner || !repo) return null;\n return { owner, repo };\n}\n\nfunction normalizeRepoUrl(\n repository: unknown,\n homepage: string | null,\n): { repoUrl: string | null; repo: { owner: string; repo: string } | null } {\n let raw: string | null = null;\n if (typeof repository === 'string') raw = repository;\n else if (repository && typeof repository === 'object' && 'url' in repository) {\n raw = String((repository as { url: unknown }).url);\n }\n const repo = parseGithubRepo(raw) ?? parseGithubRepo(homepage);\n const repoUrl = repo ? `https://github.com/${repo.owner}/${repo.repo}` : (cleanUrl(raw) ?? null);\n return { repoUrl, repo };\n}\n\nfunction cleanUrl(url: string | null): string | null {\n if (!url) return null;\n return url\n .replace(/^git\\+/, '')\n .replace(/^git:\\/\\//, 'https://')\n .replace(/\\.git$/, '');\n}\n\nfunction pickLicense(value: unknown): string | null {\n if (!value) return null;\n if (typeof value === 'string') return value;\n if (typeof value === 'object' && 'type' in value) return String((value as { type: unknown }).type);\n return null;\n}\n\nfunction toDate(value: unknown): Date | null {\n if (typeof value !== 'string') return null;\n const ms = Date.parse(value);\n return Number.isNaN(ms) ? null : new Date(ms);\n}\n\nexport function parseNpmRegistry(json: any): NpmRegistryData {\n const latest: string | null = json?.['dist-tags']?.latest ?? null;\n const latestManifest = latest ? (json?.versions?.[latest] ?? {}) : {};\n const time = json?.time ?? {};\n\n const repository = json?.repository ?? latestManifest?.repository;\n const homepage = json?.homepage ?? latestManifest?.homepage ?? null;\n const { repoUrl, repo } = normalizeRepoUrl(repository, homepage);\n\n const deprecated = Boolean(latestManifest?.deprecated ?? json?.deprecated);\n const maintainers = Array.isArray(json?.maintainers) ? json.maintainers.length : null;\n const name: string = json?.name ?? '';\n\n return {\n name,\n description: json?.description ?? latestManifest?.description ?? null,\n latestVersion: latest,\n license: pickLicense(json?.license ?? latestManifest?.license),\n homepage,\n repo,\n repoUrl,\n firstPublishedAt: toDate(time?.created),\n lastReleaseAt: toDate(latest ? time?.[latest] : null) ?? toDate(time?.modified),\n deprecated,\n maintainersCount: maintainers,\n readme: typeof json?.readme === 'string' ? json.readme : null,\n keywords: parseKeywords(json?.keywords ?? latestManifest?.keywords),\n hasTypes: detectTypes(name, latestManifest),\n hasTestScript: detectTestScript(latestManifest),\n directDependenciesCount: countDeps(latestManifest?.dependencies),\n hasProvenance: detectProvenance(latestManifest),\n hasInstallScripts: detectInstallScripts(latestManifest),\n peerDependencies: parseDepMap(latestManifest?.peerDependencies),\n peerDependenciesMeta: parsePeerMeta(latestManifest?.peerDependenciesMeta),\n engines: parseDepMap(latestManifest?.engines),\n versionTimeline: parseVersionTimeline(json),\n };\n}\n\n/** A manifest dependency/engines map → a clean { name: range } record, or null. */\nfunction parseDepMap(value: unknown): Record<string, string> | null {\n if (!value || typeof value !== 'object') return null;\n const out: Record<string, string> = {};\n for (const [name, range] of Object.entries(value as Record<string, unknown>)) {\n if (typeof range === 'string' && range.trim() !== '') out[name] = range;\n }\n return Object.keys(out).length ? out : null;\n}\n\n/** `peerDependenciesMeta` → { name: { optional } }, or null. */\nfunction parsePeerMeta(value: unknown): Record<string, { optional?: boolean }> | null {\n if (!value || typeof value !== 'object') return null;\n const out: Record<string, { optional?: boolean }> = {};\n for (const [name, meta] of Object.entries(value as Record<string, unknown>)) {\n if (meta && typeof meta === 'object' && 'optional' in meta) {\n out[name] = { optional: Boolean((meta as { optional?: unknown }).optional) };\n }\n }\n return Object.keys(out).length ? out : null;\n}\n\n/** Lifecycle install hooks run arbitrary code at install time. We surface their\n * presence; deeper analysis belongs in the sandbox tier. */\nfunction detectInstallScripts(manifest: any): boolean {\n const scripts = manifest?.scripts;\n if (!scripts || typeof scripts !== 'object') return false;\n return ['preinstall', 'install', 'postinstall'].some(\n (hook) => typeof scripts[hook] === 'string' && scripts[hook].trim() !== '',\n );\n}\n\n/**\n * The published-version timeline from the packument: every key in `versions`\n * paired with its publish date from `time`, newest first. The `time` map also\n * holds `created`/`modified` sentinels, which we skip.\n */\nexport function parseVersionTimeline(json: any): { version: string; publishedAt: Date | null }[] {\n const versions = json?.versions;\n if (!versions || typeof versions !== 'object') return [];\n const time = json?.time ?? {};\n return Object.keys(versions)\n .map((version) => ({ version, publishedAt: toDate(time?.[version]) }))\n .sort((a, b) => (b.publishedAt?.getTime() ?? 0) - (a.publishedAt?.getTime() ?? 0));\n}\n\nfunction parseKeywords(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value.filter((k): k is string => typeof k === 'string');\n}\n\n/** Ships types if the manifest declares `types`/`typings`, or it IS an @types pkg. */\nfunction detectTypes(name: string, manifest: any): boolean {\n if (typeof manifest?.types === 'string' || typeof manifest?.typings === 'string') return true;\n if (name.startsWith('@types/')) return true;\n // `exports` map with a `types` condition (modern dual-package layout).\n const exportsField = manifest?.exports;\n if (exportsField && typeof exportsField === 'object') {\n const serialized = JSON.stringify(exportsField);\n if (serialized.includes('\"types\"')) return true;\n }\n return false;\n}\n\n/** A real test script — npm's `init` leaves a placeholder we must not count. */\nfunction detectTestScript(manifest: any): boolean {\n const test = manifest?.scripts?.test;\n if (typeof test !== 'string' || test.trim() === '') return false;\n return !/no test specified/i.test(test);\n}\n\nfunction countDeps(deps: unknown): number | null {\n if (!deps || typeof deps !== 'object') return 0;\n return Object.keys(deps as Record<string, unknown>).length;\n}\n\n/** npm provenance leaves a signed attestation on the published dist. */\nfunction detectProvenance(manifest: any): boolean {\n return Boolean(manifest?.dist?.attestations);\n}\n\nexport async function fetchNpmRegistry(\n name: string,\n fetchImpl?: typeof fetch,\n): Promise<NpmRegistryData> {\n const url = `https://${HOST}/${encodeNpmName(name)}`;\n const { data } = await httpGetJson<any>(url, {\n host: HOST,\n ttlMs: CACHE_TTL.npmRegistry,\n fetchImpl,\n });\n return parseNpmRegistry(data);\n}\n\n/** Live existence check for `verify` (§12.3.4) — bypasses cache. */\nexport async function npmPackageExists(name: string, fetchImpl?: typeof fetch): Promise<boolean> {\n const url = `https://${HOST}/${encodeNpmName(name)}`;\n try {\n const { status } = await httpGetJson<any>(url, {\n host: HOST,\n ttlMs: 0,\n retries: 1,\n fetchImpl,\n });\n return status === 200;\n } catch (err) {\n if (err && typeof err === 'object' && 'status' in err && (err as any).status === 404) {\n return false;\n }\n throw err;\n }\n}\n","/**\n * npm registry search client (§2B). Seeds the discovery crawler's long-tail\n * channels: keyword/category search and a recently-published sweep. This is the\n * niche workhorse — the dependency graph structurally can't find niche\n * *alternatives* (a new package shares no edge with the incumbent it competes\n * with), so that job lives here.\n */\nimport { CACHE_TTL } from '../../core/constants';\nimport { httpGetJson } from '../../core/http';\n\nconst HOST = 'registry.npmjs.org';\n\nexport interface NpmSearchHit {\n name: string;\n /** ISO publish date of the matched version, if reported. */\n date: string | null;\n}\n\n/**\n * Run an npm registry search. `query` uses npm's search qualifier syntax, e.g.\n * `keywords:orm` or `orm typescript`. Returns name + publish date per hit.\n * Best-effort: returns [] on any failure.\n */\nexport async function searchNpm(\n query: string,\n size = 20,\n fetchImpl?: typeof fetch,\n): Promise<NpmSearchHit[]> {\n const url = `https://${HOST}/-/v1/search?text=${encodeURIComponent(query)}&size=${size}`;\n try {\n const { data } = await httpGetJson<any>(url, {\n host: HOST,\n ttlMs: CACHE_TTL.npmRegistry,\n fetchImpl,\n });\n const objects: any[] = Array.isArray(data?.objects) ? data.objects : [];\n return objects\n .map((o) => ({ name: o?.package?.name, date: o?.package?.date ?? null }))\n .filter((h): h is NpmSearchHit => typeof h.name === 'string');\n } catch {\n return [];\n }\n}\n","/**\n * npm downloads client (§9.2). Weekly downloads + 90-day growth.\n *\n * Weekly downloads is fetched in BULK at the pipeline level — npm's point API\n * accepts up to 128 comma-separated packages per call, which avoids the harsh\n * rate-limiting that per-package bursts trigger. The range (growth) API has no\n * bulk form, so growth is a per-package best-effort secondary signal.\n *\n * Bulk does not support scoped (@scope/name) packages; those are fetched singly.\n */\nimport { CACHE_TTL } from '../../core/constants';\nimport { httpGetJson, HttpError } from '../../core/http';\n\nconst HOST = 'api.npmjs.org';\nconst BULK_CHUNK = 128;\n\nexport function parseWeeklyDownloads(json: any): number | null {\n const value = json?.downloads;\n return typeof value === 'number' ? value : null;\n}\n\ninterface RangePoint {\n day: string;\n downloads: number;\n}\n\n/** Compute the 90d growth fraction from a daily-downloads range. */\nexport function parseDownloadGrowth(json: any): number | null {\n const points: RangePoint[] = Array.isArray(json?.downloads) ? json.downloads : [];\n if (points.length < 60) return null;\n const tail = points.slice(-60);\n const prior = tail.slice(0, 30);\n const recent = tail.slice(30);\n const sum = (arr: RangePoint[]) => arr.reduce((acc, p) => acc + (p.downloads || 0), 0);\n const priorAvg = sum(prior) / prior.length;\n const recentAvg = sum(recent) / recent.length;\n if (priorAvg <= 0) return recentAvg > 0 ? 1 : 0;\n // Round to 3 decimals: this is a best-effort secondary signal, so the float's\n // precision tail is meaningless — and it ships in every recommend/evaluate\n // response, where 19 chars of noise is tokens the calling agent pays for.\n return Math.round(((recentAvg - priorAvg) / priorAvg) * 1000) / 1000;\n}\n\n/** Format a Date as YYYY-MM-DD (UTC) for the npm range API. */\nfunction ymd(date: Date): string {\n return date.toISOString().slice(0, 10);\n}\n\n/** Build a `start:end` range string covering the last 90 days. */\nexport function last90DayRange(now: Date = new Date()): string {\n const end = now;\n const start = new Date(end.getTime() - 90 * 24 * 60 * 60 * 1000);\n return `${ymd(start)}:${ymd(end)}`;\n}\n\n/** Parse a bulk point response into a name→downloads map (handles single + multi forms). */\nexport function parseBulkWeekly(json: any, requested: string[]): Map<string, number | null> {\n const map = new Map<string, number | null>();\n // A single-package request returns the object directly, not keyed by name.\n if (json && typeof json.downloads === 'number' && typeof json.package === 'string') {\n map.set(json.package, json.downloads);\n return map;\n }\n for (const name of requested) {\n const entry = json?.[name];\n map.set(name, entry && typeof entry.downloads === 'number' ? entry.downloads : null);\n }\n return map;\n}\n\nfunction chunk<T>(items: T[], size: number): T[][] {\n const out: T[][] = [];\n for (let i = 0; i < items.length; i += size) out.push(items.slice(i, i + size));\n return out;\n}\n\n/** Single-package weekly downloads. 404 → null (no per-package data). */\nexport async function fetchWeeklyDownloads(\n name: string,\n fetchImpl?: typeof fetch,\n): Promise<number | null> {\n try {\n const { data } = await httpGetJson<any>(\n `https://${HOST}/downloads/point/last-week/${name}`,\n { host: HOST, ttlMs: CACHE_TTL.npmDownloads, retries: 5, fetchImpl },\n );\n return parseWeeklyDownloads(data);\n } catch (err) {\n if (err instanceof HttpError && err.status === 404) return null;\n throw err;\n }\n}\n\n/** Per-package 90d growth (best-effort secondary signal). */\nexport async function fetchDownloadGrowth(\n name: string,\n fetchImpl?: typeof fetch,\n): Promise<number | null> {\n try {\n const { data } = await httpGetJson<any>(\n `https://${HOST}/downloads/range/${last90DayRange()}/${name}`,\n { host: HOST, ttlMs: CACHE_TTL.npmDownloads, retries: 3, fetchImpl },\n );\n return parseDownloadGrowth(data);\n } catch {\n return null;\n }\n}\n\n/**\n * Bulk-fetch weekly downloads for many packages. Unscoped packages go through\n * the 128-at-a-time bulk endpoint; scoped packages are fetched individually.\n */\nexport async function fetchBulkWeeklyDownloads(\n names: string[],\n fetchImpl?: typeof fetch,\n): Promise<Map<string, number | null>> {\n const result = new Map<string, number | null>();\n const unscoped = names.filter((n) => !n.startsWith('@'));\n const scoped = names.filter((n) => n.startsWith('@'));\n\n for (const batch of chunk(unscoped, BULK_CHUNK)) {\n try {\n const { data } = await httpGetJson<any>(\n `https://${HOST}/downloads/point/last-week/${batch.join(',')}`,\n { host: HOST, ttlMs: CACHE_TTL.npmDownloads, retries: 5, fetchImpl },\n );\n for (const [k, v] of parseBulkWeekly(data, batch)) result.set(k, v);\n } catch {\n // Leave this batch absent; per-package fallback will retry it.\n }\n }\n\n for (const name of scoped) {\n try {\n result.set(name, await fetchWeeklyDownloads(name, fetchImpl));\n } catch {\n /* leave absent → per-package fallback */\n }\n }\n\n return result;\n}\n","/**\n * GitHub client (§9.3). One GraphQL call per repo fetches stars, issue counts,\n * archived flag, and recent releases (latest date + 12-month cadence).\n * Requires GITHUB_TOKEN; without it, the pipeline skips this source.\n */\nimport { CACHE_TTL } from '../../core/constants';\nimport { httpRequest } from '../../core/http';\nimport type { GithubRepoData } from '../types';\n\nconst HOST = 'api.github.com';\nconst ENDPOINT = `https://${HOST}/graphql`;\n\nconst QUERY = `query($owner:String!, $name:String!) {\n repository(owner:$owner, name:$name) {\n stargazerCount\n isArchived\n openIssues: issues(states:OPEN) { totalCount }\n closedIssues: issues(states:CLOSED) { totalCount }\n releases(first: 50, orderBy: {field: CREATED_AT, direction: DESC}) {\n nodes { createdAt }\n }\n }\n}`;\n\nconst ONE_YEAR_MS = 365 * 24 * 60 * 60 * 1000;\n\nexport function parseGithub(json: any, now: Date = new Date()): GithubRepoData | null {\n const repo = json?.data?.repository;\n if (!repo) return null;\n\n const releaseNodes: { createdAt: string }[] = repo.releases?.nodes ?? [];\n const releaseDates = releaseNodes\n .map((n) => Date.parse(n.createdAt))\n .filter((ms) => !Number.isNaN(ms));\n const cutoff = now.getTime() - ONE_YEAR_MS;\n\n return {\n stars: typeof repo.stargazerCount === 'number' ? repo.stargazerCount : null,\n openIssues: repo.openIssues?.totalCount ?? null,\n closedIssues: repo.closedIssues?.totalCount ?? null,\n archived: Boolean(repo.isArchived),\n lastReleaseAt: releaseDates.length ? new Date(Math.max(...releaseDates)) : null,\n releasesLast12mo: releaseDates.filter((ms) => ms >= cutoff).length,\n };\n}\n\nexport async function fetchGithubRepo(\n owner: string,\n repo: string,\n token: string,\n fetchImpl?: typeof fetch,\n): Promise<GithubRepoData | null> {\n const body = JSON.stringify({ query: QUERY, variables: { owner, name: repo } });\n const { data } = await httpRequest<any>(ENDPOINT, {\n host: HOST,\n ttlMs: CACHE_TTL.github,\n method: 'POST',\n headers: {\n Authorization: `bearer ${token}`,\n 'Content-Type': 'application/json',\n 'User-Agent': 'lurq',\n },\n body,\n // Keep the auth token out of the cache key.\n cacheKey: `POST ${ENDPOINT} ${owner}/${repo}`,\n fetchImpl,\n });\n return parseGithub(data);\n}\n","/**\n * deps.dev client (§9.4). Primary source for OpenSSF Scorecard and security\n * advisories.\n * - Scorecard comes from the project endpoint (keyed by github.com/owner/repo).\n * - Advisories: the version endpoint lists advisoryKeys; we fetch each (capped)\n * and derive a severity bucket from its CVSS score.\n */\nimport { CACHE_TTL } from '../../core/constants';\nimport { httpGetJson, type HttpResponse } from '../../core/http';\nimport type { Advisory, AdvisorySeverity } from '../../core/types';\nimport type { DepsDevData } from '../types';\n\nconst HOST = 'api.deps.dev';\nconst MAX_ADVISORIES = 10;\n\nfunction encodeName(name: string): string {\n return encodeURIComponent(name);\n}\n\nexport function severityFromCvss(score: number | null | undefined): AdvisorySeverity {\n if (score == null) return 'moderate';\n if (score >= 9) return 'critical';\n if (score >= 7) return 'high';\n if (score >= 4) return 'moderate';\n if (score > 0) return 'low';\n return 'info';\n}\n\nexport function parseScorecard(json: any): number | null {\n const score = json?.scorecard?.overallScore;\n return typeof score === 'number' ? score : null;\n}\n\nexport function parseAdvisoryKeys(versionJson: any): string[] {\n const keys = versionJson?.advisoryKeys;\n if (!Array.isArray(keys)) return [];\n return keys\n .map((k: any) => (typeof k === 'string' ? k : k?.id))\n .filter((id: unknown): id is string => typeof id === 'string');\n}\n\nexport function parseAdvisoryDetail(json: any): Advisory {\n return {\n id: json?.advisoryKey?.id ?? json?.advisoryKey ?? 'unknown',\n severity: severityFromCvss(json?.cvss3Score),\n summary: json?.title ?? '',\n };\n}\n\nexport async function fetchScorecard(\n owner: string,\n repo: string,\n fetchImpl?: typeof fetch,\n): Promise<number | null> {\n const projectKey = encodeURIComponent(`github.com/${owner}/${repo}`);\n const url = `https://${HOST}/v3/projects/${projectKey}`;\n try {\n const { data } = await httpGetJson<any>(url, {\n host: HOST,\n ttlMs: CACHE_TTL.depsDev,\n fetchImpl,\n });\n return parseScorecard(data);\n } catch {\n return null;\n }\n}\n\nexport async function fetchAdvisories(\n name: string,\n version: string,\n fetchImpl?: typeof fetch,\n): Promise<Advisory[]> {\n const versionUrl = `https://${HOST}/v3/systems/npm/packages/${encodeName(name)}/versions/${encodeURIComponent(version)}`;\n let keys: string[] = [];\n try {\n const { data } = await httpGetJson<any>(versionUrl, {\n host: HOST,\n ttlMs: CACHE_TTL.depsDev,\n fetchImpl,\n });\n keys = parseAdvisoryKeys(data).slice(0, MAX_ADVISORIES);\n } catch {\n return [];\n }\n\n const details = await Promise.allSettled(\n keys.map((key) =>\n httpGetJson<any>(`https://${HOST}/v3/advisories/${encodeURIComponent(key)}`, {\n host: HOST,\n ttlMs: CACHE_TTL.depsDev,\n fetchImpl,\n }),\n ),\n );\n return details\n .filter(\n (d): d is PromiseFulfilledResult<HttpResponse<any>> => d.status === 'fulfilled',\n )\n .map((d) => parseAdvisoryDetail(d.value.data));\n}\n\n/**\n * Direct dependency names from the deps.dev graph (§2B). These are the packages\n * a seed is *built on* — the adjacent foundations. Best-effort: returns [] on any\n * failure. We deliberately do NOT rank by dependent count (that re-introduces the\n * popularity bias §2B exists to avoid); the caller gates on quality instead.\n */\nexport async function fetchDependencyNames(\n name: string,\n version: string,\n fetchImpl?: typeof fetch,\n): Promise<string[]> {\n const url = `https://${HOST}/v3/systems/npm/packages/${encodeName(name)}/versions/${encodeURIComponent(version)}:dependencies`;\n try {\n const { data } = await httpGetJson<any>(url, {\n host: HOST,\n ttlMs: CACHE_TTL.depsDev,\n fetchImpl,\n });\n const nodes: any[] = Array.isArray(data?.nodes) ? data.nodes : [];\n const names = nodes\n .map((n) => n?.versionKey?.name)\n .filter((n: unknown): n is string => typeof n === 'string' && n !== name);\n return [...new Set(names)];\n } catch {\n return [];\n }\n}\n\nexport async function fetchDepsDev(\n name: string,\n version: string | null,\n repo: { owner: string; repo: string } | null,\n fetchImpl?: typeof fetch,\n): Promise<DepsDevData> {\n const [scorecard, advisories] = await Promise.all([\n repo ? fetchScorecard(repo.owner, repo.repo, fetchImpl) : Promise.resolve(null),\n version ? fetchAdvisories(name, version, fetchImpl) : Promise.resolve([]),\n ]);\n return { scorecard, advisories };\n}\n","/**\n * Bundlephobia client (§9.5). Minified + gzipped size for frontend packages.\n * Strictly best-effort: this API is slow and flaky, so failures degrade to null\n * and never block ingestion (per R1 build decision). Cached aggressively (7d).\n */\nimport { CACHE_TTL } from '../../core/constants';\nimport { httpGetJson } from '../../core/http';\nimport { isFrontendCategory, type Category } from '../../core/types';\nimport type { BundlephobiaData } from '../types';\n\nconst HOST = 'bundlephobia.com';\n\nexport function parseBundleSize(json: any): number | null {\n const gzipBytes = json?.gzip;\n if (typeof gzipBytes !== 'number') return null;\n return Math.round((gzipBytes / 1024) * 10) / 10; // KB, 1 decimal\n}\n\n/**\n * Fetch bundle size — only for frontend categories (§9.5); returns null for\n * backend-only packages without making a request.\n */\nexport async function fetchBundlephobia(\n name: string,\n category: Category | null,\n fetchImpl?: typeof fetch,\n): Promise<BundlephobiaData> {\n if (!isFrontendCategory(category)) return { bundleMinGzipKb: null };\n\n const url = `https://${HOST}/api/size?package=${encodeURIComponent(name)}`;\n try {\n const { data } = await httpGetJson<any>(url, {\n host: HOST,\n ttlMs: CACHE_TTL.bundlephobia,\n timeoutMs: 12_000,\n retries: 1,\n fetchImpl,\n });\n return { bundleMinGzipKb: parseBundleSize(data) };\n } catch {\n return { bundleMinGzipKb: null };\n }\n}\n","export * from './npmRegistry';\nexport * from './npmSearch';\nexport * from './npmDownloads';\nexport * from './github';\nexport * from './depsDev';\nexport * from './bundlephobia';\n","/**\n * Assemble compat members for a set of package names: the fast path reads\n * metadata straight from the DB in one query; any name not tracked is fetched\n * on-demand (the HTTP layer caches packuments) so a single untracked package\n * doesn't blind the whole-architecture check. Names that can't be resolved at\n * all are returned as `unverified` rather than guessed.\n */\nimport type { Database } from '../db/client';\nimport { getCompatMetadata } from '../db/compat';\nimport { fetchNpmRegistry } from '../ingestion/sources';\nimport type { CompatMember } from './peerCompat';\n\nexport async function assembleMembers(\n db: Database,\n names: string[],\n): Promise<{ members: CompatMember[]; unverified: string[] }> {\n const tracked = new Map((await getCompatMetadata(db, names)).map((r) => [r.name, r]));\n const members: CompatMember[] = [];\n const unverified: string[] = [];\n\n await Promise.all(\n names.map(async (name) => {\n const row = tracked.get(name);\n if (row) {\n members.push({\n name,\n version: row.latestVersion,\n peerDependencies: row.peerDependencies,\n peerDependenciesMeta: row.peerDependenciesMeta,\n engines: row.engines,\n });\n return;\n }\n const reg = await fetchNpmRegistry(name).catch(() => null);\n if (reg) {\n members.push({\n name,\n version: reg.latestVersion,\n peerDependencies: reg.peerDependencies,\n peerDependenciesMeta: reg.peerDependenciesMeta,\n engines: reg.engines,\n });\n } else {\n unverified.push(name);\n }\n }),\n );\n\n return { members, unverified };\n}\n","/**\n * Tier-1 compatibility: whole-architecture peer-dependency + engine analysis.\n *\n * Deterministic and instant — no install. Works over the *entire set* at once:\n * it collects every package's declared `peerDependencies`, groups them by peer,\n * and checks the declared semver ranges agree. Two plugins that need `eslint@8`\n * vs `eslint@9` conflict even if eslint isn't pinned in the set.\n *\n * Sparse data degrades safely: a package with no declared peers contributes no\n * constraints (which is correct — most packages declare none), so \"not fully\n * recorded\" never produces a false conflict. Genuinely-untracked packages are\n * reported as `unverified` by the caller, not guessed at.\n */\nimport semver from 'semver';\nimport type { CompatConflict, DependencyRanges, PeerMeta } from '../core/types';\n\nexport interface CompatMember {\n name: string;\n /** Pinned (latest) version, or null if unknown. */\n version: string | null;\n peerDependencies: DependencyRanges | null;\n peerDependenciesMeta: PeerMeta | null;\n engines: DependencyRanges | null;\n}\n\ninterface PeerConstraint {\n requirer: string;\n peer: string;\n range: string;\n optional: boolean;\n}\n\n/** null = can't assert (invalid version/range). */\nfunction satisfiesRange(version: string, range: string): boolean | null {\n if (!semver.validRange(range)) return null;\n const v = semver.valid(version) ? version : semver.coerce(version)?.version;\n if (!v) return null;\n return semver.satisfies(v, range, { includePrerelease: true });\n}\n\nfunction rangesIntersect(a: string, b: string): boolean | null {\n if (!semver.validRange(a) || !semver.validRange(b)) return null;\n try {\n return semver.intersects(a, b, { includePrerelease: true });\n } catch {\n return null;\n }\n}\n\n/** All peer/engine conflicts across the set (empty = no Tier-1 conflict found). */\nexport function resolveArchitectureCompat(members: CompatMember[]): CompatConflict[] {\n const conflicts: CompatConflict[] = [];\n const pinned = new Map<string, string>();\n for (const m of members) if (m.version) pinned.set(m.name, m.version);\n\n const constraints: PeerConstraint[] = [];\n for (const m of members) {\n if (!m.peerDependencies) continue;\n for (const [peer, range] of Object.entries(m.peerDependencies)) {\n constraints.push({\n requirer: m.name,\n peer,\n range,\n optional: Boolean(m.peerDependenciesMeta?.[peer]?.optional),\n });\n }\n }\n\n // (1) A peer that's pinned in the set must satisfy each declared range.\n for (const c of constraints) {\n const pv = pinned.get(c.peer);\n if (pv && satisfiesRange(pv, c.range) === false) {\n conflicts.push({\n source: 'peer-deps',\n packages: [c.requirer, c.peer],\n detail: `${c.requirer} needs peer ${c.peer}@${c.range}, but the stack uses ${c.peer}@${pv}`,\n });\n }\n }\n\n // (2) A peer required by ≥2 members but not pinned: their ranges must overlap.\n const byPeer = new Map<string, PeerConstraint[]>();\n for (const c of constraints) {\n if (pinned.has(c.peer) || c.optional) continue;\n const arr = byPeer.get(c.peer);\n if (arr) arr.push(c);\n else byPeer.set(c.peer, [c]);\n }\n for (const [peer, cs] of byPeer) {\n for (let i = 0; i < cs.length; i++) {\n for (let j = i + 1; j < cs.length; j++) {\n if (cs[i]!.range !== cs[j]!.range && rangesIntersect(cs[i]!.range, cs[j]!.range) === false) {\n conflicts.push({\n source: 'peer-deps',\n packages: [cs[i]!.requirer, cs[j]!.requirer],\n detail: `${cs[i]!.requirer} needs ${peer}@${cs[i]!.range} but ${cs[j]!.requirer} needs ${peer}@${cs[j]!.range} — no overlapping version`,\n });\n }\n }\n }\n }\n\n // (3) Node engine ranges across the set must have a common solution.\n const nodeReqs = members\n .map((m) => ({ name: m.name, range: m.engines?.node }))\n .filter((r): r is { name: string; range: string } => typeof r.range === 'string');\n for (let i = 0; i < nodeReqs.length; i++) {\n for (let j = i + 1; j < nodeReqs.length; j++) {\n if (rangesIntersect(nodeReqs[i]!.range, nodeReqs[j]!.range) === false) {\n conflicts.push({\n source: 'engines',\n packages: [nodeReqs[i]!.name, nodeReqs[j]!.name],\n detail: `${nodeReqs[i]!.name} needs node ${nodeReqs[i]!.range} but ${nodeReqs[j]!.name} needs node ${nodeReqs[j]!.range} — no overlap`,\n });\n }\n }\n }\n\n return conflicts;\n}\n","/**\n * Whole-architecture compatibility check for a set of packages, shared by the\n * `compat` tool and `plan`. Tier 1 (peer-deps/engines, instant) + any recorded\n * Tier-2 sandbox conflicts. The result lists every member as name@version so\n * versions are explicit and the evidence stays structured for later scraping.\n */\nimport type { CompatConflict, CompatOutput } from '../core/types';\nimport type { Database } from '../db/client';\nimport { getCompatEdges } from '../db/compat';\nimport { assembleMembers } from './members';\nimport { resolveArchitectureCompat } from './peerCompat';\n\nexport async function checkCompat(db: Database, packages: string[]): Promise<CompatOutput> {\n const names = [...new Set(packages)];\n const { members, unverified } = await assembleMembers(db, names);\n\n const conflicts: CompatConflict[] = resolveArchitectureCompat(members);\n for (const edge of await getCompatEdges(db, names)) {\n if (edge.status === 'conflict') {\n conflicts.push({\n source: 'sandbox',\n packages: [edge.packageA, edge.packageB],\n detail: `${edge.packageA}@${edge.versionA} and ${edge.packageB}@${edge.versionB} failed to co-install in the sandbox`,\n });\n }\n }\n\n const overall = conflicts.length ? 'conflict' : unverified.length ? 'unknown' : 'compatible';\n return {\n packages: names,\n overall,\n conflicts,\n unverified,\n checked: members.map((m) => ({ name: m.name, version: m.version })),\n };\n}\n","/**\n * Read/write helpers for the `packages` table. All recommendation/eval reads use\n * this single denormalized table (§8.2).\n */\nimport { desc, eq, isNotNull } from 'drizzle-orm';\nimport type { Category } from '../core/types';\nimport type { VersionInfo } from '../ingestion/types';\nimport type { Database } from './client';\nimport {\n packageVersions,\n packages,\n seedPackages,\n syncRuns,\n type NewPackageRow,\n type SyncError,\n} from './schema';\n\n/** How many rows to insert per statement (stays well under Postgres' param cap). */\nconst VERSION_CHUNK = 500;\n\nexport async function getSeedTargets(\n db: Database,\n): Promise<{ name: string; category: Category | null }[]> {\n const rows = await db\n .select({ name: seedPackages.name, category: seedPackages.category })\n .from(seedPackages);\n return rows.map((r) => ({ name: r.name, category: r.category ?? null }));\n}\n\nexport async function getPackageByName(db: Database, name: string) {\n const rows = await db.select().from(packages).where(eq(packages.name, name)).limit(1);\n return rows[0] ?? null;\n}\n\n/** Every tracked package name — the set the `_changes` follower filters against. */\nexport async function getAllPackageNames(db: Database): Promise<string[]> {\n const rows = await db.select({ name: packages.name }).from(packages);\n return rows.map((r) => r.name);\n}\n\n/**\n * Store a package's version timeline. Idempotent — versions are immutable on\n * npm, so existing rows are left untouched. Chunked to respect the param cap.\n */\nexport async function upsertPackageVersions(\n db: Database,\n name: string,\n versions: VersionInfo[],\n): Promise<void> {\n if (versions.length === 0) return;\n for (let i = 0; i < versions.length; i += VERSION_CHUNK) {\n const rows = versions.slice(i, i + VERSION_CHUNK).map((v) => ({\n packageName: name,\n version: v.version,\n publishedAt: v.publishedAt,\n }));\n await db.insert(packageVersions).values(rows).onConflictDoNothing();\n }\n}\n\n/** A package's stored version timeline, newest first. */\nexport async function getPackageVersions(\n db: Database,\n name: string,\n limit = 50,\n): Promise<VersionInfo[]> {\n const rows = await db\n .select({ version: packageVersions.version, publishedAt: packageVersions.publishedAt })\n .from(packageVersions)\n .where(eq(packageVersions.packageName, name))\n .orderBy(desc(packageVersions.publishedAt))\n .limit(limit);\n return rows.map((r) => ({ version: r.version, publishedAt: r.publishedAt }));\n}\n\n/**\n * The most-downloaded tracked packages — the reference set typosquat detection\n * compares a queried name against. Capped (default 1000) so the per-verify\n * distance scan stays cheap.\n */\nexport async function getTopPackageNames(db: Database, limit = 1000): Promise<string[]> {\n const rows = await db\n .select({ name: packages.name })\n .from(packages)\n .where(isNotNull(packages.weeklyDownloads))\n .orderBy(desc(packages.weeklyDownloads))\n .limit(limit);\n return rows.map((r) => r.name);\n}\n\n/**\n * Promote a package into the curated seed list so future `sync` runs keep it\n * fresh. Used by the on-demand path (§12.5) to make organically-discovered\n * packages durable. No-op if already seeded — preserves the original category\n * and `added_at` rather than overwriting a hand-curated entry.\n */\nexport async function ensureSeedEntry(\n db: Database,\n name: string,\n category: Category | null,\n): Promise<void> {\n await db\n .insert(seedPackages)\n .values({ name, category })\n .onConflictDoNothing({ target: seedPackages.name });\n}\n\n/** Upsert a fully-computed package row, refreshing every field on conflict. */\nexport async function upsertPackage(db: Database, row: NewPackageRow): Promise<void> {\n const { name: _name, createdAt: _createdAt, ...mutable } = row;\n await db\n .insert(packages)\n .values(row)\n .onConflictDoUpdate({\n target: packages.name,\n set: { ...mutable, updatedAt: new Date() },\n });\n}\n\n// ── sync_runs audit ─────────────────────────────────────────────────────────\n\nexport async function startSyncRun(db: Database): Promise<number> {\n const [row] = await db\n .insert(syncRuns)\n .values({ status: 'running' })\n .returning({ id: syncRuns.id });\n return row!.id;\n}\n\nexport async function finishSyncRun(\n db: Database,\n id: number,\n data: {\n packagesSeen: number;\n packagesUpdated: number;\n errors: SyncError[];\n status: 'success' | 'partial' | 'failed';\n },\n): Promise<void> {\n await db\n .update(syncRuns)\n .set({\n finishedAt: new Date(),\n packagesSeen: data.packagesSeen,\n packagesUpdated: data.packagesUpdated,\n errors: data.errors,\n status: data.status,\n })\n .where(eq(syncRuns.id, id));\n}\n","/** Read/write helpers for sandbox verification results (`verification_runs`). */\nimport { and, desc, eq } from 'drizzle-orm';\nimport type { Database } from './client';\nimport {\n verificationRuns,\n type NewVerificationRunRow,\n type VerificationRunRow,\n} from './schema';\n\nexport async function storeVerificationRun(\n db: Database,\n run: NewVerificationRunRow,\n): Promise<void> {\n await db.insert(verificationRuns).values(run);\n}\n\n/** Most recent run for a package (any version), if any — for the evaluate verdict. */\nexport async function getLatestVerificationByName(\n db: Database,\n packageName: string,\n): Promise<VerificationRunRow | null> {\n const rows = await db\n .select()\n .from(verificationRuns)\n .where(eq(verificationRuns.packageName, packageName))\n .orderBy(desc(verificationRuns.ranAt))\n .limit(1);\n return rows[0] ?? null;\n}\n\n/** Most recent run for a package version (any module system), if any. */\nexport async function getLatestVerification(\n db: Database,\n packageName: string,\n version: string,\n): Promise<VerificationRunRow | null> {\n const rows = await db\n .select()\n .from(verificationRuns)\n .where(\n and(eq(verificationRuns.packageName, packageName), eq(verificationRuns.version, version)),\n )\n .orderBy(desc(verificationRuns.ranAt))\n .limit(1);\n return rows[0] ?? null;\n}\n","/** Write helper for recommendation→outcome capture (`recommendation_outcomes`, §3.1). */\nimport type { Database } from './client';\nimport { recommendationOutcomes, type NewRecommendationOutcomeRow } from './schema';\n\n/** Record one opt-in outcome. Insert-only — the dataset is append-only by design. */\nexport async function recordOutcome(\n db: Database,\n outcome: NewRecommendationOutcomeRow,\n): Promise<void> {\n await db.insert(recommendationOutcomes).values(outcome);\n}\n","{\n \"moment\": {\n \"replacedBy\": \"dayjs\",\n \"reason\": \"In maintenance mode since 2020 (the maintainers recommend alternatives). dayjs is a ~2KB immutable library with a near-identical API.\"\n },\n \"request\": {\n \"replacedBy\": \"got\",\n \"reason\": \"Deprecated in 2020 and no longer maintained. Use the built-in fetch, or got for a full-featured HTTP client.\"\n },\n \"request-promise\": {\n \"replacedBy\": \"got\",\n \"reason\": \"Deprecated alongside request. got returns promises natively.\"\n },\n \"node-sass\": {\n \"replacedBy\": \"sass\",\n \"reason\": \"Deprecated; bindings break on new Node versions. sass is the Dart implementation (sass-embedded for speed).\"\n },\n \"tslint\": {\n \"replacedBy\": \"typescript-eslint\",\n \"reason\": \"Deprecated in 2019 in favor of ESLint. Use typescript-eslint to lint TypeScript.\"\n },\n \"enzyme\": {\n \"replacedBy\": \"@testing-library/react\",\n \"reason\": \"Unmaintained with no official React 17+/18 adapter. React Testing Library is the current standard.\"\n },\n \"protractor\": {\n \"replacedBy\": \"@playwright/test\",\n \"reason\": \"Reached end-of-life in 2023. Use Playwright (or Cypress) for browser E2E.\"\n },\n \"faker\": {\n \"replacedBy\": \"@faker-js/faker\",\n \"reason\": \"The original package was sabotaged and deprecated. @faker-js/faker is the community-maintained fork.\"\n },\n \"bower\": {\n \"replacedBy\": \"npm\",\n \"reason\": \"Deprecated; front-end packages ship on npm now. Use npm (or your package manager) directly.\"\n },\n \"popper.js\": {\n \"replacedBy\": \"@popperjs/core\",\n \"reason\": \"v1 is deprecated. @popperjs/core is the maintained v2 line.\"\n },\n \"create-react-app\": {\n \"replacedBy\": \"vite\",\n \"reason\": \"No longer recommended by the React team and effectively unmaintained. Vite is the current scaffolding standard.\"\n },\n \"babel-eslint\": {\n \"replacedBy\": \"@babel/eslint-parser\",\n \"reason\": \"Deprecated and renamed. Use @babel/eslint-parser.\"\n },\n \"istanbul\": {\n \"replacedBy\": \"nyc\",\n \"reason\": \"The istanbul package is legacy; nyc is its maintained CLI (or c8 for native V8 coverage).\"\n }\n}\n","/**\n * Deprecation → replacement map (§1.2). Agents confidently recommend dead\n * packages (moment, request, …) because their training data froze when those\n * were popular; lurq's freshness is exactly the corrective. This is the curated\n * seed the roadmap calls for — a small, high-confidence set of genuinely\n * superseded packages. Later this graph is learned from outcome data (§3.1);\n * for now it's hand-verified so `evaluate` never steers an agent wrong.\n */\nimport successors from '../data/successors.json';\n\nexport interface Successor {\n /** The package to migrate to. */\n name: string;\n /** Why the original is dead and this replaces it. */\n reason: string;\n}\n\nconst MAP = successors as Record<string, { replacedBy: string; reason: string }>;\n\n/** The recommended successor for a superseded package, or null if it isn't one. */\nexport function lookupSuccessor(name: string): Successor | null {\n const hit = MAP[name.toLowerCase()];\n return hit ? { name: hit.replacedBy, reason: hit.reason } : null;\n}\n","/**\n * GitHub raw README fallback (§9.6). The npm packument `readme` field is often\n * empty (e.g. zod), so we fetch the repo README directly when needed. Public\n * raw content needs no token.\n */\nimport { CACHE_TTL } from '../../core/constants';\nimport { httpRequest } from '../../core/http';\n\nconst HOST = 'raw.githubusercontent.com';\nconst CANDIDATES = ['README.md', 'readme.md', 'README.markdown', 'README'];\n\nexport async function fetchGithubReadme(\n owner: string,\n repo: string,\n fetchImpl?: typeof fetch,\n): Promise<string | null> {\n for (const file of CANDIDATES) {\n const url = `https://${HOST}/${owner}/${repo}/HEAD/${file}`;\n try {\n const { data } = await httpRequest<string>(url, {\n host: HOST,\n ttlMs: CACHE_TTL.github,\n accept: 'text',\n retries: 0,\n fetchImpl,\n });\n if (data && data.trim().length > 0) return data;\n } catch {\n /* try the next candidate */\n }\n }\n return null;\n}\n","/**\n * Summary + usage-guide generation (§9.6 + R1 explainer refinement).\n *\n * lurq generates its OWN guide grounded in the package's README/description —\n * it never depends on Context7. When a summary LLM key is configured we use it;\n * otherwise we fall back to the npm description + a category-derived guide,\n * fabricating nothing. The exact current API is deferred to Context7 via a hint.\n */\nimport { CATEGORIES, isCategory, type Category, type UsageGuide } from '../core/types';\nimport { getConfig } from '../core/config';\nimport { httpRequest } from '../core/http';\nimport { logger } from '../core/logger';\nimport { fetchGithubReadme } from './sources/githubReadme';\nimport type { RawPackageSignals } from './types';\n\nexport interface SummaryInput {\n name: string;\n description: string | null;\n category: Category | null;\n readme: string | null;\n repoUrl: string | null;\n}\n\nexport interface SummaryResult {\n summary: string | null;\n usageGuide: UsageGuide;\n /** Taxonomy category the LLM classified the package into (§2A), or null\n * (always null for the fallback provider — it does no classification). */\n inferredCategory: Category | null;\n}\n\nexport interface SummaryProvider {\n readonly kind: 'openai' | 'fallback';\n generate(input: SummaryInput): Promise<SummaryResult>;\n}\n\n/** Human-readable architectural role per category (generic — lurq has no code context). */\nconst CATEGORY_ROLE: Record<string, string> = {\n framework: 'the core application framework your app is built on',\n 'meta-framework': 'the full-stack framework wrapping routing, rendering, and build',\n 'state-management': 'the client state layer shared across components',\n routing: 'the routing layer mapping URLs to views',\n orm: 'the data-access layer between your code and the database',\n 'database-client': 'the low-level driver that talks to your database',\n 'ui-component-library': 'the prebuilt UI component layer',\n styling: 'the styling layer for your components',\n forms: 'form state and submission handling',\n validation: 'input/schema validation at your boundaries',\n 'data-fetching': 'the server-state/data-fetching layer',\n 'http-client': 'the HTTP request layer for calling APIs',\n auth: 'authentication and session handling',\n testing: 'the test tooling layer',\n 'build-tool': 'the build/dev pipeline',\n bundler: 'the module bundling step',\n linting: 'code-quality and formatting checks',\n 'date-time': 'date and time handling',\n animation: 'UI animation and motion',\n charts: 'data visualization and charts',\n i18n: 'internationalization and localization',\n utility: 'a focused helper you compose into your app',\n other: 'a supporting library in your app',\n};\n\nfunction context7Hint(name: string): string {\n return `For the exact current API of \"${name}\", resolve it via Context7 (resolve-library-id → query-docs).`;\n}\n\n/** Keep text to ~`max` sentences. */\nexport function truncateSentences(text: string, max = 3): string {\n const clean = text.replace(/\\s+/g, ' ').trim();\n if (!clean) return '';\n // Match full sentences, plus a trailing fragment with no terminal punctuation\n // (so descriptions without a period return the whole text, not just the last word).\n const sentences = clean.match(/[^.!?]+[.!?]+|[^.!?]+$/g) ?? [clean];\n return sentences\n .slice(0, max)\n .map((s) => s.trim())\n .join(' ')\n .trim();\n}\n\n// ── Fallback provider (no LLM key) ──────────────────────────────────────────\n\nexport class FallbackSummaryProvider implements SummaryProvider {\n readonly kind = 'fallback' as const;\n\n async generate(input: SummaryInput): Promise<SummaryResult> {\n const description = input.description?.trim() || null;\n const role = CATEGORY_ROLE[input.category ?? 'other'] ?? CATEGORY_ROLE.other!;\n const summary = description ? truncateSentences(description, 3) : null;\n const guide: UsageGuide = {\n whatItIs: description ? truncateSentences(description, 2) : input.name,\n whenToUse: `Reach for ${input.name} when you need ${role}.`,\n whereItFits: `Sits at ${role}.`,\n context7Hint: context7Hint(input.name),\n };\n return { summary, usageGuide: guide, inferredCategory: null };\n }\n}\n\n// ── OpenAI provider (raw fetch, no SDK dependency) ──────────────────────────\n\nconst SYSTEM_PROMPT =\n 'You summarize npm packages factually for an AI coding agent choosing dependencies. ' +\n 'Use ONLY the provided README/description. Never invent capabilities or APIs. ' +\n 'Be concise and concrete. Respond with a JSON object.';\n\nfunction buildUserPrompt(input: SummaryInput): string {\n const readme = (input.readme ?? '').slice(0, 4000);\n // Ask the model to classify only when we don't already have a curated category\n // (§2A) — otherwise the curated value wins and we save the model the choice.\n const needsCategory = input.category == null;\n return [\n `Package: ${input.name}`,\n `Category: ${input.category ?? 'unknown'}`,\n `Description: ${input.description ?? '(none)'}`,\n `README (truncated):\\n${readme || '(none)'}`,\n '',\n 'Return JSON with keys:',\n '- \"summary\": 2-3 sentences: what it is, when to use it, how it fits an app.',\n '- \"whatItIs\": one sentence.',\n '- \"whenToUse\": one sentence on the ideal use case.',\n '- \"whenNotToUse\": one sentence on when to pick something else (or \"\").',\n '- \"whereItFits\": one sentence on its architectural role.',\n '- \"howToWireIn\": one short sentence on the minimal setup (install + entry point), or \"\".',\n ...(needsCategory\n ? [`- \"category\": the single best fit from this list: ${CATEGORIES.join(', ')}.`]\n : []),\n ].join('\\n');\n}\n\nexport class OpenAISummaryProvider implements SummaryProvider {\n readonly kind = 'openai' as const;\n\n private readonly endpoint: string;\n private readonly host: string;\n\n constructor(\n private readonly apiKey: string,\n private readonly model: string,\n baseUrl: string,\n private readonly fetchImpl?: typeof fetch,\n ) {\n this.endpoint = `${baseUrl.replace(/\\/$/, '')}/chat/completions`;\n this.host = new URL(baseUrl).host;\n }\n\n async generate(input: SummaryInput): Promise<SummaryResult> {\n try {\n const body = JSON.stringify({\n model: this.model,\n messages: [\n { role: 'system', content: SYSTEM_PROMPT },\n { role: 'user', content: buildUserPrompt(input) },\n ],\n response_format: { type: 'json_object' },\n temperature: 0.2,\n });\n const { data } = await httpRequest<any>(this.endpoint, {\n host: this.host,\n method: 'POST',\n ttlMs: 30 * 24 * 60 * 60 * 1000, // cache summaries 30d to control cost\n cacheKey: `openai-summary ${this.model} ${input.name} ${(input.readme ?? '').length}`,\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n },\n body,\n fetchImpl: this.fetchImpl,\n });\n const content = data?.choices?.[0]?.message?.content;\n const parsed = content ? JSON.parse(content) : {};\n const guide: UsageGuide = {\n whatItIs: str(parsed.whatItIs) || input.name,\n whenToUse: str(parsed.whenToUse),\n whenNotToUse: str(parsed.whenNotToUse) || undefined,\n whereItFits: str(parsed.whereItFits),\n howToWireIn: str(parsed.howToWireIn) || undefined,\n context7Hint: context7Hint(input.name),\n };\n const rawCategory = str(parsed.category);\n const inferredCategory = rawCategory && isCategory(rawCategory) ? rawCategory : null;\n return {\n summary: str(parsed.summary) ? truncateSentences(parsed.summary, 3) : null,\n usageGuide: guide,\n inferredCategory,\n };\n } catch (err) {\n logger.warn(`summary LLM failed for ${input.name}, using fallback: ${(err as Error).message}`);\n return new FallbackSummaryProvider().generate(input);\n }\n }\n}\n\nfunction str(value: unknown): string {\n return typeof value === 'string' ? value.trim() : '';\n}\n\n// ── Factory + input assembly ────────────────────────────────────────────────\n\nexport function createSummaryProvider(fetchImpl?: typeof fetch): SummaryProvider {\n const config = getConfig();\n if (config.SUMMARY_PROVIDER === 'openai' && config.SUMMARY_API_KEY) {\n return new OpenAISummaryProvider(\n config.SUMMARY_API_KEY,\n config.SUMMARY_MODEL,\n config.SUMMARY_BASE_URL,\n fetchImpl,\n );\n }\n return new FallbackSummaryProvider();\n}\n\n/** Assemble the summary input, fetching the GitHub-raw README when npm's is empty. */\nexport async function buildSummaryInput(\n signals: RawPackageSignals,\n category: Category | null,\n fetchImpl?: typeof fetch,\n): Promise<SummaryInput> {\n const registry = signals.registry;\n let readme = registry?.readme?.trim() || null;\n if (!readme && registry?.repo) {\n readme = await fetchGithubReadme(registry.repo.owner, registry.repo.repo, fetchImpl).catch(\n () => null,\n );\n }\n return {\n name: signals.name,\n description: registry?.description ?? null,\n category,\n readme,\n repoUrl: registry?.repoUrl ?? null,\n };\n}\n","/**\n * Gather all source signals for one package (§9.7 steps 1–5). Fault-isolated:\n * each source is wrapped so a single failure records an error and degrades that\n * signal to null rather than failing the package (§17).\n */\nimport { logger } from '../core/logger';\nimport type { Category } from '../core/types';\nimport { fetchBundlephobia } from './sources/bundlephobia';\nimport { fetchDepsDev } from './sources/depsDev';\nimport { fetchGithubRepo } from './sources/github';\nimport { fetchDownloadGrowth, fetchWeeklyDownloads } from './sources/npmDownloads';\nimport { fetchNpmRegistry } from './sources/npmRegistry';\nimport type { NpmDownloadsData, RawPackageSignals } from './types';\n\nexport interface CollectDeps {\n githubToken?: string;\n fetchImpl?: typeof fetch;\n /**\n * Pre-fetched weekly downloads (from the bulk endpoint). When provided (even\n * as null), the per-package weekly fetch is skipped — avoiding the downloads\n * API's harsh rate limits during a full sync.\n */\n prefetchedWeekly?: number | null;\n}\n\nasync function attempt<T>(\n source: string,\n errors: { source: string; message: string }[],\n fn: () => Promise<T>,\n): Promise<T | null> {\n try {\n return await fn();\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n errors.push({ source, message });\n logger.debug(`[${source}] ${message}`);\n return null;\n }\n}\n\nexport async function collectSignals(\n name: string,\n category: Category | null,\n deps: CollectDeps = {},\n): Promise<RawPackageSignals> {\n const { githubToken, fetchImpl } = deps;\n const errors: { source: string; message: string }[] = [];\n\n // 1. Registry first — it provides the repo + version the other sources need.\n const registry = await attempt('npm-registry', errors, () => fetchNpmRegistry(name, fetchImpl));\n\n const repo = registry?.repo ?? null;\n const version = registry?.latestVersion ?? null;\n\n // 2–5. The rest run concurrently.\n const [downloads, github, depsDev, bundle] = await Promise.all([\n attempt('npm-downloads', errors, async (): Promise<NpmDownloadsData> => {\n const weeklyDownloads =\n deps.prefetchedWeekly !== undefined\n ? deps.prefetchedWeekly\n : await fetchWeeklyDownloads(name, fetchImpl);\n const downloadGrowth90d = await fetchDownloadGrowth(name, fetchImpl);\n return { weeklyDownloads, downloadGrowth90d };\n }),\n repo && githubToken\n ? attempt('github', errors, () => fetchGithubRepo(repo.owner, repo.repo, githubToken, fetchImpl))\n : Promise.resolve(null),\n attempt('deps-dev', errors, () => fetchDepsDev(name, version, repo, fetchImpl)),\n attempt('bundlephobia', errors, () => fetchBundlephobia(name, category, fetchImpl)),\n ]);\n\n return { name, registry, downloads, github, depsDev, bundle, errors };\n}\n","/**\n * Lightweight category inference (§11). Maps a natural-language need to a\n * taxonomy category via keyword matching. Returns null when uncertain, so the\n * caller searches across all categories rather than over-filtering.\n */\nimport type { Category } from '../core/types';\nimport type { RawPackageSignals } from '../ingestion/types';\n\nconst RULES: { category: Category; patterns: RegExp }[] = [\n { category: 'meta-framework', patterns: /\\b(meta-?framework|next\\.?js|nuxt|remix|astro|gatsby|sveltekit|full-?stack framework)\\b/ },\n { category: 'state-management', patterns: /\\b(state management|global state|store|redux|zustand|jotai|mobx|atoms?)\\b/ },\n { category: 'routing', patterns: /\\b(rout(e|er|ing)|navigation|url matching)\\b/ },\n { category: 'orm', patterns: /\\b(orm|object-?relational|query builder|prisma|drizzle|sequelize|typeorm)\\b/ },\n { category: 'database-client', patterns: /\\b(database (driver|client)|postgres|mysql|mongo(db)?|redis|sqlite|db driver)\\b/ },\n { category: 'ui-component-library', patterns: /\\b(component library|ui kit|ui components?|design system|buttons?|modal|dialog)\\b/ },\n { category: 'styling', patterns: /\\b(styl(e|ing)|css|tailwind|sass|scss|class ?names?|theme)\\b/ },\n { category: 'forms', patterns: /\\b(forms?|form (state|library|handling)|input handling)\\b/ },\n { category: 'validation', patterns: /\\b(validat(e|ion|or)|schema|parse input|type ?safe parsing)\\b/ },\n { category: 'data-fetching', patterns: /\\b(data fetching|server state|react query|swr|graphql client|caching queries)\\b/ },\n { category: 'http-client', patterns: /\\b(http client|fetch wrapper|rest client|make (a )?request|ajax|api calls?)\\b/ },\n { category: 'auth', patterns: /\\b(auth(entication|orization)?|login|session|jwt|oauth|password hashing)\\b/ },\n { category: 'testing', patterns: /\\b(test(ing|s)?|unit test|e2e|assertion|mocking|test runner)\\b/ },\n { category: 'bundler', patterns: /\\b(bundler|bundle (modules?|code)|webpack|rollup|esbuild|parcel)\\b/ },\n { category: 'build-tool', patterns: /\\b(build tool|dev server|monorepo|task runner|compile|transpile)\\b/ },\n // date-time precedes linting: \"date formatting\" must not be captured by linting's\n // bare \"formatting\" token before the date rule is reached (first-match-wins).\n { category: 'date-time', patterns: /\\b(dates?|date ?time|time(zone)?s?|calendar|parse dates?|format dates?)\\b/ },\n { category: 'linting', patterns: /\\b(lint(er|ing)?|formatter|formatting|code (quality|style|format)|prettier|eslint)\\b/ },\n { category: 'animation', patterns: /\\b(animat(e|ion)|motion|transition|spring|gsap|3d)\\b/ },\n { category: 'charts', patterns: /\\b(charts?|graphs?|data ?vis(ualization)?|plots?|dashboards?)\\b/ },\n { category: 'i18n', patterns: /\\b(i18n|internationali[sz]ation|localization|translat(e|ion)|locale)\\b/ },\n { category: 'framework', patterns: /\\b(framework|react|vue|svelte|angular|web server|backend framework)\\b/ },\n { category: 'utility', patterns: /\\b(debounce|throttle|deep ?clone|slugify|uuid|util(ity|ities)?|helper|lodash|retry)\\b/ },\n];\n\nexport function inferCategory(need: string): Category | null {\n const text = need.toLowerCase();\n for (const rule of RULES) {\n if (rule.patterns.test(text)) return rule.category;\n }\n return null;\n}\n\n/**\n * Categorize-on-ingest (§2A): infer a category from a package's *own* text —\n * name, keywords, description, and the README head — instead of a user query.\n * Keywords are repeated to give them extra weight (they're the most reliable\n * categorical signal). Returns null when no rule matches; the caller then falls\n * back to the LLM classifier or leaves the category null.\n */\nexport function inferCategoryFromSignals(signals: RawPackageSignals): Category | null {\n const r = signals.registry;\n const keywords = (r?.keywords ?? []).join(' ');\n const text = [\n signals.name,\n keywords,\n keywords, // weight keywords higher via repetition\n r?.description ?? '',\n (r?.readme ?? '').slice(0, 600),\n ]\n .filter(Boolean)\n .join(' ');\n return inferCategory(text);\n}\n","/**\n * Locate package-relative resources at runtime. Works in dev (tsx, source under\n * src/) and when published (bundled under dist/), by walking up from this module\n * until a directory containing package.json is found.\n */\nimport { existsSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nlet cachedRoot: string | undefined;\n\n/** Absolute path to the installed lurq package root (the dir with package.json). */\nexport function packageRoot(): string {\n if (cachedRoot) return cachedRoot;\n let dir = dirname(fileURLToPath(import.meta.url));\n // Walk up to the filesystem root looking for our package.json.\n for (;;) {\n if (existsSync(join(dir, 'package.json'))) {\n cachedRoot = dir;\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n // Fallback: current working directory.\n cachedRoot = process.cwd();\n return cachedRoot;\n}\n\n/** Folder holding generated Drizzle migrations. */\nexport function migrationsDir(): string {\n return join(packageRoot(), 'drizzle');\n}\n\n/** The curated seed list shipped with the package. */\nexport function seedJsonPath(): string {\n return join(packageRoot(), 'src', 'data', 'seed.json');\n}\n\n/** User-level weight-override config (§4): `~/.config/lurq/weights.json`. */\nexport function userWeightsPath(): string {\n const base = process.env.XDG_CONFIG_HOME || join(homedir(), '.config');\n return join(base, 'lurq', 'weights.json');\n}\n\n/** Project-local weight-override config (§4): `.lurq/weights.json` in the cwd.\n * Takes precedence over the user-level file when present. */\nexport function projectWeightsPath(): string {\n return join(process.cwd(), '.lurq', 'weights.json');\n}\n","/**\n * All scoring weights and thresholds in one tunable file (§10).\n * Changing the model means editing this file only.\n */\n\n/** Composite health-score weights. Must sum to 1.0. */\nexport const HEALTH_WEIGHTS = {\n maintenance: 0.35,\n adoption: 0.3,\n reliability: 0.25,\n efficiency: 0.1,\n} as const;\n\n/**\n * Health↔Quality blend for the default composite sort (§1). Quality is a\n * standalone, adoption-independent axis — NOT a member of HEALTH_WEIGHTS. The\n * two only blend here, for ranking/sort: composite = (1−λ)·health + λ·quality.\n * λ is the single most impactful knob `edit-weights` exposes.\n */\nexport const COMPOSITE = {\n lambda: 0.35,\n} as const;\n\n/**\n * Quality sub-score component weights (of the *available* components — missing\n * signals are dropped, not zeroed, via weightedAverage). All inputs are\n * adoption-independent: they measure how well-built a package is, not how many\n * people use it.\n */\nexport const QUALITY_WEIGHTS = {\n types: 0.25,\n tests: 0.2,\n docs: 0.2,\n changelog: 0.1,\n deps: 0.1,\n license: 0.1,\n provenance: 0.05,\n} as const;\n\nexport const QUALITY = {\n /** README at/above this many characters scores full marks on doc length. */\n docsFullLengthChars: 1200,\n /** Direct-dependency count at/above this scores 0 on the deps component (log-scaled). */\n depsLogMax: 30,\n /** A license string present but not OSI-recognized scores this (vs 100 / 0). */\n licenseUnrecognizedScore: 60,\n} as const;\n\n/** Maintenance sub-score component weights (of the available components). */\nexport const MAINTENANCE_WEIGHTS = {\n recency: 0.5,\n cadence: 0.25,\n closeRatio: 0.25,\n} as const;\n\nexport const MAINTENANCE = {\n /** A release within this many days scores full recency. */\n freshDays: 30,\n /** Recency decays linearly to 0 by this many days (~24 months). */\n staleDays: 730,\n /** Releases/12mo at or above this cap full cadence. */\n cadenceCap: 12,\n /** deprecated/archived hard-cap maintenance at this value. */\n deadCap: 15,\n} as const;\n\nexport const ADOPTION = {\n /** log10(weekly downloads): this maps to 0. */\n downloadsLogMin: 1, // 10/wk\n /** log10(weekly downloads): this maps to 100. */\n downloadsLogMax: 7, // 10M/wk\n /** log10(stars) that maps to 100. */\n starsLogMax: 5, // 100k stars\n /** Weight of the stars component when available (downloads gets the rest). */\n starsWeight: 0.2,\n /** Growth bonus: growth fraction × this, clamped to ±cap. */\n growthMultiplier: 30,\n growthBonusCap: 20,\n} as const;\n\nexport const RELIABILITY = {\n /** Used when no Scorecard is available (unknown security posture). */\n neutralWhenUnknown: 50,\n /** Advisory penalties by severity. */\n penalty: {\n critical: 40,\n high: 20,\n moderate: 8,\n low: 3,\n info: 0,\n },\n} as const;\n\nexport const EFFICIENCY = {\n /** Bundle size at the category median maps to this score; smaller → higher. */\n medianScore: 50,\n} as const;\n\n/** Proactive-discovery crawler tuning (§2B). The gate is quality-only — downloads\n * are deliberately excluded so merit, not popularity, decides what graduates. */\nexport const DISCOVERY = {\n /** A queued candidate must clear this quality pre-score to graduate to ingest. */\n minPreScore: 45,\n /** Max candidates fully ingested per crawler run (cost bound). */\n perRunCap: 25,\n /** npm-search hits to pull per category keyword. */\n searchSizePerCategory: 10,\n /** Max dependency-graph neighbors to enqueue per tracked seed. */\n graphNeighborsPerSeed: 20,\n} as const;\n\n// ── Tunable weight model: defaults ← user-config ← env (§4) ──────────────────\n\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { projectWeightsPath, userWeightsPath } from '../core/paths';\n\n/** The user-tunable slice of the model (§4). Sub-component weights and\n * thresholds stay fixed; these are the knobs `edit-weights` exposes. */\nexport interface WeightConfig {\n health: {\n maintenance: number;\n adoption: number;\n reliability: number;\n efficiency: number;\n };\n /** Health↔Quality blend λ for the default sort composite. */\n composite: { lambda: number };\n}\n\nexport const DEFAULT_WEIGHTS: WeightConfig = {\n health: { ...HEALTH_WEIGHTS },\n composite: { ...COMPOSITE },\n};\n\nexport type WeightSource = 'defaults' | 'user-config' | 'project-config';\n\n/** Where overrides are read from, if anywhere — for `lurq weights` to report. */\nexport function activeWeightsPath(): { path: string; source: WeightSource } | null {\n if (existsSync(projectWeightsPath())) return { path: projectWeightsPath(), source: 'project-config' };\n if (existsSync(userWeightsPath())) return { path: userWeightsPath(), source: 'user-config' };\n return null;\n}\n\nlet cachedWeights: WeightConfig | undefined;\n\n/**\n * Resolve the effective weight model: defaults, overlaid by a config file\n * (project-local wins over user-level), overlaid by env (`LURQ_COMPOSITE_LAMBDA`).\n * Always returns a validated, sum-to-1 health block. Memoized; call\n * `resetWeightsCache()` after a write or in tests.\n */\nexport function loadWeights(): WeightConfig {\n if (cachedWeights) return cachedWeights;\n\n let merged: WeightConfig = structuredClone(DEFAULT_WEIGHTS);\n const active = activeWeightsPath();\n if (active) {\n try {\n const fromFile = JSON.parse(readFileSync(active.path, 'utf8')) as Partial<WeightConfig>;\n merged = mergeWeights(merged, fromFile);\n } catch {\n // A corrupt override file must never break scoring — fall back to defaults.\n }\n }\n\n const envLambda = process.env.LURQ_COMPOSITE_LAMBDA;\n if (envLambda !== undefined && envLambda !== '') {\n const n = Number(envLambda);\n if (Number.isFinite(n)) merged.composite.lambda = n;\n }\n\n cachedWeights = validateWeights(merged).weights;\n return cachedWeights;\n}\n\nexport function resetWeightsCache(): void {\n cachedWeights = undefined;\n}\n\nfunction mergeWeights(base: WeightConfig, over: Partial<WeightConfig>): WeightConfig {\n return {\n health: { ...base.health, ...(over.health ?? {}) },\n composite: { ...base.composite, ...(over.composite ?? {}) },\n };\n}\n\nexport interface WeightValidation {\n weights: WeightConfig;\n /** True if the health block was renormalized to sum to 1.0. */\n normalized: boolean;\n}\n\n/**\n * Clamp λ to [0,1] and renormalize the health block to sum to 1.0 (§4 invariant,\n * weights.ts:6). Returns the cleaned weights and whether normalization happened\n * so the CLI can report it.\n */\nexport function validateWeights(w: WeightConfig): WeightValidation {\n const lambda = Math.max(0, Math.min(1, w.composite.lambda));\n const h = w.health;\n const sum = h.maintenance + h.adoption + h.reliability + h.efficiency;\n let normalized = false;\n let health = h;\n if (sum <= 0) {\n health = { ...DEFAULT_WEIGHTS.health };\n normalized = true;\n } else if (Math.abs(sum - 1) > 1e-6) {\n health = {\n maintenance: h.maintenance / sum,\n adoption: h.adoption / sum,\n reliability: h.reliability / sum,\n efficiency: h.efficiency / sum,\n };\n normalized = true;\n }\n return { weights: { health, composite: { lambda } }, normalized };\n}\n\n/** Keys settable via `edit-weights --set` and their slot in the config. */\nconst SETTABLE: Record<string, (w: WeightConfig, v: number) => void> = {\n 'health.maintenance': (w, v) => (w.health.maintenance = v),\n 'health.adoption': (w, v) => (w.health.adoption = v),\n 'health.reliability': (w, v) => (w.health.reliability = v),\n 'health.efficiency': (w, v) => (w.health.efficiency = v),\n 'composite.lambda': (w, v) => (w.composite.lambda = v),\n};\n\nexport function settableKeys(): string[] {\n return Object.keys(SETTABLE);\n}\n\n/** Apply `key=value` overrides to a config, returning a new config. Throws on an\n * unknown key or non-numeric value. */\nexport function applyOverrides(base: WeightConfig, sets: string[]): WeightConfig {\n const next = structuredClone(base);\n for (const entry of sets) {\n const eq = entry.indexOf('=');\n if (eq < 0) throw new Error(`Invalid --set \"${entry}\" (expected key=value).`);\n const key = entry.slice(0, eq).trim();\n const value = Number(entry.slice(eq + 1).trim());\n const apply = SETTABLE[key];\n if (!apply) {\n throw new Error(`Unknown weight key \"${key}\". Settable: ${settableKeys().join(', ')}.`);\n }\n if (!Number.isFinite(value)) throw new Error(`Value for \"${key}\" must be a number.`);\n apply(next, value);\n }\n return next;\n}\n\n/** Persist a config to the override file and bust the cache. */\nexport function saveWeights(w: WeightConfig, scope: 'user' | 'project' = 'user'): string {\n const path = scope === 'project' ? projectWeightsPath() : userWeightsPath();\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(w, null, 2) + '\\n', 'utf8');\n resetWeightsCache();\n return path;\n}\n\n/** Remove any override files, restoring defaults. Returns the paths removed. */\nexport function resetWeights(): string[] {\n const removed: string[] = [];\n for (const path of [projectWeightsPath(), userWeightsPath()]) {\n if (existsSync(path)) {\n rmSync(path);\n removed.push(path);\n }\n }\n resetWeightsCache();\n return removed;\n}\n\n/** Human-readable explanation per health component / knob (§4 `--explain`). */\nexport const WEIGHT_EXPLANATIONS: Record<string, string> = {\n maintenance: 'release recency, cadence, and issue close-ratio (weights.ts MAINTENANCE_WEIGHTS).',\n adoption: 'weekly downloads (log-scaled), stars, and 90-day growth (weights.ts ADOPTION).',\n reliability: 'OpenSSF Scorecard scaled 0–100, minus advisory penalties (weights.ts RELIABILITY).',\n efficiency: 'bundle size vs the category median; frontend categories only (weights.ts EFFICIENCY).',\n quality:\n 'intrinsic, adoption-independent: types, tests, docs, changelog, deps, license, provenance (weights.ts QUALITY_WEIGHTS). A standalone axis — it does NOT feed health.',\n lambda: 'how much the default sort composite favors quality over health: (1−λ)·health + λ·quality.',\n};\n\n/** Confidence-label thresholds (§10, §1). */\nexport const CONFIDENCE = {\n proven: {\n minWeeklyDownloads: 100_000,\n minAgeMonths: 12,\n maxLastReleaseMonths: 6,\n },\n emerging: {\n minWeeklyDownloads: 5_000,\n strongGrowth: 0.5,\n maxLastReleaseMonths: 9,\n },\n /** `promising` (§1): new but intrinsically high-quality, regardless of adoption. */\n promising: {\n minQuality: 70,\n maxLastReleaseMonths: 12,\n },\n} as const;\n","/**\n * Scoring & confidence model (§10). All functions are pure and take an explicit\n * `now` for deterministic testing.\n *\n * Two-pass design: maintenance / adoption / reliability / confidence depend only\n * on a single package, so they're computed in pass 1. Efficiency needs the\n * category median bundle size (§10), so it — and the composite health score —\n * are computed in pass 2 once all packages are collected.\n */\nimport type { Advisory, Category, Confidence, ScoreBreakdown } from '../core/types';\nimport { isFrontendCategory } from '../core/types';\nimport type { RawPackageSignals } from '../ingestion/types';\nimport {\n ADOPTION,\n COMPOSITE,\n CONFIDENCE,\n EFFICIENCY,\n HEALTH_WEIGHTS,\n MAINTENANCE,\n MAINTENANCE_WEIGHTS,\n QUALITY,\n QUALITY_WEIGHTS,\n RELIABILITY,\n} from './weights';\n\nexport interface ScoringInput {\n weeklyDownloads: number | null;\n downloadGrowth90d: number | null;\n stars: number | null;\n firstPublishedAt: Date | null;\n lastReleaseAt: Date | null;\n releasesLast12mo: number | null;\n openIssues: number | null;\n closedIssues: number | null;\n scorecard: number | null;\n advisories: Advisory[];\n deprecated: boolean;\n archived: boolean;\n bundleMinGzipKb: number | null;\n category: Category | null;\n // ── Intrinsic-quality signals (§1), adoption-independent ──\n hasTypes: boolean | null;\n hasTestScript: boolean | null;\n readmeLength: number | null;\n hasExamples: boolean | null;\n hasHomepage: boolean | null;\n hasReleaseNotes: boolean | null;\n directDependenciesCount: number | null;\n license: string | null;\n hasProvenance: boolean | null;\n}\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\nconst MONTH_MS = 30 * DAY_MS;\n\nconst clamp = (n: number, lo = 0, hi = 100): number => Math.max(lo, Math.min(hi, n));\nconst daysSince = (date: Date | null, now: Date): number | null =>\n date ? (now.getTime() - date.getTime()) / DAY_MS : null;\nconst monthsSince = (date: Date | null, now: Date): number | null =>\n date ? (now.getTime() - date.getTime()) / MONTH_MS : null;\n\n/** Build a ScoringInput from collected raw signals. */\nexport function toScoringInput(signals: RawPackageSignals, category: Category | null): ScoringInput {\n const { registry, downloads, github, depsDev, bundle } = signals;\n const readme = registry?.readme ?? null;\n return {\n weeklyDownloads: downloads?.weeklyDownloads ?? null,\n downloadGrowth90d: downloads?.downloadGrowth90d ?? null,\n stars: github?.stars ?? null,\n firstPublishedAt: registry?.firstPublishedAt ?? null,\n lastReleaseAt: github?.lastReleaseAt ?? registry?.lastReleaseAt ?? null,\n releasesLast12mo: github?.releasesLast12mo ?? null,\n openIssues: github?.openIssues ?? null,\n closedIssues: github?.closedIssues ?? null,\n scorecard: depsDev?.scorecard ?? null,\n advisories: depsDev?.advisories ?? [],\n deprecated: registry?.deprecated ?? false,\n archived: github?.archived ?? false,\n bundleMinGzipKb: bundle?.bundleMinGzipKb ?? null,\n category,\n // Quality signals — null (not false) when the manifest itself is missing, so\n // weightedAverage drops the component rather than scoring it 0.\n hasTypes: registry ? registry.hasTypes : null,\n hasTestScript: registry ? registry.hasTestScript : null,\n readmeLength: readme !== null ? readme.length : null,\n hasExamples: readme !== null ? /```/.test(readme) : null,\n hasHomepage: registry ? registry.homepage !== null : null,\n hasReleaseNotes: github?.releasesLast12mo != null ? github.releasesLast12mo > 0 : null,\n directDependenciesCount: registry?.directDependenciesCount ?? null,\n license: registry?.license ?? null,\n hasProvenance: registry ? registry.hasProvenance : null,\n };\n}\n\n// ── Maintenance ─────────────────────────────────────────────────────────────\n\nexport function computeMaintenance(input: ScoringInput, now: Date): number {\n if (input.deprecated || input.archived) return MAINTENANCE.deadCap;\n\n const components: { value: number; weight: number }[] = [];\n\n const days = daysSince(input.lastReleaseAt, now);\n if (days !== null) {\n const recency =\n days <= MAINTENANCE.freshDays\n ? 100\n : clamp((100 * (MAINTENANCE.staleDays - days)) / (MAINTENANCE.staleDays - MAINTENANCE.freshDays));\n components.push({ value: recency, weight: MAINTENANCE_WEIGHTS.recency });\n }\n\n if (input.releasesLast12mo !== null) {\n const cadence = clamp((Math.min(input.releasesLast12mo, MAINTENANCE.cadenceCap) / MAINTENANCE.cadenceCap) * 100);\n components.push({ value: cadence, weight: MAINTENANCE_WEIGHTS.cadence });\n }\n\n if (input.openIssues !== null && input.closedIssues !== null) {\n const total = input.openIssues + input.closedIssues;\n if (total > 0) {\n components.push({ value: (input.closedIssues / total) * 100, weight: MAINTENANCE_WEIGHTS.closeRatio });\n }\n }\n\n return weightedAverage(components);\n}\n\n// ── Adoption ────────────────────────────────────────────────────────────────\n\nexport function computeAdoption(input: ScoringInput): number {\n const dl = input.weeklyDownloads ?? 0;\n const downloadsScore = clamp(\n ((Math.log10(Math.max(dl, 1)) - ADOPTION.downloadsLogMin) /\n (ADOPTION.downloadsLogMax - ADOPTION.downloadsLogMin)) *\n 100,\n );\n\n let base = downloadsScore;\n if (input.stars !== null) {\n const starsScore = clamp((Math.log10(Math.max(input.stars, 1)) / ADOPTION.starsLogMax) * 100);\n base = (1 - ADOPTION.starsWeight) * downloadsScore + ADOPTION.starsWeight * starsScore;\n }\n\n if (input.downloadGrowth90d !== null) {\n const bonus = clamp(\n input.downloadGrowth90d * ADOPTION.growthMultiplier,\n -ADOPTION.growthBonusCap,\n ADOPTION.growthBonusCap,\n );\n base += bonus;\n }\n\n return clamp(base);\n}\n\n// ── Reliability ─────────────────────────────────────────────────────────────\n\nexport function computeReliability(input: ScoringInput): number {\n const base = input.scorecard !== null ? input.scorecard * 10 : RELIABILITY.neutralWhenUnknown;\n const penalty = input.advisories.reduce(\n (sum, adv) => sum + (RELIABILITY.penalty[adv.severity] ?? 0),\n 0,\n );\n return clamp(base - penalty);\n}\n\n// ── Efficiency (pass 2 — needs the category median) ─────────────────────────\n\n/**\n * Efficiency for frontend categories: smaller-than-median bundle → higher score\n * (median maps to 50). Returns null for backend categories / missing data; the\n * null signals the composite to redistribute the efficiency weight (§10, R1).\n */\nexport function computeEfficiency(\n bundleMinGzipKb: number | null,\n category: Category | null,\n categoryMedian: number | null,\n): number | null {\n if (!isFrontendCategory(category) || bundleMinGzipKb === null || !categoryMedian || categoryMedian <= 0) {\n return null;\n }\n const ratio = bundleMinGzipKb / categoryMedian;\n return clamp(100 - ratio * EFFICIENCY.medianScore);\n}\n\n// ── Quality (pass 1 — intrinsic, adoption-independent §1) ────────────────────\n\n/** A small set of OSI-recognized SPDX license IDs (prefix-matched, case-insensitive). */\nconst RECOGNIZED_LICENSES = [\n 'mit',\n 'isc',\n 'apache-2.0',\n 'bsd-2-clause',\n 'bsd-3-clause',\n 'mpl-2.0',\n 'lgpl',\n 'gpl',\n 'agpl',\n 'unlicense',\n '0bsd',\n 'cc0-1.0',\n];\n\nexport function isRecognizedLicense(license: string | null): boolean {\n if (!license) return false;\n const id = license.trim().toLowerCase();\n return RECOGNIZED_LICENSES.some((l) => id === l || id.startsWith(l));\n}\n\n/**\n * Intrinsic-quality score (§1): how well-built a package is, independent of\n * adoption. A weighted average over the *available* components, so a missing\n * signal is dropped rather than penalized. Returns null only when no signal is\n * available at all (e.g. the registry manifest itself failed to load).\n */\nexport function computeQuality(input: ScoringInput): number | null {\n const components: { value: number; weight: number }[] = [];\n\n if (input.hasTypes !== null) {\n components.push({ value: input.hasTypes ? 100 : 0, weight: QUALITY_WEIGHTS.types });\n }\n if (input.hasTestScript !== null) {\n components.push({ value: input.hasTestScript ? 100 : 0, weight: QUALITY_WEIGHTS.tests });\n }\n if (input.readmeLength !== null || input.hasHomepage !== null) {\n const lenScore = Math.min((input.readmeLength ?? 0) / QUALITY.docsFullLengthChars, 1) * 60;\n const examples = input.hasExamples ? 25 : 0;\n const homepage = input.hasHomepage ? 15 : 0;\n components.push({ value: clamp(lenScore + examples + homepage), weight: QUALITY_WEIGHTS.docs });\n }\n if (input.hasReleaseNotes !== null) {\n components.push({ value: input.hasReleaseNotes ? 100 : 0, weight: QUALITY_WEIGHTS.changelog });\n }\n if (input.directDependenciesCount !== null) {\n const deps = input.directDependenciesCount;\n const depsScore = clamp(\n 100 - (Math.log10(deps + 1) / Math.log10(QUALITY.depsLogMax + 1)) * 100,\n );\n components.push({ value: depsScore, weight: QUALITY_WEIGHTS.deps });\n }\n if (input.license !== null) {\n components.push({\n value: isRecognizedLicense(input.license) ? 100 : QUALITY.licenseUnrecognizedScore,\n weight: QUALITY_WEIGHTS.license,\n });\n }\n // Provenance is a pure bonus — only counted when present, never penalizing.\n if (input.hasProvenance) {\n components.push({ value: 100, weight: QUALITY_WEIGHTS.provenance });\n }\n\n if (components.length === 0) return null;\n return weightedAverage(components);\n}\n\n// ── Composite ───────────────────────────────────────────────────────────────\n\n/** Compose the health score, redistributing efficiency's weight when null.\n * Weights default to HEALTH_WEIGHTS but can be overridden (§4 rescore). */\nexport function computeHealthScore(\n breakdown: ScoreBreakdown,\n weights: typeof HEALTH_WEIGHTS | { maintenance: number; adoption: number; reliability: number; efficiency: number } = HEALTH_WEIGHTS,\n): number {\n const { maintenance, adoption, reliability, efficiency } = breakdown;\n const w = weights;\n if (efficiency === null) {\n const denom = w.maintenance + w.adoption + w.reliability;\n return Math.round(\n (w.maintenance * maintenance + w.adoption * adoption + w.reliability * reliability) / denom,\n );\n }\n return Math.round(\n w.maintenance * maintenance +\n w.adoption * adoption +\n w.reliability * reliability +\n w.efficiency * efficiency,\n );\n}\n\n/**\n * Default sort composite (§1): blend the popularity-tilted health score with the\n * adoption-independent quality axis. `lambda` (default COMPOSITE.lambda) is the\n * tunable knob `edit-weights` exposes. Falls back to pure health when quality is\n * unavailable, so a missing manifest never drags a package down.\n */\nexport function computeComposite(\n healthScore: number,\n qualityScore: number | null,\n lambda: number = COMPOSITE.lambda,\n): number {\n if (qualityScore === null) return healthScore;\n return Math.round((1 - lambda) * healthScore + lambda * qualityScore);\n}\n\n// ── Confidence ──────────────────────────────────────────────────────────────\n\nexport function hasCriticalOrHighAdvisory(advisories: Advisory[]): boolean {\n return advisories.some((a) => a.severity === 'critical' || a.severity === 'high');\n}\n\nexport function computeConfidence(\n input: ScoringInput,\n now: Date,\n qualityScore: number | null = null,\n): Confidence {\n const dl = input.weeklyDownloads ?? 0;\n const ageMonths = monthsSince(input.firstPublishedAt, now);\n const lastReleaseMonths = monthsSince(input.lastReleaseAt, now);\n const growth = input.downloadGrowth90d ?? 0;\n\n const provenReleaseOk =\n lastReleaseMonths !== null && lastReleaseMonths <= CONFIDENCE.proven.maxLastReleaseMonths;\n const provenAgeOk = ageMonths !== null && ageMonths >= CONFIDENCE.proven.minAgeMonths;\n\n if (\n dl >= CONFIDENCE.proven.minWeeklyDownloads &&\n provenAgeOk &&\n provenReleaseOk &&\n !hasCriticalOrHighAdvisory(input.advisories) &&\n !input.deprecated &&\n !input.archived\n ) {\n return 'proven';\n }\n\n const emergingReleaseOk =\n lastReleaseMonths !== null && lastReleaseMonths <= CONFIDENCE.emerging.maxLastReleaseMonths;\n const emergingAdoptionOk =\n dl >= CONFIDENCE.emerging.minWeeklyDownloads || growth >= CONFIDENCE.emerging.strongGrowth;\n\n if (emergingAdoptionOk && emergingReleaseOk && !input.deprecated && !input.archived) {\n return 'emerging';\n }\n\n // `promising` (§1): adoption-independent — high intrinsic quality on a package\n // that hasn't yet earned adoption traction. This is how new-but-good packages\n // surface on merit instead of sinking to `unproven`.\n // A freshly published package may have no separate release date (registry and\n // GitHub both empty); fall back to first-publish recency so a new-but-good\n // package isn't locked to `unproven` — the exact case this tier targets.\n const promisingRecencyMonths = lastReleaseMonths ?? ageMonths;\n const promisingReleaseOk =\n promisingRecencyMonths !== null &&\n promisingRecencyMonths <= CONFIDENCE.promising.maxLastReleaseMonths;\n if (\n qualityScore !== null &&\n qualityScore >= CONFIDENCE.promising.minQuality &&\n promisingReleaseOk &&\n !hasCriticalOrHighAdvisory(input.advisories) &&\n !input.deprecated &&\n !input.archived\n ) {\n return 'promising';\n }\n\n return 'unproven';\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction weightedAverage(components: { value: number; weight: number }[]): number {\n if (components.length === 0) return 0;\n const totalWeight = components.reduce((s, c) => s + c.weight, 0);\n if (totalWeight === 0) return 0;\n return Math.round(components.reduce((s, c) => s + c.value * c.weight, 0) / totalWeight);\n}\n\n/** Median of a numeric list, or null if empty. */\nexport function median(values: number[]): number | null {\n if (values.length === 0) return null;\n const sorted = [...values].sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!;\n}\n","export * from './score';\nexport * from './weights';\n","/**\n * Embedding providers (§11). A pluggable interface with two implementations:\n * - OpenAI (`text-embedding-3-small`, 1536-dim) — the default when a key is set.\n * - Local deterministic embedder (no key) — a hashing bag-of-words that captures\n * lexical overlap. Crude but real: it makes `recommend` and tests work with\n * zero credentials (R1 decision). Both emit EMBEDDING_DIM-length unit vectors,\n * so the DB column and pgvector index never change.\n */\nimport { createHash } from 'node:crypto';\nimport { getConfig } from '../core/config';\nimport { EMBEDDING_DIM } from '../core/constants';\nimport { httpRequest } from '../core/http';\nimport { logger } from '../core/logger';\nimport type { Category } from '../core/types';\n\nexport interface EmbeddingProvider {\n readonly kind: 'openai' | 'local';\n readonly dimensions: number;\n /**\n * Stable identity of the vector space this provider produces (e.g.\n * `openai:text-embedding-3-small`, `local`). Stored per row so vector search\n * only compares vectors from the same space — switching providers then falls\n * back to lexical retrieval until rows are re-embedded, instead of silently\n * returning garbage from a cosine distance across incompatible spaces.\n */\n readonly id: string;\n embed(texts: string[]): Promise<number[][]>;\n}\n\n/** Normalized text blob embedded per package (§8.2). */\nexport function buildEmbeddingText(input: {\n name: string;\n category: Category | null;\n summary: string | null;\n description: string | null;\n}): string {\n const body = input.summary || input.description || '';\n return `${input.name}. ${input.category ?? ''}. ${body}`.trim();\n}\n\n// ── Local deterministic embedder ────────────────────────────────────────────\n\nfunction tokenize(text: string): string[] {\n return text\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((t) => t.length > 1);\n}\n\n/** FNV-1a 32-bit hash. */\nfunction fnv1a(str: string): number {\n let h = 0x811c9dc5;\n for (let i = 0; i < str.length; i++) {\n h ^= str.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return h >>> 0;\n}\n\nexport function localEmbed(text: string, dim = EMBEDDING_DIM): number[] {\n const vec = new Float64Array(dim);\n const tokens = tokenize(text);\n const add = (token: string, weight: number) => {\n const idx = fnv1a(token) % dim;\n const sign = fnv1a('s:' + token) & 1 ? 1 : -1;\n vec[idx]! += weight * sign;\n };\n for (const t of tokens) add(t, 1);\n for (let i = 0; i < tokens.length - 1; i++) add(`${tokens[i]} ${tokens[i + 1]}`, 0.5);\n\n // L2-normalize to a unit vector (cosine-friendly).\n let norm = 0;\n for (let i = 0; i < dim; i++) norm += vec[i]! * vec[i]!;\n norm = Math.sqrt(norm) || 1;\n const out = new Array<number>(dim);\n for (let i = 0; i < dim; i++) out[i] = vec[i]! / norm;\n return out;\n}\n\nexport class LocalEmbeddingProvider implements EmbeddingProvider {\n readonly kind = 'local' as const;\n readonly dimensions = EMBEDDING_DIM;\n readonly id = 'local';\n async embed(texts: string[]): Promise<number[][]> {\n return texts.map((t) => localEmbed(t));\n }\n}\n\n// ── OpenAI embedder ─────────────────────────────────────────────────────────\n\nconst OPENAI_BATCH = 96;\n\nexport class OpenAIEmbeddingProvider implements EmbeddingProvider {\n readonly kind = 'openai' as const;\n readonly dimensions = EMBEDDING_DIM;\n readonly id: string;\n\n private readonly endpoint: string;\n private readonly host: string;\n\n constructor(\n private readonly apiKey: string,\n private readonly model: string,\n baseUrl: string,\n private readonly fetchImpl?: typeof fetch,\n ) {\n this.id = `openai:${model}`;\n this.endpoint = `${baseUrl.replace(/\\/$/, '')}/embeddings`;\n this.host = new URL(baseUrl).host;\n }\n\n async embed(texts: string[]): Promise<number[][]> {\n const out: number[][] = [];\n for (let i = 0; i < texts.length; i += OPENAI_BATCH) {\n const batch = texts.slice(i, i + OPENAI_BATCH);\n // Pin the output dimension to the DB column width. Every text-embedding-3\n // model honors `dimensions`, so a larger model (e.g. -3-large, natively\n // 3072-dim) is projected to 1536 instead of overflowing the vector(1536)\n // column at insert time. ponytail: non-OpenAI providers may ignore\n // `dimensions`; the length check below fails loud if the space mismatches.\n const body = JSON.stringify({ model: this.model, input: batch, dimensions: EMBEDDING_DIM });\n const { data } = await httpRequest<any>(this.endpoint, {\n host: this.host,\n method: 'POST',\n ttlMs: 30 * 24 * 60 * 60 * 1000, // cache embeddings 30d to control cost\n cacheKey: `openai-embed ${this.model} ${createHash('sha256').update(body).digest('hex')}`,\n headers: { Authorization: `Bearer ${this.apiKey}`, 'Content-Type': 'application/json' },\n body,\n fetchImpl: this.fetchImpl,\n });\n const vectors: { embedding: number[]; index: number }[] = data?.data ?? [];\n vectors.sort((a, b) => a.index - b.index);\n for (const v of vectors) {\n // Fail loud on any dimension drift rather than silently storing vectors\n // that pgvector can't compare against the rest of the column.\n if (v.embedding.length !== EMBEDDING_DIM) {\n throw new Error(\n `OpenAI model ${this.model} returned ${v.embedding.length}-dim vectors; expected ${EMBEDDING_DIM}. Set EMBEDDING_MODEL to a text-embedding-3 model or update EMBEDDING_DIM.`,\n );\n }\n out.push(v.embedding);\n }\n }\n return out;\n }\n}\n\n// ── Factory ─────────────────────────────────────────────────────────────────\n\nexport function createEmbeddingProvider(fetchImpl?: typeof fetch): EmbeddingProvider {\n const config = getConfig();\n if (config.EMBEDDING_PROVIDER === 'openai' && config.EMBEDDING_API_KEY) {\n return new OpenAIEmbeddingProvider(\n config.EMBEDDING_API_KEY,\n config.EMBEDDING_MODEL,\n config.EMBEDDING_BASE_URL,\n fetchImpl,\n );\n }\n if (config.EMBEDDING_PROVIDER === 'openai' && !config.EMBEDDING_API_KEY) {\n logger.warn('EMBEDDING_API_KEY not set — falling back to the local embedder.');\n }\n return new LocalEmbeddingProvider();\n}\n","/** Map over items with bounded concurrency, preserving input order. */\nexport async function pMap<T, R>(\n items: readonly T[],\n mapper: (item: T, index: number) => Promise<R>,\n concurrency: number,\n): Promise<R[]> {\n const results = new Array<R>(items.length);\n let cursor = 0;\n const workerCount = Math.max(1, Math.min(concurrency, items.length));\n const workers = Array.from({ length: workerCount }, async () => {\n while (cursor < items.length) {\n const index = cursor++;\n results[index] = await mapper(items[index]!, index);\n }\n });\n await Promise.all(workers);\n return results;\n}\n","/**\n * `lurq sync` pipeline (§9.7). End-to-end ingestion for the seed list (or one\n * package): collect signals → score → summarize → upsert, recording a sync_runs\n * row. Idempotent, concurrent, and tolerant of individual source failures (§17).\n *\n * Two-pass for efficiency (§10): pass 1 collects + scores everything that's\n * per-package; then category medians are computed; pass 2 finalizes efficiency\n * and the composite health score. Embeddings are added in M4.\n */\nimport { invalidateCache } from '../core/cache';\nimport { getConfig } from '../core/config';\nimport { pMap } from '../core/concurrency';\nimport { setCacheBypassRead } from '../core/http';\nimport { logger } from '../core/logger';\nimport type { Category, CategorySource, ScoreBreakdown } from '../core/types';\nimport { collectSignals } from '../ingestion/collect';\nimport { fetchBulkWeeklyDownloads } from '../ingestion/sources/npmDownloads';\nimport { buildSummaryInput, createSummaryProvider } from '../ingestion/summarize';\nimport { inferCategoryFromSignals } from '../search/categoryInference';\nimport { buildEmbeddingText, createEmbeddingProvider } from '../search/embeddings';\nimport type { RawPackageSignals } from '../ingestion/types';\nimport {\n computeAdoption,\n computeConfidence,\n computeEfficiency,\n computeHealthScore,\n computeMaintenance,\n computeQuality,\n computeReliability,\n median,\n toScoringInput,\n type ScoringInput,\n} from '../scoring';\nimport { createDb, type Database } from '../db/client';\nimport {\n finishSyncRun,\n getSeedTargets,\n startSyncRun,\n upsertPackage,\n} from '../db/packages';\nimport { isFrontendCategory } from '../core/types';\nimport type { NewPackageRow, SyncError } from '../db/schema';\n\nexport interface SyncOptions {\n full?: boolean;\n packageName?: string;\n}\n\nexport interface SyncSummary {\n seen: number;\n updated: number;\n errors: number;\n status: 'success' | 'partial' | 'failed';\n}\n\ninterface Target {\n name: string;\n category: Category | null;\n}\n\n/** Per-package state carried from pass 1 to pass 2. */\ninterface Computed {\n target: Target;\n /** Final resolved category (curated or inferred at ingest, §2A). */\n category: Category | null;\n categorySource: CategorySource | null;\n signals: RawPackageSignals;\n input: ScoringInput;\n maintenance: number;\n adoption: number;\n reliability: number;\n quality: number | null;\n confidence: ReturnType<typeof computeConfidence>;\n summary: string | null;\n usageGuide: NewPackageRow['usageGuide'];\n}\n\nexport async function runSync(opts: SyncOptions = {}): Promise<SyncSummary> {\n const config = getConfig();\n const now = new Date();\n if (opts.full) setCacheBypassRead(true);\n\n const handle = createDb({ max: Math.max(4, config.LURQ_SYNC_CONCURRENCY) });\n const provider = createSummaryProvider();\n logger.info(`Summary provider: ${provider.kind}`);\n if (!config.GITHUB_TOKEN) {\n logger.warn(\n 'GITHUB_TOKEN not set — GitHub signals (stars, issues, release cadence) will be ' +\n 'skipped, degrading maintenance/adoption scores. Set it for accurate scoring.',\n );\n }\n\n const runId = await startSyncRun(handle.db);\n const allErrors: SyncError[] = [];\n\n try {\n const targets = await resolveTargets(handle.db, opts);\n logger.info(`Syncing ${targets.length} package(s) with concurrency ${config.LURQ_SYNC_CONCURRENCY}…`);\n\n // Bulk-fetch weekly downloads up front (one call per 128 packages) to avoid\n // the downloads API rate limit that per-package bursts trigger.\n logger.info('Fetching weekly downloads in bulk…');\n const weeklyMap = await fetchBulkWeeklyDownloads(targets.map((t) => t.name));\n\n // ── Pass 1: collect + per-package scoring + summary ──────────────────────\n let done = 0;\n const computed = await pMap(\n targets,\n async (target): Promise<Computed | null> => {\n try {\n const signals = await collectSignals(target.name, target.category, {\n githubToken: config.GITHUB_TOKEN,\n prefetchedWeekly: weeklyMap.has(target.name) ? weeklyMap.get(target.name)! : undefined,\n });\n for (const e of signals.errors) allErrors.push({ package: target.name, ...e });\n\n const summaryInput = await buildSummaryInput(signals, target.category);\n const { summary, usageGuide, inferredCategory } = await provider.generate(summaryInput);\n\n // Categorize-on-ingest (§2A): curated category wins; otherwise infer\n // from the package's own text, then fall back to the LLM classifier.\n let category = target.category;\n let categorySource: CategorySource | null = target.category ? 'curated' : null;\n if (!category) {\n category = inferCategoryFromSignals(signals) ?? inferredCategory ?? null;\n categorySource = category ? 'inferred' : null;\n }\n\n const input = toScoringInput(signals, category);\n const quality = computeQuality(input);\n if (++done % 25 === 0) logger.info(` …${done}/${targets.length}`);\n return {\n target,\n category,\n categorySource,\n signals,\n input,\n maintenance: computeMaintenance(input, now),\n adoption: computeAdoption(input),\n reliability: computeReliability(input),\n quality,\n confidence: computeConfidence(input, now, quality),\n summary,\n usageGuide,\n };\n } catch (err) {\n allErrors.push({\n package: target.name,\n source: 'pipeline',\n message: err instanceof Error ? err.message : String(err),\n });\n return null;\n }\n },\n config.LURQ_SYNC_CONCURRENCY,\n );\n\n const ok = computed.filter((c): c is Computed => c !== null);\n\n // ── Category medians for efficiency (§10) ────────────────────────────────\n const medians = computeCategoryMedians(ok);\n\n // ── Embeddings (§11): embed the normalized text blob for each package ─────\n const embProvider = createEmbeddingProvider();\n logger.info(`Embedding provider: ${embProvider.kind}`);\n const embeddings = await embProvider.embed(\n ok.map((c) =>\n buildEmbeddingText({\n name: c.target.name,\n category: c.category,\n summary: c.summary,\n description: c.signals.registry?.description ?? null,\n }),\n ),\n );\n\n // ── Pass 2: efficiency + composite + upsert ──────────────────────────────\n let updated = 0;\n for (let i = 0; i < ok.length; i++) {\n const c = ok[i]!;\n const efficiency = computeEfficiency(\n c.input.bundleMinGzipKb,\n c.category,\n c.category ? (medians.get(c.category) ?? null) : null,\n );\n const breakdown: ScoreBreakdown = {\n maintenance: c.maintenance,\n adoption: c.adoption,\n reliability: c.reliability,\n efficiency,\n quality: c.quality,\n };\n const healthScore = computeHealthScore(breakdown);\n await upsertPackage(\n handle.db,\n assemblePackageRow({\n name: c.target.name,\n category: c.category,\n categorySource: c.categorySource,\n signals: c.signals,\n input: c.input,\n summary: c.summary,\n usageGuide: c.usageGuide,\n confidence: c.confidence,\n breakdown,\n healthScore,\n qualityScore: c.quality,\n embedding: embeddings[i] ?? null,\n embeddingProvider: embProvider.id,\n now,\n }),\n );\n updated++;\n }\n\n const status: SyncSummary['status'] =\n updated === 0 ? 'failed' : allErrors.length > 0 ? 'partial' : 'success';\n await finishSyncRun(handle.db, runId, {\n packagesSeen: targets.length,\n packagesUpdated: updated,\n errors: allErrors,\n status,\n });\n\n logger.info(`Sync ${status}: ${updated}/${targets.length} updated, ${allErrors.length} source errors.`);\n // The index changed — drop cached reads so the next query sees fresh scores.\n if (updated > 0) await invalidateCache();\n return { seen: targets.length, updated, errors: allErrors.length, status };\n } catch (err) {\n await finishSyncRun(handle.db, runId, {\n packagesSeen: 0,\n packagesUpdated: 0,\n errors: [{ package: '*', source: 'pipeline', message: (err as Error).message }],\n status: 'failed',\n });\n throw err;\n } finally {\n if (opts.full) setCacheBypassRead(false);\n await handle.close();\n }\n}\n\nasync function resolveTargets(db: Database, opts: SyncOptions): Promise<Target[]> {\n if (opts.packageName) {\n const seeds = await getSeedTargets(db);\n const found = seeds.find((s) => s.name === opts.packageName);\n return [{ name: opts.packageName, category: found?.category ?? null }];\n }\n return getSeedTargets(db);\n}\n\nfunction computeCategoryMedians(computed: Computed[]): Map<Category, number> {\n const byCategory = new Map<Category, number[]>();\n for (const c of computed) {\n const cat = c.category;\n const kb = c.input.bundleMinGzipKb;\n if (cat && isFrontendCategory(cat) && kb !== null) {\n const list = byCategory.get(cat) ?? [];\n list.push(kb);\n byCategory.set(cat, list);\n }\n }\n const medians = new Map<Category, number>();\n for (const [cat, list] of byCategory) {\n const m = median(list);\n if (m !== null) medians.set(cat, m);\n }\n return medians;\n}\n\n/** Assemble a fully-scored package row. Shared by the bulk sync and the\n * on-demand single-package path (§12.5). */\nexport function assemblePackageRow(p: {\n name: string;\n category: Category | null;\n categorySource: CategorySource | null;\n signals: RawPackageSignals;\n input: ScoringInput;\n summary: string | null;\n usageGuide: NewPackageRow['usageGuide'];\n confidence: NewPackageRow['confidence'];\n breakdown: ScoreBreakdown;\n healthScore: number;\n qualityScore: number | null;\n embedding: number[] | null;\n embeddingProvider: string | null;\n now: Date;\n}): NewPackageRow {\n const r = p.signals.registry;\n return {\n name: p.name,\n ecosystem: 'npm',\n category: p.category,\n categorySource: p.categorySource,\n description: r?.description ?? null,\n summary: p.summary,\n repoUrl: r?.repoUrl ?? null,\n homepage: r?.homepage ?? null,\n latestVersion: r?.latestVersion ?? null,\n license: r?.license ?? null,\n deprecated: p.input.deprecated,\n archived: p.input.archived,\n firstPublishedAt: p.input.firstPublishedAt,\n lastReleaseAt: p.input.lastReleaseAt,\n weeklyDownloads: p.input.weeklyDownloads,\n downloadGrowth90d: p.input.downloadGrowth90d,\n stars: p.input.stars,\n openIssues: p.input.openIssues,\n closedIssues: p.input.closedIssues,\n scorecard: p.input.scorecard,\n bundleMinGzipKb: p.input.bundleMinGzipKb,\n advisories: p.input.advisories,\n peerDependencies: r?.peerDependencies ?? null,\n peerDependenciesMeta: r?.peerDependenciesMeta ?? null,\n engines: r?.engines ?? null,\n healthScore: p.healthScore,\n qualityScore: p.qualityScore,\n confidence: p.confidence,\n scoreBreakdown: p.breakdown,\n usageGuide: p.usageGuide,\n embedding: p.embedding,\n embeddingProvider: p.embedding ? p.embeddingProvider : null,\n dataAsOf: p.now,\n };\n}\n","/**\n * In-process background ingester for on-demand misses (§12.5). Keeps the heavy\n * fetch→score→embed→upsert OFF the request path: evaluate/compare/verify enqueue\n * an untracked-but-real package and return immediately (\"tracking, retry\n * shortly\"), while a bounded worker pool ingests it within seconds.\n *\n * Bounded on purpose — moving unbounded work off the request path just relocates\n * the problem. Dedup (a package already pending or in-flight is never queued\n * again) + a hard pending cap mean a flood of distinct names can't spawn\n * unbounded syncs or grow memory without limit. Process-local; each instance\n * drains its own queue. Durability is by self-heal: if the process dies with\n * work pending, the next request for that package re-enqueues it.\n */\nimport { logger } from '../core/logger';\nimport type { Database } from '../db/client';\nimport { ensureSeedEntry } from '../db/packages';\nimport { syncOnePackage } from './single';\n\nconst MAX_CONCURRENT = 3;\nconst MAX_PENDING = 500;\n\nconst pending: string[] = [];\nconst inFlight = new Set<string>();\nconst queuedNames = new Set<string>();\nlet active = 0;\n\n/** Current backlog (pending + in-flight) — exposed for tests/observability. */\nexport function ingestQueueDepth(): number {\n return pending.length + inFlight.size;\n}\n\n/** Test-only: clear all queue state. */\nexport function resetIngestQueue(): void {\n pending.length = 0;\n inFlight.clear();\n queuedNames.clear();\n active = 0;\n}\n\n/**\n * Schedule an untracked-but-real package for background ingestion. No-op if it's\n * already pending or in-flight, or if the queue is at capacity. Returns without\n * awaiting any network/DB work.\n */\nexport function enqueueIngest(db: Database, name: string): void {\n if (queuedNames.has(name) || inFlight.has(name)) return;\n if (pending.length >= MAX_PENDING) {\n logger.warn(`ingest queue full (${MAX_PENDING}); dropping on-demand request for ${name}`);\n return;\n }\n queuedNames.add(name);\n pending.push(name);\n pump(db);\n}\n\nfunction pump(db: Database): void {\n while (active < MAX_CONCURRENT && pending.length > 0) {\n const name = pending.shift()!;\n queuedNames.delete(name);\n inFlight.add(name);\n active += 1;\n void ingestOne(db, name).finally(() => {\n inFlight.delete(name);\n active -= 1;\n pump(db);\n });\n }\n}\n\nasync function ingestOne(db: Database, name: string): Promise<void> {\n try {\n const row = await syncOnePackage(db, name);\n // Same roster-promotion bar as the old inline path: only genuinely-trackable\n // discoveries join the sync roster, so the on-demand tail can't inflate cost.\n if (row.confidence && row.confidence !== 'unproven') {\n await ensureSeedEntry(db, name, row.category);\n }\n } catch (err) {\n logger.warn(`on-demand ingest failed for ${name}: ${String(err)}`);\n }\n}\n","/**\n * Single-package ingestion + the on-demand path (§12.5). When a queried package\n * isn't tracked but exists on npm, lurq fetches, scores, embeds, stores, and\n * returns it — organically growing coverage beyond the seed list.\n */\nimport { and, eq, isNotNull, sql } from 'drizzle-orm';\nimport { getConfig } from '../core/config';\nimport type { Category, CategorySource, ScoreBreakdown } from '../core/types';\nimport { collectSignals } from '../ingestion/collect';\nimport { fetchWeeklyDownloads, npmPackageExists } from '../ingestion/sources';\nimport { buildSummaryInput, createSummaryProvider } from '../ingestion/summarize';\nimport { inferCategoryFromSignals } from '../search/categoryInference';\nimport {\n computeAdoption,\n computeConfidence,\n computeEfficiency,\n computeHealthScore,\n computeMaintenance,\n computeQuality,\n computeReliability,\n toScoringInput,\n} from '../scoring';\nimport { buildEmbeddingText, createEmbeddingProvider } from '../search/embeddings';\nimport type { Database } from '../db/client';\nimport {\n getPackageByName,\n upsertPackage,\n upsertPackageVersions,\n} from '../db/packages';\nimport { packages, seedPackages, type PackageRow } from '../db/schema';\nimport { assemblePackageRow } from './sync';\n// Safe module cycle: ingestQueue imports syncOnePackage from here, but both\n// bindings are used only at call time, never at module-eval, so ESM resolves it.\nimport { enqueueIngest } from './ingestQueue';\n\nasync function getSeedCategory(db: Database, name: string): Promise<Category | null> {\n const [row] = await db\n .select({ category: seedPackages.category })\n .from(seedPackages)\n .where(eq(seedPackages.name, name))\n .limit(1);\n return row?.category ?? null;\n}\n\n/** Median bundle size across already-tracked packages in a category (for efficiency). */\nasync function getCategoryMedianBundle(db: Database, category: Category): Promise<number | null> {\n const [row] = await db\n .select({\n m: sql<number | null>`percentile_cont(0.5) within group (order by ${packages.bundleMinGzipKb})`,\n })\n .from(packages)\n .where(and(eq(packages.category, category), isNotNull(packages.bundleMinGzipKb)));\n return row?.m ?? null;\n}\n\n/** Fetch, score, embed, and upsert a single package; returns the stored row. */\nexport async function syncOnePackage(\n db: Database,\n name: string,\n opts: { category?: Category | null } = {},\n): Promise<PackageRow> {\n const config = getConfig();\n const now = new Date();\n\n const existing = await getPackageByName(db, name);\n // The curated category (from a manual arg or the seed list) wins. We resolve\n // the final category *after* ingest so a discovered package can be classified\n // from its own text rather than stored as a second-class `null` (§2A).\n const curatedCategory = opts.category ?? (await getSeedCategory(db, name)) ?? null;\n const initialCategory = curatedCategory ?? existing?.category ?? null;\n\n const prefetchedWeekly = await fetchWeeklyDownloads(name).catch(() => null);\n const signals = await collectSignals(name, initialCategory, {\n githubToken: config.GITHUB_TOKEN,\n prefetchedWeekly,\n });\n\n const summaryInput = await buildSummaryInput(signals, initialCategory);\n const { summary, usageGuide, inferredCategory } =\n await createSummaryProvider().generate(summaryInput);\n\n let category: Category | null;\n let categorySource: CategorySource | null;\n if (curatedCategory) {\n category = curatedCategory;\n categorySource = 'curated';\n } else if (existing?.category) {\n category = existing.category;\n categorySource = existing.categorySource ?? 'inferred';\n } else {\n category = inferCategoryFromSignals(signals) ?? inferredCategory ?? null;\n categorySource = category ? 'inferred' : null;\n }\n\n const input = toScoringInput(signals, category);\n\n const median = category ? await getCategoryMedianBundle(db, category) : null;\n const quality = computeQuality(input);\n const breakdown: ScoreBreakdown = {\n maintenance: computeMaintenance(input, now),\n adoption: computeAdoption(input),\n reliability: computeReliability(input),\n efficiency: computeEfficiency(input.bundleMinGzipKb, category, median),\n quality,\n };\n const healthScore = computeHealthScore(breakdown);\n const confidence = computeConfidence(input, now, quality);\n\n const embProvider = createEmbeddingProvider();\n const [embedding] = await embProvider.embed([\n buildEmbeddingText({ name, category, summary, description: signals.registry?.description ?? null }),\n ]);\n\n await upsertPackage(\n db,\n assemblePackageRow({\n name,\n category,\n categorySource,\n signals,\n input,\n summary,\n usageGuide,\n confidence,\n breakdown,\n healthScore,\n qualityScore: quality,\n embedding: embedding ?? null,\n embeddingProvider: embProvider.id,\n now,\n }),\n );\n // Record the version timeline (idempotent). Non-fatal: never block a\n // successful package upsert on the version-history write.\n await upsertPackageVersions(db, name, signals.registry?.versionTimeline ?? []).catch(\n () => {},\n );\n return (await getPackageByName(db, name))!;\n}\n\nexport interface GetOrFetchResult {\n row: PackageRow | null;\n /** True if the package was already in the index before this call. */\n wasTracked: boolean;\n existsOnNpm: boolean;\n /** True if a real-but-untracked package was scheduled for background\n * ingestion this call — the caller should tell the agent to retry shortly. */\n queued?: boolean;\n}\n\n/**\n * Return a tracked package, or — if it's a real npm package not yet in the index\n * (§12.5) — schedule it for background ingestion and return row=null so the\n * request never blocks on the heavy fetch→score→embed→upsert. The caller surfaces\n * a \"tracking, retry shortly\" hint; a few seconds later the row exists. Returns\n * existsOnNpm=false when the name isn't a real package at all.\n */\nexport async function getOrFetchPackage(db: Database, name: string): Promise<GetOrFetchResult> {\n const existing = await getPackageByName(db, name);\n if (existing) return { row: existing, wasTracked: true, existsOnNpm: true };\n\n const exists = await npmPackageExists(name);\n if (!exists) return { row: null, wasTracked: false, existsOnNpm: false };\n\n // Real but untracked: ingest off the request path. Bounded + deduped so a\n // flood of distinct names can't spawn unbounded work (the whole point of not\n // doing it inline). Roster promotion happens in the worker, same quality bar.\n enqueueIngest(db, name);\n return { row: null, wasTracked: false, existsOnNpm: true, queued: true };\n}\n","/**\n * Hybrid recommendation (§3, §11). Two retrievals run over the same candidate\n * table — vector cosine (semantic) and `tsvector` lexical (exact name/keyword) —\n * fused with Reciprocal Rank Fusion (RRF), then re-ranked by a blend of fused\n * relevance and the quality-aware composite (§1). Pure vector search misses\n * exact-name hits (especially the keyless local embedder); the lexical leg fixes\n * that, and RRF avoids having to normalize two incomparable score scales.\n */\nimport { and, cosineDistance, eq, isNotNull, lte, sql } from 'drizzle-orm';\nimport type { Candidate, Category, Confidence, Runtime } from '../core/types';\nimport type { Database } from '../db/client';\nimport { packages } from '../db/schema';\nimport { computeComposite } from '../scoring';\nimport { loadWeights } from '../scoring/weights';\nimport { inferCategory } from './categoryInference';\nimport { createEmbeddingProvider, type EmbeddingProvider } from './embeddings';\n\nexport interface RecommendConstraints {\n runtime?: Runtime;\n license?: string;\n maxBundleKb?: number;\n minConfidence?: Confidence;\n}\n\nexport interface RecommendOptions {\n need: string;\n category?: Category;\n constraints?: RecommendConstraints;\n limit?: number;\n}\n\nconst CONFIDENCE_RANK: Record<Confidence, number> = {\n unproven: 0,\n promising: 1,\n emerging: 2,\n proven: 3,\n};\n/** Fused-relevance vs composite blend (§3, §11). The second term is the\n * quality-aware composite (§1), not raw health — so a well-built package isn't\n * buried by a popularity-tilted score. */\nconst RELEVANCE_WEIGHT = 0.6;\nconst COMPOSITE_WEIGHT = 0.4;\n/** RRF damping constant — standard value from the original RRF paper (§3). */\nconst RRF_K = 60;\n\ninterface Row {\n name: string;\n category: Category | null;\n healthScore: number | null;\n qualityScore: number | null;\n confidence: Confidence | null;\n latestVersion: string | null;\n weeklyDownloads: number | null;\n lastReleaseAt: Date | null;\n repoUrl: string | null;\n}\n\nexport async function recommend(\n db: Database,\n opts: RecommendOptions,\n provider: EmbeddingProvider = createEmbeddingProvider(),\n): Promise<Candidate[]> {\n const limit = Math.min(Math.max(opts.limit ?? 3, 1), 5);\n const [queryVec] = await provider.embed([opts.need]);\n if (!queryVec) return [];\n\n const category = opts.category ?? inferCategory(opts.need);\n const pool = Math.max(limit * 5, 25);\n\n // Primary search (category-filtered when we have one).\n let fused = await hybridSearch(db, queryVec, provider.id, opts.need, opts.constraints, category, pool);\n // If a category filter starved the results, broaden to all categories.\n if (category && fused.length < limit) {\n const broad = await hybridSearch(db, queryVec, provider.id, opts.need, opts.constraints, null, pool);\n const seen = new Set(fused.map((f) => f.row.name));\n fused = fused.concat(broad.filter((f) => !seen.has(f.row.name)));\n }\n if (fused.length === 0) return [];\n\n // Re-rank: blend normalized fused relevance (RRF) with the quality-aware\n // composite (§1). RRF rank-fusion already absorbs both retrieval legs, so the\n // relevance term rewards exact lexical hits the vector leg alone would miss.\n const lambda = loadWeights().composite.lambda;\n const maxRrf = Math.max(...fused.map((f) => f.rrf));\n const ranked = fused\n .map((f) => {\n const relevance = maxRrf > 0 ? f.rrf / maxRrf : 0;\n const composite = computeComposite(f.row.healthScore ?? 0, f.row.qualityScore, lambda) / 100;\n return { row: f.row, score: RELEVANCE_WEIGHT * relevance + COMPOSITE_WEIGHT * composite };\n })\n .sort((a, b) => b.score - a.score)\n .slice(0, limit);\n\n return ranked.map(({ row }) => toCandidate(row));\n}\n\ninterface Fused {\n row: Row;\n rrf: number;\n}\n\n/**\n * Run the vector and lexical retrievals and fuse them with RRF (§3). Each leg\n * independently ranks the candidate set; a doc's fused score is the sum of\n * 1/(k+rank) across the legs it appears in — so documents both legs agree on\n * rise, and exact-name hits the vector leg ranks poorly still surface.\n */\nasync function hybridSearch(\n db: Database,\n queryVec: number[],\n providerId: string,\n need: string,\n constraints: RecommendConstraints | undefined,\n category: Category | null,\n pool: number,\n): Promise<Fused[]> {\n const [vectorRows, lexicalRows] = await Promise.all([\n runVectorQuery(db, queryVec, providerId, constraints, category, pool),\n runLexicalQuery(db, need, constraints, category, pool),\n ]);\n return rrfFuse([vectorRows, lexicalRows]);\n}\n\n/**\n * Reciprocal Rank Fusion over N ranked lists (§3). A document's fused score is\n * Σ 1/(k + rank) across the lists it appears in — using only ranks, never raw\n * scores, so two incomparable scales (cosine distance vs ts_rank) never need\n * normalizing. Generic over `{ name }` so the fusion math is unit-testable.\n */\nexport function rrfFuse<T extends { name: string }>(\n lists: T[][],\n k = RRF_K,\n): { row: T; rrf: number }[] {\n const fused = new Map<string, { row: T; rrf: number }>();\n for (const list of lists) {\n list.forEach((row, idx) => {\n const contribution = 1 / (k + idx + 1); // rank is 1-based\n const prev = fused.get(row.name);\n if (prev) prev.rrf += contribution;\n else fused.set(row.name, { row, rrf: contribution });\n });\n }\n return [...fused.values()].sort((a, b) => b.rrf - a.rrf);\n}\n\nconst ROW_COLUMNS = {\n name: packages.name,\n category: packages.category,\n healthScore: packages.healthScore,\n qualityScore: packages.qualityScore,\n confidence: packages.confidence,\n latestVersion: packages.latestVersion,\n weeklyDownloads: packages.weeklyDownloads,\n lastReleaseAt: packages.lastReleaseAt,\n repoUrl: packages.repoUrl,\n} as const;\n\n/** Shared filter conditions (category + constraints) for both retrieval legs. */\nfunction buildConditions(\n constraints: RecommendConstraints | undefined,\n category: Category | null,\n) {\n const conditions = [];\n if (category) conditions.push(eq(packages.category, category));\n if (constraints?.license) conditions.push(eq(packages.license, constraints.license));\n if (constraints?.maxBundleKb !== undefined) {\n conditions.push(lte(packages.bundleMinGzipKb, constraints.maxBundleKb));\n }\n if (constraints?.minConfidence) {\n const allowed = (['proven', 'emerging', 'promising', 'unproven'] as Confidence[]).filter(\n (c) => CONFIDENCE_RANK[c] >= CONFIDENCE_RANK[constraints.minConfidence!],\n );\n conditions.push(\n sql`${packages.confidence} in ${sql.raw(`(${allowed.map((c) => `'${c}'`).join(',')})`)}`,\n );\n }\n return conditions;\n}\n\n/** Semantic leg: pgvector cosine, ordered by ascending distance. */\nasync function runVectorQuery(\n db: Database,\n queryVec: number[],\n providerId: string,\n constraints: RecommendConstraints | undefined,\n category: Category | null,\n pool: number,\n): Promise<Row[]> {\n const distance = cosineDistance(packages.embedding, queryVec);\n // Only compare vectors produced in the same space as the query vector. Rows\n // embedded by a different provider/model are excluded (they get retrieved by\n // the lexical leg instead) rather than compared across incompatible spaces.\n const conditions = [\n isNotNull(packages.embedding),\n eq(packages.embeddingProvider, providerId),\n ...buildConditions(constraints, category),\n ];\n return db\n .select(ROW_COLUMNS)\n .from(packages)\n .where(and(...conditions))\n .orderBy(distance)\n .limit(pool);\n}\n\n/** Lexical leg: full-text `tsvector` match, ranked by `ts_rank` (§3). */\nasync function runLexicalQuery(\n db: Database,\n need: string,\n constraints: RecommendConstraints | undefined,\n category: Category | null,\n pool: number,\n): Promise<Row[]> {\n const tsquery = sql`websearch_to_tsquery('english', ${need})`;\n const rank = sql<number>`ts_rank(${packages.searchVector}, ${tsquery})`;\n const conditions = [sql`${packages.searchVector} @@ ${tsquery}`, ...buildConditions(constraints, category)];\n return db\n .select(ROW_COLUMNS)\n .from(packages)\n .where(and(...conditions))\n .orderBy(sql`${rank} desc`)\n .limit(pool);\n}\n\nfunction toCandidate(row: Row): Candidate {\n return {\n name: row.name,\n category: row.category,\n healthScore: row.healthScore ?? 0,\n qualityScore: row.qualityScore,\n confidence: row.confidence ?? 'unproven',\n why: buildWhy(row),\n latestVersion: row.latestVersion,\n weeklyDownloads: row.weeklyDownloads,\n lastReleaseAt: row.lastReleaseAt ? row.lastReleaseAt.toISOString() : null,\n repoUrl: row.repoUrl,\n };\n}\n\n/** A ≤1-sentence rationale (§12.3.1). */\nfunction buildWhy(row: Row): string {\n const parts: string[] = [];\n if (row.confidence) parts.push(row.confidence);\n if (row.weeklyDownloads) parts.push(`${formatDownloads(row.weeklyDownloads)} weekly downloads`);\n if (row.healthScore !== null) parts.push(`health ${row.healthScore}`);\n return parts.join(', ') || 'tracked package';\n}\n\nfunction formatDownloads(n: number): string {\n if (n >= 1_000_000) return `${Math.round(n / 100_000) / 10}M`;\n if (n >= 1_000) return `${Math.round(n / 1_000)}k`;\n return String(n);\n}\n","/**\n * Supply-chain risk gate.\n *\n * Rolls the individual findings from `verify` into a single level an agent can\n * act on before installing:\n * high — do not install without human review\n * medium — proceed with caution / prefer an alternative\n * low — no supply-chain red flags\n *\n * Install scripts alone are NOT escalated (esbuild, sharp, husky all use them);\n * they only matter on an otherwise low-trust package.\n */\nimport type { RiskLevel } from '../core/types';\n\nexport interface RiskInput {\n /** All collected riskFlags (used for the `single-maintainer` signal). */\n flags: string[];\n hasCriticalOrHighAdvisory: boolean;\n /** Name closely mimics a popular package. */\n typosquat: boolean;\n /** Runs preinstall/install/postinstall hooks. */\n installScripts: boolean;\n /** First published within the last 7 days. */\n brandNew: boolean;\n /** Fewer than ~1k weekly downloads (or unknown). */\n lowTrust: boolean;\n deprecatedOrArchived: boolean;\n}\n\nexport function assessRisk(i: RiskInput): RiskLevel {\n // Classic malware fingerprint: brand-new + install hooks + ~no adoption.\n const malwarePattern = i.installScripts && i.brandNew && i.lowTrust;\n if (i.typosquat || i.hasCriticalOrHighAdvisory || malwarePattern) return 'high';\n\n if (\n i.deprecatedOrArchived ||\n (i.installScripts && (i.lowTrust || i.brandNew)) ||\n (i.lowTrust && i.flags.includes('single-maintainer'))\n ) {\n return 'medium';\n }\n return 'low';\n}\n","[\n \"react\", \"react-dom\", \"react-router\", \"react-router-dom\", \"next\", \"vue\",\n \"vue-router\", \"pinia\", \"vuex\", \"svelte\", \"solid-js\", \"preact\", \"angular\",\n \"@angular/core\", \"jquery\", \"lodash\", \"underscore\", \"ramda\", \"immer\", \"rxjs\",\n \"express\", \"koa\", \"fastify\", \"@nestjs/core\", \"hapi\", \"connect\", \"body-parser\",\n \"cookie-parser\", \"cors\", \"helmet\", \"morgan\", \"compression\", \"express-session\",\n \"express-rate-limit\", \"multer\", \"passport\", \"jsonwebtoken\", \"bcrypt\",\n \"bcryptjs\", \"axios\", \"node-fetch\", \"got\", \"undici\", \"superagent\", \"request\",\n \"cheerio\", \"puppeteer\", \"playwright\", \"cypress\", \"jsdom\", \"ws\", \"socket.io\",\n \"socket.io-client\", \"graphql\", \"@apollo/client\", \"apollo-server\", \"dataloader\",\n \"mongoose\", \"mongodb\", \"pg\", \"mysql2\", \"sequelize\", \"prisma\", \"knex\",\n \"drizzle-orm\", \"typeorm\", \"redis\", \"ioredis\", \"sqlite3\", \"better-sqlite3\",\n \"typescript\", \"eslint\", \"prettier\", \"tslint\", \"webpack\", \"vite\", \"rollup\",\n \"esbuild\", \"parcel\", \"@babel/core\", \"babel-core\", \"babel-loader\", \"ts-node\",\n \"tsx\", \"tsup\", \"nodemon\", \"concurrently\", \"npm-run-all\", \"jest\", \"vitest\",\n \"mocha\", \"chai\", \"sinon\", \"ava\", \"tape\", \"supertest\", \"@testing-library/react\",\n \"enzyme\", \"chalk\", \"colors\", \"kleur\", \"picocolors\", \"ansi-colors\", \"commander\",\n \"yargs\", \"meow\", \"minimist\", \"inquirer\", \"prompts\", \"ora\", \"boxen\", \"figlet\",\n \"cli-progress\", \"debug\", \"dotenv\", \"cross-env\", \"rimraf\", \"glob\", \"fast-glob\",\n \"chokidar\", \"fs-extra\", \"execa\", \"cross-spawn\", \"shelljs\", \"which\", \"semver\",\n \"uuid\", \"nanoid\", \"ulid\", \"moment\", \"dayjs\", \"date-fns\", \"luxon\", \"zod\", \"yup\",\n \"joi\", \"ajv\", \"validator\", \"class-validator\", \"winston\", \"pino\", \"bunyan\",\n \"nodemailer\", \"node-cron\", \"bull\", \"bullmq\", \"kafkajs\", \"amqplib\", \"sharp\",\n \"jimp\", \"archiver\", \"tar\", \"adm-zip\", \"qs\", \"query-string\", \"form-data\",\n \"mime-types\", \"http-errors\", \"classnames\", \"clsx\", \"styled-components\",\n \"@emotion/react\", \"tailwindcss\", \"postcss\", \"autoprefixer\", \"sass\", \"less\",\n \"framer-motion\", \"three\", \"d3\", \"chart.js\", \"recharts\", \"gsap\", \"swiper\",\n \"leaflet\", \"mapbox-gl\", \"formik\", \"react-hook-form\", \"redux\", \"@reduxjs/toolkit\",\n \"zustand\", \"jotai\", \"mobx\", \"bootstrap\", \"@popperjs/core\", \"aws-sdk\",\n \"@aws-sdk/client-s3\", \"firebase\", \"firebase-admin\", \"stripe\", \"twilio\",\n \"openai\", \"@anthropic-ai/sdk\", \"googleapis\", \"bignumber.js\", \"decimal.js\",\n \"mathjs\", \"slugify\", \"faker\", \"@faker-js/faker\", \"puppeteer-core\"\n]\n","/**\n * Typosquat detection.\n *\n * A package whose name is a near-miss of a popular one (`crossenv` for\n * `cross-env`, `expres` for `express`) is the classic supply-chain attack: a\n * coding agent fat-fingers or hallucinates a name and installs the impostor.\n * We compare a queried name against the most-downloaded packages lurq already\n * tracks — a tiny edit distance to a popular name the package itself is NOT is\n * a strong signal.\n */\nimport popularPackages from '../data/popular-packages.json';\n\n/** Static baseline of well-known npm names. Unioned with the tracked corpus so\n * detection still works on a cold/thin index (fresh deploy, few syncs) and\n * catches squats of famous packages that aren't tracked yet. */\nconst POPULAR_BASELINE = popularPackages as string[];\n\n/** Tracked top-downloads names + the static baseline, de-duplicated. Pass the\n * result as the corpus to `detectTyposquat` so the guard is never silently off. */\nexport function typosquatCorpus(trackedTopNames: string[]): string[] {\n return [...new Set([...POPULAR_BASELINE, ...trackedTopNames])];\n}\n\n/** `@scope/name` → `name` so scope decoration doesn't dominate the distance. */\nfunction bareName(name: string): string {\n const slash = name.indexOf('/');\n return (slash >= 0 ? name.slice(slash + 1) : name).toLowerCase();\n}\n\n/**\n * Damerau-Levenshtein (optimal string alignment) edit distance — counts\n * insertions, deletions, substitutions, and adjacent transpositions.\n */\nexport function editDistance(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n if (m === 0) return n;\n if (n === 0) return m;\n\n // Rolling rows: prevPrev enables the adjacent-transposition check.\n let prevPrev = new Array<number>(n + 1).fill(0);\n let prev = Array.from({ length: n + 1 }, (_, j) => j);\n for (let i = 1; i <= m; i++) {\n const cur = new Array<number>(n + 1).fill(0);\n cur[0] = i;\n for (let j = 1; j <= n; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n let val = Math.min(\n (prev[j] ?? 0) + 1,\n (cur[j - 1] ?? 0) + 1,\n (prev[j - 1] ?? 0) + cost,\n );\n if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {\n val = Math.min(val, (prevPrev[j - 2] ?? 0) + 1);\n }\n cur[j] = val;\n }\n prevPrev = prev;\n prev = cur;\n }\n return prev[n] ?? 0;\n}\n\nexport type TyposquatHit = { target: string; distance: number };\n\n/**\n * Closest popular package within `maxDistance` edits, or null. The queried name\n * being popular itself is never a hit. Names shorter than 4 chars are skipped —\n * at that length a single edit is noise, not an attack signal.\n */\nexport function detectTyposquat(\n name: string,\n popular: readonly string[],\n maxDistance = 2,\n): TyposquatHit | null {\n const target = bareName(name);\n if (target.length < 4) return null;\n if (popular.some((p) => p.toLowerCase() === name.toLowerCase())) return null;\n\n let best: TyposquatHit | null = null;\n for (const p of popular) {\n const cand = bareName(p);\n if (cand === target) continue; // same bare name (e.g. a fork under a scope)\n if (Math.abs(cand.length - target.length) > maxDistance) continue; // can't be close\n const dist = editDistance(target, cand);\n if (dist >= 1 && dist <= maxDistance && (!best || dist < best.distance)) {\n best = { target: p, distance: dist };\n if (dist === 1) break; // nothing closer is possible\n }\n }\n return best;\n}\n","/**\n * MCP tool handlers (§12.3). Pure functions over a Database — the transport\n * layer (server.ts) just wires zod schemas to these. Responses are kept compact\n * (§12.4): summaries truncated, advisories capped, no raw payloads, always a\n * `dataAsOf` and a `stale` hint when data is old (§17).\n */\nimport { createHash } from 'node:crypto';\nimport { sql } from 'drizzle-orm';\nimport { cached } from '../core/cache';\nimport { STALENESS_DAYS } from '../core/constants';\nimport type {\n Advisory,\n AdvisorySeverity,\n BuildSignal,\n BuildVerified,\n Category,\n CompatOutput,\n Confidence,\n EvaluateOutput,\n VerifyOutput,\n} from '../core/types';\nimport { checkCompat } from '../compat/check';\nimport type { Database } from '../db/client';\nimport { getTopPackageNames } from '../db/packages';\nimport { getLatestVerificationByName } from '../db/verification';\nimport { recordOutcome } from '../db/outcomes';\nimport { lookupSuccessor } from '../core/successors';\nimport type { VerificationRunRow } from '../db/schema';\nimport { packages, type PackageRow } from '../db/schema';\nimport { fetchNpmRegistry, fetchWeeklyDownloads, npmPackageExists } from '../ingestion/sources';\nimport { truncateSentences } from '../ingestion/summarize';\nimport { getOrFetchPackage } from '../pipeline/single';\nimport { hasCriticalOrHighAdvisory } from '../scoring/score';\nimport { recommend, type RecommendOptions } from '../search/recommend';\nimport { assessRisk } from '../security/risk';\nimport { detectTyposquat, typosquatCorpus } from '../security/typosquat';\n\nconst SEVERITY_RANK: Record<AdvisorySeverity, number> = {\n critical: 4,\n high: 3,\n moderate: 2,\n low: 1,\n info: 0,\n};\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nfunction isStale(dataAsOf: Date | null): boolean {\n if (!dataAsOf) return true;\n return Date.now() - dataAsOf.getTime() > STALENESS_DAYS * DAY_MS;\n}\n\n/** Re-derive the wall-clock `stale` hint (§17) on a (possibly cached) evaluate\n * row, so a cached response doesn't keep claiming fresh data after it ages past\n * the threshold between syncs. */\nfunction refreshStale(out: EvaluateOutput): EvaluateOutput {\n out.stale = isStale(out.dataAsOf ? new Date(out.dataAsOf) : null) || undefined;\n return out;\n}\n\nfunction withinDays(date: Date | null, days: number): boolean {\n return date ? Date.now() - date.getTime() <= days * DAY_MS : false;\n}\n\n/** Top advisories by severity, capped (§12.4). */\nfunction topAdvisories(advisories: Advisory[] | null, max = 5): Advisory[] {\n if (!advisories?.length) return [];\n return [...advisories]\n .sort((a, b) => SEVERITY_RANK[b.severity] - SEVERITY_RANK[a.severity])\n .slice(0, max);\n}\n\n/** Map a stored row to the compact EvaluateOutput shape (§12.3.2). */\nexport function rowToEvaluate(row: PackageRow): EvaluateOutput {\n const breakdown = row.scoreBreakdown ?? {\n maintenance: 0,\n adoption: 0,\n reliability: 0,\n efficiency: null,\n quality: null,\n };\n return {\n dataAsOf: (row.dataAsOf ?? new Date()).toISOString(),\n stale: isStale(row.dataAsOf) || undefined,\n name: row.name,\n category: row.category,\n healthScore: row.healthScore ?? 0,\n qualityScore: row.qualityScore ?? null,\n confidence: (row.confidence as Confidence) ?? 'unproven',\n scoreBreakdown: breakdown,\n latestVersion: row.latestVersion,\n lastReleaseAt: row.lastReleaseAt ? row.lastReleaseAt.toISOString() : null,\n weeklyDownloads: row.weeklyDownloads,\n downloadGrowth90d: row.downloadGrowth90d,\n scorecard: row.scorecard,\n bundleMinGzipKb: row.bundleMinGzipKb,\n deprecated: row.deprecated,\n archived: row.archived,\n advisories: topAdvisories(row.advisories),\n summary: row.summary ? truncateSentences(row.summary, 3) : null,\n usageGuide: row.usageGuide ?? null,\n repoUrl: row.repoUrl,\n replacedBy: lookupSuccessor(row.name),\n };\n}\n\nexport async function latestDataAsOf(db: Database): Promise<string> {\n const [row] = await db\n .select({ m: sql<string | null>`max(${packages.dataAsOf})` })\n .from(packages);\n return new Date(row?.m ?? Date.now()).toISOString();\n}\n\n// ── recommend ───────────────────────────────────────────────────────────────\n\nexport interface RecommendInput {\n need: string;\n category?: Category;\n constraints?: RecommendOptions['constraints'];\n}\n\n/** Short, stable cache key from arbitrary input. */\nfunction cacheKey(parts: unknown): string {\n return createHash('sha1').update(JSON.stringify(parts)).digest('hex').slice(0, 24);\n}\n\nexport async function handleRecommend(db: Database, input: RecommendInput) {\n return cached(\n 'rec',\n cacheKey([input.need, input.category ?? null, input.constraints ?? null]),\n async () => {\n const candidates = await recommend(db, {\n need: input.need,\n category: input.category,\n constraints: input.constraints,\n limit: 5,\n });\n return { dataAsOf: await latestDataAsOf(db), candidates };\n },\n // Don't cache empty results — the index may still be populating.\n { skipCache: (r) => r.candidates.length === 0 },\n );\n}\n\n// ── evaluate ────────────────────────────────────────────────────────────────\n\nexport async function handleEvaluate(\n db: Database,\n input: { package: string },\n): Promise<EvaluateOutput | { tracked: false; suggestion: string }> {\n const out = await cached(\n 'eval',\n cacheKey([input.package]),\n async () => {\n const { row, existsOnNpm } = await getOrFetchPackage(db, input.package);\n if (!row) {\n return {\n tracked: false as const,\n suggestion: existsOnNpm\n ? `🎉 Congrats — you're the first to add \"${input.package}\" to lurq's registry! It's being fetched and scored now; retry in a few seconds for the full evidence read.`\n : `\"${input.package}\" was not found on the npm registry. Check the package name.`,\n };\n }\n const evaluated = rowToEvaluate(row);\n const verification = await getLatestVerificationByName(db, row.name);\n return verification\n ? { ...evaluated, buildVerified: toBuildVerified(verification) }\n : evaluated;\n },\n // Don't cache \"not found / not scored yet\" — it may resolve on a later fetch.\n { skipCache: (r) => 'tracked' in r },\n );\n // Re-derive the time-based stale hint, which a cached row would otherwise freeze.\n return 'tracked' in out ? out : refreshStale(out);\n}\n\n// ── compare ─────────────────────────────────────────────────────────────────\n\nexport async function handleCompare(db: Database, input: { packages: string[] }) {\n // Key on the exact input — the response echoes the caller's own names/order in\n // `missing`, so a normalized key would serve another caller's casing.\n const out = await cached(\n 'cmp',\n cacheKey(input.packages),\n async () => {\n const results = await Promise.all(input.packages.map((name) => getOrFetchPackage(db, name)));\n const rows = results\n .map((r) => r.row)\n .filter((row): row is PackageRow => row !== null)\n .map(rowToEvaluate)\n .sort((a, b) => b.healthScore - a.healthScore);\n const missing = input.packages.filter((name) => !rows.some((r) => r.name === name));\n return {\n dataAsOf: await latestDataAsOf(db),\n rows,\n ...(missing.length\n ? {\n missing,\n note: \"🎉 You're the first to add these to lurq's registry! They're being scored now; retry shortly for the full comparison.\",\n }\n : {}),\n };\n },\n // Don't cache a transient miss (a package that momentarily failed to fetch).\n { skipCache: (r) => Boolean((r as { missing?: string[] }).missing?.length) },\n );\n out.rows = out.rows.map(refreshStale);\n return out;\n}\n\n// ── compat ──────────────────────────────────────────────────────────────────\n\nfunction toBuildVerified(v: VerificationRunRow): BuildVerified {\n return {\n version: v.version,\n installed: v.installed,\n loaded: v.imported,\n driver: v.driver,\n ranAt: v.ranAt ? v.ranAt.toISOString() : '',\n };\n}\n\n/**\n * Whole-architecture compatibility for a set of packages: Tier-1 peer/engine\n * analysis + recorded Tier-2 sandbox conflicts (see compat/check).\n */\nexport async function handleCompat(\n db: Database,\n input: { packages: string[] },\n): Promise<CompatOutput> {\n return checkCompat(db, input.packages);\n}\n\n// ── verify ──────────────────────────────────────────────────────────────────\n\nexport async function handleVerify(\n db: Database,\n input: { package: string },\n): Promise<VerifyOutput> {\n const name = input.package;\n const exists = await npmPackageExists(name);\n if (!exists) {\n // A name that doesn't exist but closely mimics a popular one is a squat the\n // agent was about to fall for — surface the suspected target.\n const typo = detectTyposquat(name, typosquatCorpus(await getTopPackageNames(db).catch(() => [])));\n return {\n exists: false,\n tracked: false,\n deprecated: false,\n archived: false,\n latestVersion: null,\n weeklyDownloads: null,\n riskFlags: typo\n ? ['not-found-on-registry', `possible-typosquat-of:${typo.target}`]\n : ['not-found-on-registry'],\n risk: 'high',\n typosquatOf: typo?.target ?? null,\n confidence: null,\n advisoryCount: 0,\n };\n }\n\n const [registry, { row, wasTracked }, popular] = await Promise.all([\n fetchNpmRegistry(name).catch(() => null),\n getOrFetchPackage(db, name),\n getTopPackageNames(db).catch(() => [] as string[]),\n ]);\n\n // On-demand ingestion is now async, so an untracked package has no row yet.\n // Fetch weekly downloads live (one cheap call) rather than let the risk flags\n // falsely trip 'zero-downloads' on a popular package the index hasn't caught up\n // to. Only pays the extra call on the untracked path.\n const weeklyDownloads = row?.weeklyDownloads ?? (await fetchWeeklyDownloads(name).catch(() => null));\n const advisories = row?.advisories ?? [];\n const advisoryCount = advisories.length;\n const deprecated = Boolean(row?.deprecated || registry?.deprecated);\n const archived = Boolean(row?.archived);\n const brandNew = withinDays(registry?.firstPublishedAt ?? null, 7);\n const lowTrust = weeklyDownloads === null || weeklyDownloads < 1000;\n const installScripts = registry?.hasInstallScripts ?? false;\n const typo = detectTyposquat(name, typosquatCorpus(popular));\n\n const riskFlags: string[] = [];\n if (typo) riskFlags.push(`possible-typosquat-of:${typo.target}`);\n if (weeklyDownloads === null || weeklyDownloads === 0) riskFlags.push('zero-downloads');\n else if (weeklyDownloads < 1000) riskFlags.push('low-downloads');\n if (brandNew) riskFlags.push('published-within-7-days');\n if (registry?.maintainersCount === 1) riskFlags.push('single-maintainer');\n if (installScripts) riskFlags.push('runs-install-scripts');\n if (advisoryCount > 0) riskFlags.push('has-known-advisory');\n if (deprecated) riskFlags.push('deprecated');\n if (archived) riskFlags.push('archived');\n\n const risk = assessRisk({\n flags: riskFlags,\n hasCriticalOrHighAdvisory: hasCriticalOrHighAdvisory(advisories),\n typosquat: Boolean(typo),\n installScripts,\n brandNew,\n lowTrust,\n deprecatedOrArchived: deprecated || archived,\n });\n\n return {\n exists: true,\n tracked: wasTracked,\n deprecated,\n archived,\n latestVersion: registry?.latestVersion ?? row?.latestVersion ?? null,\n weeklyDownloads,\n riskFlags,\n risk,\n typosquatOf: typo?.target ?? null,\n confidence: (row?.confidence as Confidence) ?? null,\n advisoryCount,\n };\n}\n\n// ── report_outcome ────────────────────────────────────────────────────────────\n\nexport interface ReportOutcomeInput {\n package: string;\n accepted: boolean;\n buildSignal?: BuildSignal;\n need?: string;\n}\n\n/**\n * Capture an opt-in recommendation outcome (§3.1). Append-only, no source code —\n * just which package, accepted or not, and a coarse build signal. Not cached (a\n * write), and cheap enough that the per-key rate limiter is the only guard needed.\n * `ownerId` is server-injected from the authenticated key, attributing the\n * outcome to an org so the flywheel accrues per-customer, not to a global pool.\n */\nexport async function handleReportOutcome(\n db: Database,\n input: ReportOutcomeInput,\n ownerId: string | null = null,\n): Promise<{ recorded: true }> {\n await recordOutcome(db, {\n ownerId,\n packageName: input.package,\n accepted: input.accepted,\n buildSignal: input.buildSignal ?? null,\n need: input.need ?? null,\n });\n return { recorded: true };\n}\n","/**\n * Optional `diagram` tool (§12.3.5). Emits a reference-architecture Mermaid\n * diagram for a stack the caller has *already chosen* (package names), using\n * built-in layer patterns. Input is stack-only by design: inferring an\n * architecture from a freeform description is the \"architecture oracle\" behavior\n * that the master spec (§4) and roadmap (§1) declare a non-goal. lurq labels a\n * stack you name; it does not design one. A starting point, not a validator.\n *\n * Honesty over completeness:\n * - A package we can't classify (not in the index AND no category match) is\n * placed in an explicit `Unclassified` bucket — never silently dropped into a\n * default layer. The note lists what couldn't be placed. Partial, not\n * authoritative.\n * - KNOWN LIMITATION — front/back framework ambiguity: the taxonomy has a single\n * `framework` category, so a `framework` package can't be told apart as\n * frontend vs backend from its category alone. BACKEND_FRAMEWORKS is a\n * hand-maintained band-aid that re-routes the common backend frameworks to the\n * Backend layer; it degrades as the ecosystem adds new ones (an unlisted\n * backend framework will be drawn in Presentation). The real fix is a taxonomy\n * change (a distinct backend-framework category or a runtime/target flag on\n * packages), which is out of scope for v1. Documented, not solved.\n */\nimport { inArray } from 'drizzle-orm';\nimport type { Category } from '../core/types';\nimport { inferCategory } from '../search/categoryInference';\nimport type { Database } from '../db/client';\nimport { packages } from '../db/schema';\n\n/** Bucket for packages we cannot place: unknown category, or a category with no\n * real architectural home (e.g. `other`). Rendered, but kept out of the flow. */\nconst UNCLASSIFIED = 'Unclassified';\n\n/** Which architectural layer each category sits in. Categories with no honest\n * architectural home (e.g. `other`) are intentionally absent: layerFor routes\n * anything unmapped to UNCLASSIFIED rather than faking a layer. */\nconst LAYER_OF: Partial<Record<Category, string>> = {\n framework: 'Presentation',\n 'meta-framework': 'Presentation',\n 'ui-component-library': 'Presentation',\n styling: 'Presentation',\n animation: 'Presentation',\n charts: 'Presentation',\n 'state-management': 'Client Logic',\n routing: 'Client Logic',\n forms: 'Client Logic',\n validation: 'Client Logic',\n 'data-fetching': 'Client Logic',\n 'http-client': 'Client Logic',\n i18n: 'Client Logic',\n 'date-time': 'Client Logic',\n utility: 'Client Logic',\n auth: 'Backend',\n orm: 'Data',\n 'database-client': 'Data',\n 'build-tool': 'Tooling',\n bundler: 'Tooling',\n linting: 'Tooling',\n testing: 'Tooling',\n};\n\nconst FLOW_LAYERS = ['Presentation', 'Client Logic', 'Backend', 'Data'];\n\n/** Band-aid for the front/back framework ambiguity (see file header). Category\n * `framework` alone can't distinguish frontend from backend, so these common\n * backend frameworks are re-routed to the Backend layer. Hand-maintained;\n * unlisted backend frameworks will be mis-drawn in Presentation. Not a real fix. */\nconst BACKEND_FRAMEWORKS = new Set([\n 'express',\n 'fastify',\n 'koa',\n 'hono',\n '@nestjs/core',\n '@hapi/hapi',\n]);\n\nexport interface Item {\n label: string;\n /** null = could not be classified (not in index, no category match). */\n category: Category | null;\n}\n\nexport function layerFor(item: Item): string {\n if (!item.category) return UNCLASSIFIED;\n if (item.category === 'framework' && BACKEND_FRAMEWORKS.has(item.label)) return 'Backend';\n return LAYER_OF[item.category] ?? UNCLASSIFIED;\n}\n\nfunction nodeId(label: string, i: number): string {\n return `n${i}_${label.replace(/[^a-zA-Z0-9]/g, '_')}`;\n}\n\nexport function buildMermaid(items: Item[]): string {\n const byLayer = new Map<string, Item[]>();\n for (const item of items) {\n const layer = layerFor(item);\n const list = byLayer.get(layer) ?? [];\n list.push(item);\n byLayer.set(layer, list);\n }\n\n const lines = ['flowchart TD', ' user([User])'];\n const ids = new Map<string, string>(); // label → node id\n let counter = 0;\n const repNode = new Map<string, string>(); // layer → first node id\n\n const emitLayer = (layer: string) => {\n const list = byLayer.get(layer);\n if (!list?.length) return;\n lines.push(` subgraph ${layer.replace(/\\s+/g, '_')}[\"${layer}\"]`);\n for (const item of list) {\n const id = nodeId(item.label, counter++);\n ids.set(item.label, id);\n if (!repNode.has(layer)) repNode.set(layer, id);\n // Unclassified nodes carry no category prefix — we don't claim one we lack.\n const text = layer === UNCLASSIFIED ? item.label : `${item.category}: ${item.label}`;\n lines.push(` ${id}[\"${text}\"]`);\n }\n lines.push(' end');\n };\n\n for (const layer of FLOW_LAYERS) emitLayer(layer);\n emitLayer('Tooling');\n emitLayer(UNCLASSIFIED);\n\n // Connect the flow layers that are present, top to bottom.\n const present = FLOW_LAYERS.filter((l) => byLayer.has(l));\n let prev = 'user';\n for (const layer of present) {\n lines.push(` ${prev} --> ${repNode.get(layer)}`);\n prev = repNode.get(layer)!;\n }\n if (byLayer.has('Data')) lines.push(` ${repNode.get('Data')} --> db[(Database)]`);\n\n return lines.join('\\n');\n}\n\nexport interface DiagramInput {\n stack?: string[];\n}\n\nexport async function handleDiagram(\n db: Database,\n input: DiagramInput,\n): Promise<{ mermaid: string; note: string }> {\n if (!input.stack?.length) {\n return {\n mermaid: 'flowchart TD\\n user([User]) --> app[Application]',\n note: 'Provide a `stack` of package names to diagram. lurq labels a stack you choose; it does not infer an architecture from a description.',\n };\n }\n\n const rows = await db\n .select({ name: packages.name, category: packages.category })\n .from(packages)\n .where(inArray(packages.name, input.stack));\n const known = new Map(rows.map((r) => [r.name, r.category]));\n // inferCategory is best-effort on a bare package name (it was built for NL\n // needs); a miss yields null, not a faked category. No silent 'other'.\n const items: Item[] = input.stack.map((name) => ({\n label: name,\n category: known.get(name) ?? inferCategory(name),\n }));\n\n const unclassified = items.filter((i) => layerFor(i) === UNCLASSIFIED).map((i) => i.label);\n const note = unclassified.length\n ? `Reference pattern derived from the provided stack — partial, not authoritative. Could not place ${unclassified.length} package(s): ${unclassified.join(', ')} (not in lurq's index and no category match) — shown under Unclassified, outside the flow.`\n : 'Reference pattern derived from the provided stack. A labeled starting point, not a validated architecture.';\n\n return { mermaid: buildMermaid(items), note };\n}\n","/**\n * Global stack optimizer.\n *\n * Branch-and-bound over each slot's ranked candidates to find the highest-quality\n * combination that's compatible — the globally optimal coherent stack, not the\n * greedy local one. \"Quality\" is rank-regret: each candidate's index in its slot\n * (0 = the top pick), so the objective is to deviate from the ideal ranking as\n * little as possible while staying conflict-free.\n *\n * The feasibility oracle is instant (Tier-1 peer/engine math + pre-loaded sandbox\n * conflict edges), so the search runs purely in memory. Two prunes keep the tree\n * tiny: feasibility (a partial pick that already conflicts can never un-conflict)\n * and bound (a branch whose regret already exceeds the best feasible stack can't\n * win). Both are provably safe, so within the search budget the result is\n * order-independent — the optimum.\n *\n * A node budget caps pathological search spaces (many slots × many candidates).\n * If it's hit the search returns the best stack found so far and sets\n * `bounded: true` — best-effort, no longer a proof of optimality. At realistic\n * stack sizes the budget is never approached.\n */\nimport type { CompatConflict } from '../core/types';\nimport { resolveArchitectureCompat, type CompatMember } from './peerCompat';\n\nexport interface OptimizeResult {\n /** Chosen candidate index per slot (0 = top pick; higher = more regret). */\n selection: number[];\n conflicts: CompatConflict[];\n /** Sum of chosen indices — how far the stack drifted from the ideal ranking. */\n regret: number;\n /** True if the node budget was exhausted: the result is best-effort, not a\n * proven optimum. False (the normal case) means the search completed. */\n bounded: boolean;\n}\n\n/** Conflicts for a (partial) selection: Tier-1 peer/engine + cached sandbox edges. */\nfunction conflictsFor(members: CompatMember[], sandboxConflicts: Set<string>): CompatConflict[] {\n const out = resolveArchitectureCompat(members);\n for (let i = 0; i < members.length; i++) {\n for (let j = i + 1; j < members.length; j++) {\n const a = members[i]!.name;\n const b = members[j]!.name;\n const key = a <= b ? `${a}|${b}` : `${b}|${a}`;\n if (sandboxConflicts.has(key)) {\n out.push({\n source: 'sandbox',\n packages: [a, b],\n detail: `${a} and ${b} are recorded as incompatible (sandbox)`,\n });\n }\n }\n }\n return out;\n}\n\n/**\n * Pick one candidate per slot to minimise total rank-regret subject to\n * compatibility. `slots[i]` is slot i's candidates in preference order.\n */\nexport function optimizeStack(\n slots: CompatMember[][],\n sandboxConflicts: Set<string> = new Set(),\n): OptimizeResult {\n // Every slot must offer at least one candidate — otherwise the non-null\n // indexing below (`slots[s]![idx]!`) yields undefined and crashes in\n // conflictsFor. Callers pre-filter, but keep the exported fn safe to reuse.\n if (slots.some((s) => s.length === 0)) {\n throw new Error('optimizeStack: every slot must have at least one candidate');\n }\n\n const n = slots.length;\n const budget = 50_000;\n let nodes = 0;\n let exhausted = false;\n\n // Incumbent: top pick of every slot. Only a *feasible* stack bounds the search.\n let bestSelection = new Array<number>(n).fill(0);\n let bestRegret = conflictsFor(\n slots.map((c) => c[0]).filter((m): m is CompatMember => Boolean(m)),\n sandboxConflicts,\n ).length === 0\n ? 0\n : Infinity;\n\n const chosen = new Array<number>(n).fill(0);\n const dfs = (slot: number, regret: number): void => {\n if (nodes++ > budget) {\n exhausted = true;\n return;\n }\n if (regret >= bestRegret) return; // bound prune\n if (slot === n) {\n bestSelection = chosen.slice();\n bestRegret = regret;\n return;\n }\n const candidates = slots[slot]!;\n for (let i = 0; i < candidates.length; i++) {\n chosen[slot] = i;\n // Feasibility prune: a conflict among assigned members is permanent, so a\n // partial pick that already conflicts can never become compatible.\n const assigned = chosen.slice(0, slot + 1).map((idx, s) => slots[s]![idx]!);\n if (conflictsFor(assigned, sandboxConflicts).length === 0) {\n dfs(slot + 1, regret + i);\n }\n if (nodes > budget) {\n exhausted = true;\n return;\n }\n }\n };\n dfs(0, 0);\n\n const members = bestSelection.map((idx, s) => slots[s]![idx]!);\n return {\n selection: bestSelection,\n conflicts: conflictsFor(members, sandboxConflicts),\n regret: bestRegret === Infinity ? bestSelection.reduce((a, b) => a + b, 0) : bestRegret,\n bounded: exhausted,\n };\n}\n","/**\n * `plan` tool — turn a described program into an evidence-scored build plan.\n *\n * This is NOT the \"architecture oracle\" non-goal (master-spec §4): it does not\n * invent an architecture from a one-line prompt. It takes a program the caller\n * has *already described in detail* (a spec/README) — or a pre-decomposed list\n * of needs — and runs lurq's normal `recommend` engine slot-by-slot, returning\n * real packages from the index with their scores. lurq still \"supplies building\n * blocks slot-by-slot; the agent assembles the architecture\" (§1.3). The rich\n * input is what removes the guesswork the spec warned against; the §20 roadmap\n * item (\"architecture recommendation … once data can ground it\") is honored\n * because every recommendation is grounded in the scored index.\n *\n * Decomposition (document → needs) follows Option C:\n * - a caller-supplied `needs[]` is used as-is (the agent already read the doc — the\n * fast, zero-LLM path, and the cleanest companion-model division of labor); else\n * - a raw `document` is decomposed server-side: by the summary LLM when a key is\n * configured, otherwise by a transparent heading/keyword heuristic. The heuristic\n * is honest-but-coarse, and the response note says so.\n */\nimport { createHash } from 'node:crypto';\nimport { inArray } from 'drizzle-orm';\nimport { getConfig } from '../core/config';\nimport { httpRequest } from '../core/http';\nimport { checkCompat } from '../compat/check';\nimport { assembleMembers } from '../compat/members';\nimport { optimizeStack } from '../compat/optimize';\nimport type { CompatMember } from '../compat/peerCompat';\nimport { getCompatEdges } from '../db/compat';\nimport { logger } from '../core/logger';\nimport {\n isCategory,\n type Candidate,\n type Category,\n type CompatConflict,\n type CompatOutput,\n} from '../core/types';\nimport type { Database } from '../db/client';\nimport { packages } from '../db/schema';\nimport { inferCategory } from '../search/categoryInference';\nimport { recommend } from '../search/recommend';\nimport { getOrFetchPackage } from '../pipeline/single';\nimport type { PackageRow } from '../db/schema';\nimport { buildMermaid, layerFor } from './diagram';\nimport { latestDataAsOf } from './handlers';\n\n/** A pinned package the user chose, resolved to a fixed single-candidate slot. */\nfunction packageToCandidate(row: PackageRow): Candidate {\n return {\n name: row.name,\n category: row.category,\n healthScore: row.healthScore ?? 0,\n qualityScore: row.qualityScore,\n confidence: row.confidence ?? 'unproven',\n why: 'pinned by you',\n latestVersion: row.latestVersion,\n weeklyDownloads: row.weeklyDownloads,\n lastReleaseAt: row.lastReleaseAt ? row.lastReleaseAt.toISOString() : null,\n repoUrl: row.repoUrl,\n };\n}\n\n/** Resolve user-pinned packages into fixed slots (one candidate, no alternatives)\n * so the optimizer routes the recommended slots around them. Unresolvable pins\n * (not on npm) are returned so the caller can report them. */\nexport async function resolvePins(\n db: Database,\n using: string[] | undefined,\n recommendedNames: Set<string>,\n): Promise<{ slots: PlanSlot[]; unresolved: string[] }> {\n const slots: PlanSlot[] = [];\n const unresolved: string[] = [];\n // Dedupe, and skip a pin the recommender already picked (avoid double slots).\n for (const name of new Set(using ?? [])) {\n if (recommendedNames.has(name)) continue;\n const { row } = await getOrFetchPackage(db, name);\n if (!row) {\n unresolved.push(name);\n continue;\n }\n slots.push({\n need: `using ${name}`,\n category: row.category,\n layer: layerFor({ label: name, category: row.category }),\n recommended: packageToCandidate(row),\n alternatives: [], // fixed: the user chose this, so it never gets swapped\n note: 'pinned by you',\n });\n }\n return { slots, unresolved };\n}\n\n/** A single component/slot to recommend a package for. */\nexport interface PlanNeed {\n need: string;\n category?: Category;\n}\n\nexport interface PlanInput {\n /** Detailed description of the program (spec/README). lurq decomposes it. */\n document?: string;\n /** Pre-decomposed needs (e.g. the calling agent already read the doc). */\n needs?: PlanNeed[];\n /** Packages the user has already chosen. Pinned as fixed slots; lurq\n * recommends only the remaining needs and plans the stack around these. */\n using?: string[];\n /** Ranking bias. 'speed' prefers the lightest-bundle option among the top\n * candidates for a slot; 'balanced' (default) uses the normal ranking. */\n optimize?: 'speed' | 'balanced';\n}\n\nexport interface PlanSlot {\n need: string;\n category: Category | null;\n layer: string;\n recommended: Candidate | null;\n alternatives: Candidate[];\n note?: string;\n /** Picked packages this slot's pick still conflicts with, if it couldn't be\n * auto-resolved with the available alternatives (residual conflict). */\n conflictsWith?: string[];\n /** If plan swapped this slot's pick to keep the stack compatible, the name of\n * the original (higher-ranked) pick it replaced. */\n swappedFrom?: string;\n}\n\nexport interface PlanOutput {\n dataAsOf: string;\n optimize: 'speed' | 'balanced';\n /** Where the slots came from: caller-supplied needs, lurq's LLM, or the heuristic. */\n source: 'needs' | 'llm' | 'heuristic';\n /** The framework/meta-framework that anchored the plan, if one was found. Every\n * other slot was recommended in this ecosystem's context. null = no framework\n * in the spec, so slots were recommended independently. */\n framework: string | null;\n slots: PlanSlot[];\n /** Needs for which no tracked package matched. */\n unmatched: string[];\n mermaid: string;\n note: string;\n /** Whole-stack compatibility of the picked packages (peer-deps/engines +\n * recorded sandbox conflicts). Evidence-backed, with name@version of each\n * member; null if the check couldn't run. */\n compatibility: CompatOutput | null;\n}\n\n/** Candidates to surface per slot: the pick plus a couple of alternatives. */\nconst PER_SLOT = 3;\n/** Cap on slots so a huge document can't fan out into hundreds of queries. */\nconst MAX_SLOTS = 24;\n\nexport async function handlePlan(db: Database, input: PlanInput): Promise<PlanOutput | { note: string }> {\n const optimize = input.optimize ?? 'balanced';\n\n const decomposed = input.needs?.length\n ? { needs: dedupeNeeds(input.needs), source: 'needs' as const }\n : input.document?.trim()\n ? await decompose(input.document)\n : null;\n\n const hasPins = Boolean(input.using?.length);\n if ((!decomposed || decomposed.needs.length === 0) && !hasPins) {\n return {\n note: 'Provide a `document` (a detailed description of your program), a `needs` array, or a `using` list of packages you have already chosen. lurq recommends evidence-scored packages per component — it does not invent an architecture from a bare prompt.',\n };\n }\n\n const needs = (decomposed?.needs ?? []).slice(0, MAX_SLOTS);\n const source = decomposed?.source ?? 'needs';\n\n const safeRecommend = (need: string, category: Category | undefined) =>\n recommend(db, { need, category, limit: PER_SLOT }).catch((err) => {\n logger.warn(`plan: recommend failed for \"${need}\": ${(err as Error).message}`);\n return [] as Candidate[];\n });\n // Effective category per slot — the decomposition hint, else inferred from the\n // ORIGINAL need text (before any framework context is appended, so the word we\n // inject below can never misclassify the slot).\n const effCat = (n: PlanNeed): Category | undefined => n.category ?? inferCategory(n.need) ?? undefined;\n\n // Detect the framework family from the WHOLE spec (document + need texts), so the\n // plan stays coherent even when decomposition doesn't emit a framework slot.\n // This drives the coherence re-rank below.\n const anchorFamily = familyOf(`${input.document ?? ''} ${needs.map((n) => n.need).join(' ')}`);\n\n // Phase 1: if a framework/meta-framework component exists, resolve it first to\n // name the concrete package (a meta-framework like Next wins over a bare\n // framework); otherwise the detected family is the context word.\n const metaIdx = needs.findIndex((n) => effCat(n) === 'meta-framework');\n const anchorIdx = metaIdx >= 0 ? metaIdx : needs.findIndex((n) => effCat(n) === 'framework');\n\n const recs: Candidate[][] = new Array(needs.length);\n let framework: string | null = anchorFamily;\n if (anchorIdx >= 0) {\n recs[anchorIdx] = await safeRecommend(needs[anchorIdx]!.need, effCat(needs[anchorIdx]!));\n framework = recs[anchorIdx]![0]?.name ?? anchorFamily;\n }\n\n // Phase 2: recommend the remaining slots concurrently, weaving the chosen\n // framework into each query so sibling libraries stay in-ecosystem. The slot's\n // category is passed explicitly, so the injected framework word only sways\n // relevance — never the category filter. Framework-agnostic slots (e.g.\n // date/time) are unaffected since their candidates don't mention the framework.\n const [, dataAsOf] = await Promise.all([\n Promise.all(\n needs.map(async (n, i) => {\n if (i === anchorIdx) return;\n const need = framework ? `${n.need} (for a ${framework} app)` : n.need;\n recs[i] = await safeRecommend(need, effCat(n));\n }),\n ),\n latestDataAsOf(db),\n ]);\n\n // Re-rank each slot's candidates: keep the architecture coherent (cross-\n // framework bindings last), then — for 'speed' — prefer the lightest bundle,\n // otherwise preserve recommend's relevance order. One batched lookup keeps\n // `recommend` itself untouched.\n const bundleByName = optimize === 'speed' ? await bundleSizes(db, recs.flat()) : new Map<string, number>();\n\n const recSlots: PlanSlot[] = needs.map((n, i) => {\n const candidates = orderCandidates(recs[i]!, anchorFamily, optimize, bundleByName);\n const recommended = candidates[0] ?? null;\n const category = n.category ?? recommended?.category ?? inferCategory(n.need);\n return {\n need: n.need,\n category,\n layer: layerFor({ label: recommended?.name ?? n.need, category }),\n recommended,\n alternatives: candidates.slice(1),\n note: recommended ? undefined : 'no tracked package matched this need yet',\n };\n });\n\n // Pin the user's chosen packages as fixed slots, then plan the rest around\n // them. Pins lead so they anchor the stack; the optimizer can only move the\n // recommended slots, so it routes them to stay compatible with the pins.\n const recommendedNames = new Set(\n recSlots.map((s) => s.recommended?.name).filter((n): n is string => Boolean(n)),\n );\n const { slots: pinnedSlots, unresolved: unresolvedPins } = await resolvePins(\n db,\n input.using,\n recommendedNames,\n );\n const slots = [...pinnedSlots, ...recSlots];\n\n // Auto-resolve compatibility: actually make the picked stack coherent by\n // swapping a conflicting slot's pick for an alternative that resolves it.\n // Runs before the diagram/output so everything below reflects the final stack.\n const compatibility = await resolveCompat(db, slots);\n\n const unmatched = [\n ...slots.filter((s) => !s.recommended).map((s) => s.need),\n ...unresolvedPins.map((n) => `${n} (pinned, but not found on npm)`),\n ];\n const mermaid = buildMermaid(\n slots\n .filter((s) => s.recommended)\n .map((s) => ({ label: s.recommended!.name, category: s.category })),\n );\n\n return {\n dataAsOf,\n optimize,\n source,\n framework,\n slots,\n unmatched,\n mermaid,\n note: planNote(source, unmatched.length, optimize, framework),\n compatibility,\n };\n}\n\n/** Map each slot (by need) to the other picked packages its pick conflicts with. */\nexport function flagSlotConflicts(\n picks: { need: string; name: string | null }[],\n conflicts: CompatConflict[],\n): Map<string, string[]> {\n const out = new Map<string, string[]>();\n for (const c of conflicts) {\n for (const p of picks) {\n if (p.name && c.packages.includes(p.name)) {\n const others = c.packages.filter((n) => n !== p.name);\n out.set(p.need, [...new Set([...(out.get(p.need) ?? []), ...others])]);\n }\n }\n }\n return out;\n}\n\nconst NO_META = (c: Candidate): CompatMember => ({\n name: c.name,\n version: c.latestVersion,\n peerDependencies: null,\n peerDependenciesMeta: null,\n engines: null,\n});\n\n/**\n * Make the picked stack compatible by *globally optimising* the slot choices:\n * pre-load every candidate's metadata + cached sandbox edges once, then run a\n * branch-and-bound that picks the highest-quality (lowest rank-regret) compatible\n * combination. The chosen alternative is promoted to `recommended` (original\n * demoted, recorded via `swappedFrom`); residual conflicts are flagged per slot.\n * The search is pure/in-memory; only the final report re-reads the DB.\n * Best-effort — never throws.\n */\nasync function resolveCompat(db: Database, slots: PlanSlot[]): Promise<CompatOutput | null> {\n const eligible = slots.filter((s) => s.recommended);\n if (eligible.length < 2) return null;\n\n try {\n // One pass: metadata for every candidate across all slots → pure search.\n const allNames = [\n ...new Set(eligible.flatMap((s) => [s.recommended!, ...s.alternatives].map((c) => c.name))),\n ];\n const [{ members }, edges] = await Promise.all([\n assembleMembers(db, allNames),\n getCompatEdges(db, allNames),\n ]);\n const metaByName = new Map(members.map((m) => [m.name, m]));\n const sandboxConflicts = new Set(\n edges.filter((e) => e.status === 'conflict').map((e) => `${e.packageA}|${e.packageB}`),\n );\n const slotCandidates = eligible.map((s) =>\n [s.recommended!, ...s.alternatives].map((c) => metaByName.get(c.name) ?? NO_META(c)),\n );\n\n const { selection } = optimizeStack(slotCandidates, sandboxConflicts);\n\n // Apply the optimal selection: promote the chosen candidate per slot.\n eligible.forEach((s, i) => {\n const idx = selection[i] ?? 0;\n if (idx <= 0) return;\n const all = [s.recommended!, ...s.alternatives];\n const chosen = all[idx];\n if (!chosen) return;\n s.recommended = chosen;\n s.alternatives = all.filter((c) => c.name !== chosen.name);\n s.swappedFrom = all[0]!.name;\n });\n } catch (err) {\n logger.warn(`plan: compat optimization failed: ${String(err)}`);\n }\n\n // Authoritative report on the final picks, and flag any residual conflicts.\n const compat = await checkCompat(\n db,\n eligible.map((s) => s.recommended!.name),\n ).catch(() => null);\n if (compat) {\n const flags = flagSlotConflicts(\n slots.map((s) => ({ need: s.need, name: s.recommended?.name ?? null })),\n compat.conflicts,\n );\n for (const s of slots) {\n const cw = flags.get(s.need);\n s.conflictsWith = cw?.length ? cw : undefined;\n }\n }\n return compat;\n}\n\nfunction planNote(\n source: PlanOutput['source'],\n unmatched: number,\n optimize: string,\n framework: string | null,\n): string {\n const base =\n source === 'heuristic'\n ? 'Components were extracted from your document with a keyword heuristic (no summary LLM configured) — coarse; pass a `needs` array or set SUMMARY_API_KEY for sharper decomposition.'\n : source === 'llm'\n ? 'Components were extracted from your document by the summary model.'\n : 'Components taken from the supplied needs.';\n const grounding =\n ' Each package is recommended from lurq’s scored index — a labeled, evidence-backed starting point, not a validated architecture.';\n const ctx = framework\n ? ` Anchored to the ${framework} ecosystem so sibling libraries stay coherent across the stack.`\n : '';\n const tail = unmatched ? ` ${unmatched} need(s) had no tracked match (listed in \\`unmatched\\`).` : '';\n const opt = optimize === 'speed' ? ' Ranking favored the lightest-bundle option per slot.' : '';\n return base + grounding + ctx + opt + tail;\n}\n\n/** Merge duplicate needs (same text), keeping the first category hint seen. */\nfunction dedupeNeeds(needs: PlanNeed[]): PlanNeed[] {\n const seen = new Map<string, PlanNeed>();\n for (const n of needs) {\n const key = n.need.trim().toLowerCase();\n if (!key) continue;\n if (!seen.has(key)) seen.set(key, { need: n.need.trim(), category: n.category });\n }\n return [...seen.values()];\n}\n\n/** The framework \"family\" a package name belongs to (by naming convention), or\n * null if framework-agnostic. Lets the plan stay in one ecosystem — never\n * surface a different framework's binding (e.g. vue-router in a React app). */\nconst FAMILY_TOKENS: { family: string; re: RegExp }[] = [\n { family: 'react', re: /\\breact\\b|preact/ },\n { family: 'vue', re: /\\bvue\\b|nuxt/ },\n { family: 'angular', re: /angular/ },\n { family: 'svelte', re: /svelte/ },\n { family: 'solid', re: /\\bsolid(-?js)?\\b/ },\n];\n\nexport function familyOf(name: string): string | null {\n const n = name.toLowerCase();\n for (const f of FAMILY_TOKENS) if (f.re.test(n)) return f.family;\n return null;\n}\n\n/**\n * Order a slot's candidates: in-ecosystem first and cross-framework bindings\n * last (when an anchor framework was found), then — for 'speed' — lightest\n * bundle, otherwise preserving recommend's relevance ranking (V8's sort is\n * stable, so equal-key candidates keep their incoming order).\n */\nexport function orderCandidates(\n cands: Candidate[],\n anchorFamily: string | null,\n optimize: 'speed' | 'balanced',\n bundleByName: Map<string, number>,\n): Candidate[] {\n // +1 same ecosystem, −1 a competing framework, 0 framework-agnostic.\n const coherence = (c: Candidate): number => {\n const fam = familyOf(c.name);\n if (!fam) return 0;\n return fam === anchorFamily ? 1 : -1;\n };\n return [...cands].sort((a, b) => {\n if (anchorFamily) {\n const d = coherence(b) - coherence(a);\n if (d) return d;\n }\n if (optimize === 'speed') {\n return (bundleByName.get(a.name) ?? Infinity) - (bundleByName.get(b.name) ?? Infinity);\n }\n return 0;\n });\n}\n\n/** Batched bundle-size lookup for the 'speed' re-rank. */\nasync function bundleSizes(db: Database, candidates: Candidate[]): Promise<Map<string, number>> {\n const names = [...new Set(candidates.map((c) => c.name))];\n if (names.length === 0) return new Map();\n const rows = await db\n .select({ name: packages.name, bundle: packages.bundleMinGzipKb })\n .from(packages)\n .where(inArray(packages.name, names));\n return new Map(rows.filter((r) => r.bundle != null).map((r) => [r.name, r.bundle as number]));\n}\n\n// ── Decomposition (document → needs) ─────────────────────────────────────────\n\nasync function decompose(document: string): Promise<{ needs: PlanNeed[]; source: 'llm' | 'heuristic' }> {\n const config = getConfig();\n if (config.SUMMARY_PROVIDER === 'openai' && config.SUMMARY_API_KEY) {\n const llm = await decomposeWithLlm(\n document,\n config.SUMMARY_API_KEY,\n config.SUMMARY_MODEL,\n config.SUMMARY_BASE_URL,\n ).catch((err) => {\n logger.warn(`plan: LLM decomposition failed, using heuristic: ${(err as Error).message}`);\n return null;\n });\n if (llm?.length) return { needs: dedupeNeeds(llm), source: 'llm' };\n }\n return { needs: decomposeHeuristic(document), source: 'heuristic' };\n}\n\nconst DECOMPOSE_SYSTEM =\n 'You break a software project description into the distinct technical components that each need a library. ' +\n 'Return ONLY components the project actually requires, grounded in the description. Respond with a JSON object.';\n\nasync function decomposeWithLlm(\n document: string,\n apiKey: string,\n model: string,\n baseUrl: string,\n): Promise<PlanNeed[]> {\n const prompt = [\n 'Project description:',\n document.slice(0, 8000),\n '',\n 'Return JSON: { \"needs\": [ { \"need\": \"<one phrase describing a component that needs a library>\", \"category\": \"<optional taxonomy hint or empty>\" } ] }.',\n 'One entry per distinct component (e.g. routing, validation, ORM, HTTP client). Omit anything not implied by the description.',\n ].join('\\n');\n const { data } = await httpRequest<any>(`${baseUrl.replace(/\\/$/, '')}/chat/completions`, {\n host: new URL(baseUrl).host,\n method: 'POST',\n ttlMs: 24 * 60 * 60 * 1000,\n // Hash the FULL document — length + a 64-char prefix collide for same-length\n // edits or shared templated headers, which would serve a stale decomposition.\n cacheKey: `openai-plan ${model} ${createHash('sha1').update(document).digest('hex')}`,\n headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({\n model,\n messages: [\n { role: 'system', content: DECOMPOSE_SYSTEM },\n { role: 'user', content: prompt },\n ],\n response_format: { type: 'json_object' },\n temperature: 0.2,\n }),\n });\n const content = data?.choices?.[0]?.message?.content;\n const parsed = content ? JSON.parse(content) : {};\n const raw = Array.isArray(parsed?.needs) ? parsed.needs : [];\n return raw\n .map((n: any): PlanNeed | null => {\n const need = typeof n?.need === 'string' ? n.need.trim() : '';\n if (!need) return null;\n const cat = typeof n?.category === 'string' && isCategory(n.category) ? n.category : undefined;\n return { need, category: cat };\n })\n .filter(Boolean) as PlanNeed[];\n}\n\n/**\n * Heuristic fallback: scan the document line-by-line, infer a category per line,\n * and emit one need per distinct category (first matching line as the phrase).\n * Coarse by design — it only surfaces components whose category lurq can name.\n */\nexport function decomposeHeuristic(document: string): PlanNeed[] {\n const byCategory = new Map<Category, string>();\n for (const rawLine of document.split('\\n')) {\n // Strip markdown headings/blockquotes/bullets, then an ordered-list \"12. \"\n // marker — but NOT bare leading digits, so \"2FA auth\" stays intact.\n const line = rawLine.replace(/^[#>*\\-\\s]+/, '').replace(/^\\d+\\.\\s+/, '').trim();\n if (line.length < 3) continue;\n const category = inferCategory(line);\n if (category && !byCategory.has(category)) {\n byCategory.set(category, line.slice(0, 120));\n }\n }\n return [...byCategory.entries()].map(([category, need]) => ({ need, category }));\n}\n","/**\n * Minimal per-tool metrics for the hosted MCP path — Prometheus text format, no\n * dependency. Counts calls, errors, and cumulative latency per tool so an\n * operator can see usage and error rates without wiring up an APM. Process-local\n * (a module singleton): each server instance exposes its own counters at\n * `/metrics`, which is exactly what a Prometheus scrape expects.\n */\ninterface Stat {\n calls: number;\n errors: number;\n totalMs: number;\n}\n\nconst stats = new Map<string, Stat>();\n\n/** Record one tool invocation. `ok=false` marks a handler that threw. */\nexport function recordToolCall(tool: string, ok: boolean, ms: number): void {\n const s = stats.get(tool) ?? { calls: 0, errors: 0, totalMs: 0 };\n s.calls += 1;\n if (!ok) s.errors += 1;\n s.totalMs += ms;\n stats.set(tool, s);\n}\n\n/** Time a tool handler and record the outcome, re-throwing any error unchanged. */\nexport async function timed<T>(tool: string, fn: () => Promise<T>): Promise<T> {\n const start = Date.now();\n let ok = false;\n try {\n const result = await fn();\n ok = true;\n return result;\n } finally {\n recordToolCall(tool, ok, Date.now() - start);\n }\n}\n\n/** Render current counters in Prometheus exposition format. */\nexport function renderPrometheus(): string {\n const lines = [\n '# HELP lurq_tool_calls_total Total MCP tool invocations.',\n '# TYPE lurq_tool_calls_total counter',\n '# HELP lurq_tool_errors_total MCP tool invocations that threw.',\n '# TYPE lurq_tool_errors_total counter',\n '# HELP lurq_tool_duration_ms_total Cumulative tool handler time in ms.',\n '# TYPE lurq_tool_duration_ms_total counter',\n ];\n for (const [tool, s] of stats) {\n const label = `{tool=\"${tool}\"}`;\n lines.push(`lurq_tool_calls_total${label} ${s.calls}`);\n lines.push(`lurq_tool_errors_total${label} ${s.errors}`);\n lines.push(`lurq_tool_duration_ms_total${label} ${s.totalMs}`);\n }\n return lines.join('\\n') + '\\n';\n}\n\n/** Test-only: clear all counters. */\nexport function resetMetrics(): void {\n stats.clear();\n}\n","/**\n * Compact MCP responses (§12.4). Every tool response is JSON injected straight\n * into the calling agent's context window, so each `\"field\":null` or empty\n * container is tokens the user pays for on every call — and noise that dilutes\n * the agent's attention. `compact()` recursively drops null/undefined values,\n * empty arrays, and objects that become empty, keeping only signal.\n *\n * Deliberately KEEPS `false` and `0`: `deprecated:false` and `weeklyDownloads:0`\n * carry meaning an agent shouldn't have to infer from a field's absence. Only\n * genuinely-absent data (null/undefined/empty) is stripped.\n */\nfunction isEmptyObject(value: unknown): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value).length === 0\n );\n}\n\nexport function compact<T>(value: T): T {\n if (Array.isArray(value)) {\n return value\n .map((v) => compact(v))\n .filter((v) => v !== null && v !== undefined) as unknown as T;\n }\n if (value !== null && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [key, raw] of Object.entries(value as Record<string, unknown>)) {\n if (raw === null || raw === undefined) continue;\n const cleaned = compact(raw);\n if (cleaned === null || cleaned === undefined) continue;\n if (Array.isArray(cleaned) && cleaned.length === 0) continue;\n if (isEmptyObject(cleaned)) continue;\n out[key] = cleaned;\n }\n return out as T;\n }\n return value;\n}\n","/**\n * MCP server (§12). Exposes recommend / evaluate / compare / verify over stdio.\n * Inputs are validated with zod; outputs are compact JSON text (§12.4).\n */\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\nimport { SERVER_NAME, VERSION } from '../core/constants';\nimport { CATEGORIES, type Category } from '../core/types';\nimport { createDb } from '../db/client';\nimport { logger } from '../core/logger';\nimport {\n handleCompare,\n handleCompat,\n handleEvaluate,\n handleRecommend,\n handleReportOutcome,\n handleVerify,\n} from './handlers';\nimport { handleDiagram } from './diagram';\nimport { handlePlan } from './plan';\nimport { timed } from './metrics';\nimport { compact } from './compact';\n\nconst categoryEnum = z.enum(CATEGORIES as unknown as [Category, ...Category[]]);\nconst confidenceEnum = z.enum(['proven', 'emerging', 'promising', 'unproven']);\n\n// Validate package names at the trust boundary. A name flows straight into a\n// registry URL (`registry.npmjs.org/${name}`) and the response cache key, so\n// reject anything that isn't a legal npm name: this blocks path/query\n// injection (`/`, `?`, `#`, `%`), whitespace, and control characters. Case is\n// permitted for legacy packages; the char class is what closes the hole.\nexport const npmName = z\n .string()\n .trim()\n .min(1)\n .max(214)\n .regex(/^(?:@[a-z0-9-][a-z0-9-._]*\\/)?[a-z0-9-][a-z0-9-._]*$/i, 'Invalid npm package name');\n\nconst constraintsSchema = z\n .object({\n runtime: z.enum(['browser', 'node', 'both']).optional(),\n license: z.string().optional(),\n maxBundleKb: z.number().positive().optional(),\n minConfidence: confidenceEnum.optional(),\n })\n .optional();\n\n/** Wrap any result object as a compact MCP text response. `compact` strips\n * null/empty fields so the agent's context only carries signal (§12.4). */\nfunction json(obj: unknown) {\n return { content: [{ type: 'text' as const, text: JSON.stringify(compact(obj)) }] };\n}\n\n/**\n * Per-connection identity, resolved from the authenticated API key at the HTTP\n * boundary and threaded into the tools. This is the channel that lets lurq know\n * *who* is calling — stamped onto the data it collects (§3.1 flywheel) so it\n * accrues to an org instead of an anonymous pool. `ownerId` is null on the stdio\n * / local path and for operator-issued keys with no org.\n */\nexport interface ServerContext {\n ownerId?: string | null;\n}\n\nexport function buildMcpServer(\n db: ReturnType<typeof createDb>['db'],\n ctx: ServerContext = {},\n): McpServer {\n const server = new McpServer({ name: SERVER_NAME, version: VERSION });\n\n server.registerTool(\n 'recommend',\n {\n title: 'Recommend packages',\n description:\n 'Recommend the best current npm packages for a described need — fresh, objectively scored, with confidence labels. Call before choosing or hand-rolling a dependency.',\n inputSchema: {\n need: z.string().min(1).describe('Natural-language description of what you need'),\n category: categoryEnum.optional().describe('Optional taxonomy category to restrict to'),\n constraints: constraintsSchema,\n },\n },\n async (args) => json(await timed('recommend', () => handleRecommend(db, args))),\n );\n\n server.registerTool(\n 'evaluate',\n {\n title: 'Evaluate a package',\n description:\n 'Full evidence read for one npm package: scores, signals, advisories, summary, and a usage guide. Fetches & scores on demand if not yet tracked.',\n inputSchema: {\n package: npmName.describe('npm package name'),\n },\n },\n async (args) => json(await timed('evaluate', () => handleEvaluate(db, args))),\n );\n\n server.registerTool(\n 'compare',\n {\n title: 'Compare packages',\n description: 'Side-by-side comparison of 2–5 npm packages, ranked by health score.',\n inputSchema: {\n packages: z.array(npmName).min(2).max(5).describe('2–5 npm package names'),\n },\n },\n async (args) => json(await timed('compare', () => handleCompare(db, args))),\n );\n\n server.registerTool(\n 'compat',\n {\n title: 'Check package compatibility',\n description:\n 'Check whether a set of packages forms a coherent stack: peer-dependency and engine-range compatibility across the whole set (instant, from declared metadata), plus any recorded sandbox-verified conflicts. Returns the exact clashing constraints. Read-only — does not run installs. Call before committing to a multi-package stack.',\n inputSchema: {\n packages: z\n .array(npmName)\n .min(2)\n .max(8)\n .describe('2–8 npm package names to check together'),\n },\n },\n async (args) => json(await timed('compat', () => handleCompat(db, args))),\n );\n\n server.registerTool(\n 'verify',\n {\n title: 'Verify a package',\n description:\n 'Confirm an npm package is real, healthy, and not risky before installing — guards against hallucinated or typosquatted dependency names. Checks the live registry.',\n inputSchema: {\n package: npmName.describe('npm package name to verify'),\n },\n },\n async (args) => json(await timed('verify', () => handleVerify(db, args))),\n );\n\n server.registerTool(\n 'diagram',\n {\n title: 'Reference architecture diagram',\n description:\n 'Emit a reference-architecture Mermaid diagram for a stack you have already chosen (package names). A labeled starting point keyed by layer — not a validated architecture, and not an architecture designer.',\n inputSchema: {\n stack: z\n .array(npmName)\n .optional()\n .describe('Package names that make up the stack; omit or empty to get usage guidance'),\n },\n },\n async (args) => json(await timed('diagram', () => handleDiagram(db, args))),\n );\n\n server.registerTool(\n 'plan',\n {\n title: 'Plan a stack from a program description',\n description:\n 'Turn a detailed program description (spec/README) or a list of component needs into an evidence-scored build plan: a real, lurq-scored package recommended per component, plus a Mermaid roadmap other agents can parse. Recommends building blocks slot-by-slot from the index — it does not invent an architecture from a bare prompt.',\n inputSchema: {\n document: z\n .string()\n .optional()\n .describe('Detailed description of the program (spec/README); lurq decomposes it into components'),\n needs: z\n .array(\n z.object({\n need: z.string().min(1).describe('A component that needs a library'),\n category: categoryEnum.optional(),\n }),\n )\n .optional()\n .describe('Pre-decomposed components (skip if you pass a document)'),\n using: z\n .array(npmName)\n .max(12)\n .optional()\n .describe(\n 'Packages you have already decided on. lurq pins these as fixed slots, recommends only the remaining needs, and checks/optimizes the whole stack around your picks.',\n ),\n optimize: z\n .enum(['speed', 'balanced'])\n .optional()\n .describe(\"'speed' prefers the lightest-bundle option per slot; default 'balanced'\"),\n },\n },\n async (args) => json(await timed('plan', () => handlePlan(db, args))),\n );\n\n server.registerTool(\n 'report_outcome',\n {\n title: 'Report a recommendation outcome',\n description:\n 'Opt-in feedback after acting on a lurq recommendation: report whether you went with the package and whether it built. No source code — only the coarse decision + a build signal. Helps lurq learn which packages agents actually succeed with; safe to skip.',\n inputSchema: {\n package: npmName.describe('The package that was recommended'),\n accepted: z.boolean().describe('Did you go with this package?'),\n buildSignal: z\n .enum(['installed', 'compiled', 'tests_passed', 'failed'])\n .optional()\n .describe('Coarse post-install result, if known'),\n need: z\n .string()\n .max(500)\n .optional()\n .describe('The original need this was recommended for (no source code)'),\n },\n },\n // ownerId comes from the authenticated key (ctx), NOT the tool arguments —\n // a caller must never be able to attribute an outcome to another org.\n async (args) =>\n json(await timed('report_outcome', () => handleReportOutcome(db, args, ctx.ownerId ?? null))),\n );\n\n return server;\n}\n\nexport async function startMcpServer(): Promise<void> {\n const { db, close } = createDb();\n const server = buildMcpServer(db);\n\n const shutdown = async () => {\n try {\n await close();\n } finally {\n process.exit(0);\n }\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n logger.info(`${SERVER_NAME} MCP server v${VERSION} running on stdio.`);\n}\n","/**\n * API-key generation, hashing, and lifecycle for the hosted HTTP service\n * (docs/lurq-hosted-deployment.md §5). Keys are high-entropy random strings; only\n * their sha256 hash is persisted, so a DB leak never exposes a usable key. The\n * plaintext is returned exactly once (at creation) and never stored or logged.\n */\nimport { createHash, randomBytes } from 'node:crypto';\nimport { and, desc, eq, isNull } from 'drizzle-orm';\nimport { API_KEY_PREFIX } from '../core/constants';\nimport type { Database } from '../db/client';\nimport { apiKeys, type ApiKeyRow } from '../db/schema';\nimport { logger } from '../core/logger';\n\n/** Chars of the random body kept in the display prefix (`lurq_live_<6>`). */\nconst DISPLAY_BODY = 6;\n\n/** sha256 hex of a key — the only form ever persisted or compared. */\nexport function hashKey(key: string): string {\n return createHash('sha256').update(key).digest('hex');\n}\n\nexport interface GeneratedKey {\n /** The full plaintext key — show once, never store. */\n key: string;\n /** sha256 hash to persist. */\n hash: string;\n /** Identifiable, safe-to-display prefix. */\n prefix: string;\n}\n\nexport function generateApiKey(): GeneratedKey {\n // 24 random bytes → 32-char base64url body: unbiased, URL/header-safe.\n const body = randomBytes(24).toString('base64url');\n const key = API_KEY_PREFIX + body;\n return { key, hash: hashKey(key), prefix: API_KEY_PREFIX + body.slice(0, DISPLAY_BODY) };\n}\n\nexport interface CreateKeyInput {\n label?: string;\n tier?: string;\n ownerId?: string;\n}\n\n/** Create and persist a key. Returns the plaintext ONCE plus the stored row. */\nexport async function createKey(\n db: Database,\n input: CreateKeyInput = {},\n): Promise<{ key: string; row: ApiKeyRow }> {\n const { key, hash, prefix } = generateApiKey();\n const [row] = await db\n .insert(apiKeys)\n .values({\n keyHash: hash,\n prefix,\n label: input.label,\n tier: input.tier ?? 'free',\n ownerId: input.ownerId,\n })\n .returning();\n return { key, row: row! };\n}\n\n/**\n * Short-TTL cache of resolved keys. Auth runs on every hosted request, so an\n * uncached lookup means a SELECT (plus a lastUsedAt UPDATE) per call — pure load\n * on the DB, which is the scaling bottleneck. We cache only *valid* keys (the\n * hot path); unknown tokens always hit the DB so a flood of garbage tokens can't\n * bloat the map, and the per-IP limiter blunts that anyway. Trade-off: a revoked\n * key keeps working for up to AUTH_TTL_MS. Process-local; each instance caches\n * independently, which is fine for a bearer check.\n */\ninterface AuthEntry {\n row: ApiKeyRow;\n cachedAt: number;\n lastStampAt: number;\n}\nconst authCache = new Map<string, AuthEntry>();\nconst AUTH_TTL_MS = 60_000;\n/** lastUsedAt is analytics, not correctness — stamp at most this often per key. */\nconst STAMP_INTERVAL_MS = 60_000;\n\n/** Test-only: clear the auth cache so a fresh lookup re-reads the DB. */\nexport function resetAuthCache(): void {\n authCache.clear();\n}\n\n/** Fire-and-forget usage stamp, throttled per key. Never blocks the request. */\nfunction stampLastUsed(db: Database, entry: AuthEntry, now: number): void {\n if (now - entry.lastStampAt < STAMP_INTERVAL_MS) return;\n entry.lastStampAt = now;\n db.update(apiKeys)\n .set({ lastUsedAt: new Date(now) })\n .where(eq(apiKeys.id, entry.row.id))\n .then(undefined, (err) => logger.debug(`lastUsedAt stamp failed: ${String(err)}`));\n}\n\n/**\n * Look up an active (non-revoked) key by its plaintext form. Returns null if the\n * key is unknown or revoked. Cached for AUTH_TTL_MS; stamps `lastUsedAt`\n * best-effort (throttled) without blocking.\n */\nexport async function lookupActiveKey(db: Database, key: string): Promise<ApiKeyRow | null> {\n const hash = hashKey(key);\n const now = Date.now();\n\n const cached = authCache.get(hash);\n if (cached && now - cached.cachedAt < AUTH_TTL_MS) {\n stampLastUsed(db, cached, now);\n return cached.row;\n }\n\n const [row] = await db\n .select()\n .from(apiKeys)\n .where(and(eq(apiKeys.keyHash, hash), isNull(apiKeys.revokedAt)))\n .limit(1);\n if (!row) {\n authCache.delete(hash); // e.g. a key revoked since it was last cached\n return null;\n }\n const entry: AuthEntry = { row, cachedAt: now, lastStampAt: 0 };\n authCache.set(hash, entry);\n stampLastUsed(db, entry, now);\n return row;\n}\n\nexport async function listKeys(db: Database): Promise<ApiKeyRow[]> {\n return db.select().from(apiKeys).orderBy(desc(apiKeys.createdAt));\n}\n\n/** Resolve a \"prefix or numeric id\" argument to a Drizzle equality filter. */\nfunction matchByPrefixOrId(prefixOrId: string) {\n const asId = Number(prefixOrId);\n return Number.isInteger(asId) && String(asId) === prefixOrId.trim()\n ? eq(apiKeys.id, asId)\n : eq(apiKeys.prefix, prefixOrId);\n}\n\n/**\n * Revoke a key by display prefix or numeric id. Returns how many active keys were\n * revoked (0 if none matched or it was already revoked).\n */\nexport async function revokeKey(db: Database, prefixOrId: string): Promise<number> {\n const rows = await db\n .update(apiKeys)\n .set({ revokedAt: new Date() })\n .where(and(matchByPrefixOrId(prefixOrId), isNull(apiKeys.revokedAt)))\n .returning({ id: apiKeys.id });\n return rows.length;\n}\n\n/**\n * Rotate (\"swap\") a key: issue a replacement carrying the old key's label, tier,\n * and owner, then revoke the original. Returns the new plaintext (once), the new\n * row, and the revoked row — or null if no active key matched.\n *\n * The new key is created BEFORE the old one is revoked, so a failure mid-rotation\n * leaves the caller with a working key (at worst two active keys, never zero).\n */\nexport async function rotateKey(\n db: Database,\n prefixOrId: string,\n): Promise<{ key: string; row: ApiKeyRow; previous: ApiKeyRow } | null> {\n const [previous] = await db\n .select()\n .from(apiKeys)\n .where(and(matchByPrefixOrId(prefixOrId), isNull(apiKeys.revokedAt)))\n .limit(1);\n if (!previous) return null;\n\n const { key, row } = await createKey(db, {\n label: previous.label ?? undefined,\n tier: previous.tier,\n ownerId: previous.ownerId ?? undefined,\n });\n await db.update(apiKeys).set({ revokedAt: new Date() }).where(eq(apiKeys.id, previous.id));\n return { key, row, previous };\n}\n","/**\n * Hosted HTTP transport for the MCP server (docs/lurq-hosted-deployment.md §4–5).\n *\n * Stateless Streamable HTTP: one shared DB pool created at startup, a fresh MCP\n * server+transport per request, fronted by helmet + rate limiting + API-key auth.\n * The DB credentials stay server-side; users connect with only a URL + Bearer key.\n * `buildMcpServer` is reused verbatim from the stdio path — the tools are\n * transport-agnostic.\n *\n * express/helmet/express-rate-limit are imported dynamically so the CLI and the\n * install wizard never pull server-only deps into their startup path.\n */\nimport { createHash, timingSafeEqual } from 'node:crypto';\nimport type { NextFunction, Request, Response } from 'express';\nimport type { Store } from 'express-rate-limit';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { getConfig } from '../core/config';\nimport { logger } from '../core/logger';\nimport { createKey, lookupActiveKey } from '../auth/apiKeys';\nimport { createDb } from '../db/client';\nimport type { ApiKeyRow } from '../db/schema';\nimport { buildMcpServer } from './server';\nimport { renderPrometheus } from './metrics';\n\ninterface AuthedRequest extends Request {\n lurqKey?: ApiKeyRow;\n}\n\n/** JSON-RPC-shaped error envelope for HTTP-level rejections. */\nfunction rpcError(code: number, message: string) {\n return { jsonrpc: '2.0' as const, error: { code, message }, id: null };\n}\n\n/** Constant-time secret comparison (hash to a fixed length first, so length\n * never leaks and mismatched lengths don't throw). */\nexport function secretEquals(a: string, b: string): boolean {\n return timingSafeEqual(\n createHash('sha256').update(a).digest(),\n createHash('sha256').update(b).digest(),\n );\n}\n\nexport async function startHttpServer(opts: { port?: number } = {}): Promise<void> {\n const config = getConfig();\n const port = opts.port ?? config.PORT;\n\n const [{ default: express }, { default: helmet }, { rateLimit, ipKeyGenerator }] =\n await Promise.all([import('express'), import('helmet'), import('express-rate-limit')]);\n\n // The DB pool is the expensive resource — created once, shared by all requests.\n const { db } = createDb({ max: 20 });\n\n // Without Redis the response cache is a pass-through, so every recommend/\n // evaluate/compare recomputes its search on the DB — fine for one box, but the\n // first thing that buckles under real traffic. Warn loudly on the hosted path.\n if (!process.env.REDIS_URL) {\n logger.warn(\n 'REDIS_URL not set — response caching is OFF; every request recomputes on the ' +\n 'database. Set REDIS_URL before serving real traffic (and it also backs the ' +\n 'rate limiter across instances).',\n );\n }\n\n // Rate-limit store: Redis-backed when REDIS_URL is set, so limits are shared\n // and correct across horizontally-scaled instances. Without it the default\n // in-memory store is per-process — fine for one box, but N instances would\n // each enforce the full quota (N× the real limit). Each limiter gets its own\n // prefix so their counters don't collide in one Redis keyspace.\n let makeStore: ((prefix: string) => Store) | null = null;\n if (process.env.REDIS_URL) {\n const [{ default: Redis }, { default: RedisStore }] = await Promise.all([\n import('ioredis'),\n import('rate-limit-redis'),\n ]);\n const rlRedis = new Redis(process.env.REDIS_URL, { maxRetriesPerRequest: 1, family: 0 });\n rlRedis.on('error', (err: Error) => logger.warn(`rate-limit redis: ${err.message}`));\n makeStore = (prefix: string) =>\n new RedisStore({\n prefix,\n sendCommand: (...args: string[]) => rlRedis.call(args[0]!, ...args.slice(1)) as Promise<never>,\n });\n }\n\n const app = express();\n app.set('trust proxy', 1); // Railway terminates TLS at the edge.\n app.use(helmet());\n app.use(express.json({ limit: '1mb' }));\n\n // Unauthenticated, no DB hit — for Railway's healthcheck. Intentionally not\n // rate-limited: it's a static response with no backend cost, and limiting it\n // risks 429'ing Railway's own frequent healthcheck poll into a restart loop.\n app.get('/healthz', (_req: Request, res: Response) => {\n res.status(200).json({ status: 'ok' });\n });\n\n // Prometheus scrape of per-tool call/error/latency counters. Disabled (404)\n // unless LURQ_METRICS_TOKEN is set; when set, require it as a Bearer token so\n // the endpoint doesn't leak usage on a public host.\n app.get('/metrics', (req: Request, res: Response) => {\n const token = config.LURQ_METRICS_TOKEN;\n if (!token) {\n res.status(404).end();\n return;\n }\n const header = req.headers.authorization;\n const presented = header?.startsWith('Bearer ') ? header.slice(7).trim() : '';\n if (presented !== token) {\n res.status(401).end();\n return;\n }\n res.type('text/plain').send(renderPrometheus());\n });\n\n // Coarse per-IP limiter to blunt unauthenticated floods before the auth lookup.\n const ipLimiter = rateLimit({\n windowMs: config.LURQ_RATE_LIMIT_WINDOW_MS,\n limit: config.LURQ_IP_RATE_LIMIT_MAX,\n standardHeaders: 'draft-7',\n legacyHeaders: false,\n ...(makeStore ? { store: makeStore('rl:ip:') } : {}),\n message: rpcError(-32029, 'Rate limit exceeded.'),\n });\n\n // Bearer API-key auth: resolve and attach the key, or 401.\n const auth = async (req: AuthedRequest, res: Response, next: NextFunction): Promise<void> => {\n const header = req.headers.authorization;\n const token = header?.startsWith('Bearer ') ? header.slice(7).trim() : '';\n if (!token) {\n res.status(401).json(rpcError(-32001, 'Missing API key. Pass Authorization: Bearer <key>.'));\n return;\n }\n try {\n const row = await lookupActiveKey(db, token);\n if (!row) {\n res.status(401).json(rpcError(-32001, 'Invalid or revoked API key.'));\n return;\n }\n req.lurqKey = row;\n next();\n } catch (err) {\n logger.error('auth lookup failed:', err instanceof Error ? err.message : String(err));\n res.status(500).json(rpcError(-32603, 'Internal error.'));\n }\n };\n\n // Per-key limiter (runs after auth so it can key on the resolved API key).\n const keyLimiter = rateLimit({\n windowMs: config.LURQ_RATE_LIMIT_WINDOW_MS,\n limit: config.LURQ_RATE_LIMIT_MAX,\n standardHeaders: 'draft-7',\n legacyHeaders: false,\n // Key on the resolved API key's unique row id (always present — auth runs\n // first). The display `prefix` is only 6 chars of body, so distinct keys\n // can collide on it and share a quota; the id cannot. The IP fallback uses\n // express-rate-limit's ipKeyGenerator so IPv6 addresses are normalized\n // correctly (v8 throws ERR_ERL_KEY_GEN_IPV6 on a raw req.ip).\n keyGenerator: (req: Request) => {\n const id = (req as AuthedRequest).lurqKey?.id;\n return id != null ? `key:${id}` : ipKeyGenerator(req.ip ?? '0.0.0.0');\n },\n ...(makeStore ? { store: makeStore('rl:key:') } : {}),\n message: rpcError(-32029, 'Rate limit exceeded.'),\n });\n\n // Self-serve key issuance for the web dashboard (§ identity). Gated by the\n // shared LURQ_ISSUER_SECRET: the Clerk-authenticated web app presents it and\n // supplies the signed-in user's resolved `ownerId`. The backend trusts the web\n // app to have authenticated the user — it just mints the key. NOT behind the\n // per-IP limiter: all web-app calls share one egress IP, so that would throttle\n // every user together; the secret + the web app's own per-user auth are the\n // gate. Disabled (404) when the secret is unset.\n app.post('/keys', async (req: Request, res: Response) => {\n const secret = config.LURQ_ISSUER_SECRET;\n if (!secret) {\n res.status(404).end();\n return;\n }\n const header = req.headers.authorization;\n const token = header?.startsWith('Bearer ') ? header.slice(7).trim() : '';\n if (!token || !secretEquals(token, secret)) {\n res.status(401).json({ error: 'Invalid issuer secret.' });\n return;\n }\n const body = (req.body ?? {}) as { ownerId?: unknown; label?: unknown };\n const ownerId = typeof body.ownerId === 'string' ? body.ownerId.trim() : '';\n if (!ownerId) {\n res.status(400).json({ error: 'ownerId is required.' });\n return;\n }\n const label = typeof body.label === 'string' ? body.label.slice(0, 200) : undefined;\n try {\n const { key, row } = await createKey(db, { ownerId, label, tier: 'free' });\n res.status(201).json({ key, prefix: row.prefix });\n } catch (err) {\n logger.error('key issuance failed:', err instanceof Error ? err.message : String(err));\n res.status(500).json({ error: 'Could not issue key.' });\n }\n });\n\n app.post('/mcp', ipLimiter, auth, keyLimiter, async (req: Request, res: Response) => {\n // Stateless: a fresh server+transport per request, sharing the one DB pool.\n // Thread the authenticated key's org identity into the tools (§3.1).\n const server = buildMcpServer(db, { ownerId: (req as AuthedRequest).lurqKey?.ownerId ?? null });\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n enableJsonResponse: true,\n });\n res.on('close', () => {\n void transport.close();\n void server.close();\n });\n try {\n await server.connect(transport);\n await transport.handleRequest(req, res, req.body);\n } catch (err) {\n logger.error('mcp request failed:', err instanceof Error ? err.message : String(err));\n if (!res.headersSent) res.status(500).json(rpcError(-32603, 'Internal error'));\n }\n });\n\n // Stateless server: no session GET/DELETE handling.\n app.all('/mcp', (_req: Request, res: Response) => {\n res.status(405).json(rpcError(-32000, 'Method not allowed.'));\n });\n\n app.listen(port, () => {\n logger.info(`lurq HTTP MCP server listening on :${port}/mcp`);\n });\n}\n","/**\n * `lurq rescore` (§4). Re-derive health scores from each package's *cached*\n * `scoreBreakdown` using the currently-loaded weight model — no re-ingestion,\n * no network. This is the payoff of storing the breakdown per package: a weight\n * edit (`edit-weights`) applies to the whole DB in one cheap pass.\n *\n * Only health weights change a stored value (`health_score`). The composite\n * (health↔quality blend) and its λ are applied at read time in `recommend`, so\n * a λ-only edit needs no rescore — but running it is harmless and idempotent.\n */\nimport { isNotNull } from 'drizzle-orm';\nimport { invalidateCache } from '../core/cache';\nimport { logger } from '../core/logger';\nimport { createDb } from '../db/client';\nimport { packages } from '../db/schema';\nimport { computeHealthScore } from '../scoring';\nimport { loadWeights } from '../scoring/weights';\nimport { eq } from 'drizzle-orm';\n\nexport interface RescoreSummary {\n seen: number;\n updated: number;\n}\n\nexport async function runRescore(): Promise<RescoreSummary> {\n const weights = loadWeights();\n const handle = createDb({ max: 4 });\n try {\n const rows = await handle.db\n .select({ id: packages.id, breakdown: packages.scoreBreakdown, healthScore: packages.healthScore })\n .from(packages)\n .where(isNotNull(packages.scoreBreakdown));\n\n let updated = 0;\n for (const row of rows) {\n if (!row.breakdown) continue;\n const health = computeHealthScore(row.breakdown, weights.health);\n if (health !== row.healthScore) {\n await handle.db\n .update(packages)\n .set({ healthScore: health, updatedAt: new Date() })\n .where(eq(packages.id, row.id));\n updated++;\n }\n }\n\n logger.info(`Rescored ${rows.length} package(s); ${updated} health score(s) changed.`);\n if (updated > 0) await invalidateCache();\n return { seen: rows.length, updated };\n } finally {\n await handle.close();\n }\n}\n","/**\n * Read/write helpers for the `discovery_queue` table (§2B). The crawler enqueues\n * candidates here; the merit gate pre-scores and graduates them.\n */\nimport { eq } from 'drizzle-orm';\nimport type { DiscoverySource, DiscoveryStatus } from '../core/types';\nimport type { Database } from './client';\nimport { discoveryQueue, packages, type DiscoveryQueueRow } from './schema';\n\nexport interface DiscoveryCandidate {\n name: string;\n via: DiscoverySource;\n}\n\n/** Names already tracked (in `packages`) or already queued — never re-enqueue. */\nexport async function getKnownNames(db: Database): Promise<Set<string>> {\n const [tracked, queued] = await Promise.all([\n db.select({ name: packages.name }).from(packages),\n db.select({ name: discoveryQueue.name }).from(discoveryQueue),\n ]);\n return new Set([...tracked.map((r) => r.name), ...queued.map((r) => r.name)]);\n}\n\n/** Insert new candidates, ignoring any that race in concurrently. Returns count inserted. */\nexport async function enqueueCandidates(\n db: Database,\n candidates: DiscoveryCandidate[],\n): Promise<number> {\n if (candidates.length === 0) return 0;\n const rows = candidates.map((c) => ({ name: c.name, discoveredVia: c.via }));\n const inserted = await db\n .insert(discoveryQueue)\n .values(rows)\n .onConflictDoNothing({ target: discoveryQueue.name })\n .returning({ id: discoveryQueue.id });\n return inserted.length;\n}\n\nexport async function getPendingCandidates(\n db: Database,\n limit: number,\n): Promise<DiscoveryQueueRow[]> {\n return db\n .select()\n .from(discoveryQueue)\n .where(eq(discoveryQueue.status, 'pending'))\n .limit(limit);\n}\n\nexport async function setDiscoveryStatus(\n db: Database,\n name: string,\n data: { status: DiscoveryStatus; preScore?: number | null },\n): Promise<void> {\n await db\n .update(discoveryQueue)\n .set({ status: data.status, ...(data.preScore !== undefined ? { preScore: data.preScore } : {}) })\n .where(eq(discoveryQueue.name, name));\n}\n","/**\n * Proactive multi-channel discovery crawler (§2B). OPERATOR-SIDE: this is a\n * scheduled job against the central index, never triggered by a user query.\n *\n * Three channels feed one queue, then a *merit* gate decides what graduates:\n * 1. Dependency-graph adjacency (deps.dev) — surfaced wholesale, NOT ranked by\n * dependent count (that re-introduces popularity bias).\n * 2. Category-keyword + recency (npm search) — the niche workhorse; the graph\n * structurally can't find niche alternatives.\n * 3. Merit gate — pre-scores candidates on QUALITY signals only. Downloads are\n * deliberately excluded so merit, not popularity, decides what's ingested.\n *\n * Cost is bounded by a per-run cap; anything dropped is logged (no silent\n * truncation), and the tail stays queued for the next run.\n */\nimport { isNotNull } from 'drizzle-orm';\nimport { logger } from '../core/logger';\nimport { CATEGORIES } from '../core/types';\nimport { createDb, type Database } from '../db/client';\nimport {\n enqueueCandidates,\n getKnownNames,\n getPendingCandidates,\n setDiscoveryStatus,\n type DiscoveryCandidate,\n} from '../db/discovery';\nimport { packages } from '../db/schema';\nimport { fetchDependencyNames } from '../ingestion/sources/depsDev';\nimport { fetchNpmRegistry } from '../ingestion/sources/npmRegistry';\nimport { searchNpm } from '../ingestion/sources/npmSearch';\nimport type { RawPackageSignals } from '../ingestion/types';\nimport { computeQuality, toScoringInput } from '../scoring';\nimport { DISCOVERY } from '../scoring/weights';\nimport { syncOnePackage } from './single';\n\nexport interface DiscoverOptions {\n /** Max candidates to fully ingest this run (defaults to DISCOVERY.perRunCap). */\n perRunCap?: number;\n /** Discover + queue + gate, but don't ingest survivors (preview). */\n dryRun?: boolean;\n}\n\nexport interface DiscoverSummary {\n enqueued: number;\n gated: number;\n passed: number;\n ingested: number;\n droppedToNextRun: number;\n}\n\n// ── Pure helpers (unit-tested) ───────────────────────────────────────────────\n\n/** Dedupe raw candidates by name (first channel wins), dropping anything already\n * known or with an invalid name. */\nexport function selectCandidates(\n raw: DiscoveryCandidate[],\n known: Set<string>,\n): DiscoveryCandidate[] {\n const seen = new Set<string>(known);\n const out: DiscoveryCandidate[] = [];\n for (const c of raw) {\n const name = c.name?.trim();\n if (!name || seen.has(name)) continue;\n seen.add(name);\n out.push({ name, via: c.via });\n }\n return out;\n}\n\n/** The merit gate: quality-only pre-score must clear the bar (§2B). */\nexport function passesGate(preScore: number | null): boolean {\n return preScore !== null && preScore >= DISCOVERY.minPreScore;\n}\n\n/**\n * Quality-only pre-score from a single cheap registry fetch (§2B). Reuses the\n * §1 quality model but with only manifest signals — no downloads, no GitHub —\n * so the gate is adoption-independent by construction.\n */\nexport async function preScorePackage(\n name: string,\n fetchImpl?: typeof fetch,\n): Promise<number | null> {\n try {\n const registry = await fetchNpmRegistry(name, fetchImpl);\n const signals: RawPackageSignals = {\n name,\n registry,\n downloads: null,\n github: null,\n depsDev: null,\n bundle: null,\n errors: [],\n };\n return computeQuality(toScoringInput(signals, null));\n } catch {\n return null;\n }\n}\n\n// ── Channels ─────────────────────────────────────────────────────────────────\n\n/** Dependency-graph neighbors of tracked packages (adjacency, not ranking). */\nasync function graphChannel(db: Database): Promise<DiscoveryCandidate[]> {\n const tracked = await db\n .select({ name: packages.name, version: packages.latestVersion })\n .from(packages)\n .where(isNotNull(packages.latestVersion));\n\n const out: DiscoveryCandidate[] = [];\n for (const t of tracked) {\n if (!t.version) continue;\n const deps = (await fetchDependencyNames(t.name, t.version)).slice(\n 0,\n DISCOVERY.graphNeighborsPerSeed,\n );\n for (const name of deps) out.push({ name, via: 'dependency-graph' });\n }\n return out;\n}\n\n/** Category-keyword + recency channel via npm search (the niche workhorse). */\nasync function searchChannel(): Promise<DiscoveryCandidate[]> {\n const out: DiscoveryCandidate[] = [];\n for (const category of CATEGORIES) {\n if (category === 'other') continue;\n const hits = await searchNpm(`keywords:${category}`, DISCOVERY.searchSizePerCategory);\n for (const hit of hits) {\n const via = isRecent(hit.date) ? 'recent' : 'category-search';\n out.push({ name: hit.name, via });\n }\n }\n return out;\n}\n\n/** Published within ~90 days counts as a \"recent\" entrant. */\nfunction isRecent(date: string | null): boolean {\n if (!date) return false;\n const ms = Date.parse(date);\n if (Number.isNaN(ms)) return false;\n return Date.now() - ms <= 90 * 24 * 60 * 60 * 1000;\n}\n\n// ── Orchestration ────────────────────────────────────────────────────────────\n\nexport async function runDiscovery(opts: DiscoverOptions = {}): Promise<DiscoverSummary> {\n const cap = opts.perRunCap ?? DISCOVERY.perRunCap;\n const handle = createDb({ max: 6 });\n try {\n logger.info('Discovery: gathering candidates from graph + search channels…');\n const [graph, search] = await Promise.all([graphChannel(handle.db), searchChannel()]);\n const known = await getKnownNames(handle.db);\n const fresh = selectCandidates([...graph, ...search], known);\n const enqueued = await enqueueCandidates(handle.db, fresh);\n logger.info(\n `Discovery: ${graph.length} graph + ${search.length} search candidates → ${enqueued} new queued.`,\n );\n\n // ── Merit gate: pre-score pending candidates on quality only ──────────────\n const pending = await getPendingCandidates(handle.db, cap * 4);\n const scored: { name: string; preScore: number }[] = [];\n for (const cand of pending) {\n // Reuse a stored pre-score: a candidate still 'pending' with a non-null\n // pre-score already cleared the gate on a prior run and was deferred past\n // the per-run cap. Re-fetching + re-scoring it every run is a wasted\n // registry round-trip — only score candidates that have never been gated.\n if (cand.preScore !== null) {\n scored.push({ name: cand.name, preScore: cand.preScore });\n continue;\n }\n const preScore = await preScorePackage(cand.name);\n await setDiscoveryStatus(handle.db, cand.name, {\n status: passesGate(preScore) ? 'pending' : 'rejected',\n preScore: preScore ?? null,\n });\n if (passesGate(preScore)) scored.push({ name: cand.name, preScore: preScore! });\n }\n logger.info(`Discovery: gated ${pending.length}; ${scored.length} cleared the quality bar.`);\n\n // ── Graduate the best, capped; log (don't silently drop) the tail ─────────\n scored.sort((a, b) => b.preScore - a.preScore);\n const toIngest = scored.slice(0, cap);\n const deferred = scored.slice(cap);\n if (deferred.length > 0) {\n logger.info(\n `Discovery: per-run cap ${cap} reached — ${deferred.length} eligible candidate(s) deferred to the next run: ${deferred.map((d) => d.name).join(', ')}`,\n );\n }\n\n let ingested = 0;\n if (!opts.dryRun) {\n for (const cand of toIngest) {\n try {\n await syncOnePackage(handle.db, cand.name);\n await setDiscoveryStatus(handle.db, cand.name, { status: 'ingested' });\n ingested++;\n } catch (err) {\n logger.warn(`Discovery: failed to ingest ${cand.name}: ${(err as Error).message}`);\n }\n }\n }\n\n logger.info(`Discovery: ingested ${ingested}/${toIngest.length} candidate(s).`);\n return {\n enqueued,\n gated: pending.length,\n passed: scored.length,\n ingested,\n droppedToNextRun: deferred.length,\n };\n } finally {\n await handle.close();\n }\n}\n","export { runSync, type SyncOptions, type SyncSummary } from './sync';\nexport { runRescore, type RescoreSummary } from './rescore';\nexport { runDiscovery, type DiscoverOptions, type DiscoverSummary } from './discovery';\n","/**\n * Dependency-free formatting helpers for human-facing CLI output. Compact tables\n * and labeled detail views; `--json` paths bypass these entirely.\n */\n\nconst ESC = '\u001b[';\nconst wrap = (code: string, s: string) => `${ESC}${code}m${s}${ESC}0m`;\n\nexport const bold = (s: string) => wrap('1', s);\nexport const dim = (s: string) => wrap('2', s);\nexport const red = (s: string) => wrap('31', s);\nexport const green = (s: string) => wrap('32', s);\nexport const yellow = (s: string) => wrap('33', s);\n\n// eslint-disable-next-line no-control-regex\nconst ANSI_RE = /\u001b\\[[0-9;]*m/g;\nconst width = (s: string) => s.replace(ANSI_RE, '').length;\n\n/** Render a simple aligned table. */\nexport function table(headers: string[], rows: string[][]): string {\n const widths = headers.map((h, i) => Math.max(width(h), ...rows.map((r) => width(r[i] ?? ''))));\n const pad = (s: string, w: number) => s + ' '.repeat(Math.max(0, w - width(s)));\n const line = (cells: string[]) => cells.map((c, i) => pad(c, widths[i]!)).join(' ');\n const out = [bold(line(headers)), dim(widths.map((w) => '─'.repeat(w)).join(' '))];\n for (const r of rows) out.push(line(r));\n return out.join('\\n');\n}\n\n/** Render a labeled key/value detail block. */\nexport function detail(pairs: [string, string][]): string {\n const labelWidth = Math.max(...pairs.map(([k]) => k.length));\n return pairs.map(([k, v]) => `${dim((k + ':').padEnd(labelWidth + 1))} ${v}`).join('\\n');\n}\n\n/** Compact number formatting: 1.2M, 34k, 950. */\nexport function formatNumber(n: number | null | undefined): string {\n if (n == null) return '—';\n if (n >= 1_000_000) return `${Math.round(n / 100_000) / 10}M`;\n if (n >= 1_000) return `${Math.round(n / 100) / 10}k`;\n return String(n);\n}\n\nexport function formatDate(iso: string | null): string {\n return iso ? iso.slice(0, 10) : '—';\n}\n\nexport function formatPercent(fraction: number | null | undefined): string {\n if (fraction == null) return '—';\n const pct = Math.round(fraction * 1000) / 10;\n return `${pct > 0 ? '+' : ''}${pct}%`;\n}\n\n/** Color a confidence label. */\nexport function confidenceLabel(c: string): string {\n if (c === 'proven') return green(c);\n if (c === 'emerging') return yellow(c);\n // `promising` (§1): high intrinsic quality, adoption-independent.\n if (c === 'promising') return green(c);\n return red(c);\n}\n","/**\n * Render a `plan` result as a self-contained HTML page: the Mermaid roadmap\n * rendered visually, plus the scored slot table. Mermaid is pulled from a CDN at\n * view time, so the file is a single portable artifact (no build step, no deps\n * added to the CLI). Used by `lurq plan --html <path>` / `--open`.\n */\nimport type { PlanOutput } from '../mcp/plan';\n\nfunction esc(s: string): string {\n return s.replace(/[&<>\"]/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;' })[c]!);\n}\n\nfunction slotRows(plan: PlanOutput): string {\n return plan.slots\n .map((s) => {\n const rec = s.recommended;\n const name = rec\n ? rec.repoUrl\n ? `<a href=\"${esc(rec.repoUrl)}\" target=\"_blank\" rel=\"noreferrer\">${esc(rec.name)}</a>`\n : esc(rec.name)\n : '<span class=\"muted\">— no match —</span>';\n const alts = s.alternatives.map((a) => esc(a.name)).join(', ') || '<span class=\"muted\">—</span>';\n return `<tr>\n <td>${esc(s.need)}</td>\n <td><span class=\"layer\">${esc(s.layer)}</span></td>\n <td class=\"pkg\">${name}</td>\n <td class=\"num\">${rec ? rec.healthScore : '—'}</td>\n <td>${rec ? esc(rec.confidence) : '—'}</td>\n <td class=\"alts\">${alts}</td>\n </tr>`;\n })\n .join('\\n');\n}\n\nexport function renderPlanHtml(plan: PlanOutput): string {\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n<title>lurq plan — roadmap</title>\n<style>\n :root { color-scheme: dark; }\n * { box-sizing: border-box; }\n body { margin: 0; font: 15px/1.5 ui-sans-serif, system-ui, -apple-system, sans-serif;\n background: #0b0b0f; color: #e7e7ea; padding: 2.5rem clamp(1rem, 5vw, 4rem); }\n h1 { font-size: 1.5rem; margin: 0 0 .25rem; }\n h2 { font-size: 1rem; text-transform: uppercase; letter-spacing: .08em; color: #9a9aa6; margin: 2.5rem 0 .75rem; }\n .sub { color: #9a9aa6; margin: 0 0 1rem; max-width: 70ch; }\n .diagram { background: #141419; border: 1px solid #26262e; border-radius: 14px; padding: 1.5rem; overflow: auto; }\n table { width: 100%; border-collapse: collapse; margin-top: .5rem; }\n th, td { text-align: left; padding: .55rem .75rem; border-bottom: 1px solid #1e1e25; vertical-align: top; }\n th { font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; color: #9a9aa6; }\n .pkg a { color: #d98cff; text-decoration: none; } .pkg a:hover { text-decoration: underline; }\n .num { text-align: right; font-variant-numeric: tabular-nums; }\n .muted { color: #6a6a76; } .alts { color: #b8b8c2; font-size: .92rem; }\n .layer { font-size: .8rem; color: #8ad; background: #15202b; border-radius: 6px; padding: .1rem .45rem; }\n footer { margin-top: 2.5rem; color: #6a6a76; font-size: .85rem; }\n</style>\n</head>\n<body>\n <h1>lurq plan <span class=\"muted\">· ${esc(plan.optimize)} · ${esc(plan.source)}${plan.framework ? ` · ${esc(plan.framework)} ecosystem` : ''}</span></h1>\n <p class=\"sub\">${esc(plan.note)}</p>\n\n <h2>Roadmap</h2>\n <div class=\"diagram\"><pre class=\"mermaid\">${esc(plan.mermaid)}</pre></div>\n\n <h2>Components</h2>\n <table>\n <thead><tr><th>Component</th><th>Layer</th><th>Recommended</th><th>Health</th><th>Confidence</th><th>Alternatives</th></tr></thead>\n <tbody>\n${slotRows(plan)}\n </tbody>\n </table>\n\n <footer>data as of ${esc(plan.dataAsOf)} · generated by lurq</footer>\n\n <script type=\"module\">\n import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';\n mermaid.initialize({ startOnLoad: true, theme: 'dark' });\n </script>\n</body>\n</html>\n`;\n}\n","/**\n * Cursor persistence for the npm `_changes` follower (one row per feed in\n * `watch_state`), so a restart resumes from the last processed sequence instead\n * of replaying the registry from the beginning.\n */\nimport { eq } from 'drizzle-orm';\nimport type { Database } from './client';\nimport { watchState } from './schema';\n\nexport async function getWatchCursor(db: Database, id: string): Promise<string | null> {\n const rows = await db\n .select({ seq: watchState.seq })\n .from(watchState)\n .where(eq(watchState.id, id))\n .limit(1);\n return rows[0]?.seq ?? null;\n}\n\nexport async function setWatchCursor(db: Database, id: string, seq: string): Promise<void> {\n await db\n .insert(watchState)\n .values({ id, seq, updatedAt: new Date() })\n .onConflictDoUpdate({ target: watchState.id, set: { seq, updatedAt: new Date() } });\n}\n","/**\n * npm `_changes` follower — the streaming log.\n *\n * Subscribes to the registry replication feed and, whenever a *tracked* package\n * publishes a new version, re-syncs it so scores, advisories, and the version\n * timeline stay fresh without a full crawl. Resumable via a persisted sequence\n * cursor (db/watch), so a restart picks up where it left off instead of\n * replaying the registry. Long-running: an operator runs `lurq watch` as a\n * daemon, matching lurq's external-scheduler model.\n */\nimport { logger } from '../core/logger';\nimport type { Database } from '../db/client';\nimport { getAllPackageNames } from '../db/packages';\nimport { getWatchCursor, setWatchCursor } from '../db/watch';\nimport { syncOnePackage } from './single';\n\nconst FEED_ID = 'npm-changes';\nconst FEED_URL = 'https://replicate.npmjs.com/_changes';\nconst HEARTBEAT_MS = 30_000;\nconst TRACKED_REFRESH_MS = 5 * 60_000; // re-read the tracked set this often\nconst CHECKPOINT_EVERY = 200; // advance the cursor through churn at least this often\nconst MAX_BACKOFF_MS = 30_000;\n\nexport interface ChangeRecord {\n seq: number | string;\n id: string;\n deleted: boolean;\n}\n\n/** Parse one NDJSON line from the continuous feed; null for heartbeats/garbage. */\nexport function parseChangeLine(line: string): ChangeRecord | null {\n const trimmed = line.trim();\n if (!trimmed) return null; // heartbeat\n try {\n const obj = JSON.parse(trimmed);\n if (typeof obj?.id !== 'string' || obj.seq == null) return null;\n return { seq: obj.seq, id: obj.id, deleted: Boolean(obj.deleted) };\n } catch {\n return null;\n }\n}\n\nexport interface WatchOptions {\n signal?: AbortSignal;\n /** Start point when no cursor is stored. 'now' (default) = only future changes. */\n since?: string;\n}\n\nexport async function watchNpmChanges(db: Database, opts: WatchOptions = {}): Promise<void> {\n const { signal } = opts;\n let backoff = 1000;\n\n while (!signal?.aborted) {\n let tracked = new Set(await getAllPackageNames(db));\n let trackedAt = Date.now();\n const since = (await getWatchCursor(db, FEED_ID)) ?? opts.since ?? 'now';\n const url = `${FEED_URL}?feed=continuous&since=${encodeURIComponent(since)}&heartbeat=${HEARTBEAT_MS}`;\n logger.info(`watch: connecting from seq=${since} (${tracked.size} tracked packages)`);\n\n try {\n const res = await fetch(url, { signal });\n if (!res.ok || !res.body) throw new Error(`feed responded ${res.status}`);\n backoff = 1000; // healthy connection — reset\n\n let sinceCheckpoint = 0;\n for await (const line of ndjsonLines(res.body, signal)) {\n const change = parseChangeLine(line);\n if (!change) continue;\n const seq = String(change.seq);\n sinceCheckpoint++;\n\n if (Date.now() - trackedAt > TRACKED_REFRESH_MS) {\n tracked = new Set(await getAllPackageNames(db));\n trackedAt = Date.now();\n }\n\n if (!change.deleted && tracked.has(change.id)) {\n logger.info(`watch: re-syncing ${change.id} (seq=${seq})`);\n await syncOnePackage(db, change.id).catch((err) =>\n logger.warn(`watch: re-sync failed for ${change.id}: ${String(err)}`),\n );\n await setWatchCursor(db, FEED_ID, seq);\n sinceCheckpoint = 0;\n } else if (sinceCheckpoint >= CHECKPOINT_EVERY) {\n await setWatchCursor(db, FEED_ID, seq); // advance through irrelevant churn\n sinceCheckpoint = 0;\n }\n }\n logger.info('watch: feed stream ended; reconnecting');\n } catch (err) {\n if (signal?.aborted) break;\n logger.warn(`watch: ${String(err)} — retrying in ${backoff}ms`);\n await sleep(backoff, signal);\n backoff = Math.min(backoff * 2, MAX_BACKOFF_MS);\n }\n }\n}\n\n/** Yield newline-delimited lines from a fetch ReadableStream as they arrive. */\nasync function* ndjsonLines(\n body: ReadableStream<Uint8Array>,\n signal?: AbortSignal,\n): AsyncGenerator<string> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n try {\n while (!signal?.aborted) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n let nl: number;\n while ((nl = buffer.indexOf('\\n')) >= 0) {\n yield buffer.slice(0, nl);\n buffer = buffer.slice(nl + 1);\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, ms);\n signal?.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer);\n resolve();\n },\n { once: true },\n );\n });\n}\n","/**\n * Sandbox driver contract.\n *\n * Verification runs an install + smoke-load of a package version in an isolated\n * environment and reports whether it *actually* installs and loads — evidence no\n * static signal (downloads, stars) can provide.\n *\n * The interface is deliberately small so the runner is swappable: a local\n * child-process driver for dev/operator use, and a VM-isolated driver (E2B /\n * Firecracker / gVisor) for verifying UNTRUSTED packages at scale. Callers\n * depend only on this contract, never on a concrete driver.\n */\n\nexport type ModuleSystem = 'esm' | 'cjs';\n\nexport interface SandboxTarget {\n /** Node major the run targets. The local driver uses the host Node and just\n * records this; a VM driver provisions it. */\n node: string;\n moduleSystem: ModuleSystem;\n}\n\nexport interface SandboxVerifyOptions {\n target?: SandboxTarget;\n /** Run lifecycle install scripts (preinstall/install/postinstall). Off by\n * default: running untrusted scripts needs VM isolation, not a bare driver. */\n allowScripts?: boolean;\n timeoutMs?: number;\n signal?: AbortSignal;\n}\n\nexport interface SandboxResult {\n /** Provenance tag for the driver that produced this ('local', 'e2b', ...). */\n driver: string;\n moduleSystem: ModuleSystem;\n /** `npm install` succeeded. */\n installed: boolean;\n /** Package loaded (import/require without throwing). null = not attempted\n * because the install failed. */\n imported: boolean | null;\n /** Whether install scripts were allowed to run for this result. */\n ranScripts: boolean;\n durationMs: number;\n /** Condensed first line(s) of the failure, if any. */\n error: string | null;\n}\n\nexport interface SandboxPackage {\n name: string;\n version: string | null;\n}\n\nexport interface SandboxSetResult {\n driver: string;\n moduleSystem: ModuleSystem;\n /** Co-install of the whole set succeeded. */\n installed: boolean;\n /** Per-package smoke-load (null = not attempted because the install failed). */\n loaded: { name: string; loaded: boolean | null }[];\n durationMs: number;\n error: string | null;\n}\n\nexport interface Sandbox {\n /** Provenance tag stored with each result. */\n readonly name: string;\n verify(\n pkg: string,\n version: string | null,\n opts?: SandboxVerifyOptions,\n ): Promise<SandboxResult>;\n /** Co-install a set of packages and smoke-load each — the basis of the\n * compatibility matrix. A successful co-install proves the set coexists. */\n verifySet(\n packages: SandboxPackage[],\n opts?: SandboxVerifyOptions,\n ): Promise<SandboxSetResult>;\n}\n\nexport const DEFAULT_TARGET: SandboxTarget = {\n node: '20',\n moduleSystem: 'cjs',\n};\n","/**\n * Local child-process sandbox driver.\n *\n * Installs package(s) into a throwaway temp dir and smoke-loads them, reporting\n * whether they install and load. Fast and dependency-free (just npm + node).\n *\n * NOT an isolation boundary: loading a package executes its top-level code on\n * the host, so use this only for packages you already trust (operator/dev).\n * Verify UNTRUSTED packages with a VM driver. Install scripts stay OFF unless\n * `allowScripts` is set, since the whole point of the security tier is to not\n * execute untrusted install hooks.\n */\nimport { execFile } from 'node:child_process';\nimport { mkdtemp, rm, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { promisify } from 'node:util';\nimport {\n DEFAULT_TARGET,\n type ModuleSystem,\n type Sandbox,\n type SandboxPackage,\n type SandboxResult,\n type SandboxSetResult,\n type SandboxVerifyOptions,\n} from './types';\n\nconst execFileAsync = promisify(execFile);\nconst INSTALL_TIMEOUT_MS = 120_000;\nconst SMOKE_TIMEOUT_MS = 30_000;\nconst ERROR_MAX = 500;\n\n/** npm args for a throwaway install of one or more specs into the sandbox dir. */\nexport function npmInstallArgs(specs: string[], opts: { allowScripts: boolean }): string[] {\n // A spec beginning with `-` would be parsed as an npm flag (e.g.\n // `--registry=evil`), not a package. Legitimate names/specs never start with\n // one, so reject rather than smuggle it into the install command.\n const bad = specs.find((s) => s.startsWith('-'));\n if (bad) throw new Error(`Invalid package spec: ${bad}`);\n const args = ['install', ...specs, '--no-audit', '--no-fund', '--no-package-lock', '--no-save'];\n if (!opts.allowScripts) args.push('--ignore-scripts');\n return args;\n}\n\n/** A one-liner that loads the package and exits non-zero if it throws. */\nexport function smokeScript(pkg: string, moduleSystem: ModuleSystem): string[] {\n return moduleSystem === 'esm'\n ? ['--input-type=module', '-e', `await import(${JSON.stringify(pkg)})`]\n : ['-e', `require(${JSON.stringify(pkg)})`];\n}\n\nfunction condense(s: string): string {\n return s.replace(/\\s+/g, ' ').trim().slice(0, ERROR_MAX);\n}\n\nfunction stderrOf(err: unknown): string {\n if (err && typeof err === 'object') {\n const e = err as { stderr?: unknown; message?: unknown };\n if (typeof e.stderr === 'string' && e.stderr.trim()) return e.stderr;\n if (typeof e.message === 'string') return e.message;\n }\n return String(err);\n}\n\nconst toSpec = (p: SandboxPackage): string => (p.version ? `${p.name}@${p.version}` : p.name);\n\nexport class LocalSandbox implements Sandbox {\n readonly name = 'local';\n\n async verify(\n pkg: string,\n version: string | null,\n opts: SandboxVerifyOptions = {},\n ): Promise<SandboxResult> {\n const set = await this.verifySet([{ name: pkg, version }], opts);\n return {\n driver: this.name,\n moduleSystem: set.moduleSystem,\n installed: set.installed,\n imported: set.loaded[0]?.loaded ?? null,\n ranScripts: opts.allowScripts ?? false,\n durationMs: set.durationMs,\n error: set.error,\n };\n }\n\n async verifySet(\n packages: SandboxPackage[],\n opts: SandboxVerifyOptions = {},\n ): Promise<SandboxSetResult> {\n const target = opts.target ?? DEFAULT_TARGET;\n const allowScripts = opts.allowScripts ?? false;\n const specs = packages.map(toSpec);\n const dir = await mkdtemp(join(tmpdir(), 'lurq-sandbox-'));\n const started = Date.now();\n const loaded = packages.map((p) => ({ name: p.name, loaded: null as boolean | null }));\n let installed = false;\n let error: string | null = null;\n\n try {\n await writeFile(\n join(dir, 'package.json'),\n JSON.stringify({ name: 'lurq-sandbox', version: '0.0.0', private: true }),\n );\n await execFileAsync('npm', npmInstallArgs(specs, { allowScripts }), {\n cwd: dir,\n timeout: opts.timeoutMs ?? INSTALL_TIMEOUT_MS,\n signal: opts.signal,\n });\n installed = true;\n\n for (let i = 0; i < packages.length; i++) {\n try {\n await execFileAsync('node', smokeScript(packages[i]!.name, target.moduleSystem), {\n cwd: dir,\n timeout: SMOKE_TIMEOUT_MS,\n signal: opts.signal,\n });\n loaded[i]!.loaded = true;\n } catch (err) {\n loaded[i]!.loaded = false;\n if (!error) error = condense(stderrOf(err));\n }\n }\n } catch (err) {\n error = condense(stderrOf(err));\n } finally {\n await rm(dir, { recursive: true, force: true }).catch(() => {});\n }\n\n return {\n driver: this.name,\n moduleSystem: target.moduleSystem,\n installed,\n loaded,\n durationMs: Date.now() - started,\n error,\n };\n }\n}\n","/**\n * E2B cloud-sandbox driver.\n *\n * Installs package(s) and smoke-loads them inside an isolated E2B microVM, so\n * top-level package code (and, with allowScripts, install hooks) runs OFF the\n * host. This is the isolation boundary the local driver deliberately lacks —\n * use it to verify UNTRUSTED packages at scale.\n *\n * Requires E2B_API_KEY. The launched template must have node + npm on PATH\n * (see E2B_TEMPLATE). Like the local driver, target.node is recorded but not\n * provisioned — pin a Node-versioned template for reproducible majors.\n */\nimport Sandbox from 'e2b';\nimport { getConfig } from '../core/config';\nimport {\n DEFAULT_TARGET,\n type ModuleSystem,\n type Sandbox as SandboxDriver,\n type SandboxPackage,\n type SandboxResult,\n type SandboxSetResult,\n type SandboxVerifyOptions,\n} from './types';\n\nconst INSTALL_TIMEOUT_MS = 120_000;\nconst SMOKE_TIMEOUT_MS = 30_000;\nconst ERROR_MAX = 500;\nconst WORKDIR = '/home/user';\n\n/** POSIX single-quote: safe for any arg (specs may carry `^`, `>`, spaces). */\nexport function shQuote(s: string): string {\n return `'${s.replace(/'/g, `'\\\\''`)}'`;\n}\n\n/** Shell command that installs the specs into WORKDIR. */\nexport function installCommand(specs: string[], allowScripts: boolean): string {\n const bad = specs.find((s) => s.startsWith('-'));\n if (bad) throw new Error(`Invalid package spec: ${bad}`);\n const flags = ['--no-audit', '--no-fund', '--no-package-lock', '--no-save'];\n if (!allowScripts) flags.push('--ignore-scripts');\n return `npm install ${specs.map(shQuote).join(' ')} ${flags.join(' ')}`;\n}\n\n/** Shell command that loads a package and exits non-zero if it throws. */\nexport function smokeCommand(pkg: string, moduleSystem: ModuleSystem): string {\n const js =\n moduleSystem === 'esm' ? `await import(${JSON.stringify(pkg)})` : `require(${JSON.stringify(pkg)})`;\n const flags = moduleSystem === 'esm' ? '--input-type=module ' : '';\n return `node ${flags}-e ${shQuote(js)}`;\n}\n\nfunction condense(s: string): string {\n return s.replace(/\\s+/g, ' ').trim().slice(0, ERROR_MAX);\n}\n\nfunction errText(err: unknown): string {\n if (err && typeof err === 'object') {\n const e = err as { stderr?: unknown; message?: unknown };\n if (typeof e.stderr === 'string' && e.stderr.trim()) return e.stderr;\n if (typeof e.message === 'string') return e.message;\n }\n return String(err);\n}\n\nconst toSpec = (p: SandboxPackage): string => (p.version ? `${p.name}@${p.version}` : p.name);\n\nexport class E2BSandbox implements SandboxDriver {\n readonly name = 'e2b';\n\n async verify(\n pkg: string,\n version: string | null,\n opts: SandboxVerifyOptions = {},\n ): Promise<SandboxResult> {\n const set = await this.verifySet([{ name: pkg, version }], opts);\n return {\n driver: this.name,\n moduleSystem: set.moduleSystem,\n installed: set.installed,\n imported: set.loaded[0]?.loaded ?? null,\n ranScripts: opts.allowScripts ?? false,\n durationMs: set.durationMs,\n error: set.error,\n };\n }\n\n async verifySet(\n packages: SandboxPackage[],\n opts: SandboxVerifyOptions = {},\n ): Promise<SandboxSetResult> {\n const config = getConfig();\n const target = opts.target ?? DEFAULT_TARGET;\n const allowScripts = opts.allowScripts ?? false;\n const specs = packages.map(toSpec);\n const installTimeout = opts.timeoutMs ?? INSTALL_TIMEOUT_MS;\n const started = Date.now();\n const loaded = packages.map((p) => ({ name: p.name, loaded: null as boolean | null }));\n let installed = false;\n let error: string | null = null;\n\n // Build install command up front so a bad spec fails before we spend a VM.\n const install = installCommand(specs, allowScripts);\n\n // Sandbox lifetime must outlast install + every smoke run, plus buffer.\n const createOpts = {\n apiKey: config.E2B_API_KEY,\n timeoutMs: installTimeout + SMOKE_TIMEOUT_MS * packages.length + 30_000,\n };\n const sandbox = config.E2B_TEMPLATE\n ? await Sandbox.create(config.E2B_TEMPLATE, createOpts)\n : await Sandbox.create(createOpts);\n\n try {\n await sandbox.files.write(\n `${WORKDIR}/package.json`,\n JSON.stringify({ name: 'lurq-sandbox', version: '0.0.0', private: true }),\n );\n await sandbox.commands.run(install, { cwd: WORKDIR, timeoutMs: installTimeout });\n installed = true;\n\n for (let i = 0; i < packages.length; i++) {\n try {\n await sandbox.commands.run(smokeCommand(packages[i]!.name, target.moduleSystem), {\n cwd: WORKDIR,\n timeoutMs: SMOKE_TIMEOUT_MS,\n });\n loaded[i]!.loaded = true;\n } catch (err) {\n loaded[i]!.loaded = false;\n if (!error) error = condense(errText(err));\n }\n }\n } catch (err) {\n error = condense(errText(err));\n } finally {\n await sandbox.kill().catch(() => {});\n }\n\n return {\n driver: this.name,\n moduleSystem: target.moduleSystem,\n installed,\n loaded,\n durationMs: Date.now() - started,\n error,\n };\n }\n}\n","/**\n * Sandbox driver selection. With E2B_API_KEY set, the VM-isolated E2B driver is\n * used (safe for untrusted packages); otherwise the local child-process driver\n * (trusted packages only). The E2B module is imported lazily so its heavy SDK\n * never loads on the CLI/install path when isolation isn't configured.\n */\nimport { getConfig } from '../core/config';\nimport { LocalSandbox } from './local';\nimport type { Sandbox } from './types';\n\nexport async function getSandbox(): Promise<Sandbox> {\n if (getConfig().E2B_API_KEY) {\n const { E2BSandbox } = await import('./e2b');\n return new E2BSandbox();\n }\n return new LocalSandbox();\n}\n\nexport * from './types';\nexport { LocalSandbox, npmInstallArgs, smokeScript } from './local';\n","/**\n * Run a package version through the sandbox and persist the result. Decoupled\n * from the query path: an operator/cron drives this in the background and the\n * stored verdict is read instantly at recommend/verify time.\n */\nimport type { Database } from '../db/client';\nimport { storeVerificationRun } from '../db/verification';\nimport { getSandbox } from '../sandbox';\nimport type { SandboxResult, SandboxVerifyOptions } from '../sandbox/types';\n\nexport async function verifyPackageInSandbox(\n db: Database,\n pkg: string,\n version: string | null,\n opts: SandboxVerifyOptions = {},\n): Promise<SandboxResult> {\n const result = await (await getSandbox()).verify(pkg, version, opts);\n // Persist for the query path. Non-fatal: never fail the run on a write error.\n await storeVerificationRun(db, {\n packageName: pkg,\n version: version ?? 'latest',\n driver: result.driver,\n moduleSystem: result.moduleSystem,\n installed: result.installed,\n imported: result.imported,\n ranScripts: result.ranScripts,\n durationMs: result.durationMs,\n error: result.error,\n ranAt: new Date(),\n }).catch(() => {});\n return result;\n}\n","/**\n * Compatibility verification: co-install a set of packages in the sandbox and\n * record pairwise edges. A successful co-install proves the set coexists (every\n * pair compatible); a 2-package failure proves that pair conflicts. A larger\n * failed set can't pin the culprit, so no edge is asserted (set-level report).\n */\nimport type { CompatStatus } from '../core/types';\nimport type { Database } from '../db/client';\nimport { canonicalPair, upsertCompatEdge } from '../db/compat';\nimport { getPackageByName } from '../db/packages';\nimport { getSandbox } from '../sandbox';\nimport type { SandboxSetResult } from '../sandbox/types';\n\nexport interface CompatEdge {\n a: string;\n aVersion: string;\n b: string;\n bVersion: string;\n status: CompatStatus;\n}\n\ninterface Resolved {\n name: string;\n version: string;\n}\n\n/** Derive pairwise edges from a set co-install result. Pure. */\nexport function deriveCompatEdges(resolved: Resolved[], result: SandboxSetResult): CompatEdge[] {\n const allLoaded = result.loaded.every((l) => l.loaded === true);\n const edges: CompatEdge[] = [];\n\n if (result.installed && allLoaded) {\n // Co-install proved the whole set coexists → every pair is compatible.\n for (let i = 0; i < resolved.length; i++) {\n for (let j = i + 1; j < resolved.length; j++) {\n edges.push({\n a: resolved[i]!.name,\n aVersion: resolved[i]!.version,\n b: resolved[j]!.name,\n bVersion: resolved[j]!.version,\n status: 'compatible',\n });\n }\n }\n } else if (resolved.length === 2) {\n // A failed *pair* is precise: those two conflict.\n edges.push({\n a: resolved[0]!.name,\n aVersion: resolved[0]!.version,\n b: resolved[1]!.name,\n bVersion: resolved[1]!.version,\n status: 'conflict',\n });\n }\n // else: a larger set failed — can't attribute the conflict to a single pair.\n return edges;\n}\n\nexport interface CompatRunResult {\n result: SandboxSetResult;\n edges: CompatEdge[];\n /** A set-level conflict that couldn't be pinned to a specific pair. */\n unattributedConflict: boolean;\n}\n\nexport async function verifyCompatibility(\n db: Database,\n packages: string[],\n opts: { allowScripts?: boolean } = {},\n): Promise<CompatRunResult> {\n const resolved: Resolved[] = await Promise.all(\n packages.map(async (name) => ({\n name,\n version: (await getPackageByName(db, name))?.latestVersion ?? 'latest',\n })),\n );\n\n const result = await (await getSandbox()).verifySet(\n resolved.map((r) => ({ name: r.name, version: r.version === 'latest' ? null : r.version })),\n { allowScripts: opts.allowScripts },\n );\n\n const edges = deriveCompatEdges(resolved, result);\n for (const e of edges) {\n const pair = canonicalPair(\n { name: e.a, version: e.aVersion },\n { name: e.b, version: e.bVersion },\n );\n await upsertCompatEdge(db, {\n ...pair,\n status: e.status,\n driver: result.driver,\n ranAt: new Date(),\n }).catch(() => {});\n }\n\n const failed = !result.installed || !result.loaded.every((l) => l.loaded === true);\n return { result, edges, unattributedConflict: failed && edges.length === 0 };\n}\n","/**\n * Human-facing CLI command implementations (§13). Each reuses the MCP handlers\n * against a DB connection, then renders a compact table/detail view — or raw\n * JSON with `--json`.\n */\nimport { requireConfig } from '../core/config';\nimport { isCategory, type Category, type Confidence } from '../core/types';\nimport { createDb } from '../db/client';\nimport { getPackageVersions } from '../db/packages';\nimport { handleCompare, handleEvaluate, handleRecommend, handleVerify } from '../mcp/handlers';\nimport { CONFIDENCE, QUALITY_WEIGHTS } from '../scoring/weights';\nimport {\n activeWeightsPath,\n applyOverrides,\n loadWeights,\n resetWeights,\n saveWeights,\n settableKeys,\n validateWeights,\n WEIGHT_EXPLANATIONS,\n} from '../scoring/weights';\nimport {\n bold,\n confidenceLabel,\n detail,\n dim,\n formatDate,\n formatNumber,\n formatPercent,\n green,\n red,\n table,\n yellow,\n} from './format';\n\nasync function withDb<T>(fn: (db: ReturnType<typeof createDb>['db']) => Promise<T>): Promise<T> {\n requireConfig(['DATABASE_URL']);\n const handle = createDb();\n try {\n return await fn(handle.db);\n } finally {\n await handle.close();\n }\n}\n\nexport interface RecommendCliOpts {\n category?: string;\n minConfidence?: string;\n json?: boolean;\n}\n\nexport async function runRecommend(need: string, opts: RecommendCliOpts): Promise<void> {\n if (opts.category && !isCategory(opts.category)) {\n throw new Error(`Unknown category \"${opts.category}\".`);\n }\n await withDb(async (db) => {\n const res = await handleRecommend(db, {\n need,\n category: opts.category as Category | undefined,\n constraints: opts.minConfidence\n ? { minConfidence: opts.minConfidence as Confidence }\n : undefined,\n });\n if (opts.json) return console.log(JSON.stringify(res, null, 2));\n if (res.candidates.length === 0) {\n console.log('No matching packages found.');\n return;\n }\n console.log(\n table(\n ['Package', 'Health', 'Quality', 'Confidence', 'Weekly', 'Latest', 'Category'],\n res.candidates.map((c) => [\n c.name,\n String(c.healthScore),\n c.qualityScore != null ? String(c.qualityScore) : '—',\n confidenceLabel(c.confidence),\n formatNumber(c.weeklyDownloads),\n c.latestVersion ?? '—',\n c.category ?? '—',\n ]),\n ),\n );\n console.log(dim(`\\ndata as of ${formatDate(res.dataAsOf)}`));\n });\n}\n\nexport async function runEvaluate(pkg: string, opts: { json?: boolean }): Promise<void> {\n await withDb(async (db) => {\n const res = await handleEvaluate(db, { package: pkg });\n if (opts.json) return console.log(JSON.stringify(res, null, 2));\n if ('tracked' in res) {\n console.log(res.suggestion);\n return;\n }\n console.log(bold(res.name) + (res.category ? dim(` (${res.category})`) : ''));\n const b = res.scoreBreakdown;\n console.log(\n detail([\n ['health', `${res.healthScore} ${confidenceLabel(res.confidence)}`],\n ['quality', res.qualityScore != null ? String(res.qualityScore) : '—'],\n [\n 'breakdown',\n `maint ${b.maintenance} · adopt ${b.adoption} · rel ${b.reliability} · eff ${b.efficiency ?? '—'} · qual ${b.quality ?? '—'}`,\n ],\n ['version', res.latestVersion ?? '—'],\n ['weekly dl', `${formatNumber(res.weeklyDownloads)} (${formatPercent(res.downloadGrowth90d)} 90d)`],\n ['scorecard', res.scorecard != null ? String(res.scorecard) : '—'],\n ['bundle', res.bundleMinGzipKb != null ? `${res.bundleMinGzipKb} KB gzip` : '—'],\n ['released', formatDate(res.lastReleaseAt)],\n ['flags', [res.deprecated && 'deprecated', res.archived && 'archived'].filter(Boolean).join(', ') || 'none'],\n ['advisories', res.advisories.length ? res.advisories.map((a) => `${a.severity}`).join(', ') : 'none'],\n ['repo', res.repoUrl ?? '—'],\n ]),\n );\n if (res.buildVerified) {\n const bv = res.buildVerified;\n const state = !bv.installed\n ? red('install failed')\n : bv.loaded === false\n ? yellow('installs, load failed')\n : green('installs and loads');\n console.log(`\\nsandbox: ${state} ${dim(`${bv.version} · ${bv.driver}`)}`);\n }\n if (res.summary) console.log('\\n' + res.summary);\n if (res.usageGuide) {\n const g = res.usageGuide;\n console.log(\n '\\n' +\n detail(\n [\n ['what', g.whatItIs],\n ['when', g.whenToUse],\n g.whenNotToUse ? (['when not', g.whenNotToUse] as [string, string]) : null,\n ['fits', g.whereItFits],\n g.howToWireIn ? (['wire-in', g.howToWireIn] as [string, string]) : null,\n ].filter(Boolean) as [string, string][],\n ),\n );\n }\n console.log(dim(`\\ndata as of ${formatDate(res.dataAsOf)}${res.stale ? ' (stale)' : ''}`));\n });\n}\n\nexport async function runCompare(pkgs: string[], opts: { json?: boolean }): Promise<void> {\n await withDb(async (db) => {\n const res = await handleCompare(db, { packages: pkgs });\n if (opts.json) return console.log(JSON.stringify(res, null, 2));\n console.log(\n table(\n ['Package', 'Health', 'Confidence', 'Weekly', '90d', 'Scorecard', 'Released'],\n res.rows.map((r) => [\n r.name,\n String(r.healthScore),\n confidenceLabel(r.confidence),\n formatNumber(r.weeklyDownloads),\n formatPercent(r.downloadGrowth90d),\n r.scorecard != null ? String(r.scorecard) : '—',\n formatDate(r.lastReleaseAt),\n ]),\n ),\n );\n if (res.missing?.length) console.log(dim(`\\nnot found: ${res.missing.join(', ')}`));\n console.log(dim(`data as of ${formatDate(res.dataAsOf)}`));\n });\n}\n\n// ── weights / edit-weights (§4) ──────────────────────────────────────────────\n\n/** `lurq weights` — show + explain the score model (no DB needed). */\nexport function runWeights(opts: { json?: boolean } = {}): void {\n const w = loadWeights();\n const active = activeWeightsPath();\n if (opts.json) {\n console.log(JSON.stringify({ ...w, source: active?.source ?? 'defaults' }, null, 2));\n return;\n }\n const pct = (n: number) => n.toFixed(2);\n console.log(bold('Two axes, blended for default sort:'));\n console.log(` composite = (1−λ)·health + λ·quality λ = ${pct(w.composite.lambda)}\\n`);\n console.log(bold('Health (proven-ness) — weighted sum of 4 components:'));\n console.log(\n detail([\n ['maintenance', `${pct(w.health.maintenance)} ${dim('— ' + WEIGHT_EXPLANATIONS.maintenance!)}`],\n ['adoption', `${pct(w.health.adoption)} ${dim('— ' + WEIGHT_EXPLANATIONS.adoption!)}`],\n ['reliability', `${pct(w.health.reliability)} ${dim('— ' + WEIGHT_EXPLANATIONS.reliability!)}`],\n ['efficiency', `${pct(w.health.efficiency)} ${dim('— ' + WEIGHT_EXPLANATIONS.efficiency!)}`],\n ]),\n );\n console.log('\\n' + bold('Quality (intrinsic, adoption-independent):'));\n console.log(' ' + dim(Object.keys(QUALITY_WEIGHTS).join(', ')));\n console.log('\\n' + bold('Confidence thresholds:'));\n console.log(\n detail([\n ['proven', `≥ ${formatNumber(CONFIDENCE.proven.minWeeklyDownloads)} weekly dl, ≥ ${CONFIDENCE.proven.minAgeMonths}mo old`],\n ['emerging', `≥ ${formatNumber(CONFIDENCE.emerging.minWeeklyDownloads)} weekly dl OR ≥ ${CONFIDENCE.emerging.strongGrowth * 100}% 90d growth`],\n ['promising', `≥ ${CONFIDENCE.promising.minQuality} quality score (adoption-independent)`],\n ]),\n );\n console.log(dim(`\\nSource: ${active ? `${active.source} (${active.path})` : 'defaults (no user overrides)'}`));\n}\n\nexport interface EditWeightsOpts {\n set?: string[];\n reset?: boolean;\n explain?: string;\n project?: boolean;\n json?: boolean;\n}\n\n/** `lurq edit-weights` — override / reset / explain the model (no DB needed).\n * A weight change alters ranking at read time, so invalidate the response cache\n * (no-op without REDIS_URL) when run where the index is served. */\nexport async function runEditWeights(opts: EditWeightsOpts): Promise<void> {\n const { invalidateCache } = await import('../core/cache');\n if (opts.reset) {\n const removed = resetWeights();\n console.log(removed.length ? `Removed overrides:\\n ${removed.join('\\n ')}` : 'No overrides to remove; already on defaults.');\n if (removed.length) await invalidateCache();\n return;\n }\n\n if (opts.explain) {\n const key = opts.explain;\n const text = WEIGHT_EXPLANATIONS[key];\n if (!text) {\n throw new Error(`No explanation for \"${key}\". Known: ${Object.keys(WEIGHT_EXPLANATIONS).join(', ')}.`);\n }\n console.log(`${bold(key)} — ${text}`);\n return;\n }\n\n if (opts.set && opts.set.length > 0) {\n const next = applyOverrides(loadWeights(), opts.set);\n const { weights, normalized } = validateWeights(next);\n const path = saveWeights(weights, opts.project ? 'project' : 'user');\n await invalidateCache();\n console.log(`Saved overrides to ${path}`);\n if (normalized) {\n console.log(\n yellow('Health weights did not sum to 1.0 — renormalized to: ') +\n `maint ${weights.health.maintenance.toFixed(3)}, adopt ${weights.health.adoption.toFixed(3)}, rel ${weights.health.reliability.toFixed(3)}, eff ${weights.health.efficiency.toFixed(3)}`,\n );\n }\n console.log(dim('\\nRun `lurq rescore` to apply the new health weights to the stored index.'));\n return;\n }\n\n // No action flags → behave like `lurq weights`.\n console.log(dim(`No changes. Settable keys: ${settableKeys().join(', ')}.\\n`));\n runWeights(opts);\n}\n\nexport interface PlanCliOpts {\n optimize?: string;\n json?: boolean;\n html?: string;\n open?: boolean;\n}\n\n/** Open a file/URL in the OS default app, cross-platform, best-effort. No shell\n * (avoids metacharacter injection); on Windows `cmd /c start \"\" <target>` keeps\n * spaced paths intact because Node passes each arg separately. */\nasync function openInBrowser(target: string): Promise<void> {\n const { spawn } = await import('node:child_process');\n const [cmd, args]: [string, string[]] =\n process.platform === 'darwin'\n ? ['open', [target]]\n : process.platform === 'win32'\n ? ['cmd', ['/c', 'start', '', target]]\n : ['xdg-open', [target]];\n spawn(cmd, args, { stdio: 'ignore', detached: true }).unref();\n}\n\nexport async function runPlan(file: string, opts: PlanCliOpts): Promise<void> {\n const { readFileSync } = await import('node:fs');\n let document: string;\n try {\n document = readFileSync(file, 'utf8');\n } catch {\n throw new Error(`Could not read \"${file}\".`);\n }\n if (opts.optimize && opts.optimize !== 'speed' && opts.optimize !== 'balanced') {\n throw new Error(\"--optimize must be 'speed' or 'balanced'.\");\n }\n await withDb(async (db) => {\n const { handlePlan } = await import('../mcp/plan');\n const res = await handlePlan(db, {\n document,\n optimize: opts.optimize as 'speed' | 'balanced' | undefined,\n });\n if (opts.json) return console.log(JSON.stringify(res, null, 2));\n if (!('slots' in res)) {\n console.log(res.note);\n return;\n }\n\n // Visualization: render the roadmap to a portable HTML file and optionally open it.\n if (opts.html || opts.open) {\n const { writeFileSync } = await import('node:fs');\n const { tmpdir } = await import('node:os');\n const { join } = await import('node:path');\n const { renderPlanHtml } = await import('./planView');\n const out = opts.html ?? join(tmpdir(), `lurq-plan-${Date.now()}.html`);\n writeFileSync(out, renderPlanHtml(res), 'utf8');\n console.log(`Roadmap written to ${out}`);\n if (opts.open) await openInBrowser(out);\n }\n\n console.log(\n table(\n ['Component', 'Layer', 'Recommended', 'Health', 'Confidence', 'Alternatives'],\n res.slots.map((s) => [\n s.need.length > 32 ? s.need.slice(0, 31) + '…' : s.need,\n s.layer,\n s.recommended\n ? `${s.recommended.name}@${s.recommended.latestVersion ?? '?'}`\n : dim('—'),\n s.recommended ? String(s.recommended.healthScore) : '—',\n s.recommended ? confidenceLabel(s.recommended.confidence) : '—',\n s.alternatives.map((a) => a.name).join(', ') || '—',\n ]),\n ),\n );\n if (res.unmatched.length) console.log(yellow(`\\nNo match for: ${res.unmatched.join(', ')}`));\n\n if (res.compatibility) {\n const c = res.compatibility;\n const col = c.overall === 'compatible' ? green : c.overall === 'conflict' ? red : dim;\n console.log('\\n' + bold('Compatibility: ') + col(c.overall));\n for (const s of res.slots) {\n if (s.swappedFrom && s.recommended) {\n console.log(green(` ✓ swapped ${s.swappedFrom} → ${s.recommended.name} for compatibility`));\n }\n }\n for (const cf of c.conflicts) console.log(red(` ✗ ${cf.detail} (no compatible alternative)`));\n if (c.unverified.length) console.log(dim(` unverified: ${c.unverified.join(', ')}`));\n }\n\n console.log('\\n' + bold('Roadmap (Mermaid):'));\n console.log(res.mermaid);\n console.log(dim(`\\n${res.note}`));\n console.log(dim(`data as of ${formatDate(res.dataAsOf)}`));\n });\n}\n\nexport async function runVerify(pkg: string, opts: { json?: boolean }): Promise<void> {\n await withDb(async (db) => {\n const res = await handleVerify(db, { package: pkg });\n if (opts.json) return console.log(JSON.stringify(res, null, 2));\n const riskColor = res.risk === 'high' ? red : res.risk === 'medium' ? yellow : green;\n const verdict = !res.exists\n ? red('✗ NOT FOUND on npm')\n : res.risk === 'high'\n ? red('✗ high supply-chain risk')\n : res.risk === 'medium'\n ? yellow('⚠ exists, but risky')\n : green('✓ looks safe');\n console.log(`${bold(pkg)} ${verdict}`);\n console.log(\n detail([\n ['version', res.latestVersion ?? '—'],\n ['weekly dl', formatNumber(res.weeklyDownloads)],\n ['confidence', res.confidence ? confidenceLabel(res.confidence) : '—'],\n ['advisories', String(res.advisoryCount)],\n ['risk', riskColor(res.risk)],\n ['risk flags', res.riskFlags.length ? yellow(res.riskFlags.join(', ')) : 'none'],\n ]),\n );\n });\n}\n\nexport async function runVersions(\n pkg: string,\n opts: { json?: boolean; limit?: string },\n): Promise<void> {\n const limit = opts.limit ? Math.max(1, parseInt(opts.limit, 10) || 30) : 30;\n await withDb(async (db) => {\n const versions = await getPackageVersions(db, pkg, limit);\n if (opts.json) return console.log(JSON.stringify(versions, null, 2));\n if (versions.length === 0) {\n console.log(`No stored versions for ${bold(pkg)}. Run \\`lurq sync --package ${pkg}\\` first.`);\n return;\n }\n console.log(bold(pkg));\n console.log(\n table(\n ['Version', 'Published'],\n versions.map((v) => [\n v.version,\n v.publishedAt ? v.publishedAt.toISOString().slice(0, 10) : '—',\n ]),\n ),\n );\n });\n}\n\n/** Long-running: follow the npm changes feed until interrupted (Ctrl-C). */\nexport async function runWatch(): Promise<void> {\n const { watchNpmChanges } = await import('../pipeline/watch');\n await withDb(async (db) => {\n const controller = new AbortController();\n const stop = () => controller.abort();\n process.once('SIGINT', stop);\n process.once('SIGTERM', stop);\n console.log(dim('watching npm for releases of tracked packages — Ctrl-C to stop'));\n try {\n await watchNpmChanges(db, { signal: controller.signal });\n } finally {\n process.off('SIGINT', stop);\n process.off('SIGTERM', stop);\n }\n });\n}\n\n/** Operator-side: install + smoke-load a package in the sandbox to verify it works. */\nexport async function runSandbox(\n pkg: string,\n version: string | undefined,\n opts: { esm?: boolean; allowScripts?: boolean; json?: boolean },\n): Promise<void> {\n if (opts.allowScripts) {\n console.error(\n yellow('warning: running install scripts and loading the package locally without isolation'),\n );\n }\n const { verifyPackageInSandbox } = await import('../pipeline/sandbox');\n await withDb(async (db) => {\n const result = await verifyPackageInSandbox(db, pkg, version ?? null, {\n target: { node: '20', moduleSystem: opts.esm ? 'esm' : 'cjs' },\n allowScripts: opts.allowScripts,\n });\n if (opts.json) return console.log(JSON.stringify(result, null, 2));\n const ok = result.installed && result.imported !== false;\n const label = version ? `${pkg}@${version}` : pkg;\n const verdict = ok ? green('✓ installs and loads') : red('✗ failed');\n console.log(`${bold(label)} ${verdict} ${dim(`(${result.durationMs}ms · ${result.driver})`)}`);\n console.log(\n detail([\n ['installed', result.installed ? 'yes' : 'no'],\n ['loaded', result.imported === null ? '—' : result.imported ? 'yes' : 'no'],\n ['module', result.moduleSystem],\n ['scripts', result.ranScripts ? 'ran' : 'skipped'],\n ['error', result.error ?? 'none'],\n ]),\n );\n });\n}\n\n/** Read (or, with --run, sandbox-verify then read) pairwise package compatibility. */\nexport async function runCompat(\n pkgs: string[],\n opts: { run?: boolean; json?: boolean },\n): Promise<void> {\n await withDb(async (db) => {\n if (opts.run) {\n console.error(\n yellow('co-installing in the sandbox (loads package code locally without isolation)'),\n );\n const { verifyCompatibility } = await import('../pipeline/compat');\n await verifyCompatibility(db, pkgs);\n }\n const { handleCompat } = await import('../mcp/handlers');\n const res = await handleCompat(db, { packages: pkgs });\n if (opts.json) return console.log(JSON.stringify(res, null, 2));\n const color = res.overall === 'compatible' ? green : res.overall === 'conflict' ? red : dim;\n console.log(`${bold(res.packages.join(' + '))} ${color(res.overall)}`);\n if (res.conflicts.length) {\n console.log(\n table(\n ['Source', 'Detail'],\n res.conflicts.map((c) => [c.source, c.detail]),\n ),\n );\n } else if (res.overall === 'compatible') {\n console.log(dim('no peer-dependency or engine conflicts across the set'));\n }\n if (res.unverified.length) {\n console.log(dim(`\\nunverified (no metadata): ${res.unverified.join(', ')}`));\n }\n });\n}\n","/**\n * Agent skill installer (§14). Registers lurq as an MCP server in supported\n * assistants by MERGING a single `lurq` entry into each agent's config — never\n * overwriting unrelated config — and drops the skill-instructions file.\n *\n * Two modes:\n * - **remote** (hosted, default for real users): writes a keyed HTTP entry\n * pointing at the lurq service. No DATABASE_URL ever touches a user's machine.\n * - **local** (self-host / contributors): writes the legacy stdio entry that\n * runs `lurq serve` locally against the user's own DB.\n *\n * MCP config formats move fast and differ per agent; this writes the current\n * widely-supported shapes and prints exactly what it did, so a stale path is\n * obvious rather than silent. Remote shapes verified against current agent docs\n * (2026-06): Claude Code / VS Code use `{ type:\"http\", url, headers }`; Cursor\n * uses `{ url, headers }`; Windsurf uses `{ serverUrl, headers }`; Codex (TOML)\n * uses `url` + an inline `http_headers` table.\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { copyFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { DEFAULT_ENDPOINT, PACKAGE_NAME } from '../core/constants';\nimport { logger } from '../core/logger';\nimport { packageRoot } from '../core/paths';\n\nconst ENV_KEYS = [\n 'DATABASE_URL',\n 'GITHUB_TOKEN',\n 'EMBEDDING_PROVIDER',\n 'EMBEDDING_API_KEY',\n 'EMBEDDING_MODEL',\n 'SUMMARY_PROVIDER',\n 'SUMMARY_API_KEY',\n 'SUMMARY_MODEL',\n] as const;\n\nexport type ConfigFormat = 'mcpServers' | 'servers' | 'toml';\n\nexport interface AgentSpec {\n id: string;\n label: string;\n format: ConfigFormat;\n /** Absolute config file path. */\n path: string;\n /** Whether this agent appears installed (used by `--agent all` and the wizard). */\n detected: boolean;\n}\n\nfunction home(...p: string[]): string {\n return join(homedir(), ...p);\n}\n\nexport function agentSpecs(): AgentSpec[] {\n return [\n {\n id: 'claude-code',\n label: 'Claude Code',\n format: 'mcpServers',\n path: home('.claude.json'),\n detected: existsSync(home('.claude.json')) || existsSync(home('.claude')),\n },\n {\n id: 'cursor',\n label: 'Cursor',\n format: 'mcpServers',\n path: home('.cursor', 'mcp.json'),\n detected: existsSync(home('.cursor')),\n },\n {\n id: 'windsurf',\n label: 'Windsurf',\n format: 'mcpServers',\n path: home('.codeium', 'windsurf', 'mcp_config.json'),\n detected: existsSync(home('.codeium')),\n },\n {\n id: 'copilot',\n label: 'VS Code / GitHub Copilot',\n format: 'servers',\n path: home('Library', 'Application Support', 'Code', 'User', 'mcp.json'),\n detected: existsSync(home('Library', 'Application Support', 'Code', 'User')),\n },\n {\n id: 'codex',\n label: 'OpenAI Codex CLI',\n format: 'toml',\n path: home('.codex', 'config.toml'),\n detected: existsSync(home('.codex')),\n },\n ];\n}\n\nexport const SUPPORTED_AGENTS = ['claude-code', 'cursor', 'windsurf', 'copilot', 'codex'] as const;\n\n/** How to wire the lurq entry: hosted HTTP endpoint, or local stdio process. */\nexport type InstallMode =\n | { kind: 'remote'; url: string; apiKey: string }\n | { kind: 'local'; env: Record<string, string> };\n\nfunction collectEnv(): Record<string, string> {\n const env: Record<string, string> = {};\n for (const key of ENV_KEYS) {\n const value = process.env[key];\n if (value) env[key] = value;\n }\n return env;\n}\n\nexport interface InstallResult {\n agent: string;\n path: string;\n status: 'installed' | 'skipped' | 'error';\n message?: string;\n}\n\nfunction readJsonObject(path: string): Record<string, any> {\n if (!existsSync(path)) return {};\n const text = readFileSync(path, 'utf8').trim();\n if (!text) return {};\n return JSON.parse(text);\n}\n\nfunction writeJson(path: string, obj: unknown): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(obj, null, 2) + '\\n', 'utf8');\n}\n\n/** Local (stdio) lurq server entry for JSON configs. */\nexport function buildServerEntry(env: Record<string, string>, withType: boolean): Record<string, any> {\n const entry: Record<string, any> = { command: 'npx', args: ['-y', PACKAGE_NAME, 'serve'] };\n if (withType) entry.type = 'stdio';\n if (Object.keys(env).length) entry.env = env;\n return entry;\n}\n\n/**\n * Remote (hosted) lurq server entry for JSON configs. Per-agent shape differs:\n * Claude Code & VS Code take `type:\"http\"`; Cursor & Windsurf infer transport\n * from the URL (Windsurf names the field `serverUrl`).\n */\nexport function buildRemoteServerEntry(\n agentId: string,\n opts: { url: string; apiKey: string },\n): Record<string, any> {\n const headers = { Authorization: `Bearer ${opts.apiKey}` };\n switch (agentId) {\n case 'cursor':\n return { url: opts.url, headers };\n case 'windsurf':\n return { serverUrl: opts.url, headers };\n case 'claude-code':\n case 'copilot':\n default:\n return { type: 'http', url: opts.url, headers };\n }\n}\n\n/** Local (stdio) TOML block for the Codex config. */\nexport function buildTomlBlock(env: Record<string, string>): string {\n const lines = ['[mcp_servers.lurq]', 'command = \"npx\"', `args = [\"-y\", \"${PACKAGE_NAME}\", \"serve\"]`];\n if (Object.keys(env).length) {\n lines.push('', '[mcp_servers.lurq.env]');\n for (const [k, v] of Object.entries(env)) lines.push(`${k} = ${JSON.stringify(v)}`);\n }\n return lines.join('\\n') + '\\n';\n}\n\n/**\n * Remote (hosted) TOML block for the Codex config. Codex parses with\n * `deny_unknown_fields`: literal headers go in an inline `http_headers` table,\n * NOT a `[mcp_servers.lurq.headers]` subtable (verified against the openai/codex\n * StreamableHttp config schema).\n */\nexport function buildRemoteTomlBlock(opts: { url: string; apiKey: string }): string {\n return (\n [\n '[mcp_servers.lurq]',\n `url = ${JSON.stringify(opts.url)}`,\n `http_headers = { Authorization = ${JSON.stringify(`Bearer ${opts.apiKey}`)} }`,\n ].join('\\n') + '\\n'\n );\n}\n\nfunction installJsonEntry(spec: AgentSpec, entry: Record<string, any>): InstallResult {\n const key = spec.format === 'servers' ? 'servers' : 'mcpServers';\n const config = readJsonObject(spec.path);\n if (typeof config[key] !== 'object' || config[key] === null) config[key] = {};\n config[key].lurq = entry;\n writeJson(spec.path, config);\n return { agent: spec.id, path: spec.path, status: 'installed' };\n}\n\nfunction installTomlBlock(spec: AgentSpec, block: string): InstallResult {\n const existing = existsSync(spec.path) ? readFileSync(spec.path, 'utf8') : '';\n if (existing.includes('[mcp_servers.lurq]')) {\n return {\n agent: spec.id,\n path: spec.path,\n status: 'skipped',\n message: 'lurq already present; edit manually to change it.',\n };\n }\n mkdirSync(dirname(spec.path), { recursive: true });\n const sep = existing && !existing.endsWith('\\n') ? '\\n\\n' : existing ? '\\n' : '';\n writeFileSync(spec.path, existing + sep + block, 'utf8');\n return { agent: spec.id, path: spec.path, status: 'installed' };\n}\n\n/** Apply the lurq entry to one agent's config, in the given mode. */\nexport function installAgent(spec: AgentSpec, mode: InstallMode): InstallResult {\n try {\n if (spec.format === 'toml') {\n const block =\n mode.kind === 'remote'\n ? buildRemoteTomlBlock(mode)\n : buildTomlBlock(mode.env);\n return installTomlBlock(spec, block);\n }\n const entry =\n mode.kind === 'remote'\n ? buildRemoteServerEntry(spec.id, mode)\n : buildServerEntry(mode.env, spec.format === 'servers');\n return installJsonEntry(spec, entry);\n } catch (err) {\n return {\n agent: spec.id,\n path: spec.path,\n status: 'error',\n message: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\n/** Copy the skill-instructions template to ~/.lurq. Returns the path, or null. */\nexport function installInstructionsFile(): string | null {\n const src = join(packageRoot(), 'templates', 'skill-instructions.md');\n if (!existsSync(src)) return null;\n const destDir = home('.lurq');\n const dest = join(destDir, 'skill-instructions.md');\n mkdirSync(destDir, { recursive: true });\n copyFileSync(src, dest);\n return dest;\n}\n\n/** Resolve `--agent <id|all>` to the set of agent specs to write. */\nexport function resolveAgents(target: string): AgentSpec[] {\n const specs = agentSpecs();\n if (target === 'all') return specs.filter((s) => s.detected);\n const spec = specs.find((s) => s.id === target);\n if (!spec) {\n throw new Error(`Unknown agent \"${target}\". Supported: ${SUPPORTED_AGENTS.join(', ')}, all.`);\n }\n return [spec];\n}\n\n/** Print the per-agent registration report + next steps. Shared by both paths. */\nexport function printInstallReport(\n results: InstallResult[],\n instructionsPath: string | null,\n mode: InstallMode,\n): void {\n const specs = agentSpecs();\n console.log('lurq MCP server registration:');\n for (const r of results) {\n const spec = specs.find((s) => s.id === r.agent)!;\n const mark = r.status === 'installed' ? '✓' : r.status === 'skipped' ? '•' : '✗';\n console.log(` ${mark} ${spec.label.padEnd(26)} ${r.path}${r.message ? ` (${r.message})` : ''}`);\n }\n if (instructionsPath) console.log(`\\nSkill instructions written to ${instructionsPath}`);\n console.log('\\nNext steps:');\n if (mode.kind === 'local') {\n console.log(' 1. Ensure DATABASE_URL (and any API keys) are set in the config env above.');\n console.log(' 2. Restart the agent so it picks up the new MCP server.');\n } else {\n console.log(' 1. Restart the agent so it picks up the new MCP server.');\n }\n console.log(' • Ask it to recommend a library — it should call lurq.');\n}\n\nexport interface InstallSkillOptions {\n agent?: string;\n /** Hosted endpoint URL (defaults to LURQ_ENDPOINT or the built-in default). */\n url?: string;\n /** API key for the hosted endpoint. Presence selects remote mode. */\n apiKey?: string;\n /** Force the legacy local/stdio entry (self-host). */\n local?: boolean;\n}\n\nexport async function runInstallSkill(opts: InstallSkillOptions): Promise<void> {\n const selected = resolveAgents(opts.agent ?? 'claude-code');\n if (selected.length === 0) {\n console.log('No supported agents detected on this machine.');\n return;\n }\n\n // Remote unless explicitly --local. Remote requires an API key.\n const remote = !opts.local;\n let mode: InstallMode;\n if (remote) {\n const apiKey = opts.apiKey ?? process.env.LURQ_API_KEY;\n if (!apiKey) {\n throw new Error(\n 'An API key is required for a hosted install. Pass --api-key <key> (or set LURQ_API_KEY), ' +\n 'or use `lurq install` for the guided setup, or --local to self-host.',\n );\n }\n const url = opts.url ?? process.env.LURQ_ENDPOINT ?? DEFAULT_ENDPOINT;\n mode = { kind: 'remote', url, apiKey };\n } else {\n const env = collectEnv();\n if (!env.DATABASE_URL) {\n logger.warn(\n 'DATABASE_URL is not set — the local server entry will have no DATABASE_URL. ' +\n 'Set it (in .env) and re-run, or edit the config.',\n );\n }\n mode = { kind: 'local', env };\n }\n\n const results = selected.map((spec) => installAgent(spec, mode));\n const instructionsPath = installInstructionsFile();\n printInstallReport(results, instructionsPath, mode);\n}\n","/**\n * Guided install wizard (`lurq install`, i.e. `npx lurqrun install`). Walks a user\n * through connecting lurq's hosted MCP service to their AI assistant(s): collects\n * the API key, optionally validates it against the endpoint, detects installed\n * agents, and writes the keyed remote config — no DATABASE_URL ever on their\n * machine. Fully non-interactive with `--yes` + flags/env for scripting.\n */\nimport { DEFAULT_ENDPOINT } from '../core/constants';\nimport {\n agentSpecs,\n installAgent,\n installInstructionsFile,\n printInstallReport,\n resolveAgents,\n type AgentSpec,\n type InstallMode,\n} from './installSkill';\n\nexport interface WizardOptions {\n apiKey?: string;\n url?: string;\n agent?: string;\n yes?: boolean;\n}\n\n/** Where users obtain a key (operator-issued for now; self-serve dashboard later). */\nconst GET_KEY_URL = 'https://lurq.run';\n\n/**\n * Lightweight MCP `tools/list` ping to confirm the key authenticates.\n * Distinguishes a rejected key (401/403) from an unreachable endpoint so the\n * wizard can tell the user which one happened instead of blaming the key on a\n * flaky network.\n */\ntype KeyCheck = 'valid' | 'invalid' | 'unreachable';\n\nasync function validateKey(url: string, apiKey: string): Promise<KeyCheck> {\n try {\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json, text/event-stream',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/list' }),\n });\n if (res.ok) return 'valid';\n if (res.status === 401 || res.status === 403) return 'invalid';\n return 'unreachable';\n } catch {\n return 'unreachable';\n }\n}\n\nexport async function runInstallWizard(opts: WizardOptions): Promise<void> {\n const interactive = !opts.yes;\n const url = opts.url ?? process.env.LURQ_ENDPOINT ?? DEFAULT_ENDPOINT;\n let apiKey = (opts.apiKey ?? process.env.LURQ_API_KEY)?.trim();\n\n if (interactive) {\n const { input, checkbox, confirm, select } = await import('@inquirer/prompts');\n\n console.log('\\n lurq — connect your coding agent to the hosted package index.\\n');\n\n if (!apiKey) {\n console.log(` Need a key? Get one at ${GET_KEY_URL}\\n`);\n apiKey = (\n await input({\n message: 'Paste your lurq API key',\n validate: (v) =>\n v.trim().startsWith('lurq_') ? true : 'Keys look like lurq_live_… ',\n })\n ).trim();\n }\n\n process.stdout.write(' Validating key… ');\n const check = await validateKey(url, apiKey);\n console.log(\n check === 'valid' ? 'ok' : check === 'invalid' ? 'rejected' : 'could not reach endpoint',\n );\n if (check !== 'valid') {\n const proceed = await confirm({\n message:\n check === 'invalid'\n ? `That key was rejected (401) by ${url}. Continue anyway?`\n : `Couldn't reach ${url} to validate the key. Continue anyway?`,\n default: false,\n });\n if (!proceed) {\n console.log('Aborted. No config was changed.');\n return;\n }\n }\n\n if (opts.agent) {\n await finish(resolveAgents(opts.agent), { url, apiKey });\n return;\n }\n\n const specs = agentSpecs();\n // Natural-language quick path: if we spot likely agents, offer a one-tap\n // connect before falling back to the full multi-select. Mirrors the simplified\n // \"connect to Claude Code? (y/n/other)\" flow in docs/lurq-demo.md. \"Yes\" wires\n // up EVERY detected agent (the prior multi-select pre-checked them all), so a\n // user with two editors doesn't silently leave one unconnected.\n const detected = specs.filter((s) => s.detected);\n const primary = detected.find((s) => s.id === 'claude-code') ?? detected[0];\n if (primary) {\n const others = detected.length - 1;\n const choice = await select({\n message:\n others > 0\n ? `Looks like you have ${detected.map((s) => s.label).join(', ')}. Connect lurq to them?`\n : `Looks like you have ${primary.label}. Connect lurq to it?`,\n default: 'yes',\n choices: [\n {\n name: others > 0 ? `Yes — set up all ${detected.length} detected agents` : `Yes — set up ${primary.label} for me`,\n value: 'yes',\n },\n { name: 'No — let me choose which agent(s)', value: 'other' },\n { name: 'Cancel — change nothing', value: 'cancel' },\n ],\n });\n if (choice === 'cancel') {\n console.log('No problem — nothing was changed. Run `lurq install` again anytime.');\n return;\n }\n if (choice === 'yes') {\n await finish(detected, { url, apiKey });\n return;\n }\n // 'other' falls through to the full multi-select below.\n }\n\n const ids = await checkbox({\n message: 'Which assistant(s) should I configure?',\n choices: specs.map((s) => ({\n name: `${s.label}${s.detected ? ' (detected)' : ''}`,\n value: s.id,\n checked: s.detected,\n })),\n });\n await finish(specs.filter((s) => ids.includes(s.id)), { url, apiKey });\n return;\n }\n\n // Non-interactive (--yes): require a key, use flags/env + detected agents.\n if (!apiKey) {\n throw new Error(\n 'No API key. Pass --api-key <key> or set LURQ_API_KEY (or drop --yes to be prompted).',\n );\n }\n const selected = opts.agent\n ? resolveAgents(opts.agent)\n : agentSpecs().filter((s) => s.detected);\n await finish(selected, { url, apiKey });\n}\n\nasync function finish(\n selected: AgentSpec[],\n remote: { url: string; apiKey: string },\n): Promise<void> {\n if (selected.length === 0) {\n console.log(\n '\\nNo agents selected or detected. Re-run with --agent <id>, or install an assistant first.',\n );\n return;\n }\n const mode: InstallMode = { kind: 'remote', ...remote };\n const results = selected.map((s) => installAgent(s, mode));\n const instructionsPath = installInstructionsFile();\n console.log('');\n printInstallReport(results, instructionsPath, mode);\n}\n","/**\n * Operator-only API-key management for the hosted service (`lurq keys …`).\n * Requires DATABASE_URL — these commands run where the central DB lives, never on\n * a user's machine. New keys are printed in plaintext exactly once; only hashes\n * are stored, and list/JSON output never includes the hash.\n */\nimport { requireConfig } from '../core/config';\nimport { logger } from '../core/logger';\nimport { createKey, listKeys, revokeKey, rotateKey } from '../auth/apiKeys';\nimport type { ApiKeyRow } from '../db/schema';\nimport { createDb } from '../db/client';\nimport { bold, dim, green, table } from './format';\n\nconst isoDay = (d: Date | null) => (d ? d.toISOString().slice(0, 10) : '—');\n\n/** Block until the operator presses Enter (resolves immediately if not a TTY). */\nfunction waitForEnter(prompt: string): Promise<void> {\n return new Promise((resolve) => {\n process.stdout.write(prompt);\n process.stdin.resume();\n process.stdin.once('data', () => {\n process.stdin.pause();\n resolve();\n });\n });\n}\n\n/**\n * Present a freshly-issued plaintext key exactly once. In JSON mode it prints a\n * single line (plus any `extraJson`) for scripts. Interactively it shows the key,\n * waits for the operator to copy it, then wipes it from the terminal (screen +\n * scroll-back). Shared by `keys create` and `keys rotate`.\n */\nasync function presentNewKey(\n key: string,\n row: ApiKeyRow,\n opts: { json?: boolean; header?: string; extraJson?: Record<string, unknown> },\n): Promise<void> {\n if (opts.json) {\n console.log(\n JSON.stringify({ key, prefix: row.prefix, tier: row.tier, label: row.label, ...opts.extraJson }),\n );\n return;\n }\n\n const meta = `prefix=${row.prefix} tier=${row.tier}${row.label ? ` label=${row.label}` : ''}`;\n const block = [bold(opts.header ?? 'API key created.'), '', ` ${green(key)}`, '', dim(meta)];\n\n console.log(block.join('\\n'));\n\n if (process.stdout.isTTY && process.stdin.isTTY) {\n // Show the key, then wipe it from the terminal (screen + scrollback) once\n // the operator confirms they've copied it — so it doesn't linger on screen\n // or in scroll-back history.\n await waitForEnter(dim('Copy it now, then press Enter to erase it from the terminal… '));\n // Move to the top of the printed block (block lines + the prompt line the\n // Enter advanced past), clear to end of screen, and clear scroll-back.\n process.stdout.write(`\\x1b[${block.length + 1}F\\x1b[0J\\x1b[3J`);\n console.log(\n dim(`New key (prefix ${row.prefix}) erased from the terminal. ` +\n `It is stored only as a hash and cannot be recovered, so make sure you saved it.`),\n );\n } else {\n // Non-TTY (piped, or over a non-interactive SSH exec): can't erase, so just\n // warn. Operator is responsible for clearing their buffer.\n console.log(dim('Store it now — shown only once, stored hashed, cannot be recovered.'));\n }\n}\n\nexport async function runKeysCreate(opts: {\n label?: string;\n tier?: string;\n owner?: string;\n json?: boolean;\n}): Promise<void> {\n requireConfig(['DATABASE_URL']);\n const { db, close } = createDb({ max: 1 });\n try {\n const { key, row } = await createKey(db, {\n label: opts.label,\n tier: opts.tier,\n ownerId: opts.owner,\n });\n await presentNewKey(key, row, opts);\n } finally {\n await close();\n }\n}\n\nexport async function runKeysRotate(\n prefixOrId: string,\n opts: { json?: boolean },\n): Promise<void> {\n requireConfig(['DATABASE_URL']);\n const { db, close } = createDb({ max: 1 });\n try {\n const result = await rotateKey(db, prefixOrId);\n if (!result) {\n logger.warn(`No active key matched \"${prefixOrId}\".`);\n process.exitCode = 1;\n return;\n }\n await presentNewKey(result.key, result.row, {\n json: opts.json,\n header: `API key rotated — replaces ${result.previous.prefix} (now revoked).`,\n extraJson: { replaced: result.previous.prefix },\n });\n } finally {\n await close();\n }\n}\n\nexport async function runKeysList(opts: { json?: boolean }): Promise<void> {\n requireConfig(['DATABASE_URL']);\n const { db, close } = createDb({ max: 1 });\n try {\n const rows = await listKeys(db);\n if (opts.json) {\n // Deliberately omit keyHash from machine output.\n console.log(\n JSON.stringify(\n rows.map((r) => ({\n id: r.id,\n prefix: r.prefix,\n label: r.label,\n tier: r.tier,\n ownerId: r.ownerId,\n createdAt: r.createdAt,\n lastUsedAt: r.lastUsedAt,\n revokedAt: r.revokedAt,\n })),\n null,\n 2,\n ),\n );\n return;\n }\n if (rows.length === 0) {\n console.log('No API keys yet. Create one with `lurq keys create --label <name>`.');\n return;\n }\n console.log(\n table(\n ['prefix', 'label', 'tier', 'created', 'last used', 'status'],\n rows.map((r) => [\n r.prefix,\n r.label ?? '—',\n r.tier,\n isoDay(r.createdAt),\n isoDay(r.lastUsedAt),\n r.revokedAt ? 'revoked' : 'active',\n ]),\n ),\n );\n } finally {\n await close();\n }\n}\n\nexport async function runKeysRevoke(prefixOrId: string): Promise<void> {\n requireConfig(['DATABASE_URL']);\n const { db, close } = createDb({ max: 1 });\n try {\n const n = await revokeKey(db, prefixOrId);\n if (n === 0) {\n logger.warn(`No active key matched \"${prefixOrId}\".`);\n process.exitCode = 1;\n return;\n }\n console.log(`Revoked ${n} key(s) matching \"${prefixOrId}\".`);\n } finally {\n await close();\n }\n}\n","/**\n * Load the curated seed list (§16) into `seed_packages`. Idempotent: re-running\n * upserts category and leaves `added_at` intact for existing rows.\n */\nimport { readFileSync } from 'node:fs';\nimport { sql } from 'drizzle-orm';\nimport { z } from 'zod';\nimport { CATEGORIES, type Category } from '../core/types';\nimport { logger } from '../core/logger';\nimport { seedJsonPath } from '../core/paths';\nimport type { Database } from './client';\nimport { seedPackages } from './schema';\n\nconst SeedEntrySchema = z.object({\n name: z.string().min(1),\n category: z.enum(CATEGORIES as unknown as [Category, ...Category[]]).optional(),\n});\nconst SeedFileSchema = z.array(SeedEntrySchema);\n\nexport interface SeedEntry {\n name: string;\n category?: Category;\n}\n\nexport function loadSeedFile(path = seedJsonPath()): SeedEntry[] {\n const raw = JSON.parse(readFileSync(path, 'utf8'));\n const parsed = SeedFileSchema.parse(raw);\n // De-duplicate by name (first occurrence wins) so a package can't be seeded twice.\n const byName = new Map<string, SeedEntry>();\n for (const entry of parsed) {\n if (!byName.has(entry.name)) byName.set(entry.name, entry);\n }\n return [...byName.values()];\n}\n\nexport async function loadSeedPackages(db: Database, path?: string): Promise<number> {\n const entries = loadSeedFile(path);\n if (entries.length === 0) return 0;\n await db\n .insert(seedPackages)\n .values(entries.map((e) => ({ name: e.name, category: e.category ?? null })))\n .onConflictDoUpdate({\n target: seedPackages.name,\n // Refresh category to the incoming value on conflict (EXCLUDED.category).\n set: { category: sql`excluded.category` },\n });\n logger.info(`Loaded ${entries.length} packages into seed_packages.`);\n return entries.length;\n}\n","/**\n * Schema management for `lurq db migrate` / `lurq db reset`.\n *\n * `migrate` ensures the pgvector extension exists (Drizzle does not create it),\n * applies generated migrations, then loads the curated seed list (§18 M1).\n * `reset` drops the public schema and re-runs migrate — destructive.\n */\nimport { migrate } from 'drizzle-orm/postgres-js/migrator';\nimport { logger } from '../core/logger';\nimport { migrationsDir } from '../core/paths';\nimport { createDb, type DbHandle } from './client';\nimport { loadSeedPackages } from './seed';\n\nasync function ensureVectorExtension(handle: DbHandle): Promise<void> {\n // Non-fatal: if the extension already exists (it must, once migration 0000's\n // `vector` column is in place) this is a no-op, and a transient hiccup here\n // must NOT abort the migrator and leave later migrations (0001+) unapplied.\n try {\n await handle.sql`CREATE EXTENSION IF NOT EXISTS vector`;\n } catch (err) {\n logger.warn(\n `CREATE EXTENSION vector did not run cleanly (continuing to migrations): ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n}\n\nexport async function runMigrate(): Promise<void> {\n // A single, non-pooled connection is best for migrations.\n const handle = createDb({ max: 1 });\n try {\n logger.info('Ensuring pgvector extension…');\n await ensureVectorExtension(handle);\n\n logger.info('Applying migrations…');\n await migrate(handle.db, { migrationsFolder: migrationsDir() });\n\n logger.info('Loading seed list…');\n await loadSeedPackages(handle.db);\n\n logger.info('Migration complete.');\n } finally {\n await handle.close();\n }\n}\n\nexport async function runReset(): Promise<void> {\n const handle = createDb({ max: 1 });\n try {\n logger.warn('Dropping schema `public` (destructive)…');\n await handle.sql.unsafe('DROP SCHEMA IF EXISTS public CASCADE; CREATE SCHEMA public;');\n // Drizzle tracks applied migrations in its own schema; clear it too.\n await handle.sql`DROP SCHEMA IF EXISTS drizzle CASCADE`;\n } finally {\n await handle.close();\n }\n // Re-apply everything from scratch.\n await runMigrate();\n logger.info('Reset complete.');\n}\n","#!/usr/bin/env node\n/**\n * lurq CLI entry point. Runnable via `npx lurq <command>` (§7, §13).\n */\nimport { readFileSync } from 'node:fs';\nimport updateNotifier from 'update-notifier';\nimport { buildProgram } from '../cli/index';\nimport { loadEnv } from '../core/config';\nimport { enforceGate } from '../core/gate';\nimport { logger } from '../core/logger';\n\nloadEnv();\n\n// Private-preview gate: non-owners get a placeholder, the owner runs as usual.\n// Runs after loadEnv so LURQ_OWNER_KEY from a .env file is honored too.\nenforceGate(process.argv.slice(2));\n\nnotifyOnUpdate();\n\nbuildProgram()\n .parseAsync(process.argv)\n .catch((err) => {\n logger.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n });\n\n/**\n * Check npm (at most once a day, in a detached background process) and print a\n * one-line \"update available\" banner on exit when a newer lurqrun is published.\n * Skipped in agent/machine contexts — MCP stdio servers and `--json` output —\n * so the protocol/output stream is never touched. update-notifier additionally\n * only prints in a TTY, so piped runs stay silent regardless. Any failure here\n * must never break the CLI, hence the broad guard.\n */\nfunction notifyOnUpdate(): void {\n const argv = process.argv.slice(2);\n const quiet =\n argv[0] === 'serve' || argv[0] === 'serve-http' || argv.includes('--json');\n if (quiet) return;\n\n try {\n const pkg = JSON.parse(\n readFileSync(new URL('../../package.json', import.meta.url), 'utf8'),\n ) as { name: string; version: string };\n updateNotifier({ pkg }).notify();\n } catch {\n // Offline, no config dir, malformed metadata — never fatal for the CLI.\n }\n}\n","/**\n * CLI command wiring (§13). Built with commander. Each command mirrors an MCP\n * tool or an operational task. Handlers are filled in across milestones M1–M7;\n * the command/option surface here is the final, stable shape.\n *\n * Every command supports `--json` for machine-readable output.\n */\nimport { Command } from 'commander';\nimport { SERVER_NAME, VERSION } from '../core/constants';\n\nexport function buildProgram(): Command {\n const program = new Command();\n\n program\n .name(SERVER_NAME)\n .description(\n 'lurq - a fresh, objectively-scored index of JS/TS packages for AI coding agents.',\n )\n .version(VERSION, '-v, --version', 'output the lurq version');\n\n program\n .command('serve')\n .description('start the MCP server over stdio (for agent integration)')\n .action(async () => {\n const { startMcpServer } = await import('../mcp/server');\n await startMcpServer();\n });\n\n program\n .command('serve-http')\n .description('start the hosted MCP server over HTTP with API-key auth')\n .option('--port <n>', 'port to listen on (default: $PORT or 8080)', (v) => parseInt(v, 10))\n .action(async (opts: { port?: number }) => {\n const { startHttpServer } = await import('../mcp/http');\n await startHttpServer({ port: opts.port });\n });\n\n program\n .command('sync')\n .description('run ingestion: refresh scores for the seed list (or one package)')\n .option('--full', 'force a full re-sync, ignoring cache TTLs')\n .option('--package <name>', 'sync a single package by name')\n .option('--json', 'output the run summary as JSON')\n .action(async (opts: { full?: boolean; package?: string; json?: boolean }) => {\n const { runSync } = await import('../pipeline/index');\n const summary = await runSync({ full: opts.full, packageName: opts.package });\n if (opts.json) console.log(JSON.stringify(summary, null, 2));\n if (summary.status === 'failed') process.exitCode = 1;\n });\n\n program\n .command('recommend')\n .argument('<need>', 'natural-language description of what you need')\n .description('recommend the best current packages for a described need')\n .option('--category <category>', 'restrict to a taxonomy category')\n .option('--min-confidence <level>', 'proven | emerging | promising | unproven')\n .option('--json', 'output JSON instead of a table')\n .action(async (need: string, opts: { category?: string; minConfidence?: string; json?: boolean }) => {\n const { runRecommend } = await import('./commands');\n await runRecommend(need, opts);\n });\n\n program\n .command('evaluate')\n .argument('<package>', 'npm package name')\n .description('full evidence read for one package (scores, signals, usage guide)')\n .option('--json', 'output JSON instead of a table')\n .action(async (pkg: string, opts: { json?: boolean }) => {\n const { runEvaluate } = await import('./commands');\n await runEvaluate(pkg, opts);\n });\n\n program\n .command('compare')\n .argument('<packages...>', '2–5 npm package names')\n .description('side-by-side comparison of packages, ranked by health')\n .option('--json', 'output JSON instead of a table')\n .action(async (pkgs: string[], opts: { json?: boolean }) => {\n const { runCompare } = await import('./commands');\n await runCompare(pkgs, opts);\n });\n\n program\n .command('verify')\n .argument('<package>', 'npm package name')\n .description('safety check: is this package real, healthy, and not risky?')\n .option('--json', 'output JSON instead of a table')\n .action(async (pkg: string, opts: { json?: boolean }) => {\n const { runVerify } = await import('./commands');\n await runVerify(pkg, opts);\n });\n\n program\n .command('versions')\n .argument('<package>', 'npm package name')\n .description('show the stored version timeline for a package')\n .option('--json', 'output JSON instead of a table')\n .option('-n, --limit <n>', 'how many versions to show (default 30)')\n .action(async (pkg: string, opts: { json?: boolean; limit?: string }) => {\n const { runVersions } = await import('./commands');\n await runVersions(pkg, opts);\n });\n\n program\n .command('plan')\n .argument('<file>', 'path to a markdown file describing your program')\n .description('turn a program description into an evidence-scored package plan + roadmap')\n .option('--optimize <mode>', \"ranking bias: 'speed' (lightest bundle) or 'balanced'\")\n .option('--html <path>', 'write the roadmap as a self-contained HTML visualization')\n .option('--open', 'render the roadmap to HTML and open it in your browser')\n .option('--json', 'output the full plan as JSON')\n .action(async (file: string, opts: { optimize?: string; json?: boolean; html?: string; open?: boolean }) => {\n const { runPlan } = await import('./commands');\n await runPlan(file, opts);\n });\n\n program\n .command('weights')\n .description('show and explain the scoring weight model (health, quality, composite λ)')\n .option('--json', 'output the weight model as JSON')\n .action(async (opts: { json?: boolean }) => {\n const { runWeights } = await import('./commands');\n runWeights(opts);\n });\n\n program\n .command('edit-weights')\n .description('override, reset, or explain the scoring weights (layered over defaults)')\n .option('--set <pair>', 'override key=value, e.g. composite.lambda=0.5 (repeatable)', (v: string, acc: string[]) => acc.concat(v), [])\n .option('--reset', 'remove all overrides and restore defaults')\n .option('--explain <component>', 'explain a component (e.g. adoption, quality, lambda)')\n .option('--project', 'write to project-local .lurq/weights.json instead of the user config')\n .action(async (opts: { set?: string[]; reset?: boolean; explain?: string; project?: boolean }) => {\n const { runEditWeights } = await import('./commands');\n await runEditWeights(opts);\n });\n\n program\n .command('discover')\n .description('operator-side: proactively crawl for new packages and queue/gate them (§2B)')\n .option('--cap <n>', 'max candidates to fully ingest this run', (v) => parseInt(v, 10))\n .option('--dry-run', 'discover, queue, and gate, but do not ingest survivors')\n .option('--json', 'output the discovery summary as JSON')\n .action(async (opts: { cap?: number; dryRun?: boolean; json?: boolean }) => {\n const { requireConfig } = await import('../core/config');\n requireConfig(['DATABASE_URL']);\n const { runDiscovery } = await import('../pipeline/index');\n const summary = await runDiscovery({ perRunCap: opts.cap, dryRun: opts.dryRun });\n if (opts.json) console.log(JSON.stringify(summary, null, 2));\n });\n\n program\n .command('rescore')\n .description('re-derive health scores from cached breakdowns using current weights (no re-ingest)')\n .option('--json', 'output the rescore summary as JSON')\n .action(async (opts: { json?: boolean }) => {\n const { requireConfig } = await import('../core/config');\n requireConfig(['DATABASE_URL']);\n const { runRescore } = await import('../pipeline/index');\n const summary = await runRescore();\n if (opts.json) console.log(JSON.stringify(summary, null, 2));\n });\n\n program\n .command('watch')\n .description(\n 'operator-side: follow the npm changes feed, re-syncing tracked packages on new releases',\n )\n .action(async () => {\n const { runWatch } = await import('./commands');\n await runWatch();\n });\n\n program\n .command('sandbox')\n .argument('<package>', 'npm package name')\n .argument('[version]', 'specific version (default: latest)')\n .description(\n 'operator-side: install + smoke-load a package in a sandbox to verify it actually works',\n )\n .option('--esm', 'load via ESM import instead of CJS require')\n .option('--allow-scripts', 'run install scripts (UNSAFE without VM isolation)')\n .option('--json', 'output JSON')\n .action(\n async (\n pkg: string,\n version: string | undefined,\n opts: { esm?: boolean; allowScripts?: boolean; json?: boolean },\n ) => {\n const { runSandbox } = await import('./commands');\n await runSandbox(pkg, version, opts);\n },\n );\n\n program\n .command('compat')\n .argument('<packages...>', 'npm package names to check together')\n .description('check pairwise compatibility of packages from the sandbox matrix')\n .option('--run', 'operator-side: co-install them in the sandbox first (UNSAFE without VM isolation)')\n .option('--json', 'output JSON')\n .action(async (pkgs: string[], opts: { run?: boolean; json?: boolean }) => {\n const { runCompat } = await import('./commands');\n await runCompat(pkgs, opts);\n });\n\n program\n .command('install')\n .description('guided setup: connect lurq to your AI assistant(s)')\n .option('--api-key <key>', 'hosted API key (skips the prompt)')\n .option('--url <url>', 'hosted endpoint URL (defaults to the lurq service)')\n .option('--agent <agent>', 'claude-code | cursor | copilot | windsurf | codex | all')\n .option('--yes', 'non-interactive: use flags/env and detected agents without prompting')\n .action(async (opts: { apiKey?: string; url?: string; agent?: string; yes?: boolean }) => {\n const { runInstallWizard } = await import('./install');\n await runInstallWizard(opts);\n });\n\n program\n .command('install-skill')\n .description('register lurq as an MCP server in supported AI assistants (scriptable)')\n .option(\n '--agent <agent>',\n 'claude-code | cursor | copilot | windsurf | codex | all',\n 'claude-code',\n )\n .option('--api-key <key>', 'hosted API key (remote install; default mode)')\n .option('--url <url>', 'hosted endpoint URL (defaults to the lurq service)')\n .option('--local', 'self-host: write a local stdio entry using your own DATABASE_URL')\n .action(async (opts: { agent?: string; apiKey?: string; url?: string; local?: boolean }) => {\n const { runInstallSkill } = await import('./installSkill');\n await runInstallSkill(opts);\n });\n\n const keys = program\n .command('keys')\n .description('manage API keys for the hosted service (operator; needs DATABASE_URL)');\n keys\n .command('create')\n .description('create a new API key (shown once; erased from the terminal after you copy it)')\n .option('--label <label>', 'human label (owner / org / purpose)')\n .option('--tier <tier>', 'tier name', 'free')\n .option('--owner <id>', 'org/owner id to attribute this key to (e.g. a Clerk org id)')\n .option('--json', 'print the key as JSON and skip the interactive erase (for scripts)')\n .action(async (opts: { label?: string; tier?: string; owner?: string; json?: boolean }) => {\n const { runKeysCreate } = await import('./keys');\n await runKeysCreate(opts);\n });\n keys\n .command('list')\n .description('list issued API keys (hashes are never shown)')\n .option('--json', 'output as JSON')\n .action(async (opts: { json?: boolean }) => {\n const { runKeysList } = await import('./keys');\n await runKeysList(opts);\n });\n keys\n .command('rotate')\n .argument('<prefixOrId>', 'key prefix (e.g. lurq_live_ab12cd) or numeric id to replace')\n .description('issue a replacement key (same label/tier) and revoke the old one')\n .option('--json', 'print the new key as JSON and skip the interactive erase (for scripts)')\n .action(async (prefixOrId: string, opts: { json?: boolean }) => {\n const { runKeysRotate } = await import('./keys');\n await runKeysRotate(prefixOrId, opts);\n });\n keys\n .command('revoke')\n .argument('<prefixOrId>', 'key prefix (e.g. lurq_live_ab12cd) or numeric id')\n .description('revoke an API key')\n .action(async (prefixOrId: string) => {\n const { runKeysRevoke } = await import('./keys');\n await runKeysRevoke(prefixOrId);\n });\n\n const db = program.command('db').description('database management');\n db.command('migrate')\n .description('apply database migrations and load the seed list')\n .action(async () => {\n const { runMigrate } = await import('../db/migrate');\n await runMigrate();\n });\n db.command('reset')\n .description('drop and recreate the schema (destructive)')\n .option('--yes', 'skip the confirmation prompt')\n .action(async (opts: { yes?: boolean }) => {\n if (!opts.yes) {\n console.error(\n 'Refusing to reset without confirmation. Re-run with `--yes` to drop and recreate the schema.',\n );\n process.exitCode = 1;\n return;\n }\n const { runReset } = await import('../db/migrate');\n await runReset();\n });\n\n return program;\n}\n","/**\n * Pre-launch access gate.\n *\n * While lurq is in private preview, anyone may `npm install lurqrun`, but only\n * the owner may run commands — everyone else gets a branded placeholder. The\n * owner proves identity by exporting `LURQ_OWNER_KEY` in their shell to the\n * secret whose SHA-256 is baked into `OWNER_HASH` below. The published bundle\n * carries only the hash, never the secret, so inspecting the source reveals\n * nothing usable.\n *\n * To lift the gate at public launch, flip `PRE_LAUNCH` to false (or delete the\n * `enforceGate()` call in bin/lurq.ts). The owner bypass keeps working either\n * way, so nothing else needs to change.\n */\nimport { createHash, timingSafeEqual } from 'node:crypto';\n\nimport { PACKAGE_NAME } from './constants';\n\n/** Master switch. Set to false to open lurq to everyone at launch. */\nconst PRE_LAUNCH = false;\n\n/**\n * SHA-256 of the owner secret. Regenerate after choosing a new secret with:\n * node -e \"console.log(require('node:crypto').createHash('sha256').update(process.argv[1]).digest('hex'))\" <secret>\n * and paste the result here. Keep the plaintext only in your shell env.\n */\nconst OWNER_HASH = '9675c37e56783e747e4a89ee3919d95d1364f2e5dd0f14501b0f878f8cc3682b';\n\n/**\n * Top-level commands that bypass the gate even for non-owners:\n * - `-v/--version/-h/--help/help` — harmless, expected by npm users.\n * - `serve`/`serve-http` — the MCP transports. The gate must NEVER write to the\n * stdio JSON-RPC channel (`serve`), and the hosted server must boot without\n * depending on the owner key (`serve-http`).\n * - `sync`/`discover`/`rescore`/`db`/`keys` — operator/infra commands that all\n * require DATABASE_URL, which a public installer never has. Gating them adds no\n * protection (a keyless user can't run them anyway) while risking the owner's\n * own deploy. The gate's real job is the user-facing commands (recommend,\n * evaluate, compare, verify, plan, install, install-skill, weights).\n */\nconst ALLOWED = new Set([\n '-v', '--version', '-h', '--help', 'help',\n 'serve', 'serve-http',\n 'sync', 'discover', 'rescore', 'db', 'keys',\n]);\n\n/** True when the caller has proven they are the owner via `LURQ_OWNER_KEY`. */\nexport function isOwner(): boolean {\n const key = process.env.LURQ_OWNER_KEY;\n if (!key) return false;\n const got = createHash('sha256').update(key).digest();\n const want = Buffer.from(OWNER_HASH, 'hex');\n // Equal-length buffers (both 32 bytes); timingSafeEqual guards against a\n // timing oracle on the comparison.\n return got.length === want.length && timingSafeEqual(got, want);\n}\n\n/**\n * Enforce the gate before any command runs. Returns normally when the caller is\n * the owner, the gate is lifted, or the invocation is a top-level help/version\n * query. Otherwise prints the placeholder and exits cleanly (code 0 — installing\n * early is not an error).\n */\nexport function enforceGate(argv: string[]): void {\n if (!PRE_LAUNCH || isOwner()) return;\n if (argv[0] && ALLOWED.has(argv[0])) return;\n\n printPlaceholder();\n process.exit(0);\n}\n\nfunction printPlaceholder(): void {\n const tty = process.stdout.isTTY;\n const bold = (s: string) => (tty ? `\\x1b[1m${s}\\x1b[0m` : s);\n const dim = (s: string) => (tty ? `\\x1b[2m${s}\\x1b[0m` : s);\n const accent = (s: string) => (tty ? `\\x1b[38;5;213m${s}\\x1b[0m` : s);\n\n process.stdout.write(\n [\n '',\n ` ${bold('lurq')} ${dim('— evidence-scored package index for AI coding agents')}`,\n '',\n ` ${accent('◆ private preview')}`,\n '',\n ` lurq isn't open to the public yet — thanks for installing early.`,\n ` Join the waitlist and watch the demo at ${bold('https://lurq.run')}`,\n '',\n dim(` You'll be able to connect Claude Code, Cursor, and other agents`),\n dim(` the moment we open the gate.`),\n '',\n dim(` (${PACKAGE_NAME} is installed and ready — no further action needed.)`),\n '',\n '',\n ].join('\\n'),\n );\n}\n"],"mappings":"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","names":["table","sql","cached","cached","attempt","text","json","HOST","json","HOST","json","HOST","json","HOST","json","HOST","packages","and","desc","eq","init_successors","HOST","text","text","existsSync","homedir","dirname","join","fileURLToPath","existsSync","dirname","active","eq","path","createHash","text","str","dim","index","and","eq","isNotNull","sql","median","and","eq","isNotNull","sql","createHash","sql","DAY_MS","cached","typo","init_successors","inArray","text","createHash","inArray","z","createHash","and","desc","eq","cached","createHash","init_http","isNotNull","eq","eq","isNotNull","pending","init_discovery","init_discovery","eq","backoff","init_watch","init_types","writeFile","join","init_types","packages","condense","ERROR_MAX","INSTALL_TIMEOUT_MS","SMOKE_TIMEOUT_MS","toSpec","init_types","packages","E2BSandbox","init_types","init_sandbox","packages","init_compat","active","invalidateCache","text","path","readFileSync","handlePlan","writeFileSync","tmpdir","join","renderPlanHtml","watchNpmChanges","verifyPackageInSandbox","verifyCompatibility","handleCompat","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","dirname","join","path","text","readFileSync","sql","z","path","readFileSync","startMcpServer","startHttpServer","runSync","runRecommend","runEvaluate","runCompare","runVerify","runVersions","runPlan","runWeights","runEditWeights","requireConfig","runDiscovery","runRescore","runWatch","runSandbox","runCompat","runInstallWizard","runInstallSkill","runKeysCreate","runKeysList","runKeysRotate","runKeysRevoke","runMigrate","runReset","createHash","timingSafeEqual","bold","dim","readFileSync"]}