mcp-scraper 0.89.0 → 0.89.1

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +32 -14
  2. package/README.md +5 -3
  3. package/dist/{analytics-repository-2BMT5JNE.js → analytics-repository-J25XR5E7.js} +1 -1
  4. package/dist/bin/api-server.js +1 -1
  5. package/dist/bin/mcp-scraper-cli.js +1 -1
  6. package/dist/bin/mcp-scraper-core.js +1 -1
  7. package/dist/bin/mcp-scraper-install.js +1 -1
  8. package/dist/bin/mcp-stdio-server.js +1 -1
  9. package/dist/bin/paa-harvest.js +1 -1
  10. package/dist/chunk-3GP5CYZX.js +1 -1
  11. package/dist/chunk-4FROKQJN.js +1 -1
  12. package/dist/{chunk-TXENITMS.js → chunk-57AHYL2O.js} +1 -1
  13. package/dist/chunk-5H3MCTTP.js +1 -0
  14. package/dist/{chunk-GMWKPIYX.js → chunk-63T4W2LX.js} +182 -83
  15. package/dist/{chunk-WSCGYRWA.js → chunk-645LQBE7.js} +1 -1
  16. package/dist/{chunk-7YGVI5J4.js → chunk-6QO4F2KC.js} +3 -3
  17. package/dist/{chunk-M22MM4N4.js → chunk-D6IQJP64.js} +1 -1
  18. package/dist/{chunk-CFI6CXIV.js → chunk-DGBLGFNJ.js} +1 -1
  19. package/dist/{chunk-4AI7DOS7.js → chunk-FFPD2DOF.js} +1 -1
  20. package/dist/chunk-FXEWHK54.js +1 -0
  21. package/dist/{chunk-HDPYG3XV.js → chunk-IJ2AO7AO.js} +1 -1
  22. package/dist/{chunk-PUHFVA7P.js → chunk-MEM4D2QN.js} +4 -4
  23. package/dist/{chunk-E2WRWV3A.js → chunk-PRWZNHQB.js} +1 -1
  24. package/dist/chunk-QPWPR5XG.js +3 -3
  25. package/dist/{chunk-MASR22K4.js → chunk-RYNHNEF3.js} +15 -15
  26. package/dist/{chunk-L4CGLFPU.js → chunk-YUPLOOTB.js} +1 -1
  27. package/dist/{chunk-XPZVJIZ2.js → chunk-ZHORX44A.js} +1 -1
  28. package/dist/db-JJWJLAVQ.js +1 -0
  29. package/dist/{extract-bundle-SNUIHM3J.js → extract-bundle-TTSEGWYF.js} +1 -1
  30. package/dist/{gmail-service-BZ3H75XC.js → gmail-service-34PIJRLK.js} +1 -1
  31. package/dist/index.cjs +143 -44
  32. package/dist/index.d.cts +14 -14
  33. package/dist/index.d.ts +14 -14
  34. package/dist/index.js +1 -1
  35. package/dist/{lead-list-enrichment-repository-S2H3U7T7.js → lead-list-enrichment-repository-VJBBMBCG.js} +1 -1
  36. package/dist/{location-data-repository-OTWHWMV6.js → location-data-repository-W3LPT6G3.js} +1 -1
  37. package/dist/{server-RFR2A5UJ.js → server-UEY5YQL6.js} +846 -820
  38. package/dist/{site-extract-repository-SE776XDC.js → site-extract-repository-7W5ZUNPR.js} +1 -1
  39. package/dist/worker-ZOTOKG56.js +1 -0
  40. package/package.json +131 -17
  41. package/THIRD_PARTY_NOTICES.html +0 -203
  42. package/dist/chunk-X54CQLK2.js +0 -1
  43. package/dist/chunk-Z2QGQJS2.js +0 -1
  44. package/dist/db-F2MX63GI.js +0 -1
  45. package/dist/worker-XUDSM3AL.js +0 -1
@@ -1,4 +1,103 @@
1
- import{createClient as Ce}from"@libsql/client/http";import{createHash as A,randomBytes as C,randomUUID as m,scryptSync as ie,timingSafeEqual as ke}from"crypto";import{z as T}from"zod";var O="2026-06-26 21:58:03";var Qe="Google returned a CAPTCHA. Run with --headless=false to re-warm the browser profile, then retry.",be="This operation is temporarily unavailable. Please retry later.",Le=["request_aborted","captcha_exhausted","captcha_or_blocked","location_mismatch","proxy_tunnel_failed","proxy_unavailable","harvest_timeout","mcp_request_timeout","mcp_http_error","extraction_failed","concurrency_limit_exceeded","unauthorized","forbidden","invalid_request","rate_limited","upstream_rate_limited","insufficient_balance","service_unavailable","response_lost","vendor_unavailable","page_not_found","page_forbidden","page_rate_limited","page_server_error","page_http_error","bot_check_unresolved","page_too_large","page_unreachable","browser_session_interrupted","site_export_not_found","site_export_format_unavailable","site_export_read_failed","site_export_image_not_found","image_url_invalid","image_url_not_https","image_host_unresolvable","image_host_blocked","image_redirect_invalid","image_source_unavailable","image_too_large","image_redirect_limit","image_base64_invalid","image_source_missing","image_source_ambiguous","image_source_type_invalid","image_artifact_not_found","image_page_too_large","page_image_not_found","page_image_candidates_unusable","image_format_unsupported","image_storage_unconfigured","featured_image_unhostable"],Se=["request_aborted","captcha","location_mismatch","connection","timeout","extraction","concurrency_limit","unauthorized","forbidden","invalid_request","rate_limit","billing","service_unavailable"];function L(e){return e?JSON.stringify(e):null}function z(e){if(e==null)return null;try{let t=typeof e=="string"?JSON.parse(e):e;if(!t||typeof t!="object"||Array.isArray(t))return null;let r=t;if(typeof r.error_code!="string"||!Q.has(r.error_code))return null;let n=Ie({errorCode:r.error_code,errorType:r.error_type,retryable:r.retryable,retryAfterSeconds:r.retry_after_seconds,chargeStatus:r.charge_status,details:r.details});if(typeof r.message=="string"){let i=Z(r.message).trim().slice(0,1e3);i&&!/https?:\/\//i.test(i)&&(n.message=i)}return n}catch{return null}}var Q=new Set(Le),Re=new Set(Se),we=new Set(["active","limit","operation","upgrade_url","topup_url","upgrade_command","slots_per_pack","pack_price_usd","balance_credits","required_credits","retry_guidance","http_status"]),Ae=12,fe=500;function U(e){return typeof e=="string"&&Q.has(e)?e:"service_unavailable"}function Oe(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t={};for(let[r,n]of Object.entries(e)){if(Object.keys(t).length>=Ae)break;if(we.has(r))if(typeof n=="string"){if((r==="upgrade_url"||r==="topup_url")&&!xe(n))continue;let i=Z(n).slice(0,fe);i&&(t[r]=i)}else(typeof n=="number"&&Number.isFinite(n)||typeof n=="boolean"||n===null)&&(t[r]=n)}return Object.keys(t).length>0?t:void 0}function xe(e){if(e.startsWith("/")&&!e.startsWith("//"))return!0;try{let t=new URL(e);return t.protocol==="https:"&&(t.hostname==="mcpscraper.dev"||t.hostname.endsWith(".mcpscraper.dev"))}catch{return!1}}function he(e){let t=U(e);switch(t){case"captcha_exhausted":case"captcha_or_blocked":return"captcha";case"proxy_tunnel_failed":case"proxy_unavailable":case"response_lost":return"connection";case"harvest_timeout":case"mcp_request_timeout":return"timeout";case"concurrency_limit_exceeded":return"concurrency_limit";case"rate_limited":case"upstream_rate_limited":return"rate_limit";case"extraction_failed":case"page_not_found":case"page_forbidden":case"page_rate_limited":case"page_server_error":case"page_http_error":case"bot_check_unresolved":case"page_too_large":case"page_unreachable":case"browser_session_interrupted":case"site_export_not_found":case"site_export_format_unavailable":case"site_export_read_failed":case"site_export_image_not_found":return"extraction";case"image_url_invalid":case"image_url_not_https":case"image_host_unresolvable":case"image_host_blocked":case"image_redirect_invalid":case"image_source_unavailable":case"image_too_large":case"image_redirect_limit":case"image_base64_invalid":case"image_source_missing":case"image_source_ambiguous":case"image_source_type_invalid":case"image_artifact_not_found":case"image_page_too_large":case"page_image_not_found":case"page_image_candidates_unusable":case"image_format_unsupported":case"image_storage_unconfigured":case"featured_image_unhostable":return"invalid_request";case"insufficient_balance":return"billing";case"vendor_unavailable":case"mcp_http_error":return"service_unavailable";default:return t}}function ye(e){switch(U(e)){case"request_aborted":return"The request was cancelled before it completed.";case"captcha_exhausted":case"captcha_or_blocked":return"The target site returned a verification challenge. Heavy traffic can temporarily increase these challenges; retry in a few minutes.";case"location_mismatch":return"The target site returned results for a different location. Please retry.";case"proxy_tunnel_failed":case"proxy_unavailable":return"The web request could not establish a working connection. Please retry later.";case"harvest_timeout":return"The request timed out before it completed. Please retry with a smaller request.";case"mcp_request_timeout":return"The MCP caller stopped waiting before a final response arrived. Durable work may still be running; continue with the returned Task or job handle instead of restarting it.";case"concurrency_limit_exceeded":return"The service is available, but this account has reached its parallel-operation limit. Wait for an active operation to finish or add capacity.";case"unauthorized":return"Authentication is required to perform this operation.";case"forbidden":return"This account does not have permission to perform this operation.";case"invalid_request":return"The request is invalid. Check the supplied inputs and try again.";case"rate_limited":return"This account is sending requests too quickly. Wait briefly and retry.";case"upstream_rate_limited":return"The connected provider is temporarily rate-limiting requests. Wait briefly and retry.";case"mcp_http_error":return"The API returned an unexpected HTTP response.";case"insufficient_balance":return"This account does not have enough Credits for the operation.";case"extraction_failed":return"The target could not be extracted. Please retry later.";case"response_lost":return"The connection was lost before the response arrived. The operation may have already completed and been billed on our side \u2014 check credits_info before retrying blind.";case"vendor_unavailable":return"MCP Scraper's internal browser services require MCP Scraper team attention. Servers or IPs are down until this is fixed \u2014 this is not caused by your request. Please retry in a few minutes.";case"page_not_found":return"The page could not be found. It may have been moved or deleted.";case"page_forbidden":return"The site refused the request.";case"page_rate_limited":return"The site is rate-limiting requests right now. Retrying after a short wait usually works.";case"page_server_error":return"The page's own server returned an error. This is on the target site's side, not something a retry here can fix.";case"page_http_error":return"The page returned an unexpected HTTP response.";case"bot_check_unresolved":return"This site has automated-traffic protection (a bot/CAPTCHA check) that could not be resolved in time. Some sites are simply not extractable this way.";case"page_too_large":return"The page is larger than we can safely process.";case"page_unreachable":return"The page did not respond in time, or the connection could not be completed.";case"browser_session_interrupted":return"The browser session closed before extraction completed. MCP Scraper will retry once with a fresh session; retry the request if this persists.";case"site_export_not_found":return"The site export or requested page was not found, expired, or does not belong to this account.";case"site_export_format_unavailable":return"That representation was not retained for this export page. Read the export manifest and request one of the formats marked available.";case"site_export_read_failed":return"The stored site export could not be read or did not pass its integrity check.";case"site_export_image_not_found":return"The requested site-export image was not found, expired, or does not belong to this account.";case"image_url_invalid":return"The image source is not a valid URL. Use a stable public HTTPS URL or inline image bytes.";case"image_url_not_https":return"Commons image sources must use a public HTTPS URL or inline image bytes.";case"image_host_unresolvable":return"The image host could not be resolved. Use a different stable public URL or inline image bytes.";case"image_host_blocked":return"The image source resolves to a network address Commons cannot fetch safely.";case"image_redirect_invalid":return"The image source redirected to an invalid or unsafe destination.";case"image_source_unavailable":return"The image source could not be fetched. Host a different stable public URL or provide inline image bytes.";case"image_too_large":return"The image exceeds the Commons image size limit.";case"image_redirect_limit":return"The image source exceeded the Commons redirect limit.";case"image_base64_invalid":return"The supplied inline image bytes are invalid.";case"image_source_missing":return"Provide exactly one of a public image or webpage URL, inline image bytes, or an owner-scoped image artifact.";case"image_source_ambiguous":return"Provide only one image source: sourceUrl, imageBase64, or artifactId.";case"image_source_type_invalid":return"Use sourceType only with inline image bytes or an owner-scoped image artifact.";case"image_artifact_not_found":return"The image artifact was not found, expired, or does not belong to this account.";case"image_page_too_large":return"The webpage is too large for bounded Commons image discovery.";case"page_image_not_found":return"The webpage did not expose a usable featured or content image.";case"page_image_candidates_unusable":return"The webpage exposed image candidates, but none returned supported public image bytes.";case"image_format_unsupported":return"Commons accepts JPEG, PNG, GIF, or WebP image bytes.";case"image_storage_unconfigured":return"Commons image storage is temporarily unavailable.";case"featured_image_unhostable":return"The required featured image could not be hosted for Commons publication.";default:return be}}function Ie(e){let t=U(e.errorCode),r=typeof e.retryAfterSeconds=="number"&&Number.isFinite(e.retryAfterSeconds)?Math.max(1,Math.min(86400,Math.trunc(e.retryAfterSeconds))):void 0,n=e.chargeStatus==="not_charged"||e.chargeStatus==="refund_pending"||e.chargeStatus==="refunded"||e.chargeStatus==="charged"?e.chargeStatus:void 0,i=typeof e.errorType=="string"&&Re.has(e.errorType)?e.errorType:void 0,a=Oe(e.details);return{error_code:t,error_type:i??he(t),message:ye(t),retryable:e.retryable===!0,...r?{retry_after_seconds:r}:{},...n?{charge_status:n}:{},...a?{details:a}:{}}}function Z(e){return e.replace((new RegExp("https?:\\/\\/[^\\s]*(?:\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061|on\u006b\u0065\u0072\u006e\u0065\u006c|\u006b\u0065\u0072\u006e\u0065\u006c\\.sh)[^\\s]*", "gi")),"the service").replace(/bright\s*data/gi,"the service").replace((new RegExp("\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061", "gi")),"the service").replace((new RegExp("\u006b\u0065\u0072\u006e\u0065\u006c\\.sh\\s+sessions?", "gi")),"sessions").replace((new RegExp("\u006b\u0065\u0072\u006e\u0065\u006c\\.sh\\s+session", "gi")),"this session").replace((new RegExp("\u006b\u0065\u0072\u006e\u0065\u006c\\.sh", "gi")),"the service").replace((new RegExp("\u006b\u0065\u0072\u006e\u0065\u006c\\s+sessions?", "gi")),"sessions").replace((new RegExp("\u006b\u0065\u0072\u006e\u0065\u006c\\s+session", "gi")),"this session").replace(/\b(?:sub|cus|sess|proxy)_[A-Za-z0-9_-]+\b/g,"[redacted]").replace((new RegExp("\\b(?:\u004b\u0045\u0052\u004e\u0045\u004c|\u0042\u0052\u0049\u0047\u0048\u0054\u0044\u0041\u0054\u0041|\u0042\u0052\u0049\u0047\u0048\u0054_\u0044\u0041\u0054\u0041)_[A-Z0-9_]*API_KEY\\b", "g")),"BROWSER_SERVICE_API_KEY").replace((new RegExp("\\b\u006b\u0065\u0072\u006e\u0065\u006c\\b", "gi")),"the service").replace(/ +/g," ").trim()}var G=class extends Error{constructor(r){super(`CAPTCHA detected. ${r}`);this.instructions=r}instructions;name="CaptchaError"},Y=class extends Error{constructor(r,n){super(r);this.cause=n}cause;name="ExtractionError"},J=class extends Error{constructor(r){super(`Google Maps search did not reach a complete result state (${r})`);this.pageState=r}pageState;name="MapsSearchIncompletePageError"},$=class extends Error{name="RequestAbortedError";constructor(t="Request aborted before harvest completed"){super(t)}},K=class extends Error{name="PaaInteractionInterruptedError"},V=class extends Error{name="LocationMismatchError";constructor(t="Google returned results for a different location than requested"){super(t)}};var De=process.env.TURSO_DATABASE_URL??"file:./paa-api.db",Ue=process.env.TURSO_AUTH_TOKEN,h=null,ee=!1,v="2026-08-27.1",te="data-2026-07-28-site-extract-counters.1",re=["admin_credit_adjustment_events","admin_credit_adjustments","billing_authorizations","billing_credits","billing_debits","billing_debit_allocations","billing_events","browser_profile_labels","connected_account_billing","concurrency_locks","credit_lot_expirations","credit_lots","credit_lot_repairs","free_credit_refreshes","harvest_attempts","inbox_messages","jobs","kpo_jobs","kpo_phase_log","ledger","oauth_clients","oauth_codes","oauth_tokens","page_snapshots","password_reset_tokens","rate_limits","request_events","scheduled_run_view_links","serp_identities","site_audit_jobs","site_audit_phase_log","site_extract_jobs","site_extract_pages","stripe_events","users","workflow_artifacts","workflow_runs","workflow_schedules","workflow_webhook_deliveries","workshop_registrations"],ne=["admin_credit_adjustment_events_reference","admin_credit_adjustments_user_created","billing_authorizations_user_status","billing_credits_user_status","billing_debits_user_status","billing_events_authorization","billing_events_user_created_at","concurrency_locks_active_user","concurrency_locks_operation","concurrency_locks_user_status","credit_lots_user_active","credit_lot_repairs_user_applied","harvest_attempts_job_id","harvest_attempts_provider_lookup","harvest_attempts_user_created_at","inbox_messages_user_sent_at","jobs_created_at_status_user","jobs_status","jobs_user_created_at_status","jobs_user_id","kpo_jobs_status","kpo_jobs_user_id","kpo_phase_log_job_id","ledger_stripe_pi_unique","ledger_user_id","oauth_tokens_identity","page_snapshots_user_checked_at","prt_user_id","request_events_created_at","request_events_user_created_at","scheduled_run_view_links_expiry","scheduled_run_view_links_owner_run","serp_identities_user_name","site_audit_jobs_status","site_audit_jobs_user_id","site_audit_phase_log_job_id","site_extract_jobs_status","site_extract_jobs_idempotency","site_extract_jobs_user_id","site_extract_pages_job_id","workflow_artifacts_run","workflow_runs_idempotency","workflow_runs_schedule","workflow_runs_user_created","workflow_schedules_due","workflow_schedules_user_status","workflow_webhook_deliveries_run","workshop_registrations_event_status"],se=["credit_lots_bounds_insert","credit_lots_bounds_update","credit_lots_one_migration_insert","credit_lots_one_migration_update"],ve={credit_lots:["never_expires"],harvest_attempts:["debug_json","browser_provider","provider_session_id","provider_session_observed_at","provider_lookup_status","provider_status","provider_error_code","provider_error_message","provider_reason_source","provider_duration_ms","provider_bandwidth_bytes","provider_captcha","provider_checked_at","provider_detail_json","provider_disconnect_observed","provider_disconnect_message"],jobs:["public_error_json"],oauth_tokens:["replaced_by","rotated_at"],site_extract_jobs:["attempted_urls","successful_urls","failed_urls","idempotency_key","request_fingerprint","dispatch_attempts","next_dispatch_at","dispatch_error","settlement_attempts","next_settlement_at","settlement_error","public_error_json"],stripe_events:["attempt_count","claim_token","last_error","status","updated_at"],users:["balance_mc","concurrency_stripe_sub_id","concurrency_pack_quantity","extra_concurrency_slots","key_active","memory_identity","memory_key","memory_plan","memory_provisioned","memory_subscription_id","password_hash","stripe_customer_id","subscription_concurrency","subscription_id","subscription_tier"],workshop_registrations:["field_notes_email_id","reminder_48h_email_id","reminder_24h_email_id","reminder_1h_email_id"],workflow_artifacts:["content"],workflow_runs:["step_index","step_log_json","step_state_json","total_steps","webhook_url"]};function x(e){return e.map(t=>`'${t.replaceAll("'","''")}'`).join(", ")}async function X(e){let t=[`(SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name IN (${x(re)})) = ${re.length}`,`(SELECT COUNT(*) FROM sqlite_master WHERE type = 'index' AND name IN (${x(ne)})) = ${ne.length}`,`(SELECT COUNT(*) FROM sqlite_master WHERE type = 'trigger' AND name IN (${x(se)})) = ${se.length}`,...Object.entries(ve).map(([n,i])=>`(SELECT COUNT(*) FROM pragma_table_info('${n}') WHERE name IN (${x(i)})) = ${i.length}`)],r=await e.execute(`SELECT ${t.join(" AND ")} AS ready`);return Number(r.rows[0]?.ready??0)===1}async function Xe(e){await e.execute(`
1
+ import{createClient as je}from"@libsql/client/http";import{createHash as y,randomBytes as X,randomUUID as m,scryptSync as Ee,timingSafeEqual as He}from"crypto";import{z as p}from"zod";var C="2026-06-26 21:58:03";var ct="Google returned a CAPTCHA. Run with --headless=false to re-warm the browser profile, then retry.",he="This operation is temporarily unavailable. Please retry later.",xe=["request_aborted","captcha_exhausted","captcha_or_blocked","location_mismatch","proxy_tunnel_failed","proxy_unavailable","harvest_timeout","mcp_request_timeout","mcp_http_error","extraction_failed","concurrency_limit_exceeded","unauthorized","forbidden","invalid_request","rate_limited","upstream_rate_limited","insufficient_balance","service_unavailable","response_lost","vendor_unavailable","page_not_found","page_forbidden","page_rate_limited","page_server_error","page_http_error","bot_check_unresolved","page_too_large","page_unreachable","browser_session_interrupted","site_export_not_found","site_export_format_unavailable","site_export_read_failed","site_export_image_not_found","image_url_invalid","image_url_not_https","image_host_unresolvable","image_host_blocked","image_redirect_invalid","image_source_unavailable","image_too_large","image_redirect_limit","image_base64_invalid","image_source_missing","image_source_ambiguous","image_source_type_invalid","image_artifact_not_found","image_page_too_large","page_image_not_found","page_image_candidates_unusable","image_format_unsupported","image_storage_unconfigured","featured_image_unhostable"],ye=["request_aborted","captcha","location_mismatch","connection","timeout","extraction","concurrency_limit","unauthorized","forbidden","invalid_request","rate_limit","billing","service_unavailable"];function R(e){return e?JSON.stringify(e):null}function re(e){if(e==null)return null;try{let t=typeof e=="string"?JSON.parse(e):e;if(!t||typeof t!="object"||Array.isArray(t))return null;let r=t;if(typeof r.error_code!="string"||!se.has(r.error_code))return null;let s=Fe({errorCode:r.error_code,errorType:r.error_type,retryable:r.retryable,retryAfterSeconds:r.retry_after_seconds,chargeStatus:r.charge_status,details:r.details});if(typeof r.message=="string"){let i=ne(r.message).trim().slice(0,1e3);i&&!/https?:\/\//i.test(i)&&(s.message=i)}return s}catch{return null}}var se=new Set(xe),Ie=new Set(ye),Ce=new Set(["active","limit","operation","upgrade_url","topup_url","upgrade_command","slots_per_pack","pack_price_usd","balance_credits","required_credits","retry_guidance","http_status"]),Ue=12,ke=500;function F(e){return typeof e=="string"&&se.has(e)?e:"service_unavailable"}function De(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t={};for(let[r,s]of Object.entries(e)){if(Object.keys(t).length>=Ue)break;if(Ce.has(r))if(typeof s=="string"){if((r==="upgrade_url"||r==="topup_url")&&!ve(s))continue;let i=ne(s).slice(0,ke);i&&(t[r]=i)}else(typeof s=="number"&&Number.isFinite(s)||typeof s=="boolean"||s===null)&&(t[r]=s)}return Object.keys(t).length>0?t:void 0}function ve(e){if(e.startsWith("/")&&!e.startsWith("//"))return!0;try{let t=new URL(e);return t.protocol==="https:"&&(t.hostname==="mcpscraper.dev"||t.hostname.endsWith(".mcpscraper.dev"))}catch{return!1}}function Xe(e){let t=F(e);switch(t){case"captcha_exhausted":case"captcha_or_blocked":return"captcha";case"proxy_tunnel_failed":case"proxy_unavailable":case"response_lost":return"connection";case"harvest_timeout":case"mcp_request_timeout":return"timeout";case"concurrency_limit_exceeded":return"concurrency_limit";case"rate_limited":case"upstream_rate_limited":return"rate_limit";case"extraction_failed":case"page_not_found":case"page_forbidden":case"page_rate_limited":case"page_server_error":case"page_http_error":case"bot_check_unresolved":case"page_too_large":case"page_unreachable":case"browser_session_interrupted":case"site_export_not_found":case"site_export_format_unavailable":case"site_export_read_failed":case"site_export_image_not_found":return"extraction";case"image_url_invalid":case"image_url_not_https":case"image_host_unresolvable":case"image_host_blocked":case"image_redirect_invalid":case"image_source_unavailable":case"image_too_large":case"image_redirect_limit":case"image_base64_invalid":case"image_source_missing":case"image_source_ambiguous":case"image_source_type_invalid":case"image_artifact_not_found":case"image_page_too_large":case"page_image_not_found":case"page_image_candidates_unusable":case"image_format_unsupported":case"image_storage_unconfigured":case"featured_image_unhostable":return"invalid_request";case"insufficient_balance":return"billing";case"vendor_unavailable":case"mcp_http_error":return"service_unavailable";default:return t}}function Me(e){switch(F(e)){case"request_aborted":return"The request was cancelled before it completed.";case"captcha_exhausted":case"captcha_or_blocked":return"The target site returned a verification challenge. Heavy traffic can temporarily increase these challenges; retry in a few minutes.";case"location_mismatch":return"The target site returned results for a different location. Please retry.";case"proxy_tunnel_failed":case"proxy_unavailable":return"The web request could not establish a working connection. Please retry later.";case"harvest_timeout":return"The request timed out before it completed. Please retry with a smaller request.";case"mcp_request_timeout":return"The MCP caller stopped waiting before a final response arrived. Durable work may still be running; continue with the returned Task or job handle instead of restarting it.";case"concurrency_limit_exceeded":return"The service is available, but this account has reached its parallel-operation limit. Wait for an active operation to finish or add capacity.";case"unauthorized":return"Authentication is required to perform this operation.";case"forbidden":return"This account does not have permission to perform this operation.";case"invalid_request":return"The request is invalid. Check the supplied inputs and try again.";case"rate_limited":return"This account is sending requests too quickly. Wait briefly and retry.";case"upstream_rate_limited":return"The connected provider is temporarily rate-limiting requests. Wait briefly and retry.";case"mcp_http_error":return"The API returned an unexpected HTTP response.";case"insufficient_balance":return"This account does not have enough Credits for the operation.";case"extraction_failed":return"The target could not be extracted. Please retry later.";case"response_lost":return"The connection was lost before the response arrived. The operation may have already completed and been billed on our side \u2014 check credits_info before retrying blind.";case"vendor_unavailable":return"MCP Scraper's internal browser services require MCP Scraper team attention. Servers or IPs are down until this is fixed \u2014 this is not caused by your request. Please retry in a few minutes.";case"page_not_found":return"The page could not be found. It may have been moved or deleted.";case"page_forbidden":return"The site refused the request.";case"page_rate_limited":return"The site is rate-limiting requests right now. Retrying after a short wait usually works.";case"page_server_error":return"The page's own server returned an error. This is on the target site's side, not something a retry here can fix.";case"page_http_error":return"The page returned an unexpected HTTP response.";case"bot_check_unresolved":return"This site has automated-traffic protection (a bot/CAPTCHA check) that could not be resolved in time. Some sites are simply not extractable this way.";case"page_too_large":return"The page is larger than we can safely process.";case"page_unreachable":return"The page did not respond in time, or the connection could not be completed.";case"browser_session_interrupted":return"The browser session closed before extraction completed. MCP Scraper will retry once with a fresh session; retry the request if this persists.";case"site_export_not_found":return"The site export or requested page was not found, expired, or does not belong to this account.";case"site_export_format_unavailable":return"That representation was not retained for this export page. Read the export manifest and request one of the formats marked available.";case"site_export_read_failed":return"The stored site export could not be read or did not pass its integrity check.";case"site_export_image_not_found":return"The requested site-export image was not found, expired, or does not belong to this account.";case"image_url_invalid":return"The image source is not a valid URL. Use a stable public HTTPS URL or inline image bytes.";case"image_url_not_https":return"Commons image sources must use a public HTTPS URL or inline image bytes.";case"image_host_unresolvable":return"The image host could not be resolved. Use a different stable public URL or inline image bytes.";case"image_host_blocked":return"The image source resolves to a network address Commons cannot fetch safely.";case"image_redirect_invalid":return"The image source redirected to an invalid or unsafe destination.";case"image_source_unavailable":return"The image source could not be fetched. Host a different stable public URL or provide inline image bytes.";case"image_too_large":return"The image exceeds the Commons image size limit.";case"image_redirect_limit":return"The image source exceeded the Commons redirect limit.";case"image_base64_invalid":return"The supplied inline image bytes are invalid.";case"image_source_missing":return"Provide exactly one of a public image or webpage URL, inline image bytes, or an owner-scoped image artifact.";case"image_source_ambiguous":return"Provide only one image source: sourceUrl, imageBase64, or artifactId.";case"image_source_type_invalid":return"Use sourceType only with inline image bytes or an owner-scoped image artifact.";case"image_artifact_not_found":return"The image artifact was not found, expired, or does not belong to this account.";case"image_page_too_large":return"The webpage is too large for bounded Commons image discovery.";case"page_image_not_found":return"The webpage did not expose a usable featured or content image.";case"page_image_candidates_unusable":return"The webpage exposed image candidates, but none returned supported public image bytes.";case"image_format_unsupported":return"Commons accepts JPEG, PNG, GIF, or WebP image bytes.";case"image_storage_unconfigured":return"Commons image storage is temporarily unavailable.";case"featured_image_unhostable":return"The required featured image could not be hosted for Commons publication.";default:return he}}function Fe(e){let t=F(e.errorCode),r=typeof e.retryAfterSeconds=="number"&&Number.isFinite(e.retryAfterSeconds)?Math.max(1,Math.min(86400,Math.trunc(e.retryAfterSeconds))):void 0,s=e.chargeStatus==="not_charged"||e.chargeStatus==="refund_pending"||e.chargeStatus==="refunded"||e.chargeStatus==="charged"?e.chargeStatus:void 0,i=typeof e.errorType=="string"&&Ie.has(e.errorType)?e.errorType:void 0,a=De(e.details);return{error_code:t,error_type:i??Xe(t),message:Me(t),retryable:e.retryable===!0,...r?{retry_after_seconds:r}:{},...s?{charge_status:s}:{},...a?{details:a}:{}}}function ne(e){return e.replace(/https?:\/\/[^\s]*(?:brightdata|onkernel|kernel\.sh)[^\s]*/gi,"the service").replace(/bright\s*data/gi,"the service").replace(/brightdata/gi,"the service").replace(/kernel\.sh\s+sessions?/gi,"sessions").replace(/kernel\.sh\s+session/gi,"this session").replace(/kernel\.sh/gi,"the service").replace(/kernel\s+sessions?/gi,"sessions").replace(/kernel\s+session/gi,"this session").replace(/\b(?:sub|cus|sess|proxy)_[A-Za-z0-9_-]+\b/g,"[redacted]").replace(/\b(?:KERNEL|BRIGHTDATA|BRIGHT_DATA)_[A-Z0-9_]*API_KEY\b/g,"BROWSER_SERVICE_API_KEY").replace(/\bkernel\b/gi,"the service").replace(/ +/g," ").trim()}var V=class extends Error{constructor(r){super(`CAPTCHA detected. ${r}`);this.instructions=r}instructions;name="CaptchaError"},z=class extends Error{constructor(r,s){super(r);this.cause=s}cause;name="ExtractionError"},Q=class extends Error{constructor(r){super(`Google Maps search did not reach a complete result state (${r})`);this.pageState=r}pageState;name="MapsSearchIncompletePageError"},Z=class extends Error{name="RequestAbortedError";constructor(t="Request aborted before harvest completed"){super(t)}},ee=class extends Error{name="PaaInteractionInterruptedError"},te=class extends Error{name="LocationMismatchError";constructor(t="Google returned results for a different location than requested"){super(t)}};var f=["oauth_store_metadata","oauth_clients","oauth_client_redirect_uris","oauth_codes","oauth_code_exchanges","oauth_refresh_families","oauth_refresh_tokens","oauth_refresh_rotations","oauth_security_events"],O=["oauth_clients_inactivity_idx","oauth_codes_expiry_idx","oauth_code_exchanges_replay_expiry_idx","oauth_refresh_families_lifecycle_idx","oauth_refresh_families_user_status_idx","oauth_refresh_tokens_expiry_idx","oauth_refresh_rotations_replay_expiry_idx","oauth_security_events_retention_idx"],ie={oauth_clients:"oauth_clients_legacy_raw",oauth_codes:"oauth_codes_legacy_raw",oauth_tokens:"oauth_tokens_legacy_raw"},N="strftime('%Y-%m-%dT%H:%M:%fZ','now')";async function h(e,t,r=!1){try{await e.execute(t)}catch(s){let i=s.code;if(!r||i!=="SQL_PARSE_ERROR")throw s}}var P=[`CREATE TABLE IF NOT EXISTS oauth_store_metadata (
2
+ id INTEGER PRIMARY KEY CHECK (id = 1),
3
+ store_id TEXT NOT NULL UNIQUE,
4
+ schema_version INTEGER NOT NULL CHECK (schema_version > 0),
5
+ authority_epoch INTEGER NOT NULL CHECK (authority_epoch > 0),
6
+ authority_state TEXT NOT NULL CHECK (authority_state IN ('ready','authoritative','retired')),
7
+ updated_at TEXT NOT NULL DEFAULT (${N})
8
+ ) STRICT`,`CREATE TABLE IF NOT EXISTS oauth_clients (
9
+ client_id TEXT PRIMARY KEY,
10
+ client_name TEXT NOT NULL,
11
+ client_type TEXT NOT NULL CHECK (client_type = 'public'),
12
+ token_endpoint_auth_method TEXT NOT NULL CHECK (token_endpoint_auth_method = 'none'),
13
+ status TEXT NOT NULL CHECK (status IN ('active','disabled','expired')),
14
+ created_at TEXT NOT NULL DEFAULT (${N}),
15
+ last_used_at TEXT,
16
+ expires_at TEXT
17
+ ) STRICT`,`CREATE TABLE IF NOT EXISTS oauth_client_redirect_uris (
18
+ client_id TEXT NOT NULL REFERENCES oauth_clients(client_id) ON DELETE CASCADE,
19
+ redirect_uri TEXT NOT NULL,
20
+ redirect_kind TEXT NOT NULL CHECK (redirect_kind IN ('https','loopback','private_scheme')),
21
+ PRIMARY KEY (client_id, redirect_uri)
22
+ ) STRICT`,`CREATE TABLE IF NOT EXISTS oauth_codes (
23
+ code_digest BLOB PRIMARY KEY,
24
+ lookup_key_id TEXT NOT NULL,
25
+ client_id TEXT NOT NULL REFERENCES oauth_clients(client_id) ON DELETE RESTRICT,
26
+ redirect_uri TEXT NOT NULL,
27
+ code_challenge TEXT NOT NULL,
28
+ challenge_method TEXT NOT NULL CHECK (challenge_method = 'S256'),
29
+ user_id TEXT NOT NULL,
30
+ scope TEXT NOT NULL,
31
+ resource TEXT,
32
+ issued_at TEXT NOT NULL DEFAULT (${N}),
33
+ expires_at TEXT NOT NULL
34
+ ) STRICT`,`CREATE TABLE IF NOT EXISTS oauth_code_exchanges (
35
+ code_digest BLOB PRIMARY KEY,
36
+ request_fingerprint BLOB NOT NULL UNIQUE,
37
+ client_id TEXT NOT NULL,
38
+ family_id TEXT NOT NULL UNIQUE,
39
+ grant_scope TEXT NOT NULL,
40
+ grant_resource TEXT,
41
+ scope TEXT NOT NULL,
42
+ resource TEXT,
43
+ sealed_refresh BLOB NOT NULL,
44
+ sealed_nonce BLOB NOT NULL,
45
+ sealed_tag BLOB NOT NULL,
46
+ replay_key_id TEXT NOT NULL,
47
+ completed_at TEXT NOT NULL DEFAULT (${N}),
48
+ replay_expires_at TEXT NOT NULL
49
+ ) STRICT`,`CREATE TABLE IF NOT EXISTS oauth_refresh_families (
50
+ family_id TEXT PRIMARY KEY,
51
+ user_id TEXT NOT NULL,
52
+ client_id TEXT NOT NULL REFERENCES oauth_clients(client_id) ON DELETE RESTRICT,
53
+ issuer TEXT NOT NULL,
54
+ scope TEXT NOT NULL,
55
+ resource TEXT,
56
+ status TEXT NOT NULL CHECK (status IN ('active','revoked','compromised','expired')),
57
+ current_generation INTEGER NOT NULL CHECK (current_generation > 0),
58
+ created_at TEXT NOT NULL DEFAULT (${N}),
59
+ expires_at TEXT NOT NULL,
60
+ revoked_at TEXT,
61
+ compromised_at TEXT,
62
+ UNIQUE (family_id, client_id),
63
+ FOREIGN KEY (family_id, current_generation)
64
+ REFERENCES oauth_refresh_tokens(family_id, generation)
65
+ DEFERRABLE INITIALLY DEFERRED
66
+ ) STRICT`,`CREATE TABLE IF NOT EXISTS oauth_refresh_tokens (
67
+ family_id TEXT NOT NULL REFERENCES oauth_refresh_families(family_id) ON DELETE CASCADE,
68
+ generation INTEGER NOT NULL CHECK (generation > 0),
69
+ token_digest BLOB NOT NULL UNIQUE,
70
+ lookup_key_id TEXT NOT NULL,
71
+ token_prefix TEXT NOT NULL,
72
+ predecessor_generation INTEGER,
73
+ issued_at TEXT NOT NULL DEFAULT (${N}),
74
+ expires_at TEXT NOT NULL,
75
+ used_at TEXT,
76
+ revoked_at TEXT,
77
+ PRIMARY KEY (family_id, generation),
78
+ CHECK (predecessor_generation IS NULL OR (predecessor_generation > 0 AND predecessor_generation < generation))
79
+ ) STRICT`,`CREATE TABLE IF NOT EXISTS oauth_refresh_rotations (
80
+ family_id TEXT NOT NULL REFERENCES oauth_refresh_families(family_id) ON DELETE CASCADE,
81
+ predecessor_generation INTEGER NOT NULL,
82
+ request_fingerprint BLOB NOT NULL,
83
+ successor_generation INTEGER NOT NULL,
84
+ sealed_successor BLOB NOT NULL,
85
+ sealed_nonce BLOB NOT NULL,
86
+ sealed_tag BLOB NOT NULL,
87
+ replay_key_id TEXT NOT NULL,
88
+ rotated_at TEXT NOT NULL DEFAULT (${N}),
89
+ replay_expires_at TEXT NOT NULL,
90
+ PRIMARY KEY (family_id, predecessor_generation),
91
+ UNIQUE (family_id, successor_generation),
92
+ CHECK (successor_generation = predecessor_generation + 1)
93
+ ) STRICT`,`CREATE TABLE IF NOT EXISTS oauth_security_events (
94
+ event_id TEXT PRIMARY KEY,
95
+ family_id TEXT NOT NULL,
96
+ event_type TEXT NOT NULL CHECK (event_type IN ('reuse','binding_mismatch','manual_revoke','expiry')),
97
+ reason_code TEXT NOT NULL,
98
+ occurred_at TEXT NOT NULL DEFAULT (${N}),
99
+ retain_until TEXT NOT NULL
100
+ ) STRICT`,"CREATE INDEX IF NOT EXISTS oauth_clients_inactivity_idx ON oauth_clients(status, last_used_at, client_id)","CREATE INDEX IF NOT EXISTS oauth_codes_expiry_idx ON oauth_codes(expires_at, code_digest)","CREATE INDEX IF NOT EXISTS oauth_code_exchanges_replay_expiry_idx ON oauth_code_exchanges(replay_expires_at, code_digest)","CREATE INDEX IF NOT EXISTS oauth_refresh_families_lifecycle_idx ON oauth_refresh_families(status, expires_at, family_id)","CREATE INDEX IF NOT EXISTS oauth_refresh_families_user_status_idx ON oauth_refresh_families(user_id, status)","CREATE INDEX IF NOT EXISTS oauth_refresh_tokens_expiry_idx ON oauth_refresh_tokens(expires_at, family_id, generation)","CREATE INDEX IF NOT EXISTS oauth_refresh_rotations_replay_expiry_idx ON oauth_refresh_rotations(replay_expires_at, family_id, predecessor_generation)","CREATE INDEX IF NOT EXISTS oauth_security_events_retention_idx ON oauth_security_events(retain_until, event_id)"];async function Pe(e){if(await h(e,"PRAGMA foreign_keys = ON"),await h(e,"PRAGMA busy_timeout = 5000",!0),(await e.execute("SELECT name FROM pragma_table_info('oauth_codes')")).rows.some(r=>String(r.name)==="code"))throw new Error("Legacy raw OAuth tables require the explicit maintenance-mode coexistence migration");for(let r of P)await e.execute(r);await h(e,"PRAGMA optimize",!0)}async function ae(e){await h(e,"PRAGMA foreign_keys = ON"),await h(e,"PRAGMA busy_timeout = 5000",!0);let t=await e.execute("SELECT name FROM pragma_table_info('oauth_codes')");if(!t.rows.some(a=>String(a.name)==="code")){let a=t.rows.some(u=>String(u.name)==="code_digest");return await Pe(e),a?"current":"created"}if((await e.execute({sql:"SELECT name FROM sqlite_master WHERE type='table' AND name IN (?,?,?)",args:Object.values(ie)})).rows.length>0)throw new Error("Legacy OAuth archive names already exist; refusing ambiguous migration");let i=await e.transaction("write");try{for(let[a,u]of Object.entries(ie))(await i.execute({sql:"SELECT 1 present FROM sqlite_master WHERE type='table' AND name=?",args:[a]})).rows.length>0&&await i.execute({sql:`ALTER TABLE ${a} RENAME TO ${u}`,args:[]});for(let a of P)await i.execute({sql:a,args:[]});await i.commit()}finally{i.close()}return"archived_legacy"}var qe={oauth_store_metadata:["id","store_id","schema_version","authority_epoch","authority_state","updated_at"],oauth_clients:["client_id","client_name","client_type","token_endpoint_auth_method","status","created_at","last_used_at","expires_at"],oauth_client_redirect_uris:["client_id","redirect_uri","redirect_kind"],oauth_codes:["code_digest","lookup_key_id","client_id","redirect_uri","code_challenge","challenge_method","user_id","scope","resource","issued_at","expires_at"],oauth_code_exchanges:["code_digest","request_fingerprint","client_id","family_id","grant_scope","grant_resource","scope","resource","sealed_refresh","sealed_nonce","sealed_tag","replay_key_id","completed_at","replay_expires_at"],oauth_refresh_families:["family_id","user_id","client_id","issuer","scope","resource","status","current_generation","created_at","expires_at","revoked_at","compromised_at"],oauth_refresh_tokens:["family_id","generation","token_digest","lookup_key_id","token_prefix","predecessor_generation","issued_at","expires_at","used_at","revoked_at"],oauth_refresh_rotations:["family_id","predecessor_generation","request_fingerprint","successor_generation","sealed_successor","sealed_nonce","sealed_tag","replay_key_id","rotated_at","replay_expires_at"],oauth_security_events:["event_id","family_id","event_type","reason_code","occurred_at","retain_until"]},We={oauth_clients_inactivity_idx:["status","last_used_at","client_id"],oauth_codes_expiry_idx:["expires_at","code_digest"],oauth_code_exchanges_replay_expiry_idx:["replay_expires_at","code_digest"],oauth_refresh_families_lifecycle_idx:["status","expires_at","family_id"],oauth_refresh_families_user_status_idx:["user_id","status"],oauth_refresh_tokens_expiry_idx:["expires_at","family_id","generation"],oauth_refresh_rotations_replay_expiry_idx:["replay_expires_at","family_id","predecessor_generation"],oauth_security_events_retention_idx:["retain_until","event_id"]};async function oe(e){let t=await e.execute({sql:`SELECT name FROM sqlite_master WHERE type = 'table' AND name IN (${f.map(()=>"?").join(",")})`,args:[...f]}),r=await e.execute({sql:`SELECT name FROM sqlite_master WHERE type = 'index' AND name IN (${O.map(()=>"?").join(",")})`,args:[...O]}),s=new Set(t.rows.map(o=>String(o.name))),i=new Set(r.rows.map(o=>String(o.name))),a=await e.execute("PRAGMA foreign_keys"),u=[],c=o=>o.replace(/\bIF\s+NOT\s+EXISTS\b/gi,"").replace(/\s+/g," ").trim().toLowerCase();for(let o of f){if(!s.has(o))continue;let d=(await e.execute(`PRAGMA table_info('${o}')`)).rows.map(b=>String(b.name));JSON.stringify(d)!==JSON.stringify(qe[o])&&u.push(`${o}:columns`);let E=await e.execute({sql:"SELECT sql FROM sqlite_master WHERE type='table' AND name=?",args:[o]}),l=String(E.rows[0]?.sql??""),g=P.find(b=>c(b).startsWith(`create table ${o} `));(!g||c(l)!==c(g))&&u.push(`${o}:definition`)}for(let o of O){if(!i.has(o))continue;let d=(await e.execute(`PRAGMA index_info('${o}')`)).rows.map(E=>String(E.name));JSON.stringify(d)!==JSON.stringify(We[o])&&u.push(`${o}:columns`)}return{ok:f.every(o=>s.has(o))&&O.every(o=>i.has(o))&&Number(a.rows[0]?.foreign_keys??0)===1&&u.length===0,missingTables:f.filter(o=>!s.has(o)),missingIndexes:O.filter(o=>!i.has(o)),foreignKeysEnabled:Number(a.rows[0]?.foreign_keys??0)===1,problems:u}}var Be=process.env.TURSO_DATABASE_URL??"file:./paa-api.db",Ge=process.env.TURSO_AUTH_TOKEN,k=null,ue=!1,q="2026-08-27.1",ce="data-2026-07-28-site-extract-counters.1",_e=["admin_credit_adjustment_events","admin_credit_adjustments","billing_authorizations","billing_credits","billing_debits","billing_debit_allocations","billing_events","browser_profile_labels","connected_account_billing","concurrency_locks","credit_lot_expirations","credit_lots","credit_lot_repairs","free_credit_refreshes","harvest_attempts","inbox_messages","jobs","kpo_jobs","kpo_phase_log","ledger","oauth_clients","oauth_codes","oauth_tokens","page_snapshots","password_reset_tokens","rate_limits","request_events","scheduled_run_view_links","serp_identities","site_audit_jobs","site_audit_phase_log","site_extract_jobs","site_extract_pages","stripe_events","users","workflow_artifacts","workflow_runs","workflow_schedules","workflow_webhook_deliveries","workshop_registrations"],de=["admin_credit_adjustment_events_reference","admin_credit_adjustments_user_created","billing_authorizations_user_status","billing_credits_user_status","billing_debits_user_status","billing_events_authorization","billing_events_user_created_at","concurrency_locks_active_user","concurrency_locks_operation","concurrency_locks_user_status","credit_lots_user_active","credit_lot_repairs_user_applied","harvest_attempts_job_id","harvest_attempts_provider_lookup","harvest_attempts_user_created_at","inbox_messages_user_sent_at","jobs_created_at_status_user","jobs_status","jobs_user_created_at_status","jobs_user_id","kpo_jobs_status","kpo_jobs_user_id","kpo_phase_log_job_id","ledger_stripe_pi_unique","ledger_user_id","oauth_tokens_identity","page_snapshots_user_checked_at","prt_user_id","request_events_created_at","request_events_user_created_at","scheduled_run_view_links_expiry","scheduled_run_view_links_owner_run","serp_identities_user_name","site_audit_jobs_status","site_audit_jobs_user_id","site_audit_phase_log_job_id","site_extract_jobs_status","site_extract_jobs_idempotency","site_extract_jobs_user_id","site_extract_pages_job_id","workflow_artifacts_run","workflow_runs_idempotency","workflow_runs_schedule","workflow_runs_user_created","workflow_schedules_due","workflow_schedules_user_status","workflow_webhook_deliveries_run","workshop_registrations_event_status"],le=["credit_lots_bounds_insert","credit_lots_bounds_update","credit_lots_one_migration_insert","credit_lots_one_migration_update"],Ye={credit_lots:["never_expires"],harvest_attempts:["debug_json","browser_provider","provider_session_id","provider_session_observed_at","provider_lookup_status","provider_status","provider_error_code","provider_error_message","provider_reason_source","provider_duration_ms","provider_bandwidth_bytes","provider_captcha","provider_checked_at","provider_detail_json","provider_disconnect_observed","provider_disconnect_message"],jobs:["public_error_json"],oauth_tokens:["replaced_by","rotated_at"],site_extract_jobs:["attempted_urls","successful_urls","failed_urls","idempotency_key","request_fingerprint","dispatch_attempts","next_dispatch_at","dispatch_error","settlement_attempts","next_settlement_at","settlement_error","public_error_json"],stripe_events:["attempt_count","claim_token","last_error","status","updated_at"],users:["balance_mc","concurrency_stripe_sub_id","concurrency_pack_quantity","extra_concurrency_slots","key_active","memory_identity","memory_key","memory_plan","memory_provisioned","memory_subscription_id","password_hash","stripe_customer_id","subscription_concurrency","subscription_id","subscription_tier"],workshop_registrations:["field_notes_email_id","reminder_48h_email_id","reminder_24h_email_id","reminder_1h_email_id"],workflow_artifacts:["content"],workflow_runs:["step_index","step_log_json","step_state_json","total_steps","webhook_url"]};function U(e){return e.map(t=>`'${t.replaceAll("'","''")}'`).join(", ")}async function W(e){let t=[`(SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name IN (${U(_e)})) = ${_e.length}`,`(SELECT COUNT(*) FROM sqlite_master WHERE type = 'index' AND name IN (${U(de)})) = ${de.length}`,`(SELECT COUNT(*) FROM sqlite_master WHERE type = 'trigger' AND name IN (${U(le)})) = ${le.length}`,...Object.entries(Ye).map(([s,i])=>`(SELECT COUNT(*) FROM pragma_table_info('${s}') WHERE name IN (${U(i)})) = ${i.length}`)],r=await e.execute(`SELECT ${t.join(" AND ")} AS ready`);return Number(r.rows[0]?.ready??0)===1}async function Je(e){await e.execute(`
2
101
  UPDATE site_extract_jobs SET
3
102
  attempted_urls = done_urls,
4
103
  successful_urls = (
@@ -35,12 +134,12 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
35
134
  AND attempted_urls = 0
36
135
  AND successful_urls = 0
37
136
  AND failed_urls = 0
38
- `)}async function M(e){(await e.execute({sql:"SELECT 1 AS applied FROM schema_migrations WHERE version = ? LIMIT 1",args:[te]})).rows.length>0||(await Xe(e),await e.execute({sql:"INSERT OR IGNORE INTO schema_migrations (version) VALUES (?)",args:[te]}))}function s(){return h||(h=Ce({url:De,authToken:Ue})),h}function it(e){h=e}async function at(e={}){let t=s(),r;try{r=await t.execute({sql:"SELECT 1 AS applied FROM schema_migrations WHERE version = ? LIMIT 1",args:[v]})}catch(n){let i=n instanceof Error?n.message.toLowerCase():String(n).toLowerCase();if(!i.includes("no such table")||!i.includes("schema_migrations"))throw n;await t.execute(`
137
+ `)}async function j(e){(await e.execute({sql:"SELECT 1 AS applied FROM schema_migrations WHERE version = ? LIMIT 1",args:[ce]})).rows.length>0||(await Je(e),await e.execute({sql:"INSERT OR IGNORE INTO schema_migrations (version) VALUES (?)",args:[ce]}))}function n(){return k||(k=je({url:Be,authToken:Ge})),k}function Nt(e){k=e}async function bt(e=n()){if(process.env.OAUTH_MAINTENANCE_MODE!=="true")throw new Error("Secured main OAuth schema migration requires OAUTH_MAINTENANCE_MODE=true");await ae(e)}async function Lt(e=n()){return oe(e)}async function St(e={}){let t=n(),r;try{r=await t.execute({sql:"SELECT 1 AS applied FROM schema_migrations WHERE version = ? LIMIT 1",args:[q]})}catch(s){let i=s instanceof Error?s.message.toLowerCase():String(s).toLowerCase();if(!i.includes("no such table")||!i.includes("schema_migrations"))throw s;await t.execute(`
39
138
  CREATE TABLE IF NOT EXISTS schema_migrations (
40
139
  version TEXT PRIMARY KEY,
41
140
  applied_at TEXT NOT NULL DEFAULT (datetime('now'))
42
141
  )
43
- `),r={rows:[]}}if(r.rows.length>0){if(!e.verifyCurrentSchema)return;if(await X(t)){e.runDataRepairs&&await M(t);return}}if(await X(t)){await M(t),await t.execute({sql:"INSERT OR IGNORE INTO schema_migrations (version) VALUES (?)",args:[v]});return}await t.execute(`
142
+ `),r={rows:[]}}if(r.rows.length>0){if(!e.verifyCurrentSchema)return;if(await W(t)){e.runDataRepairs&&await j(t);return}}if(await W(t)){await j(t),await t.execute({sql:"INSERT OR IGNORE INTO schema_migrations (version) VALUES (?)",args:[q]});return}await t.execute(`
44
143
  CREATE TABLE IF NOT EXISTS users (
45
144
  id INTEGER PRIMARY KEY AUTOINCREMENT,
46
145
  email TEXT UNIQUE NOT NULL,
@@ -77,14 +176,14 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
77
176
  max_questions INTEGER NOT NULL,
78
177
  status TEXT NOT NULL,
79
178
  outcome TEXT,
80
- \u006b\u0065\u0072\u006e\u0065\u006c_session_id TEXT,
179
+ kernel_session_id TEXT,
81
180
  question_count INTEGER,
82
181
  duration_ms INTEGER,
83
182
  error TEXT,
84
183
  will_retry INTEGER,
85
- \u006b\u0065\u0072\u006e\u0065\u006c_delete_started INTEGER NOT NULL DEFAULT 0,
86
- \u006b\u0065\u0072\u006e\u0065\u006c_delete_succeeded INTEGER,
87
- \u006b\u0065\u0072\u006e\u0065\u006c_delete_error TEXT,
184
+ kernel_delete_started INTEGER NOT NULL DEFAULT 0,
185
+ kernel_delete_succeeded INTEGER,
186
+ kernel_delete_error TEXT,
88
187
  browser_close_succeeded INTEGER,
89
188
  browser_close_error TEXT,
90
189
  debug_json TEXT,
@@ -107,7 +206,7 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
107
206
  completed_at TEXT,
108
207
  UNIQUE(job_id, attempt_number)
109
208
  )
110
- `),await t.execute("CREATE INDEX IF NOT EXISTS harvest_attempts_job_id ON harvest_attempts(job_id)"),await t.execute("CREATE INDEX IF NOT EXISTS harvest_attempts_user_created_at ON harvest_attempts(user_id, created_at DESC)");try{await t.execute("ALTER TABLE harvest_attempts ADD COLUMN debug_json TEXT")}catch{}for(let n of["browser_provider TEXT","provider_session_id TEXT","provider_session_observed_at TEXT","provider_lookup_status TEXT","provider_status TEXT","provider_error_code TEXT","provider_error_message TEXT","provider_reason_source TEXT","provider_duration_ms INTEGER","provider_bandwidth_bytes INTEGER","provider_captcha INTEGER","provider_checked_at TEXT","provider_detail_json TEXT","provider_disconnect_observed INTEGER","provider_disconnect_message TEXT"])try{await t.execute(`ALTER TABLE harvest_attempts ADD COLUMN ${n}`)}catch{}await t.execute("CREATE INDEX IF NOT EXISTS harvest_attempts_provider_lookup ON harvest_attempts(browser_provider, provider_lookup_status, provider_checked_at)");try{await t.execute("ALTER TABLE users ADD COLUMN password_hash TEXT")}catch{}try{await t.execute("ALTER TABLE users ADD COLUMN key_active INTEGER NOT NULL DEFAULT 1")}catch{}await t.execute(`
209
+ `),await t.execute("CREATE INDEX IF NOT EXISTS harvest_attempts_job_id ON harvest_attempts(job_id)"),await t.execute("CREATE INDEX IF NOT EXISTS harvest_attempts_user_created_at ON harvest_attempts(user_id, created_at DESC)");try{await t.execute("ALTER TABLE harvest_attempts ADD COLUMN debug_json TEXT")}catch{}for(let s of["browser_provider TEXT","provider_session_id TEXT","provider_session_observed_at TEXT","provider_lookup_status TEXT","provider_status TEXT","provider_error_code TEXT","provider_error_message TEXT","provider_reason_source TEXT","provider_duration_ms INTEGER","provider_bandwidth_bytes INTEGER","provider_captcha INTEGER","provider_checked_at TEXT","provider_detail_json TEXT","provider_disconnect_observed INTEGER","provider_disconnect_message TEXT"])try{await t.execute(`ALTER TABLE harvest_attempts ADD COLUMN ${s}`)}catch{}await t.execute("CREATE INDEX IF NOT EXISTS harvest_attempts_provider_lookup ON harvest_attempts(browser_provider, provider_lookup_status, provider_checked_at)");try{await t.execute("ALTER TABLE users ADD COLUMN password_hash TEXT")}catch{}try{await t.execute("ALTER TABLE users ADD COLUMN key_active INTEGER NOT NULL DEFAULT 1")}catch{}await t.execute(`
111
210
  CREATE TABLE IF NOT EXISTS kpo_jobs (
112
211
  id TEXT PRIMARY KEY,
113
212
  user_id INTEGER NOT NULL REFERENCES users(id),
@@ -538,7 +637,7 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
538
637
  processed_at TEXT NOT NULL DEFAULT (datetime('now')),
539
638
  updated_at TEXT NOT NULL DEFAULT (datetime('now'))
540
639
  )
541
- `);for(let n of["status TEXT NOT NULL DEFAULT 'processed'","attempt_count INTEGER NOT NULL DEFAULT 1","claim_token TEXT","last_error TEXT","updated_at TEXT"])try{await t.execute(`ALTER TABLE stripe_events ADD COLUMN ${n}`)}catch{}await t.execute(`
640
+ `);for(let s of["status TEXT NOT NULL DEFAULT 'processed'","attempt_count INTEGER NOT NULL DEFAULT 1","claim_token TEXT","last_error TEXT","updated_at TEXT"])try{await t.execute(`ALTER TABLE stripe_events ADD COLUMN ${s}`)}catch{}await t.execute(`
542
641
  UPDATE stripe_events
543
642
  SET updated_at = COALESCE(updated_at, processed_at),
544
643
  status = COALESCE(status, 'processed'),
@@ -577,7 +676,7 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
577
676
  revoked INTEGER NOT NULL DEFAULT 0,
578
677
  created_at TEXT NOT NULL DEFAULT (datetime('now'))
579
678
  )
580
- `),await t.execute("CREATE INDEX IF NOT EXISTS oauth_tokens_identity ON oauth_tokens(identity)");for(let n of["replaced_by TEXT","rotated_at TEXT"])try{await t.execute(`ALTER TABLE oauth_tokens ADD COLUMN ${n}`)}catch{}await t.execute(`
679
+ `),await t.execute("CREATE INDEX IF NOT EXISTS oauth_tokens_identity ON oauth_tokens(identity)");for(let s of["replaced_by TEXT","rotated_at TEXT"])try{await t.execute(`ALTER TABLE oauth_tokens ADD COLUMN ${s}`)}catch{}await t.execute(`
581
680
  CREATE TABLE IF NOT EXISTS page_snapshots (
582
681
  user_id INTEGER NOT NULL REFERENCES users(id),
583
682
  url TEXT NOT NULL,
@@ -621,7 +720,7 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
621
720
  updated_at TEXT NOT NULL DEFAULT (datetime('now')),
622
721
  UNIQUE(event_slug, email)
623
722
  )
624
- `);for(let n of["field_notes_email_id TEXT","reminder_48h_email_id TEXT","reminder_24h_email_id TEXT","reminder_1h_email_id TEXT"])try{await t.execute(`ALTER TABLE workshop_registrations ADD COLUMN ${n}`)}catch{}if(await t.execute(`
723
+ `);for(let s of["field_notes_email_id TEXT","reminder_48h_email_id TEXT","reminder_24h_email_id TEXT","reminder_1h_email_id TEXT"])try{await t.execute(`ALTER TABLE workshop_registrations ADD COLUMN ${s}`)}catch{}if(await t.execute(`
625
724
  CREATE INDEX IF NOT EXISTS workshop_registrations_event_status
626
725
  ON workshop_registrations(event_slug, status, registered_at)
627
726
  `),await t.execute(`
@@ -638,8 +737,8 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
638
737
  id TEXT PRIMARY KEY,
639
738
  user_id INTEGER NOT NULL REFERENCES users(id),
640
739
  name TEXT NOT NULL,
641
- \u006b\u0065\u0072\u006e\u0065\u006c_profile_name TEXT NOT NULL,
642
- \u006b\u0065\u0072\u006e\u0065\u006c_proxy_id TEXT NOT NULL,
740
+ kernel_profile_name TEXT NOT NULL,
741
+ kernel_proxy_id TEXT NOT NULL,
643
742
  proxy_type TEXT NOT NULL DEFAULT 'isp',
644
743
  country TEXT NOT NULL DEFAULT 'US',
645
744
  status TEXT NOT NULL DEFAULT 'ready',
@@ -651,7 +750,7 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
651
750
  `),await t.execute(`
652
751
  CREATE UNIQUE INDEX IF NOT EXISTS serp_identities_user_name
653
752
  ON serp_identities(user_id, name)
654
- `),!await X(t))throw new Error("core schema migration finished without all required tables, indexes, and columns");await M(t),await t.execute({sql:"INSERT OR IGNORE INTO schema_migrations (version) VALUES (?)",args:[v]})}async function ot(e,t,r){await s().execute({sql:"INSERT INTO oauth_clients (client_id, redirect_uris, name) VALUES (?, ?, ?)",args:[e,JSON.stringify(t),r]})}async function ut(e){let r=(await s().execute({sql:"SELECT * FROM oauth_clients WHERE client_id = ?",args:[e]})).rows[0];if(!r)return;let n=[];try{let i=JSON.parse(String(r.redirect_uris));Array.isArray(i)&&(n=i.filter(a=>typeof a=="string"))}catch{n=[]}return{client_id:String(r.client_id),redirect_uris:n,name:r.name!=null?String(r.name):null,created_at:String(r.created_at)}}async function ct(e){await s().execute({sql:"INSERT INTO oauth_codes (code, client_id, redirect_uri, code_challenge, identity, scope, resource, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",args:[e.code,e.client_id,e.redirect_uri,e.code_challenge,e.identity,e.scope,e.resource,e.expires_at]})}async function _t(e){let t=s(),n=(await t.execute({sql:"SELECT * FROM oauth_codes WHERE code = ?",args:[e]})).rows[0];if(await t.execute({sql:"DELETE FROM oauth_codes WHERE code = ?",args:[e]}),!!n)return{code:String(n.code),client_id:String(n.client_id),redirect_uri:String(n.redirect_uri),code_challenge:String(n.code_challenge),identity:String(n.identity),scope:String(n.scope),resource:n.resource!=null?String(n.resource):null,expires_at:String(n.expires_at)}}async function Me(e){await s().execute({sql:"INSERT INTO oauth_tokens (refresh_token, client_id, identity, scope, resource, expires_at, revoked) VALUES (?, ?, ?, ?, ?, ?, 0)",args:[e.refresh_token,e.client_id,e.identity,e.scope,e.resource,e.expires_at]})}async function dt(e){let r=(await s().execute({sql:"SELECT * FROM oauth_tokens WHERE refresh_token = ?",args:[e]})).rows[0];if(r)return{refresh_token:String(r.refresh_token),client_id:String(r.client_id),identity:String(r.identity),scope:String(r.scope),resource:r.resource!=null?String(r.resource):null,expires_at:String(r.expires_at),revoked:Number(r.revoked??0),replaced_by:r.replaced_by!=null?String(r.replaced_by):null,rotated_at:r.rotated_at!=null?String(r.rotated_at):null}}async function lt(e){await s().execute({sql:"UPDATE oauth_tokens SET revoked = 1 WHERE refresh_token = ?",args:[e]})}async function Et(e,t){await Me(t),await s().execute({sql:"UPDATE oauth_tokens SET revoked = 1, replaced_by = ?, rotated_at = ? WHERE refresh_token = ?",args:[t.refresh_token,new Date().toISOString(),e]})}async function Tt(e){let t=m();if((await s().execute({sql:`INSERT INTO stripe_events
753
+ `),!await W(t))throw new Error("core schema migration finished without all required tables, indexes, and columns");await j(t),await t.execute({sql:"INSERT OR IGNORE INTO schema_migrations (version) VALUES (?)",args:[q]})}async function Rt(e,t,r){await n().execute({sql:"INSERT INTO oauth_clients (client_id, redirect_uris, name) VALUES (?, ?, ?)",args:[e,JSON.stringify(t),r]})}async function At(e){let r=(await n().execute({sql:"SELECT * FROM oauth_clients WHERE client_id = ?",args:[e]})).rows[0];if(!r)return;let s=[];try{let i=JSON.parse(String(r.redirect_uris));Array.isArray(i)&&(s=i.filter(a=>typeof a=="string"))}catch{s=[]}return{client_id:String(r.client_id),redirect_uris:s,name:r.name!=null?String(r.name):null,created_at:String(r.created_at)}}async function wt(e){await n().execute({sql:"INSERT INTO oauth_codes (code, client_id, redirect_uri, code_challenge, identity, scope, resource, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",args:[e.code,e.client_id,e.redirect_uri,e.code_challenge,e.identity,e.scope,e.resource,e.expires_at]})}async function ft(e){let t=n(),s=(await t.execute({sql:"SELECT * FROM oauth_codes WHERE code = ?",args:[e]})).rows[0];if(await t.execute({sql:"DELETE FROM oauth_codes WHERE code = ?",args:[e]}),!!s)return{code:String(s.code),client_id:String(s.client_id),redirect_uri:String(s.redirect_uri),code_challenge:String(s.code_challenge),identity:String(s.identity),scope:String(s.scope),resource:s.resource!=null?String(s.resource):null,expires_at:String(s.expires_at)}}async function $e(e){await n().execute({sql:"INSERT INTO oauth_tokens (refresh_token, client_id, identity, scope, resource, expires_at, revoked) VALUES (?, ?, ?, ?, ?, ?, 0)",args:[e.refresh_token,e.client_id,e.identity,e.scope,e.resource,e.expires_at]})}async function Ot(e){let r=(await n().execute({sql:"SELECT * FROM oauth_tokens WHERE refresh_token = ?",args:[e]})).rows[0];if(r)return{refresh_token:String(r.refresh_token),client_id:String(r.client_id),identity:String(r.identity),scope:String(r.scope),resource:r.resource!=null?String(r.resource):null,expires_at:String(r.expires_at),revoked:Number(r.revoked??0),replaced_by:r.replaced_by!=null?String(r.replaced_by):null,rotated_at:r.rotated_at!=null?String(r.rotated_at):null}}async function ht(e){await n().execute({sql:"UPDATE oauth_tokens SET revoked = 1 WHERE refresh_token = ?",args:[e]})}async function xt(e,t){await $e(t),await n().execute({sql:"UPDATE oauth_tokens SET revoked = 1, replaced_by = ?, rotated_at = ? WHERE refresh_token = ?",args:[t.refresh_token,new Date().toISOString(),e]})}async function yt(e){let t=m();if((await n().execute({sql:`INSERT INTO stripe_events
655
754
  (event_id, status, attempt_count, claim_token, last_error, processed_at, updated_at)
656
755
  VALUES (?, 'processing', 1, ?, NULL, datetime('now'), datetime('now'))
657
756
  ON CONFLICT(event_id) DO UPDATE SET
@@ -664,18 +763,18 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
664
763
  OR (
665
764
  stripe_events.status = 'processing'
666
765
  AND stripe_events.updated_at <= datetime('now', '-10 minutes')
667
- )`,args:[e,t]})).rowsAffected>0)return{state:"claimed",token:t};let n=await s().execute({sql:"SELECT status FROM stripe_events WHERE event_id = ? LIMIT 1",args:[e]});return{state:String(n.rows[0]?.status)==="processed"?"processed":"processing"}}async function pt(e,t){return(await s().execute({sql:`UPDATE stripe_events
766
+ )`,args:[e,t]})).rowsAffected>0)return{state:"claimed",token:t};let s=await n().execute({sql:"SELECT status FROM stripe_events WHERE event_id = ? LIMIT 1",args:[e]});return{state:String(s.rows[0]?.status)==="processed"?"processed":"processing"}}async function It(e,t){return(await n().execute({sql:`UPDATE stripe_events
668
767
  SET status = 'processed',
669
768
  claim_token = NULL,
670
769
  last_error = NULL,
671
770
  processed_at = datetime('now'),
672
771
  updated_at = datetime('now')
673
- WHERE event_id = ? AND status = 'processing' AND claim_token = ?`,args:[e,t]})).rowsAffected===1}async function mt(e,t,r){return(await s().execute({sql:`UPDATE stripe_events
772
+ WHERE event_id = ? AND status = 'processing' AND claim_token = ?`,args:[e,t]})).rowsAffected===1}async function Ct(e,t,r){return(await n().execute({sql:`UPDATE stripe_events
674
773
  SET status = 'failed',
675
774
  claim_token = NULL,
676
775
  last_error = ?,
677
776
  updated_at = datetime('now')
678
- WHERE event_id = ? AND status = 'processing' AND claim_token = ?`,args:[r.slice(0,500),e,t]})).rowsAffected===1}async function gt(e){return(await s().execute({sql:"SELECT 1 FROM stripe_events WHERE event_id = ? AND status = 'processed' LIMIT 1",args:[e]})).rows.length>0}function ae(){return"sk_"+C(24).toString("hex")}function oe(e){let t=C(16).toString("hex"),r=ie(e,t,64);return`${t}:${r.toString("hex")}`}function Nt(e,t){let[r,n]=t.split(":"),i=Buffer.from(n,"hex"),a=ie(e,r,64);return ke(i,a)}function N(e){return{id:Number(e.id),email:String(e.email),name:e.name!=null?String(e.name):null,api_key:String(e.api_key),key_active:Number(e.key_active??1),password_hash:e.password_hash!=null?String(e.password_hash):null,created_at:String(e.created_at),active:Number(e.active),stripe_customer_id:e.stripe_customer_id!=null?String(e.stripe_customer_id):null,balance_mc:Number(e.balance_mc??0),extra_concurrency_slots:Number(e.extra_concurrency_slots??0),concurrency_stripe_sub_id:e.concurrency_stripe_sub_id!=null?String(e.concurrency_stripe_sub_id):null,concurrency_pack_quantity:Number(e.concurrency_pack_quantity??0),subscription_concurrency:Number(e.subscription_concurrency??0),subscription_tier:e.subscription_tier!=null?String(e.subscription_tier):null,subscription_id:e.subscription_id!=null?String(e.subscription_id):null,memory_plan:e.memory_plan!=null?String(e.memory_plan):"free",memory_subscription_id:e.memory_subscription_id!=null?String(e.memory_subscription_id):null,memory_provisioned:Number(e.memory_provisioned??0)}}async function bt(e){let t=await s().execute({sql:"SELECT * FROM users WHERE email = ? AND active = 1",args:[e]});return t.rows[0]?N(t.rows[0]):void 0}async function Lt(e){let t=await s().execute({sql:"SELECT * FROM users WHERE api_key = ? AND active = 1 AND key_active = 1",args:[e]});return t.rows[0]?N(t.rows[0]):void 0}async function St(e){let t=await s().execute({sql:"SELECT * FROM users WHERE id = ? AND active = 1",args:[e]});return t.rows[0]?N(t.rows[0]):void 0}async function Rt(e){let r=(await s().execute({sql:"SELECT memory_key, memory_identity FROM users WHERE id = ?",args:[e]})).rows[0];return{memory_key:r?.memory_key!=null?String(r.memory_key):null,memory_identity:r?.memory_identity!=null?String(r.memory_identity):null}}async function wt(e,t,r){await s().execute({sql:"UPDATE users SET memory_key = ?, memory_identity = ? WHERE id = ?",args:[t,r,e]})}async function At(e,t){await s().execute({sql:"UPDATE users SET password_hash = ? WHERE id = ?",args:[oe(t),e]})}async function ft(e){let t=s(),[r,n,i,a,o]=await Promise.all([t.execute({sql:"SELECT COUNT(*) as n FROM jobs WHERE user_id = ?",args:[e]}),t.execute({sql:"SELECT COUNT(*) as n FROM jobs WHERE user_id = ? AND status = 'done'",args:[e]}),t.execute({sql:"SELECT COUNT(*) as n FROM jobs WHERE user_id = ? AND status = 'failed'",args:[e]}),t.execute({sql:"SELECT COALESCE(SUM(json_extract(result, '$.totalQuestions')), 0) as n FROM jobs WHERE user_id = ? AND status = 'done'",args:[e]}),t.execute({sql:"SELECT MAX(created_at) as t FROM jobs WHERE user_id = ?",args:[e]})]);return{total:Number(r.rows[0]?.n??0),done:Number(n.rows[0]?.n??0),failed:Number(i.rows[0]?.n??0),totalQuestions:Number(a.rows[0]?.n??0),lastUsed:o.rows[0]?.t!=null?String(o.rows[0].t):null}}async function Ot(e,t,r,n){let i=s(),a=ae(),o=r??C(6).toString("hex"),u=oe(o);return{id:(await i.execute({sql:"INSERT INTO users (email, name, api_key, password_hash, stripe_customer_id) VALUES (?, ?, ?, ?, ?)",args:[e,t??null,a,u,n??null]})).lastInsertRowid,email:e,name:t,api_key:a,password:o}}async function xt(e,t,r,n){let i=Math.floor(Date.now()/1e3),a=Math.floor(i/n)*n,o=A("sha256").update(t).digest("hex"),u=s();ee||(await u.execute(`
777
+ WHERE event_id = ? AND status = 'processing' AND claim_token = ?`,args:[r.slice(0,500),e,t]})).rowsAffected===1}async function Ut(e){return(await n().execute({sql:"SELECT 1 FROM stripe_events WHERE event_id = ? AND status = 'processed' LIMIT 1",args:[e]})).rows.length>0}function Te(){return"sk_"+X(24).toString("hex")}function pe(e){let t=X(16).toString("hex"),r=Ee(e,t,64);return`${t}:${r.toString("hex")}`}function kt(e,t){let[r,s]=t.split(":"),i=Buffer.from(s,"hex"),a=Ee(e,r,64);return He(i,a)}function L(e){return{id:Number(e.id),email:String(e.email),name:e.name!=null?String(e.name):null,api_key:String(e.api_key),key_active:Number(e.key_active??1),password_hash:e.password_hash!=null?String(e.password_hash):null,created_at:String(e.created_at),active:Number(e.active),stripe_customer_id:e.stripe_customer_id!=null?String(e.stripe_customer_id):null,balance_mc:Number(e.balance_mc??0),extra_concurrency_slots:Number(e.extra_concurrency_slots??0),concurrency_stripe_sub_id:e.concurrency_stripe_sub_id!=null?String(e.concurrency_stripe_sub_id):null,concurrency_pack_quantity:Number(e.concurrency_pack_quantity??0),subscription_concurrency:Number(e.subscription_concurrency??0),subscription_tier:e.subscription_tier!=null?String(e.subscription_tier):null,subscription_id:e.subscription_id!=null?String(e.subscription_id):null,memory_plan:e.memory_plan!=null?String(e.memory_plan):"free",memory_subscription_id:e.memory_subscription_id!=null?String(e.memory_subscription_id):null,memory_provisioned:Number(e.memory_provisioned??0)}}async function Dt(e){let t=await n().execute({sql:"SELECT * FROM users WHERE email = ? AND active = 1",args:[e]});return t.rows[0]?L(t.rows[0]):void 0}async function vt(e){let t=await n().execute({sql:"SELECT * FROM users WHERE api_key = ? AND active = 1 AND key_active = 1",args:[e]});return t.rows[0]?L(t.rows[0]):void 0}async function Xt(e){let t=await n().execute({sql:"SELECT * FROM users WHERE id = ? AND active = 1",args:[e]});return t.rows[0]?L(t.rows[0]):void 0}async function Mt(e){let r=(await n().execute({sql:"SELECT memory_key, memory_identity FROM users WHERE id = ?",args:[e]})).rows[0];return{memory_key:r?.memory_key!=null?String(r.memory_key):null,memory_identity:r?.memory_identity!=null?String(r.memory_identity):null}}async function Ft(e,t,r){await n().execute({sql:"UPDATE users SET memory_key = ?, memory_identity = ? WHERE id = ?",args:[t,r,e]})}async function Pt(e,t){await n().execute({sql:"UPDATE users SET password_hash = ? WHERE id = ?",args:[pe(t),e]})}async function qt(e){let t=n(),[r,s,i,a,u]=await Promise.all([t.execute({sql:"SELECT COUNT(*) as n FROM jobs WHERE user_id = ?",args:[e]}),t.execute({sql:"SELECT COUNT(*) as n FROM jobs WHERE user_id = ? AND status = 'done'",args:[e]}),t.execute({sql:"SELECT COUNT(*) as n FROM jobs WHERE user_id = ? AND status = 'failed'",args:[e]}),t.execute({sql:"SELECT COALESCE(SUM(json_extract(result, '$.totalQuestions')), 0) as n FROM jobs WHERE user_id = ? AND status = 'done'",args:[e]}),t.execute({sql:"SELECT MAX(created_at) as t FROM jobs WHERE user_id = ?",args:[e]})]);return{total:Number(r.rows[0]?.n??0),done:Number(s.rows[0]?.n??0),failed:Number(i.rows[0]?.n??0),totalQuestions:Number(a.rows[0]?.n??0),lastUsed:u.rows[0]?.t!=null?String(u.rows[0].t):null}}async function Wt(e,t,r,s){let i=n(),a=Te(),u=r??X(6).toString("hex"),c=pe(u);return{id:(await i.execute({sql:"INSERT INTO users (email, name, api_key, password_hash, stripe_customer_id) VALUES (?, ?, ?, ?, ?)",args:[e,t??null,a,c,s??null]})).lastInsertRowid,email:e,name:t,api_key:a,password:u}}async function jt(e,t,r,s){let i=Math.floor(Date.now()/1e3),a=Math.floor(i/s)*s,u=y("sha256").update(t).digest("hex"),c=n();ue||(await c.execute(`
679
778
  CREATE TABLE IF NOT EXISTS rate_limits (
680
779
  scope TEXT NOT NULL,
681
780
  key_hash TEXT NOT NULL,
@@ -684,20 +783,20 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
684
783
  updated_at TEXT NOT NULL DEFAULT (datetime('now')),
685
784
  PRIMARY KEY (scope, key_hash, window_start)
686
785
  )
687
- `),ee=!0),await u.execute({sql:`
786
+ `),ue=!0),await c.execute({sql:`
688
787
  INSERT INTO rate_limits (scope, key_hash, window_start, count)
689
788
  VALUES (?, ?, ?, 1)
690
789
  ON CONFLICT(scope, key_hash, window_start)
691
790
  DO UPDATE SET count = count + 1, updated_at = datetime('now')
692
- `,args:[e,o,a]});let _=await u.execute({sql:"SELECT count FROM rate_limits WHERE scope = ? AND key_hash = ? AND window_start = ?",args:[e,o,a]}),c=Number(_.rows[0]?.count??1);return{allowed:c<=r,count:c,remaining:Math.max(0,r-c),resetSeconds:Math.max(1,a+n-i)}}async function ht(e){let t=C(32).toString("hex"),r=A("sha256").update(t).digest("hex"),n=new Date(Date.now()+3600*1e3).toISOString();return await s().execute({sql:"INSERT INTO password_reset_tokens (token, user_id, expires_at) VALUES (?, ?, ?)",args:[r,e,n]}),t}async function yt(e){let t=s(),r=A("sha256").update(e).digest("hex"),i=(await t.execute({sql:"SELECT user_id, expires_at, used FROM password_reset_tokens WHERE token = ?",args:[r]})).rows[0];return!i||Number(i.used)||new Date(String(i.expires_at))<new Date?null:(await t.execute({sql:"UPDATE password_reset_tokens SET used = 1 WHERE token = ?",args:[r]}),Number(i.user_id))}async function It(e){let t=ae();return await s().execute({sql:"UPDATE users SET api_key = ?, key_active = 1 WHERE id = ?",args:[t,e]}),t}async function Ct(e){await s().execute({sql:"UPDATE users SET key_active = 0 WHERE id = ?",args:[e]})}async function kt(){return(await s().execute("SELECT id, email, name, created_at, active FROM users ORDER BY created_at DESC")).rows.map(t=>N({...t,api_key:"",key_active:1}))}async function Dt(e){await s().execute({sql:"UPDATE users SET active = 0 WHERE id = ?",args:[e]})}function S(e){return{id:String(e.id),user_id:Number(e.user_id),status:String(e.status),query:String(e.query),options:String(e.options),callback_url:e.callback_url!=null?String(e.callback_url):null,result:e.result!=null?String(e.result):null,error:e.error!=null?String(e.error):null,public_error_json:e.public_error_json!=null?String(e.public_error_json):null,created_at:String(e.created_at),started_at:e.started_at!=null?String(e.started_at):null,completed_at:e.completed_at!=null?String(e.completed_at):null}}function w(e){return e==null?null:Number(e)===1}function y(e){if(e==null)return null;try{return JSON.parse(String(e))}catch{return null}}function ue(e){return{id:String(e.id),job_id:String(e.job_id),user_id:Number(e.user_id),attempt_number:Number(e.attempt_number),max_attempts:Number(e.max_attempts),query:String(e.query),location:e.location!=null?String(e.location):null,max_questions:Number(e.max_questions),status:String(e.status),outcome:e.outcome!=null?String(e.outcome):null,\u006b\u0065\u0072\u006e\u0065\u006c_session_id:e.\u006b\u0065\u0072\u006e\u0065\u006c_session_id!=null?String(e.\u006b\u0065\u0072\u006e\u0065\u006c_session_id):null,question_count:e.question_count!=null?Number(e.question_count):null,duration_ms:e.duration_ms!=null?Number(e.duration_ms):null,error:e.error!=null?String(e.error):null,will_retry:w(e.will_retry),\u006b\u0065\u0072\u006e\u0065\u006c_delete_started:Number(e.\u006b\u0065\u0072\u006e\u0065\u006c_delete_started??0)===1,\u006b\u0065\u0072\u006e\u0065\u006c_delete_succeeded:w(e.\u006b\u0065\u0072\u006e\u0065\u006c_delete_succeeded),\u006b\u0065\u0072\u006e\u0065\u006c_delete_error:e.\u006b\u0065\u0072\u006e\u0065\u006c_delete_error!=null?String(e.\u006b\u0065\u0072\u006e\u0065\u006c_delete_error):null,browser_close_succeeded:w(e.browser_close_succeeded),browser_close_error:e.browser_close_error!=null?String(e.browser_close_error):null,browser_provider:e.browser_provider!=null?String(e.browser_provider):null,provider_session_id:e.provider_session_id!=null?String(e.provider_session_id):null,provider_session_observed_at:e.provider_session_observed_at!=null?String(e.provider_session_observed_at):null,provider_lookup_status:e.provider_lookup_status!=null?String(e.provider_lookup_status):null,provider_status:e.provider_status!=null?String(e.provider_status):null,provider_error_code:e.provider_error_code!=null?String(e.provider_error_code):null,provider_error_message:e.provider_error_message!=null?String(e.provider_error_message):null,provider_reason_source:e.provider_reason_source!=null?String(e.provider_reason_source):null,provider_duration_ms:e.provider_duration_ms!=null?Number(e.provider_duration_ms):null,provider_bandwidth_bytes:e.provider_bandwidth_bytes!=null?Number(e.provider_bandwidth_bytes):null,provider_captcha:w(e.provider_captcha),provider_checked_at:e.provider_checked_at!=null?String(e.provider_checked_at):null,provider_detail:y(e.provider_detail_json),provider_disconnect_observed:w(e.provider_disconnect_observed),provider_disconnect_message:e.provider_disconnect_message!=null?String(e.provider_disconnect_message):null,debug:y(e.debug_json),created_at:String(e.created_at),completed_at:e.completed_at!=null?String(e.completed_at):null}}function f(e){let{public_error_json:t,...r}=e;return{...r,options:JSON.parse(e.options),result:e.result?JSON.parse(e.result):null,publicError:z(t)}}async function Ut(e,t,r,n){let i=m();return await Pe(i,e,t,r,n),i}async function Pe(e,t,r,n,i){if(!/^[a-zA-Z0-9-]{1,100}$/.test(e))throw new Error("job id is invalid");await s().execute({sql:"INSERT INTO jobs (id, user_id, query, options, callback_url) VALUES (?, ?, ?, ?, ?)",args:[e,t,r,JSON.stringify(n),i??null]})}async function vt(e,t,r){let n=m();return await s().execute({sql:"INSERT INTO jobs (id, user_id, query, options, status, started_at) VALUES (?, ?, ?, ?, 'running', datetime('now'))",args:[n,e,t,JSON.stringify(r)]}),n}async function Xt(e,t,r,n){let i=await s().execute({sql:`INSERT INTO jobs (id, user_id, query, options, status, started_at)
791
+ `,args:[e,u,a]});let o=await c.execute({sql:"SELECT count FROM rate_limits WHERE scope = ? AND key_hash = ? AND window_start = ?",args:[e,u,a]}),_=Number(o.rows[0]?.count??1);return{allowed:_<=r,count:_,remaining:Math.max(0,r-_),resetSeconds:Math.max(1,a+s-i)}}async function Ht(e){let t=X(32).toString("hex"),r=y("sha256").update(t).digest("hex"),s=new Date(Date.now()+3600*1e3).toISOString();return await n().execute({sql:"INSERT INTO password_reset_tokens (token, user_id, expires_at) VALUES (?, ?, ?)",args:[r,e,s]}),t}async function Bt(e){let t=n(),r=y("sha256").update(e).digest("hex"),i=(await t.execute({sql:"SELECT user_id, expires_at, used FROM password_reset_tokens WHERE token = ?",args:[r]})).rows[0];return!i||Number(i.used)||new Date(String(i.expires_at))<new Date?null:(await t.execute({sql:"UPDATE password_reset_tokens SET used = 1 WHERE token = ?",args:[r]}),Number(i.user_id))}async function Gt(e){let t=Te();return await n().execute({sql:"UPDATE users SET api_key = ?, key_active = 1 WHERE id = ?",args:[t,e]}),t}async function Yt(e){await n().execute({sql:"UPDATE users SET key_active = 0 WHERE id = ?",args:[e]})}async function Jt(){return(await n().execute("SELECT id, email, name, created_at, active FROM users ORDER BY created_at DESC")).rows.map(t=>L({...t,api_key:"",key_active:1}))}async function $t(e){await n().execute({sql:"UPDATE users SET active = 0 WHERE id = ?",args:[e]})}function A(e){return{id:String(e.id),user_id:Number(e.user_id),status:String(e.status),query:String(e.query),options:String(e.options),callback_url:e.callback_url!=null?String(e.callback_url):null,result:e.result!=null?String(e.result):null,error:e.error!=null?String(e.error):null,public_error_json:e.public_error_json!=null?String(e.public_error_json):null,created_at:String(e.created_at),started_at:e.started_at!=null?String(e.started_at):null,completed_at:e.completed_at!=null?String(e.completed_at):null}}function x(e){return e==null?null:Number(e)===1}function D(e){if(e==null)return null;try{return JSON.parse(String(e))}catch{return null}}function me(e){return{id:String(e.id),job_id:String(e.job_id),user_id:Number(e.user_id),attempt_number:Number(e.attempt_number),max_attempts:Number(e.max_attempts),query:String(e.query),location:e.location!=null?String(e.location):null,max_questions:Number(e.max_questions),status:String(e.status),outcome:e.outcome!=null?String(e.outcome):null,kernel_session_id:e.kernel_session_id!=null?String(e.kernel_session_id):null,question_count:e.question_count!=null?Number(e.question_count):null,duration_ms:e.duration_ms!=null?Number(e.duration_ms):null,error:e.error!=null?String(e.error):null,will_retry:x(e.will_retry),kernel_delete_started:Number(e.kernel_delete_started??0)===1,kernel_delete_succeeded:x(e.kernel_delete_succeeded),kernel_delete_error:e.kernel_delete_error!=null?String(e.kernel_delete_error):null,browser_close_succeeded:x(e.browser_close_succeeded),browser_close_error:e.browser_close_error!=null?String(e.browser_close_error):null,browser_provider:e.browser_provider!=null?String(e.browser_provider):null,provider_session_id:e.provider_session_id!=null?String(e.provider_session_id):null,provider_session_observed_at:e.provider_session_observed_at!=null?String(e.provider_session_observed_at):null,provider_lookup_status:e.provider_lookup_status!=null?String(e.provider_lookup_status):null,provider_status:e.provider_status!=null?String(e.provider_status):null,provider_error_code:e.provider_error_code!=null?String(e.provider_error_code):null,provider_error_message:e.provider_error_message!=null?String(e.provider_error_message):null,provider_reason_source:e.provider_reason_source!=null?String(e.provider_reason_source):null,provider_duration_ms:e.provider_duration_ms!=null?Number(e.provider_duration_ms):null,provider_bandwidth_bytes:e.provider_bandwidth_bytes!=null?Number(e.provider_bandwidth_bytes):null,provider_captcha:x(e.provider_captcha),provider_checked_at:e.provider_checked_at!=null?String(e.provider_checked_at):null,provider_detail:D(e.provider_detail_json),provider_disconnect_observed:x(e.provider_disconnect_observed),provider_disconnect_message:e.provider_disconnect_message!=null?String(e.provider_disconnect_message):null,debug:D(e.debug_json),created_at:String(e.created_at),completed_at:e.completed_at!=null?String(e.completed_at):null}}function I(e){let{public_error_json:t,...r}=e;return{...r,options:JSON.parse(e.options),result:e.result?JSON.parse(e.result):null,publicError:re(t)}}async function Kt(e,t,r,s){let i=m();return await Ke(i,e,t,r,s),i}async function Ke(e,t,r,s,i){if(!/^[a-zA-Z0-9-]{1,100}$/.test(e))throw new Error("job id is invalid");await n().execute({sql:"INSERT INTO jobs (id, user_id, query, options, callback_url) VALUES (?, ?, ?, ?, ?)",args:[e,t,r,JSON.stringify(s),i??null]})}async function Vt(e,t,r){let s=m();return await n().execute({sql:"INSERT INTO jobs (id, user_id, query, options, status, started_at) VALUES (?, ?, ?, ?, 'running', datetime('now'))",args:[s,e,t,JSON.stringify(r)]}),s}async function zt(e,t,r,s){let i=await n().execute({sql:`INSERT INTO jobs (id, user_id, query, options, status, started_at)
693
792
  VALUES (?, ?, ?, ?, 'running', datetime('now'))
694
- ON CONFLICT(id) DO NOTHING`,args:[e,t,r,JSON.stringify(n)]}),a=await _e(e,t);if(!a)throw new Error(`getOrCreateRunningJob: row missing immediately after insert/lookup for ${e}`);return{job:a,created:i.rowsAffected===1}}async function Mt(e){await s().execute({sql:`
793
+ ON CONFLICT(id) DO NOTHING`,args:[e,t,r,JSON.stringify(s)]}),a=await Ne(e,t);if(!a)throw new Error(`getOrCreateRunningJob: row missing immediately after insert/lookup for ${e}`);return{job:a,created:i.rowsAffected===1}}async function Qt(e){await n().execute({sql:`
695
794
  INSERT INTO harvest_attempts (
696
795
  id, job_id, user_id, attempt_number, max_attempts, query, location, max_questions, status, created_at
697
796
  )
698
797
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'running', ?)
699
798
  ON CONFLICT(job_id, attempt_number) DO NOTHING
700
- `,args:[m(),e.jobId,e.userId,e.attemptNumber,e.maxAttempts,e.query,e.location,e.maxQuestions,e.startedAt]})}async function Pt(e){return(await s().execute({sql:`
799
+ `,args:[m(),e.jobId,e.userId,e.attemptNumber,e.maxAttempts,e.query,e.location,e.maxQuestions,e.startedAt]})}async function Zt(e){return(await n().execute({sql:`
701
800
  UPDATE harvest_attempts SET
702
801
  browser_provider = ?,
703
802
  provider_session_id = ?,
@@ -707,7 +806,7 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
707
806
  ELSE 'pending'
708
807
  END
709
808
  WHERE job_id = ? AND attempt_number = ? AND status = 'running'
710
- `,args:[e.browserProvider,e.providerSessionId,e.observedAt,e.jobId,e.attemptNumber]})).rowsAffected===1}async function Ft(e,t,r=new Date().toISOString()){return(await s().execute({sql:`
809
+ `,args:[e.browserProvider,e.providerSessionId,e.observedAt,e.jobId,e.attemptNumber]})).rowsAffected===1}async function er(e,t,r=new Date().toISOString()){return(await n().execute({sql:`
711
810
  UPDATE harvest_attempts SET
712
811
  status = 'finished',
713
812
  outcome = COALESCE(outcome, 'timeout'),
@@ -720,18 +819,18 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
720
819
  provider_reason_source = COALESCE(provider_reason_source, 'client_runtime'),
721
820
  completed_at = COALESCE(completed_at, ?)
722
821
  WHERE job_id = ? AND status = 'running'
723
- `,args:[r,t?1:0,r,e]})).rowsAffected}async function jt(e){await s().execute({sql:`
822
+ `,args:[r,t?1:0,r,e]})).rowsAffected}async function tr(e){await n().execute({sql:`
724
823
  UPDATE harvest_attempts SET
725
824
  status = 'finished',
726
825
  outcome = ?,
727
- \u006b\u0065\u0072\u006e\u0065\u006c_session_id = ?,
826
+ kernel_session_id = ?,
728
827
  question_count = ?,
729
828
  duration_ms = ?,
730
829
  error = ?,
731
830
  will_retry = ?,
732
- \u006b\u0065\u0072\u006e\u0065\u006c_delete_started = ?,
733
- \u006b\u0065\u0072\u006e\u0065\u006c_delete_succeeded = ?,
734
- \u006b\u0065\u0072\u006e\u0065\u006c_delete_error = ?,
831
+ kernel_delete_started = ?,
832
+ kernel_delete_succeeded = ?,
833
+ kernel_delete_error = ?,
735
834
  browser_close_succeeded = ?,
736
835
  browser_close_error = ?,
737
836
  browser_provider = COALESCE(browser_provider, ?),
@@ -763,7 +862,7 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
763
862
  debug_json = ?,
764
863
  completed_at = ?
765
864
  WHERE job_id = ? AND attempt_number = ?
766
- `,args:[e.outcome,e.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,e.questionCount,e.durationMs,e.error,e.willRetry?1:0,e.\u006b\u0065\u0072\u006e\u0065\u006cDeleteStarted?1:0,e.\u006b\u0065\u0072\u006e\u0065\u006cDeleteSucceeded==null?null:e.\u006b\u0065\u0072\u006e\u0065\u006cDeleteSucceeded?1:0,e.\u006b\u0065\u0072\u006e\u0065\u006cDeleteError,e.browserCloseSucceeded==null?null:e.browserCloseSucceeded?1:0,e.browserCloseError,e.browserProvider??null,e.providerSessionId??null,e.providerLookupStatus??null,e.providerStatus??null,e.providerErrorCode??null,e.providerErrorMessage??null,e.providerReasonSource??null,e.providerDurationMs??null,e.providerBandwidthBytes??null,e.providerCaptcha==null?null:e.providerCaptcha?1:0,e.providerCheckedAt??null,e.providerDetail==null?null:ce(e.providerDetail),e.providerDisconnectObserved==null?null:e.providerDisconnectObserved?1:0,e.providerDisconnectMessage??null,e.debug==null?null:JSON.stringify(e.debug),e.completedAt,e.jobId,e.attemptNumber]})}function ce(e,t=4096){let r=JSON.stringify(e);return r.length<=t?r:JSON.stringify({truncated:!0})}async function Wt(e){return(await s().execute({sql:`
865
+ `,args:[e.outcome,e.kernelSessionId,e.questionCount,e.durationMs,e.error,e.willRetry?1:0,e.kernelDeleteStarted?1:0,e.kernelDeleteSucceeded==null?null:e.kernelDeleteSucceeded?1:0,e.kernelDeleteError,e.browserCloseSucceeded==null?null:e.browserCloseSucceeded?1:0,e.browserCloseError,e.browserProvider??null,e.providerSessionId??null,e.providerLookupStatus??null,e.providerStatus??null,e.providerErrorCode??null,e.providerErrorMessage??null,e.providerReasonSource??null,e.providerDurationMs??null,e.providerBandwidthBytes??null,e.providerCaptcha==null?null:e.providerCaptcha?1:0,e.providerCheckedAt??null,e.providerDetail==null?null:ge(e.providerDetail),e.providerDisconnectObserved==null?null:e.providerDisconnectObserved?1:0,e.providerDisconnectMessage??null,e.debug==null?null:JSON.stringify(e.debug),e.completedAt,e.jobId,e.attemptNumber]})}function ge(e,t=4096){let r=JSON.stringify(e);return r.length<=t?r:JSON.stringify({truncated:!0})}async function rr(e){return(await n().execute({sql:`
767
866
  UPDATE harvest_attempts SET
768
867
  provider_lookup_status = ?,
769
868
  provider_status = ?,
@@ -778,23 +877,23 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
778
877
  WHERE id = ?
779
878
  AND job_id = ?
780
879
  AND user_id = ?
781
- AND browser_provider = '\u0062\u0072\u0069\u0067\u0068\u0074_\u0064\u0061\u0074\u0061_browser_api'
880
+ AND browser_provider = 'bright_data_browser_api'
782
881
  AND provider_session_id = ?
783
882
  AND COALESCE(provider_lookup_status, '') <> 'complete'
784
- `,args:[e.lookupStatus,e.providerStatus??null,e.errorCode??null,e.errorMessage??null,e.reasonSource??null,e.durationMs??null,e.bandwidthBytes??null,e.captcha==null?null:e.captcha?1:0,e.checkedAt,e.detail==null?null:ce(e.detail),e.attemptId,e.jobId,e.userId,e.providerSessionId]})).rowsAffected===1}async function qt(e=25){let t=Math.max(1,Math.min(100,Math.trunc(e)));return(await s().execute({sql:`
883
+ `,args:[e.lookupStatus,e.providerStatus??null,e.errorCode??null,e.errorMessage??null,e.reasonSource??null,e.durationMs??null,e.bandwidthBytes??null,e.captcha==null?null:e.captcha?1:0,e.checkedAt,e.detail==null?null:ge(e.detail),e.attemptId,e.jobId,e.userId,e.providerSessionId]})).rowsAffected===1}async function sr(e=25){let t=Math.max(1,Math.min(100,Math.trunc(e)));return(await n().execute({sql:`
785
884
  SELECT * FROM harvest_attempts
786
- WHERE browser_provider = '\u0062\u0072\u0069\u0067\u0068\u0074_\u0064\u0061\u0074\u0061_browser_api'
885
+ WHERE browser_provider = 'bright_data_browser_api'
787
886
  AND provider_session_id IS NOT NULL
788
887
  AND provider_lookup_status IN ('pending', 'temporary_error')
789
888
  ORDER BY COALESCE(provider_checked_at, created_at) ASC
790
889
  LIMIT ?
791
- `,args:[t]})).rows.map(n=>ue(n))}async function Ht(e,t){return(t==null?await s().execute({sql:"SELECT * FROM harvest_attempts WHERE job_id = ? ORDER BY attempt_number ASC",args:[e]}):await s().execute({sql:`
890
+ `,args:[t]})).rows.map(s=>me(s))}async function nr(e,t){return(t==null?await n().execute({sql:"SELECT * FROM harvest_attempts WHERE job_id = ? ORDER BY attempt_number ASC",args:[e]}):await n().execute({sql:`
792
891
  SELECT ha.*
793
892
  FROM harvest_attempts ha
794
893
  INNER JOIN jobs j ON j.id = ha.job_id
795
894
  WHERE ha.job_id = ? AND j.user_id = ?
796
895
  ORDER BY ha.attempt_number ASC
797
- `,args:[e,t]})).rows.map(n=>ue(n))}async function _e(e,t){let r=s(),n=t?await r.execute({sql:"SELECT * FROM jobs WHERE id = ? AND user_id = ?",args:[e,t]}):await r.execute({sql:"SELECT * FROM jobs WHERE id = ?",args:[e]});return n.rows[0]?f(S(n.rows[0])):void 0}async function Bt(e){return(await s().execute({sql:"SELECT * FROM jobs WHERE user_id = ? ORDER BY created_at DESC LIMIT 50",args:[e]})).rows.map(r=>f(S(r)))}async function Gt(e,t){let n=(await s().execute({sql:"SELECT content_hash, content, title, content_bytes, truncated, checked_at FROM page_snapshots WHERE user_id = ? AND url = ?",args:[e,t]})).rows[0];return n?{contentHash:String(n.content_hash),content:String(n.content),title:n.title==null?null:String(n.title),contentBytes:Number(n.content_bytes),truncated:Number(n.truncated)===1,checkedAt:String(n.checked_at)}:null}async function Yt(e,t,r){await s().execute({sql:`
896
+ `,args:[e,t]})).rows.map(s=>me(s))}async function Ne(e,t){let r=n(),s=t?await r.execute({sql:"SELECT * FROM jobs WHERE id = ? AND user_id = ?",args:[e,t]}):await r.execute({sql:"SELECT * FROM jobs WHERE id = ?",args:[e]});return s.rows[0]?I(A(s.rows[0])):void 0}async function ir(e){return(await n().execute({sql:"SELECT * FROM jobs WHERE user_id = ? ORDER BY created_at DESC LIMIT 50",args:[e]})).rows.map(r=>I(A(r)))}async function ar(e,t){let s=(await n().execute({sql:"SELECT content_hash, content, title, content_bytes, truncated, checked_at FROM page_snapshots WHERE user_id = ? AND url = ?",args:[e,t]})).rows[0];return s?{contentHash:String(s.content_hash),content:String(s.content),title:s.title==null?null:String(s.title),contentBytes:Number(s.content_bytes),truncated:Number(s.truncated)===1,checkedAt:String(s.checked_at)}:null}async function or(e,t,r){await n().execute({sql:`
798
897
  INSERT INTO page_snapshots (user_id, url, content_hash, content, title, content_bytes, truncated, checked_at)
799
898
  VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now'))
800
899
  ON CONFLICT(user_id, url) DO UPDATE SET
@@ -804,56 +903,56 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
804
903
  content_bytes = excluded.content_bytes,
805
904
  truncated = excluded.truncated,
806
905
  checked_at = excluded.checked_at
807
- `,args:[e,t,r.contentHash,r.content,r.title,r.contentBytes,r.truncated?1:0]})}var Fe=32*1024;function je(e){if(e==null)return null;let t=JSON.stringify(e),r=Buffer.byteLength(t,"utf8");return r<=Fe?t:JSON.stringify({truncated:!0,originalBytes:r,sha256:A("sha256").update(t).digest("hex")})}function We(e){let t=e.result!=null?String(e.result):null;return{id:String(e.id),user_id:Number(e.user_id),source:String(e.source),status:String(e.status),query:String(e.query),location:e.location!=null?String(e.location):null,result_count:e.result_count!=null?Number(e.result_count):null,result:t?JSON.parse(t):null,error:e.error!=null?String(e.error):null,created_at:String(e.created_at)}}async function Jt(e){let t=m();return await s().execute({sql:`
906
+ `,args:[e,t,r.contentHash,r.content,r.title,r.contentBytes,r.truncated?1:0]})}var Ve=32*1024;function ze(e){if(e==null)return null;let t=JSON.stringify(e),r=Buffer.byteLength(t,"utf8");return r<=Ve?t:JSON.stringify({truncated:!0,originalBytes:r,sha256:y("sha256").update(t).digest("hex")})}function Qe(e){let t=e.result!=null?String(e.result):null;return{id:String(e.id),user_id:Number(e.user_id),source:String(e.source),status:String(e.status),query:String(e.query),location:e.location!=null?String(e.location):null,result_count:e.result_count!=null?Number(e.result_count):null,result:t?JSON.parse(t):null,error:e.error!=null?String(e.error):null,created_at:String(e.created_at)}}async function ur(e){let t=m();return await n().execute({sql:`
808
907
  INSERT INTO request_events (id, user_id, source, status, query, location, result_count, result, error)
809
908
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
810
- `,args:[t,e.userId,e.source,e.status,e.query,e.location??null,e.resultCount??null,je(e.result),e.error??null]}),t}async function $t(e,t=100){return(await s().execute({sql:`
909
+ `,args:[t,e.userId,e.source,e.status,e.query,e.location??null,e.resultCount??null,ze(e.result),e.error??null]}),t}async function cr(e,t=100){return(await n().execute({sql:`
811
910
  SELECT id, user_id, source, status, query, location, result_count, NULL AS result, error, created_at
812
911
  FROM request_events
813
912
  WHERE user_id = ?
814
913
  ORDER BY created_at DESC
815
914
  LIMIT ?
816
- `,args:[e,t]})).rows.map(n=>We(n))}function de(e){if(e==null)return{};try{let t=JSON.parse(String(e));return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return{}}}function F(e){return{id:String(e.id),user_id:Number(e.user_id),workflow_id:String(e.workflow_id),name:String(e.name),input:de(e.input_json),cadence:String(e.cadence),cron_expr:e.cron_expr!=null?String(e.cron_expr):null,timezone:String(e.timezone??"UTC"),webhook_url:e.webhook_url!=null?String(e.webhook_url):null,status:String(e.status),next_run_at:e.next_run_at!=null?String(e.next_run_at):null,last_run_at:e.last_run_at!=null?String(e.last_run_at):null,created_at:String(e.created_at),updated_at:String(e.updated_at)}}function j(e){return{id:String(e.id),user_id:Number(e.user_id),schedule_id:e.schedule_id!=null?String(e.schedule_id):null,workflow_id:String(e.workflow_id),input:de(e.input_json),status:String(e.status),manifest:e.manifest_json!=null?y(e.manifest_json):null,error_message:e.error_message!=null?String(e.error_message):null,queued_at:String(e.queued_at),started_at:e.started_at!=null?String(e.started_at):null,completed_at:e.completed_at!=null?String(e.completed_at):null,idempotency_key:e.idempotency_key!=null?String(e.idempotency_key):null,step_index:e.step_index!=null?Number(e.step_index):0,total_steps:e.total_steps!=null?Number(e.total_steps):null,step_log:le(e.step_log_json),webhook_url:e.webhook_url!=null?String(e.webhook_url):null}}function le(e){if(e==null)return[];try{let t=JSON.parse(String(e));return Array.isArray(t)?t:[]}catch{return[]}}function Ee(e){return{id:String(e.id),run_id:String(e.run_id),user_id:Number(e.user_id),kind:String(e.kind),label:String(e.label),path:String(e.path),content_type:String(e.content_type),bytes:e.bytes!=null?Number(e.bytes):null,rows_count:e.rows_count!=null?Number(e.rows_count):null,content:e.content!=null?String(e.content):null,created_at:String(e.created_at)}}async function Kt(e){let t=m();await s().execute({sql:`
915
+ `,args:[e,t]})).rows.map(s=>Qe(s))}function be(e){if(e==null)return{};try{let t=JSON.parse(String(e));return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return{}}}function B(e){return{id:String(e.id),user_id:Number(e.user_id),workflow_id:String(e.workflow_id),name:String(e.name),input:be(e.input_json),cadence:String(e.cadence),cron_expr:e.cron_expr!=null?String(e.cron_expr):null,timezone:String(e.timezone??"UTC"),webhook_url:e.webhook_url!=null?String(e.webhook_url):null,status:String(e.status),next_run_at:e.next_run_at!=null?String(e.next_run_at):null,last_run_at:e.last_run_at!=null?String(e.last_run_at):null,created_at:String(e.created_at),updated_at:String(e.updated_at)}}function G(e){return{id:String(e.id),user_id:Number(e.user_id),schedule_id:e.schedule_id!=null?String(e.schedule_id):null,workflow_id:String(e.workflow_id),input:be(e.input_json),status:String(e.status),manifest:e.manifest_json!=null?D(e.manifest_json):null,error_message:e.error_message!=null?String(e.error_message):null,queued_at:String(e.queued_at),started_at:e.started_at!=null?String(e.started_at):null,completed_at:e.completed_at!=null?String(e.completed_at):null,idempotency_key:e.idempotency_key!=null?String(e.idempotency_key):null,step_index:e.step_index!=null?Number(e.step_index):0,total_steps:e.total_steps!=null?Number(e.total_steps):null,step_log:Le(e.step_log_json),webhook_url:e.webhook_url!=null?String(e.webhook_url):null}}function Le(e){if(e==null)return[];try{let t=JSON.parse(String(e));return Array.isArray(t)?t:[]}catch{return[]}}function Se(e){return{id:String(e.id),run_id:String(e.run_id),user_id:Number(e.user_id),kind:String(e.kind),label:String(e.label),path:String(e.path),content_type:String(e.content_type),bytes:e.bytes!=null?Number(e.bytes):null,rows_count:e.rows_count!=null?Number(e.rows_count):null,content:e.content!=null?String(e.content):null,created_at:String(e.created_at)}}async function _r(e){let t=m();await n().execute({sql:`
817
916
  INSERT INTO workflow_schedules (
818
917
  id, user_id, workflow_id, name, input_json, cadence, timezone, webhook_url, next_run_at
819
918
  )
820
919
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
821
- `,args:[t,e.userId,e.workflowId,e.name,JSON.stringify(e.workflowInput),e.cadence,e.timezone??"UTC",e.webhookUrl??null,e.nextRunAt??null]});let r=await P(t,e.userId);if(!r)throw new Error("Failed to create workflow schedule");return r}async function P(e,t){let r=t==null?await s().execute({sql:"SELECT * FROM workflow_schedules WHERE id = ? AND status != ? LIMIT 1",args:[e,"deleted"]}):await s().execute({sql:"SELECT * FROM workflow_schedules WHERE id = ? AND user_id = ? AND status != ? LIMIT 1",args:[e,t,"deleted"]});return r.rows[0]?F(r.rows[0]):null}async function Vt(e){return(await s().execute({sql:"SELECT * FROM workflow_schedules WHERE user_id = ? AND status != 'deleted' ORDER BY created_at DESC LIMIT 100",args:[e]})).rows.map(r=>F(r))}async function zt(e){let t=[],r=[];return e.name!==void 0&&(t.push("name = ?"),r.push(e.name)),e.status!==void 0&&(t.push("status = ?"),r.push(e.status)),e.workflowInput!==void 0&&(t.push("input_json = ?"),r.push(JSON.stringify(e.workflowInput))),e.cadence!==void 0&&(t.push("cadence = ?"),r.push(e.cadence)),e.timezone!==void 0&&(t.push("timezone = ?"),r.push(e.timezone)),e.webhookUrl!==void 0&&(t.push("webhook_url = ?"),r.push(e.webhookUrl)),e.nextRunAt!==void 0&&(t.push("next_run_at = ?"),r.push(e.nextRunAt)),t.length===0||(t.push("updated_at = datetime('now')"),await s().execute({sql:`UPDATE workflow_schedules SET ${t.join(", ")} WHERE id = ? AND user_id = ? AND status != 'deleted'`,args:[...r,e.id,e.userId]})),P(e.id,e.userId)}async function Qt(e,t){return(await s().execute({sql:"UPDATE workflow_schedules SET status = 'deleted', updated_at = datetime('now') WHERE id = ? AND user_id = ? AND status != 'deleted'",args:[e,t]})).rowsAffected>0}async function Zt(e,t=10){return(await s().execute({sql:`
920
+ `,args:[t,e.userId,e.workflowId,e.name,JSON.stringify(e.workflowInput),e.cadence,e.timezone??"UTC",e.webhookUrl??null,e.nextRunAt??null]});let r=await H(t,e.userId);if(!r)throw new Error("Failed to create workflow schedule");return r}async function H(e,t){let r=t==null?await n().execute({sql:"SELECT * FROM workflow_schedules WHERE id = ? AND status != ? LIMIT 1",args:[e,"deleted"]}):await n().execute({sql:"SELECT * FROM workflow_schedules WHERE id = ? AND user_id = ? AND status != ? LIMIT 1",args:[e,t,"deleted"]});return r.rows[0]?B(r.rows[0]):null}async function dr(e){return(await n().execute({sql:"SELECT * FROM workflow_schedules WHERE user_id = ? AND status != 'deleted' ORDER BY created_at DESC LIMIT 100",args:[e]})).rows.map(r=>B(r))}async function lr(e){let t=[],r=[];return e.name!==void 0&&(t.push("name = ?"),r.push(e.name)),e.status!==void 0&&(t.push("status = ?"),r.push(e.status)),e.workflowInput!==void 0&&(t.push("input_json = ?"),r.push(JSON.stringify(e.workflowInput))),e.cadence!==void 0&&(t.push("cadence = ?"),r.push(e.cadence)),e.timezone!==void 0&&(t.push("timezone = ?"),r.push(e.timezone)),e.webhookUrl!==void 0&&(t.push("webhook_url = ?"),r.push(e.webhookUrl)),e.nextRunAt!==void 0&&(t.push("next_run_at = ?"),r.push(e.nextRunAt)),t.length===0||(t.push("updated_at = datetime('now')"),await n().execute({sql:`UPDATE workflow_schedules SET ${t.join(", ")} WHERE id = ? AND user_id = ? AND status != 'deleted'`,args:[...r,e.id,e.userId]})),H(e.id,e.userId)}async function Er(e,t){return(await n().execute({sql:"UPDATE workflow_schedules SET status = 'deleted', updated_at = datetime('now') WHERE id = ? AND user_id = ? AND status != 'deleted'",args:[e,t]})).rowsAffected>0}async function Tr(e,t=10){return(await n().execute({sql:`
822
921
  SELECT * FROM workflow_schedules
823
922
  WHERE status = 'active' AND next_run_at IS NOT NULL AND next_run_at <= ?
824
923
  ORDER BY next_run_at ASC
825
924
  LIMIT ?
826
- `,args:[e,t]})).rows.map(n=>F(n))}async function er(e,t,r){await s().execute({sql:"UPDATE workflow_schedules SET last_run_at = ?, next_run_at = ?, updated_at = datetime('now') WHERE id = ?",args:[t,r,e]})}async function tr(e){let t=e.id??m(),r=[t,e.userId,e.scheduleId??null,e.workflowId,JSON.stringify(e.workflowInput),e.idempotencyKey??null,e.webhookUrl??null,e.totalSteps??null];try{await s().execute({sql:`
925
+ `,args:[e,t]})).rows.map(s=>B(s))}async function pr(e,t,r){await n().execute({sql:"UPDATE workflow_schedules SET last_run_at = ?, next_run_at = ?, updated_at = datetime('now') WHERE id = ?",args:[t,r,e]})}async function mr(e){let t=e.id??m(),r=[t,e.userId,e.scheduleId??null,e.workflowId,JSON.stringify(e.workflowInput),e.idempotencyKey??null,e.webhookUrl??null,e.totalSteps??null];try{await n().execute({sql:`
827
926
  INSERT INTO workflow_runs (id, user_id, schedule_id, workflow_id, input_json, idempotency_key, webhook_url, total_steps)
828
927
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)
829
- `,args:r})}catch(i){if(e.idempotencyKey){let a=await He(e.idempotencyKey);if(a)return a}throw i}let n=await qe(t,e.userId);if(!n)throw new Error("Failed to create workflow run");return n}async function qe(e,t){let r=t==null?await s().execute({sql:"SELECT * FROM workflow_runs WHERE id = ? LIMIT 1",args:[e]}):await s().execute({sql:"SELECT * FROM workflow_runs WHERE id = ? AND user_id = ? LIMIT 1",args:[e,t]});return r.rows[0]?j(r.rows[0]):null}async function He(e){let t=await s().execute({sql:"SELECT * FROM workflow_runs WHERE idempotency_key = ? LIMIT 1",args:[e]});return t.rows[0]?j(t.rows[0]):null}async function rr(e,t=50){return(await s().execute({sql:"SELECT * FROM workflow_runs WHERE user_id = ? ORDER BY queued_at DESC LIMIT ?",args:[e,t]})).rows.map(n=>j(n))}async function nr(e){await s().execute({sql:"UPDATE workflow_runs SET status = 'running', started_at = COALESCE(started_at, datetime('now')) WHERE id = ?",args:[e]})}async function sr(e,t,r){await s().execute({sql:"UPDATE workflow_runs SET status = ?, manifest_json = ?, completed_at = datetime('now') WHERE id = ?",args:[t,JSON.stringify(r),e]})}async function ir(e,t,r){await s().execute({sql:"UPDATE workflow_runs SET status = 'failed', error_message = ?, manifest_json = ?, completed_at = datetime('now') WHERE id = ?",args:[t,r==null?null:JSON.stringify(r),e]})}function Be(e){return e==="html_report"?"text/html; charset=utf-8":e==="csv"?"text/csv; charset=utf-8":e==="json"?"application/json; charset=utf-8":"text/plain; charset=utf-8"}async function Te(e,t,r){await s().execute({sql:`
928
+ `,args:r})}catch(i){if(e.idempotencyKey){let a=await et(e.idempotencyKey);if(a)return a}throw i}let s=await Ze(t,e.userId);if(!s)throw new Error("Failed to create workflow run");return s}async function Ze(e,t){let r=t==null?await n().execute({sql:"SELECT * FROM workflow_runs WHERE id = ? LIMIT 1",args:[e]}):await n().execute({sql:"SELECT * FROM workflow_runs WHERE id = ? AND user_id = ? LIMIT 1",args:[e,t]});return r.rows[0]?G(r.rows[0]):null}async function et(e){let t=await n().execute({sql:"SELECT * FROM workflow_runs WHERE idempotency_key = ? LIMIT 1",args:[e]});return t.rows[0]?G(t.rows[0]):null}async function gr(e,t=50){return(await n().execute({sql:"SELECT * FROM workflow_runs WHERE user_id = ? ORDER BY queued_at DESC LIMIT ?",args:[e,t]})).rows.map(s=>G(s))}async function Nr(e){await n().execute({sql:"UPDATE workflow_runs SET status = 'running', started_at = COALESCE(started_at, datetime('now')) WHERE id = ?",args:[e]})}async function br(e,t,r){await n().execute({sql:"UPDATE workflow_runs SET status = ?, manifest_json = ?, completed_at = datetime('now') WHERE id = ?",args:[t,JSON.stringify(r),e]})}async function Lr(e,t,r){await n().execute({sql:"UPDATE workflow_runs SET status = 'failed', error_message = ?, manifest_json = ?, completed_at = datetime('now') WHERE id = ?",args:[t,r==null?null:JSON.stringify(r),e]})}function tt(e){return e==="html_report"?"text/html; charset=utf-8":e==="csv"?"text/csv; charset=utf-8":e==="json"?"application/json; charset=utf-8":"text/plain; charset=utf-8"}async function Re(e,t,r){await n().execute({sql:`
830
929
  INSERT INTO workflow_artifacts (id, run_id, user_id, kind, label, path, content_type, bytes, rows_count, content)
831
930
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
832
- `,args:[m(),e,t,r.kind,r.label,r.path,Be(r.kind),r.bytes??null,r.rows??null,r.content??null]})}async function ar(e,t,r){await s().execute({sql:"DELETE FROM workflow_artifacts WHERE run_id = ? AND user_id = ?",args:[e,t]});for(let n of r)await Te(e,t,n);return pe(e,t)}async function or(e,t,r){for(let n of r)await Te(e,t,n);return pe(e,t)}async function ur(e,t){let n=(t==null?await s().execute({sql:"SELECT step_index, total_steps, step_state_json, step_log_json FROM workflow_runs WHERE id = ? LIMIT 1",args:[e]}):await s().execute({sql:"SELECT step_index, total_steps, step_state_json, step_log_json FROM workflow_runs WHERE id = ? AND user_id = ? LIMIT 1",args:[e,t]})).rows[0];return n?{stepIndex:n.step_index!=null?Number(n.step_index):0,totalSteps:n.total_steps!=null?Number(n.total_steps):null,state:n.step_state_json!=null?y(n.step_state_json):null,stepLog:le(n.step_log_json)}:null}async function cr(e,t){let r=[...t.appendLog,t.logEntry];await s().execute({sql:"UPDATE workflow_runs SET status = ?, step_index = ?, total_steps = ?, step_state_json = ?, step_log_json = ?, started_at = COALESCE(started_at, datetime('now')) WHERE id = ?",args:[t.status,t.stepIndex,t.totalSteps,JSON.stringify(t.state??null),JSON.stringify(r),e]})}async function pe(e,t){return(await s().execute({sql:"SELECT * FROM workflow_artifacts WHERE run_id = ? AND user_id = ? ORDER BY created_at ASC",args:[e,t]})).rows.map(n=>Ee(n))}async function _r(e,t){let r=await s().execute({sql:"SELECT * FROM workflow_artifacts WHERE id = ? AND user_id = ? LIMIT 1",args:[e,t]});return r.rows[0]?Ee(r.rows[0]):null}async function dr(e){await s().execute({sql:`
931
+ `,args:[m(),e,t,r.kind,r.label,r.path,tt(r.kind),r.bytes??null,r.rows??null,r.content??null]})}async function Sr(e,t,r){await n().execute({sql:"DELETE FROM workflow_artifacts WHERE run_id = ? AND user_id = ?",args:[e,t]});for(let s of r)await Re(e,t,s);return Ae(e,t)}async function Rr(e,t,r){for(let s of r)await Re(e,t,s);return Ae(e,t)}async function Ar(e,t){let s=(t==null?await n().execute({sql:"SELECT step_index, total_steps, step_state_json, step_log_json FROM workflow_runs WHERE id = ? LIMIT 1",args:[e]}):await n().execute({sql:"SELECT step_index, total_steps, step_state_json, step_log_json FROM workflow_runs WHERE id = ? AND user_id = ? LIMIT 1",args:[e,t]})).rows[0];return s?{stepIndex:s.step_index!=null?Number(s.step_index):0,totalSteps:s.total_steps!=null?Number(s.total_steps):null,state:s.step_state_json!=null?D(s.step_state_json):null,stepLog:Le(s.step_log_json)}:null}async function wr(e,t){let r=[...t.appendLog,t.logEntry];await n().execute({sql:"UPDATE workflow_runs SET status = ?, step_index = ?, total_steps = ?, step_state_json = ?, step_log_json = ?, started_at = COALESCE(started_at, datetime('now')) WHERE id = ?",args:[t.status,t.stepIndex,t.totalSteps,JSON.stringify(t.state??null),JSON.stringify(r),e]})}async function Ae(e,t){return(await n().execute({sql:"SELECT * FROM workflow_artifacts WHERE run_id = ? AND user_id = ? ORDER BY created_at ASC",args:[e,t]})).rows.map(s=>Se(s))}async function fr(e,t){let r=await n().execute({sql:"SELECT * FROM workflow_artifacts WHERE id = ? AND user_id = ? LIMIT 1",args:[e,t]});return r.rows[0]?Se(r.rows[0]):null}async function Or(e){await n().execute({sql:`
833
932
  INSERT INTO workflow_webhook_deliveries (
834
933
  id, run_id, schedule_id, user_id, webhook_url, status, attempts, last_error, delivered_at
835
934
  )
836
935
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
837
- `,args:[m(),e.runId,e.scheduleId??null,e.userId,e.webhookUrl,e.status,e.attempts,e.lastError??null,e.status==="delivered"?new Date().toISOString():null]})}async function lr(){let e=await s().execute("SELECT COUNT(*) as n FROM users WHERE active = 1");return Number(e.rows[0]?.n??0)}async function Er(e){let t=await s().execute({sql:"SELECT COUNT(*) as n FROM jobs WHERE user_id = ? AND (status = 'pending' OR (status = 'running' AND started_at > datetime('now', '-10 minutes')))",args:[e]});return Number(t.rows[0]?.n??0)}async function Tr(){let e=s(),t=await e.execute(`
936
+ `,args:[m(),e.runId,e.scheduleId??null,e.userId,e.webhookUrl,e.status,e.attempts,e.lastError??null,e.status==="delivered"?new Date().toISOString():null]})}async function hr(){let e=await n().execute("SELECT COUNT(*) as n FROM users WHERE active = 1");return Number(e.rows[0]?.n??0)}async function xr(e){let t=await n().execute({sql:"SELECT COUNT(*) as n FROM jobs WHERE user_id = ? AND (status = 'pending' OR (status = 'running' AND started_at > datetime('now', '-10 minutes')))",args:[e]});return Number(t.rows[0]?.n??0)}async function yr(){let e=n(),t=await e.execute(`
838
937
  SELECT * FROM jobs
839
938
  WHERE status = 'pending'
840
939
  AND COALESCE(json_extract(options, '$.executionOwner'), 'cron') NOT IN ('direct', 'inngest')
841
940
  ORDER BY created_at
842
941
  LIMIT 1
843
- `),r=t.rows[0]?S(t.rows[0]):void 0;return r?(await e.execute({sql:"UPDATE jobs SET status = 'running', started_at = datetime('now') WHERE id = ? AND status = 'pending'",args:[r.id]})).rowsAffected===0?void 0:{...r,status:"running"}:void 0}var W=45e3;async function pr(e){let t=s(),r=await _e(e);if(!r||r.options.executionOwner!=="direct"||r.options.serpOnly===!0)return;let n=Math.max(0,Number(r.options.paaRecoveryCount??0));if(r.status!=="running"){if(r.status==="pending"){let i=m(),a=new Date().toISOString(),o=new Date(Date.now()+W).toISOString();return(await t.execute({sql:`UPDATE jobs
942
+ `),r=t.rows[0]?A(t.rows[0]):void 0;return r?(await e.execute({sql:"UPDATE jobs SET status = 'running', started_at = datetime('now') WHERE id = ? AND status = 'pending'",args:[r.id]})).rowsAffected===0?void 0:{...r,status:"running"}:void 0}var Y=45e3;async function Ir(e){let t=n(),r=await Ne(e);if(!r||r.options.executionOwner!=="direct"||r.options.serpOnly===!0)return;let s=Math.max(0,Number(r.options.paaRecoveryCount??0));if(r.status!=="running"){if(r.status==="pending"){let i=m(),a=new Date().toISOString(),u=new Date(Date.now()+Y).toISOString();return(await t.execute({sql:`UPDATE jobs
844
943
  SET status = 'running', started_at = datetime('now'), error = NULL,
845
944
  options = json_set(options,
846
945
  '$.paaLeaseToken', ?,
847
946
  '$.paaLeaseExpiresAt', ?,
848
947
  '$.paaLastDispatchAt', ?)
849
- WHERE id = ? AND status = 'pending'`,args:[i,o,a,e]})).rowsAffected===0?void 0:{job:{...r,status:"running",started_at:a,options:{...r.options,paaLeaseToken:i,paaLeaseExpiresAt:o,paaLastDispatchAt:a}},leaseToken:i,recoveryCount:n}}return{job:r,leaseToken:null,recoveryCount:n}}}async function mr(e,t){return(await s().execute({sql:"UPDATE jobs SET result = ? WHERE id = ? AND status = 'running'",args:[JSON.stringify(t),e]})).rowsAffected===1}async function gr(e,t,r){let n=new Date(Date.now()+W).toISOString();return(await s().execute({sql:`UPDATE jobs SET result = ?, options = json_set(options, '$.paaLeaseExpiresAt', ?)
850
- WHERE id = ? AND status = 'running' AND json_extract(options, '$.paaLeaseToken') = ?`,args:[JSON.stringify(r),n,e,t]})).rowsAffected===1}async function Nr(e,t){let r=new Date(Date.now()+W).toISOString();return(await s().execute({sql:`UPDATE jobs SET options = json_set(options, '$.paaLeaseExpiresAt', ?)
851
- WHERE id = ? AND status = 'running' AND json_extract(options, '$.paaLeaseToken') = ?`,args:[r,e,t]})).rowsAffected===1}async function br(e,t,r){return(await s().execute({sql:`UPDATE jobs SET status = 'done', result = ?, error = NULL, public_error_json = NULL,
948
+ WHERE id = ? AND status = 'pending'`,args:[i,u,a,e]})).rowsAffected===0?void 0:{job:{...r,status:"running",started_at:a,options:{...r.options,paaLeaseToken:i,paaLeaseExpiresAt:u,paaLastDispatchAt:a}},leaseToken:i,recoveryCount:s}}return{job:r,leaseToken:null,recoveryCount:s}}}async function Cr(e,t){return(await n().execute({sql:"UPDATE jobs SET result = ? WHERE id = ? AND status = 'running'",args:[JSON.stringify(t),e]})).rowsAffected===1}async function Ur(e,t,r){let s=new Date(Date.now()+Y).toISOString();return(await n().execute({sql:`UPDATE jobs SET result = ?, options = json_set(options, '$.paaLeaseExpiresAt', ?)
949
+ WHERE id = ? AND status = 'running' AND json_extract(options, '$.paaLeaseToken') = ?`,args:[JSON.stringify(r),s,e,t]})).rowsAffected===1}async function kr(e,t){let r=new Date(Date.now()+Y).toISOString();return(await n().execute({sql:`UPDATE jobs SET options = json_set(options, '$.paaLeaseExpiresAt', ?)
950
+ WHERE id = ? AND status = 'running' AND json_extract(options, '$.paaLeaseToken') = ?`,args:[r,e,t]})).rowsAffected===1}async function Dr(e,t,r){return(await n().execute({sql:`UPDATE jobs SET status = 'done', result = ?, error = NULL, public_error_json = NULL,
852
951
  completed_at = datetime('now'),
853
952
  options = json_set(options, '$.paaLeaseExpiresAt', NULL)
854
- WHERE id = ? AND status = 'running' AND json_extract(options, '$.paaLeaseToken') = ?`,args:[JSON.stringify(r),e,t]})).rowsAffected===1}async function Lr(e,t,r,n){return(await s().execute({sql:`UPDATE jobs SET status = 'failed', error = ?, public_error_json = ?, completed_at = datetime('now'),
953
+ WHERE id = ? AND status = 'running' AND json_extract(options, '$.paaLeaseToken') = ?`,args:[JSON.stringify(r),e,t]})).rowsAffected===1}async function vr(e,t,r,s){return(await n().execute({sql:`UPDATE jobs SET status = 'failed', error = ?, public_error_json = ?, completed_at = datetime('now'),
855
954
  options = json_set(options, '$.paaLeaseExpiresAt', NULL)
856
- WHERE id = ? AND status = 'running' AND json_extract(options, '$.paaLeaseToken') = ?`,args:[r,L(n),e,t]})).rowsAffected===1}async function Sr(e,t){let r=new Date().toISOString();return(await s().execute({sql:`UPDATE jobs SET status = 'pending', started_at = NULL,
955
+ WHERE id = ? AND status = 'running' AND json_extract(options, '$.paaLeaseToken') = ?`,args:[r,R(s),e,t]})).rowsAffected===1}async function Xr(e,t){let r=new Date().toISOString();return(await n().execute({sql:`UPDATE jobs SET status = 'pending', started_at = NULL,
857
956
  result = CASE WHEN json_valid(result) THEN json_set(result,
858
957
  '$.progress.lifecycle.discoveryStatus', 'interrupted',
859
958
  '$.progress.lifecycle.completionReason', 'The previous worker lease expired; the same job is recovering automatically.',
@@ -869,28 +968,28 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
869
968
  datetime(json_extract(options, '$.paaLeaseExpiresAt')) <= datetime('now')
870
969
  OR (json_extract(options, '$.paaLeaseExpiresAt') IS NULL AND started_at <= datetime('now', '-15 minutes'))
871
970
  )
872
- AND COALESCE(json_extract(options, '$.paaRecoveryCount'), 0) < ?`,args:[r,e,Math.max(0,Math.trunc(t))]})).rowsAffected===1}async function Rr(e,t){return(await s().execute({sql:`UPDATE jobs SET status = 'done', result = ?, error = NULL, public_error_json = NULL, completed_at = datetime('now')
971
+ AND COALESCE(json_extract(options, '$.paaRecoveryCount'), 0) < ?`,args:[r,e,Math.max(0,Math.trunc(t))]})).rowsAffected===1}async function Mr(e,t){return(await n().execute({sql:`UPDATE jobs SET status = 'done', result = ?, error = NULL, public_error_json = NULL, completed_at = datetime('now')
873
972
  WHERE id = ? AND status = 'running'
874
973
  AND (
875
974
  datetime(json_extract(options, '$.paaLeaseExpiresAt')) <= datetime('now')
876
975
  OR (json_extract(options, '$.paaLeaseExpiresAt') IS NULL AND started_at <= datetime('now', '-15 minutes'))
877
- )`,args:[JSON.stringify(t),e]})).rowsAffected===1}async function wr(e,t,r){return(await s().execute({sql:`UPDATE jobs SET status = 'failed', error = ?, public_error_json = ?, completed_at = datetime('now')
976
+ )`,args:[JSON.stringify(t),e]})).rowsAffected===1}async function Fr(e,t,r){return(await n().execute({sql:`UPDATE jobs SET status = 'failed', error = ?, public_error_json = ?, completed_at = datetime('now')
878
977
  WHERE id = ? AND status = 'running'
879
978
  AND (
880
979
  datetime(json_extract(options, '$.paaLeaseExpiresAt')) <= datetime('now')
881
980
  OR (json_extract(options, '$.paaLeaseExpiresAt') IS NULL AND started_at <= datetime('now', '-15 minutes'))
882
- )`,args:[t,L(r),e]})).rowsAffected===1}async function Ar(e=25){let t=Math.max(1,Math.min(100,Math.floor(e)));return(await s().execute({sql:`SELECT * FROM jobs
981
+ )`,args:[t,R(r),e]})).rowsAffected===1}async function Pr(e=25){let t=Math.max(1,Math.min(100,Math.floor(e)));return(await n().execute({sql:`SELECT * FROM jobs
883
982
  WHERE status IN ('done', 'failed', 'cancelled')
884
983
  AND json_extract(options, '$.executionOwner') IN ('direct', 'inngest')
885
984
  AND json_extract(options, '$.billingDebitKey') IS NOT NULL
886
985
  AND json_extract(options, '$.billingSettledAt') IS NULL
887
986
  ORDER BY completed_at DESC
888
- LIMIT ?`,args:[t]})).rows.map(n=>f(S(n)))}async function fr(e=25){let t=Math.max(1,Math.min(100,Math.floor(e)));return(await s().execute({sql:`SELECT * FROM jobs
987
+ LIMIT ?`,args:[t]})).rows.map(s=>I(A(s)))}async function qr(e=25){let t=Math.max(1,Math.min(100,Math.floor(e)));return(await n().execute({sql:`SELECT * FROM jobs
889
988
  WHERE status = 'running'
890
989
  AND started_at <= datetime('now', '-15 minutes')
891
990
  AND json_extract(options, '$.executionOwner') IN ('direct', 'inngest')
892
991
  ORDER BY started_at
893
- LIMIT ?`,args:[t]})).rows.map(n=>f(S(n)))}async function Or(e=25){let t=Math.max(1,Math.min(100,Math.floor(e)));return(await s().execute({sql:`SELECT * FROM jobs
992
+ LIMIT ?`,args:[t]})).rows.map(s=>I(A(s)))}async function Wr(e=25){let t=Math.max(1,Math.min(100,Math.floor(e)));return(await n().execute({sql:`SELECT * FROM jobs
894
993
  WHERE json_extract(options, '$.executionOwner') = 'direct'
895
994
  AND json_extract(options, '$.serpOnly') IS NOT 1
896
995
  AND (
@@ -903,11 +1002,11 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
903
1002
  AND datetime(COALESCE(json_extract(options, '$.paaLastDispatchAt'), '1970-01-01')) <= datetime('now', '-30 seconds'))
904
1003
  )
905
1004
  ORDER BY COALESCE(started_at, created_at)
906
- LIMIT ?`,args:[t]})).rows.map(n=>f(S(n)))}async function xr(e,t,r=new Date().toISOString()){if(!Number.isSafeInteger(t)||t<0)throw new Error("job billed amount must be a non-negative integer");return(await s().execute({sql:`UPDATE jobs
1005
+ LIMIT ?`,args:[t]})).rows.map(s=>I(A(s)))}async function jr(e,t,r=new Date().toISOString()){if(!Number.isSafeInteger(t)||t<0)throw new Error("job billed amount must be a non-negative integer");return(await n().execute({sql:`UPDATE jobs
907
1006
  SET options = json_set(options, '$.billingSettledAt', ?, '$.billedMc', ?)
908
- WHERE id = ?`,args:[r,t,e]})).rowsAffected===1}async function hr(e,t){await s().execute({sql:"UPDATE jobs SET status = 'done', result = ?, error = NULL, public_error_json = NULL, completed_at = datetime('now') WHERE id = ?",args:[JSON.stringify(t),e]})}async function yr(e,t){return(await s().execute({sql:`UPDATE jobs SET status = 'done', result = ?, error = NULL, public_error_json = NULL, completed_at = datetime('now')
909
- WHERE id = ? AND status = 'running'`,args:[JSON.stringify(t),e]})).rowsAffected===1}async function Ir(e,t,r){await s().execute({sql:"UPDATE jobs SET status = 'failed', error = ?, public_error_json = ?, completed_at = datetime('now') WHERE id = ?",args:[t,L(r),e]})}async function Cr(e,t,r){return(await s().execute({sql:`UPDATE jobs SET status = 'failed', error = ?, public_error_json = ?, completed_at = datetime('now')
910
- WHERE id = ? AND status = 'running'`,args:[t,L(r),e]})).rowsAffected===1}async function kr(e,t,r){await s().execute({sql:"UPDATE jobs SET status = 'cancelled', error = ?, public_error_json = ?, completed_at = datetime('now') WHERE id = ?",args:[t,L(r),e]})}function q(e){return{id:String(e.id),user_id:Number(e.user_id),status:String(e.status),entity_name:String(e.entity_name),entity_type:String(e.entity_type),url:e.url!=null?String(e.url):null,request:String(e.request),result:e.result!=null?String(e.result):null,error:e.error!=null?String(e.error):null,created_at:String(e.created_at),updated_at:String(e.updated_at)}}function Ge(e){return{id:Number(e.id),job_id:String(e.job_id),phase:String(e.phase),output:String(e.output),created_at:String(e.created_at)}}async function Dr(e,t,r,n,i,a){await s().execute({sql:"INSERT INTO kpo_jobs (id, user_id, status, entity_name, entity_type, url, request) VALUES (?, ?, 'pending', ?, ?, ?, ?)",args:[e,t,r,n,a??null,JSON.stringify(i)]})}async function Ur(){let t=await s().execute("UPDATE kpo_jobs SET status='running', updated_at=datetime('now') WHERE id = (SELECT id FROM kpo_jobs WHERE status='pending' ORDER BY created_at ASC LIMIT 1) RETURNING *");return t.rowsAffected===0?null:t.rows[0]?q(t.rows[0]):null}async function vr(e){let t=await s().execute({sql:"SELECT * FROM kpo_jobs WHERE id = ?",args:[e]});return t.rows[0]?q(t.rows[0]):null}async function Xr(e,t){await s().execute({sql:"UPDATE kpo_jobs SET status = ?, updated_at = datetime('now') WHERE id = ?",args:[t,e]})}async function Mr(e,t){await s().execute({sql:"UPDATE kpo_jobs SET status = 'done', result = ?, updated_at = datetime('now') WHERE id = ?",args:[JSON.stringify(t),e]})}async function Pr(e,t){await s().execute({sql:"UPDATE kpo_jobs SET status = 'failed', error = ?, updated_at = datetime('now') WHERE id = ?",args:[t,e]})}async function Fr(e,t,r){await s().execute({sql:"INSERT INTO kpo_phase_log (job_id, phase, output) VALUES (?, ?, ?)",args:[e,t,JSON.stringify(r)]})}async function jr(e){return(await s().execute({sql:"SELECT * FROM kpo_phase_log WHERE job_id = ? ORDER BY created_at ASC",args:[e]})).rows.map(r=>Ge(r))}async function Wr(e){return(e!=null?await s().execute({sql:"SELECT * FROM kpo_jobs WHERE user_id = ? ORDER BY created_at DESC LIMIT 50",args:[e]}):await s().execute("SELECT * FROM kpo_jobs ORDER BY created_at DESC LIMIT 50")).rows.map(r=>q(r))}async function qr(e){let t=await s().execute({sql:"SELECT * FROM users WHERE stripe_customer_id = ? AND active = 1",args:[e]});return t.rows[0]?N(t.rows[0]):void 0}async function Hr(e,t){await s().execute({sql:"UPDATE users SET stripe_customer_id = ? WHERE id = ?",args:[t,e]})}async function Br(e,t){if(!Number.isSafeInteger(t)||t<0)throw new Error("extra concurrency slots must be a non-negative safe integer");await Ye(e,Math.ceil(t/2))}async function Ye(e,t){if(!Number.isSafeInteger(t)||t<0)throw new Error("concurrency pack quantity must be a non-negative safe integer");await s().execute({sql:"UPDATE users SET concurrency_pack_quantity = ?, extra_concurrency_slots = ? WHERE id = ?",args:[t,t*2,e]})}async function Gr(e,t){await s().execute({sql:"UPDATE users SET concurrency_stripe_sub_id = ? WHERE id = ?",args:[t,e]})}async function Yr(e,t,r,n){await s().execute({sql:"UPDATE users SET subscription_tier = ?, subscription_concurrency = ?, subscription_id = ? WHERE id = ?",args:[t,Math.max(0,Math.round(r)),n,e]})}function Je(e){return{user_id:Number(e.user_id),stripe_subscription_id:e.stripe_subscription_id!=null?String(e.stripe_subscription_id):null,stripe_subscription_item_id:e.stripe_subscription_item_id!=null?String(e.stripe_subscription_item_id):null,price_id:e.price_id!=null?String(e.price_id):null,quantity:Math.max(0,Number(e.quantity??0)),status:["pending","synced","blocked","error"].includes(String(e.status))?String(e.status):"error",last_error_code:e.last_error_code!=null?String(e.last_error_code):null,checked_at:String(e.checked_at),synced_at:e.synced_at!=null?String(e.synced_at):null,updated_at:String(e.updated_at)}}async function $e(e){let r=(await s().execute({sql:"SELECT * FROM connected_account_billing WHERE user_id = ? LIMIT 1",args:[e]})).rows[0];return r?Je(r):null}async function Jr(e){let t=Math.max(0,Math.round(e.quantity));await s().execute({sql:`INSERT INTO connected_account_billing
1007
+ WHERE id = ?`,args:[r,t,e]})).rowsAffected===1}async function Hr(e,t){await n().execute({sql:"UPDATE jobs SET status = 'done', result = ?, error = NULL, public_error_json = NULL, completed_at = datetime('now') WHERE id = ?",args:[JSON.stringify(t),e]})}async function Br(e,t){return(await n().execute({sql:`UPDATE jobs SET status = 'done', result = ?, error = NULL, public_error_json = NULL, completed_at = datetime('now')
1008
+ WHERE id = ? AND status = 'running'`,args:[JSON.stringify(t),e]})).rowsAffected===1}async function Gr(e,t,r){await n().execute({sql:"UPDATE jobs SET status = 'failed', error = ?, public_error_json = ?, completed_at = datetime('now') WHERE id = ?",args:[t,R(r),e]})}async function Yr(e,t,r){return(await n().execute({sql:`UPDATE jobs SET status = 'failed', error = ?, public_error_json = ?, completed_at = datetime('now')
1009
+ WHERE id = ? AND status = 'running'`,args:[t,R(r),e]})).rowsAffected===1}async function Jr(e,t,r){await n().execute({sql:"UPDATE jobs SET status = 'cancelled', error = ?, public_error_json = ?, completed_at = datetime('now') WHERE id = ?",args:[t,R(r),e]})}function J(e){return{id:String(e.id),user_id:Number(e.user_id),status:String(e.status),entity_name:String(e.entity_name),entity_type:String(e.entity_type),url:e.url!=null?String(e.url):null,request:String(e.request),result:e.result!=null?String(e.result):null,error:e.error!=null?String(e.error):null,created_at:String(e.created_at),updated_at:String(e.updated_at)}}function rt(e){return{id:Number(e.id),job_id:String(e.job_id),phase:String(e.phase),output:String(e.output),created_at:String(e.created_at)}}async function $r(e,t,r,s,i,a){await n().execute({sql:"INSERT INTO kpo_jobs (id, user_id, status, entity_name, entity_type, url, request) VALUES (?, ?, 'pending', ?, ?, ?, ?)",args:[e,t,r,s,a??null,JSON.stringify(i)]})}async function Kr(){let t=await n().execute("UPDATE kpo_jobs SET status='running', updated_at=datetime('now') WHERE id = (SELECT id FROM kpo_jobs WHERE status='pending' ORDER BY created_at ASC LIMIT 1) RETURNING *");return t.rowsAffected===0?null:t.rows[0]?J(t.rows[0]):null}async function Vr(e){let t=await n().execute({sql:"SELECT * FROM kpo_jobs WHERE id = ?",args:[e]});return t.rows[0]?J(t.rows[0]):null}async function zr(e,t){await n().execute({sql:"UPDATE kpo_jobs SET status = ?, updated_at = datetime('now') WHERE id = ?",args:[t,e]})}async function Qr(e,t){await n().execute({sql:"UPDATE kpo_jobs SET status = 'done', result = ?, updated_at = datetime('now') WHERE id = ?",args:[JSON.stringify(t),e]})}async function Zr(e,t){await n().execute({sql:"UPDATE kpo_jobs SET status = 'failed', error = ?, updated_at = datetime('now') WHERE id = ?",args:[t,e]})}async function es(e,t,r){await n().execute({sql:"INSERT INTO kpo_phase_log (job_id, phase, output) VALUES (?, ?, ?)",args:[e,t,JSON.stringify(r)]})}async function ts(e){return(await n().execute({sql:"SELECT * FROM kpo_phase_log WHERE job_id = ? ORDER BY created_at ASC",args:[e]})).rows.map(r=>rt(r))}async function rs(e){return(e!=null?await n().execute({sql:"SELECT * FROM kpo_jobs WHERE user_id = ? ORDER BY created_at DESC LIMIT 50",args:[e]}):await n().execute("SELECT * FROM kpo_jobs ORDER BY created_at DESC LIMIT 50")).rows.map(r=>J(r))}async function ss(e){let t=await n().execute({sql:"SELECT * FROM users WHERE stripe_customer_id = ? AND active = 1",args:[e]});return t.rows[0]?L(t.rows[0]):void 0}async function ns(e,t){await n().execute({sql:"UPDATE users SET stripe_customer_id = ? WHERE id = ?",args:[t,e]})}async function is(e,t){if(!Number.isSafeInteger(t)||t<0)throw new Error("extra concurrency slots must be a non-negative safe integer");await st(e,Math.ceil(t/2))}async function st(e,t){if(!Number.isSafeInteger(t)||t<0)throw new Error("concurrency pack quantity must be a non-negative safe integer");await n().execute({sql:"UPDATE users SET concurrency_pack_quantity = ?, extra_concurrency_slots = ? WHERE id = ?",args:[t,t*2,e]})}async function as(e,t){await n().execute({sql:"UPDATE users SET concurrency_stripe_sub_id = ? WHERE id = ?",args:[t,e]})}async function os(e,t,r,s){await n().execute({sql:"UPDATE users SET subscription_tier = ?, subscription_concurrency = ?, subscription_id = ? WHERE id = ?",args:[t,Math.max(0,Math.round(r)),s,e]})}function nt(e){return{user_id:Number(e.user_id),stripe_subscription_id:e.stripe_subscription_id!=null?String(e.stripe_subscription_id):null,stripe_subscription_item_id:e.stripe_subscription_item_id!=null?String(e.stripe_subscription_item_id):null,price_id:e.price_id!=null?String(e.price_id):null,quantity:Math.max(0,Number(e.quantity??0)),status:["pending","synced","blocked","error"].includes(String(e.status))?String(e.status):"error",last_error_code:e.last_error_code!=null?String(e.last_error_code):null,checked_at:String(e.checked_at),synced_at:e.synced_at!=null?String(e.synced_at):null,updated_at:String(e.updated_at)}}async function it(e){let r=(await n().execute({sql:"SELECT * FROM connected_account_billing WHERE user_id = ? LIMIT 1",args:[e]})).rows[0];return r?nt(r):null}async function us(e){let t=Math.max(0,Math.round(e.quantity));await n().execute({sql:`INSERT INTO connected_account_billing
911
1010
  (user_id, stripe_subscription_id, stripe_subscription_item_id, price_id, quantity, status, last_error_code, checked_at, synced_at, updated_at)
912
1011
  VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now'), CASE WHEN ? THEN datetime('now') ELSE NULL END, datetime('now'))
913
1012
  ON CONFLICT(user_id) DO UPDATE SET
@@ -919,14 +1018,14 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
919
1018
  last_error_code = excluded.last_error_code,
920
1019
  checked_at = datetime('now'),
921
1020
  synced_at = CASE WHEN ? THEN datetime('now') ELSE connected_account_billing.synced_at END,
922
- updated_at = datetime('now')`,args:[e.userId,e.stripeSubscriptionId,e.stripeSubscriptionItemId,e.priceId,t,e.status,e.lastErrorCode??null,e.synced===!0?1:0,e.synced===!0?1:0]});let r=await $e(e.userId);if(!r)throw new Error("connected account billing state was not persisted");return r}async function $r(e=60,t=20){let r=`-${Math.max(1,Math.round(e))} minutes`;return(await s().execute({sql:`SELECT u.*
1021
+ updated_at = datetime('now')`,args:[e.userId,e.stripeSubscriptionId,e.stripeSubscriptionItemId,e.priceId,t,e.status,e.lastErrorCode??null,e.synced===!0?1:0,e.synced===!0?1:0]});let r=await it(e.userId);if(!r)throw new Error("connected account billing state was not persisted");return r}async function cs(e=60,t=20){let r=`-${Math.max(1,Math.round(e))} minutes`;return(await n().execute({sql:`SELECT u.*
923
1022
  FROM users u
924
1023
  LEFT JOIN connected_account_billing b ON b.user_id = u.id
925
1024
  WHERE u.active = 1
926
1025
  AND u.subscription_id IS NOT NULL
927
1026
  AND (b.checked_at IS NULL OR b.checked_at <= datetime('now', ?))
928
1027
  ORDER BY COALESCE(b.checked_at, u.created_at) ASC
929
- LIMIT ?`,args:[r,Math.max(1,Math.min(100,Math.round(t)))]})).rows.map(i=>N(i))}async function Kr(e,t,r){await s().execute({sql:"UPDATE users SET memory_plan = ?, memory_subscription_id = ? WHERE id = ?",args:[t,r,e]})}async function Vr(e){let r=(await s().execute({sql:"SELECT memory_plan, memory_subscription_id FROM users WHERE id = ?",args:[e]})).rows[0];return{plan:r?.memory_plan!=null?String(r.memory_plan):"free",memory_subscription_id:r?.memory_subscription_id!=null?String(r.memory_subscription_id):null}}async function zr(e){let r=(await s().execute({sql:"SELECT memory_provisioned FROM users WHERE id = ?",args:[e]})).rows[0];return Number(r?.memory_provisioned??0)===1}async function Qr(e,t){await s().execute({sql:"UPDATE users SET memory_provisioned = ? WHERE id = ?",args:[t?1:0,e]})}async function Zr(e){let t=await s().execute({sql:"SELECT * FROM users WHERE memory_subscription_id = ? AND active = 1",args:[e]});return t.rows[0]?N(t.rows[0]):void 0}var I="+3 months";async function R(e){return(await s().execute({sql:`INSERT INTO credit_lots (user_id, amount_mc, remaining_mc, source, expires_at)
1028
+ LIMIT ?`,args:[r,Math.max(1,Math.min(100,Math.round(t)))]})).rows.map(i=>L(i))}async function _s(e,t,r){await n().execute({sql:"UPDATE users SET memory_plan = ?, memory_subscription_id = ? WHERE id = ?",args:[t,r,e]})}async function ds(e){let r=(await n().execute({sql:"SELECT memory_plan, memory_subscription_id FROM users WHERE id = ?",args:[e]})).rows[0];return{plan:r?.memory_plan!=null?String(r.memory_plan):"free",memory_subscription_id:r?.memory_subscription_id!=null?String(r.memory_subscription_id):null}}async function ls(e){let r=(await n().execute({sql:"SELECT memory_provisioned FROM users WHERE id = ?",args:[e]})).rows[0];return Number(r?.memory_provisioned??0)===1}async function Es(e,t){await n().execute({sql:"UPDATE users SET memory_provisioned = ? WHERE id = ?",args:[t?1:0,e]})}async function Ts(e){let t=await n().execute({sql:"SELECT * FROM users WHERE memory_subscription_id = ? AND active = 1",args:[e]});return t.rows[0]?L(t.rows[0]):void 0}var v="+3 months";async function w(e){return(await n().execute({sql:`INSERT INTO credit_lots (user_id, amount_mc, remaining_mc, source, expires_at)
930
1029
  SELECT ?, legacy.balance_mc, legacy.balance_mc, 'migration', datetime('now', ?)
931
1030
  FROM (
932
1031
  SELECT COALESCE(SUM(amount_mc), 0) AS balance_mc
@@ -940,44 +1039,44 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
940
1039
  )
941
1040
  AND NOT EXISTS (
942
1041
  SELECT 1 FROM credit_lots WHERE user_id = ?
943
- )`,args:[e,I,e,e,O,e]})).rowsAffected}async function en(){let e=s(),t=await e.execute({sql:`SELECT id
1042
+ )`,args:[e,v,e,e,C,e]})).rowsAffected}async function ps(){let e=n(),t=await e.execute({sql:`SELECT id
944
1043
  FROM credit_lots
945
1044
  WHERE remaining_mc > 0
946
1045
  AND never_expires = 0
947
1046
  AND expires_at <= datetime('now')
948
- LIMIT 500`});if(t.rows.length===0)return{expired_lots:0,expired_mc:0};let r=[],n=[];for(let c of t.rows){let d=Number(c.id),p=m();r.push({token:p,insertResultIndex:n.length}),n.push({sql:`INSERT OR IGNORE INTO credit_lot_expirations (lot_id, user_id, amount_mc, claim_token)
1047
+ LIMIT 500`});if(t.rows.length===0)return{expired_lots:0,expired_mc:0};let r=[],s=[];for(let _ of t.rows){let d=Number(_.id),E=m();r.push({token:E,insertResultIndex:s.length}),s.push({sql:`INSERT OR IGNORE INTO credit_lot_expirations (lot_id, user_id, amount_mc, claim_token)
949
1048
  SELECT id, user_id, remaining_mc, ?
950
1049
  FROM credit_lots
951
1050
  WHERE id = ?
952
1051
  AND remaining_mc > 0
953
1052
  AND never_expires = 0
954
- AND expires_at <= datetime('now')`,args:[p,d]}),n.push({sql:`UPDATE credit_lots
1053
+ AND expires_at <= datetime('now')`,args:[E,d]}),s.push({sql:`UPDATE credit_lots
955
1054
  SET remaining_mc = 0
956
1055
  WHERE id = ?
957
1056
  AND EXISTS (
958
1057
  SELECT 1 FROM credit_lot_expirations
959
1058
  WHERE lot_id = ? AND claim_token = ?
960
- )`,args:[d,d,p]}),n.push({sql:`INSERT INTO ledger (user_id, amount_mc, operation, description)
1059
+ )`,args:[d,d,E]}),s.push({sql:`INSERT INTO ledger (user_id, amount_mc, operation, description)
961
1060
  SELECT user_id, -amount_mc, 'credit_expired', 'credits expired'
962
1061
  FROM credit_lot_expirations
963
- WHERE lot_id = ? AND claim_token = ?`,args:[d,p]})}let i=await e.batch(n,"write"),a=r.filter(c=>i[c.insertResultIndex]?.rowsAffected===1).map(c=>c.token);if(a.length===0)return{expired_lots:0,expired_mc:0};let o=a.map(()=>"?").join(", "),u=await e.execute({sql:`SELECT user_id, amount_mc
1062
+ WHERE lot_id = ? AND claim_token = ?`,args:[d,E]})}let i=await e.batch(s,"write"),a=r.filter(_=>i[_.insertResultIndex]?.rowsAffected===1).map(_=>_.token);if(a.length===0)return{expired_lots:0,expired_mc:0};let u=a.map(()=>"?").join(", "),c=await e.execute({sql:`SELECT user_id, amount_mc
964
1063
  FROM credit_lot_expirations
965
- WHERE claim_token IN (${o})`,args:a}),_=new Set(u.rows.map(c=>Number(c.user_id)));for(let c of _)await me(c);return{expired_lots:u.rows.length,expired_mc:u.rows.reduce((c,d)=>c+Number(d.amount_mc),0)}}async function tn(){let e=s(),t=await e.execute({sql:`SELECT DISTINCT u.id AS user_id
1064
+ WHERE claim_token IN (${u})`,args:a}),o=new Set(c.rows.map(_=>Number(_.user_id)));for(let _ of o)await we(_);return{expired_lots:c.rows.length,expired_mc:c.rows.reduce((_,d)=>_+Number(d.amount_mc),0)}}async function ms(){let e=n(),t=await e.execute({sql:`SELECT DISTINCT u.id AS user_id
966
1065
  FROM users u
967
1066
  JOIN ledger l ON l.user_id = u.id
968
1067
  WHERE l.created_at < ?
969
- AND NOT EXISTS (SELECT 1 FROM credit_lots WHERE user_id = u.id)`,args:[O]}),r=0,n=0;for(let i of t.rows){let a=Number(i.user_id);if(await R(a)===0)continue;let u=await e.execute({sql:`SELECT amount_mc FROM credit_lots
1068
+ AND NOT EXISTS (SELECT 1 FROM credit_lots WHERE user_id = u.id)`,args:[C]}),r=0,s=0;for(let i of t.rows){let a=Number(i.user_id);if(await w(a)===0)continue;let c=await e.execute({sql:`SELECT amount_mc FROM credit_lots
970
1069
  WHERE user_id = ? AND source = 'migration'
971
- ORDER BY id DESC LIMIT 1`,args:[a]}),_=Number(u.rows[0]?.amount_mc??0);await me(a),r+=1,n+=_}return{migrated:r,total_mc:n}}async function rn(e,t,r,n,i,a){let o=s();await R(e);let u=a?.neverExpires;if(u===void 0&&t>0){let p=await o.execute({sql:"SELECT subscription_tier FROM users WHERE id = ? LIMIT 1",args:[e]});u=String(p.rows[0]?.subscription_tier??"").startsWith("sonic")}let _=u?"9999-12-31 23:59:59":null;if(i){let p=[{sql:"INSERT OR IGNORE INTO ledger (user_id, amount_mc, operation, description, stripe_pi) VALUES (?, ?, ?, ?, ?)",args:[e,t,r,n??null,i]}];t>0&&p.push({sql:`INSERT INTO credit_lots (user_id, amount_mc, remaining_mc, source, stripe_pi, expires_at, never_expires)
1070
+ ORDER BY id DESC LIMIT 1`,args:[a]}),o=Number(c.rows[0]?.amount_mc??0);await we(a),r+=1,s+=o}return{migrated:r,total_mc:s}}async function gs(e,t,r,s,i,a){let u=n();await w(e);let c=a?.neverExpires;if(c===void 0&&t>0){let E=await u.execute({sql:"SELECT subscription_tier FROM users WHERE id = ? LIMIT 1",args:[e]});c=String(E.rows[0]?.subscription_tier??"").startsWith("sonic")}let o=c?"9999-12-31 23:59:59":null;if(i){let E=[{sql:"INSERT OR IGNORE INTO ledger (user_id, amount_mc, operation, description, stripe_pi) VALUES (?, ?, ?, ?, ?)",args:[e,t,r,s??null,i]}];t>0&&E.push({sql:`INSERT INTO credit_lots (user_id, amount_mc, remaining_mc, source, stripe_pi, expires_at, never_expires)
972
1071
  SELECT ?, ?, ?, ?, ?, COALESCE(?, datetime('now', ?)), ?
973
- WHERE changes() = 1`,args:[e,t,t,r,i,_,I,u?1:0]}),p.push({sql:"UPDATE users SET balance_mc = balance_mc + ? WHERE id = ? AND changes() = 1",args:[t,e]}),await o.batch(p,"write");let l=await o.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return Number(l.rows[0]?.balance_mc??0)}let c=[];t>0&&c.push({sql:"INSERT INTO credit_lots (user_id, amount_mc, remaining_mc, source, stripe_pi, expires_at, never_expires) VALUES (?, ?, ?, ?, ?, COALESCE(?, datetime('now', ?)), ?)",args:[e,t,t,r,null,_,I,u?1:0]}),c.push({sql:"UPDATE users SET balance_mc = balance_mc + ? WHERE id = ?",args:[t,e]}),c.push({sql:"INSERT INTO ledger (user_id, amount_mc, operation, description, stripe_pi) VALUES (?, ?, ?, ?, ?)",args:[e,t,r,n??null,null]}),await o.batch(c,"write");let d=await o.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return Number(d.rows[0]?.balance_mc??0)}async function nn(e,t,r,n,i,a){if(!Number.isSafeInteger(t)||t<=0)throw new Error("idempotent credit amount must be a positive integer");if(!i||i.length>500)throw new Error("idempotent credit key is required and must be bounded");let o=s();await R(e);let u=a?.neverExpires;if(u===void 0){let g=await o.execute({sql:"SELECT subscription_tier FROM users WHERE id = ? LIMIT 1",args:[e]});u=String(g.rows[0]?.subscription_tier??"").startsWith("sonic")}let _=u?"9999-12-31 23:59:59":null,c=async()=>{let g=await o.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return Number(g.rows[0]?.balance_mc??0)},d;try{d=await o.batch([{sql:"INSERT OR IGNORE INTO billing_credits (idempotency_key, user_id, amount_mc, operation, description, status) VALUES (?, ?, ?, ?, ?, 'claimed')",args:[i,e,t,r,n]},{sql:"UPDATE billing_credits SET status = 'applying' WHERE idempotency_key = ? AND user_id = ? AND amount_mc = ? AND operation = ? AND description = ? AND status = 'claimed'",args:[i,e,t,r,n]},{sql:`INSERT INTO credit_lots (user_id, amount_mc, remaining_mc, source, stripe_pi, expires_at, never_expires)
1072
+ WHERE changes() = 1`,args:[e,t,t,r,i,o,v,c?1:0]}),E.push({sql:"UPDATE users SET balance_mc = balance_mc + ? WHERE id = ? AND changes() = 1",args:[t,e]}),await u.batch(E,"write");let l=await u.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return Number(l.rows[0]?.balance_mc??0)}let _=[];t>0&&_.push({sql:"INSERT INTO credit_lots (user_id, amount_mc, remaining_mc, source, stripe_pi, expires_at, never_expires) VALUES (?, ?, ?, ?, ?, COALESCE(?, datetime('now', ?)), ?)",args:[e,t,t,r,null,o,v,c?1:0]}),_.push({sql:"UPDATE users SET balance_mc = balance_mc + ? WHERE id = ?",args:[t,e]}),_.push({sql:"INSERT INTO ledger (user_id, amount_mc, operation, description, stripe_pi) VALUES (?, ?, ?, ?, ?)",args:[e,t,r,s??null,null]}),await u.batch(_,"write");let d=await u.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return Number(d.rows[0]?.balance_mc??0)}async function Ns(e,t,r,s,i,a){if(!Number.isSafeInteger(t)||t<=0)throw new Error("idempotent credit amount must be a positive integer");if(!i||i.length>500)throw new Error("idempotent credit key is required and must be bounded");let u=n();await w(e);let c=a?.neverExpires;if(c===void 0){let g=await u.execute({sql:"SELECT subscription_tier FROM users WHERE id = ? LIMIT 1",args:[e]});c=String(g.rows[0]?.subscription_tier??"").startsWith("sonic")}let o=c?"9999-12-31 23:59:59":null,_=async()=>{let g=await u.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return Number(g.rows[0]?.balance_mc??0)},d;try{d=await u.batch([{sql:"INSERT OR IGNORE INTO billing_credits (idempotency_key, user_id, amount_mc, operation, description, status) VALUES (?, ?, ?, ?, ?, 'claimed')",args:[i,e,t,r,s]},{sql:"UPDATE billing_credits SET status = 'applying' WHERE idempotency_key = ? AND user_id = ? AND amount_mc = ? AND operation = ? AND description = ? AND status = 'claimed'",args:[i,e,t,r,s]},{sql:`INSERT INTO credit_lots (user_id, amount_mc, remaining_mc, source, stripe_pi, expires_at, never_expires)
974
1073
  SELECT user_id, amount_mc, amount_mc, operation, NULL, COALESCE(?, datetime('now', ?)), ?
975
1074
  FROM billing_credits
976
- WHERE idempotency_key = ? AND status = 'applying'`,args:[_,I,u?1:0,i]},{sql:`UPDATE users
1075
+ WHERE idempotency_key = ? AND status = 'applying'`,args:[o,v,c?1:0,i]},{sql:`UPDATE users
977
1076
  SET balance_mc = balance_mc + COALESCE((
978
1077
  SELECT amount_mc FROM billing_credits WHERE idempotency_key = ? AND status = 'applying'
979
1078
  ), 0)
980
- WHERE id = ?`,args:[i,e]},{sql:"INSERT INTO ledger (user_id, amount_mc, operation, description) SELECT user_id, amount_mc, operation, description FROM billing_credits WHERE idempotency_key = ? AND status = 'applying'",args:[i]},{sql:"UPDATE billing_credits SET status = 'applied', applied_at = datetime('now') WHERE idempotency_key = ? AND status = 'applying'",args:[i]}],"write")}catch(g){try{let E=(await o.execute({sql:"SELECT user_id, amount_mc, operation, description FROM billing_credits WHERE idempotency_key = ? AND status = 'applied' LIMIT 1",args:[i]})).rows[0];if(E&&Number(E.user_id)===e&&Number(E.amount_mc)===t&&String(E.operation)===r&&String(E.description)===n)return{ok:!0,balance_mc:await c(),duplicate:!0}}catch{}throw g}let l=(await o.execute({sql:"SELECT user_id, amount_mc, operation, description, status FROM billing_credits WHERE idempotency_key = ? LIMIT 1",args:[i]})).rows[0];if(!l||Number(l.user_id)!==e||Number(l.amount_mc)!==t||String(l.operation)!==r||String(l.description)!==n)throw new Error("idempotent credit key conflicts with another credit");return{ok:String(l.status)==="applied",balance_mc:await c(),duplicate:d[1]?.rowsAffected===0&&String(l.status)==="applied"}}async function sn(e,t){return(await s().execute({sql:"SELECT 1 FROM ledger WHERE user_id = ? AND operation = ? LIMIT 1",args:[e,t]})).rows.length>0}async function an(e,t){return(await s().execute({sql:"INSERT OR IGNORE INTO free_credit_refreshes (user_id, month) VALUES (?, ?)",args:[e,t]})).rowsAffected>0}async function on(e,t,r,n){let i=await Ke(e,t,r,n??"",`debit:${m()}`);return{ok:i.ok,balance_mc:i.balance_mc}}async function Ke(e,t,r,n,i){if(!Number.isSafeInteger(t)||t<=0)throw new Error("idempotent debit amount must be a positive integer");if(!i||i.length>500)throw new Error("idempotent debit key is required and must be bounded");let a=s();await R(e);let o;try{o=await a.batch([{sql:"UPDATE billing_debits SET amount_mc = ? WHERE idempotency_key = ? AND user_id = ? AND operation = ? AND description = ? AND status = 'claimed'",args:[t,i,e,r,n]},{sql:"INSERT OR IGNORE INTO billing_debits (idempotency_key, user_id, amount_mc, operation, description, status) VALUES (?, ?, ?, ?, ?, 'claimed')",args:[i,e,t,r,n]},{sql:`UPDATE users
1079
+ WHERE id = ?`,args:[i,e]},{sql:"INSERT INTO ledger (user_id, amount_mc, operation, description) SELECT user_id, amount_mc, operation, description FROM billing_credits WHERE idempotency_key = ? AND status = 'applying'",args:[i]},{sql:"UPDATE billing_credits SET status = 'applied', applied_at = datetime('now') WHERE idempotency_key = ? AND status = 'applying'",args:[i]}],"write")}catch(g){try{let T=(await u.execute({sql:"SELECT user_id, amount_mc, operation, description FROM billing_credits WHERE idempotency_key = ? AND status = 'applied' LIMIT 1",args:[i]})).rows[0];if(T&&Number(T.user_id)===e&&Number(T.amount_mc)===t&&String(T.operation)===r&&String(T.description)===s)return{ok:!0,balance_mc:await _(),duplicate:!0}}catch{}throw g}let l=(await u.execute({sql:"SELECT user_id, amount_mc, operation, description, status FROM billing_credits WHERE idempotency_key = ? LIMIT 1",args:[i]})).rows[0];if(!l||Number(l.user_id)!==e||Number(l.amount_mc)!==t||String(l.operation)!==r||String(l.description)!==s)throw new Error("idempotent credit key conflicts with another credit");return{ok:String(l.status)==="applied",balance_mc:await _(),duplicate:d[1]?.rowsAffected===0&&String(l.status)==="applied"}}async function bs(e,t){return(await n().execute({sql:"SELECT 1 FROM ledger WHERE user_id = ? AND operation = ? LIMIT 1",args:[e,t]})).rows.length>0}async function Ls(e,t){return(await n().execute({sql:"INSERT OR IGNORE INTO free_credit_refreshes (user_id, month) VALUES (?, ?)",args:[e,t]})).rowsAffected>0}async function Ss(e,t,r,s){let i=await at(e,t,r,s??"",`debit:${m()}`);return{ok:i.ok,balance_mc:i.balance_mc}}async function at(e,t,r,s,i){if(!Number.isSafeInteger(t)||t<=0)throw new Error("idempotent debit amount must be a positive integer");if(!i||i.length>500)throw new Error("idempotent debit key is required and must be bounded");let a=n();await w(e);let u;try{u=await a.batch([{sql:"UPDATE billing_debits SET amount_mc = ? WHERE idempotency_key = ? AND user_id = ? AND operation = ? AND description = ? AND status = 'claimed'",args:[t,i,e,r,s]},{sql:"INSERT OR IGNORE INTO billing_debits (idempotency_key, user_id, amount_mc, operation, description, status) VALUES (?, ?, ?, ?, ?, 'claimed')",args:[i,e,t,r,s]},{sql:`UPDATE users
981
1080
  SET balance_mc = balance_mc - ?
982
1081
  WHERE id = ?
983
1082
  AND balance_mc >= ?
@@ -986,7 +1085,7 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
986
1085
  WHERE user_id = ?
987
1086
  AND remaining_mc > 0
988
1087
  AND (never_expires = 1 OR expires_at > datetime('now'))) >= ?
989
- AND EXISTS (SELECT 1 FROM billing_debits WHERE idempotency_key = ? AND user_id = ? AND amount_mc = ? AND operation = ? AND description = ? AND status = 'claimed')`,args:[t,e,t,e,t,i,e,t,r,n]},{sql:"UPDATE billing_debits SET status = 'applying' WHERE idempotency_key = ? AND user_id = ? AND amount_mc = ? AND operation = ? AND description = ? AND status = 'claimed' AND changes() = 1",args:[i,e,t,r,n]},{sql:`INSERT OR IGNORE INTO billing_debit_allocations
1088
+ AND EXISTS (SELECT 1 FROM billing_debits WHERE idempotency_key = ? AND user_id = ? AND amount_mc = ? AND operation = ? AND description = ? AND status = 'claimed')`,args:[t,e,t,e,t,i,e,t,r,s]},{sql:"UPDATE billing_debits SET status = 'applying' WHERE idempotency_key = ? AND user_id = ? AND amount_mc = ? AND operation = ? AND description = ? AND status = 'claimed' AND changes() = 1",args:[i,e,t,r,s]},{sql:`INSERT OR IGNORE INTO billing_debit_allocations
990
1089
  (debit_idempotency_key, lot_id, user_id, amount_mc, expires_at)
991
1090
  WITH ordered AS MATERIALIZED (
992
1091
  SELECT id,
@@ -1013,7 +1112,7 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
1013
1112
  WHERE id IN (
1014
1113
  SELECT lot_id FROM billing_debit_allocations WHERE debit_idempotency_key = ?
1015
1114
  )
1016
- AND EXISTS (SELECT 1 FROM billing_debits WHERE idempotency_key = ? AND status = 'applying')`,args:[i,i,i]},{sql:"INSERT INTO ledger (user_id, amount_mc, operation, description) SELECT user_id, -amount_mc, operation, description FROM billing_debits WHERE idempotency_key = ? AND status = 'applying'",args:[i]},{sql:"UPDATE billing_debits SET status = 'applied', applied_at = datetime('now') WHERE idempotency_key = ? AND status = 'applying'",args:[i]}],"write")}catch(d){try{let l=(await a.execute({sql:"SELECT user_id, amount_mc, operation, description, status FROM billing_debits WHERE idempotency_key = ? AND status = 'applied' LIMIT 1",args:[i]})).rows[0];if(l&&Number(l.user_id)===e&&Number(l.amount_mc)===t&&String(l.operation)===r&&String(l.description)===n){let g=await a.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return{ok:!0,balance_mc:Number(g.rows[0]?.balance_mc??0),duplicate:!0}}}catch{}throw d}let _=(await a.execute({sql:"SELECT user_id, amount_mc, operation, description, status FROM billing_debits WHERE idempotency_key = ? LIMIT 1",args:[i]})).rows[0];if(!_||Number(_.user_id)!==e||Number(_.amount_mc)!==t||String(_.operation)!==r||String(_.description)!==n)throw new Error("idempotent debit key conflicts with another debit");let c=await a.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return{ok:String(_.status)==="applied",balance_mc:Number(c.rows[0]?.balance_mc??0),duplicate:o[2]?.rowsAffected===0&&String(_.status)==="applied"}}async function un(e,t,r,n,i,a){if(!Number.isSafeInteger(r)||r<0)throw new Error("idempotent debit settlement amount must be a non-negative integer");if(!t||t.length>500)throw new Error("idempotent debit settlement key is required and must be bounded");if(!n||!a)throw new Error("idempotent debit settlement operation and source are required");let o=s();await R(e);let u=`debit-settlement:${A("sha256").update(t).digest("hex")}`,_="wallet_hold_settlement",c=m(),d=JSON.stringify({debitIdempotencyKey:t,refundOperation:n,description:i}),p=async()=>{let E=(await o.execute({sql:`SELECT e.user_id,
1115
+ AND EXISTS (SELECT 1 FROM billing_debits WHERE idempotency_key = ? AND status = 'applying')`,args:[i,i,i]},{sql:"INSERT INTO ledger (user_id, amount_mc, operation, description) SELECT user_id, -amount_mc, operation, description FROM billing_debits WHERE idempotency_key = ? AND status = 'applying'",args:[i]},{sql:"UPDATE billing_debits SET status = 'applied', applied_at = datetime('now') WHERE idempotency_key = ? AND status = 'applying'",args:[i]}],"write")}catch(d){try{let l=(await a.execute({sql:"SELECT user_id, amount_mc, operation, description, status FROM billing_debits WHERE idempotency_key = ? AND status = 'applied' LIMIT 1",args:[i]})).rows[0];if(l&&Number(l.user_id)===e&&Number(l.amount_mc)===t&&String(l.operation)===r&&String(l.description)===s){let g=await a.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return{ok:!0,balance_mc:Number(g.rows[0]?.balance_mc??0),duplicate:!0}}}catch{}throw d}let o=(await a.execute({sql:"SELECT user_id, amount_mc, operation, description, status FROM billing_debits WHERE idempotency_key = ? LIMIT 1",args:[i]})).rows[0];if(!o||Number(o.user_id)!==e||Number(o.amount_mc)!==t||String(o.operation)!==r||String(o.description)!==s)throw new Error("idempotent debit key conflicts with another debit");let _=await a.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return{ok:String(o.status)==="applied",balance_mc:Number(_.rows[0]?.balance_mc??0),duplicate:u[2]?.rowsAffected===0&&String(o.status)==="applied"}}async function Rs(e,t,r,s,i,a){if(!Number.isSafeInteger(r)||r<0)throw new Error("idempotent debit settlement amount must be a non-negative integer");if(!t||t.length>500)throw new Error("idempotent debit settlement key is required and must be bounded");if(!s||!a)throw new Error("idempotent debit settlement operation and source are required");let u=n();await w(e);let c=`debit-settlement:${y("sha256").update(t).digest("hex")}`,o="wallet_hold_settlement",_=m(),d=JSON.stringify({debitIdempotencyKey:t,refundOperation:s,description:i}),E=async()=>{let T=(await u.execute({sql:`SELECT e.user_id,
1017
1116
  e.status,
1018
1117
  e.amount_mc AS final_amount_mc,
1019
1118
  e.billing_class,
@@ -1025,7 +1124,7 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
1025
1124
  WHERE e.idempotency_key = ?
1026
1125
  AND d.user_id = e.user_id
1027
1126
  AND d.status = 'applied'
1028
- LIMIT 1`,args:[t,u]})).rows[0];if(!E)return null;if(Number(E.user_id)!==e||String(E.billing_class)!==_||String(E.source_surface)!==a)throw new Error("idempotent debit settlement key conflicts with another settlement");if(String(E.status)!=="settled")return null;let D=Number(E.held_amount_mc),b=Number(E.final_amount_mc);if(!Number.isSafeInteger(D)||!Number.isSafeInteger(b)||b<0||b>D)throw new Error("idempotent debit settlement receipt is invalid");let ge=D-b,H=await o.execute({sql:`WITH ordered AS (
1127
+ LIMIT 1`,args:[t,c]})).rows[0];if(!T)return null;if(Number(T.user_id)!==e||String(T.billing_class)!==o||String(T.source_surface)!==a)throw new Error("idempotent debit settlement key conflicts with another settlement");if(String(T.status)!=="settled")return null;let M=Number(T.held_amount_mc),S=Number(T.final_amount_mc);if(!Number.isSafeInteger(M)||!Number.isSafeInteger(S)||S<0||S>M)throw new Error("idempotent debit settlement receipt is invalid");let fe=M-S,$=await u.execute({sql:`WITH ordered AS (
1029
1128
  SELECT a.amount_mc,
1030
1129
  a.expires_at,
1031
1130
  COALESCE(SUM(a.amount_mc) OVER (
@@ -1041,9 +1140,9 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
1041
1140
  )
1042
1141
  SELECT (SELECT COUNT(*) FROM ordered) AS allocation_count,
1043
1142
  COALESCE(SUM(CASE WHEN expires_at > ? THEN refund_mc ELSE 0 END), 0) AS credited_refund_mc
1044
- FROM refunds`,args:[t,b,String(E.settled_at)]}),B=Number(H.rows[0]?.allocation_count??0)>0?Number(H.rows[0]?.credited_refund_mc??0):0,Ne=await o.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return{balance_mc:Number(Ne.rows[0]?.balance_mc??0),final_amount_mc:b,refund_mc:B,expired_refund_mc:ge-B,duplicate:!0}},l;try{l=await o.batch([{sql:`INSERT OR IGNORE INTO billing_events
1143
+ FROM refunds`,args:[t,S,String(T.settled_at)]}),K=Number($.rows[0]?.allocation_count??0)>0?Number($.rows[0]?.credited_refund_mc??0):0,Oe=await u.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return{balance_mc:Number(Oe.rows[0]?.balance_mc??0),final_amount_mc:S,refund_mc:K,expired_refund_mc:fe-K,duplicate:!0}},l;try{l=await u.batch([{sql:`INSERT OR IGNORE INTO billing_events
1045
1144
  (id, user_id, idempotency_key, billing_class, source_surface, status, amount_mc, metadata)
1046
- VALUES (?, ?, ?, ?, ?, 'settling', ?, ?)`,args:[c,e,u,_,a,r,d]},{sql:`WITH ordered AS (
1145
+ VALUES (?, ?, ?, ?, ?, 'settling', ?, ?)`,args:[_,e,c,o,a,r,d]},{sql:`WITH ordered AS (
1047
1146
  SELECT a.lot_id,
1048
1147
  a.amount_mc,
1049
1148
  a.expires_at,
@@ -1084,14 +1183,14 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
1084
1183
  AND d.user_id = e.user_id
1085
1184
  AND d.status = 'applied'
1086
1185
  AND e.amount_mc BETWEEN 0 AND d.amount_mc
1087
- )`,args:[t,r,e,t,u,e,_,a]},{sql:`UPDATE billing_events
1186
+ )`,args:[t,r,e,t,c,e,o,a]},{sql:`UPDATE billing_events
1088
1187
  SET status = 'applying'
1089
1188
  WHERE idempotency_key = ?
1090
1189
  AND user_id = ?
1091
1190
  AND billing_class = ?
1092
1191
  AND source_surface = ?
1093
1192
  AND status = 'settling'
1094
- AND changes() = 1`,args:[u,e,_,a]},{sql:`WITH ordered AS (
1193
+ AND changes() = 1`,args:[c,e,o,a]},{sql:`WITH ordered AS (
1095
1194
  SELECT a.lot_id,
1096
1195
  a.amount_mc,
1097
1196
  a.expires_at,
@@ -1113,7 +1212,7 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
1113
1212
  SELECT lot_id FROM refunds
1114
1213
  WHERE refund_mc > 0 AND expires_at > datetime('now')
1115
1214
  )
1116
- AND EXISTS (SELECT 1 FROM billing_events WHERE idempotency_key = ? AND status = 'applying')`,args:[t,r,u]},{sql:`WITH ordered AS (
1215
+ AND EXISTS (SELECT 1 FROM billing_events WHERE idempotency_key = ? AND status = 'applying')`,args:[t,r,c]},{sql:`WITH ordered AS (
1117
1216
  SELECT a.amount_mc,
1118
1217
  a.expires_at,
1119
1218
  COALESCE(SUM(a.amount_mc) OVER (
@@ -1146,20 +1245,20 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
1146
1245
  ?,
1147
1246
  ?
1148
1247
  FROM credited
1149
- WHERE refund_mc > 0`,args:[t,r,t,u,n,i]},{sql:`UPDATE billing_events
1248
+ WHERE refund_mc > 0`,args:[t,r,t,c,s,i]},{sql:`UPDATE billing_events
1150
1249
  SET status = 'settled', settled_at = datetime('now')
1151
1250
  WHERE idempotency_key = ?
1152
- AND status = 'applying'`,args:[u]}],"write")}catch(k){try{let E=await p();if(E)return E}catch{}throw k}let g=await p();if(!g)throw new Error("idempotent debit settlement did not reach a durable settled state");return{...g,duplicate:l[0]?.rowsAffected===0}}async function cn(e,t=50){return(await s().execute({sql:"SELECT * FROM ledger WHERE user_id = ? ORDER BY created_at DESC LIMIT ?",args:[e,t]})).rows.map(n=>({id:Number(n.id),user_id:Number(n.user_id),amount_mc:Number(n.amount_mc),operation:String(n.operation),description:n.description!=null?String(n.description):null,stripe_pi:n.stripe_pi!=null?String(n.stripe_pi):null,created_at:String(n.created_at)}))}async function _n(e,t,r){let n=s(),i=r.refund.map(()=>"?").join(", "),a=r.grant.map(()=>"?").join(", "),o=r.purchase.map(()=>"?").join(", "),u=await n.execute({sql:`SELECT
1251
+ AND status = 'applying'`,args:[c]}],"write")}catch(b){try{let T=await E();if(T)return T}catch{}throw b}let g=await E();if(!g)throw new Error("idempotent debit settlement did not reach a durable settled state");return{...g,duplicate:l[0]?.rowsAffected===0}}async function As(e,t=50){return(await n().execute({sql:"SELECT * FROM ledger WHERE user_id = ? ORDER BY created_at DESC LIMIT ?",args:[e,t]})).rows.map(s=>({id:Number(s.id),user_id:Number(s.user_id),amount_mc:Number(s.amount_mc),operation:String(s.operation),description:s.description!=null?String(s.description):null,stripe_pi:s.stripe_pi!=null?String(s.stripe_pi):null,created_at:String(s.created_at)}))}async function ws(e,t,r){let s=n(),i=r.refund.map(()=>"?").join(", "),a=r.grant.map(()=>"?").join(", "),u=r.purchase.map(()=>"?").join(", "),c=await s.execute({sql:`SELECT
1153
1252
  COALESCE(SUM(CASE WHEN amount_mc < 0 AND operation NOT IN (${i}) THEN -amount_mc ELSE 0 END), 0) AS spent_mc,
1154
1253
  COALESCE(SUM(CASE WHEN amount_mc > 0 AND operation IN (${i}) THEN amount_mc ELSE 0 END), 0) AS refunded_mc,
1155
1254
  COALESCE(SUM(CASE WHEN amount_mc > 0 AND operation IN (${a}) THEN amount_mc ELSE 0 END), 0) AS granted_mc,
1156
- COALESCE(SUM(CASE WHEN amount_mc > 0 AND operation IN (${o}) THEN amount_mc ELSE 0 END), 0) AS purchased_mc,
1255
+ COALESCE(SUM(CASE WHEN amount_mc > 0 AND operation IN (${u}) THEN amount_mc ELSE 0 END), 0) AS purchased_mc,
1157
1256
  COALESCE(SUM(amount_mc), 0) AS net_mc
1158
- FROM ledger WHERE user_id = ? AND created_at >= ?`,args:[...r.refund,...r.refund,...r.grant,...r.purchase,e,t]}),_=await n.execute({sql:`SELECT operation, -SUM(amount_mc) AS mc, COUNT(*) AS count
1257
+ FROM ledger WHERE user_id = ? AND created_at >= ?`,args:[...r.refund,...r.refund,...r.grant,...r.purchase,e,t]}),o=await s.execute({sql:`SELECT operation, -SUM(amount_mc) AS mc, COUNT(*) AS count
1159
1258
  FROM ledger
1160
1259
  WHERE user_id = ? AND created_at >= ? AND amount_mc < 0 AND operation NOT IN (${i})
1161
1260
  GROUP BY operation
1162
- ORDER BY mc DESC, operation ASC`,args:[e,t,...r.refund]}),c=u.rows[0];return{spent_mc:Number(c?.spent_mc??0),refunded_mc:Number(c?.refunded_mc??0),granted_mc:Number(c?.granted_mc??0),purchased_mc:Number(c?.purchased_mc??0),net_mc:Number(c?.net_mc??0),by_operation:_.rows.map(d=>({operation:String(d.operation),mc:Number(d.mc),count:Number(d.count)}))}}async function dn(e){return(await s().execute({sql:"SELECT 1 FROM ledger WHERE stripe_pi = ? LIMIT 1",args:[e]})).rows.length>0}async function me(e,t){let r=s();for(let i=0;i<8;i+=1){let o=(await r.execute({sql:`SELECT
1261
+ ORDER BY mc DESC, operation ASC`,args:[e,t,...r.refund]}),_=c.rows[0];return{spent_mc:Number(_?.spent_mc??0),refunded_mc:Number(_?.refunded_mc??0),granted_mc:Number(_?.granted_mc??0),purchased_mc:Number(_?.purchased_mc??0),net_mc:Number(_?.net_mc??0),by_operation:o.rows.map(d=>({operation:String(d.operation),mc:Number(d.mc),count:Number(d.count)}))}}async function fs(e){return(await n().execute({sql:"SELECT 1 FROM ledger WHERE stripe_pi = ? LIMIT 1",args:[e]})).rows.length>0}async function we(e,t){let r=n();for(let i=0;i<8;i+=1){let u=(await r.execute({sql:`SELECT
1163
1262
  u.balance_mc AS cached_balance_mc,
1164
1263
  COUNT(l.id) AS lot_count,
1165
1264
  COALESCE(SUM(CASE
@@ -1169,4 +1268,4 @@ import{createClient as Ce}from"@libsql/client/http";import{createHash as A,rando
1169
1268
  FROM users u
1170
1269
  LEFT JOIN credit_lots l ON l.user_id = u.id
1171
1270
  WHERE u.id = ?
1172
- GROUP BY u.id, u.balance_mc`,args:[e]})).rows[0];if(!o)return 0;if(Number(o.lot_count??0)===0&&(await R(Number(e)),(await r.execute({sql:"SELECT 1 FROM credit_lots WHERE user_id = ? LIMIT 1",args:[e]})).rows.length>0))continue;let u=Number(o.cached_balance_mc??0),_=Number(o.projected_balance_mc??0);if(u===_||(await r.execute({sql:"UPDATE users SET balance_mc = ? WHERE id = ? AND balance_mc = ?",args:[_,e,u]})).rowsAffected===1)return _}let n=await r.execute({sql:"SELECT balance_mc FROM users WHERE id = ? LIMIT 1",args:[e]});return Number(n.rows[0]?.balance_mc??0)}var ln=T.object({id:T.string(),user_id:T.number(),status:T.string().default("pending"),client_domain:T.string(),session_path:T.string(),request:T.string(),result:T.string().nullable(),error:T.string().nullable(),created_at:T.string(),updated_at:T.string()}),En=T.object({id:T.number(),job_id:T.string(),phase:T.string(),completed_at:T.string(),output_summary:T.string()});async function Tn(e){return(await s().execute({sql:"SELECT id, subject, sent_at, opened_at FROM inbox_messages WHERE user_id = ? AND deleted_at IS NULL ORDER BY sent_at DESC, id DESC",args:[e]})).rows.map(r=>({id:String(r.id),subject:String(r.subject),sent_at:String(r.sent_at),opened_at:r.opened_at!=null?String(r.opened_at):null}))}async function pn(e,t){let n=(await s().execute({sql:"SELECT id, subject, body_md, source, sent_at, opened_at FROM inbox_messages WHERE id = ? AND user_id = ? AND deleted_at IS NULL",args:[t,e]})).rows[0];if(n)return{id:String(n.id),subject:String(n.subject),body_md:String(n.body_md),source:String(n.source),sent_at:String(n.sent_at),opened_at:n.opened_at!=null?String(n.opened_at):null}}async function mn(e,t){let r=s();await r.execute({sql:"UPDATE inbox_messages SET opened_at = datetime('now') WHERE id = ? AND user_id = ? AND deleted_at IS NULL AND opened_at IS NULL",args:[t,e]});let i=(await r.execute({sql:"SELECT opened_at FROM inbox_messages WHERE id = ? AND user_id = ? AND deleted_at IS NULL",args:[t,e]})).rows[0];return i&&i.opened_at!=null?String(i.opened_at):null}async function gn(e,t){return(await s().execute({sql:"UPDATE inbox_messages SET deleted_at = datetime('now') WHERE id = ? AND user_id = ? AND deleted_at IS NULL",args:[t,e]})).rowsAffected>0}async function Nn(e,t,r,n="operator"){let i=m();return await s().execute({sql:"INSERT INTO inbox_messages (id, user_id, subject, body_md, source) VALUES (?, ?, ?, ?, ?)",args:[i,e,t,r,n]}),i}async function bn(){return(await s().execute("SELECT id FROM users WHERE active = 1")).rows.map(t=>Number(t.id))}export{Qe as a,be as b,Le as c,L as d,z as e,U as f,ye as g,Ie as h,Z as i,G as j,Y as k,J as l,$ as m,K as n,V as o,O as p,v as q,te as r,s,it as t,at as u,ot as v,ut as w,ct as x,_t as y,Me as z,dt as A,lt as B,Et as C,Tt as D,pt as E,mt as F,gt as G,ae as H,oe as I,Nt as J,bt as K,Lt as L,St as M,Rt as N,wt as O,At as P,ft as Q,Ot as R,xt as S,ht as T,yt as U,It as V,Ct as W,kt as X,Dt as Y,Ut as Z,Pe as _,vt as $,Xt as aa,Mt as ba,Pt as ca,Ft as da,jt as ea,Wt as fa,qt as ga,Ht as ha,_e as ia,Bt as ja,Gt as ka,Yt as la,Jt as ma,$t as na,Kt as oa,P as pa,Vt as qa,zt as ra,Qt as sa,Zt as ta,er as ua,tr as va,qe as wa,He as xa,rr as ya,nr as za,sr as Aa,ir as Ba,ar as Ca,or as Da,ur as Ea,cr as Fa,pe as Ga,_r as Ha,dr as Ia,lr as Ja,Er as Ka,Tr as La,pr as Ma,mr as Na,gr as Oa,Nr as Pa,br as Qa,Lr as Ra,Sr as Sa,Rr as Ta,wr as Ua,Ar as Va,fr as Wa,Or as Xa,xr as Ya,hr as Za,yr as _a,Ir as $a,Cr as ab,kr as bb,Dr as cb,Ur as db,vr as eb,Xr as fb,Mr as gb,Pr as hb,Fr as ib,jr as jb,Wr as kb,qr as lb,Hr as mb,Br as nb,Ye as ob,Gr as pb,Yr as qb,$e as rb,Jr as sb,$r as tb,Kr as ub,Vr as vb,zr as wb,Qr as xb,Zr as yb,I as zb,en as Ab,tn as Bb,rn as Cb,nn as Db,sn as Eb,an as Fb,on as Gb,Ke as Hb,un as Ib,cn as Jb,_n as Kb,dn as Lb,me as Mb,ln as Nb,En as Ob,Tn as Pb,pn as Qb,mn as Rb,gn as Sb,Nn as Tb,bn as Ub};
1271
+ GROUP BY u.id, u.balance_mc`,args:[e]})).rows[0];if(!u)return 0;if(Number(u.lot_count??0)===0&&(await w(Number(e)),(await r.execute({sql:"SELECT 1 FROM credit_lots WHERE user_id = ? LIMIT 1",args:[e]})).rows.length>0))continue;let c=Number(u.cached_balance_mc??0),o=Number(u.projected_balance_mc??0);if(c===o||(await r.execute({sql:"UPDATE users SET balance_mc = ? WHERE id = ? AND balance_mc = ?",args:[o,e,c]})).rowsAffected===1)return o}let s=await r.execute({sql:"SELECT balance_mc FROM users WHERE id = ? LIMIT 1",args:[e]});return Number(s.rows[0]?.balance_mc??0)}var Os=p.object({id:p.string(),user_id:p.number(),status:p.string().default("pending"),client_domain:p.string(),session_path:p.string(),request:p.string(),result:p.string().nullable(),error:p.string().nullable(),created_at:p.string(),updated_at:p.string()}),hs=p.object({id:p.number(),job_id:p.string(),phase:p.string(),completed_at:p.string(),output_summary:p.string()});async function xs(e){return(await n().execute({sql:"SELECT id, subject, sent_at, opened_at FROM inbox_messages WHERE user_id = ? AND deleted_at IS NULL ORDER BY sent_at DESC, id DESC",args:[e]})).rows.map(r=>({id:String(r.id),subject:String(r.subject),sent_at:String(r.sent_at),opened_at:r.opened_at!=null?String(r.opened_at):null}))}async function ys(e,t){let s=(await n().execute({sql:"SELECT id, subject, body_md, source, sent_at, opened_at FROM inbox_messages WHERE id = ? AND user_id = ? AND deleted_at IS NULL",args:[t,e]})).rows[0];if(s)return{id:String(s.id),subject:String(s.subject),body_md:String(s.body_md),source:String(s.source),sent_at:String(s.sent_at),opened_at:s.opened_at!=null?String(s.opened_at):null}}async function Is(e,t){let r=n();await r.execute({sql:"UPDATE inbox_messages SET opened_at = datetime('now') WHERE id = ? AND user_id = ? AND deleted_at IS NULL AND opened_at IS NULL",args:[t,e]});let i=(await r.execute({sql:"SELECT opened_at FROM inbox_messages WHERE id = ? AND user_id = ? AND deleted_at IS NULL",args:[t,e]})).rows[0];return i&&i.opened_at!=null?String(i.opened_at):null}async function Cs(e,t){return(await n().execute({sql:"UPDATE inbox_messages SET deleted_at = datetime('now') WHERE id = ? AND user_id = ? AND deleted_at IS NULL",args:[t,e]})).rowsAffected>0}async function Us(e,t,r,s="operator"){let i=m();return await n().execute({sql:"INSERT INTO inbox_messages (id, user_id, subject, body_md, source) VALUES (?, ?, ?, ?, ?)",args:[i,e,t,r,s]}),i}async function ks(){return(await n().execute("SELECT id FROM users WHERE active = 1")).rows.map(t=>Number(t.id))}export{ct as a,he as b,xe as c,R as d,re as e,F as f,Me as g,Fe as h,ne as i,V as j,z as k,Q as l,Z as m,ee as n,te as o,C as p,q,ce as r,n as s,Nt as t,bt as u,Lt as v,St as w,Rt as x,At as y,wt as z,ft as A,$e as B,Ot as C,ht as D,xt as E,yt as F,It as G,Ct as H,Ut as I,Te as J,pe as K,kt as L,Dt as M,vt as N,Xt as O,Mt as P,Ft as Q,Pt as R,qt as S,Wt as T,jt as U,Ht as V,Bt as W,Gt as X,Yt as Y,Jt as Z,$t as _,Kt as $,Ke as aa,Vt as ba,zt as ca,Qt as da,Zt as ea,er as fa,tr as ga,rr as ha,sr as ia,nr as ja,Ne as ka,ir as la,ar as ma,or as na,ur as oa,cr as pa,_r as qa,H as ra,dr as sa,lr as ta,Er as ua,Tr as va,pr as wa,mr as xa,Ze as ya,et as za,gr as Aa,Nr as Ba,br as Ca,Lr as Da,Sr as Ea,Rr as Fa,Ar as Ga,wr as Ha,Ae as Ia,fr as Ja,Or as Ka,hr as La,xr as Ma,yr as Na,Ir as Oa,Cr as Pa,Ur as Qa,kr as Ra,Dr as Sa,vr as Ta,Xr as Ua,Mr as Va,Fr as Wa,Pr as Xa,qr as Ya,Wr as Za,jr as _a,Hr as $a,Br as ab,Gr as bb,Yr as cb,Jr as db,$r as eb,Kr as fb,Vr as gb,zr as hb,Qr as ib,Zr as jb,es as kb,ts as lb,rs as mb,ss as nb,ns as ob,is as pb,st as qb,as as rb,os as sb,it as tb,us as ub,cs as vb,_s as wb,ds as xb,ls as yb,Es as zb,Ts as Ab,v as Bb,ps as Cb,ms as Db,gs as Eb,Ns as Fb,bs as Gb,Ls as Hb,Ss as Ib,at as Jb,Rs as Kb,As as Lb,ws as Mb,fs as Nb,we as Ob,Os as Pb,hs as Qb,xs as Rb,ys as Sb,Is as Tb,Cs as Ub,Us as Vb,ks as Wb};