@north-light/cli 0.3.573 → 0.3.574

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.
@@ -1722,7 +1722,7 @@ ${u}`,"1").then(l=>{let d=a.options[Number.parseInt(l,10)-1]?.id;if(d===void 0)t
1722
1722
  ${f}
1723
1723
  `)}if(h==="node-done"){process.stderr.write(`
1724
1724
  \u2713 node ${i} finished \u2014 final report submitted.
1725
- `);let f=e.tagPane()??process.env.TMUX_PANE??ig()?.pane;!o&&f!==void 0&&Rs()&&wy(f)}u()}};return{done:l,teardown:d,isTornDown:()=>c,installSignalHandlers:()=>{let h=()=>d("signal");process.once("SIGTERM",h),process.once("SIGHUP",h),process.once("SIGINT",h)}}}Sl();Fhe();import{join as iri}from"node:path";function WE(t,e){let n=`${new Date().toISOString()} ${t} ${e}`.replaceAll(/[\r\n]/g," ");R3(iri(Na(),"attach-invariants.log"),n)}import{EventEmitter as yri}from"node:events";import{randomUUID as xri}from"node:crypto";Sl();import{EventEmitter as mri}from"node:events";var ori="crtr:managed-provider-cooling";function Zfn(t){let e=t?.diagnostics;return Array.isArray(e)&&e.some(n=>n?.type===ori)}function rVe(t){return typeof t=="string"?t:""}function Lp(t,e,n={}){return{kind:t,matchedOn:e,...n}}function Ym(t,e){return e.matchedOn==="text"?{...t,textKind:e.kind,textMatch:e.match,textMatches:e.textMatches}:t}var sri=[["rate-limit",/rate.?limit|\b429\b|too many requests|usage[ _]limit|usage_not_included|usagelimiterror|insufficient_quota|quota exceeded/i],["protocol",/\b413\b|payload too large|entity too large|request too large|entity\.too\.large|body exceeds/i],["auth",/invalid_grant|refresh token|unauthori[sz]ed|invalid.?api.?key|authentication failed|\b401\b|\b403\b/i],["context-overflow",/context overflow recovery failed/i],["protocol",/websocket.*(?:closed.*\b(?:1002|1003|1007|1008|1009|1010)\b|protocol error|policy violation|unsupported data|invalid (?:frame|payload)|message too big|mandatory extension)/i],["overloaded-only",/lock file is already being held/i],["overloaded",/overloaded|temporarily unavailable/i],["service-unavailable",/service.?unavailable/i],["overloaded-only",/internal server error|api.?error|\b5\d\d\b|capacity|server.{0,3}busy/i],["connection",/connection|econnreset|etimedout|enotfound|econnrefused|network|fetch failed|socket hang|timed? out|timeout|websocket\s+(?:was\s+)?closed|websocket stream closed before response\.completed|websocket\s+error|websocket.*interrupt/i],["socket",/socket/i],["connection-only",/eai_again|epipe|ehostunreach|enetunreach|\bterminated\b|other side closed|premature close/i]];function emn(t){let e=sri.flatMap(([r,i])=>{let o=t.match(i);return o?[{kind:r,match:o[0]}]:[]}),n=e[0];return n===void 0?Lp("other","none"):{...Lp(n.kind,"text",{match:n.match}),textMatches:e}}function tmn(t){let e=t.retryAfterMs,n=emn(t.message??""),r=rVe(t.code)||rVe(t.errno);if(/^(ECONNREFUSED|ECONNRESET|ETIMEDOUT|ENOENT|ENOTFOUND|EAI_AGAIN|EPIPE|EHOSTUNREACH|ENETUNREACH)$/i.test(r))return Ym(Lp("connection","errno",{retryAfterMs:e}),n);if(/^ELOCKED$/i.test(r))return Ym(Lp("overloaded","errno",{retryAfterMs:e}),n);let i=typeof t.status=="number"?t.status:void 0;if(i!==void 0){if(i===401||i===403)return Ym(Lp("auth","status",{status:i,retryAfterMs:e}),n);if(i===429)return Ym(Lp("rate-limit","status",{status:i,retryAfterMs:e}),n);if(i===500||i===502||i===503||i===504)return Ym(Lp("transient-http","status",{status:i,retryAfterMs:e}),n);if(i>=500&&i<=599)return Ym(Lp("overloaded","status",{status:i,retryAfterMs:e}),n);if(i>=400&&i<=499)return Ym(Lp("protocol","status",{status:i,retryAfterMs:e}),n)}let o=typeof t.wsCloseCode=="number"?t.wsCloseCode:void 0;if(o===1008)return Ym(Lp("protocol","websocket-close",{retryAfterMs:e}),n);if(o===1006)return Ym(Lp("connection","websocket-close",{retryAfterMs:e}),n);if(o===1011){let s=rVe(t.wsCloseReason),a=emn(s);return/no running broker/i.test(s)||a.kind==="connection"||a.kind==="connection-only"?Ym(Lp("connection","websocket-close",{retryAfterMs:e}),n):Ym(Lp("other","websocket-close",{retryAfterMs:e}),n)}return e===void 0?n:{...n,retryAfterMs:e}}function FN(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}var ari="crtr:provider-failure";function ga(t){return typeof t=="string"&&t.trim()!==""?t.trim():void 0}function rpe(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function ipe(t){return typeof t=="string"||typeof t=="number"?t:void 0}function UN(t){return FN(t)?t:void 0}function cri(t){let e=ga(t.errorMessage)??ga(t.message)??ga(t.reason)??ga(t.statusText),n={...e===void 0?{}:{message:e},...rpe(t.status)===void 0?{}:{status:rpe(t.status)},...ipe(t.code)===void 0?{}:{code:ipe(t.code)},...ga(t.errno)===void 0?{}:{errno:ga(t.errno)},...ga(t.body)===void 0?{}:{body:ga(t.body)}};return Object.keys(n).length===0?void 0:n}var uri=48,lri=256;function nmn(t){let e=UN(t),n=UN(e?.headers);if(e===void 0||n===void 0)return;let r={};for(let[i,o]of Object.entries(n)){if(Object.keys(r).length>=uri)break;typeof o=="string"&&(r[i.toLowerCase()]=o.slice(0,lri))}return{...ga(e.scope)===void 0?{}:{scope:ga(e.scope)},...ga(e.claim)===void 0?{}:{claim:ga(e.claim)},...ga(e.account)===void 0?{}:{account:ga(e.account)},...ga(e.model)===void 0?{}:{model:ga(e.model)},headers:r}}function dri(t){let e=UN(t)?.diagnostics;if(Array.isArray(e))for(let n of e){let r=UN(n);if(r?.type!==ari)continue;let i=UN(r.details);if(i===void 0)continue;let o=Array.isArray(i.causes)?i.causes.flatMap(s=>{let a=UN(s),c=a===void 0?void 0:cri(a);return c===void 0?[]:[c]}):void 0;return{...rpe(i.status)===void 0?{}:{status:rpe(i.status)},...ipe(i.code)===void 0?{}:{code:ipe(i.code)},...ga(i.errno)===void 0?{}:{errno:ga(i.errno)},...ga(i.body)===void 0?{}:{body:ga(i.body)},...o===void 0||o.length===0?{}:{causes:o},...nmn(i.ratelimit)===void 0?{}:{ratelimit:nmn(i.ratelimit)}}}}function rmn(t){return dri(t)}function pri(t){switch(t.kind){case"rate-limit":return"rate-limit";case"auth":return"auth";case"protocol":return"protocol";case"context-overflow":return"context-overflow";case"overloaded":case"overloaded-only":case"transient-http":return"overloaded";case"connection":case"connection-only":return"connection";case"socket":case"service-unavailable":case"other":return"other"}}function imn(t,e){return e==="auth"||e==="protocol"||e==="context-overflow"?"fatal":t==="pi\u2192provider"?e==="connection"||e==="rate-limit"||e==="overloaded"?"auto":"fatal":"manual"}function hri(t){if(typeof t=="string")return t;if(!FN(t))return"";let e=[t.message,t.errorMessage,t.reason,t.body,t.statusText];for(let r of e)if(typeof r=="string"&&r!=="")return r;let n=t.error;if(FN(n)){let r=n.message;if(typeof r=="string"&&r!=="")return r;let i=n.reason;if(typeof i=="string"&&i!=="")return i}return""}var fri="upstream_model_unavailable";function ope(t,e){if(t==="pi\u2192provider"&&Zfn(e))return{kind:"rate-limit",disposition:"auto"};let n=FN(e)?e:{},r=rmn(e),i=r?.causes??[];if(r?.code===fri)return{kind:"connection",disposition:imn(t,"connection")};let o=tmn({code:n.code??r?.code??i.find(a=>a.code!==void 0)?.code,errno:n.errno??r?.errno??i.find(a=>a.errno!==void 0)?.errno,status:n.status??r?.status,wsCloseCode:n.code,wsCloseReason:n.reason,message:[hri(e),r?.body,...i.flatMap(a=>[a.message,a.body])].filter(a=>typeof a=="string"&&a!=="").join(" ")}),s=pri(o);return{kind:s,disposition:imn(t,s)}}h$();aR();var ly=class extends Error{constructor(n){super(`node ${n} has no running broker \u2014 focus or revive it first`);this.nodeId=n;this.name="BrokerUnavailableError"}nodeId};var QN=class extends mri{constructor(n,r={}){super();this.nodeId=n;this.options=r}nodeId;options;socket;decoder=new V$(jz);closeEmitted=!1;redialFaultRecorded=!1;get socketPath(){return YT(this.nodeId)}recordSocketFault(n,r){if(this.options.recordsViewerFaults===!1)return;if(n==="redial"){if(this.redialFaultRecorded)return;this.redialFaultRecorded=!0}let i=ope("viewer\u2194broker",r);aXe(this.nodeId,{link:"viewer\u2194broker",op:n,kind:i.kind,retry:n==="redial"?{disposition:"auto",by:"client"}:{disposition:"manual"},message:r instanceof Error?r.message:String(r)}).catch(o=>{$d({event:"broker.daemon.operation.failed",level:"error",node_id:this.nodeId,error:o,fields:{operation:"viewer_fault_record"}})})}connect(){let n=_ge(this.nodeId);this.socket=n,n.on("connect",()=>{this.redialFaultRecorded=!1,this.clearSocketFault(),this.emit("connect")}),n.on("data",r=>this.onData(r)),n.on("error",r=>this.onError(r,"connect")),n.on("close",()=>this.onClose())}redial(n={}){return this.destroy(),this.decoder=new V$(jz),this.closeEmitted=!1,n.brokerUnavailableIsExpected&&(this.redialFaultRecorded=!1,this.clearSocketFault()),new Promise((r,i)=>{let o=_ge(this.nodeId);this.socket=o;let s=!1;o.on("connect",()=>{s||(s=!0,this.redialFaultRecorded=!1,this.clearSocketFault(),this.emit("connect"),r())}),o.on("data",a=>this.onData(a)),o.on("error",a=>{if(s){this.onError(a,"redial");return}s=!0;let c=a.code==="ECONNREFUSED"||a.code==="ENOENT";(!n.brokerUnavailableIsExpected||!c)&&this.recordSocketFault("redial",a);try{o.destroy()}catch{}i(a)}),o.on("close",()=>this.onClose())})}send(n){let r=this.socket;if(!(r===void 0||r.destroyed))try{r.write(Gz(n))}catch{}}destroy(){let n=this.socket;if(n!==void 0&&!n.destroyed)try{n.destroy()}catch{}}clearSocketFault(){this.options.recordsViewerFaults!==!1&&cXe(this.nodeId,{link:"viewer\u2194broker"}).catch(n=>{$d({event:"broker.daemon.operation.failed",level:"error",node_id:this.nodeId,error:n,fields:{operation:"viewer_fault_clear"}})})}onData(n){let r;try{r=this.decoder.push(n)}catch(i){let o=i instanceof IR?`broker sent an oversized frame (${i.message}) \u2014 disconnecting`:`failed to decode a broker frame: ${String(i)}`;this.emitError(new Error(o)),this.destroy();return}for(let i of r)this.emit("frame",i)}onError(n,r){this.recordSocketFault(r,n),n.code==="ECONNREFUSED"||n.code==="ENOENT"?this.emitError(new ly(this.nodeId)):this.emitError(new Error(`view socket error: ${n.message}`))}onClose(){this.closeEmitted||(this.closeEmitted=!0,this.emit("close"))}emitError(n){this.listenerCount("error")>0&&this.emit("error",n)}};qz();import{EventEmitter as gri}from"node:events";function Ari(t,e){if("socketPath"in t)return`ws+unix://${t.socketPath}:/v1/nodes/${encodeURIComponent(e)}/attach?revive=0`;let n=new URL(t.previewEndpoint);return n.protocol=n.protocol==="http:"?"ws:":"wss:",n.pathname=`/v1/nodes/${encodeURIComponent(e)}/attach`,n.search="?wakeParked=1",n.hash="",n.toString()}var RT=class extends gri{constructor(n,r){super();this.nodeId=n;this.target=r}nodeId;target;ws;closeEmitted=!1;get url(){return Ari(this.target,this.nodeId)}dial(){let n=new Vx.default(this.url,{..."relayToken"in this.target?{headers:{authorization:`Bearer ${this.target.relayToken}`}}:{},perMessageDeflate:!1});return this.ws=n,n}connect(){let n=this.dial();n.on("open",()=>{this.emit("connect")}),n.on("message",r=>this.onMessage(r)),n.on("error",r=>this.onError(r)),n.on("close",(r,i)=>this.onClose(r,i.toString()))}redial(n){return this.destroy(),this.closeEmitted=!1,new Promise((r,i)=>{let o=this.dial(),s=!1;o.on("open",()=>{s||(s=!0,this.emit("connect"),r())}),o.on("message",a=>this.onMessage(a)),o.on("error",a=>{if(s){this.onError(a);return}s=!0;try{o.terminate()}catch{}i(a)}),o.on("close",(a,c)=>{s&&this.onClose(a,c.toString())})})}send(n){let r=this.ws;if(!(r===void 0||r.readyState!==Vx.default.OPEN))try{r.send(JSON.stringify(n))}catch{}}destroy(){let n=this.ws;if(n!==void 0&&n.readyState<=Vx.default.OPEN)try{n.close(1e3)}catch{}}onMessage(n){let r;try{r=JSON.parse(n.toString())}catch{return}this.emit("frame",r)}onError(n){this.emitError(new Error(`relay transport error: ${n.message}`))}onClose(n,r){if(this.closeEmitted)return;this.closeEmitted=!0;let i=ope("viewer\u2194broker",{code:n,reason:r});(n===1008||i.kind==="protocol"||n===1011&&(/^no running broker/.test(r)||/^no node /.test(r)))&&this.emitError(new ly(this.nodeId)),this.emit("close")}emitError(n){this.listenerCount("error")>0&&this.emit("error",n)}};var omn=1e4;function iVe(t){return t===null?!0:t.lifecycle==="resident"&&t.status==="done"&&t.intent==="parked"&&t.final_report==null?!1:t.status==="done"||t.status==="dead"||t.status==="canceled"}var Dj=class extends yri{constructor(n,r={}){super();this.nodeId=n;this.transport=r.transport??new QN(n),this.transport.on("connect",()=>{this.closeEmitted=!1,this.connected=!0,this.lastTransportError=void 0,this.emit("connect")}),this.transport.on("frame",i=>this.onFrame(i)),this.transport.on("error",i=>{this.lastTransportError=i.message,this.emitError(i)}),this.transport.on("close",()=>this.onClose())}nodeId;transport;closeEmitted=!1;connected=!1;lastTransportError;pending=new Map;request(n){let r=xri();return new Promise((i,o)=>{if(!this.connected){o(new Error(`cannot issue '${n.type}': no live broker connection`));return}let s=setTimeout(()=>{this.pending.delete(r),o(new Error(`request '${n.type}' timed out after ${omn}ms`))},omn);typeof s.unref=="function"&&s.unref(),this.pending.set(r,{resolve:i,reject:o,timer:s}),this.send({...n,id:r})})}rejectAllPending(n){for(let{reject:r,timer:i}of this.pending.values())clearTimeout(i),r(new Error(n));this.pending.clear()}connect(){this.transport.connect()}redial(n){return this.transport.redial(n)}send(n){this.transport.send(n)}close(){this.transport.destroy()}onFrame(n){if(n.type==="data"){let r=typeof n.id=="string"?this.pending.get(n.id):void 0;r&&(this.pending.delete(n.id),clearTimeout(r.timer),r.resolve(n));return}if(n.type==="error"&&typeof n.id=="string"&&this.pending.has(n.id)){let r=this.pending.get(n.id);this.pending.delete(n.id),clearTimeout(r.timer),r.reject(new Error(n.message||`request failed: ${n.code}`));return}this.emit("frame",n)}onClose(){this.closeEmitted||(this.closeEmitted=!0,this.connected=!1,this.rejectAllPending(this.lastTransportError??"broker connection closed"),this.emit("close"))}emitError(n){this.listenerCount("error")>0&&this.emit("error",n)}};var wri=1e3,bri=3e3;function smn(t,e){let{nodeId:n,socket:r,canvasSource:i}=t,o,s=!1,a=e.initialDormant===!0,c=!1,u=!1,l=()=>{},d,p,h=new Promise(w=>{l=w}),f=w=>u?Promise.resolve(!1):new Promise(v=>{let S=_=>{d=void 0,p=void 0,v(_)};d=setTimeout(()=>S(!0),w),p=()=>{d!==void 0&&clearTimeout(d),S(!1)}}),m=()=>{r.send({type:"hello",role:e.role,client_id:e.clientId,term:{cols:process.stdout.columns??80,rows:process.stdout.rows??24}})},g=async()=>{s=!0,e.setNotice("\u21BB node refreshing \u2014 reconnecting\u2026",{sticky:!0});let w=200;try{for(;!u&&!e.isTornDown();){let v;try{v=await i.getRow(n)}catch{v=void 0}if(v!==void 0&&iVe(v)){c=v?.status==="done";break}let S=v?.status==="idle"||v?.intent==="idle-release"||v?.lifecycle==="resident"&&v.status==="done"&&v.intent==="parked"&&v.final_report==null,_=S&&!a;a=S,_&&e.onEnterDormancy(),e.setNotice(S?"":"\u21BB node refreshing \u2014 reconnecting\u2026",{sticky:!S});try{if(!await Promise.race([r.redial({brokerUnavailableIsExpected:S}).then(()=>!0),h.then(()=>!1)])||u||e.isTornDown())return;m(),a=!1,e.setNotice("");return}catch{if(!await f(S?bri:Math.min(w,wri)))return;w*=2}}}finally{s=!1}!u&&!e.isTornDown()&&e.teardown(c?"node-done":"broker-gone")};return{sendHello:m,startDormant:()=>{s||u||e.isTornDown()||(e.onEnterDormancy(),g())},isDormant:()=>a,lastSocketError:()=>o,install:async()=>{r.on("frame",e.onFrame),r.on("error",w=>{o=w.message}),r.on("close",()=>{e.isTornDown()||s||g()})},stop:()=>{u||(u=!0,p?.(),l())}}}function spe(t){if(typeof t!="object"||t===null||Array.isArray(t))return!1;try{let e=Object.getPrototypeOf(t);if(e!==Object.prototype&&e!==null||Object.getOwnPropertySymbols(t).length!==0)return!1;let n=Object.getOwnPropertyNames(t).sort();if(n.length!==3||n[0]!=="body"||n[1]!=="commandName"||n[2]!=="kind")return!1;let r=Object.getOwnPropertyDescriptors(t);if(Object.values(r).some(o=>!("value"in o)))return!1;let i=t;return i.kind!=="memory-slash"||typeof i.commandName!="string"||typeof i.body!="string"?!1:(JSON.stringify(t),!0)}catch{return!1}}function vri(t){let e="",n=0,r=!0,i,o;for(;n<t.length;){if(r&&o===void 0){let a=t.slice(n).match(/^(?: {0,3})(`{3,}|~{3,})/);if(a!==null){let c=a[1][0],u=a[1].length;i===void 0?i={marker:c,length:u}:i.marker===c&&u>=i.length&&(i=void 0)}}if(i===void 0&&o===void 0&&t.startsWith("<!--",n)){let a=t.indexOf("-->",n+4),c=a===-1?t.length:a+3,u=t.indexOf(`
1725
+ `);let f=e.tagPane()??process.env.TMUX_PANE??ig()?.pane;!o&&f!==void 0&&Rs()&&wy(f)}u()}};return{done:l,teardown:d,isTornDown:()=>c,installSignalHandlers:()=>{let h=()=>d("signal");process.once("SIGTERM",h),process.once("SIGHUP",h),process.once("SIGINT",h)}}}Sl();Fhe();import{join as iri}from"node:path";function WE(t,e){let n=`${new Date().toISOString()} ${t} ${e}`.replaceAll(/[\r\n]/g," ");R3(iri(Na(),"attach-invariants.log"),n)}import{EventEmitter as yri}from"node:events";import{randomUUID as xri}from"node:crypto";Sl();import{EventEmitter as mri}from"node:events";var ori="crtr:managed-provider-cooling";function Zfn(t){let e=t?.diagnostics;return Array.isArray(e)&&e.some(n=>n?.type===ori)}function rVe(t){return typeof t=="string"?t:""}function Lp(t,e,n={}){return{kind:t,matchedOn:e,...n}}function Ym(t,e){return e.matchedOn==="text"?{...t,textKind:e.kind,textMatch:e.match,textMatches:e.textMatches}:t}var sri=[["protocol",/workspace api usage limits?/i],["rate-limit",/rate.?limit|\b429\b|too many requests|usage[ _]limit|usage_not_included|usagelimiterror|insufficient_quota|quota exceeded/i],["protocol",/\b413\b|payload too large|entity too large|request too large|entity\.too\.large|body exceeds/i],["auth",/invalid_grant|refresh token|unauthori[sz]ed|invalid.?api.?key|authentication failed|\b401\b|\b403\b/i],["context-overflow",/context overflow recovery failed/i],["protocol",/websocket.*(?:closed.*\b(?:1002|1003|1007|1008|1009|1010)\b|protocol error|policy violation|unsupported data|invalid (?:frame|payload)|message too big|mandatory extension)/i],["overloaded-only",/lock file is already being held/i],["overloaded",/overloaded|temporarily unavailable/i],["service-unavailable",/service.?unavailable/i],["overloaded-only",/internal server error|api.?error|\b5\d\d\b|capacity|server.{0,3}busy/i],["connection",/connection|econnreset|etimedout|enotfound|econnrefused|network|fetch failed|socket hang|timed? out|timeout|websocket\s+(?:was\s+)?closed|websocket stream closed before response\.completed|websocket\s+error|websocket.*interrupt/i],["socket",/socket/i],["connection-only",/eai_again|epipe|ehostunreach|enetunreach|\bterminated\b|other side closed|premature close/i]];function emn(t){let e=sri.flatMap(([r,i])=>{let o=t.match(i);return o?[{kind:r,match:o[0]}]:[]}),n=e[0];return n===void 0?Lp("other","none"):{...Lp(n.kind,"text",{match:n.match}),textMatches:e}}function tmn(t){let e=t.retryAfterMs,n=emn(t.message??""),r=rVe(t.code)||rVe(t.errno);if(/^(ECONNREFUSED|ECONNRESET|ETIMEDOUT|ENOENT|ENOTFOUND|EAI_AGAIN|EPIPE|EHOSTUNREACH|ENETUNREACH)$/i.test(r))return Ym(Lp("connection","errno",{retryAfterMs:e}),n);if(/^ELOCKED$/i.test(r))return Ym(Lp("overloaded","errno",{retryAfterMs:e}),n);let i=typeof t.status=="number"?t.status:void 0;if(i!==void 0){if(i===401||i===403)return Ym(Lp("auth","status",{status:i,retryAfterMs:e}),n);if(i===429)return Ym(Lp("rate-limit","status",{status:i,retryAfterMs:e}),n);if(i===500||i===502||i===503||i===504)return Ym(Lp("transient-http","status",{status:i,retryAfterMs:e}),n);if(i>=500&&i<=599)return Ym(Lp("overloaded","status",{status:i,retryAfterMs:e}),n);if(i>=400&&i<=499)return Ym(Lp("protocol","status",{status:i,retryAfterMs:e}),n)}let o=typeof t.wsCloseCode=="number"?t.wsCloseCode:void 0;if(o===1008)return Ym(Lp("protocol","websocket-close",{retryAfterMs:e}),n);if(o===1006)return Ym(Lp("connection","websocket-close",{retryAfterMs:e}),n);if(o===1011){let s=rVe(t.wsCloseReason),a=emn(s);return/no running broker/i.test(s)||a.kind==="connection"||a.kind==="connection-only"?Ym(Lp("connection","websocket-close",{retryAfterMs:e}),n):Ym(Lp("other","websocket-close",{retryAfterMs:e}),n)}return e===void 0?n:{...n,retryAfterMs:e}}function FN(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}var ari="crtr:provider-failure";function ga(t){return typeof t=="string"&&t.trim()!==""?t.trim():void 0}function rpe(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function ipe(t){return typeof t=="string"||typeof t=="number"?t:void 0}function UN(t){return FN(t)?t:void 0}function cri(t){let e=ga(t.errorMessage)??ga(t.message)??ga(t.reason)??ga(t.statusText),n={...e===void 0?{}:{message:e},...rpe(t.status)===void 0?{}:{status:rpe(t.status)},...ipe(t.code)===void 0?{}:{code:ipe(t.code)},...ga(t.errno)===void 0?{}:{errno:ga(t.errno)},...ga(t.body)===void 0?{}:{body:ga(t.body)}};return Object.keys(n).length===0?void 0:n}var uri=48,lri=256;function nmn(t){let e=UN(t),n=UN(e?.headers);if(e===void 0||n===void 0)return;let r={};for(let[i,o]of Object.entries(n)){if(Object.keys(r).length>=uri)break;typeof o=="string"&&(r[i.toLowerCase()]=o.slice(0,lri))}return{...ga(e.scope)===void 0?{}:{scope:ga(e.scope)},...ga(e.claim)===void 0?{}:{claim:ga(e.claim)},...ga(e.account)===void 0?{}:{account:ga(e.account)},...ga(e.model)===void 0?{}:{model:ga(e.model)},headers:r}}function dri(t){let e=UN(t)?.diagnostics;if(Array.isArray(e))for(let n of e){let r=UN(n);if(r?.type!==ari)continue;let i=UN(r.details);if(i===void 0)continue;let o=Array.isArray(i.causes)?i.causes.flatMap(s=>{let a=UN(s),c=a===void 0?void 0:cri(a);return c===void 0?[]:[c]}):void 0;return{...rpe(i.status)===void 0?{}:{status:rpe(i.status)},...ipe(i.code)===void 0?{}:{code:ipe(i.code)},...ga(i.errno)===void 0?{}:{errno:ga(i.errno)},...ga(i.body)===void 0?{}:{body:ga(i.body)},...o===void 0||o.length===0?{}:{causes:o},...nmn(i.ratelimit)===void 0?{}:{ratelimit:nmn(i.ratelimit)}}}}function rmn(t){return dri(t)}function pri(t){switch(t.kind){case"rate-limit":return"rate-limit";case"auth":return"auth";case"protocol":return"protocol";case"context-overflow":return"context-overflow";case"overloaded":case"overloaded-only":case"transient-http":return"overloaded";case"connection":case"connection-only":return"connection";case"socket":case"service-unavailable":case"other":return"other"}}function imn(t,e){return e==="auth"||e==="protocol"||e==="context-overflow"?"fatal":t==="pi\u2192provider"?e==="connection"||e==="rate-limit"||e==="overloaded"?"auto":"fatal":"manual"}function hri(t){if(typeof t=="string")return t;if(!FN(t))return"";let e=[t.message,t.errorMessage,t.reason,t.body,t.statusText];for(let r of e)if(typeof r=="string"&&r!=="")return r;let n=t.error;if(FN(n)){let r=n.message;if(typeof r=="string"&&r!=="")return r;let i=n.reason;if(typeof i=="string"&&i!=="")return i}return""}var fri="upstream_model_unavailable";function ope(t,e){if(t==="pi\u2192provider"&&Zfn(e))return{kind:"rate-limit",disposition:"auto"};let n=FN(e)?e:{},r=rmn(e),i=r?.causes??[];if(r?.code===fri)return{kind:"connection",disposition:imn(t,"connection")};let o=tmn({code:n.code??r?.code??i.find(a=>a.code!==void 0)?.code,errno:n.errno??r?.errno??i.find(a=>a.errno!==void 0)?.errno,status:n.status??r?.status,wsCloseCode:n.code,wsCloseReason:n.reason,message:[hri(e),r?.body,...i.flatMap(a=>[a.message,a.body])].filter(a=>typeof a=="string"&&a!=="").join(" ")}),s=pri(o);return{kind:s,disposition:imn(t,s)}}h$();aR();var ly=class extends Error{constructor(n){super(`node ${n} has no running broker \u2014 focus or revive it first`);this.nodeId=n;this.name="BrokerUnavailableError"}nodeId};var QN=class extends mri{constructor(n,r={}){super();this.nodeId=n;this.options=r}nodeId;options;socket;decoder=new V$(jz);closeEmitted=!1;redialFaultRecorded=!1;get socketPath(){return YT(this.nodeId)}recordSocketFault(n,r){if(this.options.recordsViewerFaults===!1)return;if(n==="redial"){if(this.redialFaultRecorded)return;this.redialFaultRecorded=!0}let i=ope("viewer\u2194broker",r);aXe(this.nodeId,{link:"viewer\u2194broker",op:n,kind:i.kind,retry:n==="redial"?{disposition:"auto",by:"client"}:{disposition:"manual"},message:r instanceof Error?r.message:String(r)}).catch(o=>{$d({event:"broker.daemon.operation.failed",level:"error",node_id:this.nodeId,error:o,fields:{operation:"viewer_fault_record"}})})}connect(){let n=_ge(this.nodeId);this.socket=n,n.on("connect",()=>{this.redialFaultRecorded=!1,this.clearSocketFault(),this.emit("connect")}),n.on("data",r=>this.onData(r)),n.on("error",r=>this.onError(r,"connect")),n.on("close",()=>this.onClose())}redial(n={}){return this.destroy(),this.decoder=new V$(jz),this.closeEmitted=!1,n.brokerUnavailableIsExpected&&(this.redialFaultRecorded=!1,this.clearSocketFault()),new Promise((r,i)=>{let o=_ge(this.nodeId);this.socket=o;let s=!1;o.on("connect",()=>{s||(s=!0,this.redialFaultRecorded=!1,this.clearSocketFault(),this.emit("connect"),r())}),o.on("data",a=>this.onData(a)),o.on("error",a=>{if(s){this.onError(a,"redial");return}s=!0;let c=a.code==="ECONNREFUSED"||a.code==="ENOENT";(!n.brokerUnavailableIsExpected||!c)&&this.recordSocketFault("redial",a);try{o.destroy()}catch{}i(a)}),o.on("close",()=>this.onClose())})}send(n){let r=this.socket;if(!(r===void 0||r.destroyed))try{r.write(Gz(n))}catch{}}destroy(){let n=this.socket;if(n!==void 0&&!n.destroyed)try{n.destroy()}catch{}}clearSocketFault(){this.options.recordsViewerFaults!==!1&&cXe(this.nodeId,{link:"viewer\u2194broker"}).catch(n=>{$d({event:"broker.daemon.operation.failed",level:"error",node_id:this.nodeId,error:n,fields:{operation:"viewer_fault_clear"}})})}onData(n){let r;try{r=this.decoder.push(n)}catch(i){let o=i instanceof IR?`broker sent an oversized frame (${i.message}) \u2014 disconnecting`:`failed to decode a broker frame: ${String(i)}`;this.emitError(new Error(o)),this.destroy();return}for(let i of r)this.emit("frame",i)}onError(n,r){this.recordSocketFault(r,n),n.code==="ECONNREFUSED"||n.code==="ENOENT"?this.emitError(new ly(this.nodeId)):this.emitError(new Error(`view socket error: ${n.message}`))}onClose(){this.closeEmitted||(this.closeEmitted=!0,this.emit("close"))}emitError(n){this.listenerCount("error")>0&&this.emit("error",n)}};qz();import{EventEmitter as gri}from"node:events";function Ari(t,e){if("socketPath"in t)return`ws+unix://${t.socketPath}:/v1/nodes/${encodeURIComponent(e)}/attach?revive=0`;let n=new URL(t.previewEndpoint);return n.protocol=n.protocol==="http:"?"ws:":"wss:",n.pathname=`/v1/nodes/${encodeURIComponent(e)}/attach`,n.search="?wakeParked=1",n.hash="",n.toString()}var RT=class extends gri{constructor(n,r){super();this.nodeId=n;this.target=r}nodeId;target;ws;closeEmitted=!1;get url(){return Ari(this.target,this.nodeId)}dial(){let n=new Vx.default(this.url,{..."relayToken"in this.target?{headers:{authorization:`Bearer ${this.target.relayToken}`}}:{},perMessageDeflate:!1});return this.ws=n,n}connect(){let n=this.dial();n.on("open",()=>{this.emit("connect")}),n.on("message",r=>this.onMessage(r)),n.on("error",r=>this.onError(r)),n.on("close",(r,i)=>this.onClose(r,i.toString()))}redial(n){return this.destroy(),this.closeEmitted=!1,new Promise((r,i)=>{let o=this.dial(),s=!1;o.on("open",()=>{s||(s=!0,this.emit("connect"),r())}),o.on("message",a=>this.onMessage(a)),o.on("error",a=>{if(s){this.onError(a);return}s=!0;try{o.terminate()}catch{}i(a)}),o.on("close",(a,c)=>{s&&this.onClose(a,c.toString())})})}send(n){let r=this.ws;if(!(r===void 0||r.readyState!==Vx.default.OPEN))try{r.send(JSON.stringify(n))}catch{}}destroy(){let n=this.ws;if(n!==void 0&&n.readyState<=Vx.default.OPEN)try{n.close(1e3)}catch{}}onMessage(n){let r;try{r=JSON.parse(n.toString())}catch{return}this.emit("frame",r)}onError(n){this.emitError(new Error(`relay transport error: ${n.message}`))}onClose(n,r){if(this.closeEmitted)return;this.closeEmitted=!0;let i=ope("viewer\u2194broker",{code:n,reason:r});(n===1008||i.kind==="protocol"||n===1011&&(/^no running broker/.test(r)||/^no node /.test(r)))&&this.emitError(new ly(this.nodeId)),this.emit("close")}emitError(n){this.listenerCount("error")>0&&this.emit("error",n)}};var omn=1e4;function iVe(t){return t===null?!0:t.lifecycle==="resident"&&t.status==="done"&&t.intent==="parked"&&t.final_report==null?!1:t.status==="done"||t.status==="dead"||t.status==="canceled"}var Dj=class extends yri{constructor(n,r={}){super();this.nodeId=n;this.transport=r.transport??new QN(n),this.transport.on("connect",()=>{this.closeEmitted=!1,this.connected=!0,this.lastTransportError=void 0,this.emit("connect")}),this.transport.on("frame",i=>this.onFrame(i)),this.transport.on("error",i=>{this.lastTransportError=i.message,this.emitError(i)}),this.transport.on("close",()=>this.onClose())}nodeId;transport;closeEmitted=!1;connected=!1;lastTransportError;pending=new Map;request(n){let r=xri();return new Promise((i,o)=>{if(!this.connected){o(new Error(`cannot issue '${n.type}': no live broker connection`));return}let s=setTimeout(()=>{this.pending.delete(r),o(new Error(`request '${n.type}' timed out after ${omn}ms`))},omn);typeof s.unref=="function"&&s.unref(),this.pending.set(r,{resolve:i,reject:o,timer:s}),this.send({...n,id:r})})}rejectAllPending(n){for(let{reject:r,timer:i}of this.pending.values())clearTimeout(i),r(new Error(n));this.pending.clear()}connect(){this.transport.connect()}redial(n){return this.transport.redial(n)}send(n){this.transport.send(n)}close(){this.transport.destroy()}onFrame(n){if(n.type==="data"){let r=typeof n.id=="string"?this.pending.get(n.id):void 0;r&&(this.pending.delete(n.id),clearTimeout(r.timer),r.resolve(n));return}if(n.type==="error"&&typeof n.id=="string"&&this.pending.has(n.id)){let r=this.pending.get(n.id);this.pending.delete(n.id),clearTimeout(r.timer),r.reject(new Error(n.message||`request failed: ${n.code}`));return}this.emit("frame",n)}onClose(){this.closeEmitted||(this.closeEmitted=!0,this.connected=!1,this.rejectAllPending(this.lastTransportError??"broker connection closed"),this.emit("close"))}emitError(n){this.listenerCount("error")>0&&this.emit("error",n)}};var wri=1e3,bri=3e3;function smn(t,e){let{nodeId:n,socket:r,canvasSource:i}=t,o,s=!1,a=e.initialDormant===!0,c=!1,u=!1,l=()=>{},d,p,h=new Promise(w=>{l=w}),f=w=>u?Promise.resolve(!1):new Promise(v=>{let S=_=>{d=void 0,p=void 0,v(_)};d=setTimeout(()=>S(!0),w),p=()=>{d!==void 0&&clearTimeout(d),S(!1)}}),m=()=>{r.send({type:"hello",role:e.role,client_id:e.clientId,term:{cols:process.stdout.columns??80,rows:process.stdout.rows??24}})},g=async()=>{s=!0,e.setNotice("\u21BB node refreshing \u2014 reconnecting\u2026",{sticky:!0});let w=200;try{for(;!u&&!e.isTornDown();){let v;try{v=await i.getRow(n)}catch{v=void 0}if(v!==void 0&&iVe(v)){c=v?.status==="done";break}let S=v?.status==="idle"||v?.intent==="idle-release"||v?.lifecycle==="resident"&&v.status==="done"&&v.intent==="parked"&&v.final_report==null,_=S&&!a;a=S,_&&e.onEnterDormancy(),e.setNotice(S?"":"\u21BB node refreshing \u2014 reconnecting\u2026",{sticky:!S});try{if(!await Promise.race([r.redial({brokerUnavailableIsExpected:S}).then(()=>!0),h.then(()=>!1)])||u||e.isTornDown())return;m(),a=!1,e.setNotice("");return}catch{if(!await f(S?bri:Math.min(w,wri)))return;w*=2}}}finally{s=!1}!u&&!e.isTornDown()&&e.teardown(c?"node-done":"broker-gone")};return{sendHello:m,startDormant:()=>{s||u||e.isTornDown()||(e.onEnterDormancy(),g())},isDormant:()=>a,lastSocketError:()=>o,install:async()=>{r.on("frame",e.onFrame),r.on("error",w=>{o=w.message}),r.on("close",()=>{e.isTornDown()||s||g()})},stop:()=>{u||(u=!0,p?.(),l())}}}function spe(t){if(typeof t!="object"||t===null||Array.isArray(t))return!1;try{let e=Object.getPrototypeOf(t);if(e!==Object.prototype&&e!==null||Object.getOwnPropertySymbols(t).length!==0)return!1;let n=Object.getOwnPropertyNames(t).sort();if(n.length!==3||n[0]!=="body"||n[1]!=="commandName"||n[2]!=="kind")return!1;let r=Object.getOwnPropertyDescriptors(t);if(Object.values(r).some(o=>!("value"in o)))return!1;let i=t;return i.kind!=="memory-slash"||typeof i.commandName!="string"||typeof i.body!="string"?!1:(JSON.stringify(t),!0)}catch{return!1}}function vri(t){let e="",n=0,r=!0,i,o;for(;n<t.length;){if(r&&o===void 0){let a=t.slice(n).match(/^(?: {0,3})(`{3,}|~{3,})/);if(a!==null){let c=a[1][0],u=a[1].length;i===void 0?i={marker:c,length:u}:i.marker===c&&u>=i.length&&(i=void 0)}}if(i===void 0&&o===void 0&&t.startsWith("<!--",n)){let a=t.indexOf("-->",n+4),c=a===-1?t.length:a+3,u=t.indexOf(`
1726
1726
  `,c),l=t.lastIndexOf(`
1727
1727
  `,n-1)+1,d=t.slice(l,n),p=t.slice(c,u===-1?t.length:u);if(d.trim()===""&&p.trim()===""){d.length>0&&(e=e.slice(0,-d.length)),n=u===-1?t.length:u+1,r=!0;continue}let h=t.slice(n,c);r=h.endsWith(`
1728
1728
  `),n+=h.length;continue}if(i===void 0&&t[n]==="`"){let a=n;for(;t[a]==="`";)a++;let c=a-n;o===void 0?o=c:o===c&&(o=void 0),e+=t.slice(n,a),r=!1,n=a;continue}let s=t[n];e+=s,r=s===`
@@ -15,6 +15,8 @@ export declare function createNode(meta: NodeMeta, opts?: {
15
15
  }): Promise<NodeMeta>;
16
16
  /** The canonical node record, hydrated from SQL. Null if unknown. */
17
17
  export declare function getNode(nodeId: string): Promise<NodeMeta | null>;
18
+ /** The canonical node records for `nodeIds` in the order given, read with their worktrees in one query. Unknown ids are skipped. */
19
+ export declare function getNodes(nodeIds: readonly string[]): Promise<NodeMeta[]>;
18
20
  export type CreateRequestState = 'reserved' | 'warm_claimed' | 'complete';
19
21
  export interface CreateRequestRecord {
20
22
  requestKey: string;
@@ -1,8 +1,8 @@
1
- var ie=Object.defineProperty;var i=(e,n)=>ie(e,"name",{value:n,configurable:!0});import{envNodeId as W}from"../../shared/env.js";import{lstatSync as oe,realpathSync as b,rmdirSync as re,rmSync as se,statSync as de}from"node:fs";import{basename as ue,dirname as F,isAbsolute as le,join as S,relative as ce,resolve as _e,sep as pe}from"node:path";import{removeTreeBeneath as C}from"../spaces/open-beneath.js";import{emitEvent as fe}from"../events/emit.js";import{withCanvasWrite as p,openDb as s}from"./db.js";import{conversationStore as Ee,ConversationNotFoundError as we}from"../conversation-store/index.js";import{hasUnseenWakeMail as ye,UNSEEN_WAKE_MAIL_SQL as me}from"./deliveries.js";import{isAppRun as H}from"./app-run.js";import{registerOutcomeAction as M}from"./outcome-actions.js";import{publish as Ne}from"../graph/events.js";import{nodeObject as Re}from"../graph/objects.js";import{findNodeBySessionFileSql as Se}from"./sessions.js";import{hydrateFault as Oe}from"./recovery.js";import{hasUnreconciledWorktree as he,openWorktree as Te,readWorktree as Le,worktreeFromRow as De}from"./worktrees.js";import{isPidAlive as ve,isPidPresent as P,recordedPidLiveness as Ae}from"./pid.js";import{ensureHome as ge,jobDir as ke,nodeDir as Ue,nodeRunDir as $}from"./paths.js";import{appForNode as xe,ensureNodeDirs as Ie,nodeAgentDir as je}from"./node-agent-paths.js";import{appSpace as T}from"../layout.js";import{createObject as We,getById as L,ownerForGrantee as be,setObjectKind as Fe,setObjectName as Ce}from"../graph/objects.js";import{profileObject as He}from"../graph/reader.js";import{writeActsFor as q}from"../permissions/facts.js";import{CrtrError as Me}from"../errors.js";import{deleteNodeWithOwned as Pe}from"../graph/deletion.js";import{SUBTREE_ALL_IDS_SQL as $e,SUBTREE_IDS_SQL as qe}from"./tree.js";import{filterAsync as m,mapAsync as D}from"../async-array.js";function E(e,n){if(e==null)return null;const t=JSON.stringify(e);if(t===void 0)throw new TypeError(`${n} must be JSON-serializable`);return t}i(E,"jsonValue");async function vn(e,n){if((await e.prepare("SELECT deleting_at FROM nodes WHERE node_id = ?").get(n))?.deleting_at)throw new Error("run is deleting")}i(vn,"assertRunNotDeleting");async function B(e,n,t){try{return await He(e,n,t)}catch(a){if(a instanceof Me&&a.code==="not_found")return null;throw a}}i(B,"profileObjectFor");async function Be(e,n){const t=await be(n,e.grantee??"app:terminal"),a=e.profile_id?await B(n,e.profile_id,t):null;await We(n,{id:e.node_id,type:"node",kind:e.kind,owner:(a??t).id,privacy:"public",name:e.name,preview:""}),a===null&&e.sub&&await q(n,e.node_id,e.sub),await n.prepare(`INSERT INTO nodes (node_id, description, title, icon, cycles, mode, lifecycle, cwd, host_kind, profile_id, parent, spawned_by, creator, fork_from, fork_source_file, created, passive_default, cycle_pending, model_override, persona_ack_json, review_binding_json, launch_config_json, scopes_json, isolated, status, intent, final_report, finalized_at, deadline_at, "window", tmux_session, pane, sub, grant_id, client_id, metadata_json, run_id, event_cursor, usage_json, deleting_at, caused_by, app) VALUES (${Array(42).fill("?").join(", ")})`).run(e.node_id,e.description??null,e.title??null,e.icon??null,e.cycles??null,e.mode,e.lifecycle,e.cwd,e.host_kind??null,e.profile_id??null,e.parent??null,e.spawned_by??null,e.creator??null,e.fork_from??null,e.fork_source_file??null,e.created,e.passive_default===!0?1:0,e.cycle_pending===!0?1:0,e.model_override??null,E(e.persona_ack,"persona_ack"),E(e.review_binding,"review_binding"),E(e.launch,"launch"),E(e.scopes,"scopes"),e.isolated===!0?1:0,e.status??"active",e.intent??null,e.final_report??null,e.finalized_at??null,e.deadline_at??null,e.window??null,e.tmux_session??null,e.pane??null,e.sub??null,e.grant_id??null,e.client_id??null,e.metadata_json??null,e.run_id??null,e.event_cursor??null,e.usage_json??null,e.deleting_at??null,e.caused_by??null,t.id)}i(Be,"seedRow");function z(e){if(e.fault_id==null)return null;const n=Object.entries(e).filter(([t])=>t.startsWith("fault_")).map(([t,a])=>[t==="fault_id"?t:t.slice(6),a]);return Oe(Object.fromEntries(n))}i(z,"faultFrom");function f(e){const n={node_id:e.node_id,name:e.name,description:e.description??void 0,cycles:e.cycles??void 0,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,profile_id:e.profile_id??null,scopes:e.scopes_json==null?null:JSON.parse(e.scopes_json),isolated:e.isolated===1,grantee:e.grantee,sub:e.sub??null,grant_id:e.grant_id??null,client_id:e.client_id??null,metadata_json:e.metadata_json??null,run_id:e.run_id??null,event_cursor:e.event_cursor??null,last_activity_at:e.last_activity_at??null,usage_json:e.usage_json??null,caused_by:e.caused_by??null,last_turn_error_json:e.last_turn_error_json??null,deleting_at:e.deleting_at??null,parent:e.parent??null,created:e.created,intent:e.intent??null,frozen_at:e.frozen_at??null,respawn_failures:e.respawn_failures??0,respawn_not_before:e.respawn_not_before??null,launched_at:e.launched_at??null,last_settled_at:e.last_settled_at??null,terminal_reason:e.terminal_reason??null,final_report:e.final_report??null,finalized_at:e.finalized_at??null,outcome_kind:e.outcome_kind??null,outcome_reason:e.outcome_reason??null,outcome_at:e.outcome_at??null,outcome_revision:e.outcome_revision??0,outcome_detail_json:e.outcome_detail_json??null,deadline_at:e.deadline_at??null,telemetry_tokens_in:e.telemetry_tokens_in??null,telemetry_context_tokens:e.telemetry_context_tokens??null,telemetry_last_activity:e.telemetry_last_activity??null,telemetry_updated_at:e.telemetry_updated_at??null,pi_pid:e.pi_pid??null,pi_pid_identity:e.pi_pid_identity??null,window:e.window??null,tmux_session:e.tmux_session??null,pane:e.pane??null,fault:null,streaming:!1},t=P(n.pi_pid),a=z(e);return n.fault=a?.link==="pi\u2192provider"&&a.retry.by==="daemon"&&a.retry.disposition==="auto"&&!t?null:a,n.streaming=e.turn_open_at!==null&&e.turn_closed_at===null&&t,n}i(f,"rowFrom");async function J(e,n){return n??=await Le(e.node_id),{...f(e),title:e.title??void 0,icon:e.icon??void 0,spawned_by:e.spawned_by??null,creator:e.creator??null,fork_from:e.fork_from??null,fork_source_file:e.fork_source_file??null,passive_default:e.passive_default===1,cycle_pending:e.cycle_pending===1,model_override:e.model_override??null,scopes:e.scopes_json==null?null:JSON.parse(e.scopes_json),persona_ack:e.persona_ack_json==null?void 0:JSON.parse(e.persona_ack_json),review_binding:e.review_binding_json==null?void 0:JSON.parse(e.review_binding_json),launch:e.launch_config_json==null?void 0:JSON.parse(e.launch_config_json),pi_session_id:e.pi_session_id??null,pi_session_file:e.pi_session_file??null,...n===null?{}:{managed_worktree:n}}}i(J,"metaFrom");async function An(e,n={}){return ge(),await p(async t=>{await Be(e,t),e.managed_worktree!==void 0&&e.managed_worktree!==null&&await Te(e.node_id,e.managed_worktree,t),n.outcomeDelivery!==void 0&&await M(t,e.node_id,n.outcomeDelivery),await n.withinCreate?.(t,e)}),await Ie(e.node_id),await O(e.node_id)}i(An,"createNode");async function O(e){const n=await(await s()).prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n===void 0?null:await J(n)}i(O,"getNode");const ze=1440*60*1e3;function Y(e){return{requestKey:e.request_key,nodeId:e.node_id,state:e.state}}i(Y,"createRequestRecord");async function gn(e){const n=await(await s()).prepareUncached("SELECT request_key, node_id, state FROM create_requests WHERE request_key = ?").get(e);return n===void 0?null:Y(n)}i(gn,"findCreateRequest");async function kn(e){return await p(async n=>{const t=Date.now();await n.prepareUncached("DELETE FROM create_requests WHERE expires_at <= ?").run(t),await n.prepareUncached("INSERT INTO create_requests (request_key, node_id, expires_at, state) VALUES (?, NULL, ?, 'reserved') ON CONFLICT (request_key) DO NOTHING").run(e,t+ze);const a=await n.prepareUncached("SELECT request_key, node_id, state FROM create_requests WHERE request_key = ?").get(e);return Y(a)})}i(kn,"reserveCreateRequest");async function Un(e=Date.now()){return Number((await(await s()).prepareUncached("DELETE FROM create_requests WHERE expires_at <= ?").run(e)).changes)}i(Un,"pruneExpiredCreateRequests");async function xn(e,n){await(await s()).prepareUncached("UPDATE create_requests SET node_id = ?, state = 'complete' WHERE request_key = ?").run(n,e)}i(xn,"recordCreateRequestNode");async function In(e,n){const t=await s();return await t.prepareUncached("UPDATE create_requests SET node_id = ?, state = 'reserved' WHERE request_key = ? AND node_id IS NULL").run(n,e),(await t.prepareUncached("SELECT node_id FROM create_requests WHERE request_key = ?").get(e))?.node_id??null}i(In,"reserveCreateRequestNode");async function jn(e,n){await(await s()).prepareUncached("UPDATE create_requests SET state = 'complete' WHERE request_key = ? AND node_id = ?").run(e,n)}i(jn,"completeCreateRequest");async function Wn(e,n){await p(async t=>{if(n===null){await t.prepareUncached("DELETE FROM create_requests WHERE request_key = ? AND node_id IS NULL").run(e);return}await t.prepareUncached("DELETE FROM create_requests WHERE request_key = ? AND node_id = ?").run(e,n)})}i(Wn,"abandonCreateRequest");function bn(e){return _e(e)}i(bn,"canonicalSessionFile");async function Fn(e){const n=await Se(e);return n===null?null:await O(n)}i(Fn,"findNodeBySessionFile");async function Cn(e){const n=await(await s()).prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n?f(n):null}i(Cn,"getRow");async function Hn(e){const n=await(await s()).prepare("SELECT * FROM node_rows WHERE pane = ?").get(e);return n?f(n):null}i(Hn,"getRowByPane");async function Mn(e){return(await(await s()).prepare(`SELECT * FROM node_rows
1
+ var oe=Object.defineProperty;var o=(e,n)=>oe(e,"name",{value:n,configurable:!0});import{envNodeId as b}from"../../shared/env.js";import{lstatSync as re,realpathSync as C,rmdirSync as se,rmSync as de,statSync as ue}from"node:fs";import{basename as le,dirname as H,isAbsolute as ce,join as S,relative as _e,resolve as pe,sep as fe}from"node:path";import{removeTreeBeneath as M}from"../spaces/open-beneath.js";import{emitEvent as Ee}from"../events/emit.js";import{withCanvasWrite as p,openDb as s}from"./db.js";import{conversationStore as we,ConversationNotFoundError as ye}from"../conversation-store/index.js";import{hasUnseenWakeMail as me,UNSEEN_WAKE_MAIL_SQL as Ne}from"./deliveries.js";import{isAppRun as P}from"./app-run.js";import{registerOutcomeAction as $}from"./outcome-actions.js";import{publish as Re}from"../graph/events.js";import{nodeObject as Se}from"../graph/objects.js";import{findNodeBySessionFileSql as Oe}from"./sessions.js";import{hydrateFault as he}from"./recovery.js";import{hasUnreconciledWorktree as Te,openWorktree as Le,readWorktree as De,worktreeFromRow as ge}from"./worktrees.js";import{isPidAlive as Ae,isPidPresent as q,recordedPidLiveness as ve}from"./pid.js";import{ensureHome as ke,jobDir as Ue,nodeDir as xe,nodeRunDir as B}from"./paths.js";import{appForNode as je,ensureNodeDirs as Ie,nodeAgentDir as We}from"./node-agent-paths.js";import{appSpace as L}from"../layout.js";import{createObject as Fe,getById as D,ownerForGrantee as be,setObjectKind as Ce,setObjectName as He}from"../graph/objects.js";import{profileObject as Me}from"../graph/reader.js";import{writeActsFor as z}from"../permissions/facts.js";import{CrtrError as Pe}from"../errors.js";import{deleteNodeWithOwned as $e}from"../graph/deletion.js";import{SUBTREE_ALL_IDS_SQL as qe,SUBTREE_IDS_SQL as Be}from"./tree.js";import{filterAsync as m,mapAsync as O}from"../async-array.js";function E(e,n){if(e==null)return null;const t=JSON.stringify(e);if(t===void 0)throw new TypeError(`${n} must be JSON-serializable`);return t}o(E,"jsonValue");async function gn(e,n){if((await e.prepare("SELECT deleting_at FROM nodes WHERE node_id = ?").get(n))?.deleting_at)throw new Error("run is deleting")}o(gn,"assertRunNotDeleting");async function J(e,n,t){try{return await Me(e,n,t)}catch(a){if(a instanceof Pe&&a.code==="not_found")return null;throw a}}o(J,"profileObjectFor");async function ze(e,n){const t=await be(n,e.grantee??"app:terminal"),a=e.profile_id?await J(n,e.profile_id,t):null;await Fe(n,{id:e.node_id,type:"node",kind:e.kind,owner:(a??t).id,privacy:"public",name:e.name,preview:""}),a===null&&e.sub&&await z(n,e.node_id,e.sub),await n.prepare(`INSERT INTO nodes (node_id, description, title, icon, cycles, mode, lifecycle, cwd, host_kind, profile_id, parent, spawned_by, creator, fork_from, fork_source_file, created, passive_default, cycle_pending, model_override, persona_ack_json, review_binding_json, launch_config_json, scopes_json, isolated, status, intent, final_report, finalized_at, deadline_at, "window", tmux_session, pane, sub, grant_id, client_id, metadata_json, run_id, event_cursor, usage_json, deleting_at, caused_by, app) VALUES (${Array(42).fill("?").join(", ")})`).run(e.node_id,e.description??null,e.title??null,e.icon??null,e.cycles??null,e.mode,e.lifecycle,e.cwd,e.host_kind??null,e.profile_id??null,e.parent??null,e.spawned_by??null,e.creator??null,e.fork_from??null,e.fork_source_file??null,e.created,e.passive_default===!0?1:0,e.cycle_pending===!0?1:0,e.model_override??null,E(e.persona_ack,"persona_ack"),E(e.review_binding,"review_binding"),E(e.launch,"launch"),E(e.scopes,"scopes"),e.isolated===!0?1:0,e.status??"active",e.intent??null,e.final_report??null,e.finalized_at??null,e.deadline_at??null,e.window??null,e.tmux_session??null,e.pane??null,e.sub??null,e.grant_id??null,e.client_id??null,e.metadata_json??null,e.run_id??null,e.event_cursor??null,e.usage_json??null,e.deleting_at??null,e.caused_by??null,t.id)}o(ze,"seedRow");function Y(e){if(e.fault_id==null)return null;const n=Object.entries(e).filter(([t])=>t.startsWith("fault_")).map(([t,a])=>[t==="fault_id"?t:t.slice(6),a]);return he(Object.fromEntries(n))}o(Y,"faultFrom");function f(e){const n={node_id:e.node_id,name:e.name,description:e.description??void 0,cycles:e.cycles??void 0,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,profile_id:e.profile_id??null,scopes:e.scopes_json==null?null:JSON.parse(e.scopes_json),isolated:e.isolated===1,grantee:e.grantee,sub:e.sub??null,grant_id:e.grant_id??null,client_id:e.client_id??null,metadata_json:e.metadata_json??null,run_id:e.run_id??null,event_cursor:e.event_cursor??null,last_activity_at:e.last_activity_at??null,usage_json:e.usage_json??null,caused_by:e.caused_by??null,last_turn_error_json:e.last_turn_error_json??null,deleting_at:e.deleting_at??null,parent:e.parent??null,created:e.created,intent:e.intent??null,frozen_at:e.frozen_at??null,respawn_failures:e.respawn_failures??0,respawn_not_before:e.respawn_not_before??null,launched_at:e.launched_at??null,last_settled_at:e.last_settled_at??null,terminal_reason:e.terminal_reason??null,final_report:e.final_report??null,finalized_at:e.finalized_at??null,outcome_kind:e.outcome_kind??null,outcome_reason:e.outcome_reason??null,outcome_at:e.outcome_at??null,outcome_revision:e.outcome_revision??0,outcome_detail_json:e.outcome_detail_json??null,deadline_at:e.deadline_at??null,telemetry_tokens_in:e.telemetry_tokens_in??null,telemetry_context_tokens:e.telemetry_context_tokens??null,telemetry_last_activity:e.telemetry_last_activity??null,telemetry_updated_at:e.telemetry_updated_at??null,pi_pid:e.pi_pid??null,pi_pid_identity:e.pi_pid_identity??null,window:e.window??null,tmux_session:e.tmux_session??null,pane:e.pane??null,fault:null,streaming:!1},t=q(n.pi_pid),a=Y(e);return n.fault=a?.link==="pi\u2192provider"&&a.retry.by==="daemon"&&a.retry.disposition==="auto"&&!t?null:a,n.streaming=e.turn_open_at!==null&&e.turn_closed_at===null&&t,n}o(f,"rowFrom");async function g(e,n){return n??=await De(e.node_id),{...f(e),title:e.title??void 0,icon:e.icon??void 0,spawned_by:e.spawned_by??null,creator:e.creator??null,fork_from:e.fork_from??null,fork_source_file:e.fork_source_file??null,passive_default:e.passive_default===1,cycle_pending:e.cycle_pending===1,model_override:e.model_override??null,scopes:e.scopes_json==null?null:JSON.parse(e.scopes_json),persona_ack:e.persona_ack_json==null?void 0:JSON.parse(e.persona_ack_json),review_binding:e.review_binding_json==null?void 0:JSON.parse(e.review_binding_json),launch:e.launch_config_json==null?void 0:JSON.parse(e.launch_config_json),pi_session_id:e.pi_session_id??null,pi_session_file:e.pi_session_file??null,...n===null?{}:{managed_worktree:n}}}o(g,"metaFrom");async function An(e,n={}){return ke(),await p(async t=>{await ze(e,t),e.managed_worktree!==void 0&&e.managed_worktree!==null&&await Le(e.node_id,e.managed_worktree,t),n.outcomeDelivery!==void 0&&await $(t,e.node_id,n.outcomeDelivery),await n.withinCreate?.(t,e)}),await Ie(e.node_id),await h(e.node_id)}o(An,"createNode");async function h(e){const n=await(await s()).prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n===void 0?null:await g(n)}o(h,"getNode");async function vn(e){if(e.length===0)return[];const n=v.map(i=>`w.${i} AS worktree_${i}`).join(", "),t=await(await s()).prepareUncached(`SELECT n.*, ${n} FROM node_rows n LEFT JOIN worktrees w ON w.node_id = n.node_id WHERE n.node_id IN (${e.map(()=>"?").join(",")})`).all(...e),a=new Map(t.map(i=>[i.node_id,i]));return await O(e.map(i=>a.get(i)).filter(i=>i!==void 0),async i=>await g(i,V(i)))}o(vn,"getNodes");const Je=1440*60*1e3;function Q(e){return{requestKey:e.request_key,nodeId:e.node_id,state:e.state}}o(Q,"createRequestRecord");async function kn(e){const n=await(await s()).prepareUncached("SELECT request_key, node_id, state FROM create_requests WHERE request_key = ?").get(e);return n===void 0?null:Q(n)}o(kn,"findCreateRequest");async function Un(e){return await p(async n=>{const t=Date.now();await n.prepareUncached("DELETE FROM create_requests WHERE expires_at <= ?").run(t),await n.prepareUncached("INSERT INTO create_requests (request_key, node_id, expires_at, state) VALUES (?, NULL, ?, 'reserved') ON CONFLICT (request_key) DO NOTHING").run(e,t+Je);const a=await n.prepareUncached("SELECT request_key, node_id, state FROM create_requests WHERE request_key = ?").get(e);return Q(a)})}o(Un,"reserveCreateRequest");async function xn(e=Date.now()){return Number((await(await s()).prepareUncached("DELETE FROM create_requests WHERE expires_at <= ?").run(e)).changes)}o(xn,"pruneExpiredCreateRequests");async function jn(e,n){await(await s()).prepareUncached("UPDATE create_requests SET node_id = ?, state = 'complete' WHERE request_key = ?").run(n,e)}o(jn,"recordCreateRequestNode");async function In(e,n){const t=await s();return await t.prepareUncached("UPDATE create_requests SET node_id = ?, state = 'reserved' WHERE request_key = ? AND node_id IS NULL").run(n,e),(await t.prepareUncached("SELECT node_id FROM create_requests WHERE request_key = ?").get(e))?.node_id??null}o(In,"reserveCreateRequestNode");async function Wn(e,n){await(await s()).prepareUncached("UPDATE create_requests SET state = 'complete' WHERE request_key = ? AND node_id = ?").run(e,n)}o(Wn,"completeCreateRequest");async function Fn(e,n){await p(async t=>{if(n===null){await t.prepareUncached("DELETE FROM create_requests WHERE request_key = ? AND node_id IS NULL").run(e);return}await t.prepareUncached("DELETE FROM create_requests WHERE request_key = ? AND node_id = ?").run(e,n)})}o(Fn,"abandonCreateRequest");function bn(e){return pe(e)}o(bn,"canonicalSessionFile");async function Cn(e){const n=await Oe(e);return n===null?null:await h(n)}o(Cn,"findNodeBySessionFile");async function Hn(e){const n=await(await s()).prepare("SELECT * FROM node_rows WHERE node_id = ?").get(e);return n?f(n):null}o(Hn,"getRow");async function Mn(e){const n=await(await s()).prepare("SELECT * FROM node_rows WHERE pane = ?").get(e);return n?f(n):null}o(Mn,"getRowByPane");async function Pn(e){return(await(await s()).prepare(`SELECT * FROM node_rows
2
2
  WHERE deadline_at IS NOT NULL AND outcome_at IS NULL
3
3
  AND deadline_at <= ? AND status IN ('active','idle') AND kind != 'human'
4
- ORDER BY deadline_at, created, node_id`).all(e)).map(f)}i(Mn,"dueNodeDeadlines");async function Pn(e,n){return Number((await(await s()).prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ?").run(n,e)).changes)===1}i(Pn,"setNodeDeadline");async function $n(e,n){return!Number.isFinite(n)||n<=0?0:await p(async t=>{const a=await t.prepare(`SELECT node_id, deadline_at FROM nodes
5
- WHERE profile_id = ? AND deadline_at IS NOT NULL AND status IN ('active', 'idle')`).all(e),o=t.prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ? AND deadline_at = ?");let r=0;for(const d of a){const l=Date.parse(d.deadline_at);Number.isNaN(l)||(r+=Number((await o.run(new Date(l+n).toISOString(),d.node_id,d.deadline_at)).changes))}return r})}i($n,"shiftProfileNodeDeadlines");function v(e,n){if(e==null)return null;if(typeof e=="string"||typeof e=="number"||typeof e=="bigint"||e instanceof Uint8Array)return e;throw new TypeError(`${n} must be a SQLite scalar`)}i(v,"sqlInput");async function qn(e,n){const t=[],a=i((r,d=r)=>{Object.prototype.hasOwnProperty.call(n,r)&&t.push([d,v(n[r],r)])},"add");if(a("description"),a("title"),a("icon"),a("cycles"),a("mode"),a("lifecycle"),a("cwd"),a("host_kind"),a("profile_id"),a("parent"),a("spawned_by"),a("creator"),a("fork_from"),a("fork_source_file"),a("model_override"),Object.prototype.hasOwnProperty.call(n,"passive_default")&&t.push(["passive_default",n.passive_default===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"cycle_pending")&&t.push(["cycle_pending",n.cycle_pending===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"persona_ack")&&t.push(["persona_ack_json",E(n.persona_ack,"persona_ack")]),Object.prototype.hasOwnProperty.call(n,"review_binding")&&t.push(["review_binding_json",E(n.review_binding,"review_binding")]),Object.prototype.hasOwnProperty.call(n,"isolated"))throw new TypeError("isolated cannot change after node creation");Object.prototype.hasOwnProperty.call(n,"scopes")&&t.push(["scopes_json",E(n.scopes,"scopes")]),Object.prototype.hasOwnProperty.call(n,"launch")&&t.push(["launch_config_json",E(n.launch,"launch")]);const o=i(r=>Object.prototype.hasOwnProperty.call(n,r),"has");return await p(async r=>{const d=await L(r,e);if(d===null||d.type!=="node")throw new Error(`unknown node: ${e}`);if(o("name")&&await Ce(r,d,v(n.name,"name")),o("kind")&&await Fe(r,d,v(n.kind,"kind")),t.length===0)return;if(o("profile_id")){const u=await r.prepare("SELECT app FROM nodes WHERE node_id = ?").get(e),_=u?.app?await L(r,u.app):null;if(_){const w=n.profile_id?await B(r,n.profile_id,_):null;await r.prepare("UPDATE objects SET owner = ? WHERE id = ?").run((w??_).id,e);const R=(await r.prepare("SELECT sub FROM nodes WHERE node_id = ?").get(e)).sub;w===null&&R&&await q(r,e,R)}}if((await r.prepareUncached(`UPDATE nodes SET ${t.map(([u])=>`${u} = ?`).join(", ")} WHERE node_id = ?`).run(...t.map(([,u])=>u),e)).changes!==1)throw new Error(`unknown node: ${e}`)}),await O(e)}i(qn,"updateNode");async function Bn(e,n){await(await s()).prepare("UPDATE nodes SET status = ? WHERE node_id = ?").run(n,e)}i(Bn,"setStatus");async function zn(e,n){await(await s()).prepare("UPDATE nodes SET intent = ? WHERE node_id = ?").run(n??null,e)}i(zn,"setIntent");async function Jn(e,n,t={}){if(t.outcome===void 0){const o=[],r=[];Object.prototype.hasOwnProperty.call(n,"status")&&(o.push("status = ?"),r.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(o.push("intent = ?"),r.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(o.push("terminal_reason = ?"),r.push(n.terminal_reason??null));const d=["node_id = ?"];r.push(e),t.fromStatuses!==void 0&&(d.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),r.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&d.push("final_report IS NULL");const l=await(await s()).prepareUncached(`UPDATE nodes SET ${o.join(", ")} WHERE ${d.join(" AND ")}`).run(...r);return Number(l.changes)}const a=t.outcome;return await p(async o=>{const r=[],d=[];Object.prototype.hasOwnProperty.call(n,"status")&&(r.push("status = ?"),d.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(r.push("intent = ?"),d.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(r.push("terminal_reason = ?"),d.push(n.terminal_reason??null));const l=i((R,y)=>a.supersede===!0?"?":`CASE WHEN outcome_at IS NULL THEN ? ELSE ${y} END`,"outcomeValue");r.push(`outcome_kind = ${l(a.kind,"outcome_kind")}`,`outcome_reason = ${l(a.reason,"outcome_reason")}`,`outcome_detail_json = ${l(a.detailJson,"outcome_detail_json")}`,`outcome_revision = ${a.supersede===!0?"outcome_revision + 1":"CASE WHEN outcome_at IS NULL THEN outcome_revision + 1 ELSE outcome_revision END"}`,`outcome_at = ${l(a.at,"outcome_at")}`),d.push(a.kind,a.reason,a.detailJson,a.at);const u=["node_id = ?"];d.push(e),t.fromStatuses!==void 0&&(u.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),d.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&u.push("final_report IS NULL");const _=await o.prepareUncached(`UPDATE nodes SET ${r.join(", ")} WHERE ${u.join(" AND ")}`).run(...d);if(Number(_.changes)===0)return 0;const w=await o.prepare("SELECT outcome_at FROM nodes WHERE node_id = ?").get(e);return(a.supersede===!0||w.outcome_at===a.at)&&a.documentJson!==null&&a.documentJson!==void 0&&await Ne(o,{event:"outcome",object:await Re(o,e),actor:null,attrs:{revision:Number((await o.prepare("SELECT outcome_revision FROM nodes WHERE node_id = ?").get(e)).outcome_revision)},messageBody:JSON.parse(a.documentJson)}),Number(_.changes)})}i(Jn,"transitionStatusIntent");async function Yn(e){return(await(await s()).prepare("SELECT final_report FROM nodes WHERE node_id = ?").get(e))?.final_report??null}i(Yn,"getFinalReport");async function Qn(e,n){return(await(await s()).prepare("UPDATE nodes SET final_report = NULL, finalized_at = NULL WHERE node_id = ? AND final_report = ?").run(e,n)).changes>0}i(Qn,"clearFinalReportIfMatches");async function Vn(e,n){await(await s()).prepare('UPDATE nodes SET tmux_session = ?, "window" = ?, pane = ? WHERE node_id = ?').run(n.tmux_session??null,n.window??null,n.pane??null,e)}i(Vn,"setPresence");async function Kn(e,n){await(await s()).prepare("UPDATE nodes SET launched_at = ?, frozen_at = NULL, respawn_not_before = NULL WHERE node_id = ?").run(n,e)}i(Kn,"recordLaunch");async function Gn(e,n){await(await s()).prepare("UPDATE nodes SET last_settled_at = ? WHERE node_id = ?").run(n,e)}i(Gn,"recordSettledTurn");async function Xn(e,n){await(await s()).prepare("UPDATE nodes SET frozen_at = ? WHERE node_id = ?").run(n,e)}i(Xn,"setFrozen");async function Zn(e){await(await s()).prepare("UPDATE nodes SET frozen_at = NULL WHERE node_id = ?").run(e)}i(Zn,"clearFrozen");async function et(e,n){await(await s()).prepare("UPDATE nodes SET respawn_failures = ?, respawn_not_before = ? WHERE node_id = ?").run(n.failures,n.notBefore,e)}i(et,"recordRespawnAttempt");const N="node_id NOT IN (SELECT node_id FROM warm_pool)",Q=["state","cleanup_state","path","branch","repo_root","base_ref","base_sha","created_at","closed_at","next_attempt_at","attempts","quarantined","sweep_reason","sweep_detail","sweep_last_at","sweep_observed_json","abandoned_json","land_intent_json","disposal_json"];function Je(e){return e.worktree_state===null?null:De(Object.fromEntries(Q.map(n=>[n,e[`worktree_${n}`]])))}i(Je,"worktreeFromProjection");async function nt(e){const n=Q.map(a=>`w.${a} AS worktree_${a}`).join(", "),t=await(await s()).prepareUncached(`SELECT n.*, ${n} FROM node_rows n LEFT JOIN worktrees w ON w.node_id = n.node_id WHERE n.profile_id = ? ORDER BY n.created`).all(e);return await D(t,async a=>await J(a,Je(a)))}i(nt,"listNodesByProfile");async function tt(){return(await(await s()).prepare(`SELECT
4
+ ORDER BY deadline_at, created, node_id`).all(e)).map(f)}o(Pn,"dueNodeDeadlines");async function $n(e,n){return Number((await(await s()).prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ?").run(n,e)).changes)===1}o($n,"setNodeDeadline");async function qn(e,n){return!Number.isFinite(n)||n<=0?0:await p(async t=>{const a=await t.prepare(`SELECT node_id, deadline_at FROM nodes
5
+ WHERE profile_id = ? AND deadline_at IS NOT NULL AND status IN ('active', 'idle')`).all(e),i=t.prepare("UPDATE nodes SET deadline_at = ? WHERE node_id = ? AND deadline_at = ?");let r=0;for(const d of a){const l=Date.parse(d.deadline_at);Number.isNaN(l)||(r+=Number((await i.run(new Date(l+n).toISOString(),d.node_id,d.deadline_at)).changes))}return r})}o(qn,"shiftProfileNodeDeadlines");function A(e,n){if(e==null)return null;if(typeof e=="string"||typeof e=="number"||typeof e=="bigint"||e instanceof Uint8Array)return e;throw new TypeError(`${n} must be a SQLite scalar`)}o(A,"sqlInput");async function Bn(e,n){const t=[],a=o((r,d=r)=>{Object.prototype.hasOwnProperty.call(n,r)&&t.push([d,A(n[r],r)])},"add");if(a("description"),a("title"),a("icon"),a("cycles"),a("mode"),a("lifecycle"),a("cwd"),a("host_kind"),a("profile_id"),a("parent"),a("spawned_by"),a("creator"),a("fork_from"),a("fork_source_file"),a("model_override"),Object.prototype.hasOwnProperty.call(n,"passive_default")&&t.push(["passive_default",n.passive_default===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"cycle_pending")&&t.push(["cycle_pending",n.cycle_pending===!0?1:0]),Object.prototype.hasOwnProperty.call(n,"persona_ack")&&t.push(["persona_ack_json",E(n.persona_ack,"persona_ack")]),Object.prototype.hasOwnProperty.call(n,"review_binding")&&t.push(["review_binding_json",E(n.review_binding,"review_binding")]),Object.prototype.hasOwnProperty.call(n,"isolated"))throw new TypeError("isolated cannot change after node creation");Object.prototype.hasOwnProperty.call(n,"scopes")&&t.push(["scopes_json",E(n.scopes,"scopes")]),Object.prototype.hasOwnProperty.call(n,"launch")&&t.push(["launch_config_json",E(n.launch,"launch")]);const i=o(r=>Object.prototype.hasOwnProperty.call(n,r),"has");return await p(async r=>{const d=await D(r,e);if(d===null||d.type!=="node")throw new Error(`unknown node: ${e}`);if(i("name")&&await He(r,d,A(n.name,"name")),i("kind")&&await Ce(r,d,A(n.kind,"kind")),t.length===0)return;if(i("profile_id")){const u=await r.prepare("SELECT app FROM nodes WHERE node_id = ?").get(e),_=u?.app?await D(r,u.app):null;if(_){const w=n.profile_id?await J(r,n.profile_id,_):null;await r.prepare("UPDATE objects SET owner = ? WHERE id = ?").run((w??_).id,e);const R=(await r.prepare("SELECT sub FROM nodes WHERE node_id = ?").get(e)).sub;w===null&&R&&await z(r,e,R)}}if((await r.prepareUncached(`UPDATE nodes SET ${t.map(([u])=>`${u} = ?`).join(", ")} WHERE node_id = ?`).run(...t.map(([,u])=>u),e)).changes!==1)throw new Error(`unknown node: ${e}`)}),await h(e)}o(Bn,"updateNode");async function zn(e,n){await(await s()).prepare("UPDATE nodes SET status = ? WHERE node_id = ?").run(n,e)}o(zn,"setStatus");async function Jn(e,n){await(await s()).prepare("UPDATE nodes SET intent = ? WHERE node_id = ?").run(n??null,e)}o(Jn,"setIntent");async function Yn(e,n,t={}){if(t.outcome===void 0){const i=[],r=[];Object.prototype.hasOwnProperty.call(n,"status")&&(i.push("status = ?"),r.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(i.push("intent = ?"),r.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(i.push("terminal_reason = ?"),r.push(n.terminal_reason??null));const d=["node_id = ?"];r.push(e),t.fromStatuses!==void 0&&(d.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),r.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&d.push("final_report IS NULL");const l=await(await s()).prepareUncached(`UPDATE nodes SET ${i.join(", ")} WHERE ${d.join(" AND ")}`).run(...r);return Number(l.changes)}const a=t.outcome;return await p(async i=>{const r=[],d=[];Object.prototype.hasOwnProperty.call(n,"status")&&(r.push("status = ?"),d.push(n.status??null)),Object.prototype.hasOwnProperty.call(n,"intent")&&(r.push("intent = ?"),d.push(n.intent??null)),Object.prototype.hasOwnProperty.call(n,"terminal_reason")&&(r.push("terminal_reason = ?"),d.push(n.terminal_reason??null));const l=o((R,y)=>a.supersede===!0?"?":`CASE WHEN outcome_at IS NULL THEN ? ELSE ${y} END`,"outcomeValue");r.push(`outcome_kind = ${l(a.kind,"outcome_kind")}`,`outcome_reason = ${l(a.reason,"outcome_reason")}`,`outcome_detail_json = ${l(a.detailJson,"outcome_detail_json")}`,`outcome_revision = ${a.supersede===!0?"outcome_revision + 1":"CASE WHEN outcome_at IS NULL THEN outcome_revision + 1 ELSE outcome_revision END"}`,`outcome_at = ${l(a.at,"outcome_at")}`),d.push(a.kind,a.reason,a.detailJson,a.at);const u=["node_id = ?"];d.push(e),t.fromStatuses!==void 0&&(u.push(`status IN (${t.fromStatuses.map(()=>"?").join(", ")})`),d.push(...t.fromStatuses)),t.requireNoFinalReport===!0&&u.push("final_report IS NULL");const _=await i.prepareUncached(`UPDATE nodes SET ${r.join(", ")} WHERE ${u.join(" AND ")}`).run(...d);if(Number(_.changes)===0)return 0;const w=await i.prepare("SELECT outcome_at FROM nodes WHERE node_id = ?").get(e);return(a.supersede===!0||w.outcome_at===a.at)&&a.documentJson!==null&&a.documentJson!==void 0&&await Re(i,{event:"outcome",object:await Se(i,e),actor:null,attrs:{revision:Number((await i.prepare("SELECT outcome_revision FROM nodes WHERE node_id = ?").get(e)).outcome_revision)},messageBody:JSON.parse(a.documentJson)}),Number(_.changes)})}o(Yn,"transitionStatusIntent");async function Qn(e){return(await(await s()).prepare("SELECT final_report FROM nodes WHERE node_id = ?").get(e))?.final_report??null}o(Qn,"getFinalReport");async function Vn(e,n){return(await(await s()).prepare("UPDATE nodes SET final_report = NULL, finalized_at = NULL WHERE node_id = ? AND final_report = ?").run(e,n)).changes>0}o(Vn,"clearFinalReportIfMatches");async function Kn(e,n){await(await s()).prepare('UPDATE nodes SET tmux_session = ?, "window" = ?, pane = ? WHERE node_id = ?').run(n.tmux_session??null,n.window??null,n.pane??null,e)}o(Kn,"setPresence");async function Gn(e,n){await(await s()).prepare("UPDATE nodes SET launched_at = ?, frozen_at = NULL, respawn_not_before = NULL WHERE node_id = ?").run(n,e)}o(Gn,"recordLaunch");async function Xn(e,n){await(await s()).prepare("UPDATE nodes SET last_settled_at = ? WHERE node_id = ?").run(n,e)}o(Xn,"recordSettledTurn");async function Zn(e,n){await(await s()).prepare("UPDATE nodes SET frozen_at = ? WHERE node_id = ?").run(n,e)}o(Zn,"setFrozen");async function et(e){await(await s()).prepare("UPDATE nodes SET frozen_at = NULL WHERE node_id = ?").run(e)}o(et,"clearFrozen");async function nt(e,n){await(await s()).prepare("UPDATE nodes SET respawn_failures = ?, respawn_not_before = ? WHERE node_id = ?").run(n.failures,n.notBefore,e)}o(nt,"recordRespawnAttempt");const N="node_id NOT IN (SELECT node_id FROM warm_pool)",v=["state","cleanup_state","path","branch","repo_root","base_ref","base_sha","created_at","closed_at","next_attempt_at","attempts","quarantined","sweep_reason","sweep_detail","sweep_last_at","sweep_observed_json","abandoned_json","land_intent_json","disposal_json"];function V(e){return e.worktree_state===null?null:ge(Object.fromEntries(v.map(n=>[n,e[`worktree_${n}`]])))}o(V,"worktreeFromProjection");async function tt(e){const n=v.map(a=>`w.${a} AS worktree_${a}`).join(", "),t=await(await s()).prepareUncached(`SELECT n.*, ${n} FROM node_rows n LEFT JOIN worktrees w ON w.node_id = n.node_id WHERE n.profile_id = ? ORDER BY n.created`).all(e);return await O(t,async a=>await g(a,V(a)))}o(tt,"listNodesByProfile");async function at(){return(await(await s()).prepare(`SELECT
6
6
  node_id, name, description, kind, mode, lifecycle, status, cwd, profile_id,
7
7
  grantee, parent, created, frozen_at, terminal_reason, final_report,
8
8
  telemetry_tokens_in, telemetry_updated_at, pi_pid, turn_open_at, turn_closed_at,
@@ -10,13 +10,13 @@ var ie=Object.defineProperty;var i=(e,n)=>ie(e,"name",{value:n,configurable:!0})
10
10
  fault_operation_id, fault_anchor_entry_id, fault_retry_disposition,
11
11
  fault_retry_by, fault_retry_attempt, fault_retry_max, fault_retry_next_at,
12
12
  fault_provider_error_json
13
- FROM node_rows WHERE ${N} ORDER BY created`).all()).map(f)}i(tt,"browseNodes");async function at(e,n){await(await s()).prepare(`UPDATE nodes
13
+ FROM node_rows WHERE ${N} ORDER BY created`).all()).map(f)}o(at,"browseNodes");async function it(e,n){await(await s()).prepare(`UPDATE nodes
14
14
  SET telemetry_tokens_in = ?,
15
15
  telemetry_context_tokens = COALESCE(?, telemetry_context_tokens),
16
16
  telemetry_last_activity = COALESCE(?, telemetry_last_activity),
17
17
  telemetry_updated_at = ?
18
18
  WHERE node_id = ?
19
- AND (telemetry_updated_at IS NULL OR telemetry_updated_at < ?)`).run(n.tokensIn,n.contextTokens,n.lastActivity,n.updatedAt,e,n.updatedAt)}i(at,"updateNodeTelemetry");async function it(){return(await(await s()).prepare(`SELECT
19
+ AND (telemetry_updated_at IS NULL OR telemetry_updated_at < ?)`).run(n.tokensIn,n.contextTokens,n.lastActivity,n.updatedAt,e,n.updatedAt)}o(it,"updateNodeTelemetry");async function ot(){return(await(await s()).prepare(`SELECT
20
20
  node_id, name, description, cycles, kind, status, frozen_at,
21
21
  telemetry_context_tokens, telemetry_last_activity,
22
22
  pi_pid, turn_open_at, turn_closed_at,
@@ -24,14 +24,14 @@ var ie=Object.defineProperty;var i=(e,n)=>ie(e,"name",{value:n,configurable:!0})
24
24
  fault_operation_id, fault_anchor_entry_id, fault_retry_disposition,
25
25
  fault_retry_by, fault_retry_attempt, fault_retry_max, fault_retry_next_at,
26
26
  fault_provider_error_json
27
- FROM node_rows WHERE ${N} ORDER BY created`).all()).map(n=>{const t=n.pi_pid??null,a=P(t),o=z(n);return{node_id:n.node_id,name:n.name,description:n.description??null,cycles:n.cycles??null,kind:n.kind,status:n.status,frozen_at:n.frozen_at??null,pi_pid:t,telemetry_context_tokens:n.telemetry_context_tokens??null,telemetry_last_activity:n.telemetry_last_activity??null,fault:o?.link==="pi\u2192provider"&&o.retry.by==="daemon"&&o.retry.disposition==="auto"&&!a?null:o,streaming:n.turn_open_at!==null&&n.turn_closed_at===null&&a}})}i(it,"graphNodes");async function Ye(e){const n=[N],t=[];if(e?.under!==void 0&&(e.underInclusive===!0?(n.push(`(node_id IN (${$e}) OR node_id = ?)`),t.push(e.under,e.under,e.under)):(n.push(`node_id IN (${qe})`),t.push(e.under,e.under))),e?.lifecycle!==void 0&&(n.push("lifecycle = ?"),t.push(e.lifecycle)),e?.kind!==void 0&&(n.push("kind = ?"),t.push(e.kind)),e?.mode!==void 0&&(n.push("mode = ?"),t.push(e.mode)),e?.profileId!==void 0&&(n.push("profile_id = ?"),t.push(e.profileId)),e?.profilePrefix!==void 0&&(n.push("profile_id LIKE ? ESCAPE '\\'"),t.push(`${e.profilePrefix.replace(/[\\%_]/g,o=>`\\${o}`)}%`)),e?.parent!==void 0&&(n.push("parent = ?"),t.push(e.parent)),e?.topLevel===!0&&n.push("parent IS NULL"),e?.hanging===!0&&n.push("parent IS NOT NULL AND parent NOT IN (SELECT node_id FROM node_rows)"),e?.status!==void 0){const o=Array.isArray(e.status)?e.status:[e.status];n.push(`status IN (${o.map(()=>"?").join(",")})`),t.push(...o)}return e?.withRecordedPid===!0&&n.push("pi_pid IS NOT NULL"),e?.withRecordedPidOrFrozen===!0&&n.push("(pi_pid IS NOT NULL OR frozen_at IS NOT NULL)"),(await(await s()).prepareUncached(`SELECT * FROM node_rows WHERE ${n.join(" AND ")} ORDER BY created`).all(...t)).map(f)}i(Ye,"listNodes");const Qe=`SELECT
27
+ FROM node_rows WHERE ${N} ORDER BY created`).all()).map(n=>{const t=n.pi_pid??null,a=q(t),i=Y(n);return{node_id:n.node_id,name:n.name,description:n.description??null,cycles:n.cycles??null,kind:n.kind,status:n.status,frozen_at:n.frozen_at??null,pi_pid:t,telemetry_context_tokens:n.telemetry_context_tokens??null,telemetry_last_activity:n.telemetry_last_activity??null,fault:i?.link==="pi\u2192provider"&&i.retry.by==="daemon"&&i.retry.disposition==="auto"&&!a?null:i,streaming:n.turn_open_at!==null&&n.turn_closed_at===null&&a}})}o(ot,"graphNodes");async function Ye(e){const n=[N],t=[];if(e?.under!==void 0&&(e.underInclusive===!0?(n.push(`(node_id IN (${qe}) OR node_id = ?)`),t.push(e.under,e.under,e.under)):(n.push(`node_id IN (${Be})`),t.push(e.under,e.under))),e?.lifecycle!==void 0&&(n.push("lifecycle = ?"),t.push(e.lifecycle)),e?.kind!==void 0&&(n.push("kind = ?"),t.push(e.kind)),e?.mode!==void 0&&(n.push("mode = ?"),t.push(e.mode)),e?.profileId!==void 0&&(n.push("profile_id = ?"),t.push(e.profileId)),e?.profilePrefix!==void 0&&(n.push("profile_id LIKE ? ESCAPE '\\'"),t.push(`${e.profilePrefix.replace(/[\\%_]/g,i=>`\\${i}`)}%`)),e?.parent!==void 0&&(n.push("parent = ?"),t.push(e.parent)),e?.topLevel===!0&&n.push("parent IS NULL"),e?.hanging===!0&&n.push("parent IS NOT NULL AND parent NOT IN (SELECT node_id FROM node_rows)"),e?.status!==void 0){const i=Array.isArray(e.status)?e.status:[e.status];n.push(`status IN (${i.map(()=>"?").join(",")})`),t.push(...i)}return e?.withRecordedPid===!0&&n.push("pi_pid IS NOT NULL"),e?.withRecordedPidOrFrozen===!0&&n.push("(pi_pid IS NOT NULL OR frozen_at IS NOT NULL)"),(await(await s()).prepareUncached(`SELECT * FROM node_rows WHERE ${n.join(" AND ")} ORDER BY created`).all(...t)).map(f)}o(Ye,"listNodes");const Qe=`SELECT
28
28
  node_id, created, launched_at, last_settled_at, finalized_at,
29
29
  outcome_at, last_activity_at, pane, "window", tmux_session
30
30
  FROM nodes
31
31
  WHERE ${N}
32
32
  AND status IN ('done', 'canceled', 'dead')
33
33
  AND (pane IS NOT NULL OR "window" IS NOT NULL OR tmux_session IS NOT NULL)
34
- ORDER BY created`;async function ot(){return await(await s()).prepare(Qe).all()}i(ot,"listTerminalPlacementResidue");const Ve=`WITH candidates AS MATERIALIZED (
34
+ ORDER BY created`;async function rt(){return await(await s()).prepare(Qe).all()}o(rt,"listTerminalPlacementResidue");const Ve=`WITH candidates AS MATERIALIZED (
35
35
  SELECT node_id FROM nodes WHERE status IN ('active', 'idle')
36
36
  UNION
37
37
  SELECT node_id FROM nodes
@@ -45,23 +45,23 @@ var ie=Object.defineProperty;var i=(e,n)=>ie(e,"name",{value:n,configurable:!0})
45
45
  AND v.node_id NOT IN (SELECT node_id FROM warm_pool)
46
46
  AND v.kind != 'human'
47
47
  AND (v.status IN ('active', 'idle') OR (v.status IN ('done', 'canceled', 'dead') AND (v.pi_pid IS NOT NULL OR v.frozen_at IS NOT NULL)))
48
- ORDER BY v.created`;async function rt(){return(await(await s()).prepare(Ve).all()).map(f)}i(rt,"listNodesForSupervision");const V=i(e=>`(${e}.status = 'done' AND ${e}.intent = 'parked' AND ${e}.lifecycle = 'resident' AND ${e}.final_report IS NULL AND ${e}.deleting_at IS NULL)`,"PARKED_RESIDENT_SQL"),Ke=i(e=>`(${e}.status IN ('active', 'idle') OR ${V(e)} OR (${e}.status IN ('done', 'canceled', 'dead') AND ${e}.frozen_at IS NOT NULL AND ${e}.final_report IS NULL))`,"RESUMABLE_NODE_SQL");async function st(e){return await(await s()).prepare(`SELECT node_id, cwd FROM nodes WHERE ${Ke("nodes")} AND node_id != ?`).all(e)}i(st,"resumableNodeCwds");async function dt(){return(await(await s()).prepare(`SELECT v.* FROM node_rows v
49
- WHERE ${V("v")}
50
- AND EXISTS (SELECT 1 FROM deliveries d WHERE d.destination_id = v.node_id AND ${me("d")}) AND v.kind != 'human' AND v.node_id NOT IN (SELECT node_id FROM warm_pool)
51
- ORDER BY v.created`).all()).map(f)}i(dt,"listParkedResidentsWithWakeMail");async function ut(e,n){await(await s()).prepare("INSERT INTO warm_pool (node_id, recipe_key, created) VALUES (?, ?, ?) ON CONFLICT (node_id) DO UPDATE SET recipe_key = excluded.recipe_key, created = excluded.created").run(e,n,new Date().toISOString())}i(ut,"registerWarmSpare");async function lt(e){return(await(await s()).prepare("DELETE FROM warm_pool WHERE node_id = ?").run(e)).changes>0}i(lt,"unregisterWarmSpare");async function A(e,n){const t=`SELECT w.node_id AS node_id, w.recipe_key AS recipe_key, w.created AS created,
48
+ ORDER BY v.created`;async function st(){return(await(await s()).prepare(Ve).all()).map(f)}o(st,"listNodesForSupervision");const K=o(e=>`(${e}.status = 'done' AND ${e}.intent = 'parked' AND ${e}.lifecycle = 'resident' AND ${e}.final_report IS NULL AND ${e}.deleting_at IS NULL)`,"PARKED_RESIDENT_SQL"),Ke=o(e=>`(${e}.status IN ('active', 'idle') OR ${K(e)} OR (${e}.status IN ('done', 'canceled', 'dead') AND ${e}.frozen_at IS NOT NULL AND ${e}.final_report IS NULL))`,"RESUMABLE_NODE_SQL");async function dt(e){return await(await s()).prepare(`SELECT node_id, cwd FROM nodes WHERE ${Ke("nodes")} AND node_id != ?`).all(e)}o(dt,"resumableNodeCwds");async function ut(){return(await(await s()).prepare(`SELECT v.* FROM node_rows v
49
+ WHERE ${K("v")}
50
+ AND EXISTS (SELECT 1 FROM deliveries d WHERE d.destination_id = v.node_id AND ${Ne("d")}) AND v.kind != 'human' AND v.node_id NOT IN (SELECT node_id FROM warm_pool)
51
+ ORDER BY v.created`).all()).map(f)}o(ut,"listParkedResidentsWithWakeMail");async function lt(e,n){await(await s()).prepare("INSERT INTO warm_pool (node_id, recipe_key, created) VALUES (?, ?, ?) ON CONFLICT (node_id) DO UPDATE SET recipe_key = excluded.recipe_key, created = excluded.created").run(e,n,new Date().toISOString())}o(lt,"registerWarmSpare");async function ct(e){return(await(await s()).prepare("DELETE FROM warm_pool WHERE node_id = ?").run(e)).changes>0}o(ct,"unregisterWarmSpare");async function k(e,n){const t=`SELECT w.node_id AS node_id, w.recipe_key AS recipe_key, w.created AS created,
52
52
  n.status AS status, n.pi_pid AS pi_pid, n.pi_pid_identity AS pi_pid_identity
53
- FROM warm_pool w JOIN node_rows n ON n.node_id = w.node_id`+(n===void 0?"":" WHERE w.recipe_key = ?")+" ORDER BY w.created";return(n===void 0?await e.prepareUncached(t).all():await e.prepareUncached(t).all(n)).map(o=>({node_id:o.node_id,recipe_key:o.recipe_key,created:o.created,status:o.status,pi_pid:o.pi_pid??null,pi_pid_identity:o.pi_pid_identity??null}))}i(A,"warmSpareRowsFor");async function ct(){return await A(await s())}i(ct,"listWarmSpares");async function _t(e){return await(await s()).prepare("SELECT 1 FROM warm_pool WHERE node_id = ?").get(e)!==void 0}i(_t,"isWarmSpare");function K(e){return e.status!=="active"&&e.status!=="idle"?!1:Ae(e.pi_pid,e.pi_pid_identity)==="alive"}i(K,"spareIsClaimable");async function pt(e,n,t={}){return await p(async a=>{const o=(await A(a,e)).find(K);return o===void 0||t.requestKey!==void 0&&(await a.prepareUncached("UPDATE create_requests SET node_id = ?, state = 'warm_claimed' WHERE request_key = ? AND node_id IS NULL").run(o.node_id,t.requestKey)).changes===0||(await a.prepare("DELETE FROM warm_pool WHERE node_id = ?").run(o.node_id)).changes===0?null:(await a.prepare("UPDATE nodes SET created = ?, deadline_at = ? WHERE node_id = ?").run(n,t.deadlineAt??null,o.node_id),t.outcomeDelivery!==void 0&&await M(a,o.node_id,t.outcomeDelivery),o.node_id)})}i(pt,"claimWarmSpare");async function ft(e){return(await A(await s(),e)).filter(K).length}i(ft,"warmSpareCount");async function Et(e){return(await(await s()).prepare("SELECT node_id FROM nodes WHERE parent = ? ORDER BY created").all(e)).map(n=>n.node_id)}i(Et,"childrenOf");async function wt(){return(await(await s()).prepareUncached(`SELECT node_id, name, kind, mode, lifecycle, status, cwd, host_kind, parent, created, description
54
- FROM node_rows WHERE ${N} ORDER BY created`).all()).map(e=>({node_id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,parent:e.parent??null,created:e.created,description:e.description??null}))}i(wt,"rosterNodes");async function yt(e){return(await(await s()).prepareUncached(`SELECT * FROM node_rows
53
+ FROM warm_pool w JOIN node_rows n ON n.node_id = w.node_id`+(n===void 0?"":" WHERE w.recipe_key = ?")+" ORDER BY w.created";return(n===void 0?await e.prepareUncached(t).all():await e.prepareUncached(t).all(n)).map(i=>({node_id:i.node_id,recipe_key:i.recipe_key,created:i.created,status:i.status,pi_pid:i.pi_pid??null,pi_pid_identity:i.pi_pid_identity??null}))}o(k,"warmSpareRowsFor");async function _t(){return await k(await s())}o(_t,"listWarmSpares");async function pt(e){return await(await s()).prepare("SELECT 1 FROM warm_pool WHERE node_id = ?").get(e)!==void 0}o(pt,"isWarmSpare");function G(e){return e.status!=="active"&&e.status!=="idle"?!1:ve(e.pi_pid,e.pi_pid_identity)==="alive"}o(G,"spareIsClaimable");async function ft(e,n,t={}){return await p(async a=>{const i=(await k(a,e)).find(G);return i===void 0||t.requestKey!==void 0&&(await a.prepareUncached("UPDATE create_requests SET node_id = ?, state = 'warm_claimed' WHERE request_key = ? AND node_id IS NULL").run(i.node_id,t.requestKey)).changes===0||(await a.prepare("DELETE FROM warm_pool WHERE node_id = ?").run(i.node_id)).changes===0?null:(await a.prepare("UPDATE nodes SET created = ?, deadline_at = ? WHERE node_id = ?").run(n,t.deadlineAt??null,i.node_id),t.outcomeDelivery!==void 0&&await $(a,i.node_id,t.outcomeDelivery),i.node_id)})}o(ft,"claimWarmSpare");async function Et(e){return(await k(await s(),e)).filter(G).length}o(Et,"warmSpareCount");async function wt(e){return(await(await s()).prepare("SELECT node_id FROM nodes WHERE parent = ? ORDER BY created").all(e)).map(n=>n.node_id)}o(wt,"childrenOf");async function yt(){return(await(await s()).prepareUncached(`SELECT node_id, name, kind, mode, lifecycle, status, cwd, host_kind, parent, created, description
54
+ FROM node_rows WHERE ${N} ORDER BY created`).all()).map(e=>({node_id:e.node_id,name:e.name,kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,cwd:e.cwd,host_kind:e.host_kind??null,parent:e.parent??null,created:e.created,description:e.description??null}))}o(yt,"rosterNodes");async function mt(e){return(await(await s()).prepareUncached(`SELECT * FROM node_rows
55
55
  WHERE parent IS NULL AND kind != 'human'
56
56
  AND status IN ('active','idle') AND cwd = ?
57
57
  AND ${N}
58
- ORDER BY created DESC`).all(e)).map(f)}i(yt,"listResumableRoots");export*from"./tree.js";async function mt(e,n,t){return await p(async a=>{const o=await a.prepare("SELECT status, final_report, frozen_at FROM nodes WHERE node_id = ? FOR UPDATE").get(e);return o===void 0?{kind:"missing"}:n(o)?{kind:"terminal",status:o.status,final_report:o.final_report}:{kind:"ran",result:await t()}})}i(mt,"withFreshTerminalGuard");async function h(e){return await he(e)}i(h,"hasUnreconciledManagedWorktree");async function G(e,n={}){return!["done","dead","canceled"].includes(e.status)||e.pi_pid!==null||e.frozen_at!==null||await h(e.node_id)||e.node_id===W()||H(e)?!1:n.pastTtl===!0||!["crashed","stranded",null].includes(e.terminal_reason??null)}i(G,"isCollectible");async function g(e){if(e.length===0)return[];const n=e.map(()=>"?").join(","),t=await(await s()).prepareUncached(`SELECT s.session_id, s.transcript_path, s.node_id, n.grantee FROM sessions s JOIN node_rows n ON n.node_id = s.node_id WHERE s.node_id IN (${n}) AND s.session_id IS NOT NULL AND s.transcript_path IS NOT NULL ORDER BY s.created_at, s.seq`).all(...e);return[...new Map(t.map(a=>[a.session_id,{id:a.session_id,path:a.transcript_path,dir:S(T(a.grantee).conversations,a.node_id)}])).values()]}i(g,"nodeConversationIds");async function k(e){const n=await s(),t=n.prepare("SELECT 1 FROM sessions WHERE session_id = ? LIMIT 1"),a=n.prepare(`SELECT 1 FROM nodes n WHERE n.fork_source_file LIKE '%\\_' || ? || '.jsonl' ESCAPE '\\'
59
- AND NOT EXISTS (SELECT 1 FROM sessions s WHERE s.node_id = n.node_id) LIMIT 1`);for(const{id:o,path:r,dir:d}of e)if(!(await t.get(o)!==void 0||await a.get(o)!==void 0)&&oe(r,{throwIfNoEntry:!1})!==void 0){if(!Ge(d,r)){console.error(`[canvas] not deleting transcript outside its node's conversations directory: ${r}`);continue}try{await Ee().delete(o,r)}catch(l){if(!(l instanceof we))throw l}}}i(k,"deleteNodeConversations");function Ge(e,n){try{const t=ce(b(e),S(b(F(n)),ue(n)));return t!==""&&t!==".."&&!t.startsWith(`..${pe}`)&&!le(t)}catch(t){if(t.code==="ENOENT")return!1;throw t}}i(Ge,"isBeneath");async function U(e,n){const t=await L(e,n);return t===null||t.deleted_at!==null?!1:(await Pe(e,t),!0)}i(U,"deleteNodeObject");async function x(e){return{nodeId:e,app:await O(e)===null?null:await xe(e)}}i(x,"nodeFiles");async function X({nodeId:e,app:n}){n!==null&&C(T(n).nodes,await je(e,n)),C(F($(e)),$(e))}i(X,"removeNodeAppTrees");function Z({nodeId:e}){return[Ue(e)]}i(Z,"nodeOwnedDirs");function ee({nodeId:e,app:n}){if(n!==null)try{re(S(T(n).conversations,e))}catch(t){if(!["ENOENT","ENOTEMPTY"].includes(t.code??""))throw t}}i(ee,"removeNodeConversationDir");async function I(e){await X(e);for(const n of Z(e))se(n,{recursive:!0,force:!0});ee(e)}i(I,"removeNodeFiles");async function Nt(e){if(await h(e))return{deleted:!1};const n=await x(e),t=await g([e]),a=await p(async o=>(await U(o,e),{deleted:!0}));return await k(t),await I(n),a}i(Nt,"deleteNode");async function Rt(e){const n=[...new Set(e)];if(n.length===0)return[];const t=await m(n,h);if(t.length>0)throw new Error(`refusing to delete nodes with unreconciled managed worktrees: ${t.join(", ")}`);const a=await D(n,x),o=await g(n),r=n.map(()=>"?").join(","),d=(await(await s()).prepareUncached(`SELECT node_id FROM nodes WHERE node_id IN (${r}) ORDER BY created`).all(...n)).map(({node_id:u})=>u),l=await m(d,async u=>await p(async _=>await U(_,u)));await k(o);for(const u of l){const _=a[n.indexOf(u)];await j(_,async()=>await I(_))}return l}i(Rt,"deleteNodes");async function St(e){const n=e.dryRun??!1,t=e.includeStale??!1,a=Date.now()-e.ttlDays*864e5,o=new Date(a).toISOString(),r=W()??"",d=await s(),l=i(c=>ae(c)<a,"quiet"),u=i(c=>({node_id:c.node_id,status:c.status,created:c.created}),"toPruned"),_=await Xe(),w=(await m((await d.prepare(`SELECT * FROM node_rows
58
+ ORDER BY created DESC`).all(e)).map(f)}o(mt,"listResumableRoots");export*from"./tree.js";async function Nt(e,n,t){return await p(async a=>{const i=await a.prepare("SELECT status, final_report, frozen_at FROM nodes WHERE node_id = ? FOR UPDATE").get(e);return i===void 0?{kind:"missing"}:n(i)?{kind:"terminal",status:i.status,final_report:i.final_report}:{kind:"ran",result:await t()}})}o(Nt,"withFreshTerminalGuard");async function T(e){return await Te(e)}o(T,"hasUnreconciledManagedWorktree");async function X(e,n={}){return!["done","dead","canceled"].includes(e.status)||e.pi_pid!==null||e.frozen_at!==null||await T(e.node_id)||e.node_id===b()||P(e)?!1:n.pastTtl===!0||!["crashed","stranded",null].includes(e.terminal_reason??null)}o(X,"isCollectible");async function U(e){if(e.length===0)return[];const n=e.map(()=>"?").join(","),t=await(await s()).prepareUncached(`SELECT s.session_id, s.transcript_path, s.node_id, n.grantee FROM sessions s JOIN node_rows n ON n.node_id = s.node_id WHERE s.node_id IN (${n}) AND s.session_id IS NOT NULL AND s.transcript_path IS NOT NULL ORDER BY s.created_at, s.seq`).all(...e);return[...new Map(t.map(a=>[a.session_id,{id:a.session_id,path:a.transcript_path,dir:S(L(a.grantee).conversations,a.node_id)}])).values()]}o(U,"nodeConversationIds");async function x(e){const n=await s(),t=n.prepare("SELECT 1 FROM sessions WHERE session_id = ? LIMIT 1"),a=n.prepare(`SELECT 1 FROM nodes n WHERE n.fork_source_file LIKE '%\\_' || ? || '.jsonl' ESCAPE '\\'
59
+ AND NOT EXISTS (SELECT 1 FROM sessions s WHERE s.node_id = n.node_id) LIMIT 1`);for(const{id:i,path:r,dir:d}of e)if(!(await t.get(i)!==void 0||await a.get(i)!==void 0)&&re(r,{throwIfNoEntry:!1})!==void 0){if(!Ge(d,r)){console.error(`[canvas] not deleting transcript outside its node's conversations directory: ${r}`);continue}try{await we().delete(i,r)}catch(l){if(!(l instanceof ye))throw l}}}o(x,"deleteNodeConversations");function Ge(e,n){try{const t=_e(C(e),S(C(H(n)),le(n)));return t!==""&&t!==".."&&!t.startsWith(`..${fe}`)&&!ce(t)}catch(t){if(t.code==="ENOENT")return!1;throw t}}o(Ge,"isBeneath");async function j(e,n){const t=await D(e,n);return t===null||t.deleted_at!==null?!1:(await $e(e,t),!0)}o(j,"deleteNodeObject");async function I(e){return{nodeId:e,app:await h(e)===null?null:await je(e)}}o(I,"nodeFiles");async function Z({nodeId:e,app:n}){n!==null&&M(L(n).nodes,await We(e,n)),M(H(B(e)),B(e))}o(Z,"removeNodeAppTrees");function ee({nodeId:e}){return[xe(e)]}o(ee,"nodeOwnedDirs");function ne({nodeId:e,app:n}){if(n!==null)try{se(S(L(n).conversations,e))}catch(t){if(!["ENOENT","ENOTEMPTY"].includes(t.code??""))throw t}}o(ne,"removeNodeConversationDir");async function W(e){await Z(e);for(const n of ee(e))de(n,{recursive:!0,force:!0});ne(e)}o(W,"removeNodeFiles");async function Rt(e){if(await T(e))return{deleted:!1};const n=await I(e),t=await U([e]),a=await p(async i=>(await j(i,e),{deleted:!0}));return await x(t),await W(n),a}o(Rt,"deleteNode");async function St(e){const n=[...new Set(e)];if(n.length===0)return[];const t=await m(n,T);if(t.length>0)throw new Error(`refusing to delete nodes with unreconciled managed worktrees: ${t.join(", ")}`);const a=await O(n,I),i=await U(n),r=n.map(()=>"?").join(","),d=(await(await s()).prepareUncached(`SELECT node_id FROM nodes WHERE node_id IN (${r}) ORDER BY created`).all(...n)).map(({node_id:u})=>u),l=await m(d,async u=>await p(async _=>await j(_,u)));await x(i);for(const u of l){const _=a[n.indexOf(u)];await F(_,async()=>await W(_))}return l}o(St,"deleteNodes");async function Ot(e){const n=e.dryRun??!1,t=e.includeStale??!1,a=Date.now()-e.ttlDays*864e5,i=new Date(a).toISOString(),r=b()??"",d=await s(),l=o(c=>ie(c)<a,"quiet"),u=o(c=>({node_id:c.node_id,status:c.status,created:c.created}),"toPruned"),_=await Xe(),w=(await m((await d.prepare(`SELECT * FROM node_rows
60
60
  WHERE status IN ('dead', 'done', 'canceled') AND created < ?
61
- ORDER BY created`).all(o)).map(f),async c=>await G(c,{pastTtl:!0})&&l(c)&&!_.has(c.node_id)&&!await e.held(c.node_id))).map(u),R=t?(await m((await d.prepare(`SELECT * FROM node_rows
61
+ ORDER BY created`).all(i)).map(f),async c=>await X(c,{pastTtl:!0})&&l(c)&&!_.has(c.node_id)&&!await e.held(c.node_id))).map(u),R=t?(await m((await d.prepare(`SELECT * FROM node_rows
62
62
  WHERE status IN ('active', 'idle') AND created < ?
63
- ORDER BY created`).all(o)).map(f),async c=>c.node_id!==r&&!ve(c.pi_pid??null)&&(c.frozen_at??null)===null&&(c.respawn_not_before??null)===null&&c.intent!=="idle-release"&&!H(c)&&!await ye(c.node_id)&&!await h(c.node_id)&&l(c)&&!await e.held(c.node_id))).map(u):[],y=await ne([...w,...R]);return n||y.length===0?{pruned:y,dryRun:n}:(await te(y,e.removeDirs),{pruned:y,dryRun:n})}i(St,"pruneNodes");async function Xe(){const e=await(await s()).prepare(`SELECT DISTINCT d.owner AS owner FROM watches w
63
+ ORDER BY created`).all(i)).map(f),async c=>c.node_id!==r&&!Ae(c.pi_pid??null)&&(c.frozen_at??null)===null&&(c.respawn_not_before??null)===null&&c.intent!=="idle-release"&&!P(c)&&!await me(c.node_id)&&!await T(c.node_id)&&l(c)&&!await e.held(c.node_id))).map(u):[],y=await te([...w,...R]);return n||y.length===0?{pruned:y,dryRun:n}:(await ae(y,e.removeDirs),{pruned:y,dryRun:n})}o(Ot,"pruneNodes");async function Xe(){const e=await(await s()).prepare(`SELECT DISTINCT d.owner AS owner FROM watches w
64
64
  JOIN objects d ON d.id = w.object AND d.type = 'document' AND d.deleted_at IS NULL
65
65
  JOIN objects o ON o.id = w.watcher AND o.deleted_at IS NULL
66
66
  LEFT JOIN nodes n ON n.node_id = w.watcher
67
- WHERE w.watcher != d.owner AND d.owner IS NOT NULL AND (n.node_id IS NULL OR n.status IN ('active', 'idle'))`).all();return new Set(e.map(n=>n.owner))}i(Xe,"ownersOfWatchedDocuments");async function ne(e){const t=(await s()).prepare("SELECT node_id FROM nodes WHERE run_id = ? AND node_id != ?"),a=new Set(e.map(o=>o.node_id));return await m(e,async o=>(await t.all(o.node_id,o.node_id)).every(r=>a.has(r.node_id)))}i(ne,"retainRunRootsWithMembers");async function te(e,n){if(e.length===0)return;const t=await D(e,async o=>await x(o.node_id)),a=await g(e.map(o=>o.node_id));for(const o of e)await p(async r=>await U(r,o.node_id));if(await k(a),n!==void 0){for(const o of t)await j(o,async()=>{await X(o),ee(o)});n(t.flatMap(Z));return}for(const o of t)await j(o,async()=>await I(o))}i(te,"deletePrunedNodes");async function j(e,n){try{n()}catch(t){fe({level:"error",event:"canvas.node_files.remove_failed",error:t,fields:{node_id:e.nodeId}})}}i(j,"eachNodeBestEffort");function ae(e){let n=0;for(const t of[e.created,e.launched_at,e.last_settled_at,e.finalized_at,e.outcome_at,e.last_activity_at]){if(t==null)continue;const a=Date.parse(t);Number.isFinite(a)&&a>n&&(n=a)}try{const t=de(S(ke(e.node_id),"telemetry.json"),{throwIfNoEntry:!1});t!==void 0&&t.mtimeMs>n&&(n=t.mtimeMs)}catch{}return n}i(ae,"lastActivityMs");async function Ot(e){const n=e.dryRun??!1,t=await Ye(),a=await m(t,async u=>await G(u)&&!await e.held(u.node_id)),o=t.length-a.length,r=Math.max(0,e.maxNodes-o),d=a.map(u=>({row:u,recency:ae(u)})).sort((u,_)=>_.recency-u.recency).slice(r).map(({row:u})=>({node_id:u.node_id,status:u.status,created:u.created})),l=await ne(d);return n||l.length===0?{pruned:l,dryRun:n}:(await te(l),{pruned:l,dryRun:n})}i(Ot,"pruneToLimit");export{V as PARKED_RESIDENT_SQL,Ke as RESUMABLE_NODE_SQL,Wn as abandonCreateRequest,vn as assertRunNotDeleting,tt as browseNodes,bn as canonicalSessionFile,Et as childrenOf,pt as claimWarmSpare,Qn as clearFinalReportIfMatches,Zn as clearFrozen,jn as completeCreateRequest,An as createNode,Nt as deleteNode,Rt as deleteNodes,Mn as dueNodeDeadlines,gn as findCreateRequest,Fn as findNodeBySessionFile,Yn as getFinalReport,O as getNode,Cn as getRow,Hn as getRowByPane,it as graphNodes,G as isCollectible,_t as isWarmSpare,ae as lastActivityMs,Ye as listNodes,nt as listNodesByProfile,rt as listNodesForSupervision,dt as listParkedResidentsWithWakeMail,yt as listResumableRoots,ot as listTerminalPlacementResidue,ct as listWarmSpares,x as nodeFiles,Ve as nodesForSupervisionSql,Un as pruneExpiredCreateRequests,St as pruneNodes,Ot as pruneToLimit,xn as recordCreateRequestNode,Kn as recordLaunch,et as recordRespawnAttempt,Gn as recordSettledTurn,ut as registerWarmSpare,I as removeNodeFiles,kn as reserveCreateRequest,In as reserveCreateRequestNode,st as resumableNodeCwds,wt as rosterNodes,Xn as setFrozen,zn as setIntent,Pn as setNodeDeadline,Vn as setPresence,Bn as setStatus,$n as shiftProfileNodeDeadlines,Qe as terminalPlacementResidueSql,Jn as transitionStatusIntent,lt as unregisterWarmSpare,qn as updateNode,at as updateNodeTelemetry,ft as warmSpareCount,mt as withFreshTerminalGuard};
67
+ WHERE w.watcher != d.owner AND d.owner IS NOT NULL AND (n.node_id IS NULL OR n.status IN ('active', 'idle'))`).all();return new Set(e.map(n=>n.owner))}o(Xe,"ownersOfWatchedDocuments");async function te(e){const t=(await s()).prepare("SELECT node_id FROM nodes WHERE run_id = ? AND node_id != ?"),a=new Set(e.map(i=>i.node_id));return await m(e,async i=>(await t.all(i.node_id,i.node_id)).every(r=>a.has(r.node_id)))}o(te,"retainRunRootsWithMembers");async function ae(e,n){if(e.length===0)return;const t=await O(e,async i=>await I(i.node_id)),a=await U(e.map(i=>i.node_id));for(const i of e)await p(async r=>await j(r,i.node_id));if(await x(a),n!==void 0){for(const i of t)await F(i,async()=>{await Z(i),ne(i)});n(t.flatMap(ee));return}for(const i of t)await F(i,async()=>await W(i))}o(ae,"deletePrunedNodes");async function F(e,n){try{n()}catch(t){Ee({level:"error",event:"canvas.node_files.remove_failed",error:t,fields:{node_id:e.nodeId}})}}o(F,"eachNodeBestEffort");function ie(e){let n=0;for(const t of[e.created,e.launched_at,e.last_settled_at,e.finalized_at,e.outcome_at,e.last_activity_at]){if(t==null)continue;const a=Date.parse(t);Number.isFinite(a)&&a>n&&(n=a)}try{const t=ue(S(Ue(e.node_id),"telemetry.json"),{throwIfNoEntry:!1});t!==void 0&&t.mtimeMs>n&&(n=t.mtimeMs)}catch{}return n}o(ie,"lastActivityMs");async function ht(e){const n=e.dryRun??!1,t=await Ye(),a=await m(t,async u=>await X(u)&&!await e.held(u.node_id)),i=t.length-a.length,r=Math.max(0,e.maxNodes-i),d=a.map(u=>({row:u,recency:ie(u)})).sort((u,_)=>_.recency-u.recency).slice(r).map(({row:u})=>({node_id:u.node_id,status:u.status,created:u.created})),l=await te(d);return n||l.length===0?{pruned:l,dryRun:n}:(await ae(l),{pruned:l,dryRun:n})}o(ht,"pruneToLimit");export{K as PARKED_RESIDENT_SQL,Ke as RESUMABLE_NODE_SQL,Fn as abandonCreateRequest,gn as assertRunNotDeleting,at as browseNodes,bn as canonicalSessionFile,wt as childrenOf,ft as claimWarmSpare,Vn as clearFinalReportIfMatches,et as clearFrozen,Wn as completeCreateRequest,An as createNode,Rt as deleteNode,St as deleteNodes,Pn as dueNodeDeadlines,kn as findCreateRequest,Cn as findNodeBySessionFile,Qn as getFinalReport,h as getNode,vn as getNodes,Hn as getRow,Mn as getRowByPane,ot as graphNodes,X as isCollectible,pt as isWarmSpare,ie as lastActivityMs,Ye as listNodes,tt as listNodesByProfile,st as listNodesForSupervision,ut as listParkedResidentsWithWakeMail,mt as listResumableRoots,rt as listTerminalPlacementResidue,_t as listWarmSpares,I as nodeFiles,Ve as nodesForSupervisionSql,xn as pruneExpiredCreateRequests,Ot as pruneNodes,ht as pruneToLimit,jn as recordCreateRequestNode,Gn as recordLaunch,nt as recordRespawnAttempt,Xn as recordSettledTurn,lt as registerWarmSpare,W as removeNodeFiles,Un as reserveCreateRequest,In as reserveCreateRequestNode,dt as resumableNodeCwds,yt as rosterNodes,Zn as setFrozen,Jn as setIntent,$n as setNodeDeadline,Kn as setPresence,zn as setStatus,qn as shiftProfileNodeDeadlines,Qe as terminalPlacementResidueSql,Yn as transitionStatusIntent,ct as unregisterWarmSpare,Bn as updateNode,it as updateNodeTelemetry,Et as warmSpareCount,Nt as withFreshTerminalGuard};
@@ -268,9 +268,13 @@ export type HeldSettle = {
268
268
  nowIso: string;
269
269
  };
270
270
  /** Release the run lease back to idle (run settled, or stale-lease recovery
271
- * for a dead pid), applying the settlement's `held` disposition in the same
271
+ * for a dead pid) — only while the row still holds run `runId`, so a settlement of
272
+ * an old run cannot clear a newer run's lease. Applies the settlement's `held` disposition in the same
272
273
  * statement. */
273
- export declare function releaseCronRunLease(cron_id: string, held?: HeldSettle): Promise<void>;
274
+ export declare function releaseCronRunLease(cron_id: string, runId: string, held?: HeldSettle): Promise<void>;
275
+ /** Persist a run identity on a running row that has none, but only while it is still the same run (same start and lease owner).
276
+ * Recovery calls this under its claim so every later write and release names one stored run. Returns whether it was stored. */
277
+ export declare function adoptCronRunId(c: Cron, runId: string): Promise<boolean>;
274
278
  /** The daemon-level eligibility poke (`POST /v1/crons/poke`): "something
275
279
  * changed; re-check now". One write boundary, two statements:
276
280
  * 1. stamp `last_poke_at` on EVERY row — this is what reaches a gate check
@@ -1,8 +1,8 @@
1
- var w=Object.defineProperty;var a=(n,r)=>w(n,"name",{value:r,configurable:!0});import{withCanvasWrite as c,openDb as i}from"./db.js";import{capturePidIdentities as l,identitiesMatch as R,killProcessGroup as m}from"./pid.js";import{isProfilePaused as h}from"../profiles/manifest.js";import{stopAppProcess as D}from"../spaces/process.js";import{emitEvent as S}from"../events/emit.js";import{personId as p}from"./person.js";const N=20;function O(n){if(typeof n!="string")return null;try{const r=JSON.parse(n);return Array.isArray(r)?r.filter(e=>typeof e=="string"):null}catch{return null}}a(O,"scopesFrom");function s(n){return{cron_id:n.cron_id,name:n.name,created_by:n.created_by??null,grantee:n.grantee,sub:n.sub??p(),grant_id:n.grant_id??null,scopes:O(n.scopes_json),origin_run_id:n.origin_run_id??null,run_execution_id:n.run_execution_id??null,armed_from_exec:Number(n.armed_from_exec??0)!==0,isolated:Number(n.isolated)!==0,command:n.command,fire_at:n.fire_at,recur:n.recur??null,tz:n.tz??null,expires_at:n.expires_at??null,anchor_node:n.anchor_node??null,cancel_on_wake:Number(n.cancel_on_wake)!==0,cwd:n.cwd,env_json:n.env_json??null,profile:n.profile??null,scope:n.scope,run_timeout_s:Number(n.run_timeout_s),overlap:n.overlap,on_output:n.on_output,sink:n.sink,tier:n.tier,last_output_hash:n.last_output_hash??null,held:Number(n.held)!==0,last_poke_at:n.last_poke_at??null,state:n.state,run_state:n.run_state,run_pid:n.run_pid??null,run_pid_identity:n.run_pid_identity??null,run_started_at:n.run_started_at??null,run_lease_owner:n.run_lease_owner??null,run_out_of_band:Number(n.run_out_of_band)!==0,created:n.created,updated:n.updated}}a(s,"cronFrom");function E(n){try{const r=JSON.parse(n);if(typeof r.node=="string")return{kind:"node",node:r.node};if(typeof r.spawn=="string")return{kind:"spawn",spawn:r.spawn};if(r.human===!0)return{kind:"human"}}catch{}return null}a(E,"parseCronSink");function F(n){const r=E(n);if(r===null)return null;switch(r.kind){case"node":return`node:${r.node}`;case"spawn":return`spawn:${r.spawn}`;case"human":return"human"}}a(F,"cronSinkDisplay");async function L(n,r="SIGTERM"){if(!d(n))return!1;if(process.platform!=="linux")return m(n.run_pid,r),!0;try{return await D(n.run_pid,r,n.anchor_node??void 0),!0}catch(e){if(!d(n))return!1;throw e}}a(L,"stopLeasedCronRun");function _(n,r="SIGTERM"){return d(n)?(L(n,r).catch(e=>{S({level:"error",event:"cron.run.stop_failed",error:e,fields:{cron_id:n.cron_id,pid:n.run_pid}})}),!0):!1}a(_,"killLeasedCronRun");function d(n){const r=n.run_pid;if(r==null||n.run_pid_identity==null)return!1;const e=l([r]);if(e===null)return!1;const t=e.get(r);return t===void 0?!1:R(t,n.run_pid_identity)}a(d,"verifyLeasedCronRun");async function U(n){return await c(async r=>{const e=[];if(n.cancel_on_wake&&n.anchor_node!==null){await r.prepare("SELECT 1 FROM nodes WHERE node_id = ? FOR UPDATE").get(n.anchor_node);const t=(await r.prepare("SELECT * FROM crons WHERE anchor_node = ? AND cancel_on_wake = 1").all(n.anchor_node)).map(s);for(const o of t)o.run_state==="running"&&_(o),await r.prepare("DELETE FROM crons WHERE cron_id = ?").run(o.cron_id),e.push(o.cron_id)}return await y(r,n),{cron_id:n.cron_id,replaced:e}})}a(U,"armCron");async function y(n,r){const e=new Date().toISOString();await n.prepare(`INSERT INTO crons (
1
+ var w=Object.defineProperty;var a=(n,r)=>w(n,"name",{value:r,configurable:!0});import{withCanvasWrite as c,openDb as i}from"./db.js";import{capturePidIdentities as l,identitiesMatch as R,killProcessGroup as m}from"./pid.js";import{isProfilePaused as D}from"../profiles/manifest.js";import{stopAppProcess as S}from"../spaces/process.js";import{emitEvent as N}from"../events/emit.js";import{personId as p}from"./person.js";const h=20;function O(n){if(typeof n!="string")return null;try{const r=JSON.parse(n);return Array.isArray(r)?r.filter(e=>typeof e=="string"):null}catch{return null}}a(O,"scopesFrom");function s(n){return{cron_id:n.cron_id,name:n.name,created_by:n.created_by??null,grantee:n.grantee,sub:n.sub??p(),grant_id:n.grant_id??null,scopes:O(n.scopes_json),origin_run_id:n.origin_run_id??null,run_execution_id:n.run_execution_id??null,armed_from_exec:Number(n.armed_from_exec??0)!==0,isolated:Number(n.isolated)!==0,command:n.command,fire_at:n.fire_at,recur:n.recur??null,tz:n.tz??null,expires_at:n.expires_at??null,anchor_node:n.anchor_node??null,cancel_on_wake:Number(n.cancel_on_wake)!==0,cwd:n.cwd,env_json:n.env_json??null,profile:n.profile??null,scope:n.scope,run_timeout_s:Number(n.run_timeout_s),overlap:n.overlap,on_output:n.on_output,sink:n.sink,tier:n.tier,last_output_hash:n.last_output_hash??null,held:Number(n.held)!==0,last_poke_at:n.last_poke_at??null,state:n.state,run_state:n.run_state,run_pid:n.run_pid??null,run_pid_identity:n.run_pid_identity??null,run_started_at:n.run_started_at??null,run_lease_owner:n.run_lease_owner??null,run_out_of_band:Number(n.run_out_of_band)!==0,created:n.created,updated:n.updated}}a(s,"cronFrom");function E(n){try{const r=JSON.parse(n);if(typeof r.node=="string")return{kind:"node",node:r.node};if(typeof r.spawn=="string")return{kind:"spawn",spawn:r.spawn};if(r.human===!0)return{kind:"human"}}catch{}return null}a(E,"parseCronSink");function F(n){const r=E(n);if(r===null)return null;switch(r.kind){case"node":return`node:${r.node}`;case"spawn":return`spawn:${r.spawn}`;case"human":return"human"}}a(F,"cronSinkDisplay");async function T(n,r="SIGTERM"){if(!d(n))return!1;if(process.platform!=="linux")return m(n.run_pid,r),!0;try{return await S(n.run_pid,r,n.anchor_node??void 0),!0}catch(e){if(!d(n))return!1;throw e}}a(T,"stopLeasedCronRun");function _(n,r="SIGTERM"){return d(n)?(T(n,r).catch(e=>{N({level:"error",event:"cron.run.stop_failed",error:e,fields:{cron_id:n.cron_id,pid:n.run_pid}})}),!0):!1}a(_,"killLeasedCronRun");function d(n){const r=n.run_pid;if(r==null||n.run_pid_identity==null)return!1;const e=l([r]);if(e===null)return!1;const t=e.get(r);return t===void 0?!1:R(t,n.run_pid_identity)}a(d,"verifyLeasedCronRun");async function I(n){return await c(async r=>{const e=[];if(n.cancel_on_wake&&n.anchor_node!==null){await r.prepare("SELECT 1 FROM nodes WHERE node_id = ? FOR UPDATE").get(n.anchor_node);const t=(await r.prepare("SELECT * FROM crons WHERE anchor_node = ? AND cancel_on_wake = 1").all(n.anchor_node)).map(s);for(const o of t)o.run_state==="running"&&_(o),await r.prepare("DELETE FROM crons WHERE cron_id = ?").run(o.cron_id),e.push(o.cron_id)}return await L(r,n),{cron_id:n.cron_id,replaced:e}})}a(I,"armCron");async function L(n,r){const e=new Date().toISOString();await n.prepare(`INSERT INTO crons (
2
2
  cron_id, name, created_by, grantee, sub, grant_id, scopes_json, origin_run_id, isolated, command, fire_at, recur, tz, expires_at,
3
3
  anchor_node, cancel_on_wake, cwd, env_json, profile, scope,
4
4
  run_timeout_s, overlap, on_output, sink, tier, created, updated, armed_from_exec
5
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(r.cron_id,r.name,r.created_by,r.grantee??"app:terminal",r.sub??p(),r.grant_id??null,r.scopes==null?null:JSON.stringify(r.scopes),r.origin_run_id??null,r.isolated?1:0,r.command,r.fire_at,r.recur,r.tz,r.expires_at,r.anchor_node,r.cancel_on_wake?1:0,r.cwd,r.env_json,r.profile,r.scope,r.run_timeout_s,r.overlap,r.on_output,r.sink,r.tier,e,e,r.armed_from_exec?1:0)}a(y,"insertCron");async function M(n){const r=await(await i()).prepare("SELECT * FROM crons WHERE cron_id = ?").get(n);return r===void 0?null:s(r)}a(M,"getCron");async function v(n){const r=await i();let e;return"profile"in n?e=await r.prepare("SELECT * FROM crons WHERE scope = 'profile' AND profile = ? ORDER BY fire_at").all(n.profile):"global"in n?e=await r.prepare("SELECT * FROM crons WHERE scope = 'global' ORDER BY fire_at").all():e=await r.prepare("SELECT * FROM crons ORDER BY fire_at").all(),e.map(s)}a(v,"listCrons");async function I(n,r){return await c(async e=>{const t=await e.prepare("SELECT * FROM crons WHERE cron_id = ?").get(n);if(t===void 0)return!1;const o=s(t);return o.run_state==="running"&&r?.preserveRunningProcess!==!0&&_(o),await e.prepare("DELETE FROM crons WHERE cron_id = ?").run(n),!0})}a(I,"cancelCron");function f(n,r){const e=[...new Set(r)];return e.length===0?{sql:"profile = ?",params:[n]}:{sql:`profile = ? OR anchor_node IN (${e.map(()=>"?").join(",")})`,params:[n,...e]}}a(f,"profileCronWhere");async function P(n,r){const e=f(n,r);return(await(await i()).prepareUncached(`SELECT cron_id FROM crons WHERE ${e.sql} ORDER BY created, cron_id`).all(...e.params)).map(({cron_id:t})=>t)}a(P,"cronIdsForProfileDeletion");async function b(n,r){return await c(async e=>{const t=f(n,r),o=(await e.prepareUncached(`SELECT * FROM crons WHERE ${t.sql} ORDER BY created, cron_id`).all(...t.params)).map(s);for(const u of o)u.run_state==="running"&&_(u);return await e.prepareUncached(`DELETE FROM crons WHERE ${t.sql}`).run(...t.params),o.map(({cron_id:u})=>u)})}a(b,"deleteCronsForProfile");async function B(n){return(await(await i()).prepare("SELECT cron_id FROM crons WHERE profile = ? ORDER BY created, cron_id").all(n)).map(({cron_id:r})=>r)}a(B,"cronIdsForProfileDetach");async function Y(n){return await c(async r=>{const e=(await r.prepare("SELECT cron_id FROM crons WHERE profile = ? ORDER BY created, cron_id").all(n)).map(({cron_id:t})=>t);return e.length>0&&await r.prepare("UPDATE crons SET profile = NULL, scope = 'global', updated = ? WHERE profile = ?").run(new Date().toISOString(),n),e})}a(Y,"globalizeCronsForProfile");async function $(n){return(await(await i()).prepare("DELETE FROM crons WHERE cron_id = ?").run(n)).changes>0}a($,"consumeCron");async function j(n,r){return(await(await i()).prepare("UPDATE crons SET state = ?, updated = ? WHERE cron_id = ?").run(r,new Date().toISOString(),n)).changes>0}a(j,"setCronState");async function q(n,r){await(await i()).prepare("UPDATE crons SET last_output_hash = ?, updated = ? WHERE cron_id = ?").run(r,new Date().toISOString(),n)}a(q,"setCronLastOutputHash");async function z(n){const r=await(await i()).prepare(`SELECT anchor_node, cancel_on_wake, sink
5
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(r.cron_id,r.name,r.created_by,r.grantee??"app:terminal",r.sub??p(),r.grant_id??null,r.scopes==null?null:JSON.stringify(r.scopes),r.origin_run_id??null,r.isolated?1:0,r.command,r.fire_at,r.recur,r.tz,r.expires_at,r.anchor_node,r.cancel_on_wake?1:0,r.cwd,r.env_json,r.profile,r.scope,r.run_timeout_s,r.overlap,r.on_output,r.sink,r.tier,e,e,r.armed_from_exec?1:0)}a(L,"insertCron");async function U(n){const r=await(await i()).prepare("SELECT * FROM crons WHERE cron_id = ?").get(n);return r===void 0?null:s(r)}a(U,"getCron");async function M(n){const r=await i();let e;return"profile"in n?e=await r.prepare("SELECT * FROM crons WHERE scope = 'profile' AND profile = ? ORDER BY fire_at").all(n.profile):"global"in n?e=await r.prepare("SELECT * FROM crons WHERE scope = 'global' ORDER BY fire_at").all():e=await r.prepare("SELECT * FROM crons ORDER BY fire_at").all(),e.map(s)}a(M,"listCrons");async function v(n,r){return await c(async e=>{const t=await e.prepare("SELECT * FROM crons WHERE cron_id = ?").get(n);if(t===void 0)return!1;const o=s(t);return o.run_state==="running"&&r?.preserveRunningProcess!==!0&&_(o),await e.prepare("DELETE FROM crons WHERE cron_id = ?").run(n),!0})}a(v,"cancelCron");function f(n,r){const e=[...new Set(r)];return e.length===0?{sql:"profile = ?",params:[n]}:{sql:`profile = ? OR anchor_node IN (${e.map(()=>"?").join(",")})`,params:[n,...e]}}a(f,"profileCronWhere");async function P(n,r){const e=f(n,r);return(await(await i()).prepareUncached(`SELECT cron_id FROM crons WHERE ${e.sql} ORDER BY created, cron_id`).all(...e.params)).map(({cron_id:t})=>t)}a(P,"cronIdsForProfileDeletion");async function b(n,r){return await c(async e=>{const t=f(n,r),o=(await e.prepareUncached(`SELECT * FROM crons WHERE ${t.sql} ORDER BY created, cron_id`).all(...t.params)).map(s);for(const u of o)u.run_state==="running"&&_(u);return await e.prepareUncached(`DELETE FROM crons WHERE ${t.sql}`).run(...t.params),o.map(({cron_id:u})=>u)})}a(b,"deleteCronsForProfile");async function B(n){return(await(await i()).prepare("SELECT cron_id FROM crons WHERE profile = ? ORDER BY created, cron_id").all(n)).map(({cron_id:r})=>r)}a(B,"cronIdsForProfileDetach");async function Y(n){return await c(async r=>{const e=(await r.prepare("SELECT cron_id FROM crons WHERE profile = ? ORDER BY created, cron_id").all(n)).map(({cron_id:t})=>t);return e.length>0&&await r.prepare("UPDATE crons SET profile = NULL, scope = 'global', updated = ? WHERE profile = ?").run(new Date().toISOString(),n),e})}a(Y,"globalizeCronsForProfile");async function $(n){return(await(await i()).prepare("DELETE FROM crons WHERE cron_id = ?").run(n)).changes>0}a($,"consumeCron");async function j(n,r){return(await(await i()).prepare("UPDATE crons SET state = ?, updated = ? WHERE cron_id = ?").run(r,new Date().toISOString(),n)).changes>0}a(j,"setCronState");async function q(n,r){await(await i()).prepare("UPDATE crons SET last_output_hash = ?, updated = ? WHERE cron_id = ?").run(r,new Date().toISOString(),n)}a(q,"setCronLastOutputHash");async function z(n){const r=await(await i()).prepare(`SELECT anchor_node, cancel_on_wake, sink
6
6
  FROM crons
7
7
  WHERE (anchor_node = ? AND cancel_on_wake = 1 AND state = 'active')
8
8
  OR (
@@ -13,24 +13,26 @@ var w=Object.defineProperty;var a=(n,r)=>w(n,"name",{value:r,configurable:!0});i
13
13
  )
14
14
  )`).all(n,new Date().toISOString());for(const e of r){if(e.anchor_node===n&&Number(e.cancel_on_wake)!==0)return!0;const t=E(e.sink);if(t?.kind==="node"&&t.node===n)return!0}return!1}a(z,"hasPendingCronWake");async function G(n){return await c(async r=>{const e=(await r.prepare("SELECT * FROM crons WHERE anchor_node = ? AND cancel_on_wake = 1").all(n)).map(s);for(const t of e)t.run_state==="running"&&_(t),await r.prepare("DELETE FROM crons WHERE cron_id = ?").run(t.cron_id);return e})}a(G,"cancelCronsOnWake");async function J(n,r){await(await i()).prepare("UPDATE crons SET fire_at = ?, updated = ? WHERE cron_id = ?").run(r,new Date().toISOString(),n)}a(J,"advanceCron");async function V(n){return(await(await i()).prepare(`SELECT * FROM crons
15
15
  WHERE state = 'active' AND run_state = 'idle' AND fire_at <= ?
16
- ORDER BY fire_at, created, cron_id`).all(n)).map(s).filter(r=>!h(r.profile))}a(V,"dueClockCrons");async function K(n,r,e,t,o=null){const u=await(await i()).prepare(`UPDATE crons
16
+ ORDER BY fire_at, created, cron_id`).all(n)).map(s).filter(r=>!D(r.profile))}a(V,"dueClockCrons");async function K(n,r,e,t,o=null){const u=await(await i()).prepare(`UPDATE crons
17
17
  SET run_state = 'running', run_started_at = ?, run_pid = NULL, run_pid_identity = NULL,
18
18
  run_lease_owner = ?, run_out_of_band = ?, run_execution_id = ?, updated = ?
19
19
  WHERE cron_id = ? AND run_state = 'idle'`).run(e,r,t?1:0,o,new Date().toISOString(),n);return Number(u.changes)>0}a(K,"acquireCronRunLease");async function Q(n,r,e,t){const o=l([t])?.get(t)??null,u=await(await i()).prepare(`UPDATE crons SET run_pid = ?, run_pid_identity = ?, updated = ?
20
20
  WHERE cron_id = ? AND run_state = 'running' AND run_lease_owner = ?
21
- AND run_started_at = ? AND run_pid IS NULL`).run(t,o,new Date().toISOString(),n,r,e);return Number(u.changes)>0}a(Q,"attachCronRunPid");async function X(n,r){let e="";const t=[];r!==void 0&&(r.kind==="clear"?e=", held = 0":r.kind==="park"?(e=r.fireAt!==void 0?", held = 1, fire_at = ?":", held = 1",r.fireAt!==void 0&&t.push(r.fireAt)):(e=", held = 0, fire_at = ?",t.push(r.nowIso))),await(await i()).prepareUncached(`UPDATE crons
21
+ AND run_started_at = ? AND run_pid IS NULL`).run(t,o,new Date().toISOString(),n,r,e);return Number(u.changes)>0}a(Q,"attachCronRunPid");async function X(n,r,e){let t="";const o=[];e!==void 0&&(e.kind==="clear"?t=", held = 0":e.kind==="park"?(t=e.fireAt!==void 0?", held = 1, fire_at = ?":", held = 1",e.fireAt!==void 0&&o.push(e.fireAt)):(t=", held = 0, fire_at = ?",o.push(e.nowIso))),await(await i()).prepareUncached(`UPDATE crons
22
22
  SET run_state = 'idle', run_started_at = NULL, run_pid = NULL, run_pid_identity = NULL,
23
- run_lease_owner = NULL, run_out_of_band = 0, run_execution_id = NULL, updated = ?${e}
24
- WHERE cron_id = ?`).run(new Date().toISOString(),...t,n)}a(X,"releaseCronRunLease");async function Z(n,r=null){return await c(async e=>{const t=r===null?"":" AND grantee = ?",o=r===null?[]:[r];await e.prepareUncached(`UPDATE crons SET last_poke_at = ? WHERE 1 = 1${t}`).run(n,...o);const u=await e.prepareUncached(`UPDATE crons SET fire_at = ?, held = 0, updated = ? WHERE held = 1 AND state = 'active' AND run_state = 'idle'${t}`).run(n,n,...o);return Number(u.changes)})}a(Z,"pokeHeldCrons");async function nn(n){return(await(await i()).prepare(`SELECT * FROM crons
23
+ run_lease_owner = NULL, run_out_of_band = 0, run_execution_id = NULL, updated = ?${t}
24
+ WHERE cron_id = ? AND run_execution_id = ?`).run(new Date().toISOString(),...o,n,r)}a(X,"releaseCronRunLease");async function Z(n,r){const e=await(await i()).prepare(`UPDATE crons SET run_execution_id = ?, updated = ?
25
+ WHERE cron_id = ? AND run_state = 'running' AND run_execution_id IS NULL
26
+ AND run_started_at IS NOT DISTINCT FROM ? AND run_lease_owner IS NOT DISTINCT FROM ?`).run(r,new Date().toISOString(),n.cron_id,n.run_started_at,n.run_lease_owner);return Number(e.changes)>0}a(Z,"adoptCronRunId");async function nn(n,r=null){return await c(async e=>{const t=r===null?"":" AND grantee = ?",o=r===null?[]:[r];await e.prepareUncached(`UPDATE crons SET last_poke_at = ? WHERE 1 = 1${t}`).run(n,...o);const u=await e.prepareUncached(`UPDATE crons SET fire_at = ?, held = 0, updated = ? WHERE held = 1 AND state = 'active' AND run_state = 'idle'${t}`).run(n,n,...o);return Number(u.changes)})}a(nn,"pokeHeldCrons");async function rn(n){return(await(await i()).prepare(`SELECT * FROM crons
25
27
  WHERE state = 'active' AND run_state = 'running' AND run_out_of_band = 0
26
28
  AND recur IS NOT NULL AND fire_at <= ?
27
- ORDER BY fire_at, created, cron_id`).all(n)).map(s)}a(nn,"dueOverlapCrons");async function rn(n){return(await(await i()).prepare(`SELECT * FROM crons
29
+ ORDER BY fire_at, created, cron_id`).all(n)).map(s)}a(rn,"dueOverlapCrons");async function en(n){return(await(await i()).prepare(`SELECT * FROM crons
28
30
  WHERE expires_at IS NOT NULL AND expires_at <= ? AND run_state = 'idle'
29
- ORDER BY expires_at`).all(n)).map(s)}a(rn,"expiredIdleCrons");async function en(n){return(await(await i()).prepare("SELECT * FROM cron_runs WHERE cron_id = ? ORDER BY started DESC, run_id DESC").all(n)).map(r=>({run_id:r.run_id,cron_id:r.cron_id,started:r.started,finished:r.finished,duration_ms:Number(r.duration_ms),exit_code:r.exit_code??null,stdout_head:r.stdout_head??null,stderr_head:r.stderr_head??null,delivered:r.delivered??null}))}a(en,"listCronRuns");async function tn(){return(await(await i()).prepare("SELECT * FROM crons WHERE run_state = 'running'").all()).map(s)}a(tn,"runningCrons");async function g(n,r){return await n.prepare("SELECT 1 FROM crons WHERE cron_id = ?").get(r.cron_id)===void 0?!1:(await n.prepare(`INSERT INTO cron_runs (
31
+ ORDER BY expires_at`).all(n)).map(s)}a(en,"expiredIdleCrons");async function tn(n){return(await(await i()).prepare("SELECT * FROM cron_runs WHERE cron_id = ? ORDER BY started DESC, run_id DESC").all(n)).map(r=>({run_id:r.run_id,cron_id:r.cron_id,started:r.started,finished:r.finished,duration_ms:Number(r.duration_ms),exit_code:r.exit_code??null,stdout_head:r.stdout_head??null,stderr_head:r.stderr_head??null,delivered:r.delivered??null}))}a(tn,"listCronRuns");async function an(){return(await(await i()).prepare("SELECT * FROM crons WHERE run_state = 'running'").all()).map(s)}a(an,"runningCrons");async function y(n,r){return await n.prepare("SELECT 1 FROM crons WHERE cron_id = ?").get(r.cron_id)===void 0?!1:(await n.prepare(`INSERT INTO cron_runs (
30
32
  run_id, cron_id, started, finished, duration_ms, exit_code,
31
33
  stdout_head, stderr_head, delivered
32
34
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(r.run_id,r.cron_id,r.started,r.finished,r.duration_ms,r.exit_code,r.stdout_head,r.stderr_head,r.delivered),await n.prepare(`DELETE FROM cron_runs
33
35
  WHERE cron_id = ? AND run_id NOT IN (
34
36
  SELECT run_id FROM cron_runs WHERE cron_id = ?
35
37
  ORDER BY started DESC, run_id DESC LIMIT ?
36
- )`).run(r.cron_id,r.cron_id,N),!0)}a(g,"recordCronRunLocked");async function an(n){return await c(async r=>await g(r,n))}a(an,"recordCronRun");export{N as CRON_RUN_RING,K as acquireCronRunLease,J as advanceCron,U as armCron,Q as attachCronRunPid,I as cancelCron,G as cancelCronsOnWake,$ as consumeCron,P as cronIdsForProfileDeletion,B as cronIdsForProfileDetach,F as cronSinkDisplay,b as deleteCronsForProfile,V as dueClockCrons,nn as dueOverlapCrons,rn as expiredIdleCrons,M as getCron,Y as globalizeCronsForProfile,z as hasPendingCronWake,_ as killLeasedCronRun,en as listCronRuns,v as listCrons,E as parseCronSink,Z as pokeHeldCrons,an as recordCronRun,g as recordCronRunLocked,X as releaseCronRunLease,tn as runningCrons,q as setCronLastOutputHash,j as setCronState,L as stopLeasedCronRun,d as verifyLeasedCronRun};
38
+ )`).run(r.cron_id,r.cron_id,h),!0)}a(y,"recordCronRunLocked");async function on(n){return await c(async r=>await y(r,n))}a(on,"recordCronRun");export{h as CRON_RUN_RING,K as acquireCronRunLease,Z as adoptCronRunId,J as advanceCron,I as armCron,Q as attachCronRunPid,v as cancelCron,G as cancelCronsOnWake,$ as consumeCron,P as cronIdsForProfileDeletion,B as cronIdsForProfileDetach,F as cronSinkDisplay,b as deleteCronsForProfile,V as dueClockCrons,rn as dueOverlapCrons,en as expiredIdleCrons,U as getCron,Y as globalizeCronsForProfile,z as hasPendingCronWake,_ as killLeasedCronRun,tn as listCronRuns,M as listCrons,E as parseCronSink,nn as pokeHeldCrons,on as recordCronRun,y as recordCronRunLocked,X as releaseCronRunLease,an as runningCrons,q as setCronLastOutputHash,j as setCronState,T as stopLeasedCronRun,d as verifyLeasedCronRun};
@@ -131,6 +131,11 @@ export declare function hasSyncedGrants(source: string): Promise<boolean>;
131
131
  * the install's person full local scopes and is not the directory's. Delete it so no
132
132
  * grant exists until grant sync installs the directory's mirror. */
133
133
  export declare function dropLocalGrantMirror(db: CanvasDb): Promise<number>;
134
+ /** Mark rows a build older than C-D2 wrote as computed for their revision. That build computed every column locally in the same
135
+ * write but never set `computed_rev`, so its rows are complete; left NULL they read as no grant until the next successful
136
+ * sync rewrites them, and the terminal grant then refuses every launch (NL-550). A directory-written row with lagging
137
+ * columns has NULL scopes, so it is never matched. Returns the rows changed. */
138
+ export declare function backfillComputedRev(): Promise<number>;
134
139
  /** The directory response is complete; commit it or keep the prior snapshot intact. */
135
140
  /** A directory team the runtime's owner belongs to: `team` is `team:<id>`, `members` are `user:<id>`. */
136
141
  export interface TeamRecord {
@@ -1,4 +1,4 @@
1
- var w=Object.defineProperty;var t=(e,r)=>w(e,"name",{value:r,configurable:!0});import{createHash as N}from"node:crypto";import{parseScope as O}from"@north-light/identity";import{openDb as d,withCanvasWrite as h}from"../canvas/db.js";import{isUnsandboxedMachine as j}from"../runtime/unsandboxed.js";import{replaceWrittenBy as A,userSubject as b}from"../permissions/facts.js";import{GROUP_TYPE as R}from"../permissions/builtin.js";const D=["not_started","pending","ready","failed","unavailable"],k=["ultra","strong","medium","light"];function I(){const e=process.env.CRTR_RUNTIME;return e?{sql:" AND runtime = ?",args:[e]}:{sql:"",args:[]}}t(I,"runtimeScope");async function u(e,r,n=[]){const s=I();return await(await d()).prepare(`SELECT ${e} FROM grants WHERE ${r}${s.sql}`).all(...n,...s.args)}t(u,"grantRows");async function c(e,r,n=[]){return(await u(e,r,n))[0]}t(c,"grantRow");function l(e){if(!Array.isArray(e))throw new TypeError("grant scopes must be a list");return e.map(r=>{if(!r||typeof r!="object"||typeof r.scope!="string"||!["always","ask"].includes(r.mode))throw new TypeError("invalid grant scope entry");return{scope:r.scope,mode:r.mode}})}t(l,"entries");function C(e){if(!e||typeof e!="object"||Array.isArray(e))return null;const{state:r,message:n,next:s,step:a}=e;return typeof r!="string"||!D.includes(r)||n!==void 0&&typeof n!="string"||a!==void 0&&typeof a!="string"||typeof s!="string"||!s?null:{state:r,...n===void 0?{}:{message:n},next:s,...a===void 0?{}:{step:a}}}t(C,"dependencyOf");function m(e){if(!e||typeof e!="object"||Array.isArray(e))return{};const r={};for(const[n,s]of Object.entries(e)){const a=C(s);a&&(r[n]=a)}return r}t(m,"dependenciesOf");function F(e){if(!e||typeof e!="object"||Array.isArray(e))return null;const{base_url:r,rungs:n}=e;if(typeof r!="string"||!r||!n||typeof n!="object"||Array.isArray(n))return null;const s={};for(const a of k){const o=n[a];typeof o=="string"&&o&&(s[a]=o)}return Object.keys(s).length?{base_url:r.replace(/\/+$/,""),rungs:s}:null}t(F,"inferenceEndpointOf");function _(e){if(e.computed_rev!==e.rev||e.scopes_json===null||e.resolved_scopes_json===null)throw new TypeError("grant columns are not computed for this revision");return{id:e.id,runtime:e.runtime,sub:e.sub,grantee:e.grantee,rev:e.rev,scopes:l(JSON.parse(e.scopes_json)),resolved_scopes:l(JSON.parse(e.resolved_scopes_json)),spend_cap:e.spend_cap,expires_at:e.expires_at,status:e.status,revoked_at:e.revoked_at,approved_at:e.approved_at,payer:e.payer,dependencies:m(JSON.parse(e.dependencies_json??"{}")),run_notice_url:e.run_notice_url??null,inference_endpoint:e.inference_endpoint_json?F(JSON.parse(e.inference_endpoint_json)):null,synced_at:e.synced_at??""}}t(_,"record");function p(e){if(!e||e.status!=="active")return null;try{return H(_(e))}catch(r){if(r instanceof TypeError||r instanceof SyntaxError)return null;throw r}}t(p,"active");function g(e){return e.grantee!=="app:terminal"&&j()}t(g,"mirrorOnly");async function Y(){return(await $()).filter(e=>!g(e))}t(Y,"localGrants");const E="[A-Za-z0-9_-]{1,64}",M=new RegExp(`^(${E}):(${E})$`);function L(e){const r=new Set;for(const n of e)if(n.status==="active")for(const{scope:s}of n.resolved_scopes){const a=M.exec(s);a&&a[1]!=="crtr"&&r.add(a[1])}return[...r].sort()}t(L,"providerIdsFromGrants");async function Z(e){const r=await u("*","sub = ? AND status = 'active'",[e]);return new Set(L(r.flatMap(n=>{try{return[_(n)]}catch(s){if(s instanceof TypeError||s instanceof SyntaxError)return[];throw s}})))}t(Z,"grantedProviderIds");function K(e,r){return e.source_marketplace===null&&e.source_path===null&&r.has(e.name)}t(K,"isProviderBundleRow");async function $(){return(await u("*","true")).flatMap(e=>{try{return[_(e)]}catch(r){if(r instanceof TypeError||r instanceof SyntaxError)return[];throw r}})}t($,"allGrants");function G(e){return e.expires_at!==null&&!(Date.parse(e.expires_at)>Date.now())}t(G,"grantExpired");function H(e){if(e.status!=="active"||G(e))return null;try{const r=e.resolved_scopes.map(({scope:n})=>O(n));return{...e,resolved:e.resolved_scopes.flatMap(({mode:n},s)=>n==="always"?[r[s]]:[])}}catch(r){if(r instanceof TypeError||r instanceof SyntaxError)return null;throw r}}t(H,"activeRecord");function v(e){return Array.isArray(e)?`[${e.map(v).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().filter(r=>e[r]!==void 0).map(r=>`${JSON.stringify(r)}:${v(e[r])}`).join(",")}}`:JSON.stringify(e)??"null"}t(v,"canonicalJson");function Q(e){const r={rev:e.rev,resolved_scopes:e.resolved_scopes,spend_cap:e.spend_cap,payer:e.payer,dependencies:e.dependencies??{},...e.inference_endpoint?{inference_endpoint:e.inference_endpoint}:{}};return N("sha256").update(v(r)).digest("base64url").slice(0,22)}t(Q,"grantVersion");async function ee(e){return!!await c("1","id = ?",[e])}t(ee,"hasGrant");async function re(e){return await c("rev, status","id = ?",[e])??null}t(re,"grantSyncState");async function ne(e,r){return await c("rev, status","grantee = ? AND sub = ?",[e,r])??null}t(ne,"grantSyncStateFor");async function U(e){const r=await c("*","id = ?",[e]);if(!r)return null;try{return _(r)}catch(n){if(n instanceof TypeError||n instanceof SyntaxError)return null;throw n}}t(U,"grantRecord");async function te(e){const r=await c("*","id = ?",[e]);if(!r)return{standing:"inactive",sub:null,grantee:null,status:null,removal_done_at:null,record:null};const n={sub:r.sub,grantee:r.grantee,status:r.status,removal_done_at:r.removal_done_at??null};if(r.status!=="active")return{...n,standing:"inactive",record:null};if(r.computed_rev!==r.rev)return{...n,standing:"lagging",record:null};const s=p(r);return s===null?{...n,standing:"inactive",record:null}:{...n,standing:"active",record:s}}t(te,"grantStanding");async function se(e){return(await u("id",e)).map(r=>r.id)}t(se,"grantIdsWhere");async function ae(e){return(e?(await U(e))?.payer:null)??"user"}t(ae,"payerOfGrant");async function W(e){return p(await c("*","id = ?",[e]))}t(W,"activeGrant");async function oe(e,r){return p(await c("*","grantee = ? AND sub = ?",[e,r]))}t(oe,"grantFor");async function ie(e){if(g({grantee:e}))return null;const r=await u("*","grantee = ? AND status = 'active'",[e]);if(r.length>1)throw new Error(`multiple active grants for ${e}`);return p(r[0])}t(ie,"activeGrantForApp");async function ce(e){const r=await W(e);return r&&r.run_notice_url&&!g(r)?{url:r.run_notice_url,sub:r.sub,grantee:r.grantee}:null}t(ce,"runNoticeTarget");async function ue(e){const r=await u("*","grantee = 'app:terminal' AND sub = ? AND status = 'active'",[e]);if(r.length>1)throw new Error(`multiple active terminal grants for ${e}`);return p(r[0])}t(ue,"terminalGrant");async function pe(){return(await(await d()).prepare("SELECT value FROM runtime_state WHERE key = 'grants_source'").get())?.value??null}t(pe,"grantsSource");async function de(e){return(await(await d()).prepare("SELECT value FROM runtime_state WHERE key = 'grants_source'").get())?.value===e}t(de,"hasSyncedGrants");async function le(e){return(await e.prepare("SELECT value FROM runtime_state WHERE key = 'grants_source'").get())?.value!=="local"?0:(await e.prepare("DELETE FROM runtime_state WHERE key = 'grants_source'").run(),Number((await e.prepare("DELETE FROM grants").run()).changes))}t(le,"dropLocalGrantMirror");function _e(e){if(e===void 0)return[];if(!Array.isArray(e))throw new TypeError("invalid grant sync response");return e.map(r=>{const{team:n,members:s}=r??{};if(typeof n!="string"||!/^team:\S+$/.test(n)||!Array.isArray(s)||s.some(a=>typeof a!="string"||!/^user:[^\s*]+$/.test(a)))throw new TypeError("invalid grant sync response");return{team:n,members:s}})}t(_e,"teamsOf");async function fe(e,r,n,s=[]){const a=new Set;for(const o of e){if(a.has(o.id)||!o.id||!o.runtime||!o.sub||!o.grantee||!Number.isInteger(o.rev)||!["active","revoked","removed"].includes(o.status))throw new TypeError("invalid grant sync response");a.add(o.id),l(o.scopes),l(o.resolved_scopes)}await h(async o=>{let f=0;const y=[...a];f+=Number((await(y.length?o.prepareUncached(`DELETE FROM grants WHERE id NOT IN (${y.map(()=>"?").join(",")})`).run(...y):o.prepareUncached("DELETE FROM grants").run())).changes);const x=o.prepare(`INSERT INTO grants
1
+ var w=Object.defineProperty;var t=(e,r)=>w(e,"name",{value:r,configurable:!0});import{createHash as O}from"node:crypto";import{parseScope as h}from"@north-light/identity";import{openDb as d,withCanvasWrite as m}from"../canvas/db.js";import{isUnsandboxedMachine as j}from"../runtime/unsandboxed.js";import{replaceWrittenBy as A,userSubject as b}from"../permissions/facts.js";import{GROUP_TYPE as R}from"../permissions/builtin.js";const D=["not_started","pending","ready","failed","unavailable"],k=["ultra","strong","medium","light"];function I(){const e=process.env.CRTR_RUNTIME;return e?{sql:" AND runtime = ?",args:[e]}:{sql:"",args:[]}}t(I,"runtimeScope");async function u(e,r,n=[]){const s=I();return await(await d()).prepare(`SELECT ${e} FROM grants WHERE ${r}${s.sql}`).all(...n,...s.args)}t(u,"grantRows");async function c(e,r,n=[]){return(await u(e,r,n))[0]}t(c,"grantRow");function l(e){if(!Array.isArray(e))throw new TypeError("grant scopes must be a list");return e.map(r=>{if(!r||typeof r!="object"||typeof r.scope!="string"||!["always","ask"].includes(r.mode))throw new TypeError("invalid grant scope entry");return{scope:r.scope,mode:r.mode}})}t(l,"entries");function L(e){if(!e||typeof e!="object"||Array.isArray(e))return null;const{state:r,message:n,next:s,step:a}=e;return typeof r!="string"||!D.includes(r)||n!==void 0&&typeof n!="string"||a!==void 0&&typeof a!="string"||typeof s!="string"||!s?null:{state:r,...n===void 0?{}:{message:n},next:s,...a===void 0?{}:{step:a}}}t(L,"dependencyOf");function E(e){if(!e||typeof e!="object"||Array.isArray(e))return{};const r={};for(const[n,s]of Object.entries(e)){const a=L(s);a&&(r[n]=a)}return r}t(E,"dependenciesOf");function C(e){if(!e||typeof e!="object"||Array.isArray(e))return null;const{base_url:r,rungs:n}=e;if(typeof r!="string"||!r||!n||typeof n!="object"||Array.isArray(n))return null;const s={};for(const a of k){const o=n[a];typeof o=="string"&&o&&(s[a]=o)}return Object.keys(s).length?{base_url:r.replace(/\/+$/,""),rungs:s}:null}t(C,"inferenceEndpointOf");function _(e){if(e.computed_rev!==e.rev||e.scopes_json===null||e.resolved_scopes_json===null)throw new TypeError("grant columns are not computed for this revision");return{id:e.id,runtime:e.runtime,sub:e.sub,grantee:e.grantee,rev:e.rev,scopes:l(JSON.parse(e.scopes_json)),resolved_scopes:l(JSON.parse(e.resolved_scopes_json)),spend_cap:e.spend_cap,expires_at:e.expires_at,status:e.status,revoked_at:e.revoked_at,approved_at:e.approved_at,payer:e.payer,dependencies:E(JSON.parse(e.dependencies_json??"{}")),run_notice_url:e.run_notice_url??null,inference_endpoint:e.inference_endpoint_json?C(JSON.parse(e.inference_endpoint_json)):null,synced_at:e.synced_at??""}}t(_,"record");function p(e){if(!e||e.status!=="active")return null;try{return G(_(e))}catch(r){if(r instanceof TypeError||r instanceof SyntaxError)return null;throw r}}t(p,"active");function g(e){return e.grantee!=="app:terminal"&&j()}t(g,"mirrorOnly");async function Y(){return(await U()).filter(e=>!g(e))}t(Y,"localGrants");const x="[A-Za-z0-9_-]{1,64}",F=new RegExp(`^(${x}):(${x})$`);function M(e){const r=new Set;for(const n of e)if(n.status==="active")for(const{scope:s}of n.resolved_scopes){const a=F.exec(s);a&&a[1]!=="crtr"&&r.add(a[1])}return[...r].sort()}t(M,"providerIdsFromGrants");async function Z(e){const r=await u("*","sub = ? AND status = 'active'",[e]);return new Set(M(r.flatMap(n=>{try{return[_(n)]}catch(s){if(s instanceof TypeError||s instanceof SyntaxError)return[];throw s}})))}t(Z,"grantedProviderIds");function K(e,r){return e.source_marketplace===null&&e.source_path===null&&r.has(e.name)}t(K,"isProviderBundleRow");async function U(){return(await u("*","true")).flatMap(e=>{try{return[_(e)]}catch(r){if(r instanceof TypeError||r instanceof SyntaxError)return[];throw r}})}t(U,"allGrants");function $(e){return e.expires_at!==null&&!(Date.parse(e.expires_at)>Date.now())}t($,"grantExpired");function G(e){if(e.status!=="active"||$(e))return null;try{const r=e.resolved_scopes.map(({scope:n})=>h(n));return{...e,resolved:e.resolved_scopes.flatMap(({mode:n},s)=>n==="always"?[r[s]]:[])}}catch(r){if(r instanceof TypeError||r instanceof SyntaxError)return null;throw r}}t(G,"activeRecord");function v(e){return Array.isArray(e)?`[${e.map(v).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().filter(r=>e[r]!==void 0).map(r=>`${JSON.stringify(r)}:${v(e[r])}`).join(",")}}`:JSON.stringify(e)??"null"}t(v,"canonicalJson");function Q(e){const r={rev:e.rev,resolved_scopes:e.resolved_scopes,spend_cap:e.spend_cap,payer:e.payer,dependencies:e.dependencies??{},...e.inference_endpoint?{inference_endpoint:e.inference_endpoint}:{}};return O("sha256").update(v(r)).digest("base64url").slice(0,22)}t(Q,"grantVersion");async function ee(e){return!!await c("1","id = ?",[e])}t(ee,"hasGrant");async function re(e){return await c("rev, status","id = ?",[e])??null}t(re,"grantSyncState");async function ne(e,r){return await c("rev, status","grantee = ? AND sub = ?",[e,r])??null}t(ne,"grantSyncStateFor");async function H(e){const r=await c("*","id = ?",[e]);if(!r)return null;try{return _(r)}catch(n){if(n instanceof TypeError||n instanceof SyntaxError)return null;throw n}}t(H,"grantRecord");async function te(e){const r=await c("*","id = ?",[e]);if(!r)return{standing:"inactive",sub:null,grantee:null,status:null,removal_done_at:null,record:null};const n={sub:r.sub,grantee:r.grantee,status:r.status,removal_done_at:r.removal_done_at??null};if(r.status!=="active")return{...n,standing:"inactive",record:null};if(r.computed_rev!==r.rev)return{...n,standing:"lagging",record:null};const s=p(r);return s===null?{...n,standing:"inactive",record:null}:{...n,standing:"active",record:s}}t(te,"grantStanding");async function se(e){return(await u("id",e)).map(r=>r.id)}t(se,"grantIdsWhere");async function ae(e){return(e?(await H(e))?.payer:null)??"user"}t(ae,"payerOfGrant");async function W(e){return p(await c("*","id = ?",[e]))}t(W,"activeGrant");async function oe(e,r){return p(await c("*","grantee = ? AND sub = ?",[e,r]))}t(oe,"grantFor");async function ie(e){if(g({grantee:e}))return null;const r=await u("*","grantee = ? AND status = 'active'",[e]);if(r.length>1)throw new Error(`multiple active grants for ${e}`);return p(r[0])}t(ie,"activeGrantForApp");async function ce(e){const r=await W(e);return r&&r.run_notice_url&&!g(r)?{url:r.run_notice_url,sub:r.sub,grantee:r.grantee}:null}t(ce,"runNoticeTarget");async function ue(e){const r=await u("*","grantee = 'app:terminal' AND sub = ? AND status = 'active'",[e]);if(r.length>1)throw new Error(`multiple active terminal grants for ${e}`);return p(r[0])}t(ue,"terminalGrant");async function pe(){return(await(await d()).prepare("SELECT value FROM runtime_state WHERE key = 'grants_source'").get())?.value??null}t(pe,"grantsSource");async function de(e){return(await(await d()).prepare("SELECT value FROM runtime_state WHERE key = 'grants_source'").get())?.value===e}t(de,"hasSyncedGrants");async function le(e){return(await e.prepare("SELECT value FROM runtime_state WHERE key = 'grants_source'").get())?.value!=="local"?0:(await e.prepare("DELETE FROM runtime_state WHERE key = 'grants_source'").run(),Number((await e.prepare("DELETE FROM grants").run()).changes))}t(le,"dropLocalGrantMirror");async function _e(){return await m(async e=>Number((await e.prepare("UPDATE grants SET computed_rev = rev WHERE computed_rev IS NULL AND scopes_json IS NOT NULL AND resolved_scopes_json IS NOT NULL").run()).changes))}t(_e,"backfillComputedRev");function fe(e){if(e===void 0)return[];if(!Array.isArray(e))throw new TypeError("invalid grant sync response");return e.map(r=>{const{team:n,members:s}=r??{};if(typeof n!="string"||!/^team:\S+$/.test(n)||!Array.isArray(s)||s.some(a=>typeof a!="string"||!/^user:[^\s*]+$/.test(a)))throw new TypeError("invalid grant sync response");return{team:n,members:s}})}t(fe,"teamsOf");async function ye(e,r,n,s=[]){const a=new Set;for(const o of e){if(a.has(o.id)||!o.id||!o.runtime||!o.sub||!o.grantee||!Number.isInteger(o.rev)||!["active","revoked","removed"].includes(o.status))throw new TypeError("invalid grant sync response");a.add(o.id),l(o.scopes),l(o.resolved_scopes)}await m(async o=>{let f=0;const y=[...a];f+=Number((await(y.length?o.prepareUncached(`DELETE FROM grants WHERE id NOT IN (${y.map(()=>"?").join(",")})`).run(...y):o.prepareUncached("DELETE FROM grants").run())).changes);const S=o.prepare(`INSERT INTO grants
2
2
  (id, runtime, sub, grantee, rev, scopes_json, resolved_scopes_json, spend_cap, expires_at,
3
3
  status, revoked_at, approved_at, payer, dependencies_json, run_notice_url, inference_endpoint_json, synced_at, computed_rev)
4
4
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
@@ -13,4 +13,4 @@ var w=Object.defineProperty;var t=(e,r)=>w(e,"name",{value:r,configurable:!0});i
13
13
  grants.run_notice_url, grants.inference_endpoint_json, grants.computed_rev)
14
14
  IS DISTINCT FROM (excluded.runtime, excluded.sub, excluded.grantee, excluded.rev, excluded.scopes_json, excluded.resolved_scopes_json,
15
15
  excluded.spend_cap, excluded.expires_at, excluded.status, excluded.revoked_at, excluded.approved_at, excluded.payer,
16
- excluded.dependencies_json, excluded.run_notice_url, excluded.inference_endpoint_json, excluded.computed_rev)`);for(const i of e)f+=Number((await x.run(i.id,i.runtime,i.sub,i.grantee,i.rev,JSON.stringify(i.scopes),JSON.stringify(i.resolved_scopes),i.spend_cap,i.expires_at,i.status,i.revoked_at,i.approved_at,i.payer,JSON.stringify(m(i.dependencies)),i.run_notice_url??null,i.inference_endpoint?JSON.stringify(i.inference_endpoint):null,i.synced_at,i.rev)).changes);await A(o,"directory",R,"member",s.flatMap(({team:i,members:S})=>S.map(T=>({resourceId:i,subject:b(T)})))),await o.prepare("INSERT INTO runtime_state (key, value) VALUES ('grants_source', ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value").run(n),f>0&&await o.prepare("INSERT INTO runtime_state (key, value) VALUES ('grants_generation', '1') ON CONFLICT(key) DO UPDATE SET value = CAST(CAST(runtime_state.value AS INTEGER) + 1 AS TEXT)").run()})}t(fe,"replaceGrants");async function ye(){const e=await(await d()).prepare("SELECT value FROM runtime_state WHERE key = 'grants_generation'").get();return e?Number(e.value):0}t(ye,"grantsGeneration");export{W as activeGrant,ie as activeGrantForApp,H as activeRecord,$ as allGrants,m as dependenciesOf,le as dropLocalGrantMirror,G as grantExpired,oe as grantFor,se as grantIdsWhere,U as grantRecord,te as grantStanding,re as grantSyncState,ne as grantSyncStateFor,Q as grantVersion,Z as grantedProviderIds,ye as grantsGeneration,pe as grantsSource,ee as hasGrant,de as hasSyncedGrants,F as inferenceEndpointOf,K as isProviderBundleRow,Y as localGrants,g as mirrorOnly,ae as payerOfGrant,L as providerIdsFromGrants,fe as replaceGrants,ce as runNoticeTarget,_e as teamsOf,ue as terminalGrant};
16
+ excluded.dependencies_json, excluded.run_notice_url, excluded.inference_endpoint_json, excluded.computed_rev)`);for(const i of e)f+=Number((await S.run(i.id,i.runtime,i.sub,i.grantee,i.rev,JSON.stringify(i.scopes),JSON.stringify(i.resolved_scopes),i.spend_cap,i.expires_at,i.status,i.revoked_at,i.approved_at,i.payer,JSON.stringify(E(i.dependencies)),i.run_notice_url??null,i.inference_endpoint?JSON.stringify(i.inference_endpoint):null,i.synced_at,i.rev)).changes);await A(o,"directory",R,"member",s.flatMap(({team:i,members:T})=>T.map(N=>({resourceId:i,subject:b(N)})))),await o.prepare("INSERT INTO runtime_state (key, value) VALUES ('grants_source', ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value").run(n),f>0&&await o.prepare("INSERT INTO runtime_state (key, value) VALUES ('grants_generation', '1') ON CONFLICT(key) DO UPDATE SET value = CAST(CAST(runtime_state.value AS INTEGER) + 1 AS TEXT)").run()})}t(ye,"replaceGrants");async function ge(){const e=await(await d()).prepare("SELECT value FROM runtime_state WHERE key = 'grants_generation'").get();return e?Number(e.value):0}t(ge,"grantsGeneration");export{W as activeGrant,ie as activeGrantForApp,G as activeRecord,U as allGrants,_e as backfillComputedRev,E as dependenciesOf,le as dropLocalGrantMirror,$ as grantExpired,oe as grantFor,se as grantIdsWhere,H as grantRecord,te as grantStanding,re as grantSyncState,ne as grantSyncStateFor,Q as grantVersion,Z as grantedProviderIds,ge as grantsGeneration,pe as grantsSource,ee as hasGrant,de as hasSyncedGrants,C as inferenceEndpointOf,K as isProviderBundleRow,Y as localGrants,g as mirrorOnly,ae as payerOfGrant,M as providerIdsFromGrants,ye as replaceGrants,ce as runNoticeTarget,fe as teamsOf,ue as terminalGrant};
@@ -1 +1 @@
1
- var b=Object.defineProperty;var a=(t,e)=>b(t,"name",{value:e,configurable:!0});function d(t){return typeof t=="string"?t:""}a(d,"text");function n(t,e,o={}){return{kind:t,matchedOn:e,...o}}a(n,"signal");function i(t,e){return e.matchedOn==="text"?{...t,textKind:e.kind,textMatch:e.match,textMatches:e.textMatches}:t}a(i,"withTextMatch");const h=[["rate-limit",/rate.?limit|\b429\b|too many requests|usage[ _]limit|usage_not_included|usagelimiterror|insufficient_quota|quota exceeded/i],["protocol",/\b413\b|payload too large|entity too large|request too large|entity\.too\.large|body exceeds/i],["auth",/invalid_grant|refresh token|unauthori[sz]ed|invalid.?api.?key|authentication failed|\b401\b|\b403\b/i],["context-overflow",/context overflow recovery failed/i],["protocol",/websocket.*(?:closed.*\b(?:1002|1003|1007|1008|1009|1010)\b|protocol error|policy violation|unsupported data|invalid (?:frame|payload)|message too big|mandatory extension)/i],["overloaded-only",/lock file is already being held/i],["overloaded",/overloaded|temporarily unavailable/i],["service-unavailable",/service.?unavailable/i],["overloaded-only",/internal server error|api.?error|\b5\d\d\b|capacity|server.{0,3}busy/i],["connection",/connection|econnreset|etimedout|enotfound|econnrefused|network|fetch failed|socket hang|timed? out|timeout|websocket\s+(?:was\s+)?closed|websocket stream closed before response\.completed|websocket\s+error|websocket.*interrupt/i],["socket",/socket/i],["connection-only",/eai_again|epipe|ehostunreach|enetunreach|\bterminated\b|other side closed|premature close/i]];function f(t){const e=h.flatMap(([c,r])=>{const s=t.match(r);return s?[{kind:c,match:s[0]}]:[]}),o=e[0];return o===void 0?n("other","none"):{...n(o.kind,"text",{match:o.match}),textMatches:e}}a(f,"recognizeText");function E(t){const e=t.retryAfterMs,o=f(t.message??""),c=d(t.code)||d(t.errno);if(/^(ECONNREFUSED|ECONNRESET|ETIMEDOUT|ENOENT|ENOTFOUND|EAI_AGAIN|EPIPE|EHOSTUNREACH|ENETUNREACH)$/i.test(c))return i(n("connection","errno",{retryAfterMs:e}),o);if(/^ELOCKED$/i.test(c))return i(n("overloaded","errno",{retryAfterMs:e}),o);const r=typeof t.status=="number"?t.status:void 0;if(r!==void 0){if(r===401||r===403)return i(n("auth","status",{status:r,retryAfterMs:e}),o);if(r===429)return i(n("rate-limit","status",{status:r,retryAfterMs:e}),o);if(r===500||r===502||r===503||r===504)return i(n("transient-http","status",{status:r,retryAfterMs:e}),o);if(r>=500&&r<=599)return i(n("overloaded","status",{status:r,retryAfterMs:e}),o);if(r>=400&&r<=499)return i(n("protocol","status",{status:r,retryAfterMs:e}),o)}const s=typeof t.wsCloseCode=="number"?t.wsCloseCode:void 0;if(s===1008)return i(n("protocol","websocket-close",{retryAfterMs:e}),o);if(s===1006)return i(n("connection","websocket-close",{retryAfterMs:e}),o);if(s===1011){const l=d(t.wsCloseReason),u=f(l);return/no running broker/i.test(l)||u.kind==="connection"||u.kind==="connection-only"?i(n("connection","websocket-close",{retryAfterMs:e}),o):i(n("other","websocket-close",{retryAfterMs:e}),o)}return e===void 0?o:{...o,retryAfterMs:e}}a(E,"recognizeProviderError");export{E as recognizeProviderError};
1
+ var b=Object.defineProperty;var a=(t,e)=>b(t,"name",{value:e,configurable:!0});function d(t){return typeof t=="string"?t:""}a(d,"text");function n(t,e,o={}){return{kind:t,matchedOn:e,...o}}a(n,"signal");function i(t,e){return e.matchedOn==="text"?{...t,textKind:e.kind,textMatch:e.match,textMatches:e.textMatches}:t}a(i,"withTextMatch");const h=[["protocol",/workspace api usage limits?/i],["rate-limit",/rate.?limit|\b429\b|too many requests|usage[ _]limit|usage_not_included|usagelimiterror|insufficient_quota|quota exceeded/i],["protocol",/\b413\b|payload too large|entity too large|request too large|entity\.too\.large|body exceeds/i],["auth",/invalid_grant|refresh token|unauthori[sz]ed|invalid.?api.?key|authentication failed|\b401\b|\b403\b/i],["context-overflow",/context overflow recovery failed/i],["protocol",/websocket.*(?:closed.*\b(?:1002|1003|1007|1008|1009|1010)\b|protocol error|policy violation|unsupported data|invalid (?:frame|payload)|message too big|mandatory extension)/i],["overloaded-only",/lock file is already being held/i],["overloaded",/overloaded|temporarily unavailable/i],["service-unavailable",/service.?unavailable/i],["overloaded-only",/internal server error|api.?error|\b5\d\d\b|capacity|server.{0,3}busy/i],["connection",/connection|econnreset|etimedout|enotfound|econnrefused|network|fetch failed|socket hang|timed? out|timeout|websocket\s+(?:was\s+)?closed|websocket stream closed before response\.completed|websocket\s+error|websocket.*interrupt/i],["socket",/socket/i],["connection-only",/eai_again|epipe|ehostunreach|enetunreach|\bterminated\b|other side closed|premature close/i]];function f(t){const e=h.flatMap(([c,r])=>{const s=t.match(r);return s?[{kind:c,match:s[0]}]:[]}),o=e[0];return o===void 0?n("other","none"):{...n(o.kind,"text",{match:o.match}),textMatches:e}}a(f,"recognizeText");function E(t){const e=t.retryAfterMs,o=f(t.message??""),c=d(t.code)||d(t.errno);if(/^(ECONNREFUSED|ECONNRESET|ETIMEDOUT|ENOENT|ENOTFOUND|EAI_AGAIN|EPIPE|EHOSTUNREACH|ENETUNREACH)$/i.test(c))return i(n("connection","errno",{retryAfterMs:e}),o);if(/^ELOCKED$/i.test(c))return i(n("overloaded","errno",{retryAfterMs:e}),o);const r=typeof t.status=="number"?t.status:void 0;if(r!==void 0){if(r===401||r===403)return i(n("auth","status",{status:r,retryAfterMs:e}),o);if(r===429)return i(n("rate-limit","status",{status:r,retryAfterMs:e}),o);if(r===500||r===502||r===503||r===504)return i(n("transient-http","status",{status:r,retryAfterMs:e}),o);if(r>=500&&r<=599)return i(n("overloaded","status",{status:r,retryAfterMs:e}),o);if(r>=400&&r<=499)return i(n("protocol","status",{status:r,retryAfterMs:e}),o)}const s=typeof t.wsCloseCode=="number"?t.wsCloseCode:void 0;if(s===1008)return i(n("protocol","websocket-close",{retryAfterMs:e}),o);if(s===1006)return i(n("connection","websocket-close",{retryAfterMs:e}),o);if(s===1011){const l=d(t.wsCloseReason),u=f(l);return/no running broker/i.test(l)||u.kind==="connection"||u.kind==="connection-only"?i(n("connection","websocket-close",{retryAfterMs:e}),o):i(n("other","websocket-close",{retryAfterMs:e}),o)}return e===void 0?o:{...o,retryAfterMs:e}}a(E,"recognizeProviderError");export{E as recognizeProviderError};