mcp-scraper 0.95.2 → 0.96.0

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 (121) hide show
  1. package/CHANGELOG.md +48 -1
  2. package/README.md +19 -3
  3. package/dist/actions-YCMJY3PF.js +1 -0
  4. package/dist/artifacts-4ZDNP2JW.js +1 -0
  5. package/dist/artifacts-N62OPIT5.js +1 -0
  6. package/dist/artifacts-PSADD5OC.js +1 -0
  7. package/dist/artifacts-RUR3OHAK.js +1 -0
  8. package/dist/bin/api-server.js +1 -1
  9. package/dist/bin/mcp-scraper-cli.js +22 -22
  10. package/dist/bin/mcp-scraper-core.js +1 -1
  11. package/dist/bin/mcp-scraper-install.js +1 -1
  12. package/dist/bin/mcp-stdio-server.js +1 -1
  13. package/dist/bin/paa-harvest.js +1 -1
  14. package/dist/blob-store-GIH26EDO.js +1 -0
  15. package/dist/bundle-TTJP6DHU.js +1 -0
  16. package/dist/chunk-24YDQ3EO.js +5 -0
  17. package/dist/chunk-2PRH4Z3N.js +181 -0
  18. package/dist/chunk-3F7AFM53.js +1 -0
  19. package/dist/chunk-4HZXATHB.js +27 -0
  20. package/dist/chunk-55ZANTHL.js +3 -0
  21. package/dist/chunk-5BKSKLHX.js +1 -0
  22. package/dist/chunk-63VWBMYR.js +3 -0
  23. package/dist/chunk-6N5EC7ZO.js +1 -0
  24. package/dist/chunk-6SNOUSSZ.js +182 -0
  25. package/dist/chunk-7POHNTVW.js +1 -0
  26. package/dist/chunk-7SR7MEU5.js +62 -0
  27. package/dist/chunk-7UHDOIUE.js +1 -0
  28. package/dist/chunk-ARSQZCTJ.js +945 -0
  29. package/dist/chunk-B3JRL45T.js +1 -0
  30. package/dist/chunk-B4ZKPLSP.js +1 -0
  31. package/dist/chunk-C7MGJUTU.js +1 -0
  32. package/dist/{chunk-W2BVJ7S2.js → chunk-CNSVZTTT.js} +4 -4
  33. package/dist/chunk-DGAW7FD7.js +12 -0
  34. package/dist/chunk-FRXKMOXI.js +41 -0
  35. package/dist/chunk-GVYGAZV7.js +1 -0
  36. package/dist/chunk-HCK6PLM3.js +3 -0
  37. package/dist/{chunk-Y3Q4FIKK.js → chunk-HJIOH7HF.js} +199 -84
  38. package/dist/chunk-HNNYXMSI.js +1 -0
  39. package/dist/chunk-HUNSEGUN.js +57 -0
  40. package/dist/chunk-IFPION5D.js +121 -0
  41. package/dist/{chunk-MC4W6TZT.js → chunk-JAV5V3JT.js} +41 -8
  42. package/dist/chunk-JMZIDHYQ.js +2 -0
  43. package/dist/{chunk-ENZUJEIM.js → chunk-JW4GDY7S.js} +1 -1
  44. package/dist/chunk-KXJCGV3H.js +1 -0
  45. package/dist/chunk-LFRAA3MY.js +4 -0
  46. package/dist/chunk-MVMWPKRC.js +2 -0
  47. package/dist/chunk-NALXKTUU.js +1 -0
  48. package/dist/chunk-NNOX3FYG.js +198 -0
  49. package/dist/chunk-OB6E6UTD.js +1 -0
  50. package/dist/chunk-OILOHQNL.js +2 -0
  51. package/dist/chunk-OLYPLX5C.js +1 -0
  52. package/dist/chunk-QER2ELZP.js +1 -0
  53. package/dist/chunk-QWE7VKIX.js +1 -0
  54. package/dist/chunk-R5LJL6IR.js +225 -0
  55. package/dist/chunk-RDHGQ2WZ.js +1 -0
  56. package/dist/chunk-SDQW7IJN.js +1 -0
  57. package/dist/chunk-SEZETSB3.js +1 -0
  58. package/dist/chunk-SNJR5N36.js +1 -0
  59. package/dist/chunk-TPN25AFZ.js +159 -0
  60. package/dist/chunk-UIOSADPB.js +1718 -0
  61. package/dist/{chunk-ZH75KWBI.js → chunk-UNEJYZ4T.js} +1 -1
  62. package/dist/chunk-VAC3SQ5T.js +16 -0
  63. package/dist/{chunk-VREXSMC6.js → chunk-VVSHZV5S.js} +5 -5
  64. package/dist/chunk-WNUXMPVX.js +1 -0
  65. package/dist/chunk-WP3QS4CJ.js +1 -0
  66. package/dist/chunk-ZPQNY5TI.js +1 -0
  67. package/dist/contracts-GUXGFCVV.js +1 -0
  68. package/dist/core-schema-423BSTE6.js +936 -0
  69. package/dist/dispatch-3HY4735M.js +1 -0
  70. package/dist/index.cjs +104 -214
  71. package/dist/index.d.cts +181 -169
  72. package/dist/index.d.ts +181 -169
  73. package/dist/index.js +1 -1
  74. package/dist/media-artifacts-67CJWI7O.js +1 -0
  75. package/dist/metering-ZH2P62IC.js +1 -0
  76. package/dist/migrations-3AKEC5QE.js +1 -0
  77. package/dist/queue-HUP2GNXF.js +1 -0
  78. package/dist/reconciliation-ANXNJWME.js +1 -0
  79. package/dist/report-artifact-offload-6OOY2PTM.js +1 -0
  80. package/dist/repository-4EC5EXVN.js +1 -0
  81. package/dist/{location-data-repository-A2QZVP7O.js → repository-CYXVMYAI.js} +1 -1
  82. package/dist/server-VQU6S24A.js +5825 -0
  83. package/dist/settlement-6CCE2PDH.js +1 -0
  84. package/dist/worker-5G5BK23B.js +1 -0
  85. package/package.json +2 -2
  86. package/dist/analytics-repository-DZZKDZL6.js +0 -1
  87. package/dist/chunk-6DRKDSXY.js +0 -182
  88. package/dist/chunk-6ND5AFV5.js +0 -27
  89. package/dist/chunk-7XDBGQDY.js +0 -6
  90. package/dist/chunk-7YOXSMHG.js +0 -1565
  91. package/dist/chunk-BLVBUMH5.js +0 -21
  92. package/dist/chunk-EDQ57S4P.js +0 -1
  93. package/dist/chunk-GLTECY3U.js +0 -1282
  94. package/dist/chunk-GPSPSJBJ.js +0 -1
  95. package/dist/chunk-HE45FFBU.js +0 -1
  96. package/dist/chunk-HUV2WTRW.js +0 -1
  97. package/dist/chunk-IXJQHXDC.js +0 -2595
  98. package/dist/chunk-K3D2S36Q.js +0 -16
  99. package/dist/chunk-KFOFU3LA.js +0 -1
  100. package/dist/chunk-LMWU7VPZ.js +0 -63
  101. package/dist/chunk-O4LUUIYG.js +0 -4
  102. package/dist/chunk-OLSW4AN4.js +0 -19
  103. package/dist/chunk-RLFCJGHA.js +0 -100
  104. package/dist/chunk-T4VTJNDZ.js +0 -84
  105. package/dist/chunk-TMB56NCA.js +0 -1
  106. package/dist/chunk-VXOXB3IB.js +0 -1
  107. package/dist/chunk-WO3N5FH2.js +0 -5
  108. package/dist/chunk-WO46LTBW.js +0 -1
  109. package/dist/chunk-XPEJB4BZ.js +0 -1
  110. package/dist/db-CDEZHBRN.js +0 -1
  111. package/dist/extract-bundle-SXC6EWJR.js +0 -26
  112. package/dist/gmail-service-EWR76XE7.js +0 -1
  113. package/dist/lead-list-enrichment-repository-SIWGXWQV.js +0 -1
  114. package/dist/operation-metering-UJ53YX7S.js +0 -1
  115. package/dist/server-QVEKDIDQ.js +0 -5014
  116. package/dist/site-extract-repository-23ND4N77.js +0 -1
  117. package/dist/stripe-event-worker-LPXTITVC.js +0 -1
  118. package/dist/worker-EDN2TJH3.js +0 -1
  119. /package/dist/{chunk-YGBTTW5D.js → chunk-2IATUJO6.js} +0 -0
  120. /package/dist/{chunk-6DTXIZY2.js → chunk-4ZVO6GX4.js} +0 -0
  121. /package/dist/{chunk-XG6GCEUE.js → chunk-U4WIJZCX.js} +0 -0
@@ -0,0 +1,225 @@
1
+ import{a as u}from"./chunk-WNUXMPVX.js";var L="2026-06-26 21:58:03";var W="+3 months";function R(e){return{sql:`INSERT INTO credit_lots (user_id, amount_mc, remaining_mc, source, expires_at)
2
+ SELECT ?, legacy.balance_mc, legacy.balance_mc, 'migration', datetime('now', ?)
3
+ FROM (
4
+ SELECT COALESCE(SUM(amount_mc), 0) AS balance_mc
5
+ FROM ledger
6
+ WHERE user_id = ?
7
+ ) AS legacy
8
+ WHERE legacy.balance_mc > 0
9
+ AND EXISTS (
10
+ SELECT 1 FROM ledger
11
+ WHERE user_id = ? AND created_at < ?
12
+ )
13
+ AND NOT EXISTS (
14
+ SELECT 1 FROM credit_lots WHERE user_id = ?
15
+ )`,args:[e,W,e,e,L,e]}}async function T(e){return(await u().execute(R(e))).rowsAffected}import{createHash as O,randomUUID as A}from"crypto";var _=class extends Error{constructor(){super("Current operation wallet claim and matching durable plan are required"),this.name="WalletClaimLostError"}},b=class extends Error{constructor(){super("Named operation debit plan conflicts with durable billing history"),this.name="DebitPlanConflictError"}};function y(e){if(!Number.isSafeInteger(e.userId)||e.userId<=0||!Number.isSafeInteger(e.amountMc)||e.amountMc<=0||!e.key||e.key.length>500||!e.operation||!e.description||e.description.length>500)throw new b;return{sql:`EXISTS (SELECT 1 FROM billing_debits d WHERE d.idempotency_key=? AND d.user_id=?
16
+ AND d.amount_mc=? AND d.operation=? AND d.description=? AND d.status='applied'
17
+ AND NOT EXISTS (SELECT 1 FROM billing_events b WHERE b.user_id=d.user_id
18
+ AND b.billing_class='wallet_hold_settlement'
19
+ AND json_extract(b.metadata,'$.debitIdempotencyKey')=d.idempotency_key))`,args:[e.key,e.userId,e.amountMc,e.operation,e.description]}}function v(e,t){if(!/^[a-z_]+\.[a-z_]+$/.test(e)||!/^json_extract\([a-z_]+\.[a-z_]+,'\$\.hold\.key'\)$/.test(t))throw new Error("Invalid stored hold selector");return`EXISTS (SELECT 1 FROM billing_debits d WHERE d.user_id=${e}
20
+ AND d.idempotency_key=${t} AND d.status='applied'
21
+ AND NOT EXISTS (SELECT 1 FROM billing_events b WHERE b.user_id=d.user_id
22
+ AND b.billing_class='wallet_hold_settlement' AND json_extract(b.metadata,'$.debitIdempotencyKey')=d.idempotency_key))`}var D="(CAST(strftime('%s', 'now') AS INTEGER) * 1000)",f="operation-debit:",w=e=>e==="execute"?"e.phase = 'effects_started' AND r.status = 'running'":"e.phase = 'unknown' AND r.status = 'unknown'";function C(e,t,r){if(!r){if(t.startsWith(f))throw new _;return}if(r.userId!==e||!r.runId||!r.token||!["execute","compensate"].includes(r.mode))throw new _}var h=e=>String(e).includes("operation_wallet_claim_current");function x(e,t,r,n){if(C(e,t,r),!r){let a=A(),c="NOT EXISTS (SELECT 1 FROM operation_debit_plans WHERE debit_key = ?)";return{before:[{sql:`INSERT INTO operation_wallet_fences (id, allowed)
23
+ SELECT ?, CASE WHEN ${c} THEN 1 ELSE 0 END`,args:[a,t]}],after:[{sql:"DELETE FROM operation_wallet_fences WHERE id = ?",args:[a]}],current:async p=>!!(await p.execute({sql:`SELECT ${c} AS allowed`,args:[t]})).rows[0]?.allowed}}if(n.kind==="debit"&&r.mode!=="execute"||r.mode==="compensate"&&n.amountMc!==0&&!r.settlementPlanId)throw new _;let i=r.settlementPlanId?" AND EXISTS (SELECT 1 FROM operation_final_settlements s WHERE s.id=? AND s.run_id=p.run_id AND s.user_id=r.user_id AND s.debit_key=p.debit_key AND s.final_amount_mc=? AND s.refund_operation=? AND s.source_surface=?)":"",l=`SELECT 1 FROM operation_debit_plans p
24
+ JOIN operation_runs r ON r.id = p.run_id JOIN operation_executions e ON e.run_id = r.id
25
+ WHERE p.debit_key = ? AND r.id = ? AND r.user_id = ? AND e.claim_token = ?
26
+ AND e.expires_at_ms > ${D} AND ${w(r.mode)}
27
+ AND ${n.kind==="debit"?"p.amount_mc = ? AND p.operation = ? AND p.description = ?":"p.refund_operation = ? AND p.source_surface = ?"}${i}`,d=[t,r.runId,e,r.token,...n.kind==="debit"?[n.amountMc,n.operation,n.description]:[n.operation,n.sourceSurface],...r.settlementPlanId?[r.settlementPlanId,n.amountMc,n.operation,n.sourceSurface]:[]],o=A(),s=n.kind==="debit"?{sql:`INSERT OR IGNORE INTO operation_billing_links (run_id, billing_table, billing_key, relation, amount_mc)
28
+ SELECT p.run_id, 'billing_debits', d.idempotency_key, 'debit', d.amount_mc FROM operation_debit_plans p
29
+ JOIN billing_debits d ON d.idempotency_key = p.debit_key
30
+ WHERE p.debit_key = ? AND d.user_id = ? AND d.status = 'applied'`,args:[t,e]}:{sql:`INSERT OR IGNORE INTO operation_billing_links (run_id, billing_table, billing_key, relation, amount_mc)
31
+ SELECT p.run_id, 'billing_events', b.id, 'settlement', b.amount_mc FROM operation_debit_plans p
32
+ JOIN billing_events b ON b.idempotency_key = ?
33
+ WHERE p.debit_key = ? AND b.user_id = ? AND b.status = 'settled'`,args:[`debit-settlement:${O("sha256").update(t).digest("hex")}`,t,e]};return{before:[{sql:`INSERT INTO operation_wallet_fences (id, allowed)
34
+ SELECT ?, CASE WHEN EXISTS (${l}) THEN 1 ELSE 0 END`,args:[o,...d]},R(e)],after:[s,{sql:"DELETE FROM operation_wallet_fences WHERE id = ?",args:[o]}],current:async a=>(await a.execute({sql:l,args:d})).rows.length===1}}function M(e){return{label:String(e.label),key:String(e.debit_key),amountMc:Number(e.amount_mc),operation:String(e.operation),description:String(e.description),refundOperation:String(e.refund_operation),sourceSurface:String(e.source_surface)}}async function B(e,t){if(e.mode!=="execute"||!Number.isSafeInteger(t.amountMc)||t.amountMc<=0||!t.label||t.label.length>200||!t.operation||!t.refundOperation||!t.sourceSurface)throw new b;let r=u(),n=f+A();C(e.userId,n,e);let i=`EXISTS (SELECT 1 FROM operation_runs r JOIN operation_executions e ON e.run_id = r.id
35
+ WHERE r.id = ? AND r.user_id = ? AND e.claim_token = ? AND e.expires_at_ms > ${D}
36
+ AND ${w("execute")})`,l=[e.runId,e.userId,e.token],d;try{await r.batch([{sql:`INSERT OR IGNORE INTO operation_debit_plans
37
+ (run_id, label, debit_key, amount_mc, operation, description, refund_operation, source_surface)
38
+ SELECT ?, ?, ?, ?, ?, ?, ?, ? WHERE ${i}`,args:[e.runId,t.label,n,t.amountMc,t.operation,t.description,t.refundOperation,t.sourceSurface,...l]},{sql:`UPDATE operation_debit_plans SET amount_mc = ? WHERE run_id = ? AND label = ?
39
+ AND operation = ? AND description = ? AND refund_operation = ? AND source_surface = ? AND ${i}
40
+ AND EXISTS (SELECT 1 FROM billing_debits d WHERE d.idempotency_key = operation_debit_plans.debit_key
41
+ AND d.user_id = ? AND d.status = 'claimed' AND d.amount_mc = operation_debit_plans.amount_mc
42
+ AND d.operation = operation_debit_plans.operation AND d.description = operation_debit_plans.description)`,args:[t.amountMc,e.runId,t.label,t.operation,t.description,t.refundOperation,t.sourceSurface,...l,e.userId]}],"write")}catch(a){d=a}let o;try{o=(await r.execute({sql:`SELECT p.* FROM operation_debit_plans p WHERE p.run_id = ? AND p.label = ? AND ${i}`,args:[e.runId,t.label,...l]})).rows[0]}catch(a){throw d??a}if(!o)throw d||new _;let s=M(o);if(s.amountMc!==t.amountMc||s.operation!==t.operation||s.description!==t.description||s.refundOperation!==t.refundOperation||s.sourceSurface!==t.sourceSurface)throw new b;return s}async function J(e){C(e.userId,f,e);let t=u();if(!(await t.execute({sql:`SELECT 1 FROM operation_executions e JOIN operation_runs r ON r.id = e.run_id
43
+ WHERE r.id = ? AND r.user_id = ? AND e.claim_token = ? AND e.expires_at_ms > ${D}
44
+ AND ${w(e.mode)}`,args:[e.runId,e.userId,e.token]})).rows.length)throw new _;return(await t.execute({sql:"SELECT * FROM operation_debit_plans WHERE run_id = ? ORDER BY label",args:[e.runId]})).rows.map(M)}async function V(e,t){let n=(await u().execute({sql:"SELECT user_id, amount_mc, operation, description, status FROM billing_debits WHERE idempotency_key = ? AND user_id = ? LIMIT 1",args:[t,e]})).rows[0];return n?{amountMc:Number(n.amount_mc),operation:String(n.operation),description:String(n.description),status:String(n.status)}:null}async function Y(e,t,r,n,i,l){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 d=u(),o=x(e,i,l,{kind:"debit",amountMc:t,operation:r,description:n});l||await T(e);let s;try{s=await d.batch([...o.before,{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
45
+ SET balance_mc = balance_mc - ?
46
+ WHERE id = ?
47
+ AND balance_mc >= ?
48
+ AND (SELECT COALESCE(SUM(remaining_mc), 0)
49
+ FROM credit_lots
50
+ WHERE user_id = ?
51
+ AND remaining_mc > 0
52
+ AND (never_expires = 1 OR expires_at > datetime('now'))) >= ?
53
+ 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
54
+ (debit_idempotency_key, lot_id, user_id, amount_mc, expires_at)
55
+ WITH ordered AS MATERIALIZED (
56
+ SELECT id,
57
+ remaining_mc,
58
+ expires_at,
59
+ COALESCE(SUM(remaining_mc) OVER (
60
+ ORDER BY never_expires ASC, expires_at ASC, granted_at ASC, id ASC
61
+ ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
62
+ ), 0) AS prior_mc
63
+ FROM credit_lots
64
+ WHERE user_id = ? AND remaining_mc > 0 AND (never_expires = 1 OR expires_at > datetime('now'))
65
+ ), allocation AS (
66
+ SELECT id, expires_at, MIN(remaining_mc, MAX(0, ? - prior_mc)) AS take_mc
67
+ FROM ordered
68
+ )
69
+ SELECT ?, id, ?, take_mc, expires_at
70
+ FROM allocation
71
+ WHERE take_mc > 0
72
+ AND EXISTS (SELECT 1 FROM billing_debits WHERE idempotency_key = ? AND status = 'applying')`,args:[e,t,i,e,i]},{sql:`UPDATE credit_lots
73
+ SET remaining_mc = remaining_mc - COALESCE((
74
+ SELECT amount_mc FROM billing_debit_allocations
75
+ WHERE debit_idempotency_key = ? AND lot_id = credit_lots.id
76
+ ), 0)
77
+ WHERE id IN (
78
+ SELECT lot_id FROM billing_debit_allocations WHERE debit_idempotency_key = ?
79
+ )
80
+ 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]},...o.after],"write")}catch(g){if(h(g))throw new _;try{if(!await o.current(d))throw new _;let E=(await d.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(E&&Number(E.user_id)===e&&Number(E.amount_mc)===t&&String(E.operation)===r&&String(E.description)===n){let S=await d.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return{ok:!0,balance_mc:Number(S.rows[0]?.balance_mc??0),duplicate:!0}}}catch(m){if(m instanceof _)throw m}throw g}let c=(await d.execute({sql:"SELECT user_id, amount_mc, operation, description, status FROM billing_debits WHERE idempotency_key = ? LIMIT 1",args:[i]})).rows[0];if(!c||Number(c.user_id)!==e||Number(c.amount_mc)!==t||String(c.operation)!==r||String(c.description)!==n)throw new Error("idempotent debit key conflicts with another debit");let p=await d.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return{ok:String(c.status)==="applied",balance_mc:Number(p.rows[0]?.balance_mc??0),duplicate:s[2+o.before.length]?.rowsAffected===0&&String(c.status)==="applied"}}async function z(e,t,r,n,i,l,d){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||!l)throw new Error("idempotent debit settlement operation and source are required");let o=u(),s=x(e,t,d,{kind:"settlement",amountMc:r,operation:n,description:i,sourceSurface:l});d||await T(e);let a=`debit-settlement:${O("sha256").update(t).digest("hex")}`,c="wallet_hold_settlement",p=A(),g=JSON.stringify({debitIdempotencyKey:t,refundOperation:n,description:i}),m=()=>k(e,t,l),E;try{E=await o.batch([...s.before,{sql:`INSERT OR IGNORE INTO billing_events
81
+ (id, user_id, idempotency_key, billing_class, source_surface, status, amount_mc, metadata)
82
+ VALUES (?, ?, ?, ?, ?, 'settling', ?, ?)`,args:[p,e,a,c,l,r,g]},{sql:`WITH ordered AS (
83
+ SELECT a.lot_id,
84
+ a.amount_mc,
85
+ a.expires_at,
86
+ COALESCE(SUM(a.amount_mc) OVER (
87
+ ORDER BY a.expires_at ASC, a.lot_id ASC
88
+ ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
89
+ ), 0) AS prior_mc
90
+ FROM billing_debit_allocations a
91
+ WHERE a.debit_idempotency_key = ?
92
+ ), refunds AS (
93
+ SELECT lot_id,
94
+ expires_at,
95
+ amount_mc - MIN(amount_mc, MAX(0, ? - prior_mc)) AS refund_mc
96
+ FROM ordered
97
+ )
98
+ UPDATE users
99
+ SET balance_mc = balance_mc + CASE
100
+ WHEN EXISTS (SELECT 1 FROM ordered) THEN COALESCE(
101
+ (SELECT SUM(refund_mc) FROM refunds WHERE expires_at > datetime('now')),
102
+ 0
103
+ )
104
+ -- Holds created before allocation provenance cannot be safely
105
+ -- tied back to a source lot. Treat their unused portion as
106
+ -- expired instead of minting spendable credits with a guessed
107
+ -- expiry.
108
+ ELSE 0
109
+ END
110
+ WHERE id = ?
111
+ AND EXISTS (
112
+ SELECT 1
113
+ FROM billing_events e
114
+ JOIN billing_debits d ON d.idempotency_key = ?
115
+ WHERE e.idempotency_key = ?
116
+ AND e.user_id = ?
117
+ AND e.billing_class = ?
118
+ AND e.source_surface = ?
119
+ AND e.status = 'settling'
120
+ AND d.user_id = e.user_id
121
+ AND d.status = 'applied'
122
+ AND e.amount_mc BETWEEN 0 AND d.amount_mc
123
+ )`,args:[t,r,e,t,a,e,c,l]},{sql:`UPDATE billing_events
124
+ SET status = 'applying'
125
+ WHERE idempotency_key = ?
126
+ AND user_id = ?
127
+ AND billing_class = ?
128
+ AND source_surface = ?
129
+ AND status = 'settling'
130
+ AND changes() = 1`,args:[a,e,c,l]},{sql:`WITH ordered AS (
131
+ SELECT a.lot_id,
132
+ a.amount_mc,
133
+ a.expires_at,
134
+ COALESCE(SUM(a.amount_mc) OVER (
135
+ ORDER BY a.expires_at ASC, a.lot_id ASC
136
+ ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
137
+ ), 0) AS prior_mc
138
+ FROM billing_debit_allocations a
139
+ WHERE a.debit_idempotency_key = ?
140
+ ), refunds AS (
141
+ SELECT lot_id,
142
+ expires_at,
143
+ amount_mc - MIN(amount_mc, MAX(0, ? - prior_mc)) AS refund_mc
144
+ FROM ordered
145
+ )
146
+ UPDATE credit_lots
147
+ SET remaining_mc = remaining_mc + COALESCE((SELECT refund_mc FROM refunds WHERE refunds.lot_id = credit_lots.id), 0)
148
+ WHERE id IN (
149
+ SELECT lot_id FROM refunds
150
+ WHERE refund_mc > 0 AND expires_at > datetime('now')
151
+ )
152
+ AND EXISTS (SELECT 1 FROM billing_events WHERE idempotency_key = ? AND status = 'applying')`,args:[t,r,a]},{sql:`WITH ordered AS (
153
+ SELECT a.amount_mc,
154
+ a.expires_at,
155
+ COALESCE(SUM(a.amount_mc) OVER (
156
+ ORDER BY a.expires_at ASC, a.lot_id ASC
157
+ ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
158
+ ), 0) AS prior_mc
159
+ FROM billing_debit_allocations a
160
+ WHERE a.debit_idempotency_key = ?
161
+ ), refunds AS (
162
+ SELECT expires_at,
163
+ amount_mc - MIN(amount_mc, MAX(0, ? - prior_mc)) AS refund_mc
164
+ FROM ordered
165
+ ), credited AS (
166
+ SELECT e.user_id,
167
+ CASE
168
+ WHEN EXISTS (SELECT 1 FROM ordered) THEN COALESCE(
169
+ (SELECT SUM(refund_mc) FROM refunds WHERE expires_at > datetime('now')),
170
+ 0
171
+ )
172
+ ELSE 0
173
+ END AS refund_mc
174
+ FROM billing_events e
175
+ JOIN billing_debits d ON d.idempotency_key = ?
176
+ WHERE e.idempotency_key = ?
177
+ AND e.status = 'applying'
178
+ )
179
+ INSERT INTO ledger (user_id, amount_mc, operation, description)
180
+ SELECT user_id,
181
+ refund_mc,
182
+ ?,
183
+ ?
184
+ FROM credited
185
+ WHERE refund_mc > 0`,args:[t,r,t,a,n,i]},{sql:`UPDATE billing_events
186
+ SET status = 'settled', settled_at = datetime('now')
187
+ WHERE idempotency_key = ?
188
+ AND status = 'applying'`,args:[a]},...s.after],"write")}catch(I){if(h(I))throw new _;try{if(!await s.current(o))throw new _;let N=await m();if(N)return N}catch(N){if(N instanceof _)throw N}throw I}let S=await m();if(!S)throw new Error("idempotent debit settlement did not reach a durable settled state");return{...S,duplicate:E[s.before.length]?.rowsAffected===0}}async function Z(e,t){let{hold:r}=t,n=y(r);if(r.userId!==e.userId||!e.runId||!e.token||!t.label||t.label.length>200||!t.refundOperation||!t.sourceSurface||!t.tool||!t.jobId)throw new b;let i=`EXISTS (SELECT 1 FROM operation_runs r JOIN operation_executions e ON e.run_id=r.id
189
+ WHERE r.id=? AND r.user_id=? AND r.tool=? AND r.job_id=? AND r.status='running'
190
+ AND json_extract(r.normalized_flags_json,'$._storeGateRequired') IS 1
191
+ AND e.claim_token=? AND e.phase='claimed' AND e.expires_at_ms > ${D})`,l=[e.runId,e.userId,t.tool,t.jobId,e.token],d=u(),o;try{await d.batch([{sql:`INSERT OR IGNORE INTO operation_debit_plans
192
+ (run_id,label,debit_key,amount_mc,operation,description,refund_operation,source_surface)
193
+ SELECT ?,?,?,?,?,?,?,? WHERE ${i} AND (${n.sql})`,args:[e.runId,t.label,r.key,r.amountMc,r.operation,r.description,t.refundOperation,t.sourceSurface,...l,...n.args]},{sql:`INSERT OR IGNORE INTO operation_billing_links (run_id,billing_table,billing_key,relation,amount_mc)
194
+ SELECT p.run_id,'billing_debits',p.debit_key,'hold',p.amount_mc FROM operation_debit_plans p
195
+ WHERE p.run_id=? AND p.label=? AND p.debit_key=? AND p.amount_mc=? AND p.operation=? AND p.description=?
196
+ AND p.refund_operation=? AND p.source_surface=? AND ${i} AND (${n.sql})`,args:[e.runId,t.label,r.key,r.amountMc,r.operation,r.description,t.refundOperation,t.sourceSurface,...l,...n.args]}],"write")}catch(c){o=c}let s;try{s=(await d.execute({sql:`SELECT p.* FROM operation_debit_plans p
197
+ WHERE p.run_id=? AND p.label=? AND ${i} AND (${n.sql})`,args:[e.runId,t.label,...l,...n.args]})).rows[0]}catch(c){throw o??c}if(!s)throw o||new _;let a=M(s);if(a.key!==r.key||a.amountMc!==r.amountMc||a.operation!==r.operation||a.description!==r.description||a.refundOperation!==t.refundOperation||a.sourceSurface!==t.sourceSurface)throw new b;return a}async function k(e,t,r){if(!Number.isSafeInteger(e)||e<=0||!t||!r)throw new _;let n=u(),i=`debit-settlement:${O("sha256").update(t).digest("hex")}`,l="wallet_hold_settlement",o=(await n.execute({sql:`SELECT e.user_id,
198
+ e.status,
199
+ e.amount_mc AS final_amount_mc,
200
+ e.billing_class,
201
+ e.source_surface,
202
+ e.settled_at,
203
+ d.amount_mc AS held_amount_mc
204
+ FROM billing_events e
205
+ JOIN billing_debits d ON d.idempotency_key = ?
206
+ WHERE e.idempotency_key = ?
207
+ AND d.user_id = e.user_id
208
+ AND d.status = 'applied'
209
+ LIMIT 1`,args:[t,i]})).rows[0];if(!o)return null;if(Number(o.user_id)!==e||String(o.billing_class)!==l||String(o.source_surface)!==r)throw new Error("idempotent debit settlement key conflicts with another settlement");if(String(o.status)!=="settled")return null;let s=Number(o.held_amount_mc),a=Number(o.final_amount_mc);if(!Number.isSafeInteger(s)||!Number.isSafeInteger(a)||a<0||a>s)throw new Error("idempotent debit settlement receipt is invalid");let c=s-a,p=await n.execute({sql:`WITH ordered AS (
210
+ SELECT a.amount_mc,
211
+ a.expires_at,
212
+ COALESCE(SUM(a.amount_mc) OVER (
213
+ ORDER BY a.expires_at ASC, a.lot_id ASC
214
+ ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
215
+ ), 0) AS prior_mc
216
+ FROM billing_debit_allocations a
217
+ WHERE a.debit_idempotency_key = ?
218
+ ), refunds AS (
219
+ SELECT expires_at,
220
+ amount_mc - MIN(amount_mc, MAX(0, ? - prior_mc)) AS refund_mc
221
+ FROM ordered
222
+ )
223
+ SELECT (SELECT COUNT(*) FROM ordered) AS allocation_count,
224
+ COALESCE(SUM(CASE WHEN expires_at > ? THEN refund_mc ELSE 0 END), 0) AS credited_refund_mc
225
+ FROM refunds`,args:[t,a,String(o.settled_at)]}),m=Number(p.rows[0]?.allocation_count??0)>0?Number(p.rows[0]?.credited_refund_mc??0):0,E=await n.execute({sql:"SELECT balance_mc FROM users WHERE id = ?",args:[e]});return{balance_mc:Number(E.rows[0]?.balance_mc??0),final_amount_mc:a,refund_mc:m,expired_refund_mc:c-m,duplicate:!0}}export{W as a,T as b,y as c,v as d,B as e,J as f,V as g,Y as h,z as i,Z as j,k};
@@ -0,0 +1 @@
1
+ import{c as f,d,e as p,h as u,i as A,j as m}from"./chunk-SEZETSB3.js";import{c as s,i as l}from"./chunk-SDQW7IJN.js";import{randomUUID as D}from"crypto";var x="connected-data-exports/",_=10080*60*1e3,b=900*1e3;function C(){return process.env.CONNECTED_DATA_READ_WRITE_TOKEN?.trim()||process.env.CONNECTED_DATA_BLOB_READ_WRITE_TOKEN?.trim()||null}function r(){return{prefix:x,artifactTtlMs:_,downloadTtlMs:b,token:C()}}function i(t){return(t.toLowerCase().replace(/[^a-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"connected-data-export").slice(0,120)}function N(t){return l(t,x)}function w(t){return f(t,r())}function O(t,e=Date.now()){let n=w(t);return!n||n.getTime()<=e}async function P(t){return g({...t,contentType:"application/x-ndjson"})}async function g(t){let e=t.stableCreatedAt?Date.parse(t.stableCreatedAt):NaN,n=Number.isFinite(e)?e:Date.now(),c=i(t.filename),y=t.stableKey?i(t.stableKey):D(),a;try{a=await p({policy:r(),ownerId:t.ownerId,artifactKey:`${i(t.exportId)}-${y}--${c}`,createdAt:n,filename:c,contentType:t.contentType,content:typeof t.content=="string"?t.content:Buffer.from(t.content)})}catch(o){throw o instanceof Error&&o.message==="private_artifact_blob_not_configured"?new Error("connected_data_private_blob_not_configured"):o}return{...a,...a.capabilities.includes("text")?{readback:{tool:"report_artifact_read",arguments:{artifactId:a.artifactId,offset:0,maxBytes:2e4},continuation:"Repeat with offset set to the previous result nextOffset until nextOffset is null."}}:{}}}async function B(t){return u({...t,policy:r()})}async function R(t,e,n){return A({policy:r(),artifactId:t,offset:e,maxBytes:n})}async function U(t){try{return await m({...t,policy:r(),maxBytes:t.maxBytes??25*1024*1024})}catch(e){if(e instanceof s&&e.code==="read_limit")return null;throw e}}async function h(t={}){let e=t.now??new Date,n=r();return n.token?!t.force&&!(e.getUTCHours()===3&&e.getUTCMinutes()===17)?{deleted:0,store:"private-vercel-blob",skipped:!0}:d({policy:n,now:e,includeLegacy:!0,maxObjects:2e4}):{deleted:0,store:process.env.VERCEL==="1"||process.env.NODE_ENV==="production"?"none":"local"}}export{x as a,_ as b,b as c,r as d,N as e,w as f,O as g,P as h,g as i,B as j,R as k,U as l,h as m};
@@ -0,0 +1 @@
1
+ import{createHash as w}from"crypto";import{createReadStream as R}from"fs";import{createHash as A}from"crypto";var g=/--v1-([a-f0-9]{64})(?:\.[a-zA-Z0-9]{1,16})?$/,m=class extends Error{constructor(e,n,a){super(`private_artifact_storage_${n}`,{cause:a});this.artifactId=e;this.outcome=n}artifactId;outcome;name="ArtifactStorageError"},d=class extends Error{constructor(e,n){super(n);this.code=e}code;name="ArtifactReadError"};function P(t){let r=t.toLowerCase().split(";")[0].trim(),e=["download"],n=t.match(/;\s*charset\s*=\s*"?([^;"\s]+)/i)?.[1]?.toLowerCase();return(n===void 0||n==="utf-8"||n==="utf8")&&(r.startsWith("text/")||["application/json","application/x-ndjson","application/ndjson","application/xml","application/javascript","message/rfc822"].includes(r)||r.endsWith("+json")||r.endsWith("+xml"))&&e.push("text"),r==="application/zip"&&e.push("archive"),r.startsWith("image/")&&e.push("image"),r.startsWith("audio/")&&e.push("audio"),r.startsWith("video/")&&e.push("video"),e}function _(t){return(t.trim().replace(/[^a-zA-Z0-9_.-]+/g,"-").replace(/^-+|-+$/g,"")||"artifact").slice(0,160)}function T(t){let r=t.replace(/^\/+/,"").replace(/\/+$/,"");if(!r||r.includes("..")||!/^[a-zA-Z0-9/_-]+$/.test(r))throw new Error("private artifact prefix is invalid");return`${r}/`}function x(t,r){let e=t.trim();if(!/^[a-zA-Z0-9_-]{1,160}$/.test(e)||e==="_metadata")throw new Error(`${r} must contain only letters, numbers, underscores, or hyphens`);return e}function B(t){let r=t.trim();if(!/^[a-zA-Z0-9_.-]{1,600}$/.test(r)||r.includes(".."))throw new Error("private artifact key is invalid");return r}function O(t,r){let e=T(r);if(!t.startsWith(e))return null;let n=t.slice(e.length).split("/");if(n.length<2)return null;try{let a=x(n[0],"ownerId");return n.slice(1,-1).forEach(s=>x(s,"scope")),B(n.at(-1)),/^\d{13}-/.test(n.at(-1))?a:null}catch{return null}}function S(t){let r=t.split("/").at(-1)?.match(/^(\d{13})-/),e=r?Number(r[1]):NaN;return Number.isSafeInteger(e)&&e>0?e:null}function M(t,r,e,n){if(r>n||t.length&&(t[0]&192)===128)throw new d("invalid_offset","private artifact offset falls inside a UTF-8 character or exceeds content");let a=Math.min(e,t.length);for(;a>0&&a<t.length&&(t[a]&192)===128;)a--;if(a===0&&r<n)throw new d("window_too_small","private artifact maxBytes is too small for the next UTF-8 character");let s;try{s=new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0}).decode(t.subarray(0,a))}catch{throw new d("invalid_utf8","private artifact is not valid UTF-8 text")}return{text:s,consumedBytes:a,nextOffset:r+a<n?r+a:null}}function N(t){return A("sha256").update(JSON.stringify(t)).digest("hex")}function U(t,r){let e=t;if(!e||e.version!==1||e.artifactId!==r||r.match(g)?.[1]!==e.fingerprint||!/^[a-f0-9]{64}$/.test(e.sha256)||!Number.isSafeInteger(e.bytes)||e.bytes<0||typeof e.filename!="string"||_(e.filename)!==e.filename||typeof e.contentType!="string"||!Number.isFinite(Date.parse(e.createdAt))||!Number.isFinite(Date.parse(e.expiresAt)))return!1;let{artifactId:n,fingerprint:a,...s}=e;return N(s)===a&&JSON.stringify(e.capabilities)===JSON.stringify(P(e.contentType))&&Date.parse(e.createdAt)===S(r)}function I(t,r){return`${r}_metadata/${t.slice(r.length)}.json`}async function k(t,r){let e=t.getReader(),n=[],a=0;try{for(;;){let{done:s,value:i}=await e.read();if(s)break;if(a+=i.byteLength,a>r)throw new d("read_limit","private artifact exceeds read limit");n.push(Buffer.from(i))}return Buffer.concat(n,a)}finally{await e.cancel().catch(()=>{}),e.releaseLock()}}async function y(t,r,e){let n=r.backend?null:await import("@vercel/blob"),a=r.backend?await r.backend.get(t,e):await n.get(t,{access:"private",token:r.token,useCache:!1,...e?{headers:{Range:`bytes=${e.start}-${e.end}`}}:{}});if(!a||"statusCode"in a&&a.statusCode!==200)return null;if(a.blob?.pathname!==t)throw await a.stream.cancel().catch(()=>{}),new d("integrity_mismatch","private artifact returned a different object identity");if(e){let i=a.headers?.get("content-range")?.match(/^bytes (\d+)-(\d+)\/(\d+)$/);if(!i||i.slice(1).some(c=>!Number.isSafeInteger(Number(c)))||Number(i[1])!==e.start||Number(i[2])>e.end||Number(i[2])<e.start||Number(i[3])<=Number(i[2]))throw await a.stream.cancel().catch(()=>{}),new d("range_unavailable","private artifact backend did not acknowledge the requested bounded range");return{...a,totalBytes:Number(i[3]),rangeBytes:Number(i[2])-e.start+1}}let s=a.blob.size;if(!r.backend&&(!Number.isSafeInteger(s)||s<0||s===0&&a.headers.get("content-length")!=="0"))try{let i=await n.head(t,{token:r.token});if(i.pathname!==t||!Number.isSafeInteger(i.size)||i.size<0)throw new d("integrity_mismatch","private artifact length metadata is invalid");s=i.size}catch(i){throw await a.stream.cancel().catch(()=>{}),i}return{...a,blob:{...a.blob,size:s},totalBytes:s,rangeBytes:s}}async function F(t){let r=R(t.file);try{if((t.policy.backend?await t.policy.backend.put({id:t.id,body:r,bytes:t.bytes,sha256:t.sha256,contentType:t.contentType}):await(await import("@vercel/blob")).put(t.id,r,{access:"private",token:t.policy.token,contentType:t.contentType,addRandomSuffix:!1,allowOverwrite:!1,cacheControlMaxAge:60,multipart:t.bytes>104857600})).pathname!==t.id)throw new Error("private artifact put returned a different object identity")}catch(e){r.destroy();try{let n=await y(t.id,t.policy);if(!n)throw e;if(n.totalBytes!==t.bytes||n.blob.contentType.split(";")[0]!==t.contentType.split(";")[0])throw await n.stream.cancel().catch(()=>{}),e;let a=n.stream.getReader(),s=w("sha256"),i=0;try{for(;;){let c=await a.read();if(c.done)break;if(i+=c.value.byteLength,i>t.bytes)throw e;s.update(c.value)}}finally{await a.cancel().catch(()=>{}),a.releaseLock()}if(i!==t.bytes||s.digest("hex")!==t.sha256)throw e}catch{throw new m(t.id,"unknown",e)}}finally{r.destroy()}}async function W(t,r,e,n){try{if((e.backend?await e.backend.put({id:t,body:Buffer.from(r),bytes:Buffer.byteLength(r),sha256:w("sha256").update(r).digest("hex"),contentType:"application/json"}):await(await import("@vercel/blob")).put(t,r,{access:"private",token:e.token,contentType:"application/json",addRandomSuffix:!1,allowOverwrite:!1,cacheControlMaxAge:60})).pathname!==t)throw new Error("private artifact metadata put returned a different identity")}catch(a){try{let s=await y(t,e);if(!s||(await k(s.stream,8192)).toString()!==r)throw a}catch{throw new m(n,"bytes-stored-metadata-pending",a)}}}async function L(t,r,e){if(e.backend){let u=await e.backend.sign(t,r);if(!u.startsWith("https://"))throw Error("private artifact download URL must use HTTPS");return u}let{getDownloadUrl:n,issueSignedToken:a,presignUrl:s}=await import("@vercel/blob"),i=await a({token:e.token,pathname:t,operations:["get"],validUntil:r}),c=await s(i,{access:"private",operation:"get",pathname:t,validUntil:r});if(!c.presignedUrl.startsWith("https://"))throw new Error("private artifact download URL must use HTTPS");return n(c.presignedUrl)}async function D(t,r,e){let n=t.backend?o=>t.backend.list(o.prefix,o.cursor,o.limit):(await import("@vercel/blob")).list,a=t.backend?o=>t.backend.delete(Array.isArray(o)?o:[o]):(await import("@vercel/blob")).del,s=t.backend?.kind??"private-vercel-blob",i=`${t.prefix}_cleanup/cursor.json`,c,u=0,h=0,f=!1,v=await y(i,t);if(v)try{let o=JSON.parse((await k(v.stream,8192)).toString());o.version===1&&o.prefix===t.prefix&&typeof o.cursor=="string"&&o.cursor.length>0&&o.cursor.length<=4096&&(c=o.cursor)}catch{return{deleted:0,store:s,pending:!0}}do{let o=await n({prefix:t.prefix,token:t.token,limit:Math.min(1e3,e-u),cursor:c});u+=o.blobs.length;let p=[];for(let l of o.blobs)await r(l.pathname)&&p.push(l.pathname);if(p.length)try{await a(p,{token:t.token}),h+=p.length;let l=p.filter(b=>g.test(b)).map(b=>I(b,t.prefix));l.length&&await a(l,{token:t.token})}catch{return{deleted:h,store:s,pending:!0}}if(f=o.hasMore,!f){if(c)try{await a(i,{token:t.token})}catch{f=!0}break}if(!o.cursor||o.cursor===c){f=!0;break}if(c=o.cursor,u>=e){try{if(c.length>4096)throw Error("private artifact cleanup cursor exceeds limit");let l=JSON.stringify({version:1,prefix:t.prefix,cursor:c});if((t.backend?await t.backend.put({id:i,body:Buffer.from(l),bytes:Buffer.byteLength(l),sha256:w("sha256").update(l).digest("hex"),contentType:"application/json",overwrite:!0}):await(await import("@vercel/blob")).put(i,l,{access:"private",token:t.token,contentType:"application/json",addRandomSuffix:!1,allowOverwrite:!0,cacheControlMaxAge:0})).pathname!==i)throw Error("private artifact cleanup cursor identity mismatch")}catch{f=!0}break}}while(!0);return{deleted:h,store:s,pending:f}}export{g as a,m as b,d as c,P as d,_ as e,T as f,x as g,B as h,O as i,S as j,M as k,N as l,U as m,I as n,k as o,y as p,F as q,W as r,L as s,D as t};
@@ -0,0 +1 @@
1
+ import{a as T,b as K,c as u,d as F,e as Z,f as q,g as J,h as G,i as h,j as Q,k as tt,l as et,m as B,n as C,o as R,p as k,q as at,r as it,s as z}from"./chunk-SDQW7IJN.js";import{c as O}from"./chunk-OILOHQNL.js";import{opendir as rt,readFile as nt,rm as X,stat as ut}from"fs/promises";import{join as b}from"path";var kt=7*864e5,Mt=15*6e4,$="9999-12-31T23:59:59.999Z";function g(e){if(e.artifactTtlMs!==null&&(!Number.isSafeInteger(e.artifactTtlMs)||e.artifactTtlMs<=0))throw new Error("private artifact TTL must be a positive integer");if(!Number.isSafeInteger(e.downloadTtlMs)||e.downloadTtlMs<=0)throw new Error("private artifact download TTL must be a positive integer");return{...e,token:e.token?.trim()||null,prefix:q(e.prefix)}}function N(e,t){let a=g(t);if(h(e,a.prefix)===null||a.artifactTtlMs===null)return null;let i=Q(e);return i===null?null:new Date(i+a.artifactTtlMs)}function D(e,t,a,i=Date.now()){let r=h(e,t.prefix);if(!r||a!==void 0&&r!==a)return!1;let n=N(e,t);return t.artifactTtlMs===null||n!==null&&n.getTime()>i}function E(e){return e.hosted??(process.env.VERCEL==="1"||process.env.NODE_ENV==="production")}function Y(e,t,a=Date.now()){let i=Math.min(a+t.downloadTtlMs,Date.parse(e));return i>a?i:null}async function Ft(e){let t=g(e.policy),a=(e.now??new Date).getTime(),i=e.maxObjects??1e3;if(!Number.isSafeInteger(i)||i<1||i>2e4||!Number.isFinite(a))throw new Error("private artifact cleanup budget/time is invalid");let r=d=>e.includeLegacy===!0&&D(d,t,void 0,a)===!1&&h(d,t.prefix)!==null,n=(d,m)=>B(d,m)&&h(m,t.prefix)===d.ownerId&&Date.parse(d.expiresAt)<=a,o=d=>T.test(d)&&h(d,t.prefix)!==null&&(N(d,t)?.getTime()??1/0)<=a;if(t.artifactTtlMs===null)return{deleted:0,store:t.backend?.kind??(t.token?"private-vercel-blob":E(t)?"none":"local"),pending:!1};if(t.backend||t.token?.trim()){let{cleanupPrivateBlobObjects:d,getPrivateBlob:m,metadataBlobId:v,consumePrivateBlob:c}=await import("./blob-store-GIH26EDO.js");return d(t,async s=>{if(s.startsWith(`${t.prefix}_metadata/`)&&s.endsWith(".json")){let y=`${t.prefix}${s.slice(`${t.prefix}_metadata/`.length,-5)}`;if(!o(y))return!1;let _=await m(s,t);if(!_)return!1;try{return n(JSON.parse((await c(_.stream,8192)).toString()),y)}catch{return!1}}if(!h(s,t.prefix))return!1;if(!T.test(s))return r(s);if(!o(s))return!1;let f=await m(v(s,t.prefix),t);if(!f)return o(s);try{return n(JSON.parse((await c(f.stream,8192)).toString()),s)}catch{return!1}},i)}if(E(t))return{deleted:0,store:"none",pending:!0};let l=O(t.localBaseDir),w=0,x=0,p=!1;async function I(d,m=""){let v=await rt(d).catch(c=>{if(c.code==="ENOENT")return null;throw c});if(v)for await(let c of v){let s=m?`${m}/${c.name}`:c.name;if(c.isDirectory())await I(b(d,c.name),s);else if(c.isFile()){let f=`${t.prefix}${s}`;if(!o(f)&&!r(f))continue;if(w>=i){p=!0;return}if(w++,T.test(f)){let y=await nt(b(l,"artifact-metadata",`${f}.json`),"utf8").catch(()=>null);if(y){let _;try{_=JSON.parse(y)}catch{p=!0;continue}if(!n(_,f)){(!B(_,f)||h(f,t.prefix)!==_.ownerId)&&(p=!0);continue}}}else if(!r(f))continue;try{await X(b(l,"blobs",f)),x++,await X(b(l,"artifact-metadata",`${f}.json`),{force:!0})}catch{p=!0}}}}await I(b(l,"blobs",t.prefix));async function P(d,m=""){let v=await rt(d).catch(c=>{if(c.code==="ENOENT")return null;throw c});if(v)for await(let c of v){let s=m?`${m}/${c.name}`:c.name;if(c.isDirectory())await P(b(d,c.name),s);else if(c.isFile()&&s.endsWith(".json")){let f=`${t.prefix}${s.slice(0,-5)}`;if(!o(f)||await ut(b(l,"blobs",f)).then(()=>!0,y=>{if(y.code==="ENOENT")return!1;throw y}))continue;if(w>=i){p=!0;return}w++;try{let y=JSON.parse(await nt(b(d,c.name),"utf8"));if(!n(y,f)){(!B(y,f)||h(f,t.prefix)!==y.ownerId)&&(p=!0);continue}await X(b(d,c.name)),x++}catch{p=!0}}}}return await P(b(l,"artifact-metadata",t.prefix)),{deleted:x,store:"local",pending:p}}import{createHash as H}from"crypto";import{constants as A,createWriteStream as mt}from"fs";import{link as ot,mkdir as V,mkdtemp as pt,open as M,readFile as wt,rm as yt,writeFile as ht}from"fs/promises";import{tmpdir as vt}from"os";import{dirname as ct,join as S}from"path";import{Readable as xt,Transform as bt}from"stream";import{pipeline as At}from"stream/promises";var L=T,Pt=1e5,Et=e=>H("sha256").update(e).digest("hex"),U=(e,t)=>S(O(e.localBaseDir),"blobs",t),st=(e,t)=>S(O(e.localBaseDir),"artifact-metadata",`${t}.json`);function It(e){let t=typeof e=="string"&&/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(e)?`${e.replace(" ","T")}Z`:e,a=t instanceof Date?t.getTime():typeof t=="number"?t:Date.parse(t);if(!Number.isSafeInteger(a)||a<1e12||a>9999999999999)throw new Error("private artifact createdAt is invalid");return a}function _t(e,t,a){let i=e;if(!B(i,t)||!t.startsWith(`${a.prefix}${i.ownerId}/`)||i.expiresAt!==(N(t,a)?.toISOString()??$))throw new u("integrity_mismatch","private artifact metadata does not match its identity/policy");return i}async function j(e,t){if(!L.test(e))return null;let a;if(t.backend||t.token?.trim()){let i=await k(C(e,t.prefix),t);if(!i)return null;a=await R(i.stream,8192)}else{if(E(t))return null;let i=await M(st(t,e),A.O_RDONLY|A.O_NOFOLLOW).catch(r=>{if(r.code==="ENOENT")return null;throw r});if(!i)return null;try{let r=await i.stat();if(!r.isFile()||r.size>8192)throw new u("integrity_mismatch","private artifact metadata exceeds limit");a=await i.readFile()}finally{await i.close()}}try{return _t(JSON.parse(a.toString("utf8")),e,t)}catch(i){throw i instanceof u?i:new u("integrity_mismatch","private artifact metadata is not valid JSON")}}async function ft(e,t){if(Date.parse(e.expiresAt)<=Date.now())return{downloadUrl:null,downloadUrlExpiresAt:null,downloadState:"unavailable"};if(t.backend?.localPath)return{downloadUrl:null,downloadUrlExpiresAt:null,downloadState:"local"};if(!(t.backend||t.token?.trim()))return{downloadUrl:null,downloadUrlExpiresAt:null,downloadState:E(t)?"unavailable":"local"};let a=Y(e.expiresAt,t);if(!a)return{downloadUrl:null,downloadUrlExpiresAt:null,downloadState:"unavailable"};try{return{downloadUrl:await z(e.artifactId,a,t),downloadUrlExpiresAt:new Date(a).toISOString(),downloadState:"available"}}catch{return{downloadUrl:null,downloadUrlExpiresAt:null,downloadState:"unavailable"}}}async function gt(e,t,a,i){let r=U(a,t.artifactId),n=st(a,t.artifactId),o=JSON.stringify(t);await V(ct(r),{recursive:!0}),await V(ct(n),{recursive:!0});let l=S(i,"metadata.json");await ht(l,o,{flag:"wx",mode:384});try{await ot(l,n)}catch(w){if(w.code!=="EEXIST")throw w;if(await wt(n,"utf8")!==o)throw new u("integrity_mismatch","private artifact metadata collision")}try{await ot(e,r)}catch(w){if(w.code!=="EEXIST")throw w;let x=H("sha256"),p=0,I=await M(r,A.O_RDONLY|A.O_NOFOLLOW);try{for await(let P of I.createReadStream()){if(p+=P.length,p>t.bytes)throw new u("integrity_mismatch","private artifact data collision");x.update(P)}if(p!==t.bytes||x.digest("hex")!==t.sha256)throw new u("integrity_mismatch","private artifact data collision")}finally{await I.close()}}}async function Kt(e){return St({...e,content:xt.from([Buffer.isBuffer(e.content)?e.content:Buffer.from(e.content)])})}async function St(e){let t=g(e.policy),a=J(e.ownerId,"ownerId"),i=G(e.artifactKey);if(i.length>400)throw new Error("private artifact key is too long");let r=(e.scopeSegments??[]).map(m=>J(m,"scopeSegments")),n=It(e.createdAt),o=Z(e.filename),l=e.contentType.trim().toLowerCase();if(l.length>256||!/^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+(?:;[\x20-\x7e]+)?$/.test(l))throw new Error("private artifact contentType is invalid");if(!(t.backend||t.token?.trim())&&E(t))throw new Error("private_artifact_blob_not_configured");let w=!(t.backend||t.token?.trim())||t.localBaseDir?S(O(t.localBaseDir),".artifact-staging"):S(vt(),"mcp-private-artifacts");await V(w,{recursive:!0,mode:448});let x=await pt(S(w,"write-")),p=S(x,"bytes"),I=H("sha256"),P=0,d=new bt({transform(m,v,c){P+=m.length,I.update(m),c(null,m)}});try{await At(e.content,d,mt(p,{flags:"wx",mode:384}));let m={version:1,ownerId:a,filename:o,contentType:l,bytes:P,sha256:I.digest("hex"),createdAt:new Date(n).toISOString(),expiresAt:t.artifactTtlMs===null?$:new Date(n+t.artifactTtlMs).toISOString(),capabilities:F(l)},v=o.match(/\.([a-zA-Z0-9]{1,16})$/)?.[1],c=et(m),s=`${t.prefix}${a}/${r.length?r.join("/")+"/":""}${n}-${i}--v1-${c}${v?"."+v:""}`;if(h(s,t.prefix)!==a)throw new Error("private artifact identity is invalid");let f={...m,artifactId:s,fingerprint:c};if(t.backend||t.token?.trim())await at({id:s,file:p,bytes:P,sha256:f.sha256,contentType:l,policy:t}),await it(C(s,t.prefix),JSON.stringify(f),t,s);else try{await gt(p,f,t,x)}catch(W){throw W instanceof u?W:new K(s,"unknown",W)}let{version:y,fingerprint:_,...dt}=f;return{...dt,...await ft(f,t)}}finally{await yt(x,{recursive:!0,force:!0})}}async function lt(e,t){if(t.backend||t.token?.trim()){let i=await k(e.artifactId,t);return i?(await i.stream.cancel().catch(()=>{}),i.totalBytes===e.bytes):!1}if(E(t))return!1;let a=await M(U(t,e.artifactId),A.O_RDONLY|A.O_NOFOLLOW).catch(i=>{if(i.code==="ENOENT")return null;throw i});if(!a)return!1;try{let i=await a.stat();return i.isFile()&&i.size===e.bytes}finally{await a.close()}}async function Zt(e){let t=g(e.policy);if(!D(e.artifactId,t,e.ownerId))return null;let a=await j(e.artifactId,t);if(!a||!await lt(a,t))return null;let{version:i,fingerprint:r,...n}=a;return{...n,...await ft(a,t)}}async function qt(e){let t=g(e.policy);if(!D(e.artifactId,t,e.ownerId)||!(t.backend||t.token?.trim()))return null;let a=await j(e.artifactId,t);if(L.test(e.artifactId)&&(!a||!await lt(a,t)))return null;let i=a?.expiresAt??N(e.artifactId,t)?.toISOString()??$,r=Y(i,t);return r?{downloadUrl:await z(e.artifactId,r,t),downloadUrlExpiresAt:new Date(r).toISOString(),expiresAt:i}:null}function Ot(e){let t=e.split(".").at(-1)?.toLowerCase();return{txt:"text/plain",md:"text/markdown",html:"text/html",csv:"text/csv",json:"application/json",jsonl:"application/x-ndjson",xml:"application/xml",eml:"message/rfc822"}[t??""]??"application/octet-stream"}async function Gt(e){let t=g(e.policy);if(!D(e.artifactId,t,e.ownerId))return null;if(!Number.isSafeInteger(e.offset)||e.offset<0)throw new u("invalid_offset","private artifact offset is invalid");if(!Number.isSafeInteger(e.maxBytes)||e.maxBytes<1||e.maxBytes>Pt||!Number.isSafeInteger(e.offset+e.maxBytes+1))throw new Error("private artifact maxBytes is invalid");let a=await j(e.artifactId,t);if(L.test(e.artifactId)&&!a)return null;let i=a?.contentType??Ot(e.artifactId),r,n;if(a&&!a.capabilities.includes("text"))throw new u("unsupported_text","private artifact does not support text reads; use its download/archive/media capability");if(t.backend||t.token?.trim()){if(a&&e.offset>a.bytes)throw new u("invalid_offset","private artifact offset exceeds content");if(a&&e.offset===a.bytes)return{text:"",totalBytes:a.bytes,offset:e.offset,consumedBytes:0,nextOffset:null,contentType:i,sha256:a.sha256};let o=await k(e.artifactId,t,{start:e.offset,end:e.offset+e.maxBytes});if(!o)return null;if(i=o.blob.contentType,n=o.totalBytes,!F(i).includes("text")||a&&n!==a.bytes)throw await o.stream.cancel().catch(()=>{}),new u(a&&n!==a.bytes?"integrity_mismatch":"unsupported_text","private artifact range metadata/capability is invalid");if(r=await R(o.stream,e.maxBytes+1),r.length!==o.rangeBytes)throw new u("integrity_mismatch","private artifact range body is incomplete")}else{if(E(t))return null;if(!F(i).includes("text"))throw new u("unsupported_text","private artifact does not support text reads; use its download/archive/media capability");let o=await M(U(t,e.artifactId),A.O_RDONLY|A.O_NOFOLLOW).catch(l=>{if(l.code==="ENOENT")return null;throw l});if(!o)return null;try{let l=await o.stat();if(n=l.size,!l.isFile()||a&&a.bytes!==n)throw new u("integrity_mismatch","private artifact bytes do not match metadata");if(e.offset>n)throw new u("invalid_offset","private artifact offset exceeds content");r=Buffer.alloc(Math.min(e.maxBytes+1,n-e.offset));let{bytesRead:w}=await o.read(r,0,r.length,e.offset);r=r.subarray(0,w)}finally{await o.close()}}return{...tt(r,e.offset,e.maxBytes,n),totalBytes:n,offset:e.offset,contentType:i,sha256:a?.sha256??null}}async function Qt(e){let t=g(e.policy);if(!D(e.artifactId,t,e.ownerId))return null;if(!Number.isSafeInteger(e.maxBytes)||e.maxBytes<1)throw new Error("private artifact maxBytes is invalid");let a=await j(e.artifactId,t);if(L.test(e.artifactId)&&!a)return null;let i;if(t.backend||t.token?.trim()){let r=await k(e.artifactId,t);if(!r)return null;if(a&&r.totalBytes!==a.bytes||r.totalBytes>e.maxBytes)throw await r.stream.cancel().catch(()=>{}),new u("read_limit","private artifact exceeds read limit or metadata size");i=await R(r.stream,e.maxBytes)}else{if(E(t))return null;let r=await M(U(t,e.artifactId),A.O_RDONLY|A.O_NOFOLLOW).catch(n=>{if(n.code==="ENOENT")return null;throw n});if(!r)return null;try{let n=await r.stat();if(!n.isFile()||a&&n.size!==a.bytes)throw new u("integrity_mismatch","private artifact bytes do not match metadata");if(n.size>e.maxBytes)throw new u("read_limit","private artifact exceeds read limit");i=Buffer.alloc(n.size);let o=0;for(;o<i.length;){let{bytesRead:l}=await r.read(i,o,i.length-o,o);if(!l)break;o+=l}if(o!==i.length)throw new u("integrity_mismatch","private artifact bytes changed during read")}finally{await r.close()}}if(a&&(i.length!==a.bytes||Et(i)!==a.sha256))throw new u("integrity_mismatch","private artifact digest mismatch");return i}export{kt as a,Mt as b,N as c,Ft as d,Kt as e,St as f,Zt as g,qt as h,Gt as i,Qt as j};
@@ -0,0 +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};