import{existsSync as et,mkdirSync as N,readFileSync as nt,rmSync as rt,statSync as ot,writeFileSync as it}from"node:fs";import{join as m}from"node:path";import{randomUUID as ut}from"node:crypto";var U=".zibby/output",O="sessions";function M(t){if(!t||typeof t!="object")return 8;let e=t.parallel;if(!e||typeof e!="object")return 8;let r=e.maxConcurrentRuns??e.maxConcurrent,n=Number(r);if(!Number.isFinite(n))return 8;let o=Math.floor(n);return o<1?8:Math.min(64,o)}function h(t){if(!t||typeof t!="object")return!1;let e=t.parallel;return!(!e||typeof e!="object"||e.waitWhenAtCapacity===!1)}import{existsSync as E,mkdirSync as X,readFileSync as k,readdirSync as L,statSync as F,writeFileSync as Q}from"node:fs";import{join as C}from"node:path";function S(t){let e=Number(t);if(!Number.isFinite(e)||e<=0)return null;try{return process.kill(e,0),!0}catch(r){let n=r&&typeof r=="object"?r.code:"";return n==="ESRCH"?!1:n==="EPERM"?!0:null}}function H(t,e={}){if(!t||!E(t))return{patched:0};let r=e.studioNoPidMaxAgeMs!=null&&Number.isFinite(e.studioNoPidMaxAgeMs)?Math.max(0,e.studioNoPidMaxAgeMs):120*1e3,n=Date.now(),o=0,i;try{i=L(t)}catch{return{patched:0}}for(let s of i){let u=C(t,s),a;try{a=F(u)}catch{continue}if(!a.isDirectory())continue;let c=x(u);if(!c||c.status!=="running")continue;let l=Number(c.updatedAt)||0,y=S(c.pid),f=!1,p="";y===!1?(f=!0,p="process-exited"):y===null&&c.runSource==="studio"&&r>0&&l>0&&n-l>r&&(f=!0,p="studio-stale-no-pid"),f&&(K(u,{status:"interrupted",activeNode:null,activeStageIndex:null,exitReason:p}),o+=1)}return{patched:o}}var $="zibby-run-state.json";function g(t){return C(t,$)}function x(t){if(!t||typeof t!="string")return null;let e=g(t);if(!E(e))return null;try{let r=k(e,"utf8"),n=JSON.parse(r);return n&&typeof n=="object"?n:null}catch{return null}}function K(t,e){if(!t||typeof t!="string")return;try{X(t,{recursive:!0})}catch{return}let n={...x(t)||{v:1},...e,v:1,updatedAt:Date.now()};try{Q(g(t),`${JSON.stringify(n)}
`,"utf8")}catch(o){console.warn(`[zibby run-state] ${o.message}`)}}function v(t,e={}){if(!t||!E(t))return[];e.reconcile!==!1&&H(t,e.reconcile||{});let r=e.maxStaleMs!=null&&Number.isFinite(e.maxStaleMs)&&e.maxStaleMs>0?e.maxStaleMs:1800*1e3,n=typeof e.now=="number"?e.now:Date.now(),o;try{o=L(t)}catch{return[]}let i=[];for(let s of o){let u=C(t,s),a;try{a=F(u)}catch{continue}if(!a.isDirectory())continue;let c=x(u);if(!c||c.status!=="running")continue;let l=Number(c.updatedAt)||0;r>0&&l>0&&n-l>r||i.push({sessionId:s,sessionPathAbs:u,...c})}return i}import{existsSync as A,mkdirSync as Y,readFileSync as J,renameSync as q,unlinkSync as z,writeFileSync as V}from"node:fs";import{join as G}from"node:path";var Z="run-capacity-wait.json",d=1,tt=10800*1e3;function b(t){return G(t,Z)}function _(){return{v:d,entries:[]}}function D(t){if(!t||!A(t))return _();let e=b(t);if(!A(e))return _();try{let r=J(e,"utf8"),n=JSON.parse(r);if(!n||typeof n!="object")return _();let o=Array.isArray(n.entries)?n.entries:[];return{v:d,entries:o}}catch{return _()}}function j(t,e=Date.now()){let r=t&&Array.isArray(t.entries)?t.entries:[],n=[];for(let o of r){if(!o||typeof o!="object")continue;let i=Number(o.pid),s=Number(o.updatedAt)||Number(o.enqueuedAt)||0,u=Number.isFinite(i)&&i>0?S(i):null;u!==!1&&(u===null&&s>0&&e-s>tt||n.push(o))}return{v:d,entries:n}}function P(t,e){let r=b(t);Y(t,{recursive:!0});let n={v:d,entries:Array.isArray(e.entries)?e.entries:[]},o=`${r}.${process.pid}.${Date.now()}.tmp`;V(o,`${JSON.stringify(n)}
`,"utf8");try{A(r)&&z(r)}catch{}q(o,r)}function W(t,e){let r=j(D(t)),n=e?.id!=null?String(e.id):"";if(!n)return;let o=r.entries.filter(s=>s&&String(s.id)!==n),i=Date.now();o.push({...e,id:n,pid:Number.isFinite(Number(e.pid))?Number(e.pid):process.pid,enqueuedAt:Number(e.enqueuedAt)||i,updatedAt:i}),P(t,{v:d,entries:o})}function I(t,e){let r=e!=null?String(e):"";if(!r||!t)return;let n=j(D(t)),o=n.entries.filter(i=>i&&String(i.id)!==r);o.length!==n.entries.length&&P(t,{v:d,entries:o})}var ct=".zibby-run-capacity-guard",st=12e4;function at(t,e){let r=e?.paths?.output||U,n=m(t,r),o=m(n,O);return{outputAbs:n,sessionsRootAbs:o}}function R(t){try{rt(t,{recursive:!0,force:!0})}catch{}}function lt(t){try{let e=nt(m(t,"owner.pid"),"utf8"),r=Number(String(e).trim());return Number.isFinite(r)&&r>0?r:null}catch{return null}}function ft(t){if(!et(t))return!0;let e=lt(t);if(e!=null){let r=S(e);if(r===!0)return!1;if(r===!1)return R(t),!0}try{let r=ot(t);if(Date.now()-r.mtimeMs>st)return R(t),!0}catch{return R(t),!0}return!1}async function pt(t,e){N(t,{recursive:!0});let r=m(t,ct);for(;;)try{N(r,{recursive:!1}),it(m(r,"owner.pid"),String(process.pid),"utf8");try{return await e()}finally{R(r)}}catch(n){if((n&&typeof n=="object"?n.code:"")!=="EEXIST")throw n;if(ft(r))continue;await new Promise(i=>setTimeout(i,35+Math.random()*45))}}async function Mt(t){let{cwd:e,config:r,meta:n={},log:o,pollMs:i=1500}=t;if(process.env.ZIBBY_WAIT_FOR_RUN_CAPACITY==="0"||process.env.ZIBBY_WAIT_FOR_RUN_CAPACITY==="false")return{waited:!1,jobId:""};if(!h(r))return{waited:!1,jobId:""};let s=M(r),{outputAbs:u,sessionsRootAbs:a}=at(e,r);N(u,{recursive:!0});let c=ut(),l=n.studioTestCaseId!=null&&String(n.studioTestCaseId).trim()!==""?String(n.studioTestCaseId).trim():null,y={id:c,pid:process.pid,cwd:String(e),enqueuedAt:Date.now(),updatedAt:Date.now(),source:n.source!=null?String(n.source):"cli",specHint:n.specHint!=null&&String(n.specHint).trim()!==""?String(n.specHint).trim().slice(0,240):"",studioTestCaseId:l},f=!1,p=0,B=()=>{try{I(u,c)}catch{}};try{for(;;){let w=!1;if(await pt(u,async()=>{if(N(u,{recursive:!0}),p=v(a,{reconcile:{}}).length,p<s){I(u,c),w=!0;return}W(u,{...y,updatedAt:Date.now()})}),w)return{waited:f,jobId:c};f||(typeof o=="function"&&o(`Waiting for run capacity (${p}/${s} active)\u2026`),f=!0),await new Promise(T=>setTimeout(T,i))}}finally{B()}}export{at as resolveRunCapacityPaths,Mt as waitUntilRunCapacity};
