@xenosystem/agent-sdk 0.9.27 → 0.9.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/THIRD_PARTY_NOTICES.md +89 -0
  2. package/dist/artifacts/index.cjs +6 -6
  3. package/dist/artifacts/index.js +6 -6
  4. package/dist/artifacts/metafile-cjs.json +1 -1
  5. package/dist/artifacts/metafile-esm.json +1 -1
  6. package/dist/automation/index.cjs +1 -1
  7. package/dist/automation/index.js +1 -1
  8. package/dist/automation/metafile-cjs.json +1 -1
  9. package/dist/automation/metafile-esm.json +1 -1
  10. package/dist/control-plane/index.cjs +7 -7
  11. package/dist/control-plane/index.js +7 -7
  12. package/dist/control-plane/metafile-cjs.json +1 -1
  13. package/dist/control-plane/metafile-esm.json +1 -1
  14. package/dist/control-room/index.cjs +1 -1
  15. package/dist/control-room/index.d.cts +2 -1
  16. package/dist/control-room/index.d.ts +2 -1
  17. package/dist/control-room/index.js +1 -1
  18. package/dist/control-room/metafile-cjs.json +1 -1
  19. package/dist/control-room/metafile-esm.json +1 -1
  20. package/dist/coordination/index.cjs +2 -2
  21. package/dist/coordination/index.d.cts +70 -4
  22. package/dist/coordination/index.d.ts +70 -4
  23. package/dist/coordination/index.js +2 -2
  24. package/dist/coordination/metafile-cjs.json +1 -1
  25. package/dist/coordination/metafile-esm.json +1 -1
  26. package/dist/electron/index.cjs +151 -151
  27. package/dist/electron/index.d.cts +81 -0
  28. package/dist/electron/index.d.ts +81 -0
  29. package/dist/electron/index.js +153 -153
  30. package/dist/electron/metafile-cjs.json +1 -1
  31. package/dist/electron/metafile-esm.json +1 -1
  32. package/dist/hosted/metafile-cjs.json +1 -1
  33. package/dist/hosted/metafile-esm.json +1 -1
  34. package/dist/index.cjs +334 -334
  35. package/dist/index.d.cts +541 -364
  36. package/dist/index.d.ts +541 -364
  37. package/dist/index.js +331 -331
  38. package/dist/metafile-cjs.json +1 -1
  39. package/dist/metafile-esm.json +1 -1
  40. package/dist/providers/index.cjs +10 -10
  41. package/dist/providers/index.d.cts +15 -1
  42. package/dist/providers/index.d.ts +15 -1
  43. package/dist/providers/index.js +10 -10
  44. package/dist/providers/metafile-cjs.json +1 -1
  45. package/dist/providers/metafile-esm.json +1 -1
  46. package/dist/recipes/index.cjs +1 -1
  47. package/dist/recipes/index.js +2 -2
  48. package/dist/recipes/metafile-cjs.json +1 -1
  49. package/dist/recipes/metafile-esm.json +1 -1
  50. package/dist/research/metafile-cjs.json +1 -1
  51. package/dist/research/metafile-esm.json +1 -1
  52. package/dist/session/index.cjs +24 -24
  53. package/dist/session/index.d.cts +49 -1
  54. package/dist/session/index.d.ts +49 -1
  55. package/dist/session/index.js +24 -24
  56. package/dist/session/metafile-cjs.json +1 -1
  57. package/dist/session/metafile-esm.json +1 -1
  58. package/package.json +2 -1
@@ -1,2 +1,2 @@
1
- "use strict";var $=Object.create;var C=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var U=Object.getOwnPropertyNames;var j=Object.getPrototypeOf,J=Object.prototype.hasOwnProperty;var B=(d,t)=>{for(var s in t)C(d,s,{get:t[s],enumerable:!0})},M=(d,t,s,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of U(t))!J.call(d,e)&&e!==s&&C(d,e,{get:()=>t[e],enumerable:!(r=q(t,e))||r.enumerable});return d};var x=(d,t,s)=>(s=d!=null?$(j(d)):{},M(t||!d||!d.__esModule?C(s,"default",{value:d,enumerable:!0}):s,d)),W=d=>M(C({},"__esModule",{value:!0}),d);var ie={};B(ie,{DurableXenoCoordinationStore:()=>b,XENO_COORDINATION_MANAGED_SESSION_SCHEMA_VERSION:()=>k,XENO_COORDINATION_SCHEMA_VERSION:()=>I,XenoCoordinationError:()=>l,XenoExecutionLeaseSession:()=>G,executeXenoCoordinationAction:()=>se});module.exports=W(ie);var I=1,k=2,l=class extends Error{constructor(s,r,e={}){super(r);this.code=s;this.details=e;this.name="XenoCoordinationError"}code;details};var y=require("node:crypto"),f=x(require("node:fs/promises"),1),A=x(require("node:os"),1),m=x(require("node:path"),1);var v=require("node:os");var T=require("node:path"),ce=(0,v.platform)();var le=(0,v.release)(),ue=(0,v.homedir)();function _(){let d=process.env.XENO_AGENT_HOME?.trim();return d?(0,T.resolve)(d):(0,T.resolve)((0,v.homedir)(),".xeno-agent")}var K=3e4,Q=3e4,Y=6e4,z=2e4,N=new Set(["EACCES","EBUSY","EPERM"]),D=[5,10,20,40,80,160,320],Z=[5,10,20,40,80,160,320];function p(d,t,s=16384){let r=d.trim();if(!r||r.length>s)throw new l("INVALID",`${t} must be non-empty and no longer than ${s} characters`);return r}function L(d,t){return[...new Set((d??[]).map(s=>p(s,t)))]}function ee(d){if(!d)return;let t={};for(let[s,r]of Object.entries(d))if(r!==void 0){if(!Number.isSafeInteger(r)||r<=0)throw new l("INVALID",`${s} must be a positive safe integer when provided`);t[s]=r}return t}function te(d){if(d){if(d.kind!=="fixed-interval"&&d.kind!=="dynamic")throw new l("INVALID","schedule.kind must be fixed-interval or dynamic");if(d.kind==="fixed-interval"&&(!Number.isSafeInteger(d.intervalMs)||(d.intervalMs??0)<=0))throw new l("INVALID","Fixed-interval schedules require a positive safe intervalMs");if(d.intervalMs!==void 0&&(!Number.isSafeInteger(d.intervalMs)||d.intervalMs<=0))throw new l("INVALID","schedule.intervalMs must be a positive safe integer when provided");for(let t of["nextRunAt","expiresAt"]){let s=d[t];if(s!==void 0&&!Number.isFinite(Date.parse(s)))throw new l("INVALID",`schedule.${t} must be an ISO timestamp when provided`)}return w(d)}}function w(d){return structuredClone(d)}function X(d){let t=Date.parse(d);return Number.isFinite(t)?t:0}function R(d){if(!Number.isInteger(d)||d<=0)return!1;try{return process.kill(d,0),!0}catch(t){return t.code==="EPERM"}}function ne(d){return{summary:"Goal created; work has not started.",completedTaskCount:0,totalTaskCount:0,outstanding:[],decisions:[],updatedAt:d}}function oe(){return{status:"pending",criteria:[],evidence:[]}}function re(d){return(0,y.createHash)("sha256").update(d).digest("hex")}var b=class{rootDirectory;now;idFactory;ownerLeaseMs;lockTimeoutMs;lockStaleMs;maximumEventsPerSession;constructor(t={}){this.rootDirectory=t.rootDirectory??m.join(_(),"coordination"),this.now=t.now??(()=>new Date().toISOString()),this.idFactory=t.idFactory??(s=>`${s}_${(0,y.randomUUID)()}`),this.ownerLeaseMs=t.ownerLeaseMs??K,this.lockTimeoutMs=t.lockTimeoutMs??Q,this.lockStaleMs=t.lockStaleMs??Y,this.maximumEventsPerSession=t.maximumEventsPerSession??z}async getSessionState(t){let s=p(t,"sessionId",1024);return w(await this.readState(s))}async fenceAdmission(t,s,r){let e=p(r.authorityId,"authorityId",512),n=p(r.operationId,"operationId",512);if(!Number.isSafeInteger(s)||s<0)throw new l("INVALID","Expected session version must be a nonnegative safe integer");if(r.action!=="archive"&&r.action!=="delete")throw new l("INVALID","Unsupported admission fence action");return this.mutate(t,o=>{let i=o.admissionFence;if(i?.authorityId===e&&i.operationId===n&&i.action===r.action)return i;if(o.version!==s)throw new l("CONFLICT","Session version changed before lifecycle fencing",{expected:s,actual:o.version});if(i?.authorityId===e&&i.action==="archive"&&r.action==="archive")return i;if(i&&!(i.authorityId===e&&i.action==="archive"&&r.action==="delete"))throw new l("CONFLICT","Another lifecycle fence already owns this session");let a={schemaVersion:1,authorityId:e,operationId:n,action:r.action,createdAt:this.now()};return o.admissionFence=a,o.schemaVersion=2,this.appendEvent(o,"admission.fenced",{data:{authorityId:e,operationId:n,action:r.action}}),a},!0)}async clearAdmissionFence(t,s,r,e){await this.mutate(t,n=>{this.assertVersion(t,n.version,s);let o=n.admissionFence;if(!o||o.authorityId!==r||o.operationId!==e)throw new l("CONFLICT","Lifecycle fence identity does not match");if(o.action==="delete")throw new l("CONFLICT","Deleted session admission cannot be restored");if(n.owner)throw new l("CONFLICT","Execution ownership must settle before restoration");n.admissionFence=void 0,this.appendEvent(n,"admission.restored",{data:{authorityId:r,operationId:e}})},!0)}async releaseDeadLifecycleOwner(t,s,r,e){await this.mutate(t,n=>{this.assertVersion(t,n.version,s);let o=n.admissionFence;if(!o||o.authorityId!==r||o.operationId!==e)throw new l("CONFLICT","Lifecycle fence identity does not match");let i=n.owner;if(i){if(i.host!==A.hostname()||!Number.isInteger(i.processId)||(i.processId??0)<=0||R(i.processId))throw new l("CONFLICT","Execution owner exit has not been proved");n.owner=void 0,this.appendEvent(n,"ownership.released",{ownerId:i.ownerId,data:{epoch:i.epoch,reason:"fenced-local-owner-exited"}})}},!0)}async listSessionStates(){let t=m.join(this.rootDirectory,"sessions"),s;try{s=await f.readdir(t)}catch(e){if(e.code==="ENOENT")return[];throw e}return(await Promise.all(s.filter(e=>e.endsWith(".json")).map(async e=>{try{let n=JSON.parse(await f.readFile(m.join(t,e),"utf8"));return![1,2].includes(n.schemaVersion)||typeof n.sessionId!="string"?void 0:((!Number.isSafeInteger(n.ownershipEpoch)||n.ownershipEpoch<0)&&(n.ownershipEpoch=Math.max(n.owner?.epoch??0,...n.handoffs.map(o=>o.targetLeaseEpoch??o.sourceLeaseEpoch??0))),n)}catch{return}}))).filter(e=>e!==void 0).sort((e,n)=>X(n.updatedAt)-X(e.updatedAt)).map(e=>w(e))}async createGoal(t){let s=p(t.sessionId,"sessionId",1024),r=ee(t.limits);return this.mutate(s,e=>{let n=e.goals.find(c=>["active","paused","waiting","blocked"].includes(c.status));if(n)throw new l("CONFLICT",`Session ${s} already has active goal ${n.id}`);let o=this.now(),i=(t.successCriteria??[]).map(c=>typeof c=="string"?{id:this.idFactory("criterion"),description:p(c,"successCriteria"),required:!0}:{id:c.id?p(c.id,"successCriteria.id",512):this.idFactory("criterion"),description:p(c.description,"successCriteria.description"),required:c.required}),a={schemaVersion:1,id:this.idFactory("goal"),version:1,sessionId:s,objective:p(t.objective,"objective"),...t.why?{why:p(t.why,"why")}:{},successCriteria:i,constraints:L(t.constraints,"constraints"),...r?{limits:r}:{},metadata:w(t.metadata??{}),status:"active",milestones:[],tasks:[],progress:ne(o),verification:oe(),steering:[],createdAt:o,updatedAt:o};return e.goals.push(a),this.appendEvent(e,"goal.created",{goalId:a.id,data:{objective:a.objective}}),a})}async getGoal(t,s){let r=await this.getSessionState(t),e=s?r.goals.find(n=>n.id===s):[...r.goals].reverse().find(n=>["active","paused","waiting","blocked"].includes(n.status));return e?w(e):void 0}async updateGoal(t,s,r,e){return this.mutate(t,n=>{let o=this.requireGoal(n,s);if(this.assertVersion(o.id,o.version,r),["completed","cancelled","failed"].includes(o.status))throw new l("CONFLICT",`Goal ${o.id} is terminal (${o.status})`);return e.status==="active"&&o.status==="blocked"?o.status="active":e.status&&(o.status=e.status),e.objective!==void 0&&(o.objective=p(e.objective,"objective")),e.why!==void 0&&(o.why=p(e.why,"why")),e.constraints&&(o.constraints=L(e.constraints,"constraints")),e.successCriteria&&(o.successCriteria=w(e.successCriteria)),e.progress&&(o.progress={...o.progress,...w(e.progress),outstanding:L(e.progress.outstanding??o.progress.outstanding,"progress.outstanding"),decisions:L(e.progress.decisions??o.progress.decisions,"progress.decisions"),updatedAt:this.now()}),e.verification&&(o.verification=w(e.verification)),e.metadata&&(o.metadata=w(e.metadata)),o.version+=1,o.updatedAt=this.now(),this.appendEvent(n,"goal.updated",{goalId:o.id,data:{status:o.status,version:o.version}}),o},e.status!==void 0&&["paused","cancelled","failed"].includes(e.status))}async addMilestone(t,s,r,e){return this.mutateGoal(t,s,r,(n,o)=>{let i={id:this.idFactory("milestone"),title:p(e.title,"milestone.title"),...e.description?{description:p(e.description,"milestone.description")}:{},status:n.milestones.some(a=>a.status==="active")?"pending":"active",taskIds:[],createdAt:o,updatedAt:o};n.milestones.push(i),n.progress.currentMilestoneId??=i.id,n.progress.updatedAt=o})}async addTask(t,s,r,e){return this.mutateGoal(t,s,r,(n,o)=>{let i=n.milestones.find(u=>u.id===e.milestoneId);if(!i)throw new l("NOT_FOUND",`Milestone ${e.milestoneId} was not found`);if(e.parentTaskId&&!n.tasks.some(u=>u.id===e.parentTaskId))throw new l("NOT_FOUND",`Parent task ${e.parentTaskId} was not found`);let a=[...new Set(e.dependsOn??[])];for(let u of a)if(!n.tasks.some(g=>g.id===u))throw new l("NOT_FOUND",`Task dependency ${u} was not found`);let c={id:this.idFactory("task"),milestoneId:i.id,...e.parentTaskId?{parentTaskId:e.parentTaskId}:{},title:p(e.title,"task.title"),...e.description?{description:p(e.description,"task.description")}:{},status:a.length===0?"ready":"pending",...e.assignedAgentId?{assignedAgentId:p(e.assignedAgentId,"task.assignedAgentId",512)}:{},...a.length?{dependsOn:a}:{},createdAt:o,updatedAt:o};n.tasks.push(c),i.taskIds.push(c.id),i.updatedAt=o,n.progress.totalTaskCount=n.tasks.length,n.progress.outstanding=n.tasks.filter(u=>u.status!=="completed").map(u=>u.title),n.progress.updatedAt=o})}async updateTask(t,s,r,e,n){return this.mutateGoal(t,s,e,(o,i)=>{let a=o.tasks.find(u=>u.id===r);if(!a)throw new l("NOT_FOUND",`Task ${r} was not found`);a.status=n.status,n.progress!==void 0&&(a.progress=p(n.progress,"task.progress")),n.resultEventId!==void 0&&(a.resultEventId=p(n.resultEventId,"task.resultEventId",512)),n.assignedAgentId!==void 0&&(a.assignedAgentId=p(n.assignedAgentId,"task.assignedAgentId",512)),a.updatedAt=i,a.status==="completed"&&(a.completedAt=i);let c=o.milestones.find(u=>u.id===a.milestoneId);if(c){let u=o.tasks.filter(g=>g.milestoneId===c.id);u.length>0&&u.every(g=>g.status==="completed")?(c.status="completed",c.completedAt=i):u.some(g=>g.status==="running")?c.status="active":u.some(g=>g.status==="blocked")&&(c.status="blocked"),c.updatedAt=i}for(let u of o.tasks)u.status!=="pending"||!u.dependsOn?.length||u.dependsOn.every(g=>o.tasks.find(O=>O.id===g)?.status==="completed")&&(u.status="ready",u.updatedAt=i);this.recalculateProgress(o,i)})}async steerGoal(t,s,r,e){return this.mutateGoal(t,s,r,(n,o,i)=>{let a=this.idFactory("steer");n.steering.push({id:a,instruction:p(e,"instruction"),createdAt:o}),this.appendEvent(i,"goal.steered",{goalId:s,data:{steeringId:a}})},!1)}async consumeGoalSteering(t,s,r){let e=[];return{goal:await this.mutateGoal(t,s,r,(o,i)=>{e=o.steering.filter(a=>!a.consumedAt).map(({id:a,instruction:c,createdAt:u})=>({id:a,instruction:c,createdAt:u}));for(let a of o.steering)a.consumedAt||(a.consumedAt=i)}),instructions:e}}async completeGoal(t,s,r,e){if(e.status!=="passed")throw new l("VERIFICATION_REQUIRED","Goal completion requires passed verification");return this.mutate(t,n=>{let o=this.requireGoal(n,s);this.assertVersion(o.id,o.version,r);let i=o.successCriteria.filter(u=>u.required),a=i.filter(u=>{let g=e.criteria.find(O=>O.criterionId===u.id);return!g?.satisfied||g.evidence.length===0});if(a.length>0)throw new l("VERIFICATION_REQUIRED","Required success criteria lack passing evidence",{unmetCriteria:a.map(u=>u.id)});if(i.length===0&&e.evidence.length===0)throw new l("VERIFICATION_REQUIRED","Goal completion requires at least one durable evidence reference");let c=this.now();return o.status="completed",o.verification=w(e),o.verification.verifiedAt??=c,o.completedAt=c,o.updatedAt=c,o.version+=1,this.appendEvent(n,"goal.completed",{goalId:s,data:{evidence:o.verification.evidence}}),o},!0)}async cancelGoal(t,s,r,e){return this.mutate(t,n=>{let o=this.requireGoal(n,s);if(this.assertVersion(o.id,o.version,r),["completed","cancelled","failed"].includes(o.status))return o;o.status="cancelled",o.updatedAt=this.now(),o.version+=1,this.appendEvent(n,"goal.cancelled",{goalId:s,data:{reason:p(e,"reason")}});for(let i of n.loops.filter(a=>a.goalId===s&&["running","paused","waiting"].includes(a.status)))i.status="stopped",i.stopReason=`Goal cancelled: ${e}`,i.stoppedAt=this.now(),i.updatedAt=i.stoppedAt,i.version+=1;return o},!0)}async startLoop(t){return this.mutate(t.sessionId,s=>{if(t.kind==="goal-continuation"&&!t.goalId)throw new l("INVALID","Goal-continuation loops require a goalId");if(t.goalId){let i=this.requireGoal(s,t.goalId);if(["completed","cancelled","failed"].includes(i.status))throw new l("CONFLICT",`Cannot start a loop for terminal goal ${i.id}`)}if(t.kind==="scheduled"&&!t.schedule)throw new l("INVALID","Scheduled loops require schedule metadata");if(t.kind!=="scheduled"&&t.schedule)throw new l("INVALID","Only scheduled loops may carry schedule metadata");let r=te(t.schedule),e=s.loops.find(i=>i.goalId===t.goalId&&i.kind===t.kind&&["running","paused","waiting"].includes(i.status));if(e)throw new l("CONFLICT",`Loop ${e.id} is already active`);let n=this.now(),o={schemaVersion:1,id:this.idFactory("loop"),version:1,sessionId:s.sessionId,...t.goalId?{goalId:t.goalId}:{},kind:t.kind,status:"running",...t.activity?{currentActivity:p(t.activity,"activity")}:{},iterations:[],...r?{schedule:r}:{},createdAt:n,updatedAt:n};return s.loops.push(o),this.appendEvent(s,"loop.started",{loopId:o.id,goalId:o.goalId,data:{kind:o.kind}}),o})}async getLoop(t,s){let r=await this.getSessionState(t),e=s?r.loops.find(n=>n.id===s):[...r.loops].reverse().find(n=>["running","paused","waiting"].includes(n.status));return e?w(e):void 0}async beginLoopIteration(t,s,r,e,n){return this.mutateLoop(t,s,r,(o,i,a)=>{if(o.status!=="running")throw new l("CONFLICT",`Loop ${o.id} is ${o.status}`);if(o.iterations.some(u=>u.status==="running"))throw new l("CONFLICT",`Loop ${o.id} already has a running iteration`);let c=(o.iterations.at(-1)?.number??0)+1;o.currentActivity=p(e,"activity"),o.iterations.push({number:c,startedAt:i,status:"running",activity:o.currentActivity,...n?{taskId:p(n,"taskId",512)}:{}}),this.appendEvent(a,"loop.iteration",{loopId:s,goalId:o.goalId,data:{number:c,phase:"started",activity:o.currentActivity}})},!1)}async finishLoopIteration(t,s,r,e){return this.mutateLoop(t,s,r,(n,o,i)=>{let a=[...n.iterations].reverse().find(c=>c.status==="running");if(!a)throw new l("CONFLICT",`Loop ${n.id} has no running iteration`);a.status=e.status,a.completedAt=o,e.verificationEventId&&(a.verificationEventId=p(e.verificationEventId,"verificationEventId",512)),e.error&&(a.error=p(e.error,"error")),n.status=i.admissionFence?"paused":e.nextStatus??(n.status==="paused"||n.status==="waiting"?n.status:"running"),this.appendEvent(i,"loop.iteration",{loopId:s,goalId:n.goalId,data:{number:a.number,phase:"finished",status:e.status}})},!1,!0)}async setLoopStatus(t,s,r,e,n){return this.mutateLoop(t,s,r,(o,i,a)=>{let c=o.status;if(["stopped","completed","failed"].includes(c))throw new l("CONFLICT",`Loop ${o.id} is terminal (${c})`);let u=[...o.iterations].reverse().find(O=>O.status==="running");if(u&&e==="completed")throw new l("CONFLICT",`Loop ${o.id} cannot complete while iteration ${u.number} is running`);u&&(e==="stopped"||e==="failed")&&(u.status=e==="failed"?"failed":"interrupted",u.completedAt=i,u.error=p(n??e,"reason")),o.status=e,["stopped","completed","failed"].includes(e)&&(o.stoppedAt=i,o.stopReason=p(n??e,"reason"));let g=e==="paused"?"loop.paused":e==="waiting"?"loop.waiting":e==="running"&&(c==="paused"||c==="waiting")?"loop.resumed":e==="completed"?"loop.completed":e==="failed"?"loop.failed":"loop.stopped";this.appendEvent(a,g,{loopId:s,goalId:o.goalId,data:{previous:c,status:e,...n?{reason:n}:{}}})},!1,e!=="running"&&e!=="waiting")}async acquireOwnership(t,s,r={}){return this.mutate(t,e=>{let n=this.now();if(e.owner&&!this.ownerExpired(e.owner,n)){if(e.owner.ownerId===s&&r.processId!==void 0&&e.owner.processId===r.processId&&(r.host===void 0||e.owner.host===r.host))return e.owner;throw new l("CONFLICT",`Session ${t} is owned by ${e.owner.ownerId}`,{owner:e.owner})}let o=e.owner&&this.ownerExpired(e.owner,n)?e.owner:void 0;if(o&&o.ownerId!==s)for(let c of e.handoffs.filter(u=>u.status==="claimed"&&u.claimedBy===o.ownerId))c.status="failed",c.failureReason=`Claimed owner ${o.ownerId} lost its execution lease before completing the handoff.`,c.failedAt=n,c.updatedAt=n,c.version+=1,this.appendEvent(e,"handoff.failed",{handoffId:c.id,goalId:c.goalId,loopId:c.loopId,data:{reason:c.failureReason,expiredLeaseId:o.leaseId}});let i=e.ownershipEpoch+1,a=this.newOwner(s,i,r,n);return e.owner=a,e.ownershipEpoch=i,this.appendEvent(e,"ownership.acquired",{ownerId:s,data:{epoch:i,leaseId:a.leaseId}}),a})}async renewOwnership(t,s,r,e=this.ownerLeaseMs){return this.mutate(t,n=>{let o=this.requireOwner(n,s,r);if(this.ownerExpired(o,this.now()))throw new l("LEASE_EXPIRED",`Ownership lease ${r} expired`);return o.heartbeatAt=this.now(),o.expiresAt=new Date(X(o.heartbeatAt)+e).toISOString(),this.appendEvent(n,"ownership.renewed",{ownerId:s,data:{epoch:o.epoch,leaseId:r}}),o})}async releaseOwnership(t,s,r){return this.mutate(t,e=>{let n=this.requireOwner(e,s,r);return e.owner=void 0,this.appendEvent(e,"ownership.released",{ownerId:s,data:{epoch:n.epoch}}),n},!0)}async createHandoff(t){return this.mutate(t.sessionId,s=>{let r=this.requireOwner(s,t.sourceOwnerId,t.sourceLeaseId);if(this.ownerExpired(r,this.now()))throw new l("LEASE_EXPIRED",`Ownership lease ${r.leaseId} expired`);let e=(t.operations??[]).filter(a=>a.status==="running"&&a.sideEffecting&&a.recovery==="retry");if(e.length>0)throw new l("UNSAFE_HANDOFF","Running side-effecting operations cannot be transferred with automatic retry",{operationIds:e.map(a=>a.operationId)});if(t.goalId&&this.requireGoal(s,t.goalId),t.loopId&&!s.loops.some(a=>a.id===t.loopId))throw new l("NOT_FOUND",`Loop ${t.loopId} was not found`);let n=s.handoffs.find(a=>["prepared","available","claimed"].includes(a.status));if(n)throw new l("CONFLICT",`Handoff ${n.id} is already active`);let o=this.now(),i={schemaVersion:1,id:this.idFactory("handoff"),version:1,sessionId:s.sessionId,...t.goalId?{goalId:t.goalId}:{},...t.loopId?{loopId:t.loopId}:{},status:"available",sourceOwnerId:r.ownerId,...t.targetOwnerId?{targetOwnerId:p(t.targetOwnerId,"targetOwnerId",512)}:{},sourceLeaseEpoch:r.epoch,...t.workspace?{workspace:p(t.workspace,"workspace",32768)}:{},...t.branch?{branch:p(t.branch,"branch",1024)}:{},...t.currentMilestoneId?{currentMilestoneId:t.currentMilestoneId}:{},...t.currentTaskId?{currentTaskId:t.currentTaskId}:{},agentIds:[...new Set(t.agentIds??[])],operations:w(t.operations??[]),...t.contextDigest?{contextDigest:p(t.contextDigest,"contextDigest",512)}:{},createdAt:o,updatedAt:o};return s.handoffs.push(i),this.appendEvent(s,"handoff.created",{handoffId:i.id,goalId:i.goalId,loopId:i.loopId,ownerId:r.ownerId,data:{targetOwnerId:i.targetOwnerId}}),i})}async claimHandoff(t){let s;return{handoff:await this.mutate(t.sessionId,e=>{let n=e.handoffs.find(a=>a.id===t.handoffId);if(!n)throw new l("NOT_FOUND",`Handoff ${t.handoffId} was not found`);if(n.status!=="available")throw new l("CONFLICT",`Handoff ${n.id} is ${n.status}`,{claimedBy:n.claimedBy});if(n.targetOwnerId&&n.targetOwnerId!==t.targetOwnerId)throw new l("CONFLICT",`Handoff ${n.id} is reserved for ${n.targetOwnerId}`);let o=e.owner;if(!o||o.ownerId!==n.sourceOwnerId||o.epoch!==n.sourceLeaseEpoch)throw new l("CONFLICT",`Handoff ${n.id} no longer matches the source ownership epoch`);let i=this.now();return s=this.newOwner(t.targetOwnerId,o.epoch+1,{processId:t.processId,host:t.host},i),e.owner=s,e.ownershipEpoch=s.epoch,n.status="claimed",n.claimedBy=t.targetOwnerId,n.targetOwnerId=t.targetOwnerId,n.targetLeaseEpoch=s.epoch,n.claimedAt=i,n.updatedAt=i,n.version+=1,this.appendEvent(e,"handoff.claimed",{handoffId:n.id,goalId:n.goalId,loopId:n.loopId,ownerId:t.targetOwnerId,data:{sourceOwnerId:n.sourceOwnerId,epoch:s.epoch}}),n}),owner:w(s)}}async completeHandoff(t,s,r,e){return this.mutate(t,n=>{this.requireOwner(n,r,e);let o=n.handoffs.find(i=>i.id===s);if(!o)throw new l("NOT_FOUND",`Handoff ${s} was not found`);if(o.status!=="claimed"||o.claimedBy!==r)throw new l("CONFLICT",`Handoff ${o.id} cannot be completed by ${r}`);return o.status="completed",o.completedAt=this.now(),o.updatedAt=o.completedAt,o.version+=1,this.appendEvent(n,"handoff.completed",{handoffId:s,goalId:o.goalId,loopId:o.loopId,ownerId:r,data:{epoch:n.owner?.epoch}}),o})}async failHandoff(t,s,r){return this.mutate(t,e=>{let n=e.handoffs.find(o=>o.id===s);if(!n)throw new l("NOT_FOUND",`Handoff ${s} was not found`);return["completed","cancelled","failed"].includes(n.status)||(n.status="failed",n.failureReason=p(r,"reason"),n.failedAt=this.now(),n.updatedAt=n.failedAt,n.version+=1,this.appendEvent(e,"handoff.failed",{handoffId:s,goalId:n.goalId,loopId:n.loopId,data:{reason:n.failureReason}})),n},!0)}async mutateGoal(t,s,r,e,n=!0){return this.mutate(t,o=>{let i=this.requireGoal(o,s);this.assertVersion(i.id,i.version,r);let a=this.now();return e(i,a,o),i.version+=1,i.updatedAt=a,n&&this.appendEvent(o,"goal.updated",{goalId:s,data:{status:i.status,version:i.version}}),i})}async mutateLoop(t,s,r,e,n=!0,o=!1){return this.mutate(t,i=>{let a=i.loops.find(u=>u.id===s);if(!a)throw new l("NOT_FOUND",`Loop ${s} was not found`);this.assertVersion(a.id,a.version,r);let c=this.now();return e(a,c,i),a.version+=1,a.updatedAt=c,n&&this.appendEvent(i,"loop.iteration",{loopId:s,goalId:a.goalId,data:{status:a.status,version:a.version}}),a},o)}recalculateProgress(t,s){let r=t.tasks.filter(e=>e.status==="completed").length;t.progress.completedTaskCount=r,t.progress.totalTaskCount=t.tasks.length,t.progress.percent=t.tasks.length?Math.round(r/t.tasks.length*100):void 0,t.progress.outstanding=t.tasks.filter(e=>!["completed","cancelled"].includes(e.status)).map(e=>e.title),t.progress.updatedAt=s}requireGoal(t,s){let r=t.goals.find(e=>e.id===s);if(!r)throw new l("NOT_FOUND",`Goal ${s} was not found`);return r}requireOwner(t,s,r){let e=t.owner;if(!e||e.ownerId!==s||e.leaseId!==r)throw new l("NOT_OWNER",`${s} does not own session ${t.sessionId}`,{owner:e});return e}assertVersion(t,s,r){if(!Number.isInteger(r)||r<1||s!==r)throw new l("CONFLICT",`Expected ${t} version ${r}, found ${s}`,{expected:r,actual:s})}newOwner(t,s,r,e){let n=r.leaseMs??this.ownerLeaseMs;if(!Number.isSafeInteger(n)||n<1)throw new l("INVALID","leaseMs must be a positive safe integer");return{ownerId:p(t,"ownerId",512),leaseId:this.idFactory("owner"),epoch:s,acquiredAt:e,heartbeatAt:e,expiresAt:new Date(X(e)+n).toISOString(),...r.processId!==void 0?{processId:r.processId}:{},...r.host?{host:p(r.host,"host",512)}:{}}}ownerExpired(t,s){return X(t.expiresAt)<=X(s)?!0:t.processId!==void 0&&t.host===A.hostname()&&!R(t.processId)}appendEvent(t,s,r){let e={schemaVersion:1,id:this.idFactory("event"),sequence:(t.events.at(-1)?.sequence??0)+1,type:s,sessionId:t.sessionId,...r.goalId?{goalId:r.goalId}:{},...r.loopId?{loopId:r.loopId}:{},...r.handoffId?{handoffId:r.handoffId}:{},...r.ownerId?{ownerId:r.ownerId}:{},timestamp:this.now(),data:w(r.data)};t.events.push(e),t.events.length>this.maximumEventsPerSession&&t.events.splice(0,t.events.length-this.maximumEventsPerSession)}async mutate(t,s,r=!1){let e=p(t,"sessionId",1024);return this.withSessionLock(e,async()=>{let n=await this.readState(e);if(n.admissionFence&&!r)throw new l("CONFLICT","Session execution is blocked by a persisted lifecycle fence");let o=s(n);return n.version+=1,n.updatedAt=this.now(),await this.writeState(n),w(o)})}statePath(t){return m.join(this.rootDirectory,"sessions",`${re(t)}.json`)}lockPath(t){return`${this.statePath(t)}.lock`}async readState(t){let s=this.statePath(t);try{let r=await f.readFile(s,"utf8"),e=JSON.parse(r);if(![1,2].includes(e.schemaVersion)||e.sessionId!==t)throw new l("INVALID",`Coordination state at ${s} does not match session ${t}`);if(e.admissionFence!==void 0){let n=e.admissionFence;if(!n||n.schemaVersion!==1||typeof n.authorityId!="string"||!n.authorityId.trim()||typeof n.operationId!="string"||!n.operationId.trim()||!["archive","delete"].includes(n.action)||!Number.isFinite(Date.parse(n.createdAt)))throw new l("INVALID","Persisted lifecycle fence is corrupt; execution remains unavailable")}return(!Number.isSafeInteger(e.ownershipEpoch)||e.ownershipEpoch<0)&&(e.ownershipEpoch=Math.max(e.owner?.epoch??0,...e.handoffs.map(n=>n.targetLeaseEpoch??n.sourceLeaseEpoch??0))),e}catch(r){if(r.code!=="ENOENT")throw r;let e=this.now();return{schemaVersion:1,sessionId:t,version:0,ownershipEpoch:0,goals:[],loops:[],handoffs:[],events:[],createdAt:e,updatedAt:e}}}async writeState(t){let s=this.statePath(t.sessionId),r=m.dirname(s);await f.mkdir(r,{recursive:!0});let e=`${s}.${process.pid}.${(0,y.randomUUID)()}.tmp`,n=await f.open(e,"wx");try{await n.writeFile(`${JSON.stringify(t,null,2)}
2
- `,"utf8"),await n.sync()}finally{await n.close()}try{await this.renameReplacing(e,s);try{let o=await f.open(r,"r");try{await o.sync()}finally{await o.close()}}catch{}}finally{await f.unlink(e).catch(()=>{})}}async renameReplacing(t,s){for(let r=0;;r+=1)try{await f.rename(t,s);return}catch(e){let n=e.code,o=D[r];if(process.platform!=="win32"||!n||!N.has(n)||o===void 0)throw e;await new Promise(i=>setTimeout(i,o))}}async withSessionLock(t,s){let r=this.lockPath(t),e=m.join(r,"owner.json"),n=(0,y.randomUUID)(),o=`${r}.candidate.${n}`,i=Date.now();await f.mkdir(m.dirname(r),{recursive:!0});let a={schemaVersion:1,token:n,pid:process.pid,host:A.hostname(),acquiredAt:this.now()};await f.mkdir(o),await f.writeFile(m.join(o,"owner.json"),JSON.stringify(a),{encoding:"utf8",flag:"wx"});for(let c=0;;c+=1)try{await f.rename(o,r);break}catch(u){let g=u.code;if(!(g==="EEXIST"||process.platform==="win32"&&!!g&&N.has(g)))throw await f.rm(o,{recursive:!0,force:!0}).catch(()=>{}),u;let F=await this.staleLockOwner(r,e);if(F){await this.quarantineLock(r,F.token,"stale");continue}if(Date.now()-i>=this.lockTimeoutMs)throw await f.rm(o,{recursive:!0,force:!0}).catch(()=>{}),new l("CONFLICT",`Timed out waiting for coordination lock for session ${t}`);await new Promise(V=>setTimeout(V,Math.min(100,5+c*5)+Math.floor(Math.random()*10)))}try{return await s()}finally{await this.quarantineLock(r,n,"released"),await f.rm(o,{recursive:!0,force:!0}).catch(()=>{})}}async staleLockOwner(t,s){try{let[r,e]=await Promise.all([f.readFile(s,"utf8").catch(()=>""),f.stat(t)]),n=r?JSON.parse(r):void 0;return!n||n.host===A.hostname()&&R(n.pid)?void 0:Date.now()-e.mtimeMs>this.lockStaleMs?n:void 0}catch{return}}async quarantineLock(t,s,r){let e=m.join(t,"owner.json"),n=`${t}.${r}.${s}.${(0,y.randomUUID)()}`;for(let o=0;;o+=1){let i;try{i=JSON.parse(await f.readFile(e,"utf8"))}catch(a){if(a.code==="ENOENT")return;throw a}if(i.token!==s)return;try{await f.rename(t,n);break}catch(a){let c=a.code;if(c==="ENOENT"||c==="EEXIST")return;let u=D[o];if(process.platform!=="win32"||!c||!N.has(c)||u===void 0)throw a;await new Promise(g=>setTimeout(g,u))}}for(let o=0;;o+=1)try{await f.rm(n,{recursive:!0});return}catch(i){let a=i.code;if(a==="ENOENT")return;let c=Z[o];if(process.platform!=="win32"||!a||!N.has(a)||c===void 0)throw i;await new Promise(u=>setTimeout(u,c))}}};function S(d,t){if(!d||typeof d!="object"||Array.isArray(d))throw new Error(`${t} must be an object`);return d}function h(d,t){if(typeof d!="string"||!d.trim())throw new Error(`${t} must be a non-empty string`);return d}function E(d,t){if(typeof d!="number"||!Number.isInteger(d))throw new Error(`${t} must be an integer`);return d}async function se(d,t){let{action:s,sessionId:r}=t,e=t.payload??{},n;switch(s){case"state.get":n=await d.getSessionState(r);break;case"goal.create":n=await d.createGoal({sessionId:r,...e});break;case"goal.update":n=await d.updateGoal(r,h(e.goalId,"goalId"),E(e.expectedVersion,"expectedVersion"),S(e.update,"update"));break;case"goal.complete":n=await d.completeGoal(r,h(e.goalId,"goalId"),E(e.expectedVersion,"expectedVersion"),S(e.verification,"verification"));break;case"goal.cancel":n=await d.cancelGoal(r,h(e.goalId,"goalId"),E(e.expectedVersion,"expectedVersion"),h(e.reason,"reason"));break;case"goal.steer":n=await d.steerGoal(r,h(e.goalId,"goalId"),E(e.expectedVersion,"expectedVersion"),h(e.instruction,"instruction"));break;case"loop.start":n=await d.startLoop({sessionId:r,kind:h(e.kind,"kind"),...typeof e.goalId=="string"?{goalId:e.goalId}:{},...typeof e.activity=="string"?{activity:e.activity}:{},...e.schedule?{schedule:S(e.schedule,"schedule")}:{}});break;case"loop.get":n=await d.getLoop(r,typeof e.loopId=="string"?e.loopId:void 0);break;case"loop.begin":n=await d.beginLoopIteration(r,h(e.loopId,"loopId"),E(e.expectedVersion,"expectedVersion"),h(e.activity,"activity"),typeof e.taskId=="string"?e.taskId:void 0);break;case"loop.finish":n=await d.finishLoopIteration(r,h(e.loopId,"loopId"),E(e.expectedVersion,"expectedVersion"),S(e.result,"result"));break;case"loop.set_status":n=await d.setLoopStatus(r,h(e.loopId,"loopId"),E(e.expectedVersion,"expectedVersion"),h(e.status,"status"),typeof e.reason=="string"?e.reason:void 0);break;case"ownership.acquire":n=await d.acquireOwnership(r,h(e.ownerId,"ownerId"),S(e.options??{},"options"));break;case"ownership.renew":n=await d.renewOwnership(r,h(e.ownerId,"ownerId"),h(e.leaseId,"leaseId"),typeof e.leaseMs=="number"?e.leaseMs:void 0);break;case"ownership.release":n=await d.releaseOwnership(r,h(e.ownerId,"ownerId"),h(e.leaseId,"leaseId"));break;case"handoff.create":n=await d.createHandoff({sessionId:r,...e});break;case"handoff.claim":n=await d.claimHandoff({sessionId:r,handoffId:h(e.handoffId,"handoffId"),targetOwnerId:h(e.targetOwnerId,"targetOwnerId"),...typeof e.processId=="number"?{processId:e.processId}:{},...typeof e.host=="string"?{host:e.host}:{}});break;case"handoff.complete":n=await d.completeHandoff(r,h(e.handoffId,"handoffId"),h(e.ownerId,"ownerId"),h(e.leaseId,"leaseId"));break;case"handoff.fail":n=await d.failHandoff(r,h(e.handoffId,"handoffId"),h(e.reason,"reason"));break}let o=await d.getSessionState(r),i=s==="state.get"||s==="loop.get"?void 0:o.events.at(-1);return{action:s,sessionId:r,result:n,state:o,...i?{event:i}:{}}}var P=require("node:crypto"),H=require("node:os");var G=class{sessionId;ownerId;store;processId;host;leaseMs;heartbeatMs;claimHandoffId;onOwnershipLost;timer;heartbeatInFlight=!1;owner;stopped=!1;lostError;preparedHandoffId;constructor(t){if(this.store=t.store??new b,this.sessionId=t.sessionId,this.processId=t.processId??process.pid,this.host=t.host??(0,H.hostname)(),this.ownerId=t.ownerId??`runtime:${this.host}:${this.processId}:${(0,P.randomUUID)().slice(0,8)}`,this.leaseMs=t.leaseMs??3e4,this.heartbeatMs=t.heartbeatMs??Math.max(250,Math.floor(this.leaseMs/3)),this.heartbeatMs>=this.leaseMs)throw new Error("heartbeatMs must be shorter than leaseMs");this.claimHandoffId=t.claimHandoffId,this.onOwnershipLost=t.onOwnershipLost}get currentOwner(){return this.owner?structuredClone(this.owner):void 0}get active(){return!!this.owner&&!this.stopped&&this.lostError===void 0}async start(){if(this.owner)return structuredClone(this.owner);if(this.stopped)throw new Error("Execution lease session has already stopped");if(this.claimHandoffId){let t=await this.store.claimHandoff({sessionId:this.sessionId,handoffId:this.claimHandoffId,targetOwnerId:this.ownerId,processId:this.processId,host:this.host});this.owner=t.owner,await this.store.completeHandoff(this.sessionId,this.claimHandoffId,this.ownerId,this.owner.leaseId)}else this.owner=await this.store.acquireOwnership(this.sessionId,this.ownerId,{processId:this.processId,host:this.host,leaseMs:this.leaseMs});return this.timer=setInterval(()=>{this.heartbeat()},this.heartbeatMs),this.timer.unref?.(),structuredClone(this.owner)}async assertOwned(){if(this.stopped)throw new Error("Execution surface is detached");if(this.lostError)throw this.lostError;if(this.preparedHandoffId)throw new Error(`Execution surface prepared handoff ${this.preparedHandoffId} and is detached from mutation`);if(!this.owner)throw new Error("Execution ownership was not started");return this.renewHeldLease()}async renewHeldLease(){if(!this.owner)throw new Error("Execution ownership was not started");try{return this.owner=await this.store.renewOwnership(this.sessionId,this.ownerId,this.owner.leaseId,this.leaseMs),structuredClone(this.owner)}catch(t){throw this.markLost(t),t}}async prepareHandoff(t={}){if(this.preparedHandoffId)throw new Error(`Handoff ${this.preparedHandoffId} is already prepared`);let s=await this.assertOwned(),r=await this.store.createHandoff({...t,sessionId:this.sessionId,sourceOwnerId:s.ownerId,sourceLeaseId:s.leaseId});return this.preparedHandoffId=r.id,r}async stop(t={}){if(this.stopped)return;this.stopped=!0,this.timer&&clearInterval(this.timer),this.timer=void 0;let s=this.owner;if(this.owner=void 0,!(t.release===!1||this.preparedHandoffId||!s||this.lostError))try{await this.store.releaseOwnership(this.sessionId,s.ownerId,s.leaseId)}catch{}}async heartbeat(){if(!(!this.active||this.heartbeatInFlight)){this.heartbeatInFlight=!0;try{await this.renewHeldLease()}catch(t){this.markLost(t)}finally{this.heartbeatInFlight=!1}}}markLost(t){this.lostError===void 0&&(this.lostError=t,this.timer&&clearInterval(this.timer),this.timer=void 0,this.onOwnershipLost?.(t))}};0&&(module.exports={DurableXenoCoordinationStore,XENO_COORDINATION_MANAGED_SESSION_SCHEMA_VERSION,XENO_COORDINATION_SCHEMA_VERSION,XenoCoordinationError,XenoExecutionLeaseSession,executeXenoCoordinationAction});
1
+ "use strict";var j=Object.create;var N=Object.defineProperty;var W=Object.getOwnPropertyDescriptor;var J=Object.getOwnPropertyNames;var K=Object.getPrototypeOf,z=Object.prototype.hasOwnProperty;var Q=(c,t)=>{for(var o in t)N(c,o,{get:t[o],enumerable:!0})},F=(c,t,o,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of J(t))!z.call(c,e)&&e!==o&&N(c,e,{get:()=>t[e],enumerable:!(i=W(t,e))||i.enumerable});return c};var k=(c,t,o)=>(o=c!=null?j(K(c)):{},F(t||!c||!c.__esModule?N(o,"default",{value:c,enumerable:!0}):o,c)),Y=c=>F(N({},"__esModule",{value:!0}),c);var ce={};Q(ce,{DurableXenoCoordinationStore:()=>X,XENO_COORDINATION_BUDGET_SESSION_SCHEMA_VERSION:()=>C,XENO_COORDINATION_MANAGED_SESSION_SCHEMA_VERSION:()=>G,XENO_COORDINATION_SCHEMA_VERSION:()=>w,XENO_COORDINATION_TURN_SESSION_SCHEMA_VERSION:()=>T,XenoCoordinationError:()=>d,XenoExecutionLeaseSession:()=>D,executeXenoCoordinationAction:()=>de});module.exports=Y(ce);var w=1,G=2,C=3,T=4,d=class extends Error{constructor(o,i,e={}){super(i);this.code=o;this.details=e;this.name="XenoCoordinationError"}code;details};var y=require("node:crypto"),f=k(require("node:fs/promises"),1),E=k(require("node:os"),1),I=k(require("node:path"),1);var v=require("node:os");var R=require("node:path"),pe=(0,v.platform)();var fe=(0,v.release)(),he=(0,v.homedir)();function M(){let c=process.env.XENO_AGENT_HOME?.trim();return c?(0,R.resolve)(c):(0,R.resolve)((0,v.homedir)(),".xeno-agent")}var Z=3e4,ee=3e4,te=6e4,ne=2e4,L=new Set(["EACCES","EBUSY","EPERM"]),H=[5,10,20,40,80,160,320],oe=[5,10,20,40,80,160,320],P=[1,2,3,4];function p(c,t,o=16384){let i=c.trim();if(!i||i.length>o)throw new d("INVALID",`${t} must be non-empty and no longer than ${o} characters`);return i}function x(c,t){return[...new Set((c??[]).map(o=>p(o,t)))]}function q(c){if(c===void 0)return;if(!c||typeof c!="object"||Array.isArray(c))throw new d("INVALID","Goal limits must be an object when provided");let t={};for(let[o,i]of Object.entries(c)){if(o!=="maxIterations"&&o!=="maxTokens"&&o!=="maxWallClockMs")throw new d("INVALID","Unknown goal limit");if(i!==void 0){if(!Number.isSafeInteger(i)||i<=0)throw new d("INVALID",`${o} must be a positive safe integer when provided`);t[o]=i}}return t}function re(c){if(c){if(c.kind!=="fixed-interval"&&c.kind!=="dynamic")throw new d("INVALID","schedule.kind must be fixed-interval or dynamic");if(c.kind==="fixed-interval"&&(!Number.isSafeInteger(c.intervalMs)||(c.intervalMs??0)<=0))throw new d("INVALID","Fixed-interval schedules require a positive safe intervalMs");if(c.intervalMs!==void 0&&(!Number.isSafeInteger(c.intervalMs)||c.intervalMs<=0))throw new d("INVALID","schedule.intervalMs must be a positive safe integer when provided");for(let t of["nextRunAt","expiresAt"]){let o=c[t];if(o!==void 0&&!Number.isFinite(Date.parse(o)))throw new d("INVALID",`schedule.${t} must be an ISO timestamp when provided`)}return m(c)}}function m(c){return structuredClone(c)}function S(c){let t=Date.parse(c);return Number.isFinite(t)?t:0}function _(c){if(!Number.isInteger(c)||c<=0)return!1;try{return process.kill(c,0),!0}catch(t){return t.code==="EPERM"}}function ie(c){return{summary:"Goal created; work has not started.",completedTaskCount:0,totalTaskCount:0,outstanding:[],decisions:[],updatedAt:c}}function se(){return{status:"pending",criteria:[],evidence:[]}}function ae(c){return(0,y.createHash)("sha256").update(c).digest("hex")}var X=class{get goalTurnAdmissionVersion(){return 1}rootDirectory;now;idFactory;ownerLeaseMs;lockTimeoutMs;lockStaleMs;maximumEventsPerSession;constructor(t={}){this.rootDirectory=t.rootDirectory??I.join(M(),"coordination"),this.now=t.now??(()=>new Date().toISOString()),this.idFactory=t.idFactory??(o=>`${o}_${(0,y.randomUUID)()}`),this.ownerLeaseMs=t.ownerLeaseMs??Z,this.lockTimeoutMs=t.lockTimeoutMs??ee,this.lockStaleMs=t.lockStaleMs??te,this.maximumEventsPerSession=t.maximumEventsPerSession??ne}async getSessionState(t){let o=p(t,"sessionId",1024);return m(await this.readState(o))}async fenceAdmission(t,o,i){let e=p(i.authorityId,"authorityId",512),n=p(i.operationId,"operationId",512);if(!Number.isSafeInteger(o)||o<0)throw new d("INVALID","Expected session version must be a nonnegative safe integer");if(i.action!=="archive"&&i.action!=="delete")throw new d("INVALID","Unsupported admission fence action");return this.mutate(t,r=>{let s=r.admissionFence;if(s?.authorityId===e&&s.operationId===n&&s.action===i.action)return s;if(r.version!==o)throw new d("CONFLICT","Session version changed before lifecycle fencing",{expected:o,actual:r.version});if(s?.authorityId===e&&s.action==="archive"&&i.action==="archive")return s;if(s&&!(s.authorityId===e&&s.action==="archive"&&i.action==="delete"))throw new d("CONFLICT","Another lifecycle fence already owns this session");let a={schemaVersion:1,authorityId:e,operationId:n,action:i.action,createdAt:this.now()};return r.admissionFence=a,r.schemaVersion===1&&(r.schemaVersion=2),this.appendEvent(r,"admission.fenced",{data:{authorityId:e,operationId:n,action:i.action}}),a},!0)}async clearAdmissionFence(t,o,i,e){await this.mutate(t,n=>{this.assertVersion(t,n.version,o);let r=n.admissionFence;if(!r||r.authorityId!==i||r.operationId!==e)throw new d("CONFLICT","Lifecycle fence identity does not match");if(r.action==="delete")throw new d("CONFLICT","Deleted session admission cannot be restored");if(n.owner)throw new d("CONFLICT","Execution ownership must settle before restoration");n.admissionFence=void 0,this.appendEvent(n,"admission.restored",{data:{authorityId:i,operationId:e}})},!0)}async releaseDeadLifecycleOwner(t,o,i,e){await this.mutate(t,n=>{this.assertVersion(t,n.version,o);let r=n.admissionFence;if(!r||r.authorityId!==i||r.operationId!==e)throw new d("CONFLICT","Lifecycle fence identity does not match");let s=n.owner;if(s){if(s.host!==E.hostname()||!Number.isInteger(s.processId)||(s.processId??0)<=0||_(s.processId))throw new d("CONFLICT","Execution owner exit has not been proved");n.owner=void 0,this.appendEvent(n,"ownership.released",{ownerId:s.ownerId,data:{epoch:s.epoch,reason:"fenced-local-owner-exited"}})}},!0)}async listSessionStates(){let t=I.join(this.rootDirectory,"sessions"),o;try{o=await f.readdir(t)}catch(e){if(e.code==="ENOENT")return[];throw e}return(await Promise.all(o.filter(e=>e.endsWith(".json")).map(async e=>{try{let n=JSON.parse(await f.readFile(I.join(t,e),"utf8"));return!P.includes(n.schemaVersion)||typeof n.sessionId!="string"?void 0:((!Number.isSafeInteger(n.ownershipEpoch)||n.ownershipEpoch<0)&&(n.ownershipEpoch=Math.max(n.owner?.epoch??0,...n.handoffs.map(r=>r.targetLeaseEpoch??r.sourceLeaseEpoch??0))),n)}catch{return}}))).filter(e=>e!==void 0).sort((e,n)=>S(n.updatedAt)-S(e.updatedAt)).map(e=>m(e))}async createGoal(t){let o=p(t.sessionId,"sessionId",1024),i=q(t.limits);return this.mutate(o,e=>{let n=e.goals.find(l=>["active","paused","waiting","blocked"].includes(l.status));if(n)throw new d("CONFLICT",`Session ${o} already has active goal ${n.id}`);let r=this.now(),s=(t.successCriteria??[]).map(l=>typeof l=="string"?{id:this.idFactory("criterion"),description:p(l,"successCriteria"),required:!0}:{id:l.id?p(l.id,"successCriteria.id",512):this.idFactory("criterion"),description:p(l.description,"successCriteria.description"),required:l.required}),a={schemaVersion:1,id:this.idFactory("goal"),version:1,sessionId:o,objective:p(t.objective,"objective"),...t.why?{why:p(t.why,"why")}:{},successCriteria:s,constraints:x(t.constraints,"constraints"),...i?{limits:i}:{},metadata:m(t.metadata??{}),status:"active",milestones:[],tasks:[],progress:ie(r),verification:se(),steering:[],createdAt:r,updatedAt:r};return e.goals.push(a),this.appendEvent(e,"goal.created",{goalId:a.id,data:{objective:a.objective}}),a})}async getGoal(t,o){let i=await this.getSessionState(t),e=o?i.goals.find(n=>n.id===o):[...i.goals].reverse().find(n=>["active","paused","waiting","blocked"].includes(n.status));return e?m(e):void 0}async updateGoal(t,o,i,e){return this.mutate(t,n=>{let r=this.requireGoal(n,o);if(this.assertVersion(r.id,r.version,i),["completed","cancelled","failed"].includes(r.status))throw new d("CONFLICT",`Goal ${r.id} is terminal (${r.status})`);let s=r.status!=="active";if(e.status==="active"&&r.status==="blocked"?r.status="active":e.status&&(r.status=e.status),e.objective!==void 0&&(r.objective=p(e.objective,"objective")),e.why!==void 0&&(r.why=p(e.why,"why")),e.constraints&&(r.constraints=x(e.constraints,"constraints")),e.successCriteria&&(r.successCriteria=m(e.successCriteria)),e.progress&&(r.progress={...r.progress,...m(e.progress),outstanding:x(e.progress.outstanding??r.progress.outstanding,"progress.outstanding"),decisions:x(e.progress.decisions??r.progress.decisions,"progress.decisions"),updatedAt:this.now()}),e.verification&&(r.verification=m(e.verification)),e.metadata&&(r.metadata=m(e.metadata)),s&&r.status==="active")for(let a of n.loops.filter(l=>l.goalId===o&&l.kind==="goal-continuation"&&l.status==="running"))a.resumeRequested=!0,a.version+=1,a.updatedAt=this.now();return r.version+=1,r.updatedAt=this.now(),this.appendEvent(n,"goal.updated",{goalId:r.id,data:{status:r.status,version:r.version}}),r},e.status!==void 0&&["paused","cancelled","failed"].includes(e.status))}async addMilestone(t,o,i,e){return this.mutateGoal(t,o,i,(n,r)=>{let s={id:this.idFactory("milestone"),title:p(e.title,"milestone.title"),...e.description?{description:p(e.description,"milestone.description")}:{},status:n.milestones.some(a=>a.status==="active")?"pending":"active",taskIds:[],createdAt:r,updatedAt:r};n.milestones.push(s),n.progress.currentMilestoneId??=s.id,n.progress.updatedAt=r})}async addTask(t,o,i,e){return this.mutateGoal(t,o,i,(n,r)=>{let s=n.milestones.find(u=>u.id===e.milestoneId);if(!s)throw new d("NOT_FOUND",`Milestone ${e.milestoneId} was not found`);if(e.parentTaskId&&!n.tasks.some(u=>u.id===e.parentTaskId))throw new d("NOT_FOUND",`Parent task ${e.parentTaskId} was not found`);let a=[...new Set(e.dependsOn??[])];for(let u of a)if(!n.tasks.some(h=>h.id===u))throw new d("NOT_FOUND",`Task dependency ${u} was not found`);let l={id:this.idFactory("task"),milestoneId:s.id,...e.parentTaskId?{parentTaskId:e.parentTaskId}:{},title:p(e.title,"task.title"),...e.description?{description:p(e.description,"task.description")}:{},status:a.length===0?"ready":"pending",...e.assignedAgentId?{assignedAgentId:p(e.assignedAgentId,"task.assignedAgentId",512)}:{},...a.length?{dependsOn:a}:{},createdAt:r,updatedAt:r};n.tasks.push(l),s.taskIds.push(l.id),s.updatedAt=r,n.progress.totalTaskCount=n.tasks.length,n.progress.outstanding=n.tasks.filter(u=>u.status!=="completed").map(u=>u.title),n.progress.updatedAt=r})}async updateTask(t,o,i,e,n){return this.mutateGoal(t,o,e,(r,s)=>{let a=r.tasks.find(u=>u.id===i);if(!a)throw new d("NOT_FOUND",`Task ${i} was not found`);a.status=n.status,n.progress!==void 0&&(a.progress=p(n.progress,"task.progress")),n.resultEventId!==void 0&&(a.resultEventId=p(n.resultEventId,"task.resultEventId",512)),n.assignedAgentId!==void 0&&(a.assignedAgentId=p(n.assignedAgentId,"task.assignedAgentId",512)),a.updatedAt=s,a.status==="completed"&&(a.completedAt=s);let l=r.milestones.find(u=>u.id===a.milestoneId);if(l){let u=r.tasks.filter(h=>h.milestoneId===l.id);u.length>0&&u.every(h=>h.status==="completed")?(l.status="completed",l.completedAt=s):u.some(h=>h.status==="running")?l.status="active":u.some(h=>h.status==="blocked")&&(l.status="blocked"),l.updatedAt=s}for(let u of r.tasks)u.status!=="pending"||!u.dependsOn?.length||u.dependsOn.every(h=>r.tasks.find(O=>O.id===h)?.status==="completed")&&(u.status="ready",u.updatedAt=s);this.recalculateProgress(r,s)})}async steerGoal(t,o,i,e){return this.mutateGoal(t,o,i,(n,r,s)=>{let a=this.idFactory("steer");n.steering.push({id:a,instruction:p(e,"instruction"),createdAt:r}),this.appendEvent(s,"goal.steered",{goalId:o,data:{steeringId:a}})},!1)}async consumeGoalSteering(t,o,i){let e=[];return{goal:await this.mutateGoal(t,o,i,(r,s)=>{e=r.steering.filter(a=>!a.consumedAt).map(({id:a,instruction:l,createdAt:u})=>({id:a,instruction:l,createdAt:u}));for(let a of r.steering)a.consumedAt||(a.consumedAt=s)}),instructions:e}}async completeGoal(t,o,i,e){if(e.status!=="passed")throw new d("VERIFICATION_REQUIRED","Goal completion requires passed verification");return this.mutate(t,n=>{let r=this.requireGoal(n,o);this.assertVersion(r.id,r.version,i);let s=r.successCriteria.filter(u=>u.required),a=s.filter(u=>{let h=e.criteria.find(O=>O.criterionId===u.id);return!h?.satisfied||h.evidence.length===0});if(a.length>0)throw new d("VERIFICATION_REQUIRED","Required success criteria lack passing evidence",{unmetCriteria:a.map(u=>u.id)});if(s.length===0&&e.evidence.length===0)throw new d("VERIFICATION_REQUIRED","Goal completion requires at least one durable evidence reference");let l=this.now();return r.status="completed",r.verification=m(e),r.verification.verifiedAt??=l,r.completedAt=l,r.updatedAt=l,r.version+=1,this.appendEvent(n,"goal.completed",{goalId:o,data:{evidence:r.verification.evidence}}),r},!0)}async cancelGoal(t,o,i,e){return this.mutate(t,n=>{let r=this.requireGoal(n,o);if(this.assertVersion(r.id,r.version,i),["completed","cancelled","failed"].includes(r.status))return r;r.status="cancelled",r.updatedAt=this.now(),r.version+=1,this.appendEvent(n,"goal.cancelled",{goalId:o,data:{reason:p(e,"reason")}});for(let s of n.loops.filter(a=>a.goalId===o&&["running","paused","waiting"].includes(a.status)))s.status="stopped",s.resumeRequested!==void 0&&(s.resumeRequested=!1),s.stopReason=`Goal cancelled: ${e}`,s.stoppedAt=this.now(),s.updatedAt=s.stoppedAt,s.version+=1;return r},!0)}async startLoop(t){return this.mutate(t.sessionId,o=>this.createLoopRecord(o,t))}createLoopRecord(t,o){if(o.kind==="goal-continuation"&&!o.goalId)throw new d("INVALID","Goal-continuation loops require a goalId");if(o.goalId){let s=this.requireGoal(t,o.goalId);if(["completed","cancelled","failed"].includes(s.status))throw new d("CONFLICT",`Cannot start a loop for terminal goal ${s.id}`)}if(o.kind==="scheduled"&&!o.schedule)throw new d("INVALID","Scheduled loops require schedule metadata");if(o.kind!=="scheduled"&&o.schedule)throw new d("INVALID","Only scheduled loops may carry schedule metadata");let i=re(o.schedule),e=t.loops.find(s=>s.goalId===o.goalId&&s.kind===o.kind&&["running","paused","waiting"].includes(s.status));if(e)throw new d("CONFLICT",`Loop ${e.id} is already active`);let n=this.now(),r={schemaVersion:1,id:this.idFactory("loop"),version:1,sessionId:t.sessionId,...o.goalId?{goalId:o.goalId}:{},kind:o.kind,status:"running",...o.activity?{currentActivity:p(o.activity,"activity")}:{},iterations:[],...i?{schedule:i}:{},createdAt:n,updatedAt:n};return t.loops.push(r),this.appendEvent(t,"loop.started",{loopId:r.id,goalId:r.goalId,data:{kind:r.kind}}),r}async getLoop(t,o){let i=await this.getSessionState(t),e=o?i.loops.find(n=>n.id===o):[...i.loops].reverse().find(n=>["running","paused","waiting"].includes(n.status));return e?m(e):void 0}async beginLoopIteration(t,o,i,e,n){return this.mutateLoop(t,o,i,(r,s,a)=>{this.appendLoopIteration(a,r,s,e,n)},!1)}appendLoopIteration(t,o,i,e,n){if(o.status!=="running")throw new d("CONFLICT",`Loop ${o.id} is ${o.status}`);if(o.goalId){let a=this.requireGoal(t,o.goalId);this.isCliGoal(a)&&this.initializeGoalTurnAccounting(t,a)}if(this.assertGoalIterationAdmission(t,o,i),o.iterations.some(a=>a.status==="running"))throw new d("CONFLICT",`Loop ${o.id} already has a running iteration`);let r=(o.iterations.at(-1)?.number??0)+1;o.currentActivity=p(e,"activity");let s={number:r,startedAt:i,status:"running",activity:o.currentActivity,...o.goalId&&t.goalTurnAccounting?.[o.goalId]?{goalAccountingVersion:1}:{},...n?{taskId:p(n,"taskId",512)}:{}};return o.iterations.push(s),o.resumeRequested!==void 0&&(o.resumeRequested=!1),this.appendEvent(t,"loop.iteration",{loopId:o.id,goalId:o.goalId,data:{number:r,phase:"started",activity:o.currentActivity}}),s}async admitGoalTurn(t){let o=p(t.requestId,"requestId",512),i=this.goalTurnHash(t.requestHash);return this.mutate(t.sessionId,e=>{let n=this.requireGoal(e,t.goalId);for(let l of e.loops.filter(u=>u.goalId===n.id)){let u=l.iterations.find(h=>h.goalTurn?.requestId===o);if(u){if(u.goalTurn?.requestHash!==i)throw new d("CONFLICT","Goal turn identity was reused for different work");return{...this.goalTurnState(e,n,l,u),admitted:!1}}}if(this.assertVersion(n.id,n.version,t.expectedGoalVersion),n.status!=="active")throw new d("CONFLICT",`Goal ${n.id} is ${n.status}`);let r=[...e.loops].reverse().find(l=>l.goalId===n.id&&l.kind==="goal-continuation");if(t.expectedLoopId!==void 0){if(!r||r.id!==t.expectedLoopId)throw new d("CONFLICT","Goal continuation loop changed before admission");this.assertVersion(r.id,r.version,t.expectedLoopVersion??-1)}else if(t.expectedLoopVersion!==void 0)throw new d("INVALID","A goal turn loop version requires its exact loop ID");if(r&&r.status!=="running")throw new d("CONFLICT",`Goal loop ${r.id} is ${r.status}; resume or start it explicitly`);this.initializeGoalTurnAccounting(e,n),r??=this.createLoopRecord(e,{sessionId:e.sessionId,goalId:n.id,kind:"goal-continuation"});let s=this.now(),a=this.appendLoopIteration(e,r,s,"Interactive goal turn");if(t.executionKind!==void 0&&t.executionKind!=="local-sdk"&&t.executionKind!=="external")throw new d("INVALID","Unknown goal execution lane");return a.goalTurn={requestId:o,requestHash:i,executor:t.executionKind==="local-sdk"?{kind:"local-sdk",processId:process.pid,host:E.hostname()}:{kind:"external"}},r.version+=1,r.updatedAt=s,{...this.goalTurnState(e,n,r,a),admitted:!0}},!1,e=>e.admitted)}async getGoalTurnState(t,o,i){let e=await this.getSessionState(t),n=o?e.goals.find(l=>l.id===o):[...e.goals].reverse().find(l=>["active","paused","waiting","blocked"].includes(l.status));if(!n)return;let r=e.loops.filter(l=>l.goalId===n.id),s=i?r.find(l=>l.iterations.some(u=>u.goalTurn?.requestId===i)):[...r].reverse().find(l=>l.kind==="goal-continuation"),a=i?s?.iterations.find(l=>l.goalTurn?.requestId===i):s?.iterations.at(-1);if(i&&!a)throw new d("NOT_FOUND","Goal turn was not found");return this.goalTurnState(e,n,s,a)}async finishGoalTurn(t){if(!["completed","failed","interrupted"].includes(t.status))throw new d("INVALID","Invalid goal turn outcome");let o=this.goalTurnHash(t.requestHash);return this.mutate(t.sessionId,i=>{let e=this.requireGoal(i,t.goalId),n=i.loops.find(s=>s.goalId===e.id&&s.iterations.some(a=>a.goalTurn?.requestId===t.requestId)),r=n?.iterations.find(s=>s.goalTurn?.requestId===t.requestId);if(!n||!r)throw new d("NOT_FOUND","Goal turn was not found");if(r.goalTurn?.requestHash!==o)throw new d("CONFLICT","Goal turn settlement identity does not match");return r.status==="running"&&(this.settleLoopIteration(i,n,r,this.now(),{status:e.status==="cancelled"||["stopped","failed"].includes(n.status)?"interrupted":t.status}),n.version+=1,n.updatedAt=this.now()),this.goalTurnState(i,e,n,r)},!0)}async recoverGoalTurn(t,o,i){return this.mutate(t,e=>{let n=this.requireGoal(e,o),r=e.loops.find(a=>a.goalId===o&&a.iterations.some(l=>l.goalTurn?.requestId===i)),s=r?.iterations.find(a=>a.goalTurn?.requestId===i);if(!r||!s)throw new d("NOT_FOUND","Goal turn was not found");if(s.status==="running"){if(!this.goalTurnOwnerExited(s))throw new d("NOT_OWNER","The original local goal executor has not been proved exited; external execution requires reconciliation");this.settleLoopIteration(e,r,s,this.now(),{status:"interrupted",error:"Original local SDK executor exited; inspect persisted results before retrying work"}),r.resumeRequested=n.status==="active"&&r.status==="running",r.version+=1,r.updatedAt=this.now()}return this.goalTurnState(e,n,r,s)},!0)}async finishLoopIteration(t,o,i,e){return this.mutateLoop(t,o,i,(n,r,s)=>{let a=[...n.iterations].reverse().find(l=>l.status==="running");if(!a)throw new d("CONFLICT",`Loop ${n.id} has no running iteration`);this.settleLoopIteration(s,n,a,r,e)},!1,!0)}settleLoopIteration(t,o,i,e,n){i.status=n.status,i.completedAt=e,n.verificationEventId&&(i.verificationEventId=p(n.verificationEventId,"verificationEventId",512)),n.error&&(i.error=p(n.error,"error")),o.status=["stopped","completed","failed"].includes(o.status)?o.status:t.admissionFence?"paused":n.nextStatus??(o.status==="paused"||o.status==="waiting"?o.status:"running"),this.appendEvent(t,"loop.iteration",{loopId:o.id,goalId:o.goalId,data:{number:i.number,phase:"finished",status:n.status}})}async setLoopStatus(t,o,i,e,n){return this.mutateLoop(t,o,i,(r,s,a)=>{let l=r.status;if(["stopped","completed","failed"].includes(l))throw new d("CONFLICT",`Loop ${r.id} is terminal (${l})`);let u=[...r.iterations].reverse().find(O=>O.status==="running");if(u&&e==="completed")throw new d("CONFLICT",`Loop ${r.id} cannot complete while iteration ${u.number} is running`);u&&(e==="stopped"||e==="failed")&&(u.status=e==="failed"?"failed":"interrupted",u.completedAt=s,u.error=p(n??e,"reason")),r.status=e,r.kind==="goal-continuation"&&(r.resumeRequested=e==="running"),["stopped","completed","failed"].includes(e)&&(r.stoppedAt=s,r.stopReason=p(n??e,"reason"));let h=e==="paused"?"loop.paused":e==="waiting"?"loop.waiting":e==="running"&&(l==="paused"||l==="waiting")?"loop.resumed":e==="completed"?"loop.completed":e==="failed"?"loop.failed":"loop.stopped";this.appendEvent(a,h,{loopId:o,goalId:r.goalId,data:{previous:l,status:e,...n?{reason:n}:{}}})},!1,e!=="running"&&e!=="waiting")}async acquireOwnership(t,o,i={}){return this.mutate(t,e=>{let n=this.now();if(e.owner&&!this.ownerExpired(e.owner,n)){if(e.owner.ownerId===o&&i.processId!==void 0&&e.owner.processId===i.processId&&(i.host===void 0||e.owner.host===i.host))return e.owner;throw new d("CONFLICT",`Session ${t} is owned by ${e.owner.ownerId}`,{owner:e.owner})}let r=e.owner&&this.ownerExpired(e.owner,n)?e.owner:void 0;if(r&&r.ownerId!==o)for(let l of e.handoffs.filter(u=>u.status==="claimed"&&u.claimedBy===r.ownerId))l.status="failed",l.failureReason=`Claimed owner ${r.ownerId} lost its execution lease before completing the handoff.`,l.failedAt=n,l.updatedAt=n,l.version+=1,this.appendEvent(e,"handoff.failed",{handoffId:l.id,goalId:l.goalId,loopId:l.loopId,data:{reason:l.failureReason,expiredLeaseId:r.leaseId}});let s=e.ownershipEpoch+1,a=this.newOwner(o,s,i,n);return e.owner=a,e.ownershipEpoch=s,this.appendEvent(e,"ownership.acquired",{ownerId:o,data:{epoch:s,leaseId:a.leaseId}}),a})}async renewOwnership(t,o,i,e=this.ownerLeaseMs){return this.mutate(t,n=>{let r=this.requireOwner(n,o,i);if(this.ownerExpired(r,this.now()))throw new d("LEASE_EXPIRED",`Ownership lease ${i} expired`);return r.heartbeatAt=this.now(),r.expiresAt=new Date(S(r.heartbeatAt)+e).toISOString(),this.appendEvent(n,"ownership.renewed",{ownerId:o,data:{epoch:r.epoch,leaseId:i}}),r})}async releaseOwnership(t,o,i){return this.mutate(t,e=>{let n=this.requireOwner(e,o,i);return e.owner=void 0,this.appendEvent(e,"ownership.released",{ownerId:o,data:{epoch:n.epoch}}),n},!0)}async createHandoff(t){return this.mutate(t.sessionId,o=>{let i=this.requireOwner(o,t.sourceOwnerId,t.sourceLeaseId);if(this.ownerExpired(i,this.now()))throw new d("LEASE_EXPIRED",`Ownership lease ${i.leaseId} expired`);let e=(t.operations??[]).filter(a=>a.status==="running"&&a.sideEffecting&&a.recovery==="retry");if(e.length>0)throw new d("UNSAFE_HANDOFF","Running side-effecting operations cannot be transferred with automatic retry",{operationIds:e.map(a=>a.operationId)});if(t.goalId&&this.requireGoal(o,t.goalId),t.loopId&&!o.loops.some(a=>a.id===t.loopId))throw new d("NOT_FOUND",`Loop ${t.loopId} was not found`);let n=o.handoffs.find(a=>["prepared","available","claimed"].includes(a.status));if(n)throw new d("CONFLICT",`Handoff ${n.id} is already active`);let r=this.now(),s={schemaVersion:1,id:this.idFactory("handoff"),version:1,sessionId:o.sessionId,...t.goalId?{goalId:t.goalId}:{},...t.loopId?{loopId:t.loopId}:{},status:"available",sourceOwnerId:i.ownerId,...t.targetOwnerId?{targetOwnerId:p(t.targetOwnerId,"targetOwnerId",512)}:{},sourceLeaseEpoch:i.epoch,...t.workspace?{workspace:p(t.workspace,"workspace",32768)}:{},...t.branch?{branch:p(t.branch,"branch",1024)}:{},...t.currentMilestoneId?{currentMilestoneId:t.currentMilestoneId}:{},...t.currentTaskId?{currentTaskId:t.currentTaskId}:{},agentIds:[...new Set(t.agentIds??[])],operations:m(t.operations??[]),...t.contextDigest?{contextDigest:p(t.contextDigest,"contextDigest",512)}:{},createdAt:r,updatedAt:r};return o.handoffs.push(s),this.appendEvent(o,"handoff.created",{handoffId:s.id,goalId:s.goalId,loopId:s.loopId,ownerId:i.ownerId,data:{targetOwnerId:s.targetOwnerId}}),s})}async claimHandoff(t){let o;return{handoff:await this.mutate(t.sessionId,e=>{let n=e.handoffs.find(a=>a.id===t.handoffId);if(!n)throw new d("NOT_FOUND",`Handoff ${t.handoffId} was not found`);if(n.status!=="available")throw new d("CONFLICT",`Handoff ${n.id} is ${n.status}`,{claimedBy:n.claimedBy});if(n.targetOwnerId&&n.targetOwnerId!==t.targetOwnerId)throw new d("CONFLICT",`Handoff ${n.id} is reserved for ${n.targetOwnerId}`);let r=e.owner;if(!r||r.ownerId!==n.sourceOwnerId||r.epoch!==n.sourceLeaseEpoch)throw new d("CONFLICT",`Handoff ${n.id} no longer matches the source ownership epoch`);let s=this.now();return o=this.newOwner(t.targetOwnerId,r.epoch+1,{processId:t.processId,host:t.host},s),e.owner=o,e.ownershipEpoch=o.epoch,n.status="claimed",n.claimedBy=t.targetOwnerId,n.targetOwnerId=t.targetOwnerId,n.targetLeaseEpoch=o.epoch,n.claimedAt=s,n.updatedAt=s,n.version+=1,this.appendEvent(e,"handoff.claimed",{handoffId:n.id,goalId:n.goalId,loopId:n.loopId,ownerId:t.targetOwnerId,data:{sourceOwnerId:n.sourceOwnerId,epoch:o.epoch}}),n}),owner:m(o)}}async completeHandoff(t,o,i,e){return this.mutate(t,n=>{this.requireOwner(n,i,e);let r=n.handoffs.find(s=>s.id===o);if(!r)throw new d("NOT_FOUND",`Handoff ${o} was not found`);if(r.status!=="claimed"||r.claimedBy!==i)throw new d("CONFLICT",`Handoff ${r.id} cannot be completed by ${i}`);return r.status="completed",r.completedAt=this.now(),r.updatedAt=r.completedAt,r.version+=1,this.appendEvent(n,"handoff.completed",{handoffId:o,goalId:r.goalId,loopId:r.loopId,ownerId:i,data:{epoch:n.owner?.epoch}}),r})}async failHandoff(t,o,i){return this.mutate(t,e=>{let n=e.handoffs.find(r=>r.id===o);if(!n)throw new d("NOT_FOUND",`Handoff ${o} was not found`);return["completed","cancelled","failed"].includes(n.status)||(n.status="failed",n.failureReason=p(i,"reason"),n.failedAt=this.now(),n.updatedAt=n.failedAt,n.version+=1,this.appendEvent(e,"handoff.failed",{handoffId:o,goalId:n.goalId,loopId:n.loopId,data:{reason:n.failureReason}})),n},!0)}async mutateGoal(t,o,i,e,n=!0){return this.mutate(t,r=>{let s=this.requireGoal(r,o);this.assertVersion(s.id,s.version,i);let a=this.now();return e(s,a,r),s.version+=1,s.updatedAt=a,n&&this.appendEvent(r,"goal.updated",{goalId:o,data:{status:s.status,version:s.version}}),s})}async mutateLoop(t,o,i,e,n=!0,r=!1){return this.mutate(t,s=>{let a=s.loops.find(u=>u.id===o);if(!a)throw new d("NOT_FOUND",`Loop ${o} was not found`);this.assertVersion(a.id,a.version,i);let l=this.now();return e(a,l,s),a.version+=1,a.updatedAt=l,n&&this.appendEvent(s,"loop.iteration",{loopId:o,goalId:a.goalId,data:{status:a.status,version:a.version}}),a},r)}assertGoalIterationAdmission(t,o,i){if(!o.goalId)return;let e=this.requireGoal(t,o.goalId);if(e.status!=="active")throw new d("CONFLICT",`Goal ${e.id} is ${e.status}; no iteration was admitted`);let n=q(e.limits);if(n?.maxTokens!==void 0)throw new d("BUDGET_UNAVAILABLE","Goal token allowance is not bound to request-level admission; no iteration was admitted",{goalId:e.id,limit:"maxTokens"});if(n?.maxWallClockMs!==void 0){let r=Date.parse(e.createdAt),s=Date.parse(i);if(!Number.isFinite(r)||!Number.isFinite(s)||s<r)throw new d("BUDGET_UNAVAILABLE","Goal wall-clock allowance cannot be verified",{goalId:e.id,limit:"maxWallClockMs"});if(s-r>=n.maxWallClockMs)throw new d("BUDGET_EXCEEDED","Goal wall-clock limit reached; no iteration was admitted",{goalId:e.id,limit:"maxWallClockMs",maximum:n.maxWallClockMs})}if(n?.maxIterations!==void 0){let r=t.goalTurnAccounting!==void 0||t.schemaVersion===4?this.resolveGoalTurnAccounting(t,e):void 0;if(r?.coverage==="partial")throw new d("BUDGET_UNAVAILABLE","Legacy goal turn accounting is incomplete");let s=this.goalIterationCount(t,e)+(r?.baseIterations??0);if(!Number.isSafeInteger(s)||s<0)throw new d("BUDGET_UNAVAILABLE","Invalid goal iteration accounting");if(s>=n.maxIterations)throw new d("BUDGET_EXCEEDED","Goal iteration limit reached; no iteration was admitted",{goalId:e.id,limit:"maxIterations",admitted:s,maximum:n.maxIterations})}}isCliGoal(t){return"cli.accountedTurns"in t.metadata||"cli.createdByCliVersion"in t.metadata}goalIterationCount(t,o){let i=0;for(let e of t.loops.filter(n=>n.goalId===o.id)){if(!Array.isArray(e.iterations))throw new d("BUDGET_UNAVAILABLE","Goal iteration history is unavailable");let n=0;for(let r of e.iterations){if(!r||!Number.isSafeInteger(r.number)||r.number<=n)throw new d("BUDGET_UNAVAILABLE","Goal iteration history is invalid");n=r.number}if(i+=n,!Number.isSafeInteger(i))throw new d("BUDGET_UNAVAILABLE","Goal iteration count exceeds its supported range")}return i}resolveGoalTurnAccounting(t,o){let i=t.goalTurnAccounting;if(i!==void 0&&(!i||typeof i!="object"||Array.isArray(i)))throw new d("BUDGET_UNAVAILABLE","Persisted goal turn accounting is invalid");if(i&&Object.hasOwn(i,o.id)){let a=i[o.id];if(!a||a.schemaVersion!==1||!Number.isSafeInteger(a.baseIterations)||a.baseIterations<0||!["complete","partial"].includes(a.coverage))throw new d("BUDGET_UNAVAILABLE","Persisted goal turn accounting is invalid");return a}if(t.loops.some(a=>a.goalId===o.id&&a.iterations.some(l=>l.goalTurn||l.goalAccountingVersion)))throw new d("BUDGET_UNAVAILABLE","Recorded goal turns are missing their protected accounting");let e=this.goalIterationCount(t,o),n=o.metadata["cli.accountedTurns"],r=typeof n=="number"&&Number.isSafeInteger(n)&&n>=0,s=this.isCliGoal(o)&&(!r||n>0&&e>0);return{schemaVersion:1,baseIterations:r&&e===0?n:0,coverage:s?"partial":"complete"}}initializeGoalTurnAccounting(t,o){let i=this.resolveGoalTurnAccounting(t,o);if(i.coverage==="partial"&&o.limits?.maxIterations!==void 0)throw new d("BUDGET_UNAVAILABLE","Legacy goal turn accounting needs reconciliation before bounded execution");t.goalTurnAccounting??={},Object.defineProperty(t.goalTurnAccounting,o.id,{value:i,writable:!0,enumerable:!0,configurable:!0})}goalTurnHash(t){let o=p(t,"requestHash",64).toLowerCase();if(!/^[0-9a-f]{64}$/.test(o))throw new d("INVALID","Goal turn requestHash must be a SHA-256 digest");return o}goalTurnState(t,o,i,e){let n=this.resolveGoalTurnAccounting(t,o),r=this.goalIterationCount(t,o)+n.baseIterations;if(!Number.isSafeInteger(r))throw new d("BUDGET_UNAVAILABLE","Goal turn count exceeds its supported range");return m({goal:o,admittedTurns:r,accountingCoverage:n.coverage,...i?{loopId:i.id,loopVersion:i.version,loopStatus:i.status,resumeRequested:i.resumeRequested===!0}:{},...e?{iterationNumber:e.number,iterationStatus:e.status,...e.goalTurn?{requestId:e.goalTurn.requestId,requestHash:e.goalTurn.requestHash}:{},canRecover:e.status==="running"&&this.goalTurnOwnerExited(e)}:{}})}goalTurnOwnerExited(t){let o=t.goalTurn?.executor;if(o?.kind!=="local-sdk"||o.host!==E.hostname()||!Number.isSafeInteger(o.processId)||o.processId<=0)return!1;try{return process.kill(o.processId,0),!1}catch(i){return i.code==="ESRCH"}}recalculateProgress(t,o){let i=t.tasks.filter(e=>e.status==="completed").length;t.progress.completedTaskCount=i,t.progress.totalTaskCount=t.tasks.length,t.progress.percent=t.tasks.length?Math.round(i/t.tasks.length*100):void 0,t.progress.outstanding=t.tasks.filter(e=>!["completed","cancelled"].includes(e.status)).map(e=>e.title),t.progress.updatedAt=o}requireGoal(t,o){let i=t.goals.find(e=>e.id===o);if(!i)throw new d("NOT_FOUND",`Goal ${o} was not found`);return i}requireOwner(t,o,i){let e=t.owner;if(!e||e.ownerId!==o||e.leaseId!==i)throw new d("NOT_OWNER",`${o} does not own session ${t.sessionId}`,{owner:e});return e}assertVersion(t,o,i){if(!Number.isInteger(i)||i<1||o!==i)throw new d("CONFLICT",`Expected ${t} version ${i}, found ${o}`,{expected:i,actual:o})}newOwner(t,o,i,e){let n=i.leaseMs??this.ownerLeaseMs;if(!Number.isSafeInteger(n)||n<1)throw new d("INVALID","leaseMs must be a positive safe integer");return{ownerId:p(t,"ownerId",512),leaseId:this.idFactory("owner"),epoch:o,acquiredAt:e,heartbeatAt:e,expiresAt:new Date(S(e)+n).toISOString(),...i.processId!==void 0?{processId:i.processId}:{},...i.host?{host:p(i.host,"host",512)}:{}}}ownerExpired(t,o){return S(t.expiresAt)<=S(o)?!0:t.processId!==void 0&&t.host===E.hostname()&&!_(t.processId)}appendEvent(t,o,i){let e={schemaVersion:1,id:this.idFactory("event"),sequence:(t.events.at(-1)?.sequence??0)+1,type:o,sessionId:t.sessionId,...i.goalId?{goalId:i.goalId}:{},...i.loopId?{loopId:i.loopId}:{},...i.handoffId?{handoffId:i.handoffId}:{},...i.ownerId?{ownerId:i.ownerId}:{},timestamp:this.now(),data:m(i.data)};t.events.push(e),t.events.length>this.maximumEventsPerSession&&t.events.splice(0,t.events.length-this.maximumEventsPerSession)}async mutate(t,o,i=!1,e=()=>!0){let n=p(t,"sessionId",1024);return this.withSessionLock(n,async()=>{let r=await this.readState(n);if(r.admissionFence&&!i)throw new d("CONFLICT","Session execution is blocked by a persisted lifecycle fence");let s=r.schemaVersion;this.promoteGoalBudgetEnvelope(r),r.schemaVersion!==s&&await this.writeState(r);let a=o(r);return e(a)&&(r.version+=1,r.updatedAt=this.now(),await this.writeState(r)),m(a)})}statePath(t){return I.join(this.rootDirectory,"sessions",`${ae(t)}.json`)}lockPath(t){return`${this.statePath(t)}.lock`}async readState(t){let o=this.statePath(t);try{let i=await f.readFile(o,"utf8"),e=JSON.parse(i);if(!P.includes(e.schemaVersion)||e.sessionId!==t)throw new d("INVALID",`Coordination state at ${o} does not match session ${t}`);if(e.admissionFence!==void 0){let n=e.admissionFence;if(!n||n.schemaVersion!==1||typeof n.authorityId!="string"||!n.authorityId.trim()||typeof n.operationId!="string"||!n.operationId.trim()||!["archive","delete"].includes(n.action)||!Number.isFinite(Date.parse(n.createdAt)))throw new d("INVALID","Persisted lifecycle fence is corrupt; execution remains unavailable")}return(!Number.isSafeInteger(e.ownershipEpoch)||e.ownershipEpoch<0)&&(e.ownershipEpoch=Math.max(e.owner?.epoch??0,...e.handoffs.map(n=>n.targetLeaseEpoch??n.sourceLeaseEpoch??0))),e}catch(i){if(i.code!=="ENOENT")throw i;let e=this.now();return{schemaVersion:1,sessionId:t,version:0,ownershipEpoch:0,goals:[],loops:[],handoffs:[],events:[],createdAt:e,updatedAt:e}}}promoteGoalBudgetEnvelope(t){(t.goalTurnAccounting!==void 0||t.loops.some(o=>o.resumeRequested!==void 0||o.iterations.some(i=>i.goalTurn!==void 0)))&&(t.schemaVersion=4),t.schemaVersion<3&&t.goals.some(o=>o.limits!==void 0&&(!o.limits||typeof o.limits!="object"||Array.isArray(o.limits)||Object.keys(o.limits).length>0))&&(t.schemaVersion=3)}async writeState(t){this.promoteGoalBudgetEnvelope(t);let o=this.statePath(t.sessionId),i=I.dirname(o);await f.mkdir(i,{recursive:!0});let e=`${o}.${process.pid}.${(0,y.randomUUID)()}.tmp`,n=await f.open(e,"wx");try{await n.writeFile(`${JSON.stringify(t,null,2)}
2
+ `,"utf8"),await n.sync()}finally{await n.close()}try{await this.renameReplacing(e,o);try{let r=await f.open(i,"r");try{await r.sync()}finally{await r.close()}}catch{}}finally{await f.unlink(e).catch(()=>{})}}async renameReplacing(t,o){for(let i=0;;i+=1)try{await f.rename(t,o);return}catch(e){let n=e.code,r=H[i];if(process.platform!=="win32"||!n||!L.has(n)||r===void 0)throw e;await new Promise(s=>setTimeout(s,r))}}async withSessionLock(t,o){let i=this.lockPath(t),e=I.join(i,"owner.json"),n=(0,y.randomUUID)(),r=`${i}.candidate.${n}`,s=Date.now();await f.mkdir(I.dirname(i),{recursive:!0});let a={schemaVersion:1,token:n,pid:process.pid,host:E.hostname(),acquiredAt:this.now()};await f.mkdir(r),await f.writeFile(I.join(r,"owner.json"),JSON.stringify(a),{encoding:"utf8",flag:"wx"});for(let l=0;;l+=1)try{await f.rename(r,i);break}catch(u){let h=u.code;if(!(h==="EEXIST"||process.platform==="win32"&&!!h&&L.has(h)))throw await f.rm(r,{recursive:!0,force:!0}).catch(()=>{}),u;let V=await this.staleLockOwner(i,e);if(V){await this.quarantineLock(i,V.token,"stale");continue}if(Date.now()-s>=this.lockTimeoutMs)throw await f.rm(r,{recursive:!0,force:!0}).catch(()=>{}),new d("CONFLICT",`Timed out waiting for coordination lock for session ${t}`);await new Promise(B=>setTimeout(B,Math.min(100,5+l*5)+Math.floor(Math.random()*10)))}try{return await o()}finally{await this.quarantineLock(i,n,"released"),await f.rm(r,{recursive:!0,force:!0}).catch(()=>{})}}async staleLockOwner(t,o){try{let[i,e]=await Promise.all([f.readFile(o,"utf8").catch(()=>""),f.stat(t)]),n=i?JSON.parse(i):void 0;return!n||n.host===E.hostname()&&_(n.pid)?void 0:Date.now()-e.mtimeMs>this.lockStaleMs?n:void 0}catch{return}}async quarantineLock(t,o,i){let e=I.join(t,"owner.json"),n=`${t}.${i}.${o}.${(0,y.randomUUID)()}`;for(let r=0;;r+=1){let s;try{s=JSON.parse(await f.readFile(e,"utf8"))}catch(a){if(a.code==="ENOENT")return;throw a}if(s.token!==o)return;try{await f.rename(t,n);break}catch(a){let l=a.code;if(l==="ENOENT"||l==="EEXIST")return;let u=H[r];if(process.platform!=="win32"||!l||!L.has(l)||u===void 0)throw a;await new Promise(h=>setTimeout(h,u))}}for(let r=0;;r+=1)try{await f.rm(n,{recursive:!0});return}catch(s){let a=s.code;if(a==="ENOENT")return;let l=oe[r];if(process.platform!=="win32"||!a||!L.has(a)||l===void 0)throw s;await new Promise(u=>setTimeout(u,l))}}};function b(c,t){if(!c||typeof c!="object"||Array.isArray(c))throw new Error(`${t} must be an object`);return c}function g(c,t){if(typeof c!="string"||!c.trim())throw new Error(`${t} must be a non-empty string`);return c}function A(c,t){if(typeof c!="number"||!Number.isInteger(c))throw new Error(`${t} must be an integer`);return c}async function de(c,t){let{action:o,sessionId:i}=t,e=t.payload??{};if(e.sessionId!==void 0&&e.sessionId!==i)throw new d("INVALID","Payload sessionId must match the routed sessionId");let n;switch(o){case"state.get":n=await c.getSessionState(i);break;case"goal.create":n=await c.createGoal({...e,sessionId:i});break;case"goal.update":n=await c.updateGoal(i,g(e.goalId,"goalId"),A(e.expectedVersion,"expectedVersion"),b(e.update,"update"));break;case"goal.complete":n=await c.completeGoal(i,g(e.goalId,"goalId"),A(e.expectedVersion,"expectedVersion"),b(e.verification,"verification"));break;case"goal.cancel":n=await c.cancelGoal(i,g(e.goalId,"goalId"),A(e.expectedVersion,"expectedVersion"),g(e.reason,"reason"));break;case"goal.steer":n=await c.steerGoal(i,g(e.goalId,"goalId"),A(e.expectedVersion,"expectedVersion"),g(e.instruction,"instruction"));break;case"loop.start":n=await c.startLoop({sessionId:i,kind:g(e.kind,"kind"),...typeof e.goalId=="string"?{goalId:e.goalId}:{},...typeof e.activity=="string"?{activity:e.activity}:{},...e.schedule?{schedule:b(e.schedule,"schedule")}:{}});break;case"loop.get":n=await c.getLoop(i,typeof e.loopId=="string"?e.loopId:void 0);break;case"loop.begin":n=await c.beginLoopIteration(i,g(e.loopId,"loopId"),A(e.expectedVersion,"expectedVersion"),g(e.activity,"activity"),typeof e.taskId=="string"?e.taskId:void 0);break;case"loop.finish":n=await c.finishLoopIteration(i,g(e.loopId,"loopId"),A(e.expectedVersion,"expectedVersion"),b(e.result,"result"));break;case"loop.set_status":n=await c.setLoopStatus(i,g(e.loopId,"loopId"),A(e.expectedVersion,"expectedVersion"),g(e.status,"status"),typeof e.reason=="string"?e.reason:void 0);break;case"ownership.acquire":n=await c.acquireOwnership(i,g(e.ownerId,"ownerId"),b(e.options??{},"options"));break;case"ownership.renew":n=await c.renewOwnership(i,g(e.ownerId,"ownerId"),g(e.leaseId,"leaseId"),typeof e.leaseMs=="number"?e.leaseMs:void 0);break;case"ownership.release":n=await c.releaseOwnership(i,g(e.ownerId,"ownerId"),g(e.leaseId,"leaseId"));break;case"handoff.create":n=await c.createHandoff({...e,sessionId:i});break;case"handoff.claim":n=await c.claimHandoff({sessionId:i,handoffId:g(e.handoffId,"handoffId"),targetOwnerId:g(e.targetOwnerId,"targetOwnerId"),...typeof e.processId=="number"?{processId:e.processId}:{},...typeof e.host=="string"?{host:e.host}:{}});break;case"handoff.complete":n=await c.completeHandoff(i,g(e.handoffId,"handoffId"),g(e.ownerId,"ownerId"),g(e.leaseId,"leaseId"));break;case"handoff.fail":n=await c.failHandoff(i,g(e.handoffId,"handoffId"),g(e.reason,"reason"));break;default:throw new d("INVALID","Unsupported coordination action")}let r=await c.getSessionState(i),s=o==="state.get"||o==="loop.get"?void 0:r.events.at(-1);return{action:o,sessionId:i,result:n,state:r,...s?{event:s}:{}}}var $=require("node:crypto"),U=require("node:os");var D=class{sessionId;ownerId;store;processId;host;leaseMs;heartbeatMs;claimHandoffId;onOwnershipLost;timer;heartbeatInFlight=!1;owner;stopped=!1;lostError;preparedHandoffId;constructor(t){if(this.store=t.store??new X,this.sessionId=t.sessionId,this.processId=t.processId??process.pid,this.host=t.host??(0,U.hostname)(),this.ownerId=t.ownerId??`runtime:${this.host}:${this.processId}:${(0,$.randomUUID)().slice(0,8)}`,this.leaseMs=t.leaseMs??3e4,this.heartbeatMs=t.heartbeatMs??Math.max(250,Math.floor(this.leaseMs/3)),this.heartbeatMs>=this.leaseMs)throw new Error("heartbeatMs must be shorter than leaseMs");this.claimHandoffId=t.claimHandoffId,this.onOwnershipLost=t.onOwnershipLost}get currentOwner(){return this.owner?structuredClone(this.owner):void 0}get active(){return!!this.owner&&!this.stopped&&this.lostError===void 0}async start(){if(this.owner)return structuredClone(this.owner);if(this.stopped)throw new Error("Execution lease session has already stopped");if(this.claimHandoffId){let t=await this.store.claimHandoff({sessionId:this.sessionId,handoffId:this.claimHandoffId,targetOwnerId:this.ownerId,processId:this.processId,host:this.host});this.owner=t.owner,await this.store.completeHandoff(this.sessionId,this.claimHandoffId,this.ownerId,this.owner.leaseId)}else this.owner=await this.store.acquireOwnership(this.sessionId,this.ownerId,{processId:this.processId,host:this.host,leaseMs:this.leaseMs});return this.timer=setInterval(()=>{this.heartbeat()},this.heartbeatMs),this.timer.unref?.(),structuredClone(this.owner)}async assertOwned(){if(this.stopped)throw new Error("Execution surface is detached");if(this.lostError)throw this.lostError;if(this.preparedHandoffId)throw new Error(`Execution surface prepared handoff ${this.preparedHandoffId} and is detached from mutation`);if(!this.owner)throw new Error("Execution ownership was not started");return this.renewHeldLease()}async renewHeldLease(){if(!this.owner)throw new Error("Execution ownership was not started");try{return this.owner=await this.store.renewOwnership(this.sessionId,this.ownerId,this.owner.leaseId,this.leaseMs),structuredClone(this.owner)}catch(t){throw this.markLost(t),t}}async prepareHandoff(t={}){if(this.preparedHandoffId)throw new Error(`Handoff ${this.preparedHandoffId} is already prepared`);let o=await this.assertOwned(),i=await this.store.createHandoff({...t,sessionId:this.sessionId,sourceOwnerId:o.ownerId,sourceLeaseId:o.leaseId});return this.preparedHandoffId=i.id,i}async stop(t={}){if(this.stopped)return;this.stopped=!0,this.timer&&clearInterval(this.timer),this.timer=void 0;let o=this.owner;if(this.owner=void 0,!(t.release===!1||this.preparedHandoffId||!o||this.lostError))try{await this.store.releaseOwnership(this.sessionId,o.ownerId,o.leaseId)}catch{}}async heartbeat(){if(!(!this.active||this.heartbeatInFlight)){this.heartbeatInFlight=!0;try{await this.renewHeldLease()}catch(t){this.markLost(t)}finally{this.heartbeatInFlight=!1}}}markLost(t){this.lostError===void 0&&(this.lostError=t,this.timer&&clearInterval(this.timer),this.timer=void 0,this.onOwnershipLost?.(t))}};0&&(module.exports={DurableXenoCoordinationStore,XENO_COORDINATION_BUDGET_SESSION_SCHEMA_VERSION,XENO_COORDINATION_MANAGED_SESSION_SCHEMA_VERSION,XENO_COORDINATION_SCHEMA_VERSION,XENO_COORDINATION_TURN_SESSION_SCHEMA_VERSION,XenoCoordinationError,XenoExecutionLeaseSession,executeXenoCoordinationAction});
@@ -1,5 +1,7 @@
1
1
  declare const XENO_COORDINATION_SCHEMA_VERSION: 1;
2
2
  declare const XENO_COORDINATION_MANAGED_SESSION_SCHEMA_VERSION: 2;
3
+ declare const XENO_COORDINATION_BUDGET_SESSION_SCHEMA_VERSION: 3;
4
+ declare const XENO_COORDINATION_TURN_SESSION_SCHEMA_VERSION: 4;
3
5
  type XenoGoalStatus = "active" | "paused" | "waiting" | "blocked" | "completed" | "failed" | "cancelled";
4
6
  type XenoGoalTaskStatus = "pending" | "ready" | "running" | "blocked" | "failed" | "completed" | "cancelled" | "interrupted";
5
7
  interface XenoGoalCriterion {
@@ -105,6 +107,45 @@ interface XenoLoopIteration {
105
107
  taskId?: string;
106
108
  verificationEventId?: string;
107
109
  error?: string;
110
+ goalTurn?: {
111
+ requestId: string;
112
+ requestHash: string;
113
+ executor: {
114
+ kind: "local-sdk";
115
+ processId: number;
116
+ host: string;
117
+ } | {
118
+ kind: "external";
119
+ };
120
+ };
121
+ goalAccountingVersion?: 1;
122
+ }
123
+ interface XenoGoalTurnRequest {
124
+ sessionId: string;
125
+ goalId: string;
126
+ expectedGoalVersion: number;
127
+ expectedLoopId?: string;
128
+ expectedLoopVersion?: number;
129
+ requestId: string;
130
+ requestHash: string;
131
+ executionKind?: "local-sdk" | "external";
132
+ }
133
+ interface XenoGoalTurnState {
134
+ goal: XenoGoalRecord;
135
+ admittedTurns: number;
136
+ accountingCoverage: "complete" | "partial";
137
+ loopId?: string;
138
+ loopVersion?: number;
139
+ loopStatus?: XenoLoopStatus;
140
+ requestId?: string;
141
+ requestHash?: string;
142
+ iterationNumber?: number;
143
+ iterationStatus?: XenoLoopIteration["status"];
144
+ resumeRequested?: boolean;
145
+ canRecover?: boolean;
146
+ }
147
+ interface XenoGoalTurnAdmission extends XenoGoalTurnState {
148
+ admitted: boolean;
108
149
  }
109
150
  interface XenoLoopRecord {
110
151
  schemaVersion: typeof XENO_COORDINATION_SCHEMA_VERSION;
@@ -115,6 +156,7 @@ interface XenoLoopRecord {
115
156
  kind: XenoLoopKind;
116
157
  status: XenoLoopStatus;
117
158
  currentActivity?: string;
159
+ resumeRequested?: boolean;
118
160
  iterations: XenoLoopIteration[];
119
161
  schedule?: XenoLoopSchedule;
120
162
  stopReason?: string;
@@ -182,13 +224,18 @@ interface XenoCoordinationEvent {
182
224
  data: Record<string, unknown>;
183
225
  }
184
226
  interface XenoCoordinationSessionState {
185
- schemaVersion: typeof XENO_COORDINATION_SCHEMA_VERSION | typeof XENO_COORDINATION_MANAGED_SESSION_SCHEMA_VERSION;
227
+ schemaVersion: typeof XENO_COORDINATION_SCHEMA_VERSION | typeof XENO_COORDINATION_MANAGED_SESSION_SCHEMA_VERSION | typeof XENO_COORDINATION_BUDGET_SESSION_SCHEMA_VERSION | typeof XENO_COORDINATION_TURN_SESSION_SCHEMA_VERSION;
186
228
  sessionId: string;
187
229
  version: number;
188
230
  ownershipEpoch: number;
189
231
  admissionFence?: XenoCoordinationAdmissionFence;
190
232
  owner?: XenoExecutionOwner;
191
233
  goals: XenoGoalRecord[];
234
+ goalTurnAccounting?: Record<string, {
235
+ schemaVersion: 1;
236
+ baseIterations: number;
237
+ coverage: "complete" | "partial";
238
+ }>;
192
239
  loops: XenoLoopRecord[];
193
240
  handoffs: XenoHandoffRecord[];
194
241
  events: XenoCoordinationEvent[];
@@ -238,9 +285,9 @@ interface CreateXenoHandoffInput {
238
285
  contextDigest?: string;
239
286
  }
240
287
  declare class XenoCoordinationError extends Error {
241
- readonly code: "INVALID" | "NOT_FOUND" | "CONFLICT" | "NOT_OWNER" | "LEASE_EXPIRED" | "UNSAFE_HANDOFF" | "VERIFICATION_REQUIRED";
288
+ readonly code: "INVALID" | "NOT_FOUND" | "CONFLICT" | "NOT_OWNER" | "LEASE_EXPIRED" | "BUDGET_EXCEEDED" | "BUDGET_UNAVAILABLE" | "UNSAFE_HANDOFF" | "VERIFICATION_REQUIRED";
242
289
  readonly details: Record<string, unknown>;
243
- constructor(code: "INVALID" | "NOT_FOUND" | "CONFLICT" | "NOT_OWNER" | "LEASE_EXPIRED" | "UNSAFE_HANDOFF" | "VERIFICATION_REQUIRED", message: string, details?: Record<string, unknown>);
290
+ constructor(code: "INVALID" | "NOT_FOUND" | "CONFLICT" | "NOT_OWNER" | "LEASE_EXPIRED" | "BUDGET_EXCEEDED" | "BUDGET_UNAVAILABLE" | "UNSAFE_HANDOFF" | "VERIFICATION_REQUIRED", message: string, details?: Record<string, unknown>);
244
291
  }
245
292
  interface UpdateXenoGoalInput {
246
293
  objective?: string;
@@ -267,6 +314,7 @@ interface ClaimXenoHandoffInput {
267
314
  host?: string;
268
315
  }
269
316
  declare class DurableXenoCoordinationStore {
317
+ get goalTurnAdmissionVersion(): 1;
270
318
  private readonly rootDirectory;
271
319
  private readonly now;
272
320
  private readonly idFactory;
@@ -308,14 +356,23 @@ declare class DurableXenoCoordinationStore {
308
356
  completeGoal(sessionId: string, goalId: string, expectedVersion: number, verification: XenoGoalVerification): Promise<XenoGoalRecord>;
309
357
  cancelGoal(sessionId: string, goalId: string, expectedVersion: number, reason: string): Promise<XenoGoalRecord>;
310
358
  startLoop(input: StartXenoLoopInput): Promise<XenoLoopRecord>;
359
+ private createLoopRecord;
311
360
  getLoop(sessionId: string, loopId?: string): Promise<XenoLoopRecord | undefined>;
312
361
  beginLoopIteration(sessionId: string, loopId: string, expectedVersion: number, activity: string, taskId?: string): Promise<XenoLoopRecord>;
362
+ private appendLoopIteration;
363
+ admitGoalTurn(input: XenoGoalTurnRequest): Promise<XenoGoalTurnAdmission>;
364
+ getGoalTurnState(sessionId: string, goalId?: string, requestId?: string): Promise<XenoGoalTurnState | undefined>;
365
+ finishGoalTurn(input: Omit<XenoGoalTurnRequest, "expectedGoalVersion"> & {
366
+ status: "completed" | "failed" | "interrupted";
367
+ }): Promise<XenoGoalTurnState>;
368
+ recoverGoalTurn(sessionId: string, goalId: string, requestId: string): Promise<XenoGoalTurnState>;
313
369
  finishLoopIteration(sessionId: string, loopId: string, expectedVersion: number, result: {
314
370
  status: "completed" | "failed" | "interrupted";
315
371
  verificationEventId?: string;
316
372
  error?: string;
317
373
  nextStatus?: Extract<XenoLoopStatus, "running" | "waiting" | "failed">;
318
374
  }): Promise<XenoLoopRecord>;
375
+ private settleLoopIteration;
319
376
  setLoopStatus(sessionId: string, loopId: string, expectedVersion: number, status: Extract<XenoLoopStatus, "paused" | "running" | "waiting" | "stopped" | "completed" | "failed">, reason?: string): Promise<XenoLoopRecord>;
320
377
  acquireOwnership(sessionId: string, ownerId: string, options?: {
321
378
  processId?: number;
@@ -333,6 +390,14 @@ declare class DurableXenoCoordinationStore {
333
390
  failHandoff(sessionId: string, handoffId: string, reason: string): Promise<XenoHandoffRecord>;
334
391
  private mutateGoal;
335
392
  private mutateLoop;
393
+ private assertGoalIterationAdmission;
394
+ private isCliGoal;
395
+ private goalIterationCount;
396
+ private resolveGoalTurnAccounting;
397
+ private initializeGoalTurnAccounting;
398
+ private goalTurnHash;
399
+ private goalTurnState;
400
+ private goalTurnOwnerExited;
336
401
  private recalculateProgress;
337
402
  private requireGoal;
338
403
  private requireOwner;
@@ -344,6 +409,7 @@ declare class DurableXenoCoordinationStore {
344
409
  private statePath;
345
410
  private lockPath;
346
411
  private readState;
412
+ private promoteGoalBudgetEnvelope;
347
413
  private writeState;
348
414
  private renameReplacing;
349
415
  private withSessionLock;
@@ -404,4 +470,4 @@ declare class XenoExecutionLeaseSession {
404
470
  private heartbeat;
405
471
  private markLost;
406
472
  }
407
- export { type ClaimXenoHandoffInput, type CreateXenoGoalInput, type CreateXenoHandoffInput, DurableXenoCoordinationStore, type ExecuteXenoCoordinationActionInput, type ExecuteXenoCoordinationActionResult, type StartXenoLoopInput, type UpdateXenoGoalInput, XENO_COORDINATION_MANAGED_SESSION_SCHEMA_VERSION, XENO_COORDINATION_SCHEMA_VERSION, type XenoCoordinationAction, type XenoCoordinationAdmissionFence, XenoCoordinationError, type XenoCoordinationEvent, type XenoCoordinationEventType, type XenoCoordinationSessionState, type XenoCoordinationStoreOptions, XenoExecutionLeaseSession, type XenoExecutionLeaseSessionOptions, type XenoExecutionOwner, type XenoGoalCriterion, type XenoGoalCriterionResult, type XenoGoalMilestone, type XenoGoalProgress, type XenoGoalRecord, type XenoGoalStatus, type XenoGoalTask, type XenoGoalTaskStatus, type XenoGoalVerification, type XenoHandoffOperation, type XenoHandoffRecord, type XenoHandoffStatus, type XenoLoopIteration, type XenoLoopKind, type XenoLoopRecord, type XenoLoopSchedule, type XenoLoopStatus, executeXenoCoordinationAction };
473
+ export { type ClaimXenoHandoffInput, type CreateXenoGoalInput, type CreateXenoHandoffInput, DurableXenoCoordinationStore, type ExecuteXenoCoordinationActionInput, type ExecuteXenoCoordinationActionResult, type StartXenoLoopInput, type UpdateXenoGoalInput, XENO_COORDINATION_BUDGET_SESSION_SCHEMA_VERSION, XENO_COORDINATION_MANAGED_SESSION_SCHEMA_VERSION, XENO_COORDINATION_SCHEMA_VERSION, XENO_COORDINATION_TURN_SESSION_SCHEMA_VERSION, type XenoCoordinationAction, type XenoCoordinationAdmissionFence, XenoCoordinationError, type XenoCoordinationEvent, type XenoCoordinationEventType, type XenoCoordinationSessionState, type XenoCoordinationStoreOptions, XenoExecutionLeaseSession, type XenoExecutionLeaseSessionOptions, type XenoExecutionOwner, type XenoGoalCriterion, type XenoGoalCriterionResult, type XenoGoalMilestone, type XenoGoalProgress, type XenoGoalRecord, type XenoGoalStatus, type XenoGoalTask, type XenoGoalTaskStatus, type XenoGoalTurnAdmission, type XenoGoalTurnRequest, type XenoGoalTurnState, type XenoGoalVerification, type XenoHandoffOperation, type XenoHandoffRecord, type XenoHandoffStatus, type XenoLoopIteration, type XenoLoopKind, type XenoLoopRecord, type XenoLoopSchedule, type XenoLoopStatus, executeXenoCoordinationAction };
@@ -1,5 +1,7 @@
1
1
  declare const XENO_COORDINATION_SCHEMA_VERSION: 1;
2
2
  declare const XENO_COORDINATION_MANAGED_SESSION_SCHEMA_VERSION: 2;
3
+ declare const XENO_COORDINATION_BUDGET_SESSION_SCHEMA_VERSION: 3;
4
+ declare const XENO_COORDINATION_TURN_SESSION_SCHEMA_VERSION: 4;
3
5
  type XenoGoalStatus = "active" | "paused" | "waiting" | "blocked" | "completed" | "failed" | "cancelled";
4
6
  type XenoGoalTaskStatus = "pending" | "ready" | "running" | "blocked" | "failed" | "completed" | "cancelled" | "interrupted";
5
7
  interface XenoGoalCriterion {
@@ -105,6 +107,45 @@ interface XenoLoopIteration {
105
107
  taskId?: string;
106
108
  verificationEventId?: string;
107
109
  error?: string;
110
+ goalTurn?: {
111
+ requestId: string;
112
+ requestHash: string;
113
+ executor: {
114
+ kind: "local-sdk";
115
+ processId: number;
116
+ host: string;
117
+ } | {
118
+ kind: "external";
119
+ };
120
+ };
121
+ goalAccountingVersion?: 1;
122
+ }
123
+ interface XenoGoalTurnRequest {
124
+ sessionId: string;
125
+ goalId: string;
126
+ expectedGoalVersion: number;
127
+ expectedLoopId?: string;
128
+ expectedLoopVersion?: number;
129
+ requestId: string;
130
+ requestHash: string;
131
+ executionKind?: "local-sdk" | "external";
132
+ }
133
+ interface XenoGoalTurnState {
134
+ goal: XenoGoalRecord;
135
+ admittedTurns: number;
136
+ accountingCoverage: "complete" | "partial";
137
+ loopId?: string;
138
+ loopVersion?: number;
139
+ loopStatus?: XenoLoopStatus;
140
+ requestId?: string;
141
+ requestHash?: string;
142
+ iterationNumber?: number;
143
+ iterationStatus?: XenoLoopIteration["status"];
144
+ resumeRequested?: boolean;
145
+ canRecover?: boolean;
146
+ }
147
+ interface XenoGoalTurnAdmission extends XenoGoalTurnState {
148
+ admitted: boolean;
108
149
  }
109
150
  interface XenoLoopRecord {
110
151
  schemaVersion: typeof XENO_COORDINATION_SCHEMA_VERSION;
@@ -115,6 +156,7 @@ interface XenoLoopRecord {
115
156
  kind: XenoLoopKind;
116
157
  status: XenoLoopStatus;
117
158
  currentActivity?: string;
159
+ resumeRequested?: boolean;
118
160
  iterations: XenoLoopIteration[];
119
161
  schedule?: XenoLoopSchedule;
120
162
  stopReason?: string;
@@ -182,13 +224,18 @@ interface XenoCoordinationEvent {
182
224
  data: Record<string, unknown>;
183
225
  }
184
226
  interface XenoCoordinationSessionState {
185
- schemaVersion: typeof XENO_COORDINATION_SCHEMA_VERSION | typeof XENO_COORDINATION_MANAGED_SESSION_SCHEMA_VERSION;
227
+ schemaVersion: typeof XENO_COORDINATION_SCHEMA_VERSION | typeof XENO_COORDINATION_MANAGED_SESSION_SCHEMA_VERSION | typeof XENO_COORDINATION_BUDGET_SESSION_SCHEMA_VERSION | typeof XENO_COORDINATION_TURN_SESSION_SCHEMA_VERSION;
186
228
  sessionId: string;
187
229
  version: number;
188
230
  ownershipEpoch: number;
189
231
  admissionFence?: XenoCoordinationAdmissionFence;
190
232
  owner?: XenoExecutionOwner;
191
233
  goals: XenoGoalRecord[];
234
+ goalTurnAccounting?: Record<string, {
235
+ schemaVersion: 1;
236
+ baseIterations: number;
237
+ coverage: "complete" | "partial";
238
+ }>;
192
239
  loops: XenoLoopRecord[];
193
240
  handoffs: XenoHandoffRecord[];
194
241
  events: XenoCoordinationEvent[];
@@ -238,9 +285,9 @@ interface CreateXenoHandoffInput {
238
285
  contextDigest?: string;
239
286
  }
240
287
  declare class XenoCoordinationError extends Error {
241
- readonly code: "INVALID" | "NOT_FOUND" | "CONFLICT" | "NOT_OWNER" | "LEASE_EXPIRED" | "UNSAFE_HANDOFF" | "VERIFICATION_REQUIRED";
288
+ readonly code: "INVALID" | "NOT_FOUND" | "CONFLICT" | "NOT_OWNER" | "LEASE_EXPIRED" | "BUDGET_EXCEEDED" | "BUDGET_UNAVAILABLE" | "UNSAFE_HANDOFF" | "VERIFICATION_REQUIRED";
242
289
  readonly details: Record<string, unknown>;
243
- constructor(code: "INVALID" | "NOT_FOUND" | "CONFLICT" | "NOT_OWNER" | "LEASE_EXPIRED" | "UNSAFE_HANDOFF" | "VERIFICATION_REQUIRED", message: string, details?: Record<string, unknown>);
290
+ constructor(code: "INVALID" | "NOT_FOUND" | "CONFLICT" | "NOT_OWNER" | "LEASE_EXPIRED" | "BUDGET_EXCEEDED" | "BUDGET_UNAVAILABLE" | "UNSAFE_HANDOFF" | "VERIFICATION_REQUIRED", message: string, details?: Record<string, unknown>);
244
291
  }
245
292
  interface UpdateXenoGoalInput {
246
293
  objective?: string;
@@ -267,6 +314,7 @@ interface ClaimXenoHandoffInput {
267
314
  host?: string;
268
315
  }
269
316
  declare class DurableXenoCoordinationStore {
317
+ get goalTurnAdmissionVersion(): 1;
270
318
  private readonly rootDirectory;
271
319
  private readonly now;
272
320
  private readonly idFactory;
@@ -308,14 +356,23 @@ declare class DurableXenoCoordinationStore {
308
356
  completeGoal(sessionId: string, goalId: string, expectedVersion: number, verification: XenoGoalVerification): Promise<XenoGoalRecord>;
309
357
  cancelGoal(sessionId: string, goalId: string, expectedVersion: number, reason: string): Promise<XenoGoalRecord>;
310
358
  startLoop(input: StartXenoLoopInput): Promise<XenoLoopRecord>;
359
+ private createLoopRecord;
311
360
  getLoop(sessionId: string, loopId?: string): Promise<XenoLoopRecord | undefined>;
312
361
  beginLoopIteration(sessionId: string, loopId: string, expectedVersion: number, activity: string, taskId?: string): Promise<XenoLoopRecord>;
362
+ private appendLoopIteration;
363
+ admitGoalTurn(input: XenoGoalTurnRequest): Promise<XenoGoalTurnAdmission>;
364
+ getGoalTurnState(sessionId: string, goalId?: string, requestId?: string): Promise<XenoGoalTurnState | undefined>;
365
+ finishGoalTurn(input: Omit<XenoGoalTurnRequest, "expectedGoalVersion"> & {
366
+ status: "completed" | "failed" | "interrupted";
367
+ }): Promise<XenoGoalTurnState>;
368
+ recoverGoalTurn(sessionId: string, goalId: string, requestId: string): Promise<XenoGoalTurnState>;
313
369
  finishLoopIteration(sessionId: string, loopId: string, expectedVersion: number, result: {
314
370
  status: "completed" | "failed" | "interrupted";
315
371
  verificationEventId?: string;
316
372
  error?: string;
317
373
  nextStatus?: Extract<XenoLoopStatus, "running" | "waiting" | "failed">;
318
374
  }): Promise<XenoLoopRecord>;
375
+ private settleLoopIteration;
319
376
  setLoopStatus(sessionId: string, loopId: string, expectedVersion: number, status: Extract<XenoLoopStatus, "paused" | "running" | "waiting" | "stopped" | "completed" | "failed">, reason?: string): Promise<XenoLoopRecord>;
320
377
  acquireOwnership(sessionId: string, ownerId: string, options?: {
321
378
  processId?: number;
@@ -333,6 +390,14 @@ declare class DurableXenoCoordinationStore {
333
390
  failHandoff(sessionId: string, handoffId: string, reason: string): Promise<XenoHandoffRecord>;
334
391
  private mutateGoal;
335
392
  private mutateLoop;
393
+ private assertGoalIterationAdmission;
394
+ private isCliGoal;
395
+ private goalIterationCount;
396
+ private resolveGoalTurnAccounting;
397
+ private initializeGoalTurnAccounting;
398
+ private goalTurnHash;
399
+ private goalTurnState;
400
+ private goalTurnOwnerExited;
336
401
  private recalculateProgress;
337
402
  private requireGoal;
338
403
  private requireOwner;
@@ -344,6 +409,7 @@ declare class DurableXenoCoordinationStore {
344
409
  private statePath;
345
410
  private lockPath;
346
411
  private readState;
412
+ private promoteGoalBudgetEnvelope;
347
413
  private writeState;
348
414
  private renameReplacing;
349
415
  private withSessionLock;
@@ -404,4 +470,4 @@ declare class XenoExecutionLeaseSession {
404
470
  private heartbeat;
405
471
  private markLost;
406
472
  }
407
- export { type ClaimXenoHandoffInput, type CreateXenoGoalInput, type CreateXenoHandoffInput, DurableXenoCoordinationStore, type ExecuteXenoCoordinationActionInput, type ExecuteXenoCoordinationActionResult, type StartXenoLoopInput, type UpdateXenoGoalInput, XENO_COORDINATION_MANAGED_SESSION_SCHEMA_VERSION, XENO_COORDINATION_SCHEMA_VERSION, type XenoCoordinationAction, type XenoCoordinationAdmissionFence, XenoCoordinationError, type XenoCoordinationEvent, type XenoCoordinationEventType, type XenoCoordinationSessionState, type XenoCoordinationStoreOptions, XenoExecutionLeaseSession, type XenoExecutionLeaseSessionOptions, type XenoExecutionOwner, type XenoGoalCriterion, type XenoGoalCriterionResult, type XenoGoalMilestone, type XenoGoalProgress, type XenoGoalRecord, type XenoGoalStatus, type XenoGoalTask, type XenoGoalTaskStatus, type XenoGoalVerification, type XenoHandoffOperation, type XenoHandoffRecord, type XenoHandoffStatus, type XenoLoopIteration, type XenoLoopKind, type XenoLoopRecord, type XenoLoopSchedule, type XenoLoopStatus, executeXenoCoordinationAction };
473
+ export { type ClaimXenoHandoffInput, type CreateXenoGoalInput, type CreateXenoHandoffInput, DurableXenoCoordinationStore, type ExecuteXenoCoordinationActionInput, type ExecuteXenoCoordinationActionResult, type StartXenoLoopInput, type UpdateXenoGoalInput, XENO_COORDINATION_BUDGET_SESSION_SCHEMA_VERSION, XENO_COORDINATION_MANAGED_SESSION_SCHEMA_VERSION, XENO_COORDINATION_SCHEMA_VERSION, XENO_COORDINATION_TURN_SESSION_SCHEMA_VERSION, type XenoCoordinationAction, type XenoCoordinationAdmissionFence, XenoCoordinationError, type XenoCoordinationEvent, type XenoCoordinationEventType, type XenoCoordinationSessionState, type XenoCoordinationStoreOptions, XenoExecutionLeaseSession, type XenoExecutionLeaseSessionOptions, type XenoExecutionOwner, type XenoGoalCriterion, type XenoGoalCriterionResult, type XenoGoalMilestone, type XenoGoalProgress, type XenoGoalRecord, type XenoGoalStatus, type XenoGoalTask, type XenoGoalTaskStatus, type XenoGoalTurnAdmission, type XenoGoalTurnRequest, type XenoGoalTurnState, type XenoGoalVerification, type XenoHandoffOperation, type XenoHandoffRecord, type XenoHandoffStatus, type XenoLoopIteration, type XenoLoopKind, type XenoLoopRecord, type XenoLoopSchedule, type XenoLoopStatus, executeXenoCoordinationAction };