mcp-scraper 0.96.0 → 0.96.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 (41) hide show
  1. package/CHANGELOG.md +20 -1
  2. package/README.md +3 -1
  3. package/dist/{actions-YCMJY3PF.js → actions-R4EJDLRO.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/{bundle-TTJP6DHU.js → bundle-FCXZMIRB.js} +1 -1
  11. package/dist/{chunk-ZPQNY5TI.js → chunk-5LYINW7Z.js} +8 -1
  12. package/dist/{chunk-R5LJL6IR.js → chunk-6BD75VKS.js} +30 -37
  13. package/dist/{chunk-6SNOUSSZ.js → chunk-7WPCGRD7.js} +1 -1
  14. package/dist/{chunk-DGAW7FD7.js → chunk-BPKTUCV7.js} +1 -1
  15. package/dist/{chunk-QWE7VKIX.js → chunk-CORWWDHL.js} +1 -1
  16. package/dist/chunk-CVQUHVHX.js +1 -0
  17. package/dist/{chunk-VAC3SQ5T.js → chunk-FB4KBB5W.js} +1 -1
  18. package/dist/{chunk-HJIOH7HF.js → chunk-H6MODA7W.js} +2 -2
  19. package/dist/{chunk-JAV5V3JT.js → chunk-HVQZRQRJ.js} +19 -19
  20. package/dist/{chunk-2PRH4Z3N.js → chunk-IY6ZUUY7.js} +29 -37
  21. package/dist/chunk-JHT6A4U6.js +11 -0
  22. package/dist/{chunk-ARSQZCTJ.js → chunk-RIHI3KH7.js} +255 -245
  23. package/dist/{chunk-LFRAA3MY.js → chunk-RN4VG3VH.js} +1 -1
  24. package/dist/{chunk-SNJR5N36.js → chunk-RYX4FJVH.js} +1 -1
  25. package/dist/{chunk-JW4GDY7S.js → chunk-SE4VKLEC.js} +1 -1
  26. package/dist/{chunk-TPN25AFZ.js → chunk-SFUOSJ3A.js} +1 -1
  27. package/dist/{chunk-GVYGAZV7.js → chunk-UXNR3K6I.js} +1 -1
  28. package/dist/{chunk-FRXKMOXI.js → chunk-ZTMQEDIB.js} +1 -1
  29. package/dist/{dispatch-3HY4735M.js → dispatch-P7IY75LH.js} +1 -1
  30. package/dist/index.cjs +36 -36
  31. package/dist/index.d.cts +3 -0
  32. package/dist/index.d.ts +3 -0
  33. package/dist/index.js +1 -1
  34. package/dist/{queue-HUP2GNXF.js → queue-AC4XKD6Z.js} +1 -1
  35. package/dist/{reconciliation-ANXNJWME.js → reconciliation-UZUZ6B74.js} +1 -1
  36. package/dist/{server-VQU6S24A.js → server-DXZ27KQO.js} +488 -488
  37. package/dist/{settlement-6CCE2PDH.js → settlement-6CS4JZTY.js} +1 -1
  38. package/dist/{worker-5G5BK23B.js → worker-ATRD6VKM.js} +1 -1
  39. package/package.json +1 -1
  40. package/dist/chunk-7UHDOIUE.js +0 -1
  41. package/dist/chunk-OB6E6UTD.js +0 -1
@@ -1,4 +1,4 @@
1
- import{$ as E,B as R,D as S,La as C,Ma as P,Y as v,_ as h,ha as T,ja as w,ka as _,la as y,x as u,y as f,z as g}from"./chunk-ARSQZCTJ.js";import{a as x}from"./chunk-VAC3SQ5T.js";import{a as c}from"./chunk-7UHDOIUE.js";import{readFileSync as L}from"fs";import{homedir as B}from"os";import{join as U}from"path";import{serveStdio as Y}from"@modelcontextprotocol/server/stdio";import{McpServer as J}from"@modelcontextprotocol/server";var I=new Map(_.map(r=>[r.upstreamName,r.id]));function N(r){let s=r.split(`
1
+ import{$ as E,B as R,D as S,La as C,Ma as P,Y as v,_ as h,ha as T,ja as w,ka as _,la as y,x as u,y as f,z as g}from"./chunk-RIHI3KH7.js";import{a as x}from"./chunk-FB4KBB5W.js";import{a as c}from"./chunk-CVQUHVHX.js";import{readFileSync as L}from"fs";import{homedir as B}from"os";import{join as U}from"path";import{serveStdio as Y}from"@modelcontextprotocol/server/stdio";import{McpServer as J}from"@modelcontextprotocol/server";var I=new Map(_.map(r=>[r.upstreamName,r.id]));function N(r){let s=r.split(`
2
2
  `).filter(t=>t.startsWith("data:")).map(t=>t.slice(5).trim()).filter(Boolean);if(!s.length)return JSON.parse(r);for(let t of s){let e=JSON.parse(t);if(e.result||e.error)return e}throw new Error("hosted MCP returned no JSON-RPC result")}function l(r){return{content:[{type:"text",text:JSON.stringify({ok:!1,error:r})}],isError:!0}}var p=class{baseUrl;apiKey;constructor(s,t){this.baseUrl=s.replace(/\/$/,""),this.apiKey=t}async callMemoryTool(s,t){let e=I.get(s);if(!e)return l(`unknown memory tool: ${s}`);try{let n=await fetch(`${this.baseUrl}/mcp`,{method:"POST",headers:{"content-type":"application/json",accept:"application/json, text/event-stream","x-api-key":this.apiKey},body:JSON.stringify({jsonrpc:"2.0",id:`memory:${e}`,method:"tools/call",params:{name:e,arguments:t}})}),i=await n.text();if(!n.ok)return l(`hosted memory ${e} failed (HTTP ${n.status})`);let o=N(i);return o.error?l(o.error.message??`hosted memory ${e} failed`):o.result??l(`hosted memory ${e} returned no result`)}catch(n){return l(n instanceof Error?n.message:`hosted memory ${e} call failed`)}}};function M(r,s){if(s.length===0)throw new Error("Restricted MCP tool allowlist must contain at least one tool name");let t=new Set;for(let o of s){if(typeof o!="string"||o.trim()!==o||o.length===0)throw new Error("Restricted MCP tool allowlist contains a malformed tool name");if(t.has(o))throw new Error(`Restricted MCP tool allowlist contains duplicate tool name: ${o}`);t.add(o)}let e=new Set,n=r,i=n.registerTool.bind(r);return n.registerTool=(o,a,m)=>{if(t.has(o))return e.add(o),i(o,a,m)},{assertComplete(){let o=[...t].filter(a=>!e.has(a));if(o.length>0)throw new Error(`Restricted MCP tool allowlist contains unknown or unavailable tool names: ${o.join(", ")}`)},registeredToolNames(){return[...e]}}}import{Client as b,StreamableHTTPClientTransport as k}from"@modelcontextprotocol/client";var $=new Set(["artifact_read","artifact_describe","artifact_download","report_artifact_read"]),A=()=>({content:[{type:"text",text:"Retained file storage is unavailable. Preserve the artifactId and retry retrieval; do not repeat acquisition."}],isError:!0});function O(r,s,t={}){return async(e,n)=>{if(!$.has(e))return A();let i=new b({name:"mcp-scraper-artifact-client",version:c},{versionNegotiation:{mode:"auto"}}),o=AbortSignal.timeout(3e4);try{let a=new k(new URL(`${r.replace(/\/$/,"")}/mcp`),{requestInit:{signal:o,headers:{Authorization:`Bearer ${s}`,"x-api-key":s,...t.localNetworkAccess?{"x-mcp-scraper-local-network":"1"}:{}}}});return await i.connect(a,{signal:o,timeout:3e4}),await i.callTool({name:e,arguments:n},{signal:o,timeout:3e4})}catch{return A()}finally{await i.close().catch(()=>{})}}}var G=new Set(["paa","serp","browser-agent","scheduled-results","memory"]);function K(){let s=[process.env.MCP_SCRAPER_KEY_PATH?.trim(),U(B(),".mcp-scraper-key")].filter(Boolean);for(let t of s)try{let e=L(t,"utf8").trim();if(e)return e}catch{}}function j(r,s={}){let t=s.toolsets??G,e=process.env.MCP_SCRAPER_BASE_URL?.trim()||process.env.MCP_BASE_URL?.trim()||"https://mcpscraper.dev",n=R(),i=S({deploymentProfile:n,transportProfile:"stdio",baseUrl:e,explicitlyEnabled:process.env.MCP_SCRAPER_ALLOW_PRIVATE_NETWORK==="1"}),o=process.env.BROWSER_AGENT_CONSOLE_URL?.trim()||e,a=new J({name:"mcp-scraper",version:c},{instructions:f,cacheHints:{"server/discover":{ttlMs:3e5,cacheScope:"private"},"tools/list":{ttlMs:3e5,cacheScope:"private"},"prompts/list":{ttlMs:3e5,cacheScope:"private"},"resources/list":{ttlMs:3e5,cacheScope:"private"},"resources/templates/list":{ttlMs:3e5,cacheScope:"private"},"resources/read":{ttlMs:6e4,cacheScope:"private"}}});g(a);let m=s.allowedToolNames?M(a,s.allowedToolNames):void 0,d=s.httpExecutor??new T(e,r,{localNetworkAccess:i,analyticsIdentity:()=>E(a.server.getClientVersion()?.name)});return t.has("paa")&&h(a,d,{ownerId:v(r),deploymentProfile:n,transportProfile:"stdio",baseUrl:e,localNetworkAccess:i,taskHandleSecret:r,remoteArtifactAccess:O(e,r,{localNetworkAccess:i})}),t.has("serp")&&u(a,d,{exposeDevelopmentDiagnostics:n==="development"||n==="test"}),t.has("browser-agent")&&w(a,{baseUrl:e,apiKey:r,consoleBaseUrl:o}),t.has("scheduled-results")&&P(a,new C(e,r)),t.has("memory")&&y(a,new p(e,r)),m?.assertComplete(),a}function Re(r={}){let s=process.argv.includes("--stdio")||process.env.MCP_SCRAPER_FORCE_STDIO==="1",t=!!(process.stdin.isTTY&&process.stdout.isTTY),e=process.argv.includes("--help")||process.argv.includes("-h");if(!s&&(t||e)){let i=process.argv.includes("--no-color")||process.env.NO_COLOR!==void 0||process.env.FORCE_COLOR==="0"||!process.stdout.isTTY;process.stdout.write(x({version:c,color:!i,apiKeyConfigured:!!process.env.MCP_SCRAPER_API_KEY?.trim()})),process.exit(0)}let n=(process.env.MCP_SCRAPER_API_KEY??process.env.MCP_SCRAPER_KEY??process.env.MCP_API_KEY??K())?.trim();n||(process.stderr.write(`MCP_SCRAPER_API_KEY env var or ~/.mcp-scraper-key is required
3
3
  `),process.exit(1)),Y(()=>j(n,r),{legacy:"serve",onerror(i){process.stderr.write(`${i.message}
4
4
  `)}})}export{Re as a};
@@ -1 +1 @@
1
- import{c as j}from"./chunk-DGAW7FD7.js";import{k as X}from"./chunk-FRXKMOXI.js";import{c as A,d as $,g as b,h as C,n as K,o as U,p as G,q as M,r as D,s as W,y as q,z as F}from"./chunk-6SNOUSSZ.js";import{a as B,b as L,c as H}from"./chunk-QER2ELZP.js";import{b as k,c as S,d as y,e as x,f as O,g as I,h,i as m,k as E,o as N}from"./chunk-HUNSEGUN.js";import{h as v,i as z}from"./chunk-C7MGJUTU.js";import{a as d,b as J,c as T,d as R}from"./chunk-HNNYXMSI.js";import{randomUUID as oe}from"crypto";import{createHash as Q,randomUUID as V}from"crypto";function _(e,i=new Set){if(e===null||typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return e;if(typeof e!="object"||!e)throw new d("Operation inputs must be finite JSON data");if(i.has(e))throw new d("Operation inputs cannot be cyclic");if(!Array.isArray(e)&&![Object.prototype,null].includes(Object.getPrototypeOf(e)))throw new d("Operation inputs must be plain JSON data");i.add(e);try{return Array.isArray(e)?e.map(t=>_(t,i)):Object.fromEntries(Object.keys(e).sort().map(t=>[t,_(e[t],i)]))}finally{i.delete(e)}}async function P(e){if(!Number.isSafeInteger(e.userId)||e.userId<=0)throw new d("Authenticated operation principal is required");if(e.jobId!=null&&(!e.jobId.trim()||e.jobId.length>512))throw new d("Operation job ID is invalid");let i=e.tool.trim();if(!i||i.length>100)throw new d("Operation tool is required and bounded");if(e.idempotencyKey!=null&&(!e.idempotencyKey.trim()||e.idempotencyKey.length>512))throw new d("Operation idempotency key is invalid");let t=e.leaseMs??3e5;if(!Number.isSafeInteger(t)||t<1e3||t>36e5)throw new d("Execution lease must be between one second and one hour");let n=JSON.stringify(_(e.normalizedInput));if(Buffer.byteLength(n)>64*1024)throw new d("Operation inputs exceed 64 KiB");let r=e.idempotencyKey?.trim()??V();return E({userId:e.userId,ownerScope:`user:${e.userId}`,tool:i,jobId:e.jobId??null,normalizedFlags:e.normalizedInput,idempotencyKey:r,requestFingerprint:Q("sha256").update(n).digest("hex")},V(),t,e.storeGate)}async function Y(e){let i=JSON.stringify(_(e.normalizedInput));if(!Number.isSafeInteger(e.userId)||e.userId<=0||Buffer.byteLength(i)>64*1024)throw new d("Invalid operation receipt principal/input");let{readOperationIntentResult:t}=await import("./repository-4EC5EXVN.js"),{operationIdentityHash:n}=await import("./contracts-GUXGFCVV.js");return t(e.userId,n(`user:${e.userId}\0${e.tool}\0${e.idempotencyKey}`),Q("sha256").update(i).digest("hex"))}async function we(e){let i=Date.now()+27e4,t=e.idempotencyKey?.trim()??oe();if(!t||t.length>512)return{status:400,body:{error_code:"invalid_request",message:"Idempotency-Key must contain 1 to 512 characters"}};let n=(a,c,p)=>({...a,body:{...a.body,operation:{runId:c,idempotencyKey:t,state:p}}}),r=(a,c,p)=>n({status:c==="pending"?202:503,headers:{"Retry-After":"2"},body:{...v({errorCode:"response_lost",retryable:!0,chargeStatus:p,details:{retry_guidance:"Retry the identical request with the returned idempotencyKey. Pending work is not started again; a saved response replays. Unknown work permits compensation only."}}),message:c==="pending"?"This operation is still running. Retry with the same idempotencyKey.":"The execution outcome is unknown. Retry with the same idempotencyKey for result or compensation recovery."}},a,c),s;try{s=await P({...e,idempotencyKey:t,leaseMs:3e5})}catch(a){return a instanceof d?n({status:400,body:{error_code:"invalid_request",message:a.message,retryable:!1}},null,"not_started"):a instanceof J?n({status:409,body:{error_code:"idempotency_conflict",message:a.message,retryable:!1}},null,"conflict"):r(null,"unknown")}let o=s.kind==="claimed"?s.claim.runId:s.runId;if(s.kind==="replay"){let a=JSON.parse(s.result.json);return!a||typeof a.status!="number"||!a.body||typeof a.body!="object"?r(o,"unknown"):n(a,o,"replayed")}if(s.kind==="pending")return r(o,"pending");if(s.kind==="unknown")try{let a=await y(o,e.userId);if(!a)return r(o,"unknown");let c=await e.recover(a);if(c.recover)return await h(a),n(c.reply,o,"unknown");let p=n(c.reply,o,"recovered_unknown"),l={json:JSON.stringify(p),status:"unknown"};return await O(a,l)?p:r(o,"unknown")}catch{return r(o,"unknown","refund_pending")}if(s.kind!=="claimed")return r(o,"unknown");let u=s.claim,f;try{if(f=await e.prepare(),f.rejection)return await I(u),n(f.rejection,o,"not_started");if(!await k(u))return r(o,"unknown");let a={claim:u,deadlineAt:i,assertActive:async()=>{if(B(i),!await m(u))throw Error("Execution ownership is no longer current")}},c;try{c=await e.execute(a,f.value)}catch{return await h(u),r(o,"unknown","refund_pending")}if(c.recover)return await h(u),n(c.reply,o,"unknown");let p=n(c.reply,o,c.reply.status<400?"succeeded":"failed");try{return await x(u,{json:JSON.stringify(p),status:p.status<400?"succeeded":"failed"})?p:r(o,"unknown")}catch{return await h(u).catch(()=>{}),r(o,"unknown")}}catch{return await I(u).catch(()=>{}),r(o,"unknown")}finally{await f?.release().catch(()=>{})}}var g=3e5;function ee(e){if(!e?.trim()||e.length>512)throw new d("A bounded framework workflow ID is required");return T(`workflow:${e}`)}async function ye(e){if(!Number.isSafeInteger(e.userId)||e.userId<=0)throw new d("Workflow principal is required");let i=ee(e.workflowId),t=await E(e,i,g);if(t.kind==="claimed"){let n;try{n=await k(t.claim)}catch(r){if(!await m(t.claim))throw r;n=!0}if(!n)throw Error("workflow_execution_start_unknown");return t}if(t.kind==="pending"){let n={runId:t.runId,userId:e.userId,token:i};if(await m(n)&&await S(n,g))return{kind:"claimed",claim:n}}return t}var te=e=>`${e.workflow.runId}:${e.phase}`;async function he(e){if(!await S(e.workflow,g))throw Error("workflow_execution_not_current");let i=te(e),t=await P({userId:e.workflow.userId,tool:e.tool,jobId:e.jobId,normalizedInput:e.normalizedInput,idempotencyKey:i,leaseMs:g});if(t.kind==="replay"){if(t.result.status!=="succeeded")throw Error(`operation_phase_unknown:${t.runId}`);return JSON.parse(t.result.json)}if(t.kind!=="claimed")throw Error(`operation_phase_${t.kind}:${t.runId}`);let n=t.claim;try{await e.prepare()}catch(r){throw await I(n).catch(()=>{}),r}try{let r;try{r=await k(n)}catch(a){if(!await m(n))throw a;r=!0}if(!r)throw Error("operation_phase_start_unknown");let s=Date.now()+g,o=async()=>{if(Date.now()>=s)throw new L(e.phase);if(!await m(e.workflow)||!await m(n))throw Error("operation_phase_claim_not_current")};await o();let u=await H(s,()=>e.execute({claim:n,deadlineAt:s,assertActive:o}),e.phase);await o();let f=JSON.stringify(u);if(f==null||!await x(n,{status:"succeeded",json:f}))throw Error("operation_phase_publication_unknown");return u}catch(r){await h(n).catch(()=>{});let s=await y(n.runId,n.userId).catch(()=>null);throw s&&await O(s,{status:"unknown",json:JSON.stringify({phase:e.phase,outcome:"unknown"})}).catch(()=>{}),r}}async function be(e,i){let t=await Y({userId:e.workflow.userId,tool:e.tool,idempotencyKey:te(e),normalizedInput:e.normalizedInput});if(!t||t.result.status!=="succeeded"||R({value:JSON.parse(t.result.json)})!==R({value:i}))throw Error("operation_phase_cache_receipt_unknown")}async function ge(e,i,t){let n={runId:e,userId:i,token:ee(t)};if(await m(n))return{claim:n,recovery:!1};let r=await y(e,i);return r?{claim:r,recovery:!0}:null}async function re(e,i,t){let n={json:JSON.stringify(i),status:e.recovery?"unknown":t};if(!(e.recovery?await O(e.claim,n,e.settlementGate):await x(e.claim,n)))throw Error("workflow_result_publication_unknown")}async function je(e){if(!await b(e))return{kind:"missing",body:{error:"job not found"}};let t=await M(e);if(!t)return{kind:"conflict",body:{error:"Only failed or expired recovery jobs can be re-finalized.",status:(await b(e))?.status??"missing"}};let n=t.executionGeneration;if(!await D(e,n))return{kind:"conflict",body:{error:"job state changed during re-finalization claim"}};let r;try{r=await X(t,{})}catch(l){throw await F(e,l instanceof Error?l.message:String(l),void 0,n).catch(()=>!1),l}let s=A(t),o=$(t,s.creditTruncated),u=o==="failed"?`No pages were extracted successfully (${t.failedUrls} failed, ${t.remainingUrls} remaining).`:o==="partial"?`${t.successfulUrls} pages succeeded; ${t.failedUrls} failed and ${t.remainingUrls} remain.${s.creditTruncated?` Credit availability limited this request from ${s.requestedMaxPages} to ${s.effectiveMaxPages} pages.`:""}`:null,f;try{f=await q(e,r,o,u,!1,null,n)}catch(l){let w=await b(e).catch(()=>null);if(!w||w.id!==e||w.executionGeneration!==n||w.status!==o||JSON.stringify(w.artifacts)!==JSON.stringify(r)||w.error!==(u?z(u).slice(0,2e3):null)||w.publicError!==null)throw l;f=!0}if(!f)return{kind:"conflict",body:{error:"job state changed during re-finalization"}};let a=await b(e);if(!a||a.executionGeneration!==n||a.status!==o)return{kind:"conflict",body:{error:"job state changed before re-finalization settlement"}};let c="already_settled_or_refunded";if(a.billedMc==null&&a.userId!=null){let l=await j(a);if(!l)throw Error("extract_settlement_acknowledgment_unknown");c=`settled: billed ${l.netChargeMc} mc, refunded ${l.refundMc} mc${l.expiredRefundMc?`, expired refund ${l.expiredRefundMc} mc`:""}`}let p=r.find(l=>l.contentType==="application/zip"||l.filename?.endsWith(".zip"));return{kind:"complete",body:{ok:!0,jobId:e,artifacts:r.length,settlement:c,bundleUrl:p?.url??null,bundleBytes:p?.bytes??null}}}async function Pe(e=25){let i=await U(e);for(let r of i)await G(r.id).catch(()=>!1);let t=await C(e),n={checked:new Set([...i,...t].map(r=>r.id)).size,settled:0,failed:0};for(let r of t){if(r.userId==null){await W(r.id,"Settlement abandoned because the legacy job has no user owner.",r.executionGeneration??0),n.failed+=1;continue}try{if(!await j(r))throw Error("extract_settlement_acknowledgment_unknown");if(r.executionGeneration===0&&await N(`extract-site:${r.id}`,r.userId)){let o=await y(`extract-site:${r.id}`,r.userId);o&&await re({claim:o,recovery:!0},{jobId:r.id,status:r.status,artifacts:r.artifacts??[]},"unknown")}n.settled+=1}catch(s){n.failed+=1;let o=s instanceof Error?s.message:String(s);await K(r.id,o,r.executionGeneration??0).catch(()=>{}),console.warn("[site-extract/reconcile]",r.id,o)}}return n}export{we as a,g as b,ee as c,ye as d,he as e,be as f,ge as g,re as h,je as i,Pe as j};
1
+ import{c as j}from"./chunk-BPKTUCV7.js";import{k as X}from"./chunk-ZTMQEDIB.js";import{c as A,d as $,g as b,h as C,n as K,o as U,p as G,q as M,r as D,s as W,y as q,z as F}from"./chunk-7WPCGRD7.js";import{a as B,b as L,c as H}from"./chunk-QER2ELZP.js";import{b as k,c as S,d as y,e as x,f as O,g as I,h,i as m,k as E,o as N}from"./chunk-HUNSEGUN.js";import{h as v,i as z}from"./chunk-C7MGJUTU.js";import{a as d,b as J,c as T,d as R}from"./chunk-HNNYXMSI.js";import{randomUUID as oe}from"crypto";import{createHash as Q,randomUUID as V}from"crypto";function _(e,i=new Set){if(e===null||typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return e;if(typeof e!="object"||!e)throw new d("Operation inputs must be finite JSON data");if(i.has(e))throw new d("Operation inputs cannot be cyclic");if(!Array.isArray(e)&&![Object.prototype,null].includes(Object.getPrototypeOf(e)))throw new d("Operation inputs must be plain JSON data");i.add(e);try{return Array.isArray(e)?e.map(t=>_(t,i)):Object.fromEntries(Object.keys(e).sort().map(t=>[t,_(e[t],i)]))}finally{i.delete(e)}}async function P(e){if(!Number.isSafeInteger(e.userId)||e.userId<=0)throw new d("Authenticated operation principal is required");if(e.jobId!=null&&(!e.jobId.trim()||e.jobId.length>512))throw new d("Operation job ID is invalid");let i=e.tool.trim();if(!i||i.length>100)throw new d("Operation tool is required and bounded");if(e.idempotencyKey!=null&&(!e.idempotencyKey.trim()||e.idempotencyKey.length>512))throw new d("Operation idempotency key is invalid");let t=e.leaseMs??3e5;if(!Number.isSafeInteger(t)||t<1e3||t>36e5)throw new d("Execution lease must be between one second and one hour");let n=JSON.stringify(_(e.normalizedInput));if(Buffer.byteLength(n)>64*1024)throw new d("Operation inputs exceed 64 KiB");let r=e.idempotencyKey?.trim()??V();return E({userId:e.userId,ownerScope:`user:${e.userId}`,tool:i,jobId:e.jobId??null,normalizedFlags:e.normalizedInput,idempotencyKey:r,requestFingerprint:Q("sha256").update(n).digest("hex")},V(),t,e.storeGate)}async function Y(e){let i=JSON.stringify(_(e.normalizedInput));if(!Number.isSafeInteger(e.userId)||e.userId<=0||Buffer.byteLength(i)>64*1024)throw new d("Invalid operation receipt principal/input");let{readOperationIntentResult:t}=await import("./repository-4EC5EXVN.js"),{operationIdentityHash:n}=await import("./contracts-GUXGFCVV.js");return t(e.userId,n(`user:${e.userId}\0${e.tool}\0${e.idempotencyKey}`),Q("sha256").update(i).digest("hex"))}async function we(e){let i=Date.now()+27e4,t=e.idempotencyKey?.trim()??oe();if(!t||t.length>512)return{status:400,body:{error_code:"invalid_request",message:"Idempotency-Key must contain 1 to 512 characters"}};let n=(a,c,p)=>({...a,body:{...a.body,operation:{runId:c,idempotencyKey:t,state:p}}}),r=(a,c,p)=>n({status:c==="pending"?202:503,headers:{"Retry-After":"2"},body:{...v({errorCode:"response_lost",retryable:!0,chargeStatus:p,details:{retry_guidance:"Retry the identical request with the returned idempotencyKey. Pending work is not started again; a saved response replays. Unknown work permits compensation only."}}),message:c==="pending"?"This operation is still running. Retry with the same idempotencyKey.":"The execution outcome is unknown. Retry with the same idempotencyKey for result or compensation recovery."}},a,c),s;try{s=await P({...e,idempotencyKey:t,leaseMs:3e5})}catch(a){return a instanceof d?n({status:400,body:{error_code:"invalid_request",message:a.message,retryable:!1}},null,"not_started"):a instanceof J?n({status:409,body:{error_code:"idempotency_conflict",message:a.message,retryable:!1}},null,"conflict"):r(null,"unknown")}let o=s.kind==="claimed"?s.claim.runId:s.runId;if(s.kind==="replay"){let a=JSON.parse(s.result.json);return!a||typeof a.status!="number"||!a.body||typeof a.body!="object"?r(o,"unknown"):n(a,o,"replayed")}if(s.kind==="pending")return r(o,"pending");if(s.kind==="unknown")try{let a=await y(o,e.userId);if(!a)return r(o,"unknown");let c=await e.recover(a);if(c.recover)return await h(a),n(c.reply,o,"unknown");let p=n(c.reply,o,"recovered_unknown"),l={json:JSON.stringify(p),status:"unknown"};return await O(a,l)?p:r(o,"unknown")}catch{return r(o,"unknown","refund_pending")}if(s.kind!=="claimed")return r(o,"unknown");let u=s.claim,f;try{if(f=await e.prepare(),f.rejection)return await I(u),n(f.rejection,o,"not_started");if(!await k(u))return r(o,"unknown");let a={claim:u,deadlineAt:i,assertActive:async()=>{if(B(i),!await m(u))throw Error("Execution ownership is no longer current")}},c;try{c=await e.execute(a,f.value)}catch{return await h(u),r(o,"unknown","refund_pending")}if(c.recover)return await h(u),n(c.reply,o,"unknown");let p=n(c.reply,o,c.reply.status<400?"succeeded":"failed");try{return await x(u,{json:JSON.stringify(p),status:p.status<400?"succeeded":"failed"})?p:r(o,"unknown")}catch{return await h(u).catch(()=>{}),r(o,"unknown")}}catch{return await I(u).catch(()=>{}),r(o,"unknown")}finally{await f?.release().catch(()=>{})}}var g=3e5;function ee(e){if(!e?.trim()||e.length>512)throw new d("A bounded framework workflow ID is required");return T(`workflow:${e}`)}async function ye(e){if(!Number.isSafeInteger(e.userId)||e.userId<=0)throw new d("Workflow principal is required");let i=ee(e.workflowId),t=await E(e,i,g);if(t.kind==="claimed"){let n;try{n=await k(t.claim)}catch(r){if(!await m(t.claim))throw r;n=!0}if(!n)throw Error("workflow_execution_start_unknown");return t}if(t.kind==="pending"){let n={runId:t.runId,userId:e.userId,token:i};if(await m(n)&&await S(n,g))return{kind:"claimed",claim:n}}return t}var te=e=>`${e.workflow.runId}:${e.phase}`;async function he(e){if(!await S(e.workflow,g))throw Error("workflow_execution_not_current");let i=te(e),t=await P({userId:e.workflow.userId,tool:e.tool,jobId:e.jobId,normalizedInput:e.normalizedInput,idempotencyKey:i,leaseMs:g});if(t.kind==="replay"){if(t.result.status!=="succeeded")throw Error(`operation_phase_unknown:${t.runId}`);return JSON.parse(t.result.json)}if(t.kind!=="claimed")throw Error(`operation_phase_${t.kind}:${t.runId}`);let n=t.claim;try{await e.prepare()}catch(r){throw await I(n).catch(()=>{}),r}try{let r;try{r=await k(n)}catch(a){if(!await m(n))throw a;r=!0}if(!r)throw Error("operation_phase_start_unknown");let s=Date.now()+g,o=async()=>{if(Date.now()>=s)throw new L(e.phase);if(!await m(e.workflow)||!await m(n))throw Error("operation_phase_claim_not_current")};await o();let u=await H(s,()=>e.execute({claim:n,deadlineAt:s,assertActive:o}),e.phase);await o();let f=JSON.stringify(u);if(f==null||!await x(n,{status:"succeeded",json:f}))throw Error("operation_phase_publication_unknown");return u}catch(r){await h(n).catch(()=>{});let s=await y(n.runId,n.userId).catch(()=>null);throw s&&await O(s,{status:"unknown",json:JSON.stringify({phase:e.phase,outcome:"unknown"})}).catch(()=>{}),r}}async function be(e,i){let t=await Y({userId:e.workflow.userId,tool:e.tool,idempotencyKey:te(e),normalizedInput:e.normalizedInput});if(!t||t.result.status!=="succeeded"||R({value:JSON.parse(t.result.json)})!==R({value:i}))throw Error("operation_phase_cache_receipt_unknown")}async function ge(e,i,t){let n={runId:e,userId:i,token:ee(t)};if(await m(n))return{claim:n,recovery:!1};let r=await y(e,i);return r?{claim:r,recovery:!0}:null}async function re(e,i,t){let n={json:JSON.stringify(i),status:e.recovery?"unknown":t};if(!(e.recovery?await O(e.claim,n,e.settlementGate):await x(e.claim,n)))throw Error("workflow_result_publication_unknown")}async function je(e){if(!await b(e))return{kind:"missing",body:{error:"job not found"}};let t=await M(e);if(!t)return{kind:"conflict",body:{error:"Only failed or expired recovery jobs can be re-finalized.",status:(await b(e))?.status??"missing"}};let n=t.executionGeneration;if(!await D(e,n))return{kind:"conflict",body:{error:"job state changed during re-finalization claim"}};let r;try{r=await X(t,{})}catch(l){throw await F(e,l instanceof Error?l.message:String(l),void 0,n).catch(()=>!1),l}let s=A(t),o=$(t,s.creditTruncated),u=o==="failed"?`No pages were extracted successfully (${t.failedUrls} failed, ${t.remainingUrls} remaining).`:o==="partial"?`${t.successfulUrls} pages succeeded; ${t.failedUrls} failed and ${t.remainingUrls} remain.${s.creditTruncated?` Credit availability limited this request from ${s.requestedMaxPages} to ${s.effectiveMaxPages} pages.`:""}`:null,f;try{f=await q(e,r,o,u,!1,null,n)}catch(l){let w=await b(e).catch(()=>null);if(!w||w.id!==e||w.executionGeneration!==n||w.status!==o||JSON.stringify(w.artifacts)!==JSON.stringify(r)||w.error!==(u?z(u).slice(0,2e3):null)||w.publicError!==null)throw l;f=!0}if(!f)return{kind:"conflict",body:{error:"job state changed during re-finalization"}};let a=await b(e);if(!a||a.executionGeneration!==n||a.status!==o)return{kind:"conflict",body:{error:"job state changed before re-finalization settlement"}};let c="already_settled_or_refunded";if(a.billedMc==null&&a.userId!=null){let l=await j(a);if(!l)throw Error("extract_settlement_acknowledgment_unknown");c=`settled: billed ${l.netChargeMc} mc, refunded ${l.refundMc} mc${l.expiredRefundMc?`, expired refund ${l.expiredRefundMc} mc`:""}`}let p=r.find(l=>l.contentType==="application/zip"||l.filename?.endsWith(".zip"));return{kind:"complete",body:{ok:!0,jobId:e,artifacts:r.length,settlement:c,bundleUrl:p?.url??null,bundleBytes:p?.bytes??null}}}async function Pe(e=25){let i=await U(e);for(let r of i)await G(r.id).catch(()=>!1);let t=await C(e),n={checked:new Set([...i,...t].map(r=>r.id)).size,settled:0,failed:0};for(let r of t){if(r.userId==null){await W(r.id,"Settlement abandoned because the legacy job has no user owner.",r.executionGeneration??0),n.failed+=1;continue}try{if(!await j(r))throw Error("extract_settlement_acknowledgment_unknown");if(r.executionGeneration===0&&await N(`extract-site:${r.id}`,r.userId)){let o=await y(`extract-site:${r.id}`,r.userId);o&&await re({claim:o,recovery:!0},{jobId:r.id,status:r.status,artifacts:r.artifacts??[]},"unknown")}n.settled+=1}catch(s){n.failed+=1;let o=s instanceof Error?s.message:String(s);await K(r.id,o,r.executionGeneration??0).catch(()=>{}),console.warn("[site-extract/reconcile]",r.id,o)}}return n}export{we as a,g as b,ee as c,ye as d,he as e,be as f,ge as g,re as h,je as i,Pe as j};
@@ -1,4 +1,4 @@
1
- import{S as K}from"./chunk-TPN25AFZ.js";import{a as X}from"./chunk-NALXKTUU.js";import{h as J,i as H}from"./chunk-RDHGQ2WZ.js";import{a as f}from"./chunk-WNUXMPVX.js";import{createHash as U,createHmac as re,timingSafeEqual as he}from"crypto";import{createHash as fe,randomUUID as Y}from"crypto";var ge=1440*60*1e3,F=5e3,h=class extends Error{constructor(n,i,o=400){super(i);this.code=n;this.status=o;this.name="GmailSelectionError"}code;status},k=null,P=null;function $(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map($).join(",")}]`:`{${Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>`${JSON.stringify(t)}:${$(n)}`).join(",")}}`}function b(e){return fe("sha256").update($(e)).digest("hex")}async function x(){let e=f();return k&&P===e||(P=e,k=(async()=>{await e.execute(`
1
+ import{S as K}from"./chunk-SFUOSJ3A.js";import{a as X}from"./chunk-NALXKTUU.js";import{h as J,i as H}from"./chunk-RDHGQ2WZ.js";import{a as f}from"./chunk-WNUXMPVX.js";import{createHash as U,createHmac as re,timingSafeEqual as he}from"crypto";import{createHash as fe,randomUUID as Y}from"crypto";var ge=1440*60*1e3,F=5e3,h=class extends Error{constructor(n,i,o=400){super(i);this.code=n;this.status=o;this.name="GmailSelectionError"}code;status},k=null,P=null;function $(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map($).join(",")}]`:`{${Object.entries(e).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>`${JSON.stringify(t)}:${$(n)}`).join(",")}}`}function b(e){return fe("sha256").update($(e)).digest("hex")}async function x(){let e=f();return k&&P===e||(P=e,k=(async()=>{await e.execute(`
2
2
  CREATE TABLE IF NOT EXISTS gmail_selections (
3
3
  selection_id TEXT PRIMARY KEY,
4
4
  owner_identity TEXT NOT NULL,
@@ -1,4 +1,4 @@
1
- import{a as M,b as q,h as L}from"./chunk-R5LJL6IR.js";import{o as b,r as J,s as pe,t as _e,u as H,w as ge}from"./chunk-QWE7VKIX.js";import{b as I,d as F}from"./chunk-ZPQNY5TI.js";import{g as j}from"./chunk-VVSHZV5S.js";import{b as $}from"./chunk-4ZVO6GX4.js";import{a as l}from"./chunk-WNUXMPVX.js";import{createHash as O,randomUUID as Oe}from"crypto";import{Client as tt,StreamableHTTPClientTransport as nt}from"@modelcontextprotocol/client";import{randomUUID as Q}from"crypto";import{createHash as Y,randomBytes as W,scryptSync as fe,timingSafeEqual as We}from"crypto";function Ee(){return"sk_"+W(24).toString("hex")}function ye(e){let t=W(16).toString("hex"),n=fe(e,t,64);return`${t}:${n.toString("hex")}`}function Ct(e,t){let[n,i]=t.split(":"),r=Buffer.from(i,"hex"),o=fe(e,n,64);return We(r,o)}function K(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 X(e){let t=await l().execute({sql:"SELECT * FROM users WHERE email = ? AND active = 1",args:[e]});return t.rows[0]?K(t.rows[0]):void 0}async function St(e){let t=await l().execute({sql:"SELECT * FROM users WHERE api_key = ? AND active = 1 AND key_active = 1",args:[e]});return t.rows[0]?K(t.rows[0]):void 0}async function Nt(e){let t=await l().execute({sql:"SELECT * FROM users WHERE id = ? AND active = 1",args:[e]});return t.rows[0]?K(t.rows[0]):void 0}async function ht(e,t){await l().execute({sql:"UPDATE users SET password_hash = ? WHERE id = ?",args:[ye(t),e]})}async function Rt(e){let t=l(),[n,i,r,o,s]=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(n.rows[0]?.n??0),done:Number(i.rows[0]?.n??0),failed:Number(r.rows[0]?.n??0),totalQuestions:Number(o.rows[0]?.n??0),lastUsed:s.rows[0]?.t!=null?String(s.rows[0].t):null}}async function At(e,t,n,i){let r=l(),o=Ee(),s=n??W(6).toString("hex"),a=ye(s);return{id:(await r.execute({sql:"INSERT INTO users (email, name, api_key, password_hash, stripe_customer_id) VALUES (?, ?, ?, ?, ?)",args:[e,t??null,o,a,i??null]})).lastInsertRowid,email:e,name:t,api_key:o,password:s}}async function xt(e,t,n,i){let r=Math.floor(Date.now()/1e3),o=Math.floor(r/i)*i,s=Y("sha256").update(t).digest("hex"),d=await l().execute({sql:`
1
+ import{a as M,b as q,f as L}from"./chunk-6BD75VKS.js";import{o as b,r as J,s as pe,t as _e,u as H,w as ge}from"./chunk-CORWWDHL.js";import{f as I,h as F}from"./chunk-5LYINW7Z.js";import{g as j}from"./chunk-VVSHZV5S.js";import{b as $}from"./chunk-4ZVO6GX4.js";import{a as l}from"./chunk-WNUXMPVX.js";import{createHash as O,randomUUID as Oe}from"crypto";import{Client as tt,StreamableHTTPClientTransport as nt}from"@modelcontextprotocol/client";import{randomUUID as Q}from"crypto";import{createHash as Y,randomBytes as W,scryptSync as fe,timingSafeEqual as We}from"crypto";function Ee(){return"sk_"+W(24).toString("hex")}function ye(e){let t=W(16).toString("hex"),n=fe(e,t,64);return`${t}:${n.toString("hex")}`}function Ct(e,t){let[n,i]=t.split(":"),r=Buffer.from(i,"hex"),o=fe(e,n,64);return We(r,o)}function K(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 X(e){let t=await l().execute({sql:"SELECT * FROM users WHERE email = ? AND active = 1",args:[e]});return t.rows[0]?K(t.rows[0]):void 0}async function St(e){let t=await l().execute({sql:"SELECT * FROM users WHERE api_key = ? AND active = 1 AND key_active = 1",args:[e]});return t.rows[0]?K(t.rows[0]):void 0}async function Nt(e){let t=await l().execute({sql:"SELECT * FROM users WHERE id = ? AND active = 1",args:[e]});return t.rows[0]?K(t.rows[0]):void 0}async function ht(e,t){await l().execute({sql:"UPDATE users SET password_hash = ? WHERE id = ?",args:[ye(t),e]})}async function Rt(e){let t=l(),[n,i,r,o,s]=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(n.rows[0]?.n??0),done:Number(i.rows[0]?.n??0),failed:Number(r.rows[0]?.n??0),totalQuestions:Number(o.rows[0]?.n??0),lastUsed:s.rows[0]?.t!=null?String(s.rows[0].t):null}}async function At(e,t,n,i){let r=l(),o=Ee(),s=n??W(6).toString("hex"),a=ye(s);return{id:(await r.execute({sql:"INSERT INTO users (email, name, api_key, password_hash, stripe_customer_id) VALUES (?, ?, ?, ?, ?)",args:[e,t??null,o,a,i??null]})).lastInsertRowid,email:e,name:t,api_key:o,password:s}}async function xt(e,t,n,i){let r=Math.floor(Date.now()/1e3),o=Math.floor(r/i)*i,s=Y("sha256").update(t).digest("hex"),d=await l().execute({sql:`
2
2
  INSERT INTO rate_limits (scope, key_hash, window_start, count)
3
3
  VALUES (?, ?, ?, 1)
4
4
  ON CONFLICT(scope, key_hash, window_start)
@@ -1 +1 @@
1
- import{g as c,j as d,k as p,l as w,m}from"./chunk-6SNOUSSZ.js";import{i as u}from"./chunk-C7MGJUTU.js";import{Inngest as x}from"inngest";var h=new x({id:"mcp-scraper"});function b(r){return Math.min(3600,Math.max(15,15*2**Math.min(8,Math.max(0,r-1))))}async function f(r){let t={claimed:r.rows.length,dispatched:0,failed:0},e=()=>{t.unknown=(t.unknown??0)+1},o=async a=>{let i=await r.read(a).catch(()=>null);return i?.id===a.id?i:null};for(let a of r.rows){let i=a.claimToken;if(!i||!await r.isCurrent(a,i).catch(()=>!1)){e();continue}try{await r.send(a)}catch(n){let l=(n instanceof Error?n.message:String(n)).slice(0,2e3);if(await r.retainRetry(a,i,l,b(a.attempts)).catch(async()=>{let s=await o(a);return s?.status==="failed"&&s.lastError===l}))t.failed+=1;else{let s=await o(a);s?.status==="dispatched"&&s.dispatchedAt?t.dispatched+=1:e()}continue}if(await r.acknowledge(a,i).catch(()=>!1))t.dispatched+=1;else{let n=await o(a);n?.status==="dispatched"&&n.dispatchedAt?t.dispatched+=1:e()}}return t}async function k(r){return f({rows:r,isCurrent:(t,e)=>p(t.id,e),send:async t=>{try{return await h.send({id:t.id,name:"mcp-scraper/extract.requested",data:{jobId:t.id}})}catch(e){throw Error(u(e instanceof Error?e.message:String(e)).slice(0,2e3))}},acknowledge:(t,e)=>w(t.id,e),retainRetry:(t,e,o,a)=>m(t.id,e,o,a),read:async t=>{let e=await c(t.id);return e?{id:e.id,status:e.dispatchedAt?"dispatched":e.dispatchClaimToken?"dispatching":e.dispatchError?"failed":"pending",dispatchedAt:e.dispatchedAt??null,lastError:e.dispatchError??null}:null}})}async function A(r){if((await c(r))?.dispatchedAt)return{claimed:0,dispatched:1,failed:0};let e=await d({jobId:r});return e.length?k(e):{claimed:0,dispatched:0,failed:0,unknown:1}}async function S(r=25){let t=await k(await d({limit:r}));return{checked:t.claimed,dispatched:t.dispatched,failed:t.failed,...t.unknown?{unknown:t.unknown}:{}}}export{h as a,f as b,A as c,S as d};
1
+ import{g as c,j as d,k as p,l as w,m}from"./chunk-7WPCGRD7.js";import{i as u}from"./chunk-C7MGJUTU.js";import{Inngest as x}from"inngest";var h=new x({id:"mcp-scraper"});function b(r){return Math.min(3600,Math.max(15,15*2**Math.min(8,Math.max(0,r-1))))}async function f(r){let t={claimed:r.rows.length,dispatched:0,failed:0},e=()=>{t.unknown=(t.unknown??0)+1},o=async a=>{let i=await r.read(a).catch(()=>null);return i?.id===a.id?i:null};for(let a of r.rows){let i=a.claimToken;if(!i||!await r.isCurrent(a,i).catch(()=>!1)){e();continue}try{await r.send(a)}catch(n){let l=(n instanceof Error?n.message:String(n)).slice(0,2e3);if(await r.retainRetry(a,i,l,b(a.attempts)).catch(async()=>{let s=await o(a);return s?.status==="failed"&&s.lastError===l}))t.failed+=1;else{let s=await o(a);s?.status==="dispatched"&&s.dispatchedAt?t.dispatched+=1:e()}continue}if(await r.acknowledge(a,i).catch(()=>!1))t.dispatched+=1;else{let n=await o(a);n?.status==="dispatched"&&n.dispatchedAt?t.dispatched+=1:e()}}return t}async function k(r){return f({rows:r,isCurrent:(t,e)=>p(t.id,e),send:async t=>{try{return await h.send({id:t.id,name:"mcp-scraper/extract.requested",data:{jobId:t.id}})}catch(e){throw Error(u(e instanceof Error?e.message:String(e)).slice(0,2e3))}},acknowledge:(t,e)=>w(t.id,e),retainRetry:(t,e,o,a)=>m(t.id,e,o,a),read:async t=>{let e=await c(t.id);return e?{id:e.id,status:e.dispatchedAt?"dispatched":e.dispatchClaimToken?"dispatching":e.dispatchError?"failed":"pending",dispatchedAt:e.dispatchedAt??null,lastError:e.dispatchError??null}:null}})}async function A(r){if((await c(r))?.dispatchedAt)return{claimed:0,dispatched:1,failed:0};let e=await d({jobId:r});return e.length?k(e):{claimed:0,dispatched:0,failed:0,unknown:1}}async function S(r=25){let t=await k(await d({limit:r}));return{checked:t.claimed,dispatched:t.dispatched,failed:t.failed,...t.unknown?{unknown:t.unknown}:{}}}export{h as a,f as b,A as c,S as d};
@@ -1,4 +1,4 @@
1
- import{a as ot}from"./chunk-U4WIJZCX.js";import{F as fe,a as Qe,c as Ve}from"./chunk-6SNOUSSZ.js";import{g as Ke,h as Ze}from"./chunk-KXJCGV3H.js";import{c as st}from"./chunk-JMZIDHYQ.js";import{c as tt,e as nt,f as rt,g as it}from"./chunk-CNSVZTTT.js";import{c as et}from"./chunk-5BKSKLHX.js";import{h as Ge}from"./chunk-C7MGJUTU.js";import{a as se}from"./chunk-WNUXMPVX.js";import{createWriteStream as ae,mkdtempSync as Yt,mkdirSync as le,readFileSync as Wt,readdirSync as Gt,rmSync as Kt,statSync as Zt,writeFileSync as y}from"fs";import{createHash as W}from"crypto";import{join as l}from"path";import{tmpdir as Qt}from"os";import{createGzip as Vt}from"zlib";import{once as G}from"events";import{finished as ue}from"stream/promises";import{ZipFile as en}from"yazl";import tn from"p-limit";var vt=new Set(["browser_navigation_blocked","browser_navigation_failed","browser_timeout","browser_session_failed","browser_result_missing"]);function Mt(e){return e instanceof Error?e.code:void 0}function At(e){return e instanceof Error?e.message:String(e)}function at(e){let r=e?.match(/^browser_http_(\d+)$/);return r?Number(r[1]):null}function It(e){return e===404?"page_not_found":e===403?"page_forbidden":e===429?"page_rate_limited":e>=500&&e<=599?"page_server_error":"page_http_error"}function Rt(e){let r=At(e),i=Mt(e);if(ot(e,r))return{errorCode:"vendor_unavailable",httpStatus:null,retryable:!0};let a=at(i)??at(r.match(/^(browser_http_\d+)/)?.[1]);return a!=null?{errorCode:It(a),httpStatus:a,retryable:a===429||a>=500}:i==="browser_challenge_unresolved"||/^browser_challenge_unresolved/.test(r)?{errorCode:"bot_check_unresolved",httpStatus:null,retryable:!0}:i==="browser_response_too_large"||/exceeds \d+ byte limit/i.test(r)?{errorCode:"page_too_large",httpStatus:null,retryable:!1}:/browser (?:has been )?closed|context closed|target page, context or browser has been closed|session closed/i.test(r)?{errorCode:"browser_session_interrupted",httpStatus:null,retryable:!0}:vt.has(i??"")||/timeout|navigation_failed|ERR_/i.test(r)?{errorCode:"page_unreachable",httpStatus:null,retryable:!0}:{errorCode:"extraction_failed",httpStatus:null,retryable:!1}}function lt(e,r){switch(e){case"page_not_found":return`The page could not be found (HTTP ${r??404}). It may have been moved or deleted.`;case"page_forbidden":return`The site refused the request (HTTP ${r??403}).`;case"page_rate_limited":return"The site is rate-limiting requests right now (HTTP 429). Retrying after a short wait usually works.";case"page_server_error":return`The page's own server returned an error (HTTP ${r}). 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 ${r} 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. A retry uses a fresh browser session.";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"extraction_failed":return"The page could not be extracted. Check retryable before attempting it again; contact support if this persists for the same URL."}}function on(e,r={}){let i=lt(e.errorCode,e.httpStatus);return{...Ge({errorCode:e.errorCode,retryable:e.retryable,chargeStatus:r.chargeStatus,details:{...r.details??{},...e.httpStatus!=null?{http_status:e.httpStatus}:{}}}),message:i,error:i}}function an(e){return e.httpStatus===404?404:e.httpStatus===403?403:e.httpStatus===429?429:e.httpStatus!=null&&e.httpStatus>=500&&e.httpStatus<=599?500:e.httpStatus!=null?502:e.errorCode==="vendor_unavailable"?503:502}var Dt="wayback_capture_missing";function Me(e,r){if(e==null)return{failureCode:null,failureReason:null};if(e===Dt)return{failureCode:e,failureReason:r??null};let i=new Error(r??e);i.code=e;let a=Rt(i);return{failureCode:a.errorCode,failureReason:lt(a.errorCode,a.httpStatus)}}import{createHash as Ie}from"crypto";import{neon as $t}from"@neondatabase/serverless";import{waitUntil as Ut}from"@vercel/functions";var jt="jina",ye=null,ut=!1;function be(){return(process.env.JINA_EMBED_MODEL??"jina-embeddings-v5-omni-small").trim()}function _e(){return Number((process.env.JINA_EMBED_DIM??"1024").trim())}function Ae(){return!!(process.env.JINA_API_KEY?.trim()&&process.env.MEMORY_DATABASE_URL?.trim())}function oe(){if(ye)return ye;let e=process.env.MEMORY_DATABASE_URL?.trim();if(!e)throw new Error("MEMORY_DATABASE_URL is not set; Commons semantic search needs the shared Postgres.");return ye=$t(e),ye}async function mt(){if(ut)return;let e=_e();await oe().query("CREATE EXTENSION IF NOT EXISTS vector"),await oe().query(`
1
+ import{a as ot}from"./chunk-U4WIJZCX.js";import{F as fe,a as Qe,c as Ve}from"./chunk-7WPCGRD7.js";import{g as Ke,h as Ze}from"./chunk-KXJCGV3H.js";import{c as st}from"./chunk-JMZIDHYQ.js";import{c as tt,e as nt,f as rt,g as it}from"./chunk-CNSVZTTT.js";import{c as et}from"./chunk-5BKSKLHX.js";import{h as Ge}from"./chunk-C7MGJUTU.js";import{a as se}from"./chunk-WNUXMPVX.js";import{createWriteStream as ae,mkdtempSync as Yt,mkdirSync as le,readFileSync as Wt,readdirSync as Gt,rmSync as Kt,statSync as Zt,writeFileSync as y}from"fs";import{createHash as W}from"crypto";import{join as l}from"path";import{tmpdir as Qt}from"os";import{createGzip as Vt}from"zlib";import{once as G}from"events";import{finished as ue}from"stream/promises";import{ZipFile as en}from"yazl";import tn from"p-limit";var vt=new Set(["browser_navigation_blocked","browser_navigation_failed","browser_timeout","browser_session_failed","browser_result_missing"]);function Mt(e){return e instanceof Error?e.code:void 0}function At(e){return e instanceof Error?e.message:String(e)}function at(e){let r=e?.match(/^browser_http_(\d+)$/);return r?Number(r[1]):null}function It(e){return e===404?"page_not_found":e===403?"page_forbidden":e===429?"page_rate_limited":e>=500&&e<=599?"page_server_error":"page_http_error"}function Rt(e){let r=At(e),i=Mt(e);if(ot(e,r))return{errorCode:"vendor_unavailable",httpStatus:null,retryable:!0};let a=at(i)??at(r.match(/^(browser_http_\d+)/)?.[1]);return a!=null?{errorCode:It(a),httpStatus:a,retryable:a===429||a>=500}:i==="browser_challenge_unresolved"||/^browser_challenge_unresolved/.test(r)?{errorCode:"bot_check_unresolved",httpStatus:null,retryable:!0}:i==="browser_response_too_large"||/exceeds \d+ byte limit/i.test(r)?{errorCode:"page_too_large",httpStatus:null,retryable:!1}:/browser (?:has been )?closed|context closed|target page, context or browser has been closed|session closed/i.test(r)?{errorCode:"browser_session_interrupted",httpStatus:null,retryable:!0}:vt.has(i??"")||/timeout|navigation_failed|ERR_/i.test(r)?{errorCode:"page_unreachable",httpStatus:null,retryable:!0}:{errorCode:"extraction_failed",httpStatus:null,retryable:!1}}function lt(e,r){switch(e){case"page_not_found":return`The page could not be found (HTTP ${r??404}). It may have been moved or deleted.`;case"page_forbidden":return`The site refused the request (HTTP ${r??403}).`;case"page_rate_limited":return"The site is rate-limiting requests right now (HTTP 429). Retrying after a short wait usually works.";case"page_server_error":return`The page's own server returned an error (HTTP ${r}). 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 ${r} 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. A retry uses a fresh browser session.";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"extraction_failed":return"The page could not be extracted. Check retryable before attempting it again; contact support if this persists for the same URL."}}function on(e,r={}){let i=lt(e.errorCode,e.httpStatus);return{...Ge({errorCode:e.errorCode,retryable:e.retryable,chargeStatus:r.chargeStatus,details:{...r.details??{},...e.httpStatus!=null?{http_status:e.httpStatus}:{}}}),message:i,error:i}}function an(e){return e.httpStatus===404?404:e.httpStatus===403?403:e.httpStatus===429?429:e.httpStatus!=null&&e.httpStatus>=500&&e.httpStatus<=599?500:e.httpStatus!=null?502:e.errorCode==="vendor_unavailable"?503:502}var Dt="wayback_capture_missing";function Me(e,r){if(e==null)return{failureCode:null,failureReason:null};if(e===Dt)return{failureCode:e,failureReason:r??null};let i=new Error(r??e);i.code=e;let a=Rt(i);return{failureCode:a.errorCode,failureReason:lt(a.errorCode,a.httpStatus)}}import{createHash as Ie}from"crypto";import{neon as $t}from"@neondatabase/serverless";import{waitUntil as Ut}from"@vercel/functions";var jt="jina",ye=null,ut=!1;function be(){return(process.env.JINA_EMBED_MODEL??"jina-embeddings-v5-omni-small").trim()}function _e(){return Number((process.env.JINA_EMBED_DIM??"1024").trim())}function Ae(){return!!(process.env.JINA_API_KEY?.trim()&&process.env.MEMORY_DATABASE_URL?.trim())}function oe(){if(ye)return ye;let e=process.env.MEMORY_DATABASE_URL?.trim();if(!e)throw new Error("MEMORY_DATABASE_URL is not set; Commons semantic search needs the shared Postgres.");return ye=$t(e),ye}async function mt(){if(ut)return;let e=_e();await oe().query("CREATE EXTENSION IF NOT EXISTS vector"),await oe().query(`
2
2
  CREATE TABLE IF NOT EXISTS commons_index_vectors (
3
3
  document_id TEXT PRIMARY KEY,
4
4
  entity_id TEXT NOT NULL,
@@ -1 +1 @@
1
- import{c as a,d as b}from"./chunk-GVYGAZV7.js";import"./chunk-6SNOUSSZ.js";import"./chunk-KXJCGV3H.js";import"./chunk-HUNSEGUN.js";import"./chunk-SEZETSB3.js";import"./chunk-SDQW7IJN.js";import"./chunk-C7MGJUTU.js";import"./chunk-4ZVO6GX4.js";import"./chunk-WNUXMPVX.js";import"./chunk-OILOHQNL.js";import"./chunk-HNNYXMSI.js";export{a as dispatchSiteExtractJob,b as redispatchFundedSiteExtractJobs};
1
+ import{c as a,d as b}from"./chunk-UXNR3K6I.js";import"./chunk-7WPCGRD7.js";import"./chunk-KXJCGV3H.js";import"./chunk-HUNSEGUN.js";import"./chunk-SEZETSB3.js";import"./chunk-SDQW7IJN.js";import"./chunk-C7MGJUTU.js";import"./chunk-4ZVO6GX4.js";import"./chunk-WNUXMPVX.js";import"./chunk-OILOHQNL.js";import"./chunk-HNNYXMSI.js";export{a as dispatchSiteExtractJob,b as redispatchFundedSiteExtractJobs};