@xenosystem/agent-cli 0.5.107 → 0.5.108

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 (77) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/index.js +2 -2
  3. package/dist/metafile-esm.json +1 -1
  4. package/dist/sdk-build-identity.json +4 -4
  5. package/native/xeno-pty/prebuilds/win32-x64/manifest.json +18 -18
  6. package/node_modules/@xeno-corporation/account/LICENSE +39 -0
  7. package/node_modules/@xeno-corporation/account/README.md +211 -0
  8. package/node_modules/@xeno-corporation/account/dist/chunk-FELZILY4.mjs +60 -0
  9. package/node_modules/@xeno-corporation/account/dist/chunk-FELZILY4.mjs.map +1 -0
  10. package/node_modules/@xeno-corporation/account/dist/index.d.mts +883 -0
  11. package/node_modules/@xeno-corporation/account/dist/index.d.ts +883 -0
  12. package/node_modules/@xeno-corporation/account/dist/index.js +2301 -0
  13. package/node_modules/@xeno-corporation/account/dist/index.js.map +1 -0
  14. package/node_modules/@xeno-corporation/account/dist/index.mjs +2191 -0
  15. package/node_modules/@xeno-corporation/account/dist/index.mjs.map +1 -0
  16. package/node_modules/@xeno-corporation/account/dist/node.d.mts +35 -0
  17. package/node_modules/@xeno-corporation/account/dist/node.d.ts +35 -0
  18. package/node_modules/@xeno-corporation/account/dist/node.js +715 -0
  19. package/node_modules/@xeno-corporation/account/dist/node.js.map +1 -0
  20. package/node_modules/@xeno-corporation/account/dist/node.mjs +645 -0
  21. package/node_modules/@xeno-corporation/account/dist/node.mjs.map +1 -0
  22. package/node_modules/@xeno-corporation/account/dist/tokenStore-CnIo2ILq.d.mts +47 -0
  23. package/node_modules/@xeno-corporation/account/dist/tokenStore-CnIo2ILq.d.ts +47 -0
  24. package/node_modules/@xeno-corporation/account/package.json +60 -0
  25. package/node_modules/zod/LICENSE +21 -0
  26. package/node_modules/zod/README.md +3028 -0
  27. package/node_modules/zod/index.d.ts +2 -0
  28. package/node_modules/zod/lib/ZodError.d.ts +164 -0
  29. package/node_modules/zod/lib/ZodError.js +137 -0
  30. package/node_modules/zod/lib/__tests__/Mocker.d.ts +17 -0
  31. package/node_modules/zod/lib/__tests__/Mocker.js +57 -0
  32. package/node_modules/zod/lib/benchmarks/datetime.d.ts +5 -0
  33. package/node_modules/zod/lib/benchmarks/datetime.js +54 -0
  34. package/node_modules/zod/lib/benchmarks/discriminatedUnion.d.ts +5 -0
  35. package/node_modules/zod/lib/benchmarks/discriminatedUnion.js +79 -0
  36. package/node_modules/zod/lib/benchmarks/index.d.ts +1 -0
  37. package/node_modules/zod/lib/benchmarks/index.js +59 -0
  38. package/node_modules/zod/lib/benchmarks/ipv4.d.ts +5 -0
  39. package/node_modules/zod/lib/benchmarks/ipv4.js +54 -0
  40. package/node_modules/zod/lib/benchmarks/object.d.ts +5 -0
  41. package/node_modules/zod/lib/benchmarks/object.js +70 -0
  42. package/node_modules/zod/lib/benchmarks/primitives.d.ts +5 -0
  43. package/node_modules/zod/lib/benchmarks/primitives.js +170 -0
  44. package/node_modules/zod/lib/benchmarks/realworld.d.ts +5 -0
  45. package/node_modules/zod/lib/benchmarks/realworld.js +56 -0
  46. package/node_modules/zod/lib/benchmarks/string.d.ts +5 -0
  47. package/node_modules/zod/lib/benchmarks/string.js +55 -0
  48. package/node_modules/zod/lib/benchmarks/union.d.ts +5 -0
  49. package/node_modules/zod/lib/benchmarks/union.js +79 -0
  50. package/node_modules/zod/lib/errors.d.ts +5 -0
  51. package/node_modules/zod/lib/errors.js +17 -0
  52. package/node_modules/zod/lib/external.d.ts +6 -0
  53. package/node_modules/zod/lib/external.js +22 -0
  54. package/node_modules/zod/lib/helpers/enumUtil.d.ts +8 -0
  55. package/node_modules/zod/lib/helpers/enumUtil.js +2 -0
  56. package/node_modules/zod/lib/helpers/errorUtil.d.ts +9 -0
  57. package/node_modules/zod/lib/helpers/errorUtil.js +8 -0
  58. package/node_modules/zod/lib/helpers/parseUtil.d.ts +78 -0
  59. package/node_modules/zod/lib/helpers/parseUtil.js +125 -0
  60. package/node_modules/zod/lib/helpers/partialUtil.d.ts +8 -0
  61. package/node_modules/zod/lib/helpers/partialUtil.js +2 -0
  62. package/node_modules/zod/lib/helpers/typeAliases.d.ts +2 -0
  63. package/node_modules/zod/lib/helpers/typeAliases.js +2 -0
  64. package/node_modules/zod/lib/helpers/util.d.ts +82 -0
  65. package/node_modules/zod/lib/helpers/util.js +142 -0
  66. package/node_modules/zod/lib/index.d.ts +4 -0
  67. package/node_modules/zod/lib/index.js +33 -0
  68. package/node_modules/zod/lib/index.mjs +4382 -0
  69. package/node_modules/zod/lib/index.umd.js +4497 -0
  70. package/node_modules/zod/lib/locales/en.d.ts +3 -0
  71. package/node_modules/zod/lib/locales/en.js +129 -0
  72. package/node_modules/zod/lib/standard-schema.d.ts +102 -0
  73. package/node_modules/zod/lib/standard-schema.js +2 -0
  74. package/node_modules/zod/lib/types.d.ts +1062 -0
  75. package/node_modules/zod/lib/types.js +3823 -0
  76. package/node_modules/zod/package.json +122 -0
  77. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2902,7 +2902,7 @@ ${_e}${ee.compose(KW(),ee.bold)("\u2717")} ${rB(e)}
2902
2902
  `)}function OC(){return`
2903
2903
  ${_e}${Ce("Goodbye.")}
2904
2904
  `}var oVt,n5e,KW,sn,Ce,iB,rB,iVt,sB,sVt,cVt,lVt,q,_e,c5e,ble,C,Ele,s5e,oB,rs=ge(()=>{"use strict";Xa();bd();qHe();XW();yle();oVt=new af(process.stdout),n5e=new af(process.stderr),KW=()=>Lo(),sn=e=>KW()(e),Ce=ee.dim,iB=ee.bold,rB=e=>KW()(e),iVt="\u25A0",sB="\u2514",sVt={open:"\x1B[4m",close:"\x1B[24m"};cVt={Read:e=>yd()(e),ReadImage:e=>yd()(e),Glob:e=>yd()(e),Grep:e=>yd()(e),ElfAnalyze:e=>yd()(e),MemoryRead:e=>yd()(e),Write:e=>nB()(e),Edit:e=>nB()(e),MemoryWrite:e=>nB()(e),Bash:e=>ule()(e),GitStatus:e=>yd()(e),GitDiff:e=>yd()(e),GitLog:e=>yd()(e),GitBranch:e=>yd()(e),GitCommit:e=>ule()(e),WebSearch:e=>ee.cyan(e),WebFetch:e=>ee.cyan(e),TaskOutput:e=>yd()(e),TaskInput:e=>ee.cyan(e),TaskStop:e=>Av()(e)};lVt={Edit:"Update",Glob:"Search",Grep:"Search",WebSearch:"Web Search",WebFetch:"Web Fetch"};q={accent:sn,purple:rB,cyan:rB,dim:Ce,bold:iB,red:rB,green:rB},_e=" ",c5e=1e3,ble=3;C={moveTo:(e,t)=>`\x1B[${e};${t}H`,saveCursor:()=>"\x1B[s",restoreCursor:()=>"\x1B[u",setScrollRegion:(e,t)=>`\x1B[${e};${t}r`,resetScrollRegion:()=>"\x1B[r",eraseLine:()=>"\x1B[2K",clearScreen:()=>"\x1B[2J\x1B[3J\x1B[H",showCursor:()=>"\x1B[?25h",hideCursor:()=>"\x1B[?25l",disableWrap:()=>"\x1B[?7l",enableWrap:()=>"\x1B[?7h",enableMouseReporting:()=>"\x1B[?1000h\x1B[?1006h",disableMouseReporting:()=>"\x1B[?1006l\x1B[?1000l",enableBracketedPaste:()=>"\x1B[?2004h",disableBracketedPaste:()=>"\x1B[?2004l"};Ele=class{atLineStart=!0;writeFn;constructor(t){this.writeFn=t??(n=>{oVt.writeOrdered(n,"stream")})}write(t){let n="";for(let r of t)this.atLineStart&&(n+=_e,this.atLineStart=!1),n+=r,r===`
2905
- `&&(this.atLineStart=!0);this.writeFn(n)}reset(){this.atLineStart=!0}markLineStarted(){this.atLineStart=!1}},s5e=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],oB=class{interval=null;frameIndex=0;lastLength=0;writeFn;clearFn;constructor(t,n){this.writeFn=t??(r=>{n5e.writeFrame(r,"spinner")}),this.clearFn=n??(()=>{n5e.writeFrame(`\r${" ".repeat(this.lastLength)}\r`,"spinner")})}start(t){this.stop(),this.frameIndex=0,this.interval=setInterval(()=>{let n=s5e[this.frameIndex%s5e.length],r=`${sn(n)} ${Ce(t)}`;this.writeFn(`\r${" ".repeat(this.lastLength)}\r${r}`),this.lastLength=t.length+4,this.frameIndex++},80)}stop(){this.interval&&(clearInterval(this.interval),this.interval=null,this.clearFn(),this.lastLength=0)}}});var Re,Ko=ge(()=>{"use strict";Re="0.5.107"});var ede,lWe=ge(()=>{"use strict";ede="1.0.0"});var yWe={};oa(yWe,{TERMINAL_WEB_JOB_STATES:()=>nde,WEB_JOB_PROGRESS_OPERATIONS:()=>hWe,WEB_JOB_PROGRESS_SCHEMA:()=>HC,WEB_JOB_PROGRESS_SCHEMA_VERSION:()=>gV,WEB_JOB_PROGRESS_STATES:()=>gWe,deriveWebJobProgress:()=>AV,isTerminalWebJobState:()=>lA,isWebJobProgress:()=>AWe,parseWebJobProgress:()=>wV,webJobProgressSignature:()=>ode});function lA(e){return nde.includes(e)}function uWe(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function pWe(e,t){return Object.keys(e).every(n=>t.has(n))}function rde(e,t){return typeof e=="string"&&e.trim().length>0&&e.length<=t&&!/[\u0000-\u001f\u007f]/u.test(e)}function tde(e){return rde(e,64)&&Number.isFinite(Date.parse(e))}function wWe(e){return rde(e,120)&&/^[A-Za-z0-9._:-]+$/u.test(e)}function fWe(e){return typeof e=="number"&&Number.isSafeInteger(e)&&e>=0}function wV(e){if(!uWe(e)||!pWe(e,e4t))throw new TypeError("invalid Web Context progress object");if(e.schema!==HC||e.schemaVersion!==gV||e.contractVersion!==ede)throw new TypeError("unsupported Web Context progress schema");if(!rde(e.jobId,256))throw new TypeError("invalid Web Context progress jobId");if(!hWe.includes(e.operation))throw new TypeError("invalid Web Context progress operation");if(!gWe.includes(e.state))throw new TypeError("invalid Web Context progress state");let t=lA(e.state);if(e.terminal!==t)throw new TypeError("inconsistent Web Context terminal state");if(t){if(e.terminalState!==e.state)throw new TypeError("invalid Web Context terminalState")}else if("terminalState"in e)throw new TypeError("non-terminal Web Context progress cannot carry terminalState");if("terminalReason"in e&&(!t||!wWe(e.terminalReason)))throw new TypeError("invalid Web Context terminalReason");if(!uWe(e.counters)||!pWe(e.counters,dWe))throw new TypeError("invalid Web Context progress counters");for(let r of dWe)if(!fWe(e.counters[r]))throw new TypeError(`invalid Web Context counter ${r}`);let n=Number(e.counters.queuedPages)+Number(e.counters.activePages)+Number(e.counters.completedPages)+Number(e.counters.failedPages)+Number(e.counters.excludedPages);if(e.counters.knownPages!==n)throw new TypeError("inconsistent Web Context knownPages counter");if(!fWe(e.sequence))throw new TypeError("invalid Web Context progress sequence");if(!tde(e.observedAt))throw new TypeError("invalid Web Context observedAt");if("createdAt"in e&&!tde(e.createdAt))throw new TypeError("invalid Web Context createdAt");if("updatedAt"in e&&!tde(e.updatedAt))throw new TypeError("invalid Web Context updatedAt");return structuredClone(e)}function AWe(e){try{return wV(e),!0}catch{return!1}}function AB(e){return typeof e=="number"&&Number.isFinite(e)&&e>0?Math.floor(e):0}function mWe(e){return typeof e=="string"&&e.length>0?e:void 0}function AV(e,t,n=new Date().toISOString()){let r=AB(e.queuedPages),o=AB(e.activePages),i=AB(e.completedPages),s=AB(e.failedPages),a=AB(e.excludedPages),c={queuedPages:r,activePages:o,completedPages:i,failedPages:s,excludedPages:a,knownPages:r+o+i+s+a},l=lA(e.state),d=wWe(e.terminalReason)?e.terminalReason:void 0,u=mWe(e.createdAt),p=mWe(e.updatedAt);return{schema:HC,schemaVersion:gV,contractVersion:ede,jobId:e.jobId,operation:e.operation,state:e.state,terminal:l,...l?{terminalState:e.state}:{},...d?{terminalReason:d}:{},counters:c,sequence:t,observedAt:n,...u?{createdAt:u}:{},...p?{updatedAt:p}:{}}}function ode(e){let t=e.counters;return[e.jobId,e.operation,e.state,e.terminalReason??"",e.updatedAt??"",t.queuedPages,t.activePages,t.completedPages,t.failedPages,t.excludedPages].join("|")}var HC,gV,nde,hWe,gWe,e4t,dWe,yB=ge(()=>{"use strict";lWe();HC="xeno.web-context.job-progress",gV="1.0.0",nde=["completed","partial","failed","cancelled"],hWe=["scrape","batch-scrape","map","crawl","render","extract"],gWe=["queued","running",...nde];e4t=new Set(["schema","schemaVersion","contractVersion","jobId","operation","state","terminal","terminalState","terminalReason","counters","sequence","observedAt","createdAt","updatedAt"]),dWe=new Set(["queuedPages","activePages","completedPages","failedPages","excludedPages","knownPages"])});function n4t(e){if(e===void 0||e==="")return"";if(!t4t.test(e)||e.split("/").includes(".."))throw new TypeError("pathPrefix must be an absolute path such as /v1/web");return e}function bB(e){return e.signal?{signal:e.signal}:{}}function r4t(e,t){if(!t)return`scrape job ended in ${e}`;let[n,r]=t.split(":",2),o=r?` (${r})`:"";switch(n){case"SITE_BLOCKED":return`the site refused the request${o}; it blocks automated access, so use another source`;case"RATE_LIMITED":return"the site is rate-limiting requests; try again later";case"NOT_FOUND":return"the page does not exist (HTTP 404/410)";case"NETWORK_ERROR":return"the site could not be reached (network error)";case"DEADLINE_EXCEEDED":return"the page did not respond within the time budget";case"MIME_DENIED":return"the page is not a supported document type";case"ROBOTS_DENIED":case"ROBOTS_DISALLOWED":return"the site's robots.txt does not allow this page to be fetched";case"ROBOTS_UNAVAILABLE":return"the site's robots.txt could not be read, so the page was not fetched";default:return/^HTTP_\d{3}$/.test(n??"")?`the site answered HTTP ${n.slice(5)}`:`the page could not be retrieved (${t})`}}function bWe(e,t){let n=e;return{message:t,...typeof n?.code=="string"?{code:n.code}:{},...typeof n?.status=="number"?{status:n.status}:{}}}function o4t(e,t){if(typeof e!="object"||e===null||!Object.isExtensible(e))return e;try{Object.defineProperty(e,"cancellation",{value:t,enumerable:!0,configurable:!0,writable:!0})}catch{}return e}function i4t(e,t){let n=0,r,o=!1;return async i=>{if(!e)return;let s=lA(i.state);if(s&&o)return;let a=AV(i,n),c=ode(a);if(!(r===c&&!s)){r=c,n+=1,s&&(o=!0);try{await e(a)}catch(l){throw Object.assign(new Error("job progress listener failed"),{code:"PROGRESS_LISTENER_FAILED",jobId:t,state:a.state,cause:l})}}}}var t4t,vB,vWe=ge(()=>{"use strict";yB();yB();t4t=/^\/[A-Za-z0-9._~-]+(?:\/[A-Za-z0-9._~-]+)*$/;vB=class{#e;#n;#r;#o;constructor(t){if(this.#e=new URL(t.baseUrl),this.#n=t.token,this.#o=n4t(t.pathPrefix),!this.#n.trim())throw new TypeError("token is required");this.#r=t.fetchImpl??fetch}#i(t){if(this.#o==="")return new URL(t,this.#e);if(!t.startsWith("/v1/"))throw new TypeError("pathPrefix can only rewrite /v1 routes");return new URL(`${this.#o}${t.slice(3)}`,this.#e)}async#t(t,n={}){let r=await this.#r(this.#i(t),{...n,redirect:"error",headers:{authorization:`Bearer ${this.#n}`,...n.body?{"content-type":"application/json"}:{},...n.headers}});if(!r.ok){let o=`HTTP ${r.status}`,i;try{let s=await r.json();o=s.error?.message??o,i=s.error?.code}catch{}throw Object.assign(new Error(o),{status:r.status,...i?{code:i}:{}})}return r.status===204?void 0:await r.json()}async#s(t,n={}){let r=await this.#r(this.#i(t),{...n,redirect:"error",headers:{authorization:`Bearer ${this.#n}`,...n.headers}});if(!r.ok){let o=`HTTP ${r.status}`,i;try{let s=await r.json();o=s.error?.message??o,i=s.error?.code}catch{}throw Object.assign(new Error(o),{status:r.status,...i?{code:i}:{}})}return r}capabilities(){return this.#t("/v1/capabilities")}account(t={}){return this.#t("/v1/account",bB(t))}usage(){return this.#t("/v1/usage")}search(t,n={}){return this.#t("/v1/search",{method:"POST",body:JSON.stringify(t),...bB(n)})}searchAndScrape(t,n={}){return this.#t("/v1/search-and-scrape",{method:"POST",body:JSON.stringify(t),...bB(n)})}scrape(t){return this.#t("/v1/scrape",{method:"POST",body:JSON.stringify(t)})}render(t){return this.#t("/v1/render",{method:"POST",body:JSON.stringify(t)})}map(t){return this.#t("/v1/map",{method:"POST",body:JSON.stringify(t)})}crawl(t){return this.#t("/v1/crawl",{method:"POST",body:JSON.stringify(t)})}batchScrape(t){return this.#t("/v1/batch-scrape",{method:"POST",body:JSON.stringify(t)})}activity(t={}){let n=new URLSearchParams;return t.limit&&n.set("limit",String(t.limit)),t.cursor&&n.set("cursor",t.cursor),this.#t(`/v1/activity?${n}`)}job(t){return this.#t(`/v1/jobs/${encodeURIComponent(t)}`)}frontier(t,n={}){let r=new URLSearchParams;return n.limit&&r.set("limit",String(n.limit)),n.cursor&&r.set("cursor",n.cursor),this.#t(`/v1/jobs/${encodeURIComponent(t)}/frontier?${r}`)}results(t,n={}){let r=new URLSearchParams;return n.limit&&r.set("limit",String(n.limit)),n.cursor&&r.set("cursor",n.cursor),this.#t(`/v1/jobs/${encodeURIComponent(t)}/results?${r}`,bB(n))}async artifact(t,n,r={}){if(!/^artifact:[a-f0-9]{64}$/i.test(n))throw new TypeError("artifactId is invalid");let o=await this.#s(`/v1/jobs/${encodeURIComponent(t)}/artifacts/${n}`,bB(r)),i=o.headers.get("etag")??void 0;return{jobId:t,artifactId:n,mediaType:o.headers.get("content-type")?.split(";",1)[0]?.trim()||"application/octet-stream",bytes:new Uint8Array(await o.arrayBuffer()),...i?{etag:i}:{}}}cancel(t){return this.#t(`/v1/jobs/${encodeURIComponent(t)}/cancel`,{method:"POST"})}resume(t){return this.#t(`/v1/jobs/${encodeURIComponent(t)}/resume`,{method:"POST"})}webhookDeliveries(t){return this.#t(`/v1/jobs/${encodeURIComponent(t)}/webhooks`)}upload(t){return this.#t("/v1/artifacts",{method:"POST",body:JSON.stringify(t)})}parse(t){return this.#t("/v1/parse",{method:"POST",body:JSON.stringify(t)})}extract(t){return this.#t("/v1/extract",{method:"POST",body:JSON.stringify(t)})}monitors(){return this.#t("/v1/monitors")}createMonitor(t){return this.#t("/v1/monitors",{method:"POST",body:JSON.stringify(t)})}monitorChecks(t,n=100){return this.#t(`/v1/monitors/${encodeURIComponent(t)}/checks?limit=${n}`)}setMonitorState(t,n){return this.#t(`/v1/monitors/${encodeURIComponent(t)}`,{method:"PATCH",body:JSON.stringify({state:n})})}removeMonitor(t){return this.#t(`/v1/monitors/${encodeURIComponent(t)}`,{method:"DELETE"})}async#a(t,n,r,o){let i;try{({job:i}=await this.cancel(t))}catch(p){return{attempted:!0,trigger:n,jobId:t,outcome:"failed",error:bWe(p,"Web Context cancellation failed")}}let s=o.cancelConfirmationMs??2e3,a=Date.now()+(Number.isFinite(s)&&s>0?s:0),c=o.pollMs??500,l,d=async p=>{try{await r(p)}catch(f){l??=bWe(f,"Web Context progress listener failed during cancellation confirmation")}};for(await d(i);!lA(i.state)&&Date.now()<a;){await new Promise(f=>{setTimeout(f,Math.min(c,Math.max(0,a-Date.now())))});let p;try{({job:p}=await this.job(t))}catch{break}i=p,await d(i)}let u=lA(i.state)?AV(i,0):void 0;return{attempted:!0,trigger:n,jobId:t,outcome:i.state==="cancelled"?"cancelled":"requested",...u?{terminalProgress:u}:{},...l?{listenerError:l}:{}}}async waitForJob(t,n={}){let r=Date.now()+(n.timeoutMs??12e4),o=i4t(n.onProgress,t),i;try{for(;Date.now()<r;){if(n.signal?.aborted)throw i="abort",n.signal.reason;let{job:s}=await this.job(t);if(await o(s),lA(s.state))return s;await new Promise((a,c)=>{let l=setTimeout(a,n.pollMs??500);n.signal?.addEventListener("abort",()=>{clearTimeout(l),i="abort",c(n.signal?.reason)},{once:!0})})}throw i="timeout",Object.assign(new Error("job wait timed out"),{code:"WAIT_TIMEOUT",jobId:t})}catch(s){let a=i==="abort"?n.cancelOnAbort===!0:i==="timeout"?n.cancelOnTimeout===!0:!1;throw!i||!a?s:o4t(s,await this.#a(t,i,o,n))}}async scrapeAndWait(t,n={}){let r=await this.scrape(t),o=await this.waitForJob(r.job.jobId,n);if(o.state!=="completed"&&o.state!=="partial"){let c;try{let d=(await this.results(o.jobId,{limit:1})).items.find(u=>typeof u.errorCode=="string")?.errorCode;typeof d=="string"&&(c=d)}catch{}throw Object.assign(new Error(r4t(o.state,c)),{code:"JOB_NOT_COMPLETED",jobId:o.jobId,state:o.state,...c?{reason:c}:{}})}let i=await this.results(o.jobId,{limit:1}),s=i.items.find(c=>c.state==="completed"&&typeof c.artifactId=="string")??i.items.find(c=>typeof c.artifactId=="string");if(!s?.artifactId)throw Object.assign(new Error("completed scrape job has no readable artifact"),{code:"JOB_ARTIFACT_MISSING",jobId:o.jobId});let a=await this.artifact(o.jobId,s.artifactId);return{job:o,item:s,artifact:a,text:new TextDecoder().decode(a.bytes)}}}});import{readFileSync as s4t}from"node:fs";function sde(e=process.env,t){let n=t??e.XENO_WEB_CONTEXT_MAX_PROVIDER_COST_USD;if(n===void 0)return;let r=Number(n.trim());if(!/^[0-9]+(?:\.[0-9]+)?$/.test(n.trim())||!Number.isFinite(r)||r<0)throw Object.assign(new Error("Web Context provider cost budget must be a finite non-negative decimal USD amount."),{code:"WEB_CONTEXT_INVALID_BUDGET"});return r}function IB(e,t,n,r=5){if(n!==void 0&&(!Number.isSafeInteger(n)||n<1))throw Object.assign(new Error("Web Context account returned an invalid page quota."),{code:"WEB_CONTEXT_INVALID_ACCOUNT"});if(e==="search"&&(!Number.isSafeInteger(r)||r<1||r>20))throw Object.assign(new Error("Web Context search result count must be an integer from 1 to 20."),{code:"WEB_CONTEXT_INVALID_BUDGET"});let o=e==="map"||e==="crawl"?100:e==="search"?r:1;return{maxAttempts:3,maxConcurrency:4,maxBytes:1e7,maxPages:Math.min(o,n??o),maxDurationMs:12e4,maxRedirects:8,maxProviderCostUsd:t??0,...t===void 0?{providerCostMode:"account-default"}:{}}}function c4t(e=process.env){let t=e.XENO_WEB_CONTEXT_TOKEN?.trim();if(t)return t;let n=e.XENO_WEB_CONTEXT_TOKEN_FILE?.trim();if(n){let r=s4t(n,"utf8").trim();if(r)return r}throw Object.assign(new Error("XENO Web Context is not configured. Set XENO_WEB_CONTEXT_TOKEN or XENO_WEB_CONTEXT_TOKEN_FILE."),{code:"WEB_CONTEXT_NOT_CONFIGURED"})}function l4t(e=process.env,t={}){let n=e.XENO_WEB_CONTEXT_URL?.trim(),r=!!(e.XENO_WEB_CONTEXT_TOKEN?.trim()||e.XENO_WEB_CONTEXT_TOKEN_FILE?.trim());if(n||r)return{baseUrl:n||a4t,token:c4t(e),source:"explicit",auth:"bearer"};let o=e.XENO_API_KEY?.trim();return o?{baseUrl:IWe,token:o,pathPrefix:kWe,source:"account",auth:"bearer"}:{baseUrl:IWe,pathPrefix:kWe,source:"account",auth:"dpop"}}function d4t(){return Object.assign(new Error("XENO Web Context needs a XENO account. Sign in with `xeno`, or set XENO_WEB_CONTEXT_URL and XENO_WEB_CONTEXT_TOKEN."),{code:"WEB_CONTEXT_NOT_CONFIGURED"})}function u4t(e={}){return async(t,n)=>{let r=typeof t=="string"?t:t instanceof URL?t.href:t.url,o=(n?.method??"GET").toUpperCase(),s=await(e.accountHost?await e.accountHost():await ys()).authorize(o,r,["inference:run"]),a=new Headers(n?.headers);if(s)return a.set("authorization",`DPoP ${s.token}`),a.set("dpop",s.headers.dpop),fetch(t,{...n,headers:a});let c=hv(e);if(c.state!=="present")throw d4t();return a.set("authorization",`Bearer ${c.key}`),fetch(t,{...n,headers:a})}}function ade(e=process.env,t={}){let n=l4t(e,t);return n.auth==="dpop"?new vB({baseUrl:n.baseUrl,token:"dpop-account-session",pathPrefix:n.pathPrefix,fetchImpl:u4t(t)}):new vB({baseUrl:n.baseUrl,token:n.token??"",...n.pathPrefix?{pathPrefix:n.pathPrefix}:{}})}function EWe(e=process.env){let t=sde(e),n=IB("fetch",t),r=yq({actor:{id:"xeno-agent-cli",kind:"agent"},scope:{kind:"local-profile",profileId:"pending-token-scope"},classification:"public",purposePrefix:"xeno-agent-cli:chat",budget:{...n,maxProviderCostUsd:t,durationMs:n.maxDurationMs}});return{client:new ide(e),createRequest:(o,i)=>{let s=r(o,i);return o==="search"&&(s.budget.maxPages=IB("search",n.maxProviderCostUsd,void 0,typeof i.maxResults=="number"?i.maxResults:5).maxPages),s}}}var a4t,IWe,kWe,ide,cde=ge(()=>{"use strict";vWe();of();Tu();et();a4t="http://127.0.0.1:8080",IWe="https://api.xenostudio.ai",kWe="/v1/web";ide=class{constructor(t){this.env=t}env;client;account;async search(t){return this.getClient().search(await this.bindTenant(t,"search",t.count))}async scrapeAndWait(t,n){return this.getClient().scrapeAndWait(await this.bindTenant(t,"fetch"),n)}getClient(){return this.client??=ade(this.env),this.client}async bindTenant(t,n,r){this.account??=this.getClient().account();let o=await this.account,i=IB(n,t.budget.maxProviderCostUsd,o.quota?.maxPagesPerJob,r);return{...t,scope:{kind:"tenant",tenantId:o.tenantId},budget:{...t.budget,maxPages:Math.min(t.budget.maxPages,i.maxPages)}}}}});var SWe=ge(()=>{"use strict"});function CWe(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e;if(t.success===!1)return typeof t.error=="string";if(t.success!==!0||!t.snapshot||typeof t.snapshot!="object"||Array.isArray(t.snapshot))return!1;let n=t.snapshot,r=i=>typeof i=="number"&&Number.isSafeInteger(i)&&i>=0,o=(i,s,a,c=!1)=>Array.isArray(i)&&i.every(l=>l&&typeof l=="object"&&!Array.isArray(l)&&typeof l[s]=="string"&&r(l[a])&&(!c||l.cost===null));return n.source==="local-runtime-journal"&&n.billingStatus==="unavailable"&&n.totalCost===null&&typeof n.observedAt=="string"&&Number.isFinite(Date.parse(n.observedAt))&&r(n.totalTokens)&&r(n.totalRequests)&&r(n.unmeasuredRequests)&&n.unmeasuredRequests<=n.totalRequests&&o(n.dailyUsage,"label","value")&&o(n.weeklyUsage,"label","value")&&o(n.monthlyUsage,"label","value")&&o(n.costByModel,"model","tokens",!0)&&o(n.topAgents,"name","tokens",!0)}var xWe=ge(()=>{"use strict"});var RWe=ge(()=>{"use strict"});function TWe(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e;return t.success===!1?typeof t.error=="string":t.success===!0&&t.source==="local-runtime-journal"&&typeof t.observedAt=="string"&&Number.isFinite(Date.parse(t.observedAt))&&typeof t.complete=="boolean"&&(t.complete?t.nextCursor===null:typeof t.nextCursor=="string"&&t.nextCursor.length>0&&t.nextCursor.length<=4096)&&Array.isArray(t.entries)&&t.entries.length<=1e4&&t.entries.every(n=>n&&typeof n=="object"&&["id","timestamp","action","actor","target","details"].every(r=>typeof n[r]=="string")&&Number.isFinite(Date.parse(n.timestamp)))}var PWe=ge(()=>{"use strict"});function _We(e){return!lde(e)||typeof e.success!="boolean"||e.error!==void 0&&(typeof e.error!="string"||e.error.length>1e3)?!1:e.success?e.content!==void 0&&(typeof e.content!="string"||e.content.length>128e3)||e.loadedModel!==void 0&&!$We(e.loadedModel)||e.models!==void 0&&(!Array.isArray(e.models)||e.models.length>1e3||!e.models.every(t=>lde(t)&&$We(t.id)&&typeof t.name=="string"&&t.name.length<=512&&(t.contextWindowTokens===void 0||Number.isSafeInteger(t.contextWindowTokens)&&t.contextWindowTokens>0)))||e.usage!==void 0&&(!lde(e.usage)||!["inputTokens","outputTokens"].every(t=>Number.isSafeInteger(e.usage[t])&&(e.usage[t]??-1)>=0))?!1:e.content!==void 0||e.models!==void 0||e.loadedModel!==void 0:typeof e.error=="string"&&!!e.error}var lde,$We,BWe=ge(()=>{"use strict";lde=e=>!!e&&typeof e=="object"&&!Array.isArray(e),$We=e=>typeof e=="string"&&e.length>0&&e.length<=512&&!/[\x00-\x1f\x7f]/.test(e)});var c6n,OWe=ge(()=>{"use strict";c6n=new TextEncoder});var MWe=ge(()=>{"use strict"});var NWe=ge(()=>{"use strict"});var DWe,p4t,LWe=ge(()=>{"use strict";NWe();DWe=["completed","partial","failed","cancelled"],p4t=["queued","running",...DWe]});var QWe=ge(()=>{"use strict"});var FWe=ge(()=>{"use strict"});var UWe=ge(()=>{"use strict"});var jWe=ge(()=>{"use strict"});var qWe=ge(()=>{"use strict";jWe()});var HWe=ge(()=>{"use strict"});var WWe=ge(()=>{"use strict"});var VWe=ge(()=>{"use strict"});var f4t,GWe=ge(()=>{"use strict";dA();f4t=1024*1024});function A4t(e){return typeof e=="string"&&m4t.includes(e)}function XWe(e){return Ui(e)?Yn(e.clientId)&&Yn(e.clientVersion)&&Yn(e.instanceId)&&A4t(e.surface):!1}function zWe(e){return!Ui(e)||!Ui(e.protocol)||!Ui(e.host)||!Ui(e.storage)?!1:Number.isInteger(e.protocol.current)&&E4t(e.protocol.supported)&&Yn(e.host.instanceId)&&Yn(e.host.version)&&(e.host.authority==="primary"||e.host.authority==="diagnostic-read-only")&&(e.host.processBoundary==="in-process"||e.host.processBoundary==="per-user-service")&&e.storage.owner==="xeno-agent-host"&&Number.isInteger(e.storage.schemaVersion)&&Number.isInteger(e.storage.eventSchemaVersion)&&XWe(e.surface)}function dde(e){return!Ui(e)||!Yn(e.revision)||!Array.isArray(e.providers)?!1:e.providers.every(I4t)}function y4t(e){return!Ui(e)||!Ui(e.event)?!1:Yn(e.id)&&Number.isInteger(e.sequence)&&typeof e.sequence=="number"&&e.sequence>=0&&Yn(e.timestamp)&&Yn(e.conversationId)&&Yn(e.requestId)&&Yn(e.type)&&Yn(e.source)}function KWe(e){return!Ui(e)||!Array.isArray(e.events)?!1:(e.nextSequence===null||typeof e.nextSequence=="number"&&Number.isInteger(e.nextSequence)&&e.nextSequence>=0)&&e.events.every(y4t)}function YWe(e){return!Ui(e)||typeof e.success!="boolean"?!1:e.success?(e.status==="accepted"||e.status==="replayed")&&Yn(e.conversationId)&&Yn(e.requestId)&&Yn(e.adapterId)&&Ui(e.selection)&&Yn(e.selection.providerId)&&Yn(e.selection.catalogRevision):Yn(e.code)&&Yn(e.safeError)}function ZWe(e){return!Ui(e)||typeof e.success!="boolean"?!1:e.success?(e.status==="cancel_requested"||e.status==="replayed")&&Yn(e.conversationId)&&Yn(e.requestId):Yn(e.code)&&Yn(e.safeError)}function eVe(e){return Ui(e)&&Yn(e.id)&&typeof e.sequence=="number"&&Number.isInteger(e.sequence)&&e.sequence>0&&typeof e.timestamp=="number"&&Number.isFinite(e.timestamp)&&b4t(e.type)&&e.source==="host"&&e.schemaVersion===1&&e.redactionState==="safe"&&"payload"in e}function b4t(e){return typeof e=="string"&&w4t.includes(e)}function tVe(e,t,n){if(e.surface.surface!==t.surface||e.surface.instanceId!==t.instanceId)throw new wi("surface_mismatch",`Agent host acknowledged ${e.surface.surface}/${e.surface.instanceId} instead of ${t.surface}/${t.instanceId}.`);if(e.protocol.current<n.min||e.protocol.current>n.max||n.max<e.protocol.supported.min||n.min>e.protocol.supported.max)throw new wi("protocol_mismatch",`Agent host protocol ${e.protocol.current} is incompatible with client range ${n.min}-${n.max}.`)}function v4t(e){return!(!Ui(e)||e.chatExecution!==void 0&&!kB(e.chatExecution)||e.durableResume!==void 0&&!kB(e.durableResume)||e.nativeTuiAttach!==void 0&&!kB(e.nativeTuiAttach)||e.reconciliation!==void 0&&!kB(e.reconciliation)||e.modelSwitchInPlace!==void 0&&!kB(e.modelSwitchInPlace)||e.resumeCompatibilityKey!==void 0&&typeof e.resumeCompatibilityKey!="string")}function kB(e){return Ui(e)?(e.status==="available"||e.status==="degraded"||e.status==="blocked"||e.status==="unsupported")&&(e.source==="provider"||e.source==="host"||e.source==="policy")&&(e.reason===void 0||typeof e.reason=="string")&&(e.version===void 0||typeof e.version=="string"):!1}function I4t(e){return Ui(e)?Yn(e.id)&&typeof e.kind=="string"&&h4t.includes(e.kind)&&Yn(e.displayName)&&nVe(e.availability)&&Ui(e.capabilities)&&(e.providerSession===void 0||v4t(e.providerSession))&&Array.isArray(e.models)&&e.models.every(k4t)&&Yn(e.catalogRevision):!1}function k4t(e){return Ui(e)&&Yn(e.id)&&Yn(e.displayName)&&nVe(e.availability)&&(e.reasoningOptions===void 0||Array.isArray(e.reasoningOptions)&&e.reasoningOptions.every(t=>Ui(t)&&Yn(t.id)&&Yn(t.label)&&(t.runtimeModelId===void 0||Yn(t.runtimeModelId))&&(t.runtimeReasoningEffort===void 0||typeof t.runtimeReasoningEffort=="string"&&/^[a-z][a-z0-9_-]{0,79}$/i.test(t.runtimeReasoningEffort))&&(t.isDefault===void 0||typeof t.isDefault=="boolean")))}function nVe(e){return e==="available"||e==="degraded"||e==="blocked"||e==="unavailable"}function E4t(e){return Ui(e)&&Number.isInteger(e.min)&&Number.isInteger(e.max)&&typeof e.min=="number"&&typeof e.max=="number"&&e.min>0&&e.max>=e.min}function Yn(e){return typeof e=="string"&&e.trim().length>0}function Ui(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function yV(e){for(let t of C4t)for(let n of S4t)if(e===`${t}tool.${n}`)return n;return null}function Cv(e,t){let n=e?.[t];return typeof n=="string"&&n.trim()?n:void 0}function bV(e){let t=e.event;return Cv(t,"toolName")||Cv(t,"tool")||Cv(t,"name")||Cv(t,"title")||Cv(t,"kind")}function VC(e){let t=e.event;return Cv(t,"toolCallId")||Cv(t,"tool_call_id")}function rVe(e){let t=e.event;for(let n of["rawInput","input","arguments","parameters","args"]){let r=t?.[n];if(r&&typeof r=="object"&&!Array.isArray(r))return r}}function oVe(e){let t=e.event;for(let n of["rawOutput","output","result","content"]){let r=t?.[n];if(typeof r=="string")return r.length>0?r:void 0;if(r!=null)try{let o=JSON.stringify(r);if(o&&o!=="{}"&&o!=="[]")return o}catch{}}}function vV(e){return e==="completed"?!0:e==="failed"||e==="cancelled"?!1:null}var WC,JWe,m4t,h4t,g4t,x6n,w4t,wi,S4t,C4t,dA=ge(()=>{"use strict";SWe();xWe();RWe();PWe();BWe();OWe();MWe();LWe();QWe();FWe();UWe();qWe();HWe();WWe();VWe();GWe();WC=1,JWe=1,m4t=["standalone-desktop","hub-embed","shell-embed","embed-preview","panel-embed","headless-client"],h4t=["sdk-native","xeno-cloud","cli-app-server","cli-remote","acp"],g4t=["workspace.usage","workspace.audit","inference.request","workspace.schedule","workspace.backup","workspace.environment","account.request","workforce.request","workspace.notifications","workspace.rules","workspace.browser","workspace.browser.session","host.handshake","providers.list","providers.refresh","runtime.events.list","workspace.lifecycle.apply","state.workspaces.load","state.workspaces.save","state.conversations.load","state.conversations.save","state.conversations.delete","workspace.access.grant","coordination.held.list","coordination.held.release","coordination.policy.set","coordination.state.get","coordination.action","workspace.application.grant","workspace.directory.list","workspace.file.read","workspace.file.write","workspace.command.run","workspace.terminal.start","workspace.terminal.stop","workspace.pty.start","workspace.pty.snapshot","workspace.pty.input","workspace.pty.resize","workspace.pty.clear","workspace.pty.stop","conversation.open","conversation.resume","xeno.tui.attach","provider.lanes.list","provider.lanes.get","provider.lanes.select","provider.native.attach","provider.native.detach","provider.native.reattach","provider.native.stop","provider.reconcile","turn.start","turn.cancel","turn.steer","context.inject","turn.queue","turn.queue.list","run.observation.snapshot","run.observation.change","run.observation.overlaps","fleet.view","fleet.route","fleet.plan","subagent.run.create","subagent.run.list","subagent.run.cancel","subagent.scheduler.status","subagent.scheduler.recover","session.list","session.attach","session.detach","session.snapshot","session.input","session.takeover","session.release","session.setMode","acp.agents.list","acp.agents.addPreset","acp.agents.remove","acp.capabilitySnapshot.get","acp.command.invoke","intake.sources.list","intake.items.list","intake.item.claim","intake.item.release","intake.item.dispatch","knowledge.list","knowledge.record","knowledge.forget","knowledge.context","turn.queue.drop","elicitation.choose-directory.answer","elicitation.workspace-placement.answer","elicitation.permission.answer","turn.resume","acp.provider.approve","permissions.rules.list","permissions.rules.revoke","elicitation.ask-user.answer","sdk.sessions.list","sdk.sessions.show","sdk.sessions.attach","sdk.sessions.detach","sdk.sessions.delete","sdk.sessions.clean","sdk.checkpoints.list","sdk.checkpoints.restore","sdk.checkpoints.delete","sdk.tasks.output","sdk.tasks.stop","engineering.git.status","engineering.git.diff","engineering.git.stage","engineering.git.unstage","engineering.git.commit","engineering.git.branch","engineering.git.push","engineering.git.pr.create","engineering.landing.enqueue","engineering.landing.remove","engineering.landing.status","engineering.landing.land","engineering.landing.verify","engineering.checks.discover","engineering.checks.run","engineering.background.start","engineering.background.list","engineering.background.output","engineering.background.stop","engineering.runs.list","engineering.diagnostics","engineering.patches.list","engineering.patches.enqueue","engineering.patches.update","engineering.patches.review","engineering.checkpoints.list","engineering.checkpoints.compare","engineering.checkpoints.restore","engineering.sessions.list","engineering.runtime.timeline"],x6n=new Set(g4t),w4t=["host.ready","provider.catalog.changed","state.workspaces.changed","runtime.event.appended","turn.execution.completed","turn.execution.failed","turn.execution.abandoned","elicitation.choose-directory.requested","elicitation.workspace-placement.requested","elicitation.permission.requested","elicitation.ask-user.requested","task.changed","workspace.terminal.data","workspace.terminal.exit","workspace.pty.data","workspace.pty.exit","coordination.event","run.observation","session.event","provider.lane.created","provider.lane.selected","provider.lane.resumed","provider.lane.invalidated","provider.writer.acquired","provider.writer.renewed","provider.writer.released","provider.writer.recovery_classified","provider.native_tui.started","provider.native_tui.detached","provider.native_tui.exited","provider.reconciliation.started","provider.reconciliation.completed","provider.reconciliation.failed","provider.portable_context.acknowledged_partial"],wi=class extends Error{code;constructor(t,n){super(n),this.name="AgentHostProtocolError",this.code=t}};S4t=["started","updated","completed","failed","cancelled"],C4t=["","acp."]});function IV(e){let t=e.type.toLowerCase();if(!(t.includes("tool")||VC(e))&&!(!t.includes("text")&&!t.includes("message")&&!t.includes("delta"))&&!(t.includes("complete")||t.includes("final")||t.includes("end")))for(let n of["delta","text","content","chunk"]){let r=e.event[n];if(typeof r=="string"&&r.length>0)return r}}var ude=ge(()=>{"use strict";dA()});import{createHash as x4t}from"node:crypto";import{setTimeout as R4t}from"node:timers/promises";function $4t(e,t){return`subrun-${x4t("sha256").update(`${e}\0${t}`).digest("hex").slice(0,32)}`}async function _4t(e,t,n){return((await e.listRuntimeEvents({conversationId:t,subagentRunId:n,limit:500}))?.events??[]).map(o=>IV(o)??"").join("")}function B4t(e,t,n,r){let o=new Set,i=typeof r.onToolStart=="function"||typeof r.onToolEnd=="function",s=a=>{try{a()}catch{}};return async function(){if(!i)return;let c=await e.listRuntimeEvents({conversationId:t,subagentRunId:n,limit:500}).catch(()=>null);for(let l of c?.events??[]){let d=yV(String(l.type??""));if(!d)continue;let u=`${VC(l)??l.id}:${d}`;if(o.has(u))continue;o.add(u);let p=bV(l)??"unknown";if(d==="started"&&r.onToolStart){let m=r.onToolStart;s(()=>m(p,rVe(l)??{}))}let f=vV(d);if(f!==null&&r.onToolEnd){let m=r.onToolEnd;s(()=>m(p,{success:f,output:oVe(l)??""}))}}}}function iVe(e){let t=e.pollIntervalMs??250;return async n=>{let r=n.task,o=$4t(e.rootTraceId,r.id),i={lastTraceId:null,tokenUsage:{input:0,output:0,total:0},async run(s){let a=Math.max(1e3,e.deadline-Date.now()),c={parentConversationId:e.parentConversationId,...e.parentRequestId===void 0?{}:{parentRequestId:e.parentRequestId},parentAgentId:e.parentAgentId,childConversationId:o,childAgentId:r.role?`delegated-${r.role}`:"delegated-branch",workspaceId:e.workspaceId,teamId:e.teamId,objective:s,...r.role===void 0?{}:{role:r.role},policy:{maxRuntimeMs:a}},l=await e.client.createSubagentRun(c);if(!l?.success||!l.run)throw new Error(l?.safeError??"The Agent host refused to create a subagent run for this delegated branch.");let d=l.run.id;i.lastTraceId=d;let u=B4t(e.client,o,d,{onToolStart:n.onToolStart,onToolEnd:n.onToolEnd});for(;;){if(e.signal?.aborted){await e.client.cancelSubagentRun({runId:d}).catch(()=>{});let g=new Error("Delegated branch was cancelled.");throw g.name="AgentInterruptedError",g}let f=((await e.client.listSubagentRuns({parentConversationId:e.parentConversationId}))?.runs??[]).find(g=>g.id===d),m=String(f?.status??"");if(T4t.has(m)){if(P4t.has(m))throw new Error(f?.error??`The delegated branch ended as '${m}' without reporting a reason.`);await u();let g=await _4t(e.client,o,d);if(g.length===0)throw new Error(`The delegated branch reported '${m}' but produced no readable output. Its runtime events carry no text for this run id.`);return g}if(Date.now()>=e.deadline)throw await e.client.cancelSubagentRun({runId:d}).catch(()=>{}),new Error("The delegated branch exceeded the time this run was given to wait.");await u(),await R4t(t,void 0,{signal:e.signal})}}};return i}}var T4t,P4t,sVe=ge(()=>{"use strict";dA();ude();T4t=new Set(["completed","succeeded","failed","cancelled","error"]),P4t=new Set(["failed","cancelled","error"])});function EB(e,t){let n=e.run.bind(e);return e.run=async r=>{try{return await t.start(),await n(r)}finally{await t.stop()}},e}function Ah(e){return!e||e.status==="completed"}function SB(e,t=n=>{at.cleanupOwner(n)}){if(e)try{t(e)}catch{}}async function df(e){let{agent:t,signal:n}=e,r=()=>SB(e.ownerSessionId,e.cleanupOwner),o=()=>{t.cancelCurrentTurn()};if(n?.aborted)throw r(),await e.lifecycle?.stop(),new _r;n?.addEventListener("abort",o,{once:!0});let i=!1;try{if(e.lifecycle&&(await e.lifecycle.start(n),n?.aborted))throw new _r;let s=await(e.run??(()=>t.run(e.prompt)))(),a=t.lastRunTermination??void 0;i=Ah(a);let c=a?{status:a.status,reason:a.reason,...a.message?{message:a.message}:{}}:void 0;return{output:s,...c?{termination:c}:{},tokenUsage:{...t.tokenUsage}}}finally{n?.removeEventListener("abort",o),i||r(),await e.lifecycle?.stop()}}function xv(e,t,n){if(!t)return e;let r=e.run.bind(e);return e.run=async o=>{let i=!1;try{let s=await r(o);return i=Ah(e.lastRunTermination),s}finally{i||SB(t,n)}},e}function pde(e){return e.stopRequested||e.termination?.status==="interrupted"?"stopped":e.threw||e.termination?.status==="error"?"failed":Ah(e.termination)?"completed":"unfinished"}function CB(e){let t=e.summary.cancelled??0,n=e.summary.incomplete??0,r=[];return n>0&&r.push(`${n} stopped before finishing`),t>0&&r.push(`${t} cancelled`),e.incomplete?`Delegation incomplete: no branch finished${r.length?` (${r.join(", ")})`:""}. The answer below is partial output from a branch that stopped early, not a final answer.`:r.length?`Delegation finished with unfinished branches: ${r.join(", ")}.`:void 0}var xB=ge(()=>{"use strict";et()});import{execFile as aVe,execFileSync as mde}from"node:child_process";import{promisify as cVe}from"node:util";import{createHash as O4t}from"node:crypto";import{existsSync as lVe,readFileSync as hde,readlinkSync as M4t}from"node:fs";import{hostname as uA}from"node:os";function EV(){return Mu}function SV(e=process.env){if(e===process.env&&fde)return fde;let t=e.SystemRoot??e.SYSTEMROOT??e.windir??e.WINDIR,n="powershell.exe";if(t&&/^[a-z]:[\\/]/i.test(t)){let r=`${t.replace(/[\\/]+$/,"")}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;lVe(r)&&(n=r)}return e===process.env&&(fde=n),n}function CV(e){return Number.isInteger(e)&&e>0}function L4t(e){return O4t("sha256").update(e).digest("hex")}function PB(e){let t=e?.trim().replaceAll("\\","/").toLowerCase();return t?`sha256:${L4t(t)}`:void 0}function kV(){if(process.platform==="linux")try{return hde("/proc/sys/kernel/random/boot_id","utf8").trim()||void 0}catch{return}}function Nu(e){if(typeof e!="number"||!CV(e))return"dead";try{return process.kill(e,0),"live"}catch(t){return t.code==="ESRCH"?"dead":"unknown"}}function wde(e){let t=Date.parse(e);return Number.isFinite(t)?new Date(t).toISOString():null}function mVe(e){return["-NoLogo","-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-Command",["$ErrorActionPreference = 'Stop'",`$items = @(Get-Process -Id @(${e.join(", ")}) -ErrorAction SilentlyContinue)`,"$out = @($items | ForEach-Object { $path = try { [string]$_.Path } catch { '' }; $started = try { $_.StartTime.ToUniversalTime().ToString('o') } catch { '' }; [pscustomobject]@{ pid = [int]$_.Id; startedAt = $started; executable = $path } })","$out | ConvertTo-Json -Compress"].join("; ")]}function hVe(e){let t=new Map;try{if(!e)return t;let n=JSON.parse(e);for(let r of Array.isArray(n)?n:[n]){let o=Number(r.pid),i=wde(String(r.startedAt??""));!CV(o)||!i||t.set(o,{pid:o,processStartedAt:i,hostname:uA(),...PB(r.executable)?{executableFingerprint:PB(r.executable)}:{},confidence:"observed"})}}catch{return t}return t}function gVe(e,t){let n=new Map;if(t.fresh)return{known:n,pending:e,skip:!1};let r=Mu.now(),o=[];for(let i of e){let s=TB.get(i);s&&r>=s.at&&r-s.at<fVe?s.identity&&n.set(i,s.identity):o.push(i)}return{known:n,pending:o,skip:o.length>0&&r<gde}}function wVe(e,t){let n=Mu.now();gde=0;for(let r of e)TB.set(r,{identity:t.get(r)??null,at:n});if(TB.size>512)for(let[r,o]of TB)n-o.at>=fVe&&TB.delete(r)}function AVe(){gde=Mu.now()+N4t}function Q4t(e,t={}){if(!e.length)return new Map;let{known:n,pending:r,skip:o}=gVe(e,t);if(!r.length||o)return n;try{let i=hVe(Mu.runSync(SV(),mVe(r),{timeoutMs:pVe}).trim());wVe(r,i);for(let[s,a]of i)n.set(s,a)}catch{AVe()}return n}function F4t(){if(RB)return RB;try{let e=Number.parseInt(mde("getconf",["CLK_TCK"],{encoding:"utf8",timeout:2e3,stdio:["ignore","pipe","ignore"]}).trim(),10);RB=Number.isFinite(e)&&e>0?e:100}catch{RB=100}return RB}function U4t(){try{let e=/^btime\s+(\d+)$/m.exec(hde("/proc/stat","utf8"));return e?Number.parseInt(e[1]??"",10):null}catch{return null}}function j4t(e){try{let t=hde(`/proc/${e}/stat`,"utf8"),n=t.lastIndexOf(")");if(n<0)return null;let r=t.slice(n+2).trim().split(/\s+/),o=Number(r[19]),i=U4t();if(!Number.isFinite(o)||i===null)return null;let s=new Date((i+o/F4t())*1e3).toISOString(),a;try{a=M4t(`/proc/${e}/exe`)}catch{a=void 0}return{pid:e,processStartedAt:s,hostname:uA(),...kV()?{bootId:kV()}:{},...PB(a)?{executableFingerprint:PB(a)}:{},confidence:"observed"}}catch{return null}}function yVe(e){let t=new Map;if(Mu.platform==="linux"){for(let n of e){let r=j4t(n);r&&t.set(n,r)}return t}for(let n of e)try{let r=mde("ps",["-p",String(n),"-o","lstart="],{encoding:"utf8",timeout:2e3,env:{...process.env,LC_ALL:"C"},stdio:["ignore","pipe","ignore"]}).trim(),o=wde(r);if(!o)continue;t.set(n,{pid:n,processStartedAt:o,hostname:uA(),confidence:"observed"})}catch{continue}return t}function $B(e,t={}){let n=[...new Set(e.filter(CV))],r=n.includes(process.pid),o=r?n.filter(s=>s!==process.pid):n,i=Mu.platform==="win32"?Q4t(o,t):yVe(o);return r&&i.set(process.pid,pA()),i}function Ade(e,t={}){return $B([e],t).get(e)??null}async function bVe(e,t,n={}){t?.throwIfAborted();let r=[...new Set(e.filter(CV))],o=r.filter(s=>s!==process.pid),i=new Map;if(Mu.platform==="win32"&&o.length){let{known:s,pending:a,skip:c}=gVe(o,n);if(i=s,a.length&&!c)try{let l=hVe((await Mu.run(SV(),mVe(a),{timeoutMs:pVe,signal:t})).trim());wVe(a,l);for(let[d,u]of l)i.set(d,u)}catch{t?.throwIfAborted(),AVe()}}else if(Mu.platform==="linux")i=yVe(o);else if(Mu.platform!=="win32")for(let s of o){t?.throwIfAborted();try{let{stdout:a}=await cVe(aVe)("ps",["-p",String(s),"-o","lstart="],{encoding:"utf8",timeout:2e3,signal:t,env:{...process.env,LC_ALL:"C"},maxBuffer:4096}),c=wde(a.trim());c&&i.set(s,{pid:s,processStartedAt:c,hostname:uA(),confidence:"observed"})}catch{t?.throwIfAborted()}}return t?.throwIfAborted(),r.includes(process.pid)&&i.set(process.pid,pA()),i}function xV(e,t=new Date,n=!1){return(n?Ade(e):null)??{pid:e,processStartedAt:t.toISOString(),hostname:uA(),confidence:"degraded"}}function pA(){let e=new Date(Date.now()-Math.floor(process.uptime()*1e3)).toISOString();return{pid:process.pid,processStartedAt:e,hostname:uA(),...kV()?{bootId:kV()}:{},...lVe(process.execPath)?{executableFingerprint:PB(process.execPath)}:{},confidence:"self"}}function Ja(e,t=Ade){if(e.hostname!==uA())return{status:"remote",expected:e,reason:"Process belongs to another host."};if(Nu(e.pid)==="dead")return{status:"dead",expected:e,reason:"Process ID is not live."};let n=t(e.pid);if(!n)return Nu(e.pid)==="dead"?{status:"dead",expected:e,reason:"Process ID is not live."}:{status:"degraded",expected:e,reason:"Creation time could not be observed."};let r=Date.parse(e.processStartedAt),o=Date.parse(n.processStartedAt);return!Number.isFinite(r)||!Number.isFinite(o)||Math.abs(r-o)>dVe?{status:"mismatch",expected:e,observed:n,reason:"Process creation time does not match."}:e.bootId&&n.bootId&&e.bootId!==n.bootId?{status:"mismatch",expected:e,observed:n,reason:"Host boot identity does not match."}:e.executableFingerprint&&n.executableFingerprint&&e.executableFingerprint!==n.executableFingerprint?{status:"mismatch",expected:e,observed:n,reason:"Executable identity does not match."}:{status:"live",expected:e,observed:n}}function uf(e){return e.hostname===uA()&&Nu(e.pid)==="dead"}var dVe,uVe,pVe,N4t,fVe,GC,D4t,Mu,TB,gde,fde,RB,RV,Ed=ge(()=>{"use strict";dVe=3e3,uVe=dVe,pVe=4e3,N4t=15e3,fVe=2e3,GC=1e4,D4t={platform:process.platform,now:()=>Date.now(),runSync:(e,t,n)=>mde(e,t,{encoding:"utf8",windowsHide:!0,timeout:n.timeoutMs,stdio:["ignore","pipe","ignore"]}),run:async(e,t,n)=>(await cVe(aVe)(e,t,{encoding:"utf8",windowsHide:!0,timeout:n.timeoutMs,maxBuffer:1024*1024,signal:n.signal})).stdout},Mu=D4t,TB=new Map,gde=0;RV=e=>Ade(e,{fresh:!0})});import{createHash as q4t,randomBytes as H4t}from"node:crypto";import{chmodSync as W4t,existsSync as V4t,mkdirSync as IVe,readFileSync as G4t,renameSync as X4t,unlinkSync as kVe,writeFileSync as J4t}from"node:fs";import{dirname as z4t,join as _B}from"node:path";function EVe(){return fa()}function K4t(e){return q4t("sha256").update(e).digest("hex").slice(0,16)}function wn(){return _B(EVe(),"daemon")}function yde(){return _B(wn(),"daemon.json")}function SVe(){return _B(wn(),"daemon.lock")}function XC(){return _B(wn(),"daemon.log")}function bde(){let e=K4t(EVe());return process.platform==="win32"?{transport:"named-pipe",endpoint:`\\\\.\\pipe\\xeno-agent-daemon-${e}`}:{transport:"unix-socket",endpoint:_B(wn(),"daemon.sock")}}function TV(){IVe(wn(),{recursive:!0})}function CVe(){return H4t(32).toString("base64url")}function vVe(e){if(process.platform!=="win32")try{W4t(e,384)}catch{}}function vde(){try{let e=yde(),t=G4t(e,"utf8"),n=JSON.parse(t);if(!n||n.schemaVersion!==1||n.protocolVersion!==1||n.transport!=="named-pipe"&&n.transport!=="unix-socket"||typeof n.endpoint!="string"||typeof n.authToken!="string"||!Number.isSafeInteger(n.pid)||typeof n.startedAt!="string"||typeof n.cliVersion!="string"||typeof n.logPath!="string")throw new Error("daemon state schema is invalid");return n}catch(e){if(e.code==="ENOENT")return null;throw new Error(`Daemon state is corrupt or unreadable: ${e instanceof Error?e.message:String(e)}`)}}function xVe(e){let t=yde();IVe(z4t(t),{recursive:!0});let n=`${t}.${process.pid}.${Date.now()}.tmp`;J4t(n,JSON.stringify(e,null,2)+`
2905
+ `&&(this.atLineStart=!0);this.writeFn(n)}reset(){this.atLineStart=!0}markLineStarted(){this.atLineStart=!1}},s5e=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],oB=class{interval=null;frameIndex=0;lastLength=0;writeFn;clearFn;constructor(t,n){this.writeFn=t??(r=>{n5e.writeFrame(r,"spinner")}),this.clearFn=n??(()=>{n5e.writeFrame(`\r${" ".repeat(this.lastLength)}\r`,"spinner")})}start(t){this.stop(),this.frameIndex=0,this.interval=setInterval(()=>{let n=s5e[this.frameIndex%s5e.length],r=`${sn(n)} ${Ce(t)}`;this.writeFn(`\r${" ".repeat(this.lastLength)}\r${r}`),this.lastLength=t.length+4,this.frameIndex++},80)}stop(){this.interval&&(clearInterval(this.interval),this.interval=null,this.clearFn(),this.lastLength=0)}}});var Re,Ko=ge(()=>{"use strict";Re="0.5.108"});var ede,lWe=ge(()=>{"use strict";ede="1.0.0"});var yWe={};oa(yWe,{TERMINAL_WEB_JOB_STATES:()=>nde,WEB_JOB_PROGRESS_OPERATIONS:()=>hWe,WEB_JOB_PROGRESS_SCHEMA:()=>HC,WEB_JOB_PROGRESS_SCHEMA_VERSION:()=>gV,WEB_JOB_PROGRESS_STATES:()=>gWe,deriveWebJobProgress:()=>AV,isTerminalWebJobState:()=>lA,isWebJobProgress:()=>AWe,parseWebJobProgress:()=>wV,webJobProgressSignature:()=>ode});function lA(e){return nde.includes(e)}function uWe(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function pWe(e,t){return Object.keys(e).every(n=>t.has(n))}function rde(e,t){return typeof e=="string"&&e.trim().length>0&&e.length<=t&&!/[\u0000-\u001f\u007f]/u.test(e)}function tde(e){return rde(e,64)&&Number.isFinite(Date.parse(e))}function wWe(e){return rde(e,120)&&/^[A-Za-z0-9._:-]+$/u.test(e)}function fWe(e){return typeof e=="number"&&Number.isSafeInteger(e)&&e>=0}function wV(e){if(!uWe(e)||!pWe(e,e4t))throw new TypeError("invalid Web Context progress object");if(e.schema!==HC||e.schemaVersion!==gV||e.contractVersion!==ede)throw new TypeError("unsupported Web Context progress schema");if(!rde(e.jobId,256))throw new TypeError("invalid Web Context progress jobId");if(!hWe.includes(e.operation))throw new TypeError("invalid Web Context progress operation");if(!gWe.includes(e.state))throw new TypeError("invalid Web Context progress state");let t=lA(e.state);if(e.terminal!==t)throw new TypeError("inconsistent Web Context terminal state");if(t){if(e.terminalState!==e.state)throw new TypeError("invalid Web Context terminalState")}else if("terminalState"in e)throw new TypeError("non-terminal Web Context progress cannot carry terminalState");if("terminalReason"in e&&(!t||!wWe(e.terminalReason)))throw new TypeError("invalid Web Context terminalReason");if(!uWe(e.counters)||!pWe(e.counters,dWe))throw new TypeError("invalid Web Context progress counters");for(let r of dWe)if(!fWe(e.counters[r]))throw new TypeError(`invalid Web Context counter ${r}`);let n=Number(e.counters.queuedPages)+Number(e.counters.activePages)+Number(e.counters.completedPages)+Number(e.counters.failedPages)+Number(e.counters.excludedPages);if(e.counters.knownPages!==n)throw new TypeError("inconsistent Web Context knownPages counter");if(!fWe(e.sequence))throw new TypeError("invalid Web Context progress sequence");if(!tde(e.observedAt))throw new TypeError("invalid Web Context observedAt");if("createdAt"in e&&!tde(e.createdAt))throw new TypeError("invalid Web Context createdAt");if("updatedAt"in e&&!tde(e.updatedAt))throw new TypeError("invalid Web Context updatedAt");return structuredClone(e)}function AWe(e){try{return wV(e),!0}catch{return!1}}function AB(e){return typeof e=="number"&&Number.isFinite(e)&&e>0?Math.floor(e):0}function mWe(e){return typeof e=="string"&&e.length>0?e:void 0}function AV(e,t,n=new Date().toISOString()){let r=AB(e.queuedPages),o=AB(e.activePages),i=AB(e.completedPages),s=AB(e.failedPages),a=AB(e.excludedPages),c={queuedPages:r,activePages:o,completedPages:i,failedPages:s,excludedPages:a,knownPages:r+o+i+s+a},l=lA(e.state),d=wWe(e.terminalReason)?e.terminalReason:void 0,u=mWe(e.createdAt),p=mWe(e.updatedAt);return{schema:HC,schemaVersion:gV,contractVersion:ede,jobId:e.jobId,operation:e.operation,state:e.state,terminal:l,...l?{terminalState:e.state}:{},...d?{terminalReason:d}:{},counters:c,sequence:t,observedAt:n,...u?{createdAt:u}:{},...p?{updatedAt:p}:{}}}function ode(e){let t=e.counters;return[e.jobId,e.operation,e.state,e.terminalReason??"",e.updatedAt??"",t.queuedPages,t.activePages,t.completedPages,t.failedPages,t.excludedPages].join("|")}var HC,gV,nde,hWe,gWe,e4t,dWe,yB=ge(()=>{"use strict";lWe();HC="xeno.web-context.job-progress",gV="1.0.0",nde=["completed","partial","failed","cancelled"],hWe=["scrape","batch-scrape","map","crawl","render","extract"],gWe=["queued","running",...nde];e4t=new Set(["schema","schemaVersion","contractVersion","jobId","operation","state","terminal","terminalState","terminalReason","counters","sequence","observedAt","createdAt","updatedAt"]),dWe=new Set(["queuedPages","activePages","completedPages","failedPages","excludedPages","knownPages"])});function n4t(e){if(e===void 0||e==="")return"";if(!t4t.test(e)||e.split("/").includes(".."))throw new TypeError("pathPrefix must be an absolute path such as /v1/web");return e}function bB(e){return e.signal?{signal:e.signal}:{}}function r4t(e,t){if(!t)return`scrape job ended in ${e}`;let[n,r]=t.split(":",2),o=r?` (${r})`:"";switch(n){case"SITE_BLOCKED":return`the site refused the request${o}; it blocks automated access, so use another source`;case"RATE_LIMITED":return"the site is rate-limiting requests; try again later";case"NOT_FOUND":return"the page does not exist (HTTP 404/410)";case"NETWORK_ERROR":return"the site could not be reached (network error)";case"DEADLINE_EXCEEDED":return"the page did not respond within the time budget";case"MIME_DENIED":return"the page is not a supported document type";case"ROBOTS_DENIED":case"ROBOTS_DISALLOWED":return"the site's robots.txt does not allow this page to be fetched";case"ROBOTS_UNAVAILABLE":return"the site's robots.txt could not be read, so the page was not fetched";default:return/^HTTP_\d{3}$/.test(n??"")?`the site answered HTTP ${n.slice(5)}`:`the page could not be retrieved (${t})`}}function bWe(e,t){let n=e;return{message:t,...typeof n?.code=="string"?{code:n.code}:{},...typeof n?.status=="number"?{status:n.status}:{}}}function o4t(e,t){if(typeof e!="object"||e===null||!Object.isExtensible(e))return e;try{Object.defineProperty(e,"cancellation",{value:t,enumerable:!0,configurable:!0,writable:!0})}catch{}return e}function i4t(e,t){let n=0,r,o=!1;return async i=>{if(!e)return;let s=lA(i.state);if(s&&o)return;let a=AV(i,n),c=ode(a);if(!(r===c&&!s)){r=c,n+=1,s&&(o=!0);try{await e(a)}catch(l){throw Object.assign(new Error("job progress listener failed"),{code:"PROGRESS_LISTENER_FAILED",jobId:t,state:a.state,cause:l})}}}}var t4t,vB,vWe=ge(()=>{"use strict";yB();yB();t4t=/^\/[A-Za-z0-9._~-]+(?:\/[A-Za-z0-9._~-]+)*$/;vB=class{#e;#n;#r;#o;constructor(t){if(this.#e=new URL(t.baseUrl),this.#n=t.token,this.#o=n4t(t.pathPrefix),!this.#n.trim())throw new TypeError("token is required");this.#r=t.fetchImpl??fetch}#i(t){if(this.#o==="")return new URL(t,this.#e);if(!t.startsWith("/v1/"))throw new TypeError("pathPrefix can only rewrite /v1 routes");return new URL(`${this.#o}${t.slice(3)}`,this.#e)}async#t(t,n={}){let r=await this.#r(this.#i(t),{...n,redirect:"error",headers:{authorization:`Bearer ${this.#n}`,...n.body?{"content-type":"application/json"}:{},...n.headers}});if(!r.ok){let o=`HTTP ${r.status}`,i;try{let s=await r.json();o=s.error?.message??o,i=s.error?.code}catch{}throw Object.assign(new Error(o),{status:r.status,...i?{code:i}:{}})}return r.status===204?void 0:await r.json()}async#s(t,n={}){let r=await this.#r(this.#i(t),{...n,redirect:"error",headers:{authorization:`Bearer ${this.#n}`,...n.headers}});if(!r.ok){let o=`HTTP ${r.status}`,i;try{let s=await r.json();o=s.error?.message??o,i=s.error?.code}catch{}throw Object.assign(new Error(o),{status:r.status,...i?{code:i}:{}})}return r}capabilities(){return this.#t("/v1/capabilities")}account(t={}){return this.#t("/v1/account",bB(t))}usage(){return this.#t("/v1/usage")}search(t,n={}){return this.#t("/v1/search",{method:"POST",body:JSON.stringify(t),...bB(n)})}searchAndScrape(t,n={}){return this.#t("/v1/search-and-scrape",{method:"POST",body:JSON.stringify(t),...bB(n)})}scrape(t){return this.#t("/v1/scrape",{method:"POST",body:JSON.stringify(t)})}render(t){return this.#t("/v1/render",{method:"POST",body:JSON.stringify(t)})}map(t){return this.#t("/v1/map",{method:"POST",body:JSON.stringify(t)})}crawl(t){return this.#t("/v1/crawl",{method:"POST",body:JSON.stringify(t)})}batchScrape(t){return this.#t("/v1/batch-scrape",{method:"POST",body:JSON.stringify(t)})}activity(t={}){let n=new URLSearchParams;return t.limit&&n.set("limit",String(t.limit)),t.cursor&&n.set("cursor",t.cursor),this.#t(`/v1/activity?${n}`)}job(t){return this.#t(`/v1/jobs/${encodeURIComponent(t)}`)}frontier(t,n={}){let r=new URLSearchParams;return n.limit&&r.set("limit",String(n.limit)),n.cursor&&r.set("cursor",n.cursor),this.#t(`/v1/jobs/${encodeURIComponent(t)}/frontier?${r}`)}results(t,n={}){let r=new URLSearchParams;return n.limit&&r.set("limit",String(n.limit)),n.cursor&&r.set("cursor",n.cursor),this.#t(`/v1/jobs/${encodeURIComponent(t)}/results?${r}`,bB(n))}async artifact(t,n,r={}){if(!/^artifact:[a-f0-9]{64}$/i.test(n))throw new TypeError("artifactId is invalid");let o=await this.#s(`/v1/jobs/${encodeURIComponent(t)}/artifacts/${n}`,bB(r)),i=o.headers.get("etag")??void 0;return{jobId:t,artifactId:n,mediaType:o.headers.get("content-type")?.split(";",1)[0]?.trim()||"application/octet-stream",bytes:new Uint8Array(await o.arrayBuffer()),...i?{etag:i}:{}}}cancel(t){return this.#t(`/v1/jobs/${encodeURIComponent(t)}/cancel`,{method:"POST"})}resume(t){return this.#t(`/v1/jobs/${encodeURIComponent(t)}/resume`,{method:"POST"})}webhookDeliveries(t){return this.#t(`/v1/jobs/${encodeURIComponent(t)}/webhooks`)}upload(t){return this.#t("/v1/artifacts",{method:"POST",body:JSON.stringify(t)})}parse(t){return this.#t("/v1/parse",{method:"POST",body:JSON.stringify(t)})}extract(t){return this.#t("/v1/extract",{method:"POST",body:JSON.stringify(t)})}monitors(){return this.#t("/v1/monitors")}createMonitor(t){return this.#t("/v1/monitors",{method:"POST",body:JSON.stringify(t)})}monitorChecks(t,n=100){return this.#t(`/v1/monitors/${encodeURIComponent(t)}/checks?limit=${n}`)}setMonitorState(t,n){return this.#t(`/v1/monitors/${encodeURIComponent(t)}`,{method:"PATCH",body:JSON.stringify({state:n})})}removeMonitor(t){return this.#t(`/v1/monitors/${encodeURIComponent(t)}`,{method:"DELETE"})}async#a(t,n,r,o){let i;try{({job:i}=await this.cancel(t))}catch(p){return{attempted:!0,trigger:n,jobId:t,outcome:"failed",error:bWe(p,"Web Context cancellation failed")}}let s=o.cancelConfirmationMs??2e3,a=Date.now()+(Number.isFinite(s)&&s>0?s:0),c=o.pollMs??500,l,d=async p=>{try{await r(p)}catch(f){l??=bWe(f,"Web Context progress listener failed during cancellation confirmation")}};for(await d(i);!lA(i.state)&&Date.now()<a;){await new Promise(f=>{setTimeout(f,Math.min(c,Math.max(0,a-Date.now())))});let p;try{({job:p}=await this.job(t))}catch{break}i=p,await d(i)}let u=lA(i.state)?AV(i,0):void 0;return{attempted:!0,trigger:n,jobId:t,outcome:i.state==="cancelled"?"cancelled":"requested",...u?{terminalProgress:u}:{},...l?{listenerError:l}:{}}}async waitForJob(t,n={}){let r=Date.now()+(n.timeoutMs??12e4),o=i4t(n.onProgress,t),i;try{for(;Date.now()<r;){if(n.signal?.aborted)throw i="abort",n.signal.reason;let{job:s}=await this.job(t);if(await o(s),lA(s.state))return s;await new Promise((a,c)=>{let l=setTimeout(a,n.pollMs??500);n.signal?.addEventListener("abort",()=>{clearTimeout(l),i="abort",c(n.signal?.reason)},{once:!0})})}throw i="timeout",Object.assign(new Error("job wait timed out"),{code:"WAIT_TIMEOUT",jobId:t})}catch(s){let a=i==="abort"?n.cancelOnAbort===!0:i==="timeout"?n.cancelOnTimeout===!0:!1;throw!i||!a?s:o4t(s,await this.#a(t,i,o,n))}}async scrapeAndWait(t,n={}){let r=await this.scrape(t),o=await this.waitForJob(r.job.jobId,n);if(o.state!=="completed"&&o.state!=="partial"){let c;try{let d=(await this.results(o.jobId,{limit:1})).items.find(u=>typeof u.errorCode=="string")?.errorCode;typeof d=="string"&&(c=d)}catch{}throw Object.assign(new Error(r4t(o.state,c)),{code:"JOB_NOT_COMPLETED",jobId:o.jobId,state:o.state,...c?{reason:c}:{}})}let i=await this.results(o.jobId,{limit:1}),s=i.items.find(c=>c.state==="completed"&&typeof c.artifactId=="string")??i.items.find(c=>typeof c.artifactId=="string");if(!s?.artifactId)throw Object.assign(new Error("completed scrape job has no readable artifact"),{code:"JOB_ARTIFACT_MISSING",jobId:o.jobId});let a=await this.artifact(o.jobId,s.artifactId);return{job:o,item:s,artifact:a,text:new TextDecoder().decode(a.bytes)}}}});import{readFileSync as s4t}from"node:fs";function sde(e=process.env,t){let n=t??e.XENO_WEB_CONTEXT_MAX_PROVIDER_COST_USD;if(n===void 0)return;let r=Number(n.trim());if(!/^[0-9]+(?:\.[0-9]+)?$/.test(n.trim())||!Number.isFinite(r)||r<0)throw Object.assign(new Error("Web Context provider cost budget must be a finite non-negative decimal USD amount."),{code:"WEB_CONTEXT_INVALID_BUDGET"});return r}function IB(e,t,n,r=5){if(n!==void 0&&(!Number.isSafeInteger(n)||n<1))throw Object.assign(new Error("Web Context account returned an invalid page quota."),{code:"WEB_CONTEXT_INVALID_ACCOUNT"});if(e==="search"&&(!Number.isSafeInteger(r)||r<1||r>20))throw Object.assign(new Error("Web Context search result count must be an integer from 1 to 20."),{code:"WEB_CONTEXT_INVALID_BUDGET"});let o=e==="map"||e==="crawl"?100:e==="search"?r:1;return{maxAttempts:3,maxConcurrency:4,maxBytes:1e7,maxPages:Math.min(o,n??o),maxDurationMs:12e4,maxRedirects:8,maxProviderCostUsd:t??0,...t===void 0?{providerCostMode:"account-default"}:{}}}function c4t(e=process.env){let t=e.XENO_WEB_CONTEXT_TOKEN?.trim();if(t)return t;let n=e.XENO_WEB_CONTEXT_TOKEN_FILE?.trim();if(n){let r=s4t(n,"utf8").trim();if(r)return r}throw Object.assign(new Error("XENO Web Context is not configured. Set XENO_WEB_CONTEXT_TOKEN or XENO_WEB_CONTEXT_TOKEN_FILE."),{code:"WEB_CONTEXT_NOT_CONFIGURED"})}function l4t(e=process.env,t={}){let n=e.XENO_WEB_CONTEXT_URL?.trim(),r=!!(e.XENO_WEB_CONTEXT_TOKEN?.trim()||e.XENO_WEB_CONTEXT_TOKEN_FILE?.trim());if(n||r)return{baseUrl:n||a4t,token:c4t(e),source:"explicit",auth:"bearer"};let o=e.XENO_API_KEY?.trim();return o?{baseUrl:IWe,token:o,pathPrefix:kWe,source:"account",auth:"bearer"}:{baseUrl:IWe,pathPrefix:kWe,source:"account",auth:"dpop"}}function d4t(){return Object.assign(new Error("XENO Web Context needs a XENO account. Sign in with `xeno`, or set XENO_WEB_CONTEXT_URL and XENO_WEB_CONTEXT_TOKEN."),{code:"WEB_CONTEXT_NOT_CONFIGURED"})}function u4t(e={}){return async(t,n)=>{let r=typeof t=="string"?t:t instanceof URL?t.href:t.url,o=(n?.method??"GET").toUpperCase(),s=await(e.accountHost?await e.accountHost():await ys()).authorize(o,r,["inference:run"]),a=new Headers(n?.headers);if(s)return a.set("authorization",`DPoP ${s.token}`),a.set("dpop",s.headers.dpop),fetch(t,{...n,headers:a});let c=hv(e);if(c.state!=="present")throw d4t();return a.set("authorization",`Bearer ${c.key}`),fetch(t,{...n,headers:a})}}function ade(e=process.env,t={}){let n=l4t(e,t);return n.auth==="dpop"?new vB({baseUrl:n.baseUrl,token:"dpop-account-session",pathPrefix:n.pathPrefix,fetchImpl:u4t(t)}):new vB({baseUrl:n.baseUrl,token:n.token??"",...n.pathPrefix?{pathPrefix:n.pathPrefix}:{}})}function EWe(e=process.env){let t=sde(e),n=IB("fetch",t),r=yq({actor:{id:"xeno-agent-cli",kind:"agent"},scope:{kind:"local-profile",profileId:"pending-token-scope"},classification:"public",purposePrefix:"xeno-agent-cli:chat",budget:{...n,maxProviderCostUsd:t,durationMs:n.maxDurationMs}});return{client:new ide(e),createRequest:(o,i)=>{let s=r(o,i);return o==="search"&&(s.budget.maxPages=IB("search",n.maxProviderCostUsd,void 0,typeof i.maxResults=="number"?i.maxResults:5).maxPages),s}}}var a4t,IWe,kWe,ide,cde=ge(()=>{"use strict";vWe();of();Tu();et();a4t="http://127.0.0.1:8080",IWe="https://api.xenostudio.ai",kWe="/v1/web";ide=class{constructor(t){this.env=t}env;client;account;async search(t){return this.getClient().search(await this.bindTenant(t,"search",t.count))}async scrapeAndWait(t,n){return this.getClient().scrapeAndWait(await this.bindTenant(t,"fetch"),n)}getClient(){return this.client??=ade(this.env),this.client}async bindTenant(t,n,r){this.account??=this.getClient().account();let o=await this.account,i=IB(n,t.budget.maxProviderCostUsd,o.quota?.maxPagesPerJob,r);return{...t,scope:{kind:"tenant",tenantId:o.tenantId},budget:{...t.budget,maxPages:Math.min(t.budget.maxPages,i.maxPages)}}}}});var SWe=ge(()=>{"use strict"});function CWe(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e;if(t.success===!1)return typeof t.error=="string";if(t.success!==!0||!t.snapshot||typeof t.snapshot!="object"||Array.isArray(t.snapshot))return!1;let n=t.snapshot,r=i=>typeof i=="number"&&Number.isSafeInteger(i)&&i>=0,o=(i,s,a,c=!1)=>Array.isArray(i)&&i.every(l=>l&&typeof l=="object"&&!Array.isArray(l)&&typeof l[s]=="string"&&r(l[a])&&(!c||l.cost===null));return n.source==="local-runtime-journal"&&n.billingStatus==="unavailable"&&n.totalCost===null&&typeof n.observedAt=="string"&&Number.isFinite(Date.parse(n.observedAt))&&r(n.totalTokens)&&r(n.totalRequests)&&r(n.unmeasuredRequests)&&n.unmeasuredRequests<=n.totalRequests&&o(n.dailyUsage,"label","value")&&o(n.weeklyUsage,"label","value")&&o(n.monthlyUsage,"label","value")&&o(n.costByModel,"model","tokens",!0)&&o(n.topAgents,"name","tokens",!0)}var xWe=ge(()=>{"use strict"});var RWe=ge(()=>{"use strict"});function TWe(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e;return t.success===!1?typeof t.error=="string":t.success===!0&&t.source==="local-runtime-journal"&&typeof t.observedAt=="string"&&Number.isFinite(Date.parse(t.observedAt))&&typeof t.complete=="boolean"&&(t.complete?t.nextCursor===null:typeof t.nextCursor=="string"&&t.nextCursor.length>0&&t.nextCursor.length<=4096)&&Array.isArray(t.entries)&&t.entries.length<=1e4&&t.entries.every(n=>n&&typeof n=="object"&&["id","timestamp","action","actor","target","details"].every(r=>typeof n[r]=="string")&&Number.isFinite(Date.parse(n.timestamp)))}var PWe=ge(()=>{"use strict"});function _We(e){return!lde(e)||typeof e.success!="boolean"||e.error!==void 0&&(typeof e.error!="string"||e.error.length>1e3)?!1:e.success?e.content!==void 0&&(typeof e.content!="string"||e.content.length>128e3)||e.loadedModel!==void 0&&!$We(e.loadedModel)||e.models!==void 0&&(!Array.isArray(e.models)||e.models.length>1e3||!e.models.every(t=>lde(t)&&$We(t.id)&&typeof t.name=="string"&&t.name.length<=512&&(t.contextWindowTokens===void 0||Number.isSafeInteger(t.contextWindowTokens)&&t.contextWindowTokens>0)))||e.usage!==void 0&&(!lde(e.usage)||!["inputTokens","outputTokens"].every(t=>Number.isSafeInteger(e.usage[t])&&(e.usage[t]??-1)>=0))?!1:e.content!==void 0||e.models!==void 0||e.loadedModel!==void 0:typeof e.error=="string"&&!!e.error}var lde,$We,BWe=ge(()=>{"use strict";lde=e=>!!e&&typeof e=="object"&&!Array.isArray(e),$We=e=>typeof e=="string"&&e.length>0&&e.length<=512&&!/[\x00-\x1f\x7f]/.test(e)});var c6n,OWe=ge(()=>{"use strict";c6n=new TextEncoder});var MWe=ge(()=>{"use strict"});var NWe=ge(()=>{"use strict"});var DWe,p4t,LWe=ge(()=>{"use strict";NWe();DWe=["completed","partial","failed","cancelled"],p4t=["queued","running",...DWe]});var QWe=ge(()=>{"use strict"});var FWe=ge(()=>{"use strict"});var UWe=ge(()=>{"use strict"});var jWe=ge(()=>{"use strict"});var qWe=ge(()=>{"use strict";jWe()});var HWe=ge(()=>{"use strict"});var WWe=ge(()=>{"use strict"});var VWe=ge(()=>{"use strict"});var f4t,GWe=ge(()=>{"use strict";dA();f4t=1024*1024});function A4t(e){return typeof e=="string"&&m4t.includes(e)}function XWe(e){return Ui(e)?Yn(e.clientId)&&Yn(e.clientVersion)&&Yn(e.instanceId)&&A4t(e.surface):!1}function zWe(e){return!Ui(e)||!Ui(e.protocol)||!Ui(e.host)||!Ui(e.storage)?!1:Number.isInteger(e.protocol.current)&&E4t(e.protocol.supported)&&Yn(e.host.instanceId)&&Yn(e.host.version)&&(e.host.authority==="primary"||e.host.authority==="diagnostic-read-only")&&(e.host.processBoundary==="in-process"||e.host.processBoundary==="per-user-service")&&e.storage.owner==="xeno-agent-host"&&Number.isInteger(e.storage.schemaVersion)&&Number.isInteger(e.storage.eventSchemaVersion)&&XWe(e.surface)}function dde(e){return!Ui(e)||!Yn(e.revision)||!Array.isArray(e.providers)?!1:e.providers.every(I4t)}function y4t(e){return!Ui(e)||!Ui(e.event)?!1:Yn(e.id)&&Number.isInteger(e.sequence)&&typeof e.sequence=="number"&&e.sequence>=0&&Yn(e.timestamp)&&Yn(e.conversationId)&&Yn(e.requestId)&&Yn(e.type)&&Yn(e.source)}function KWe(e){return!Ui(e)||!Array.isArray(e.events)?!1:(e.nextSequence===null||typeof e.nextSequence=="number"&&Number.isInteger(e.nextSequence)&&e.nextSequence>=0)&&e.events.every(y4t)}function YWe(e){return!Ui(e)||typeof e.success!="boolean"?!1:e.success?(e.status==="accepted"||e.status==="replayed")&&Yn(e.conversationId)&&Yn(e.requestId)&&Yn(e.adapterId)&&Ui(e.selection)&&Yn(e.selection.providerId)&&Yn(e.selection.catalogRevision):Yn(e.code)&&Yn(e.safeError)}function ZWe(e){return!Ui(e)||typeof e.success!="boolean"?!1:e.success?(e.status==="cancel_requested"||e.status==="replayed")&&Yn(e.conversationId)&&Yn(e.requestId):Yn(e.code)&&Yn(e.safeError)}function eVe(e){return Ui(e)&&Yn(e.id)&&typeof e.sequence=="number"&&Number.isInteger(e.sequence)&&e.sequence>0&&typeof e.timestamp=="number"&&Number.isFinite(e.timestamp)&&b4t(e.type)&&e.source==="host"&&e.schemaVersion===1&&e.redactionState==="safe"&&"payload"in e}function b4t(e){return typeof e=="string"&&w4t.includes(e)}function tVe(e,t,n){if(e.surface.surface!==t.surface||e.surface.instanceId!==t.instanceId)throw new wi("surface_mismatch",`Agent host acknowledged ${e.surface.surface}/${e.surface.instanceId} instead of ${t.surface}/${t.instanceId}.`);if(e.protocol.current<n.min||e.protocol.current>n.max||n.max<e.protocol.supported.min||n.min>e.protocol.supported.max)throw new wi("protocol_mismatch",`Agent host protocol ${e.protocol.current} is incompatible with client range ${n.min}-${n.max}.`)}function v4t(e){return!(!Ui(e)||e.chatExecution!==void 0&&!kB(e.chatExecution)||e.durableResume!==void 0&&!kB(e.durableResume)||e.nativeTuiAttach!==void 0&&!kB(e.nativeTuiAttach)||e.reconciliation!==void 0&&!kB(e.reconciliation)||e.modelSwitchInPlace!==void 0&&!kB(e.modelSwitchInPlace)||e.resumeCompatibilityKey!==void 0&&typeof e.resumeCompatibilityKey!="string")}function kB(e){return Ui(e)?(e.status==="available"||e.status==="degraded"||e.status==="blocked"||e.status==="unsupported")&&(e.source==="provider"||e.source==="host"||e.source==="policy")&&(e.reason===void 0||typeof e.reason=="string")&&(e.version===void 0||typeof e.version=="string"):!1}function I4t(e){return Ui(e)?Yn(e.id)&&typeof e.kind=="string"&&h4t.includes(e.kind)&&Yn(e.displayName)&&nVe(e.availability)&&Ui(e.capabilities)&&(e.providerSession===void 0||v4t(e.providerSession))&&Array.isArray(e.models)&&e.models.every(k4t)&&Yn(e.catalogRevision):!1}function k4t(e){return Ui(e)&&Yn(e.id)&&Yn(e.displayName)&&nVe(e.availability)&&(e.reasoningOptions===void 0||Array.isArray(e.reasoningOptions)&&e.reasoningOptions.every(t=>Ui(t)&&Yn(t.id)&&Yn(t.label)&&(t.runtimeModelId===void 0||Yn(t.runtimeModelId))&&(t.runtimeReasoningEffort===void 0||typeof t.runtimeReasoningEffort=="string"&&/^[a-z][a-z0-9_-]{0,79}$/i.test(t.runtimeReasoningEffort))&&(t.isDefault===void 0||typeof t.isDefault=="boolean")))}function nVe(e){return e==="available"||e==="degraded"||e==="blocked"||e==="unavailable"}function E4t(e){return Ui(e)&&Number.isInteger(e.min)&&Number.isInteger(e.max)&&typeof e.min=="number"&&typeof e.max=="number"&&e.min>0&&e.max>=e.min}function Yn(e){return typeof e=="string"&&e.trim().length>0}function Ui(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function yV(e){for(let t of C4t)for(let n of S4t)if(e===`${t}tool.${n}`)return n;return null}function Cv(e,t){let n=e?.[t];return typeof n=="string"&&n.trim()?n:void 0}function bV(e){let t=e.event;return Cv(t,"toolName")||Cv(t,"tool")||Cv(t,"name")||Cv(t,"title")||Cv(t,"kind")}function VC(e){let t=e.event;return Cv(t,"toolCallId")||Cv(t,"tool_call_id")}function rVe(e){let t=e.event;for(let n of["rawInput","input","arguments","parameters","args"]){let r=t?.[n];if(r&&typeof r=="object"&&!Array.isArray(r))return r}}function oVe(e){let t=e.event;for(let n of["rawOutput","output","result","content"]){let r=t?.[n];if(typeof r=="string")return r.length>0?r:void 0;if(r!=null)try{let o=JSON.stringify(r);if(o&&o!=="{}"&&o!=="[]")return o}catch{}}}function vV(e){return e==="completed"?!0:e==="failed"||e==="cancelled"?!1:null}var WC,JWe,m4t,h4t,g4t,x6n,w4t,wi,S4t,C4t,dA=ge(()=>{"use strict";SWe();xWe();RWe();PWe();BWe();OWe();MWe();LWe();QWe();FWe();UWe();qWe();HWe();WWe();VWe();GWe();WC=1,JWe=1,m4t=["standalone-desktop","hub-embed","shell-embed","embed-preview","panel-embed","headless-client"],h4t=["sdk-native","xeno-cloud","cli-app-server","cli-remote","acp"],g4t=["workspace.usage","workspace.audit","inference.request","workspace.schedule","workspace.backup","workspace.environment","account.request","workforce.request","workspace.notifications","workspace.rules","workspace.browser","workspace.browser.session","host.handshake","providers.list","providers.refresh","runtime.events.list","workspace.lifecycle.apply","state.workspaces.load","state.workspaces.save","state.conversations.load","state.conversations.save","state.conversations.delete","workspace.access.grant","coordination.held.list","coordination.held.release","coordination.policy.set","coordination.state.get","coordination.action","workspace.application.grant","workspace.directory.list","workspace.file.read","workspace.file.write","workspace.command.run","workspace.terminal.start","workspace.terminal.stop","workspace.pty.start","workspace.pty.snapshot","workspace.pty.input","workspace.pty.resize","workspace.pty.clear","workspace.pty.stop","conversation.open","conversation.resume","xeno.tui.attach","provider.lanes.list","provider.lanes.get","provider.lanes.select","provider.native.attach","provider.native.detach","provider.native.reattach","provider.native.stop","provider.reconcile","turn.start","turn.cancel","turn.steer","context.inject","turn.queue","turn.queue.list","run.observation.snapshot","run.observation.change","run.observation.overlaps","fleet.view","fleet.route","fleet.plan","subagent.run.create","subagent.run.list","subagent.run.cancel","subagent.scheduler.status","subagent.scheduler.recover","session.list","session.attach","session.detach","session.snapshot","session.input","session.takeover","session.release","session.setMode","acp.agents.list","acp.agents.addPreset","acp.agents.remove","acp.capabilitySnapshot.get","acp.command.invoke","intake.sources.list","intake.items.list","intake.item.claim","intake.item.release","intake.item.dispatch","knowledge.list","knowledge.record","knowledge.forget","knowledge.context","turn.queue.drop","elicitation.choose-directory.answer","elicitation.workspace-placement.answer","elicitation.permission.answer","turn.resume","acp.provider.approve","permissions.rules.list","permissions.rules.revoke","elicitation.ask-user.answer","sdk.sessions.list","sdk.sessions.show","sdk.sessions.attach","sdk.sessions.detach","sdk.sessions.delete","sdk.sessions.clean","sdk.checkpoints.list","sdk.checkpoints.restore","sdk.checkpoints.delete","sdk.tasks.output","sdk.tasks.stop","engineering.git.status","engineering.git.diff","engineering.git.stage","engineering.git.unstage","engineering.git.commit","engineering.git.branch","engineering.git.push","engineering.git.pr.create","engineering.landing.enqueue","engineering.landing.remove","engineering.landing.status","engineering.landing.land","engineering.landing.verify","engineering.checks.discover","engineering.checks.run","engineering.background.start","engineering.background.list","engineering.background.output","engineering.background.stop","engineering.runs.list","engineering.diagnostics","engineering.patches.list","engineering.patches.enqueue","engineering.patches.update","engineering.patches.review","engineering.checkpoints.list","engineering.checkpoints.compare","engineering.checkpoints.restore","engineering.sessions.list","engineering.runtime.timeline"],x6n=new Set(g4t),w4t=["host.ready","provider.catalog.changed","state.workspaces.changed","runtime.event.appended","turn.execution.completed","turn.execution.failed","turn.execution.abandoned","elicitation.choose-directory.requested","elicitation.workspace-placement.requested","elicitation.permission.requested","elicitation.ask-user.requested","task.changed","workspace.terminal.data","workspace.terminal.exit","workspace.pty.data","workspace.pty.exit","coordination.event","run.observation","session.event","provider.lane.created","provider.lane.selected","provider.lane.resumed","provider.lane.invalidated","provider.writer.acquired","provider.writer.renewed","provider.writer.released","provider.writer.recovery_classified","provider.native_tui.started","provider.native_tui.detached","provider.native_tui.exited","provider.reconciliation.started","provider.reconciliation.completed","provider.reconciliation.failed","provider.portable_context.acknowledged_partial"],wi=class extends Error{code;constructor(t,n){super(n),this.name="AgentHostProtocolError",this.code=t}};S4t=["started","updated","completed","failed","cancelled"],C4t=["","acp."]});function IV(e){let t=e.type.toLowerCase();if(!(t.includes("tool")||VC(e))&&!(!t.includes("text")&&!t.includes("message")&&!t.includes("delta"))&&!(t.includes("complete")||t.includes("final")||t.includes("end")))for(let n of["delta","text","content","chunk"]){let r=e.event[n];if(typeof r=="string"&&r.length>0)return r}}var ude=ge(()=>{"use strict";dA()});import{createHash as x4t}from"node:crypto";import{setTimeout as R4t}from"node:timers/promises";function $4t(e,t){return`subrun-${x4t("sha256").update(`${e}\0${t}`).digest("hex").slice(0,32)}`}async function _4t(e,t,n){return((await e.listRuntimeEvents({conversationId:t,subagentRunId:n,limit:500}))?.events??[]).map(o=>IV(o)??"").join("")}function B4t(e,t,n,r){let o=new Set,i=typeof r.onToolStart=="function"||typeof r.onToolEnd=="function",s=a=>{try{a()}catch{}};return async function(){if(!i)return;let c=await e.listRuntimeEvents({conversationId:t,subagentRunId:n,limit:500}).catch(()=>null);for(let l of c?.events??[]){let d=yV(String(l.type??""));if(!d)continue;let u=`${VC(l)??l.id}:${d}`;if(o.has(u))continue;o.add(u);let p=bV(l)??"unknown";if(d==="started"&&r.onToolStart){let m=r.onToolStart;s(()=>m(p,rVe(l)??{}))}let f=vV(d);if(f!==null&&r.onToolEnd){let m=r.onToolEnd;s(()=>m(p,{success:f,output:oVe(l)??""}))}}}}function iVe(e){let t=e.pollIntervalMs??250;return async n=>{let r=n.task,o=$4t(e.rootTraceId,r.id),i={lastTraceId:null,tokenUsage:{input:0,output:0,total:0},async run(s){let a=Math.max(1e3,e.deadline-Date.now()),c={parentConversationId:e.parentConversationId,...e.parentRequestId===void 0?{}:{parentRequestId:e.parentRequestId},parentAgentId:e.parentAgentId,childConversationId:o,childAgentId:r.role?`delegated-${r.role}`:"delegated-branch",workspaceId:e.workspaceId,teamId:e.teamId,objective:s,...r.role===void 0?{}:{role:r.role},policy:{maxRuntimeMs:a}},l=await e.client.createSubagentRun(c);if(!l?.success||!l.run)throw new Error(l?.safeError??"The Agent host refused to create a subagent run for this delegated branch.");let d=l.run.id;i.lastTraceId=d;let u=B4t(e.client,o,d,{onToolStart:n.onToolStart,onToolEnd:n.onToolEnd});for(;;){if(e.signal?.aborted){await e.client.cancelSubagentRun({runId:d}).catch(()=>{});let g=new Error("Delegated branch was cancelled.");throw g.name="AgentInterruptedError",g}let f=((await e.client.listSubagentRuns({parentConversationId:e.parentConversationId}))?.runs??[]).find(g=>g.id===d),m=String(f?.status??"");if(T4t.has(m)){if(P4t.has(m))throw new Error(f?.error??`The delegated branch ended as '${m}' without reporting a reason.`);await u();let g=await _4t(e.client,o,d);if(g.length===0)throw new Error(`The delegated branch reported '${m}' but produced no readable output. Its runtime events carry no text for this run id.`);return g}if(Date.now()>=e.deadline)throw await e.client.cancelSubagentRun({runId:d}).catch(()=>{}),new Error("The delegated branch exceeded the time this run was given to wait.");await u(),await R4t(t,void 0,{signal:e.signal})}}};return i}}var T4t,P4t,sVe=ge(()=>{"use strict";dA();ude();T4t=new Set(["completed","succeeded","failed","cancelled","error"]),P4t=new Set(["failed","cancelled","error"])});function EB(e,t){let n=e.run.bind(e);return e.run=async r=>{try{return await t.start(),await n(r)}finally{await t.stop()}},e}function Ah(e){return!e||e.status==="completed"}function SB(e,t=n=>{at.cleanupOwner(n)}){if(e)try{t(e)}catch{}}async function df(e){let{agent:t,signal:n}=e,r=()=>SB(e.ownerSessionId,e.cleanupOwner),o=()=>{t.cancelCurrentTurn()};if(n?.aborted)throw r(),await e.lifecycle?.stop(),new _r;n?.addEventListener("abort",o,{once:!0});let i=!1;try{if(e.lifecycle&&(await e.lifecycle.start(n),n?.aborted))throw new _r;let s=await(e.run??(()=>t.run(e.prompt)))(),a=t.lastRunTermination??void 0;i=Ah(a);let c=a?{status:a.status,reason:a.reason,...a.message?{message:a.message}:{}}:void 0;return{output:s,...c?{termination:c}:{},tokenUsage:{...t.tokenUsage}}}finally{n?.removeEventListener("abort",o),i||r(),await e.lifecycle?.stop()}}function xv(e,t,n){if(!t)return e;let r=e.run.bind(e);return e.run=async o=>{let i=!1;try{let s=await r(o);return i=Ah(e.lastRunTermination),s}finally{i||SB(t,n)}},e}function pde(e){return e.stopRequested||e.termination?.status==="interrupted"?"stopped":e.threw||e.termination?.status==="error"?"failed":Ah(e.termination)?"completed":"unfinished"}function CB(e){let t=e.summary.cancelled??0,n=e.summary.incomplete??0,r=[];return n>0&&r.push(`${n} stopped before finishing`),t>0&&r.push(`${t} cancelled`),e.incomplete?`Delegation incomplete: no branch finished${r.length?` (${r.join(", ")})`:""}. The answer below is partial output from a branch that stopped early, not a final answer.`:r.length?`Delegation finished with unfinished branches: ${r.join(", ")}.`:void 0}var xB=ge(()=>{"use strict";et()});import{execFile as aVe,execFileSync as mde}from"node:child_process";import{promisify as cVe}from"node:util";import{createHash as O4t}from"node:crypto";import{existsSync as lVe,readFileSync as hde,readlinkSync as M4t}from"node:fs";import{hostname as uA}from"node:os";function EV(){return Mu}function SV(e=process.env){if(e===process.env&&fde)return fde;let t=e.SystemRoot??e.SYSTEMROOT??e.windir??e.WINDIR,n="powershell.exe";if(t&&/^[a-z]:[\\/]/i.test(t)){let r=`${t.replace(/[\\/]+$/,"")}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;lVe(r)&&(n=r)}return e===process.env&&(fde=n),n}function CV(e){return Number.isInteger(e)&&e>0}function L4t(e){return O4t("sha256").update(e).digest("hex")}function PB(e){let t=e?.trim().replaceAll("\\","/").toLowerCase();return t?`sha256:${L4t(t)}`:void 0}function kV(){if(process.platform==="linux")try{return hde("/proc/sys/kernel/random/boot_id","utf8").trim()||void 0}catch{return}}function Nu(e){if(typeof e!="number"||!CV(e))return"dead";try{return process.kill(e,0),"live"}catch(t){return t.code==="ESRCH"?"dead":"unknown"}}function wde(e){let t=Date.parse(e);return Number.isFinite(t)?new Date(t).toISOString():null}function mVe(e){return["-NoLogo","-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-Command",["$ErrorActionPreference = 'Stop'",`$items = @(Get-Process -Id @(${e.join(", ")}) -ErrorAction SilentlyContinue)`,"$out = @($items | ForEach-Object { $path = try { [string]$_.Path } catch { '' }; $started = try { $_.StartTime.ToUniversalTime().ToString('o') } catch { '' }; [pscustomobject]@{ pid = [int]$_.Id; startedAt = $started; executable = $path } })","$out | ConvertTo-Json -Compress"].join("; ")]}function hVe(e){let t=new Map;try{if(!e)return t;let n=JSON.parse(e);for(let r of Array.isArray(n)?n:[n]){let o=Number(r.pid),i=wde(String(r.startedAt??""));!CV(o)||!i||t.set(o,{pid:o,processStartedAt:i,hostname:uA(),...PB(r.executable)?{executableFingerprint:PB(r.executable)}:{},confidence:"observed"})}}catch{return t}return t}function gVe(e,t){let n=new Map;if(t.fresh)return{known:n,pending:e,skip:!1};let r=Mu.now(),o=[];for(let i of e){let s=TB.get(i);s&&r>=s.at&&r-s.at<fVe?s.identity&&n.set(i,s.identity):o.push(i)}return{known:n,pending:o,skip:o.length>0&&r<gde}}function wVe(e,t){let n=Mu.now();gde=0;for(let r of e)TB.set(r,{identity:t.get(r)??null,at:n});if(TB.size>512)for(let[r,o]of TB)n-o.at>=fVe&&TB.delete(r)}function AVe(){gde=Mu.now()+N4t}function Q4t(e,t={}){if(!e.length)return new Map;let{known:n,pending:r,skip:o}=gVe(e,t);if(!r.length||o)return n;try{let i=hVe(Mu.runSync(SV(),mVe(r),{timeoutMs:pVe}).trim());wVe(r,i);for(let[s,a]of i)n.set(s,a)}catch{AVe()}return n}function F4t(){if(RB)return RB;try{let e=Number.parseInt(mde("getconf",["CLK_TCK"],{encoding:"utf8",timeout:2e3,stdio:["ignore","pipe","ignore"]}).trim(),10);RB=Number.isFinite(e)&&e>0?e:100}catch{RB=100}return RB}function U4t(){try{let e=/^btime\s+(\d+)$/m.exec(hde("/proc/stat","utf8"));return e?Number.parseInt(e[1]??"",10):null}catch{return null}}function j4t(e){try{let t=hde(`/proc/${e}/stat`,"utf8"),n=t.lastIndexOf(")");if(n<0)return null;let r=t.slice(n+2).trim().split(/\s+/),o=Number(r[19]),i=U4t();if(!Number.isFinite(o)||i===null)return null;let s=new Date((i+o/F4t())*1e3).toISOString(),a;try{a=M4t(`/proc/${e}/exe`)}catch{a=void 0}return{pid:e,processStartedAt:s,hostname:uA(),...kV()?{bootId:kV()}:{},...PB(a)?{executableFingerprint:PB(a)}:{},confidence:"observed"}}catch{return null}}function yVe(e){let t=new Map;if(Mu.platform==="linux"){for(let n of e){let r=j4t(n);r&&t.set(n,r)}return t}for(let n of e)try{let r=mde("ps",["-p",String(n),"-o","lstart="],{encoding:"utf8",timeout:2e3,env:{...process.env,LC_ALL:"C"},stdio:["ignore","pipe","ignore"]}).trim(),o=wde(r);if(!o)continue;t.set(n,{pid:n,processStartedAt:o,hostname:uA(),confidence:"observed"})}catch{continue}return t}function $B(e,t={}){let n=[...new Set(e.filter(CV))],r=n.includes(process.pid),o=r?n.filter(s=>s!==process.pid):n,i=Mu.platform==="win32"?Q4t(o,t):yVe(o);return r&&i.set(process.pid,pA()),i}function Ade(e,t={}){return $B([e],t).get(e)??null}async function bVe(e,t,n={}){t?.throwIfAborted();let r=[...new Set(e.filter(CV))],o=r.filter(s=>s!==process.pid),i=new Map;if(Mu.platform==="win32"&&o.length){let{known:s,pending:a,skip:c}=gVe(o,n);if(i=s,a.length&&!c)try{let l=hVe((await Mu.run(SV(),mVe(a),{timeoutMs:pVe,signal:t})).trim());wVe(a,l);for(let[d,u]of l)i.set(d,u)}catch{t?.throwIfAborted(),AVe()}}else if(Mu.platform==="linux")i=yVe(o);else if(Mu.platform!=="win32")for(let s of o){t?.throwIfAborted();try{let{stdout:a}=await cVe(aVe)("ps",["-p",String(s),"-o","lstart="],{encoding:"utf8",timeout:2e3,signal:t,env:{...process.env,LC_ALL:"C"},maxBuffer:4096}),c=wde(a.trim());c&&i.set(s,{pid:s,processStartedAt:c,hostname:uA(),confidence:"observed"})}catch{t?.throwIfAborted()}}return t?.throwIfAborted(),r.includes(process.pid)&&i.set(process.pid,pA()),i}function xV(e,t=new Date,n=!1){return(n?Ade(e):null)??{pid:e,processStartedAt:t.toISOString(),hostname:uA(),confidence:"degraded"}}function pA(){let e=new Date(Date.now()-Math.floor(process.uptime()*1e3)).toISOString();return{pid:process.pid,processStartedAt:e,hostname:uA(),...kV()?{bootId:kV()}:{},...lVe(process.execPath)?{executableFingerprint:PB(process.execPath)}:{},confidence:"self"}}function Ja(e,t=Ade){if(e.hostname!==uA())return{status:"remote",expected:e,reason:"Process belongs to another host."};if(Nu(e.pid)==="dead")return{status:"dead",expected:e,reason:"Process ID is not live."};let n=t(e.pid);if(!n)return Nu(e.pid)==="dead"?{status:"dead",expected:e,reason:"Process ID is not live."}:{status:"degraded",expected:e,reason:"Creation time could not be observed."};let r=Date.parse(e.processStartedAt),o=Date.parse(n.processStartedAt);return!Number.isFinite(r)||!Number.isFinite(o)||Math.abs(r-o)>dVe?{status:"mismatch",expected:e,observed:n,reason:"Process creation time does not match."}:e.bootId&&n.bootId&&e.bootId!==n.bootId?{status:"mismatch",expected:e,observed:n,reason:"Host boot identity does not match."}:e.executableFingerprint&&n.executableFingerprint&&e.executableFingerprint!==n.executableFingerprint?{status:"mismatch",expected:e,observed:n,reason:"Executable identity does not match."}:{status:"live",expected:e,observed:n}}function uf(e){return e.hostname===uA()&&Nu(e.pid)==="dead"}var dVe,uVe,pVe,N4t,fVe,GC,D4t,Mu,TB,gde,fde,RB,RV,Ed=ge(()=>{"use strict";dVe=3e3,uVe=dVe,pVe=4e3,N4t=15e3,fVe=2e3,GC=1e4,D4t={platform:process.platform,now:()=>Date.now(),runSync:(e,t,n)=>mde(e,t,{encoding:"utf8",windowsHide:!0,timeout:n.timeoutMs,stdio:["ignore","pipe","ignore"]}),run:async(e,t,n)=>(await cVe(aVe)(e,t,{encoding:"utf8",windowsHide:!0,timeout:n.timeoutMs,maxBuffer:1024*1024,signal:n.signal})).stdout},Mu=D4t,TB=new Map,gde=0;RV=e=>Ade(e,{fresh:!0})});import{createHash as q4t,randomBytes as H4t}from"node:crypto";import{chmodSync as W4t,existsSync as V4t,mkdirSync as IVe,readFileSync as G4t,renameSync as X4t,unlinkSync as kVe,writeFileSync as J4t}from"node:fs";import{dirname as z4t,join as _B}from"node:path";function EVe(){return fa()}function K4t(e){return q4t("sha256").update(e).digest("hex").slice(0,16)}function wn(){return _B(EVe(),"daemon")}function yde(){return _B(wn(),"daemon.json")}function SVe(){return _B(wn(),"daemon.lock")}function XC(){return _B(wn(),"daemon.log")}function bde(){let e=K4t(EVe());return process.platform==="win32"?{transport:"named-pipe",endpoint:`\\\\.\\pipe\\xeno-agent-daemon-${e}`}:{transport:"unix-socket",endpoint:_B(wn(),"daemon.sock")}}function TV(){IVe(wn(),{recursive:!0})}function CVe(){return H4t(32).toString("base64url")}function vVe(e){if(process.platform!=="win32")try{W4t(e,384)}catch{}}function vde(){try{let e=yde(),t=G4t(e,"utf8"),n=JSON.parse(t);if(!n||n.schemaVersion!==1||n.protocolVersion!==1||n.transport!=="named-pipe"&&n.transport!=="unix-socket"||typeof n.endpoint!="string"||typeof n.authToken!="string"||!Number.isSafeInteger(n.pid)||typeof n.startedAt!="string"||typeof n.cliVersion!="string"||typeof n.logPath!="string")throw new Error("daemon state schema is invalid");return n}catch(e){if(e.code==="ENOENT")return null;throw new Error(`Daemon state is corrupt or unreadable: ${e instanceof Error?e.message:String(e)}`)}}function xVe(e){let t=yde();IVe(z4t(t),{recursive:!0});let n=`${t}.${process.pid}.${Date.now()}.tmp`;J4t(n,JSON.stringify(e,null,2)+`
2906
2906
  `,{encoding:"utf8",mode:384}),vVe(n),X4t(n,t),vVe(t)}function PV(){try{kVe(yde())}catch{}}function RVe(){if(process.platform==="win32")return;let{endpoint:e}=bde();if(V4t(e))try{kVe(e)}catch{}}function js(e){return Nu(e)!=="dead"}var Yo=ge(()=>{"use strict";hh();Ed()});import{existsSync as Y4t,linkSync as Z4t,mkdirSync as eXt,readFileSync as tXt,rmSync as kde,statSync as nXt,writeFileSync as rXt}from"node:fs";import{hostname as TVe}from"node:os";import{dirname as oXt}from"node:path";import{randomUUID as iXt}from"node:crypto";function sXt(){return new Date().toISOString()}function Ide(e){try{return JSON.parse(tXt(e,"utf8"))}catch{return null}}function aXt(e){if(e.hostname!==TVe())return!0;let t=Date.parse(e.acquiredAt);if(Number.isFinite(t)&&Date.now()-t<3e4)return!0;if(!js(e.pid))return!1;if(e.processIdentity){let n=Ja(e.processIdentity);return n.status==="live"||n.status==="degraded"||n.status==="remote"}return!0}function PVe(e,t){eXt(oXt(e),{recursive:!0});let n=`${e}.${process.pid}.${iXt()}.tmp`;rXt(n,JSON.stringify(t,null,2)+`
2907
2907
  `,{encoding:"utf8",flag:"wx"});try{Z4t(n,e)}finally{kde(n,{force:!0})}}function cXt(e){try{return Date.now()-nXt(e).mtimeMs<3e4}catch{return!1}}function lXt(e,t){return e?.pid===t.pid&&e.hostname===t.hostname&&e.processStartedAt===t.processStartedAt&&e.acquiredAt===t.acquiredAt}function BB(e,t){return Object.assign(new Error(`${e} is already locked ${t}.`),{code:"CONTROL_PLANE_LOCK_BUSY"})}function ga(e){return e instanceof Error&&"code"in e&&e.code==="CONTROL_PLANE_LOCK_BUSY"}function dXt(e,t,n){try{PVe(e,t)}catch(r){throw r.code==="EEXIST"?BB(n,"by another contender"):r}}function uXt(e,t){let n=Ide(e);n?.pid!==t.pid||n.hostname!==t.hostname||n.processStartedAt!==t.processStartedAt||kde(e,{force:!0})}function Ai(e,t,n){let r=sXt(),o=pA(),i={schemaVersion:1,name:t,pid:process.pid,hostname:TVe(),processStartedAt:o.processStartedAt,processIdentity:o,version:n,acquiredAt:r,updatedAt:r};try{PVe(e,i)}catch(s){if(s.code!=="EEXIST")throw s;let c=Ide(e);if(c&&aXt(c))throw BB(t,`by PID ${c.pid} on ${c.hostname}`);if(c){if(!lXt(Ide(e),c))throw BB(t,"while ownership was changing")}else{if(!Y4t(e))throw BB(t,"while ownership was changing");if(cXt(e))throw BB(t,"by an owner whose record is still being published")}kde(e,{force:!0}),dXt(e,i,t)}return{record:i,release:()=>{uXt(e,i)}}}var Sd=ge(()=>{"use strict";Yo();Ed()});import{createHash as DVe,randomBytes as pXt,randomUUID as LVe}from"node:crypto";import{closeSync as QVe,existsSync as Cde,fstatSync as fXt,fsyncSync as mXt,mkdirSync as xde,openSync as FVe,readFileSync as Sde,readSync as hXt,renameSync as gXt,writeFileSync as UVe}from"node:fs";import{cpus as wXt}from"node:os";import{dirname as jVe,isAbsolute as AXt,join as KC,resolve as yXt}from"node:path";function MB(e,t,n=1,r=Number.MAX_SAFE_INTEGER){let o=typeof e=="number"?e:Number.parseInt(String(e??""),10);return Number.isFinite(o)?Math.min(r,Math.max(n,Math.trunc(o))):t}function IXt(e,t,n=0,r=Number.MAX_SAFE_INTEGER){let o=typeof e=="number"?e:Number(e);return Number.isFinite(o)?Math.min(r,Math.max(n,o)):t}function JC(e,t){return t===void 0?e:Math.min(e,t)}function OB(e,t){return{maxConcurrency:JC(e.maxConcurrency,t?.maxConcurrency),maxCredentialConcurrency:JC(e.maxCredentialConcurrency,t?.maxCredentialConcurrency),maxRequestsPerWindow:JC(e.maxRequestsPerWindow,t?.maxRequestsPerWindow),maxTokensPerWindow:JC(e.maxTokensPerWindow,t?.maxTokensPerWindow),windowMs:t?.windowMs===void 0?e.windowMs:Math.max(1e3,t.windowMs)}}function kXt(e={}){let t=e.env??process.env,n=Math.max(1,e.cpuCount??wXt().length),r=Math.min(Math.max(1,n-2),bXt),o=MB(t.XENO_WORKFLOW_GLOBAL_CONCURRENCY,r,1,Ede),s=t.XENO_WORKFLOW_TRUSTED_CONCURRENCY_OVERRIDE==="1"?o:Math.min(r,o);s=JC(s,e.user?.globalConcurrency),s=JC(s,e.managed?.globalConcurrency),s=MB(s,r,1,Ede);let a={maxConcurrency:Math.min(s,8),maxCredentialConcurrency:Math.min(s,4),maxRequestsPerWindow:120,maxTokensPerWindow:2e6,windowMs:6e4},c=OB(a,e.user?.providerDefault),l=OB(c,e.managed?.providerDefault),d=new Set([...Object.keys(e.user?.providers??{}),...Object.keys(e.managed?.providers??{})]),u=Object.fromEntries([...d].map(f=>[f,OB(OB(l,e.user?.providers?.[f]),e.managed?.providers?.[f])])),p=(f,m,g=1,h=Number.MAX_SAFE_INTEGER)=>{let w=m,A=e.user?.[f],y=e.managed?.[f];return typeof A=="number"&&(w=Math.min(w,A)),typeof y=="number"&&(w=Math.min(w,y)),MB(w,m,g,h)};return{schemaVersion:1,productHardConcurrency:Ede,globalConcurrency:s,perRunConcurrency:p("perRunConcurrency",s,1,s),perParentConcurrency:p("perParentConcurrency",s,1,s),reservedPrioritySlots:Math.min(2,Math.max(0,s-1)),maxQueueLength:p("maxQueueLength",4096,1,65536),maxQueueWaitMs:p("maxQueueWaitMs",5*6e4,1e3,1440*6e4),maxAttemptsPerLogicalChild:p("maxAttemptsPerLogicalChild",3,1,100),maxAttemptsPerRun:p("maxAttemptsPerRun",1e3,1,1e4),maxReservedTokens:p("maxReservedTokens",4e6,1,Number.MAX_SAFE_INTEGER),maxReservedCostUsd:IXt(Math.min(e.user?.maxReservedCostUsd??500,e.managed?.maxReservedCostUsd??500),500,.01,1e6),leaseTtlMs:p("leaseTtlMs",4e3,2e3,5*6e4),handoffTtlMs:Math.max(p("leaseTtlMs",4e3,2e3,5*6e4),p("handoffTtlMs",6e4,2e3,10*6e4)),heartbeatIntervalMs:p("heartbeatIntervalMs",1e3,250,6e4),maxStarvationMs:p("maxStarvationMs",3e4,1e3,60*6e4),providerDefault:l,providers:u}}function BVe(e,t){if(!Cde(e)){if(t)throw new Gr("WORKFLOW_GOVERNOR_UNAVAILABLE",`Resource policy file not found: ${e}`);return}try{let n=JSON.parse(Sde(e,"utf8"));if(!n||typeof n!="object"||Array.isArray(n))throw new Error("policy root must be an object");return n}catch(n){throw new Gr("WORKFLOW_GOVERNOR_UNAVAILABLE",`Resource policy is invalid: ${e}: ${n instanceof Error?n.message:String(n)}`)}}function EXt(e=process.env){let t=jVe(wn()),n=e.XENO_WORKFLOW_RESOURCE_POLICY?.trim(),r=e.XENO_MANAGED_WORKFLOW_RESOURCE_POLICY?.trim(),o=a=>AXt(a)?a:yXt(a),i=BVe(n?o(n):KC(t,"resource-policy.json"),!!n),s=r?BVe(o(r),!0):void 0;return kXt({env:e,user:i,managed:s})}function wo(e){return new Date(e).toISOString()}function SXt(e){return{schemaVersion:1,revision:0,nextFencingToken:1,updatedAt:wo(e),permits:[],queue:[],attempts:[],usage:[],providerRates:[],effects:[]}}function CXt(e){let t=e,n=p=>!!(p&&typeof p=="object"&&!Array.isArray(p)),r=p=>typeof p=="string"&&p.length>0&&p.length<=512,o=p=>typeof p=="string"&&Number.isFinite(Date.parse(p)),i=p=>n(p)&&Number.isInteger(p.pid)&&Number(p.pid)>0&&r(p.hostname)&&o(p.processStartedAt),s=p=>n(p)&&r(p.permitId)&&r(p.requestId)&&r(p.operationId)&&r(p.runId)&&r(p.providerId)&&r(p.logicalChildId)&&r(p.attemptId)&&r(p.idempotencyKey)&&Number.isInteger(p.fencingToken)&&Number(p.fencingToken)>0&&i(p.owner)&&o(p.acquiredAt)&&o(p.heartbeatAt)&&o(p.expiresAt)&&Number.isFinite(p.reservedTokens)&&Number(p.reservedTokens)>=0&&Number.isFinite(p.reservedCostUsd)&&Number(p.reservedCostUsd)>=0&&(p.handoff===void 0||n(p.handoff)&&i(p.handoff.target)&&o(p.handoff.startedAt)&&o(p.handoff.deadlineAt))&&(p.claimedAt===void 0||o(p.claimedAt)),a=p=>n(p)&&r(p.requestId)&&r(p.operationId)&&r(p.runId)&&r(p.providerId)&&r(p.logicalChildId)&&r(p.attemptId)&&r(p.idempotencyKey)&&i(p.owner)&&o(p.enqueuedAt)&&o(p.updatedAt),c=p=>n(p)&&r(p.runId)&&r(p.logicalChildId)&&r(p.attemptId)&&r(p.idempotencyKey)&&r(p.state)&&o(p.startedAt),l=p=>n(p)&&r(p.runId)&&Number.isFinite(p.tokens)&&Number(p.tokens)>=0&&Number.isFinite(p.costUsd)&&Number(p.costUsd)>=0&&Number.isInteger(p.attempts)&&Number(p.attempts)>=0&&o(p.updatedAt),d=p=>n(p)&&r(p.providerId)&&o(p.timestamp)&&Number.isFinite(p.tokens)&&Number(p.tokens)>=0,u=p=>n(p)&&r(p.effectKey)&&r(p.idempotencyKey)&&r(p.permitId)&&Number.isInteger(p.fencingToken)&&Number(p.fencingToken)>0&&r(p.state)&&o(p.claimedAt);return!!(t&&t.schemaVersion===1&&Number.isInteger(t.revision)&&Number(t.revision)>=0&&Number.isInteger(t.nextFencingToken)&&Number(t.nextFencingToken)>0&&o(t.updatedAt)&&Array.isArray(t.permits)&&t.permits.every(s)&&Array.isArray(t.queue)&&t.queue.every(a)&&Array.isArray(t.attempts)&&t.attempts.every(c)&&Array.isArray(t.usage)&&t.usage.every(l)&&Array.isArray(t.providerRates)&&t.providerRates.every(d)&&Array.isArray(t.effects)&&t.effects.every(u))}function xXt(e,t){xde(jVe(e),{recursive:!0});let n=`${e}.${process.pid}.${LVe()}.tmp`,r=FVe(n,"wx",384);try{UVe(r,JSON.stringify(t,null,2)+`
2908
2908
  `,"utf8"),mXt(r)}finally{QVe(r)}gXt(n,e)}function RXt(e,t,n){let r=Date.parse(e.requestedAt??""),o=Number.isFinite(r)?r:t,i=Date.parse(e.queueDeadlineAt??"");return{requestedAt:wo(o),deadlineAt:wo(Number.isFinite(i)?Math.min(i,o+n):o+n)}}function qVe(e,t){return OB(e.providerDefault,e.providers[t])}function OVe(e,t,n){let r=Math.max(0,t-Date.parse(e.enqueuedAt));return vXt[e.priorityClass]+Math.floor(r/n.maxStarvationMs)*1001}function TXt(e,t,n){return[...e].sort((r,o)=>OVe(o,t,n)-OVe(r,t,n)||Date.parse(r.enqueuedAt)-Date.parse(o.enqueuedAt)||r.requestId.localeCompare(o.requestId))}function MVe(e,t){return e.pid===t.pid&&e.hostname===t.hostname&&e.processStartedAt===t.processStartedAt}function zC(e){return Number.isFinite(e)?Math.max(0,Number(e)):0}function NVe(e,t,n,r){let o=e.permits;if(o.length>=n.globalConcurrency)return{code:"WORKFLOW_CONCURRENCY_LIMIT",reason:"global_concurrency"};if(!(t.priorityClass==="control"||t.priorityClass==="foreground"||t.priorityClass==="reconciliation"||t.priorityClass==="terminal")&&o.length>=Math.max(0,n.globalConcurrency-n.reservedPrioritySlots))return{code:"WORKFLOW_CONCURRENCY_LIMIT",reason:"reserved_priority_capacity"};let s=Math.min(n.perRunConcurrency,MB(t.runConcurrencyLimit,n.perRunConcurrency,1,n.globalConcurrency));if(o.filter(b=>b.runId===t.runId).length>=s)return{code:"WORKFLOW_CONCURRENCY_LIMIT",reason:"run_concurrency"};if(t.parentId&&o.filter(b=>b.parentId===t.parentId).length>=n.perParentConcurrency)return{code:"WORKFLOW_CONCURRENCY_LIMIT",reason:"parent_concurrency"};let a=qVe(n,t.providerId);if(o.filter(b=>b.providerId===t.providerId).length>=a.maxConcurrency)return{code:"WORKFLOW_CONCURRENCY_LIMIT",reason:"provider_concurrency"};if(t.credentialFingerprint&&o.filter(b=>b.providerId===t.providerId&&b.credentialFingerprint===t.credentialFingerprint).length>=a.maxCredentialConcurrency)return{code:"WORKFLOW_CONCURRENCY_LIMIT",reason:"credential_concurrency"};if(o.some(b=>b.logicalChildId===t.logicalChildId))return{code:"WORKFLOW_CONCURRENCY_LIMIT",reason:"logical_child_active"};let c=new Set(e.attempts.filter(b=>b.logicalChildId===t.logicalChildId).map(b=>b.attemptId));if(!c.has(t.attemptId)&&c.size>=n.maxAttemptsPerLogicalChild)return{code:"WORKFLOW_ATTEMPT_LIMIT",reason:"logical_child_attempt_limit"};let l=new Set(e.attempts.filter(b=>b.runId===t.runId).map(b=>b.attemptId)),d=Math.min(n.maxAttemptsPerRun,MB(t.runAttemptLimit,n.maxAttemptsPerRun,1,n.maxAttemptsPerRun));if(!l.has(t.attemptId)&&l.size>=d)return{code:"WORKFLOW_ATTEMPT_LIMIT",reason:"run_attempt_limit"};let u=zC(t.reservedTokens);if(o.reduce((b,v)=>b+v.reservedTokens,0)+u>n.maxReservedTokens)return{code:"WORKFLOW_TOKEN_LIMIT",reason:"global_token_reservation"};let f=zC(t.reservedCostUsd);if(o.reduce((b,v)=>b+v.reservedCostUsd,0)+f>n.maxReservedCostUsd)return{code:"WORKFLOW_COST_LIMIT",reason:"global_cost_reservation"};let g=e.usage.find(b=>b.runId===t.runId),h=o.filter(b=>b.runId===t.runId).reduce((b,v)=>b+v.reservedTokens,0);if(t.runTokenLimit!==void 0&&(g?.tokens??0)+h+u>t.runTokenLimit)return{code:"WORKFLOW_TOKEN_LIMIT",reason:"run_token_limit"};let w=o.filter(b=>b.runId===t.runId).reduce((b,v)=>b+v.reservedCostUsd,0);if(t.runCostLimitUsd!==void 0&&(g?.costUsd??0)+w+f>t.runCostLimitUsd)return{code:"WORKFLOW_COST_LIMIT",reason:"run_cost_limit"};let A=r-a.windowMs,y=e.providerRates.filter(b=>b.providerId===t.providerId&&Date.parse(b.timestamp)>=A&&(!t.credentialFingerprint||b.credentialFingerprint===t.credentialFingerprint));return y.length>=a.maxRequestsPerWindow?{reason:"provider_request_rate"}:y.reduce((b,v)=>b+v.tokens,0)+u>a.maxTokensPerWindow?{reason:"provider_token_rate"}:{}}function PXt(e){for(let[t,n]of Object.entries({requestId:e.requestId,operationId:e.operationId,runId:e.runId,providerId:e.providerId,logicalChildId:e.logicalChildId,attemptId:e.attemptId,idempotencyKey:e.idempotencyKey}))if(typeof n!="string"||!n.trim()||n.length>512)throw new Gr("WORKFLOW_GOVERNOR_UNAVAILABLE",`Invalid resource request field: ${t}.`);if(e.credentialFingerprint&&!/^(?:cred_)?sha256_[a-f0-9]{32,64}$/i.test(e.credentialFingerprint))throw new Gr("WORKFLOW_GOVERNOR_UNAVAILABLE","credentialFingerprint must be a scoped SHA-256 fingerprint.")}function fA(e,t){let n=String(e??"default").trim().toLowerCase().split(/[/:]/,1)[0]||"default",r=t?.trim()?DVe("sha256").update(t.trim().toLowerCase()).digest("hex").slice(0,16):"default";return`${n}@${r}`}function Rde(e){let t=DVe("sha256");return t.update(e.salt),t.update("\0"),t.update(e.providerId),t.update("\0"),t.update(e.endpoint?.trim().toLowerCase()??""),t.update("\0"),t.update(e.credential),`cred_sha256_${t.digest("hex")}`}function Tde(e=KC(wn(),"governor")){let t=KC(e,"credential-salt.bin");if(xde(e,{recursive:!0}),Cde(t))return Sde(t);let n=pXt(32);try{return UVe(t,n,{flag:"wx",mode:384}),n}catch{return Sde(t)}}function YC(e,t=process.env,n){let r=e.split("@",1)[0]?.toLowerCase(),i=(r==="anthropic"||r==="claude"?["ANTHROPIC_API_KEY","XENO_API_KEY"]:r==="openai"||r==="gpt"?["OPENAI_API_KEY","XENO_API_KEY"]:r==="google"||r==="gemini"?["GOOGLE_API_KEY","GEMINI_API_KEY","XENO_API_KEY"]:["XENO_API_KEY","ANTHROPIC_API_KEY","OPENAI_API_KEY","GOOGLE_API_KEY","GEMINI_API_KEY"]).map(s=>t[s]?.trim()).find(Boolean);return i?Rde({providerId:e,endpoint:n,credential:i,salt:Tde()}):void 0}function $V(e){return{XENO_RESOURCE_PERMIT_ID:e.permitId,XENO_RESOURCE_FENCING_TOKEN:String(e.fencingToken),XENO_RESOURCE_OPERATION_ID:e.operationId,XENO_RESOURCE_IDEMPOTENCY_KEY:e.idempotencyKey}}function _V(e=process.env){let t=e.XENO_RESOURCE_PERMIT_ID?.trim(),n=Number.parseInt(e.XENO_RESOURCE_FENCING_TOKEN??"",10);return t&&Number.isInteger(n)&&n>0?{permitId:t,fencingToken:n}:null}function yh(e,t,n=process.env){if(n.XENO_RESOURCE_OPERATION_ID?.trim()!==e)return;let r=_V(n);if(!t||!r||t.permitId!==r.permitId||t.fencingToken!==r.fencingToken)throw new Gr("WORKER_LEASE_EXPIRED","Worker state write rejected because its fencing token is stale.");new Ao().assertFence(r.permitId,r.fencingToken)}var Ede,bXt,$Ve,_Ve,Gr,vXt,Ao,bh=ge(()=>{"use strict";Ko();PC();Yo();Sd();Ed();Ede=64,bXt=16,$Ve=16*1024*1024,_Ve=15*6e4,Gr=class extends Error{constructor(n,r,o){super(r,o);this.code=n;this.name="WorkflowResourceError"}code},vXt={control:1e3,foreground:900,reconciliation:850,terminal:800,"app-server":700,workflow:500,background:400,scheduled:300};Ao=class{policy;rootDir;ledgerPath;lockPath;now;owner;fault;constructor(t={}){this.rootDir=t.rootDir??KC(wn(),"governor"),this.ledgerPath=KC(this.rootDir,"resource-ledger.json"),this.lockPath=KC(this.rootDir,"resource-ledger.lock"),this.policy=t.policy??EXt(),this.now=t.now??Date.now,this.owner=t.owner??pA,this.fault=t.fault,xde(this.rootDir,{recursive:!0})}acquire(t){PXt(t);let n=0,r=this.withLedger((a,c)=>{this.cleanupExpired(a,c);let l=a.permits.find(v=>v.requestId===t.requestId||v.attemptId===t.attemptId);if(l)return n=a.permits.length,{value:{status:"active",permit:l,reason:"attempt_already_active"},changed:!0};let d=RXt(t,c,this.policy.maxQueueWaitMs);if(c>Date.parse(d.deadlineAt))return{value:{status:"rejected",code:"WORKFLOW_QUEUE_EXPIRED",reason:"Queued work exceeded its deadline."},changed:!1};let u=a.queue.find(v=>v.requestId===t.requestId);if(u&&c>Date.parse(u.queueDeadlineAt??d.deadlineAt))return a.queue=a.queue.filter(v=>v.requestId!==t.requestId),{value:{status:"rejected",code:"WORKFLOW_QUEUE_EXPIRED",reason:"Queued work exceeded its deadline."},changed:!0};if(!u&&a.queue.length>=this.policy.maxQueueLength)return{value:{status:"rejected",code:"WORKFLOW_QUEUE_FULL",reason:"The host workflow queue is full."},changed:!1};let p=t.owner??this.owner(),f=u?{...u,...t,owner:u.owner,updatedAt:wo(c)}:{...t,owner:p,requestedAt:d.requestedAt,queueDeadlineAt:d.deadlineAt,enqueuedAt:wo(c),updatedAt:wo(c)};u?a.queue=a.queue.map(v=>v.requestId===f.requestId?f:v):a.queue.push(f);let m=TXt(a.queue,c,this.policy),g,h={};for(let v of m){let I=NVe(a,v,this.policy,c);if(v.requestId===f.requestId&&(h=I),!I.reason){g=v;break}}if(h.code==="WORKFLOW_ATTEMPT_LIMIT"||h.code==="WORKFLOW_TOKEN_LIMIT"||h.code==="WORKFLOW_COST_LIMIT")return a.queue=a.queue.filter(v=>v.requestId!==f.requestId),{value:{status:"rejected",code:h.code,reason:h.reason??"resource_limit"},changed:!0};if(!g||g.requestId!==f.requestId){let v=a.permits.map(T=>Date.parse(T.expiresAt)).filter(Number.isFinite).sort((T,S)=>T-S)[0],I=qVe(this.policy,f.providerId),k=a.providerRates.filter(T=>T.providerId===f.providerId&&(!f.credentialFingerprint||T.credentialFingerprint===f.credentialFingerprint)).map(T=>Date.parse(T.timestamp)+I.windowMs).filter(T=>Number.isFinite(T)&&T>c).sort((T,S)=>T-S)[0],x=[v,k].filter(T=>typeof T=="number").sort((T,S)=>T-S)[0];return{value:{status:"queued",request:f,reason:h.reason??"waiting_for_fair_turn",...x?{estimatedEligibleAt:wo(x)}:{}},changed:!0}}let w=NVe(a,f,this.policy,c);if(w.reason)return w.code==="WORKFLOW_ATTEMPT_LIMIT"||w.code==="WORKFLOW_TOKEN_LIMIT"||w.code==="WORKFLOW_COST_LIMIT"?(a.queue=a.queue.filter(v=>v.requestId!==f.requestId),{value:{status:"rejected",code:w.code,reason:w.reason},changed:!0}):{value:{status:"queued",request:f,reason:w.reason},changed:!0};let A=wo(c),y={permitId:`permit_${LVe()}`,requestId:f.requestId,operationId:f.operationId,surface:f.surface,priorityClass:f.priorityClass,runId:f.runId,...f.parentId?{parentId:f.parentId}:{},providerId:f.providerId,...f.credentialFingerprint?{credentialFingerprint:f.credentialFingerprint}:{},logicalChildId:f.logicalChildId,attemptId:f.attemptId,idempotencyKey:f.idempotencyKey,fencingToken:a.nextFencingToken++,owner:f.owner,acquiredAt:A,heartbeatAt:A,expiresAt:wo(c+this.policy.leaseTtlMs),reservedTokens:zC(f.reservedTokens),reservedCostUsd:zC(f.reservedCostUsd),lastDurableSequence:0};a.queue=a.queue.filter(v=>v.requestId!==f.requestId),a.permits.push(y),n=a.permits.length;let b=a.attempts.find(v=>v.attemptId===f.attemptId);return b?Object.assign(b,{state:"active",permitId:y.permitId,operationId:f.operationId,endedAt:void 0,outcome:void 0,refusedClaim:void 0}):a.attempts.push({runId:f.runId,operationId:f.operationId,logicalChildId:f.logicalChildId,attemptId:f.attemptId,idempotencyKey:f.idempotencyKey,state:"active",permitId:y.permitId,startedAt:A}),a.providerRates.push({providerId:f.providerId,...f.credentialFingerprint?{credentialFingerprint:f.credentialFingerprint}:{},timestamp:A,tokens:y.reservedTokens}),this.fault?.("acquire.before_commit"),{value:{status:"acquired",permit:y},changed:!0,afterCommit:()=>this.fault?.("acquire.after_commit")}}),o=r.status==="rejected"?r.code:r.status==="acquired"?"admitted":r.reason;ro("xeno.workflow.admission_results",1,{component:"resource_governor",provider:t.providerId,state:r.status,reason:o,...r.status==="rejected"?{error_code:r.code}:{}}),(o==="provider_request_rate"||o==="provider_token_rate"||o==="provider_concurrency"||o==="credential_concurrency")&&ro("xeno.workflow.provider_throttles",1,{component:"resource_governor",provider:t.providerId,reason:o});let i=Date.parse((r.status==="queued"?r.request.requestedAt:t.requestedAt)??""),s=r.status==="acquired"||r.status==="active"?Date.parse(r.permit.acquiredAt):this.now();return Number.isFinite(i)&&Number.isFinite(s)&&Fs("xeno.workflow.queue_wait_ms",Math.max(0,s-i),{component:"resource_governor",provider:t.providerId,state:r.status}),n>0&&Fs("xeno.workflow.active_concurrency",n,{component:"resource_governor",provider:t.providerId}),r}heartbeat(t){return this.withLedger((n,r)=>{let o=this.currentPermit(n,t.permitId,t.fencingToken,r),i=t.owner??this.owner();if(!MVe(o.owner,i))throw new Gr("WORKER_IDENTITY_MISMATCH","Permit heartbeat came from a different worker identity.");return o.heartbeatAt=wo(r),o.expiresAt=wo(r+this.policy.leaseTtlMs),o.lastDurableSequence=Math.max(o.lastDurableSequence,Math.max(0,t.lastDurableSequence??0)),{value:{...o},changed:!0}})}assertFence(t,n){return this.withLedger((r,o)=>({value:{...this.currentPermit(r,t,n,o)},changed:!1}))}beginHandoff(t){return this.withLedger((n,r)=>{let o=this.currentPermit(n,t.permitId,t.fencingToken,r);if(o.claimedAt)return{value:{...o},changed:!1};let i=Math.max(Date.parse(o.expiresAt),r+this.policy.handoffTtlMs);return o.handoff={target:{...t.target},startedAt:wo(r),deadlineAt:wo(i)},o.owner={...t.target},o.expiresAt=wo(i),{value:{...o},changed:!0}})}transfer(t,n,r){let o=this.withLedger((i,s)=>{this.cleanupExpired(i,s);let a=l=>{let d=i.attempts.find(u=>u.permitId===t);return d?(d.refusedClaim={pid:r.pid,code:l.code,at:wo(s)},{value:{error:l},changed:!0}):{value:{error:l},changed:!1}},c=i.permits.find(l=>l.permitId===t);if(!c||c.fencingToken!==n){let l=i.attempts.find(d=>d.permitId===t);return a(l?.outcome==="WORKER_HANDOFF_EXPIRED"||l?.outcome==="WORKER_HANDOFF_ABANDONED"?new Gr("WORKER_HANDOFF_EXPIRED",`The worker hand-off window closed (${l.outcome} at ${l.endedAt??"unknown"}) before this worker claimed its permit.`):new Gr("WORKER_LEASE_EXPIRED","The worker lease is missing, expired, or fenced out."))}if(c.handoff){let l=c.handoff.target;if(l.pid!==r.pid||l.hostname!==r.hostname)return a(new Gr("WORKER_IDENTITY_MISMATCH","The permit hand-off is bound to a different worker process."))}else if(c.claimedAt&&!MVe(c.owner,r))return a(new Gr("WORKER_IDENTITY_MISMATCH","The permit is already claimed by another worker process."));return c.owner=r,delete c.handoff,c.claimedAt??=wo(s),c.heartbeatAt=wo(s),c.expiresAt=wo(s+this.policy.leaseTtlMs),{value:{permit:{...c}},changed:!0}});if("error"in o)throw o.error;return o.permit}settle(t){return this.withLedger((n,r)=>{let o=n.permits.find(c=>c.permitId===t.permitId);if(!o)return{value:!1,changed:!1};if(o.fencingToken!==t.fencingToken||Date.parse(o.expiresAt)<=r)throw new Gr("WORKER_LEASE_EXPIRED","The worker fencing token is stale.");n.permits=n.permits.filter(c=>c.permitId!==o.permitId);let i=n.attempts.find(c=>c.attemptId===o.attemptId);i&&Object.assign(i,{state:"settled",endedAt:wo(r),outcome:t.outcome});let s=n.usage.find(c=>c.runId===o.runId),a={runId:o.runId,tokens:(s?.tokens??0)+zC(t.actualTokens),costUsd:(s?.costUsd??0)+zC(t.actualCostUsd),attempts:(s?.attempts??0)+1,updatedAt:wo(r)};return n.usage=[...n.usage.filter(c=>c.runId!==o.runId),a],{value:!0,changed:!0}})}settleOperation(t,n,r=0,o=0){let i=this.snapshot().permits.find(s=>s.operationId===t);return i?this.settle({permitId:i.permitId,fencingToken:i.fencingToken,outcome:n,actualTokens:r,actualCostUsd:o}):!1}cancelQueued(t){return this.withLedger(n=>{let r=n.queue.some(o=>o.requestId===t);return n.queue=n.queue.filter(o=>o.requestId!==t),{value:r,changed:r}})}claimEffect(t){return this.withLedger((n,r)=>{let o=this.currentPermit(n,t.permitId,t.fencingToken,r),i=n.effects.find(s=>s.effectKey===t.effectKey||s.idempotencyKey===o.idempotencyKey);return i?{value:i.permitId===o.permitId&&i.fencingToken===o.fencingToken&&i.state==="claimed",changed:!1}:(n.effects.push({effectKey:t.effectKey,idempotencyKey:o.idempotencyKey,permitId:o.permitId,fencingToken:o.fencingToken,state:"claimed",claimedAt:wo(r)}),{value:!0,changed:!0})})}commitEffect(t){return this.withLedger((n,r)=>{this.currentPermit(n,t.permitId,t.fencingToken,r);let o=n.effects.find(i=>i.effectKey===t.effectKey);return!o||o.permitId!==t.permitId||o.fencingToken!==t.fencingToken?{value:!1,changed:!1}:o.state==="committed"?{value:!0,changed:!1}:(o.state="committed",o.committedAt=wo(r),{value:!0,changed:!0})})}reconcile(t){let n=this.withLedger((r,o)=>{let i=[...r.permits],s=[...r.queue],a=t??$B(i.map(A=>A.owner.pid)),c=new Set,l=new Set,d=new Set;for(let A of i){let y=Ja(A.owner,b=>a.get(b)??null);if(A.handoff){let b=y.status==="mismatch"&&y.observed&&Date.parse(y.observed.processStartedAt)>Date.parse(A.owner.processStartedAt);y.status==="dead"||b?d.add(A.permitId):y.status!=="live"&&l.add(A.permitId);continue}y.status==="mismatch"&&c.add(A.permitId),(y.status==="degraded"||y.status==="remote")&&l.add(A.permitId)}this.cleanupExpired(r,o,c,d);let u=new Set(r.permits.map(A=>A.permitId)),p=i.filter(A=>!u.has(A.permitId)&&!c.has(A.permitId)),f=i.filter(A=>c.has(A.permitId)),m=new Set(r.queue.map(A=>A.requestId)),g=s.filter(A=>!m.has(A.requestId)),h=new Map(r.effects.map(A=>[A.permitId,A.fencingToken]));for(let A of i)h.set(A.permitId,A.fencingToken);let w=new Map(r.attempts.filter(A=>A.state==="expired"&&A.permitId&&(A.outcome==="WORKER_HANDOFF_EXPIRED"||A.outcome==="WORKER_HANDOFF_ABANDONED")&&o-Date.parse(A.endedAt??"")<=_Ve).map(A=>[A.attemptId,{...A.operationId?{operationId:A.operationId}:{},permitId:A.permitId,fencingToken:h.get(A.permitId)??0,outcome:A.outcome,...A.endedAt?{endedAt:A.endedAt}:{},...A.refusedClaim?{refusedClaim:{...A.refusedClaim}}:{}}]));return{value:{expiredPermits:p,handoffFailures:w,identityMismatches:f,expiredQueue:g,livePermits:r.permits.length,degradedPermits:r.permits.filter(A=>l.has(A.permitId)).length},changed:p.length>0||f.length>0||g.length>0}});return Fs("xeno.worker.live_leases",n.livePermits,{component:"resource_governor",operation:"reconcile"}),Fs("xeno.worker.degraded_leases",n.degradedPermits,{component:"resource_governor",operation:"reconcile"}),n.expiredPermits.length>0&&ro("xeno.worker.lease_expirations",n.expiredPermits.length,{component:"resource_governor",operation:"reconcile"}),n.identityMismatches.length>0&&ro("xeno.worker.identity_mismatches",n.identityMismatches.length,{component:"resource_governor",operation:"reconcile"}),n}snapshot(){return this.withLedger(t=>({value:structuredClone(t),changed:!1}))}recentHandoffFailureOperations(){return this.withLedger((t,n)=>({value:[...new Set(t.attempts.filter(r=>r.operationId&&r.state==="expired"&&(r.outcome==="WORKER_HANDOFF_EXPIRED"||r.outcome==="WORKER_HANDOFF_ABANDONED")&&n-Date.parse(r.endedAt??"")<=_Ve).map(r=>r.operationId))],changed:!1}))}cleanupExpired(t,n,r=new Set,o=new Set){let i=new Map(t.permits.filter(a=>Date.parse(a.expiresAt)<=n||r.has(a.permitId)||o.has(a.permitId)).map(a=>[a.permitId,a]));if(i.size>0){t.permits=t.permits.filter(a=>!i.has(a.permitId));for(let a of t.attempts)a.permitId&&i.has(a.permitId)&&a.state==="active"&&(a.state="expired",a.endedAt=wo(n),a.outcome=r.has(a.permitId)?"WORKER_IDENTITY_MISMATCH":o.has(a.permitId)?"WORKER_HANDOFF_ABANDONED":i.get(a.permitId)?.handoff?"WORKER_HANDOFF_EXPIRED":"WORKER_LEASE_EXPIRED")}t.queue=t.queue.filter(a=>Date.parse(a.queueDeadlineAt??a.updatedAt)>n);let s=Math.max(this.policy.providerDefault.windowMs,...Object.values(this.policy.providers).map(a=>a.windowMs??0));if(t.providerRates=t.providerRates.filter(a=>Date.parse(a.timestamp)>n-s),t.attempts.length>2e4){let a=t.attempts.filter(l=>l.state==="active"),c=t.attempts.filter(l=>l.state!=="active").slice(-Math.max(0,2e4-a.length));t.attempts=[...c,...a]}t.effects.length>2e4&&(t.effects=t.effects.slice(-2e4)),t.usage.length>1e4&&(t.usage=t.usage.slice(-1e4))}currentPermit(t,n,r,o){let i=t.permits.find(s=>s.permitId===n);if(!i||Date.parse(i.expiresAt)<=o||i.fencingToken!==r)throw new Gr("WORKER_LEASE_EXPIRED","The worker lease is missing, expired, or fenced out.");return i}readLedger(t){if(!Cde(this.ledgerPath))return SXt(t);let n;try{n=FVe(this.ledgerPath,"r");let r=fXt(n).size;if(!Number.isSafeInteger(r)||r>$Ve)throw new Error(`ledger exceeds the ${$Ve} byte limit`);let o=Buffer.alloc(r),i=0;for(;i<r;){let c=hXt(n,o,i,r-i,i);if(c===0)throw new Error("Resource ledger changed during read");i+=c}let s=o.toString("utf8"),a=JSON.parse(s);if(!CXt(a))throw new Error("Unsupported resource ledger schema.");return a}catch(r){throw new Gr("WORKFLOW_GOVERNOR_UNAVAILABLE",`Resource ledger is unreadable and was not overwritten: ${r instanceof Error?r.message:String(r)}`)}finally{n!==void 0&&QVe(n)}}withLedger(t){let n=Date.now()+5e3,r=new Int32Array(new SharedArrayBuffer(4)),o,i;for(;!o&&Date.now()<=n;)try{o=Ai(this.lockPath,"workflow-resource-governor",Re)}catch(s){if(i=s,!(s instanceof Error)||!s.message.includes("is already locked"))break;Atomics.wait(r,0,0,10)}if(!o)throw new Gr("WORKFLOW_GOVERNOR_UNAVAILABLE",i instanceof Error?i.message:String(i??"Resource governor lock unavailable."),{cause:i});try{let s=this.now(),a=this.readLedger(s),c=t(a,s);return c.changed&&(a.revision+=1,a.updatedAt=wo(s),xXt(this.ledgerPath,a)),c.afterCommit?.(),c.value}finally{o.release()}}}});import{createHash as $Xt,randomUUID as _Xt}from"node:crypto";import{setTimeout as BXt}from"node:timers/promises";function OXt(){return`delegation-${Date.now().toString(36)}-${_Xt().slice(0,8)}`}function MXt(e,t){return async n=>{let r=e.createToolRegistry?void 0:fS(t,n.task.id);return xv((await ov({cwd:e.cwd,apiKey:e.apiKey,baseURL:e.baseURL,authorizeRequest:e.authorizeRequest,model:e.model,...e.fallbackModels?{fallbackModels:e.fallbackModels}:{},...e.effort?{effort:e.effort}:{},maxTokens:Kw(n.task.maxTokens,e.maxOutputTokens),turnTokenBudget:n.task.maxTokens,maxIterations:n.task.maxIterations,parentSystemPrompt:e.parentSystemPrompt,parentExecutionMode:e.parentExecutionMode,subagentRole:n.task.role,permissionEngine:e.permissionEngine,toolRegistry:e.createToolRegistry?.(),...r?{ownerSessionId:r}:{},...e.auditLogger?{session:{auditLogger:e.auditLogger}}:{},onIteration:n.onIteration,onToolStart:n.onToolStart,onToolWillExecute:n.onToolWillExecute,onToolEnd:n.onToolEnd})).agent,r)}}async function NXt(e){for(;;){if(e.signal?.aborted){e.governor.cancelQueued(e.request.requestId);let n=new Error("Delegated branch admission was cancelled.");throw n.name="AgentInterruptedError",n}let t=e.governor.acquire(e.request);if(t.status==="acquired")return t.permit;if(t.status==="active")throw new Gr("WORKFLOW_CONCURRENCY_LIMIT","Delegated branch attempt is already active.");if(t.status==="rejected")throw new Gr(t.code,t.reason);if(Date.now()>=e.deadline)throw e.governor.cancelQueued(e.request.requestId),new Gr("WORKFLOW_QUEUE_EXPIRED","Delegated branch exceeded its admission deadline.");await BXt(50,void 0,{signal:e.signal})}}function DXt(e,t,n){let r=e.run.bind(e),o=!1,i=a=>{o||(o=!0,t.settle({permitId:n.permitId,fencingToken:n.fencingToken,outcome:a,actualTokens:e.tokenUsage.total}))};e.run=async a=>{try{let c=await r(a);return i("completed"),c}catch(c){throw i(c instanceof Error&&c.name==="AgentInterruptedError"?"cancelled":"failed"),c}};let s=e;if(s.cancelCurrentTurn){let a=s.cancelCurrentTurn.bind(s);s.cancelCurrentTurn=()=>(i("cancelled"),a())}else if(s.cancel){let a=s.cancel.bind(s);s.cancel=()=>(i("cancelled"),a())}return e}async function NB(e){e=U_(e);let t=new Ao,n=e.rootTraceId??OXt(),r=fA(e.model,e.baseURL),o=e.apiKey?Rde({providerId:r,endpoint:e.baseURL,credential:e.apiKey,salt:Tde()}):YC(r,process.env,e.baseURL),i=e.createBranchAgent??MXt(e,n),s=Date.now()+e.timeoutMs,a=async c=>{let l=c.task,d=`${n}:${l.id}`,u=`${d}:attempt-1`,p=$Xt("sha256").update(`${n}\0${l.id}\0${l.prompt}`).digest("hex"),f=await NXt({governor:t,request:{requestId:`admit:${d}:attempt-1`,operationId:d,surface:"delegated-branch",priorityClass:"foreground",runId:n,parentId:n,providerId:r,...o?{credentialFingerprint:o}:{},logicalChildId:d,attemptId:u,idempotencyKey:p,reservedTokens:l.maxTokens,runConcurrencyLimit:e.branchPolicy?.maxConcurrentBranches,runAttemptLimit:e.branchPolicy?.roles?.length,runTokenLimit:e.maxTotalTokens,queueDeadlineAt:new Date(s).toISOString()},deadline:s,signal:l.signal??e.signal});if(!t.claimEffect({permitId:f.permitId,fencingToken:f.fencingToken,effectKey:`delegated:${f.operationId}`}))throw t.settle({permitId:f.permitId,fencingToken:f.fencingToken,outcome:"duplicate_branch_suppressed"}),new Gr("WORKFLOW_CONCURRENCY_LIMIT","Duplicate delegated branch execution was suppressed.");try{let m=await i(c);return t.commitEffect({permitId:f.permitId,fencingToken:f.fencingToken,effectKey:`delegated:${f.operationId}`}),DXt(m,t,f)}catch(m){throw t.settle({permitId:f.permitId,fencingToken:f.fencingToken,outcome:"branch_creation_failed"}),m}};if(e.hostDelegation){if(e.createBranchAgent)throw new Error("Host-routed delegation and a local createBranchAgent are mutually exclusive: the branch either executes on the Agent host or in this process. Pass one.");if(typeof e.onToolWillExecute=="function")throw new Error("Host-routed delegation cannot honour onToolWillExecute: it delays tool execution until it resolves, and a branch running on the Agent host does not wait for this process. A hook that cannot delay is not the hook you asked for, so it is refused rather than silently downgraded. Remove it to delegate on the host, or run without host delegation.");if(typeof e.onIteration=="function")throw new Error("Host-routed delegation cannot report onIteration: the host mints no iteration-bearing runtime event, so there is nothing to read \u2014 unlike onToolStart/onToolEnd, which now fire. Remove onIteration to delegate on the host, or run without host delegation.");return K5({...e,rootTraceId:n,createBranchAgent:iVe({...e.hostDelegation,rootTraceId:n,deadline:s,...e.signal===void 0?{}:{signal:e.signal}})})}return K5({...e,rootTraceId:n,createBranchAgent:a})}var HVe=ge(()=>{"use strict";et();sVe();xB();fh();bh();et()});import{renameSync as LXt}from"node:fs";function vh(e,t){for(let n=0;;n++)try{LXt(e,t);return}catch(r){if(n>=10||!["EPERM","EACCES","EBUSY"].includes(r.code??""))throw r;Atomics.wait(QXt,0,0,Math.min(25,(n+1)*5))}}var QXt,DB=ge(()=>{"use strict";QXt=new Int32Array(new SharedArrayBuffer(4))});import{closeSync as FXt,fstatSync as UXt,openSync as jXt,readSync as qXt}from"node:fs";function ZC(e){let t;try{t=jXt(e,"r")}catch(n){if(n.code==="ENOENT")return{text:"",startOffset:0,endOffset:0,totalBytes:0};throw n}try{let n=UXt(t);if(!n.isFile()||!Number.isSafeInteger(n.size))throw new Error("Output preview requires a regular file of supported size.");let r=n.size,o=Math.max(0,r-HXt),i=Buffer.allocUnsafe(r-o),s=0;for(;s<i.length;){let d=qXt(t,i,s,i.length-s,o+s);if(d===0)throw new Error("Output changed during preview; retry.");s+=d}let a=0;if(o>0)for(;a<Math.min(3,i.length)&&(i[a]&192)===128;)a++;let c=o+a,l;try{l=new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0}).decode(i.subarray(a),{stream:!0})}catch{throw new Error("Output preview contains invalid UTF-8; inspect the persisted output as bytes.")}return{text:l,startOffset:c,endOffset:c+Buffer.byteLength(l,"utf8"),totalBytes:r}}finally{FXt(t)}}var HXt,BV=ge(()=>{"use strict";HXt=64*1024});import{randomUUID as WVe}from"node:crypto";import{closeSync as WXt,fstatSync as VVe,linkSync as VXt,openSync as GXt,readSync as XXt,unlinkSync as JXt,writeFileSync as zXt}from"node:fs";import{basename as KXt,join as GVe}from"node:path";function Ih(e,t){let n=e.requestCancellation(t);if(!n)return{accepted:!1,cancelled:!1,pending:!1,operationId:null,run:null};let r=null,o;try{e.cancel(t),r=e.getRun(t),(!r||r.cancellation?.operationId!==n.operationId)&&(o="Cancellation was accepted but current state could not be confirmed. Inspect this operation; do not submit new work.")}catch{o="Cancellation was accepted but processing or readback is unconfirmed. Inspect this operation; do not submit new work."}let i=!o&&r?.status==="cancelled"&&r.cancellation?.pendingChildCount===0&&!!r.cancellation.completedAt;return{accepted:!0,cancelled:i,pending:!i,operationId:n.operationId,run:r,...o?{warning:o}:{}}}function XVe(e,t){if(!e||KXt(e)!==e)throw new Error("Invalid workflow cancellation target");return GVe(t,e,"cancellation-request.json")}function mA(e,t=GVe(wn(),"workflows","runs")){let n;try{n=GXt(XVe(e,t),"r")}catch(i){if(i.code==="ENOENT")return null;throw i}let r;try{let i=VVe(n).size;if(i>8192)throw new Error("Workflow cancellation state exceeds its 8 KiB bound; it was preserved and execution is held.");let s=Buffer.alloc(i),a=0;for(;a<i;){let c=XXt(n,s,a,i-a,a);if(!c)throw new Error("Workflow cancellation state changed during read; execution is held.");a+=c}if(VVe(n).size!==i)throw new Error("Workflow cancellation state changed during read; execution is held.");r=s.toString("utf8")}finally{WXt(n)}let o=Ga(r,null);if(o?.schemaVersion!==1||o.workflowRunId!==e||typeof o.operationId!="string"||!/^[a-f0-9-]{36}$/.test(o.operationId)||typeof o.requestedAt!="string"||!Number.isFinite(Date.parse(o.requestedAt)))throw new Error("Workflow cancellation state is invalid; it was preserved and execution is held.");return o}function JVe(e,t){let n=mA(e,t);if(n)return n;let r=XVe(e,t),o={schemaVersion:1,operationId:WVe(),workflowRunId:e,requestedAt:new Date().toISOString()},i=`${r}.${process.pid}.${WVe()}.tmp`;zXt(i,JSON.stringify(o)+`
@@ -4393,7 +4393,7 @@ ${r}`}}import{execFileSync as QKe}from"node:child_process";function Din(){let e=
4393
4393
  `),o.model||o.baseURL||o.apiKey||o.maxTokens||o.permissionMode||o.plugins&&o.plugins.length>0||o.mcpServers&&o.mcpServers.length>0||n.onOutput(` (no settings configured)
4394
4394
  `),n.onOutput(`
4395
4395
  `),{handled:!0}}function VA(e){let t=Math.max(0,Math.floor(e)),n=Math.floor(t/1e3),r=Math.floor(n/3600),o=Math.floor(n%3600/60),i=n%60;return r>0?`${r}h ${o}m ${i}s`:o>0?`${o}m ${i}s`:`${i}s`}function zKe(e){let t=["Last Session Summary",`- model: ${e.model}`,`- mode: ${e.mode??"unknown"}`,`- status: ${e.status??"unknown"}`,`- started: ${e.startedAt}`,`- ended: ${e.endedAt}`,`- duration: ${VA(e.durationMs)}`,`- tokens: ${e.tokenUsage.input.toLocaleString()} in / ${e.tokenUsage.output.toLocaleString()} out / ${e.tokenUsage.total.toLocaleString()} total`,`- estimated cost: ${mv(e.estimatedCostUsd)}`];return e.sessionId&&t.splice(1,0,`- session: ${e.sessionId}`),e.role&&t.splice(e.sessionId?2:1,0,`- role: ${e.role}`),e.messageCount!==void 0&&t.push(`- messages: ${e.messageCount}`),t.join(`
4396
- `)}function msn(e){let t=e.replace(/\s+/g," ").trim();return t.length>72?`${t.slice(0,69)}...`:t}async function KX(e){if(!e.checkpointManager||e.messages.length===0)return null;let t=`Branch before rewind to "${msn(e.targetPrompt)}"`,n=await e.checkpointManager.create({trigger:"manual",messages:e.messages,description:t});if(e.sessionManager){let r=[n.id,...e.sessionManager.meta.checkpoints.filter(o=>o!==n.id)];await e.sessionManager.updateMeta({checkpoints:r}),await e.sessionManager.transcript.append({type:"checkpoint",data:{id:n.id,action:"create",name:t,trigger:"manual",messageCount:e.messages.length}})}return n.id}Vr();Ko();var hsn={"0.5.107":["`/as` in chat: act as one of your XENO agents in the same conversation. `/as` lists them, `/as <name>` switches, `/as me` returns to you. Each switch revokes the previous agent credential, and leaving the chat revokes the last one.","`xeno run --resume` acts as the agent the session acted as before, with a fresh credential. Only the agent id is stored; `--as me` clears it.","Lines piped into `xeno chat` now run in order. Before, a slash command could end the session while later lines were still waiting.","Uses SDK 0.10.59."],"0.5.106":["`xeno run` takes its prompt from standard input (`xeno run -`, or piped with no prompt) or from `--prompt-file <path>`, so a prompt longer than a command line allows reaches the model as the message itself, up to 8 MB.","`xeno run --as <agent>` acts as one of your XENO agents: its instructions, model, effort and tool policy, with the XENO Tasks tools ready. Its credential stays in memory and is revoked when the run ends, however it ends. `--json` reports `acting_as`.","`xeno spawn <args>` hands the rest of the command to XENO Spawn.","Uses SDK 0.10.58."],"0.5.105":["`xeno run` saves every run as a session and prints its `session_id` in `--json` output. `--resume <id>` continues that conversation with a new prompt, and `--continue` picks up this folder's most recent session. Both work for local runs, not with --delegate, --remote or --bg."],"0.5.104":["`xeno run --output-schema <file>`: the final answer must be JSON that matches the given JSON Schema. An answer that does not match is sent back with the errors to fix, and the valid result is returned as `structured_output` in the JSON output. If no valid answer arrives, the run ends incomplete (exit 1).","Uses SDK 0.10.55."],"0.5.103":["A run that produced every output named in XENO_REQUIRED_OUTPUT_PATHS_JSON now reports ok (exit 0) even if one of its tool calls was denied along the way. The denial is still listed in tool_summary and the audit. Without declared outputs, a denial is still the outcome.","`xeno run --allowed-tools` and `--disallowed-tools` (comma-separated) control which tools the agent is offered. The limit also applies to helpers it starts."],"0.5.102":["A research run whose answer is a written document that cites its sources is no longer held open asking for the sources again in chat.","Uses SDK 0.10.54."],"0.5.101":["Skills found by default are named project:<name> or user:<name>, so the Skill tool resolves the name it was given, and the same name in project and user folders is two skills.","Child agents and background workers inherit their parent's skills again; the interactive-child inheritance tests pass.","Uses SDK 0.10.53."],"0.5.100":["You can set how much web research one turn may do. `xeno run` and chat accept --max-web-searches (1 to 200), --max-web-fetches (1 to 500) and --max-web-calls, or the environment variables XENO_MAX_WEB_SEARCHES, XENO_MAX_WEB_FETCHES and XENO_MAX_WEB_CALLS. Without them the limits are unchanged: 5 searches and 12 fetches for a research request, 3 and 4 for a quick question. A value that is not a whole number in range stops the command with a message. Each search can cost provider money, up to the per-request cap.","Uses SDK 0.10.42."],"0.5.99":["Web search uses your account's configured provider allowance when you have not set a limit. Explicit limits still narrow it, including zero: XENO_WEB_CONTEXT_MAX_PROVIDER_COST_USD and --provider-cost-budget-usd never silently authorize additional spending.","WebFetch reports the recorded reason when a page cannot be retrieved, such as site refusal, a missing page, rate limiting or a network error, instead of only saying the scrape failed. Conversational tools preserve the specific error code for the agent. Explicit site refusals are not bypassed.","Uses SDK 0.10.41 and Web Context client 0.1.5. The HTML transcript redesign and /provider picker remain outside this release."],"0.5.98":["Chat draws its composer before loading session state or building the agent. You can type immediately; early submissions wait until restoration, permission state and execution ownership are ready. In five real-terminal runs on our large workspace, the usable frame appeared in 579 ms median. Line-input chat also preserves input received before readiness, including piped input ending at EOF.","Terminal updates repaint only changed lines; typing and in-place tool updates no longer redraw the whole screen. The status command refreshes on changes with a bounded cadence. --version runs from a tiny entry without loading the agent runtime.","Background dispatch helpers report their results back when they settle. The footer separates the agent list from status by one blank row, keeps main and helpers adjacent, shows state on the left and aligns elapsed time and tokens on the right.","Web Context uses your signed-in XENO account by default, with a fresh DPoP proof for each request. XENO_API_KEY also works; explicit Web Context endpoint/token settings still take precedence. Gateway-prefixed search, fetch and artifact reads use Web Context client 0.1.3.","Uses SDK 0.10.40, including faster startup, background reports and the compatible Web Context client peer. The new transcript design and /provider picker are not part of this release."],"0.5.97":["Long sessions stay fast. Adding a line to the conversation no longer redraws the whole history: with 2,000 rows on screen, a new tool row went from about 8.5 seconds to about 5 milliseconds.","Each screen update is sent to the terminal in one piece, wrapped so terminals that support it paint it all at once, which removes flicker and half-drawn frames.","Typing @ to pick a file no longer reads the folder on every key; the listing is reused for two seconds. Set XENO_RENDER_STATS=1 to log frame times and key-to-screen latency to ~/.xeno/render-stats.jsonl."],"0.5.96":['The /model list is the full list the XENO API serves, read live. It shows "Loading models..." while it loads, says so plainly if the list cannot be loaded instead of offering a short built-in list, and keeps models that are temporarily unavailable at the bottom with the reason; picking one is refused with that reason.',"Switching to a model from the live list no longer makes a second network check, so the switch is immediate. Uses @xenosystem/agent-sdk 0.10.38."],"0.5.95":['Messages between sessions are now one line each. A sent message reads "sent to SESSION2: ... \xB7 queued" and its state (queued, held, delivered, running, reported, failed) updates in place; a received one reads "from SESSION1: ...". The full text and message id are behind ctrl+o, and the Send tool no longer prints its own call and JSON result.',"Tool rows no longer wait. A finished tool row settles at once instead of staying for at least 0.7 seconds, and the end of a turn no longer waits for it. Tool results open collapsed (ctrl+o to expand) instead of opening expanded and collapsing 2.2 seconds later."],"0.5.94":["You can save a model API key once with `xeno auth login --api-key`. It is read from a hidden prompt or from standard input, never from the command line, and it is checked with XENO before it is saved. XENO_API_KEY still takes precedence when it is set.","Where the key is kept: on Windows it is protected by Windows DPAPI for your Windows user account, using the native system call, and nothing is saved if that protection is unavailable. On Linux it goes into the desktop keyring (Secret Service, via secret-tool) when one is available, and otherwise into a file only you can read. On macOS it is a file only you can read.","If you used an earlier version, your saved API key moves to the new protected store the first time you start this version, and the old plaintext file loses only that key. Your previous sign-in cannot be carried over: run `xeno login` once to sign in again.","`xeno auth status` shows where the model credential is stored without printing any part of a key. On a machine that has never signed in it says 'not signed in' and how to sign in, rather than reporting a fault. `xeno logout` and `xeno auth logout` remove a saved key.","Account sign-in is available on Windows only for now. On macOS and Linux, `xeno login` says so and points to `xeno auth login --api-key` or XENO_API_KEY. Account sign-in is also bundled inside the CLI, so installing from npm needs nothing from a private registry.","Plan mode now works through the model's own tools: it starts planning by itself when the work calls for it and hands you the plan to approve. You can approve, approve with edits typed in your editor or the input box (your version is what gets carried out), or send it back with feedback. Tools from connected servers that only read keep working while planning. From @xenosystem/agent-sdk 0.10.35.","Stopping a helper at the exact moment it starts a tool no longer crashes the app.","Notification history and dismissal stay within the selected workspace, including isolated helper worktrees and deleted-parent recovery. Control Room actions accept the exact displayed snapshot for 60 seconds and refuse changed state.","MCP authentication failures identify the exact server and its dedicated login command. Repeated failures do not produce duplicate notices, and line-input chat shows the same recovery guidance as fullscreen chat.","Web fetch requests one page instead of exceeding the connected account's page quota. Map and crawl respect the account's page limit. Paid web search supports an explicit per-request USD budget and still defaults to no spending.","A prepared session handoff can now be cancelled from the original fullscreen or line-input chat. The exact offer is withdrawn before the conversation writer resumes; other detached execution stays refused."],"0.5.93":["Plan mode is here. Start with --permission-mode plan, type /plan, or press Shift+Tab: the agent can read and investigate but every change is refused until you approve its plan, including changes a helper agent would make. Plan mode survives a crash and resume, and xeno run returns the plan instead of waiting for an approval.","A session can now move to another enrolled computer with its conversation: the receiving computer downloads it from the execution authority and checks it is exactly the same before taking over. A computer that loses ownership now also stops the background tasks, helper sessions and workflow runs that session started.","Helper agents can be stopped one at a time from the agent list, cancelling a turn stops its helpers, and a helper that ran out of budget is shown as unfinished instead of done.","Every command that takes a prompt now refuses a /command it cannot run instead of sending it to the model, pause and resume on Windows really suspend the work, and slow Windows process queries no longer make commands time out. /goal clear, /goal pause and /loop stop now always win against a running goal loop, and a !command typed during a turn runs as a shell command."],"0.5.92":["A /command the chat does not know is no longer sent to the model as a prompt. Typos like /revew, commands this mode does not support, and commands from another lane now stop with a message naming the command and why, and nothing is sent. This covers the chat, xeno run, background runs and the app server.","Moving a session between computers through an execution authority now recovers safely: a computer that loses contact stops working on the session before another can take it, a failed or abandoned move hands the session back to the computer that offered it, and /handoff cancel withdraws an offer. The receiving computer checks it has exactly the same conversation before taking over.","Helper agents now keep their background tasks private: a helper can no longer read or stop its parent's or another helper's tasks, and the reverse."],"0.5.91":["You can now stop two computers from working on the same session at once. Run xeno app-server --http --execution-authority on one machine, enrol each computer with xeno executors add, and start chats with --execution-authority. While one computer has a session, another is refused until the first lets go or stops responding. Before, each computer only checked its own records, so two could both think they had the session."],"0.5.90":["Forking a conversation now makes you choose, instead of deciding silently: the whole conversation or only up to a checkpoint, and whether the fork shares this folder or gets its own git worktree. Use /fork in the chat, or xeno sessions fork with --history and --working-tree. An isolated fork says how many uncommitted changes it does not carry over. Before, every fork quietly shared the same folder, so both conversations changed the same files."],"0.5.89":["A helper started with dispatch_agent now shows in the agent list below the input while it works. Press Enter on it to open its conversation; what you type there reaches it at its next step, and once it finishes the conversation stays open to read. Before, it was one line in the transcript and its conversation could not be seen.","/agents now lists the agents started from this chat, numbered, so /attach 2 opens the one shown as 2."],"0.5.88":["With helper agents working, pressing Enter on a helper now opens its conversation in the chat, as it happens. While it is still working, what you type there reaches it at its next step. Once it has finished, the conversation stays open to read. Before, Enter showed only a status panel.","A large delegation budget no longer breaks the helpers. Given 200,000 tokens or more, a helper stopped before sending anything, because its whole budget was being reserved as room for one reply. From @xenosystem/agent-sdk 0.10.29."],"0.5.87":["Open a background agent's conversation right in the chat with /attach, by its name, its number in the agent list, or its id. Inside it, /attach opens an agent it started. Esc or /back goes back one level, and /main returns to your own chat. Before, opening an agent's agent lost the way back to the one you came from.","With helper agents working, the Down key now reaches the background agents below them too. Before, it stopped at the helpers."],"0.5.86":["An agent file's max-tokens and deadline now also apply when the agent is called as a helper in the middle of a chat, not only when it runs in the background."],"0.5.85":["xeno agents new now takes --max-tokens and --deadline (for example 30m), so a background run can have its own budget and time limit. They are kept with the run, so relaunching it does not reset them, and a reply in progress is stopped when the time limit passes.","An agent file can set a default budget with max-tokens and deadline at the top. It applies to background work started as that agent, unless you give a budget yourself. From @xenosystem/agent-sdk 0.10.28."],"0.5.84":["A background agent can now be given its own token budget and time limit when it is started. It stops once it has spent the budget, and when the time limit passes it stops, even in the middle of a reply. Both are kept with the session, so restarting the worker does not reset them. Before, a background agent had no limit of its own unless its parent goal had one."],"0.5.83":["With delegation on, each helper agent now stays inside its share of the delegation token budget. Before, the budget only limited each single reply, so a helper given 1,200 tokens could keep calling tools and spend several times that. It now stops once its share is spent and says how much it used. From @xenosystem/agent-sdk 0.10.26."],"0.5.82":["If the CLI closes while the agent is waiting for your answer, the question comes back when you resume the session, with the same choices. Before, the question was lost: the agent was told it had been interrupted and not to repeat it, so it never asked again. Press Esc to skip it and answer in your own words instead."],"0.5.81":["Tools from MCP servers now work with every model. Their names contain dots, and several models refused any request that included one: Claude and DeepSeek failed the whole turn, and gpt-6 answered with nothing. The tool still shows its real name in the terminal and in permission prompts. From @xenosystem/agent-sdk 0.10.23."],"0.5.80":["A tool server that sends a huge reply no longer ties up the agent. A reply over 16 MB is refused as it arrives, and the request fails right away with a clear error. Before, a 200 MB reply was read in full, which took about 48 seconds, and then almost all of it was thrown away. From @xenosystem/agent-sdk 0.10.22."],"0.5.79":["Long sessions stay fast to scroll. In a session of 10,000 messages, one scroll step took about 430 ms and now takes about 24 ms, and a keypress went from about 27 ms to about 4 ms. Resizing and entering scroll mode got faster too.","Images from tools now reach models that accept images even when the name is new, such as gpt-6, because the model list says which models take images. From @xenosystem/agent-sdk 0.10.21.","A reply that ends without the model sending anything now shows as an error instead of an empty, finished turn. From @xenosystem/agent-sdk 0.10.21."],"0.5.78":["When a tool's output is too long and gets shortened, the agent can now read the part that was left out. The full output is kept, and the new ToolOutput tool reads it back. Before, a long shell command lost its middle for good. From @xenosystem/agent-sdk 0.10.19.","ToolOutput reads appear in the compact tool-activity row with the other reads, and the tool line shows which stored output and offset it read."],"0.5.77":["Long sessions no longer slow down as they grow. Adding output used to re-draw the whole conversation every time, so each new line took longer the more was already on screen. Now 10,000 blocks of output take under a second instead of minutes, and memory stays flat.","The spinner on a running tool stays in the right place as output scrolls, including after it scrolls off screen and back."],"0.5.76":["Model endpoints behind a proxy that ignores streaming now work. Their reply is read as one complete answer instead of failing as a broken stream. From @xenosystem/agent-sdk 0.10.18."],"0.5.75":["A model reply cut off in the middle of a tool call no longer runs that tool with empty input. The agent is told the call was not run and nothing was changed.","If you stop the agent after it has sent a change, it is told the change may have happened, and to check before trying again, instead of being told it was cancelled. The same applies to a change that timed out.","The request time limit now covers the whole reply, not just the moment the reply starts. A reply that stalls part-way now ends at the limit instead of hanging. A timed-out request is not repeated automatically, because it may still be running.","`xeno harbor` analysis recognises the new timeout and dropped-stream messages as transport failures, as it did the old wording.","Uses @xenosystem/agent-sdk 0.10.17."],"0.5.74":["New Patch tool: the agent can change several files in one all-or-nothing edit, including adding, moving and deleting files. Nothing is written unless every change matches the files as they are. In accept-edits mode it is approved automatically, like Edit. From @xenosystem/agent-sdk 0.10.16.","Patch is treated as a file write everywhere a write is: it is denied in hosted runs that allow no edits, shown with the files it touches in the tool line and background session details, and counted by the completion checks that look at which files a run wrote."],"0.5.73":["Background and workflow workers that start slowly, for example on a busy machine, now claim their slot reliably. Before, a worker that took more than about 4 seconds to start could lose its slot and exit without a trace, leaving its run stuck as running. A worker that misses the longer start-up window is now refused with a recorded reason.","Stopping all of an agent's background processes now always finishes (from @xenosystem/agent-sdk 0.10.14)."],"0.5.72":['When no approval screen is available and the agent asks for permission in a plain terminal, typing "y" now approves. Before, every answer was recorded as a denial. For a command asking for extra access, the question now lists exactly what it wants and why. Uses @xenosystem/agent-sdk 0.10.13.'],"0.5.71":["Approving or rejecting an agent session's permission request in the Control Room now takes effect. Before, the session ignored the answer and kept waiting until it was stopped.","Control Room approvals and the SDK's built-in approval screens show a command's exact extra access and its reason, the same as the terminal prompt. Uses @xenosystem/agent-sdk 0.10.12."],"0.5.70":['When a command asks for access beyond its sandbox (network or extra folders), the approval prompt lists exactly what it wants and the reason it gave. It offers "Yes, for this call only" instead of "always", because an elevated command needs your approval every time. Uses @xenosystem/agent-sdk 0.10.11.'],"0.5.69":[`The agent can run a command in a specific directory, or through a specific shell (bash, sh, powershell, pwsh or cmd), for that one call, without moving the session's directory. The tool call line shows both, e.g. "npm test (in packages/app, via pwsh)".`,'Approving a command "always" covers only the directory and shell it was approved in, and the approval prompt names both.',"Requires @xenosystem/agent-sdk 0.10.10."],"0.5.68":["New: `xeno ctx-viz --audit` reports tools that are defined but registered by no lane, defined twice, or pointed at by an alias that goes nowhere. Run it from a CLI checkout; it exits 1 when it finds anything.",'Saving artifacts and other local records no longer fails intermittently on Windows with "EPERM: operation not permitted, rename" when another program briefly holds the file.',"Requires @xenosystem/agent-sdk 0.10.9."],"0.5.67":["Auto permission mode no longer asks before ElfAnalyze or ToolSearch, which default mode allows without asking.","The permission audit log labels every tool with the same risk level shown everywhere else.","New generated references: docs/TOOL_CATALOGUE.md (every tool per chat/run/ACP lane) and docs/TOOL_MAPPING.md (the permission decision per mode, how the terminal shows it, and its tests).","Requires @xenosystem/agent-sdk 0.10.8."],"0.5.66":["When a goal token budget runs out, the message now says how many tokens are left and how many the next request needs.",'A goal run no longer fails with "Ownership lease expired" when the process briefly stalls; the session keeps its lease as long as nobody else took it.',"Requires @xenosystem/agent-sdk 0.10.7."],"0.5.65":["Goal token limits now work on the XENO cloud route as a SOFT budget: each request's output is capped to what is left, measured usage is charged, and the goal stops once the limit is spent. One request may overshoot slightly, and the overshoot is recorded.","Local xeno-rt keeps its exact, hard limit. /goal status, xeno run and the chat notice say which kind of limit applies.","Requires @xenosystem/agent-sdk 0.10.5."],"0.5.64":["Removed the direct OpenAI Responses lane for bounded goals that 0.5.63 added. Token-limited goals run on local xeno-rt; other lanes refuse bounded work before inference, as in 0.5.62.","Background runs still refuse inline --api-key arguments, so a credential never reaches a worker's process arguments."],"0.5.63":["Bounded CLI goals can now use the official OpenAI Responses endpoint through an explicit OpenAI base URL and API key. Exact input counting, capped output and durable settlement share the same goal allowance as local xeno-rt.","The Responses lane refuses mutable remote image URLs, invalid counts and unsupported hosts before inference. It is fixture-qualified; live OpenAI and hosted/ACP quota qualification remain open.","Background runs refuse inline API keys before daemon handoff or worker spawn; use an environment or saved credential. Headless quota admission and execution now resolve the same provider endpoint."],"0.5.62":["Goals can use a durable total token limit in the local xeno-rt lane. The allowance survives restarts and is shared with local child agents; unsupported provider lanes refuse bounded work before inference.","TUI commands now execute in order, so renaming a session and immediately preparing a handoff cannot race their transcript and ownership changes.","Automatic goal continuation no longer inserts text into the command you are typing."],"0.5.61":["Goals can now carry an explicit total token limit with /goal set --max-tokens or xeno run --goal-max-tokens. The allowance survives restarts and is shared with local child agents.","Token-limited goals require a local xeno-rt runtime that advertises exact prompt counting and an enforced token ceiling. Other execution lanes report that requirement before starting work.","Automatic goal continuation no longer inserts text into a command you are typing. Human input received during a turn is queued for the next turn."],"0.5.60":[`The four canonical tools \u2014 Send, Receive, ListAgents, ListSessions \u2014 are now the CLI's own, bound to this session's peer runtime. 0.5.58 announced them and shipped the SDK's stock versions, which have no host: they recorded every message as coming from "unknown", so a delegated task's report had no sender to return to, and they forced every message to kind "task", so a note or a question ran a whole turn in the receiving session instead of being injected or asked. Both were silent. The name the release notes told the model to prefer was the one that got this wrong, while the legacy CoordinationSend it replaced got it right.`,"CoordinationSend and CoordinationQuery keep working, and are hidden again. They had been promoted back into the model's tool list beside their own canonical names, so one capability was offered twice.","ListAgents and ListSessions exist for the first time. They answer different questions on purpose \u2014 who you can send to, versus what is running where.","Sending now writes a Sent to row whoever sends. It was rendered only by the /peers command, so a human saw it and the model did not \u2014 the same asymmetry 0.5.59 fixed for arriving messages, in the other direction."],"0.5.59":["Inbound messages from other sessions now land as durable transcript rows on the live path: Received from, including a task waiting until idle and a held message with /peers accept, not a notice that scrolls away."],"0.5.58":["Unified agent architecture: sub-agents are full sessions, docked under the main-agent in the panel beneath the input box or detached as their own window \u2014 one engine, two presentations.","Messages between sessions are now first-class transcript rows in both directions: Sent to / Received from with the message visible, not a transient notice that scrolled away.","Wire vocabulary: the model gets four canonical tools \u2014 Send, Receive, ListAgents, ListSessions. CoordinationSend/CoordinationQuery keep working as hidden aliases.","Picks up SDK 0.10.0, which ships the canonical wire vocabulary and the alias layer."],"0.5.57":["Reliability pass from the goal-reconciliation: one shared projection now turns runtime events into assistant text (run turns and host-delegated branches used to keep separate copies, the class of bug where a tool payload renders as chat text).","Provider cockpit hardening: the host's durable conversation binding is validated before any mode or scope change, a mismatched host can no longer receive your project as a side effect, and the active provider lane is re-read every turn so a selection changed in another window takes effect immediately.","Tool start/end events are now driven by the interface contract's own vocabulary (phase, call id, success) instead of re-parsing raw type strings.","Release plumbing: the packed CLI manifest now records the publishable SDK version rather than the local build reference, and the security-boundary audit resolves file: SDK links through the installed package."],"0.5.56":["Independent sessions can now delegate to each other, the way Claude Code's SendMessage works: /rename names this session (shown on the input border), /peers lists every XENO Agent session on this machine, and /message <session> <task> hands it work that runs INSIDE that session with its own workspace and permissions; the result comes back here automatically.","The model has the same two primitives as the Interface - CoordinationQuery and CoordinationSend - so 'ask my DB - PLUGIN session to audit the auth flow' works in plain language. Delivery and completion are separate states; a task left running by a crashed session is marked recovery-required and never re-run.","Picks up SDK 0.9.39: the durable peer store behind this, a strict /rename commit (a failed disk write is a failed rename), and permission classification of the two coordination tools.","Typing a slash command that takes an argument ghosts its placeholder after the cursor, e.g. /rename [name].","Rendered artifacts, the way Claude Code's Artifact tool works: the model writes an HTML page and publishes it with the Artifact tool; the page appears as a link tray under the status bar (ctrl+] opens it) and is served from a private loopback viewer under a sandboxing CSP. Comments left on the page come back into the conversation as turns, and republishing the same artifact_id keeps the link.","Two homes, your choice: local is private to this machine and needs no account; home cloud (or /artifacts promote <id>) hosts the same revision on your XENO account at xenostudio.ai/a/<id>, private until /artifacts share <id> turns link sharing on. Hosted comments reach the session the same way local ones do."],"0.5.55":["Updated to SDK 0.9.38: app-server retries and permission responses enforce current tenant, workspace, and connection authority.","Fixed standalone startup by bundling the web-context client with the CLI.","Qualified context recovery, schemas, scheduling, subagents, skills, and app-server regression checks on Windows and Linux."],"0.5.54":["Picks up SDK 0.9.37, which corrects the root cause published in 0.9.36: the Linux install failure came from lockfile metadata, not from the dependency itself.","The 0.9.36 fix was correct and is retained; only its explanation was wrong, and a wrong cause is worse than none because the next person reasons from it.","Fixes a crash where a second CLI session in the same workspace killed the first one: listing schedules took a cross-process mutation lock, and the resulting error came from a background timer with no catch, which terminates the process."],"0.5.53":["Picks up SDK 0.9.36: a Windows-only native addon was a hard dependency, so `npm ci` failed outright on Linux - the SDK could not be installed there at all.","The addon is now optional and loaded lazily, which is what its call sites already assumed. Found by running the full suite on a real Linux filesystem rather than a mounted Windows drive."],"0.5.52":["Picks up SDK 0.9.35: a model the gateway cannot route was classified as a retryable server error, so a permanently wrong model id would be retried on a backoff loop forever.","A model that is temporarily unavailable stays retryable, so only the unroutable case changed. Found by a live provider conformance run against the XENO gateway."],"0.5.51":["Picks up SDK 0.9.34, which fixes provider error classification: a bad API key returning HTTP 400 was reported as a missing model capability rather than an authentication failure.","That told you your model lacked a feature when your key was simply wrong. Found by a live provider canary - offline tests prove what we send, never how we read what comes back."],"0.5.50":["Picks up SDK 0.9.33, which fixes a permission-rule wildcard that could span a carriage return: Bash(command:git*) matched 'git status\\rrm -rf /', so a prefix rule an operator wrote as a constraint could authorize a composed command.","On a terminal a carriage return returns the cursor to column zero, so an approval preview could display one command while the shell received a second one. A single * now stops at every line terminator and ** remains strictly broader."],"0.5.49":["Picks up SDK 0.9.32, which fixes a single-writer violation: a live session owner whose heartbeat stalled could be treated as stale and have its lock taken by a second writer.","A long tool call, a paused debugger or a saturated event loop no longer risks losing session ownership; a genuinely dead owner is still reclaimed immediately."],"0.5.48":["xeno handoff status gains --since-revision and --wait-ms: a caller passes the revision it already saw and the command returns when the session actually moves, instead of re-reading the whole session in a loop.","A wait that reaches its deadline exits 2 rather than 1, so an unchanged session reads as a retryable observation rather than a failure."],"0.5.47":["xeno sessions show gains --history and --cursor: recent transcript activity is read in a bounded window with a continuation cursor, instead of loading an entire transcript to display the last few entries.","New xeno agents wait <run-ids...> waits for the first of several background runs to reach a terminal state, or every run with --all. A deadline exits 2 rather than 1, so a caller can tell a timeout from a failure.","New xeno mcp resource-templates lists parameterized resources a connected MCP server offers; servers without template support are unaffected.","AskUser questions can now be cancelled, so an unanswered question no longer holds a turn open indefinitely (via SDK 0.9.31)."],"0.5.46":["Sessions can be branched: xeno sessions fork <id> creates a new session from an existing one without changing the original, carrying its transcript history and linking back to its parent, so both lines of work stay resumable.","Sessions can be titled, pinned and archived: xeno sessions title, pin and archive. Pinned sessions lead every listing regardless of activity, and archiving retains the transcript rather than deleting it.","xeno sessions list gains --archived, and shows titles and pin state inline."],"0.5.45":["The top-level xeno ctx-viz command now exposes the same bounded live tool inventory as the interactive TUI, with cursor paging and permission-safe metadata.","Inventory output clearly separates registered tools from request-loaded schemas and never grants execution authority."],"0.5.44":["File tools now complete reliably in standalone and packaged CLI processes, including guarded Edit and Write results after permission approval.","Durable interrupted-session recovery now preserves receipt-before-status crash ordering and requires explicit respawn for fresh input.","Worker stop, lease revocation, permission approval, workflow recovery, and goal-budget controls are qualified through the unsigned Windows candidate package.","Synced Agent SDK 0.9.28 with the awaited tool-operation liveness repair and recovery contracts."],"0.5.43":["Provider-native Codex and Claude continuations can be attached from the XENO provider cockpit without replacing the XENO TUI; exact provider session identity, workspace, and ownership survive detach, reattach, and Interface handoff.","The native terminal path mirrors user messages into the owning graphical conversation and keeps XENO application system instructions out of provider-visible chat text.","Synced XENO ACP 0.2.13 and Agent Interface 0.1.23 after the earlier immutable candidates were published without moving their npm latest tags."],"0.5.42":["Durable Web Context operations now render the canonical typed evidence progress stream in human and NDJSON modes without inventing counters.","SIGINT and external abort request exactly one service-side cancellation and report whether the durable job reached a confirmed terminal state.","Synced Web Context 0.1.1, Agent SDK 0.9.25, and Agent Interface 0.1.22 for the negotiated ACP v2 evidence contract."],"0.5.41":["Durable compaction now flushes the recoverable session snapshot before mutating resident history, so repeated long-context cycles and crash recovery retain completed turns.","Chat and non-interactive run paths bind the real host parent-session identity before delegating, keeping nested work and results attached to the correct resumable conversation.","Execution handoff preserves writer fencing and live ownership across A-to-B-to-C resume while Loop continuation remains unbounded by default.","Synced the public Agent SDK 0.9.24 and Agent Interface 0.1.21 registry packages for the qualified Goal / Loop / Handoff contract."],"0.5.40":["Added durable Goal records with explicit criteria, milestones, delegated tasks, progress, steering, and evidence-gated completion.","Added distinct scheduled, development, and goal-continuation loops that are unbounded by default, persist every iteration, survive restart, and remain recoverable after an iteration failure.","Added live, heartbeat-backed execution handoff across resumed terminals with atomic A-to-B-to-C transfer and immediate source fencing; one-shot commands cannot impersonate a live owner.","Handoff now flushes and relinquishes the source session-writer lock before printing the resume command, so the target can resume the same transcript without either terminal deleting or rewriting the other's lock state.","Synced Agent SDK 0.9.23 and Agent Interface 0.1.20 for the shared Goal / Loop / Handoff runtime contract."],"0.5.39":["Added XENO Web Context search, fetch, render, map, crawl, extract, job wait/cancel/resume, and Browser handoff commands with canonical evidence metadata.","Preserved Chat and Agent session mode/workspace identity across CLI and Interface resume paths.","Synced Agent SDK 0.9.22 and Agent Interface 0.1.19 for the typed Web Context runtime event contract."],"0.5.38":["Corrective Agent Interface handoff: explicit Chat, Agent, and resume launch intent now wins over restored persisted desktop tabs after session hydration.","`xeno agent --interface` preserves the exact granted workspace even when the desktop has existing Chat history, while `xeno chat --interface` remains Chat-only with no project grant.","Synced the Agent Interface client and contract packages to the installable 0.1.18 release."],"0.5.37":["`xeno chat --interface` opens the canonical desktop surface as XENO Chat with Chat-only authority and no project grant.","`xeno agent --interface` opens the same surface as XENO Agent and grants the exact current local workspace.","Synced the Agent Interface client and contract packages to 0.1.16."],"0.5.36":["`xeno chat` and `xeno agent` now launch the same canonical XENO terminal interface while preserving their invoked identity: Chat is branded XENO CHAT and Agent is branded XENO AGENT.","Chat mode owns a private managed workspace and cannot be promoted to Agent authority by saved settings or `--mode`; Agent mode keeps the explicit local-workspace and full-capability contract.","Windows Terminal multiline paste remains one editable composer item and submits as one persisted user message, including fragmented bracketed-paste frames.","Synced the Agent Interface client and contract packages to 0.1.15 and the Agent SDK to 0.9.21."],"0.5.35":["The provider cockpit now exposes durable provider lanes, exact native attach and detach, explicit stop and reconcile controls, and persists whether each Agent session is Chat mode or Agent mode.","The status bar shows the active provider lane, and non-interactive provider, lane, attach, and reconcile commands expose the same control plane to scripts.","The local release gate now builds the native Windows XENO PTY before integration tests and typechecks the complete test surface from a clean checkout.","Synced the Agent Interface client and contract packages to 0.1.12 and the Agent SDK to 0.9.18."],"0.5.34":["Windows multiline-paste recovery now keys off the actual win32 runtime even when terminal TTY capability probing reports an inconclusive profile.","Input diagnostics now record the runtime platform, terminal profile, and stdin/stdout TTY state so real-terminal evidence explains which paste path ran."],"0.5.33":["Windows Terminal multiline paste now remains one editable composer message even when Windows omits bracketed-paste markers because virtual-terminal input is unavailable.","Real bracketed-paste frames still retain stateful fragmented-stream handling, and an ordinary Enter remains a submit after the short paste-boundary grace period.","Synced the Agent Interface client and contract packages to 0.1.11 and the Agent SDK to 0.9.17."],"0.5.32":["Recent-session state now stays inside XENO_AGENT_HOME and uses durable per-workspace updates, preventing Windows EPERM contention and lost concurrent session entries.","PowerShell command completion now drains the final stdout pipe data before settling, so successful commands cannot intermittently return empty output."],"0.5.31":["Windows Terminal bracketed-paste mode is now explicitly negotiated for the full composer lifetime, correcting 0.5.30's incomplete decoder-only repair.","Native TUI and external-editor handoffs release terminal paste mode before transfer and restore it only after XENO regains terminal ownership.","`--interface` now waits for an exact nonce-bound acknowledgement from the desktop renderer instead of reporting success when an older app merely spawned and ignored the resume request.","Managed finite operations can continue beyond the generic three-turn safety cap, recent-session writes are serialized across processes, and background commands receive privacy-safe semantic fallback labels."],"0.5.30":["Multiline terminal pastes now remain one editable composer message even when Windows Terminal fragments the bracketed-paste frame across multiple input chunks.","Complete bracketed-paste frames are handled before generic Escape sequences, and their terminal markers never leak into the submitted prompt."],"0.5.29":["ACP provider cockpit: resume durable Codex, Claude, and compatible provider lanes without replaying the XENO transcript into a new native session.","Attach, detach, reattach, stop, and reconcile native provider TUIs with one-writer ownership between the XENO TUI, Agent Interface, and provider terminal.","`--interface` handoff now preserves the selected conversation host binding and exact provider continuation identity.","Background work uses semantic task names, and continuation checkpoints retain the original objective instead of ending a live operation at an arbitrary automatic-turn boundary.","Synced Agent Interface client/contract to 0.1.8 and @xenosystem/agent-sdk to 0.9.14."],"0.5.28":["The root `xeno --help` output now exposes `--interface` and `--resume [id]`, so terminal-to-desktop session handoff is discoverable at the exact command surface where it is used."],"0.5.27":["Open the XENO Agent Interface from the terminal with `xeno --interface`, resuming an exact session ID or the latest session in the current workspace.","Long-running background commands now stay alive while active, preserve native PowerShell syntax, and display meaningful task names.","Short follow-through messages such as do it and proceed now retain implementation authority, while nested continuations preserve the original objective.","Synced @xenosystem/agent-sdk to 0.9.13."],"0.5.26":["Terminal bracketed paste & multi-line input: bracketed paste frames are cleanly decoded, collapsed into `[Pasted text #N +N lines]` tokens for large blocks, and submitted with full uncorrupted text without escape code dropouts.","Dynamic terminal reflow: turn receipts, turn dividers, and prompt bubbles adapt smoothly to window resize events without clipping."],"0.5.25":["Interactive `/status`, `/config`, `/usage`, `/stats`, `/settings` multi-tab modal with live search, keyboard cycling, and instant ~/.xeno/config.json persistence.","Live 52-week session activity heatmap, longest/current streak metrics, active days summary, lifetime token metrics, and favorite model analytics.","Real-time git workspace analytics including active branch, ahead/behind counts, working tree diff additions/deletions, and live turn API elapsed times.","Turn receipt visual polish with right-margin padding and formatted recap indentation.","Interactive `/handoff` command: switch seamlessly between specialist agents with prompt context and intent transfer.","Zero-config `.claude/agents/*.md` & `.xeno/agents/*.md` discovery with level-ordered priority shadowing.","Host mid-turn steering (`turn.steer`) and subagent wire payload artifacts integration.","Synced @xenosystem/agent-sdk to 0.9.12 with enhanced offline grace monetization validation.","xeno-rt: resolved Qwen 3.8 / 3.5 MTP NextN architecture prefixes and prevented layer 32 recurrent tensor probe failure."],"0.5.24":["Published with exact matching CLI_VERSION literal, guarded by verify:version in CI.","Synced @xenosystem/agent-sdk to 0.9.11, pulling model-aware context budgets from live gateway `/v1/models` catalog.","`/import` now immediately triggers context reconstruction turns rather than pausing at the input prompt."],"0.5.23":["Model-aware context budget: queries gateway `/v1/models` catalog for authoritative `context_window` limits.","Context compaction request byte budget scaled to prevent false refusals on large toolsets."],"0.5.22":["`/context` divided by a hardcoded 200,000 regardless of which model you are on. That figure is XENO's window and nobody else's: on a 128,000-token OpenAI model the gauge read about 12% where the truth was 19%, and near the limit it said \"Context is healthy\" with compaction imminent; on Google's 1,000,000-token window it pegged at 100% from a fifth of the way in and warned permanently. It now divides by the budget the SDK actually resolved for the run.","The gauge also says how well it knows that number. A configured budget is exact and prints a plain percentage; a provider profile is one window for every model that provider serves, so it prints `~62%` and labels itself approximate. Before any turn has reported, it says the 200,000 is an assumption rather than presenting it as fact.","The numerator was always right and is unchanged: it sums the messages currently in context, so it falls when a compaction drops them. Only the denominator was asserted rather than resolved."],"0.5.21":["Security: undici 6.27.0 -> 6.28.0, closing a cookie-injection advisory. This repo had 12 open alerts and this was the ONLY one that reaches shipped code \u2014 the five rated HIGH are all build and test tooling. Fixing by severity rank would have addressed the wrong thing first.","Worktree cleanup could delete THROUGH a junction. That is the failure that destroyed two repositories on 2026-08-03: on Windows a recursive delete follows a junction and removes the target, and npm creates one for every file: dependency. Cleanup now clears the reparse point itself and never the thing it points at.","Worktree cleanup had also decayed into a no-op \u2014 its filter excluded every orphan it existed to remove, so it ran, reported success, and cleaned nothing. And a reparse-point scan that hits its cap now REFUSES rather than returning a short list, because a truncated scan that looks complete is how the delete above becomes safe-looking.","The control-plane `list()` was not a read: it wrote once per stale record, every time anything listed runs. Listing is now free of side effects.","`/import` brings a session from another agent CLI into XENO and continues it \u2014 including agy stores, where the obvious store turned out not to be the best source. `--imported` shows what is on disk and says plainly that it persists. The source transcript is never touched, and that is enforced rather than intended.","Delegated branches now run on the Agent host under XENO_AGENT_ATTACH, report tool progress while they work, and the CLI reads the HOST's audit rather than only its own. Previously a host-routed branch was silent until it finished, and a refusal blamed a missing stream that in fact existed.","`xeno host status` now reports WHICH lanes the host offers and why a blocked one is blocked \u2014 including whose environment the blockage is about, which was the part that made the old message useless.","Pinned to @xenosystem/agent-sdk 0.9.10. The pin had been two releases stale, so work that shipped in 0.9.9 reached nobody. 0.9.10 also reports how full an agent's context is: turn.completed carries the RESIDENT token count, not the cumulative billing counter, and context.pressure arrives after every model response. The obvious field re-adds the whole prompt each turn \u2014 measured live, three one-word turns reported 3049, 6106 then 9171 tokens while the context grew by about eight.","Budget accounting no longer reads the entire run store when no budget cap is configured."],"0.5.20":["Pinned to @xenosystem/agent-sdk 0.9.8. The SDK's ownership policy still labelled this CLI by a scope retired in 8363d30c, which had failed the release smoke on every run since 2026-08-13 \u2014 the mismatch was never in this repo, so the fix was a repin rather than a workaround.","The release smoke now derives how strict it should be from the release trust policy: while no signing identity is approved it holds the engineering bar, and it tightens by itself the moment one lands. It previously demanded a signature no ordinary CI run could produce, and had failed for long enough to read as background noise.","First test coverage of the native manifest signing path, which had never executed once. Signer and verifier each carry their own copy of the canonical-JSON serializer and cannot import each other, so a drift as small as key ordering would have invalidated every release signature \u2014 and would have surfaced on release day, looking like a key problem.","Windows: temporary-directory cleanup no longer loses a race with exiting child processes, and the certification matrix checks out correctly on Windows ARM. `force: true` suppresses ENOENT, not EPERM, so the previous cleanup looked defensive and was not.","Groundwork for interactive Ctrl+C on Windows: the native addon can now raise a real console interrupt. Writing 0x03 into a ConPTY does not raise a signal, which is why Ctrl+C has never worked there. NOT yet wired \u2014 the console attach succeeds and the event is raised, and a ConPTY client still does not observe it."],"0.5.19":["The CLI did nothing at all on Linux and macOS. Its entry point did not resolve symlinks, so every npx and global install ran the wrong path and exited silently \u2014 the install looked successful and the binary did nothing. Fixed.","Agent permission decisions now reach an actual human on both rails, rather than being resolved without one.","A remote run that is read-only now says so, instead of failing silently and leaving you to work out why nothing changed.","The version the binary REPORTS is now bound to the version npm publishes, and a test enforces it. They had drifted: 0.5.18 was published as a package whose `--version` said 0.5.17.","\u26A0\uFE0F 0.5.18 exists on npm and was published from a branch that was never merged. It is superseded by this release, which is cut from `main`. If you installed 0.5.18, upgrade."],"0.5.17":["The CLI now ships as @xenosystem/agent-cli. The former name @xeno-corporation/xeno-agent-cli is deprecated on npm and receives no further releases; the `xeno`, `xeno-agent` and `xeno-code` binaries are unchanged, so nothing in your shell or scripts has to change.","The exact SDK pin moves with it: the CLI is bound to @xenosystem/agent-sdk 0.8.12. 0.8.11 was never published under either name and cannot be \u2014 GitLab evaluates .gitlab-ci.yml as it exists at the tag, and tag sdk-v0.8.11 predates that pipeline.","This release cannot be installed until @xenosystem/agent-sdk 0.8.12 is live on the registry; the release pipeline fails closed on --require-dependencies-published until it is."],"0.5.16":["Windows 11 ARM64 containment certification now performs architecture-neutral MXC host preparation with the reviewed x64 helper through operating-system emulation while keeping the contained runtime native ARM64.","The CLI is bound exactly to SDK 0.8.11, whose host-preparation reports distinguish the host architecture from the reviewed setup-helper architecture and retain timeout diagnostics."],"0.5.15":["macOS and Linux standalone diagnostics now report their verified POSIX process-group lifecycle independently from the stronger process-hardened sandbox level, preserving truthful security status while certifying full-tree cancellation, timeout, and shutdown behavior.","Generated Harbor benchmark and audit workspaces are excluded from source control, keeping Windows ARM64 checkouts below platform path limits and removing 9,938 generated artifacts from release candidates."],"0.5.14":["Windows 11 24H2 containment admission now uses the authoritative non-server NT client build floor instead of rejecting current Azure and GitHub Windows 11 images whose legacy registry ProductName still says Windows 10.","Windows Server remains fail-closed, pre-26100 clients remain ineligible, and both x64 and ARM64 host identities have regression coverage."],"0.5.13":["Hosted Windows x64 containment certification now fails closed unless the runner is Windows 11 24H2 or newer, the platform supported by Microsoft MXC, instead of treating Windows Server runner failures as product failures.","The certification matrix accepts a protected XENO_WINDOWS_X64_RUNNER label for an ephemeral Windows 11 x64 runner while keeping all other hosted platform rows unchanged.","Containment failure reports preserve bounded head-and-tail diagnostics through SDK 0.8.10 so the actionable trailing Win32 or MXC error is retained."],"0.5.12":["Windows MXC containment now launches its unrestricted host from the prepared system-drive temporary directory, outside directories whose DACLs are mutated by the contained policy, and certification captures official redacted MXC diagnostics.","Internal background session workers no longer start a competing global reconciler, preventing slower macOS hosts from quarantining a healthy turn between transcript append and checkpoint commit.","The interactive attach/input/stop smoke now follows the actual persisted inbox sequence and records worker logs on failure; the CLI is bound exactly to SDK 0.8.9."],"0.5.11":["Windows x64 containment certification now launches the MXC host and contained runtime with working-directory and temporary paths on the prepared system drive, matching split-drive GitHub runners.","The CLI is bound exactly to SDK 0.8.8, preserving the passing Linux, macOS, and Windows ARM64 conformance behavior while repairing Windows x64 ProcessContainer startup."],"0.5.10":["Linux containment certification now keeps disposable fixtures under the OS-private temporary mount instead of GitHub's workspace-projected runner directory, preserving the unlisted-filesystem boundary probe.","Windows certification retains the MXC-prepared system-drive fixture root required by hosted runners whose workspace and default temp directory use another volume."],"0.5.9":["Windows containment certification now creates its disposable fixtures on the MXC-prepared system drive, including hosted runners whose workspace and default temp directory live on another volume.","Standalone Windows certification now performs the same explicit host preparation and temporary-root binding as the native package matrix."],"0.5.8":["Native containment certification now compiles its macOS UI-policy probe against the stable libsystem_sandbox ABI without depending on private SDK headers.","Windows certification now distinguishes MXC's persistent per-policy DACL requirement from its explicit one-time host-preparation warnings."],"0.5.7":["The immutable CLI candidate now binds SDK 0.8.5 to the exact canonical Linux npm tarball bytes used by certification."],"0.5.6":["Windows containment certification now performs Microsoft MXC's explicit idempotent host preparation before AppContainer+DACL conformance.","macOS ARM64 certification now records behavioral Seatbelt evidence for pasteboard, WindowServer, LaunchServices, and HID isolation."],"0.5.5":["Native certification now resolves the SDK candidate artifact from the same workspace path on Bash and PowerShell runners.","SDK containment assets retain executable package modes on Linux and macOS, with a source regression check for every reviewed Unix binary."],"0.5.4":["Native engineering certification jobs now download the exact SDK tarball produced by the successful parent gate before installing dependencies.","The six-platform matrix remains source-bound to one immutable CLI tag and one immutable SDK candidate artifact."],"0.5.3":["Candidate packaging accepts both npm 11 array-form and npm 12 package-keyed JSON, with explicit diagnostics for malformed output.","Hosted SDK packaging now parses a bounded JSON file instead of relying on a large shell variable or an obsolete npm output shape."],"0.5.2":["Hosted certification now caps SDK declaration generation at two concurrent entry points and cleans declaration output in isolated bounded-memory workers.","SDK build subprocess failures now report their terminating signal or exit status instead of producing a silent hosted-run failure."],"0.5.1":["Hosted certification now builds the exact SDK candidate in bounded declaration groups, preventing parallel TypeScript declaration generation from exhausting GitHub-hosted runner resources.","Post-freeze readiness now distinguishes exact candidate tags verified at the candidate commit from collisions in release, registry, feed, and service namespaces."],"0.5.0":["Agent Profiles now provide enforceable Assistant, SWE, Reviewer, Writer, Research, Product, CI, DevOps, and Legal Research identities with bounded tools, permissions, skills, hooks, memory, isolation, and external-action authority.","The XENO Artifact Protocol adds durable plans, patches, diffs, reviews, screenshots, recordings, reports, provenance, approvals, and evidence relationships shared across local, hosted, and Hub workflows.","Secure Execution Contracts and capability leases now make filesystem, network, secret, process, device, browser, and external-action authority explicit and auditable.","Skills v2 adds standards-compatible SKILL.md discovery, progressive loading, bundled resources, invocation policy, version identity, and compatibility with XENO, .agents, and Claude skill locations.","MCP now supports current Streamable HTTP sessions and OAuth discovery while retaining compatible stdio and legacy SSE connections.","Browser, computer-use, hosted-agent, semantic-index, production-review, spec-planning, secure-sharing, and provider-onboarding surfaces are integrated through the shared platform contracts.","The retained TUI now presents stable grouped tool activity, live task and subagent status, candidate-bound edit previews, context-pressure and compaction state, and clearer turn completion receipts.","Six-product candidate certification now binds the SDK, XENO Use, XENO Browser, Agents API, CLI, and Hub to exact source identities, versions, tags, evidence, and protected release gates."],"0.4.45":["This transitional release is engineering-tested but not GA-certified: native PTY artifacts are unsigned and remain disabled by default until the Azure signing identity is approved; ordinary CLI and pipe-mode commands remain available.","App Server v2 now provides durable threads and turns, typed clients, permission ownership and expiry, bounded replay and backpressure, authenticated HTTP access, and additive v1 compatibility.","The terminal renderer now uses committed retained frames, bounded coalescing, one normal write per frame, a responsive 50-agent footer, accessibility modes, and a native terminal compatibility matrix.","Release certification now fails closed on six native architectures, platform and manifest signatures, reproducible package payloads, SBOMs, provenance attestations, independent approvals, npm OIDC publication, and public clean-install verification.","Long chat prompts now soft-wrap into a growing six-row composer with Unicode-safe editing, visual Up/Down navigation, file-panel parity, and a temporary XENO_INPUT_SOFT_WRAP=0 rollback switch.","Long-running model-authored shell commands now use managed operations: Ctrl+B promotes the same process, finite background work waits without model polling, and durable continuations resume exactly once after terminal output arrives.","ReadImage now uses Xeno's dependency-free owned raster codec for bounded PNG, BMP, Netpbm, and core-SVG previews; /processes and doctor expose task control, process-tree containment, operation-schema, and codec status.","Dynamic workflows now expose first-class run limits and terminal reducer summaries in run records and inspect JSON.","Background agent sessions now deliver durable completion, failure, stop, and request-keyed needs-input notifications to interactive parent chats and bounded headless runs without clobbering prompt drafts.","Workflow orchestration includes grouped phase/child progress, parent-chat completion notifications, WorkflowWait, /workflows drill-down, watch JSONL snapshots, and ultracode workflow prompts.","Workflow starts now support plan preview and exact-definition approval memory, scheduler ticks are serialized, and workflow lifecycle metrics are available through the OTel usage export.","Tool activity now uses semantic Update and Search labels, contextual line-numbered edit previews, expandable read/search/shell output, and accurate failure rendering.","Interactive chat now blocks repeated inspections and unrequested mutations on short questions, gives explicit research a larger typo-tolerant evidence budget, and reserves a tool-free final-answer turn when work limits are reached."],"0.4.44":["Markdown source links now render as clickable terminal links in supported terminals, with visible URLs preserved when links are disabled."],"0.4.43":["New background agents now appear in the footer immediately after launch, and the footer can show up to eight agent sessions."],"0.4.42":["Background agent footer rows now fit the common three-agent fanout without hiding the first agent on compact terminals.","Completed background agent sessions now close after BackgroundAgentJoin returns their result to the main agent."],"0.4.41":["Completed background agent footer rows now keep a fixed runtime instead of continuing to count upward."],"0.4.40":["One-shot background agent sessions now mark done after returning their result, while user-follow-up sessions stay idle for continued chat."],"0.4.39":["Background agent session activity now uses concise status labels like Thinking instead of showing the full task prompt."],"0.4.38":["Opened background agent sessions now show their own session activity line while keeping main-agent tool progress isolated."],"0.4.37":["Opened background agent sessions no longer show the main agent's active tool progress line."],"0.4.36":["Opened background agent sessions now render the same main-chat transcript surface for user messages, assistant messages, tool calls, and tool results."],"0.4.35":["Background agent session chat now includes tool calls and tool results in its visible history."],"0.4.34":["Opening a footer background agent now switches the main chat surface into that agent session instead of showing a separate info panel.","Child-session input now queues messages to that agent while Esc returns to the main chat."],"0.4.33":["Background agent footer rows now repaint immediately during active turns.","Remembered background-agent approvals now apply to later background-agent launches."],"0.4.32":["Startup release-note hints now sit directly under the note text and render dimmed in the side panel."],"0.4.31":["Unread release notes now render beside the startup XENO AGENT header on wide terminals."],"0.4.30":["BackgroundAgentList now only reports current-chat footer sessions so old workspace agents do not hide missing new deployments."],"0.4.29":["Background agent footer markers now use filled and empty squares.","Opening a background agent from the footer now shows its session chat with transcript and message input."],"0.4.28":["First-run default model is now gpt-5.5 while saved user model choices are preserved.","Number keys in the model picker now type into search instead of selecting by index.","Model selections made with /model now persist as the user's saved default."],"0.4.27":["Background agent footer rows are now scoped to the current chat session."],"0.4.26":["Background agent rows now sit below the status line and inherit the live chat model."],"0.4.25":["Legacy BackgroundAgent calls now create footer-visible interactive background sessions."],"0.4.24":["Model picker support now has a `xeno models --json` command, share export proof, and GitHub review artifact contracts."],"0.4.23":["Model picker and /model listings now refresh Xeno API model availability before switching."],"0.4.22":["Hook review now shows command-hook hashes and supports trust, disable, and explain commands.","Expanded lifecycle hooks now cover permission decisions, stop failures, and delegated subagent start/stop events.","Set XENO_STATUS_LINE_COMMAND to replace the TUI status line with a cached command output.","Rewind now saves the abandoned conversation branch as a manual checkpoint before restoring.","Interactive chat now supports Ctrl+R history search, Ctrl+G prompt editing, /vim input mode, and /copy answer/block/diff clipboard copy.","/theme is now a discoverable alias for /color with user/project custom theme files, and /processes stop-all stops running background tasks."],"0.4.20":["Shell completions now include the current control-plane commands, flags, statuses, scopes, and usage groups.","The local app-server browser page now includes prompt and process controls on top of advanced JSON-RPC.","Published CLI and SDK packages now include GitHub repository metadata.","Docs now call out the temporary GitHub Actions startup_failure blocker while local gates remain authoritative."],"0.1.0":["Persistent shell sessions now preserve cwd and shell state across Bash calls.","Delegated planner, explorer, executor, and reviewer branches now support staged and parallel policies.","MCP now supports stdio and SSE transports, prompt discovery, resource reads, and live tool sync.","Notebook, ask-user, and memory tools are available in the shared agent runtime.","CLI operator workflows now include doctor, bug-report, config editing, cost summaries, and runtime inspection."]};function Lme(e=Re){return hsn[e]??[]}function gsn(e=Re){let t=Pt().lastReleaseNotesSeen;return Lme(e).length>0&&t!==e}function mx(e=Re){Do({lastReleaseNotesSeen:e})}function YX(e){let t=e??Re,n=Lme(t);return n.length===0?`No release notes available for version ${t}.`:[`Release notes for version ${t}`,"",...n.map(r=>`- ${r}`)].join(`
4396
+ `)}function msn(e){let t=e.replace(/\s+/g," ").trim();return t.length>72?`${t.slice(0,69)}...`:t}async function KX(e){if(!e.checkpointManager||e.messages.length===0)return null;let t=`Branch before rewind to "${msn(e.targetPrompt)}"`,n=await e.checkpointManager.create({trigger:"manual",messages:e.messages,description:t});if(e.sessionManager){let r=[n.id,...e.sessionManager.meta.checkpoints.filter(o=>o!==n.id)];await e.sessionManager.updateMeta({checkpoints:r}),await e.sessionManager.transcript.append({type:"checkpoint",data:{id:n.id,action:"create",name:t,trigger:"manual",messageCount:e.messages.length}})}return n.id}Vr();Ko();var hsn={"0.5.108":['Signing in works again. Since 0.5.95 the npm package was missing the module that holds your XENO sign-in, so `xeno login` said "XENO sign-in is unavailable". The release check now refuses any package that cannot load it.'],"0.5.107":["`/as` in chat: act as one of your XENO agents in the same conversation. `/as` lists them, `/as <name>` switches, `/as me` returns to you. Each switch revokes the previous agent credential, and leaving the chat revokes the last one.","`xeno run --resume` acts as the agent the session acted as before, with a fresh credential. Only the agent id is stored; `--as me` clears it.","Lines piped into `xeno chat` now run in order. Before, a slash command could end the session while later lines were still waiting.","Uses SDK 0.10.59."],"0.5.106":["`xeno run` takes its prompt from standard input (`xeno run -`, or piped with no prompt) or from `--prompt-file <path>`, so a prompt longer than a command line allows reaches the model as the message itself, up to 8 MB.","`xeno run --as <agent>` acts as one of your XENO agents: its instructions, model, effort and tool policy, with the XENO Tasks tools ready. Its credential stays in memory and is revoked when the run ends, however it ends. `--json` reports `acting_as`.","`xeno spawn <args>` hands the rest of the command to XENO Spawn.","Uses SDK 0.10.58."],"0.5.105":["`xeno run` saves every run as a session and prints its `session_id` in `--json` output. `--resume <id>` continues that conversation with a new prompt, and `--continue` picks up this folder's most recent session. Both work for local runs, not with --delegate, --remote or --bg."],"0.5.104":["`xeno run --output-schema <file>`: the final answer must be JSON that matches the given JSON Schema. An answer that does not match is sent back with the errors to fix, and the valid result is returned as `structured_output` in the JSON output. If no valid answer arrives, the run ends incomplete (exit 1).","Uses SDK 0.10.55."],"0.5.103":["A run that produced every output named in XENO_REQUIRED_OUTPUT_PATHS_JSON now reports ok (exit 0) even if one of its tool calls was denied along the way. The denial is still listed in tool_summary and the audit. Without declared outputs, a denial is still the outcome.","`xeno run --allowed-tools` and `--disallowed-tools` (comma-separated) control which tools the agent is offered. The limit also applies to helpers it starts."],"0.5.102":["A research run whose answer is a written document that cites its sources is no longer held open asking for the sources again in chat.","Uses SDK 0.10.54."],"0.5.101":["Skills found by default are named project:<name> or user:<name>, so the Skill tool resolves the name it was given, and the same name in project and user folders is two skills.","Child agents and background workers inherit their parent's skills again; the interactive-child inheritance tests pass.","Uses SDK 0.10.53."],"0.5.100":["You can set how much web research one turn may do. `xeno run` and chat accept --max-web-searches (1 to 200), --max-web-fetches (1 to 500) and --max-web-calls, or the environment variables XENO_MAX_WEB_SEARCHES, XENO_MAX_WEB_FETCHES and XENO_MAX_WEB_CALLS. Without them the limits are unchanged: 5 searches and 12 fetches for a research request, 3 and 4 for a quick question. A value that is not a whole number in range stops the command with a message. Each search can cost provider money, up to the per-request cap.","Uses SDK 0.10.42."],"0.5.99":["Web search uses your account's configured provider allowance when you have not set a limit. Explicit limits still narrow it, including zero: XENO_WEB_CONTEXT_MAX_PROVIDER_COST_USD and --provider-cost-budget-usd never silently authorize additional spending.","WebFetch reports the recorded reason when a page cannot be retrieved, such as site refusal, a missing page, rate limiting or a network error, instead of only saying the scrape failed. Conversational tools preserve the specific error code for the agent. Explicit site refusals are not bypassed.","Uses SDK 0.10.41 and Web Context client 0.1.5. The HTML transcript redesign and /provider picker remain outside this release."],"0.5.98":["Chat draws its composer before loading session state or building the agent. You can type immediately; early submissions wait until restoration, permission state and execution ownership are ready. In five real-terminal runs on our large workspace, the usable frame appeared in 579 ms median. Line-input chat also preserves input received before readiness, including piped input ending at EOF.","Terminal updates repaint only changed lines; typing and in-place tool updates no longer redraw the whole screen. The status command refreshes on changes with a bounded cadence. --version runs from a tiny entry without loading the agent runtime.","Background dispatch helpers report their results back when they settle. The footer separates the agent list from status by one blank row, keeps main and helpers adjacent, shows state on the left and aligns elapsed time and tokens on the right.","Web Context uses your signed-in XENO account by default, with a fresh DPoP proof for each request. XENO_API_KEY also works; explicit Web Context endpoint/token settings still take precedence. Gateway-prefixed search, fetch and artifact reads use Web Context client 0.1.3.","Uses SDK 0.10.40, including faster startup, background reports and the compatible Web Context client peer. The new transcript design and /provider picker are not part of this release."],"0.5.97":["Long sessions stay fast. Adding a line to the conversation no longer redraws the whole history: with 2,000 rows on screen, a new tool row went from about 8.5 seconds to about 5 milliseconds.","Each screen update is sent to the terminal in one piece, wrapped so terminals that support it paint it all at once, which removes flicker and half-drawn frames.","Typing @ to pick a file no longer reads the folder on every key; the listing is reused for two seconds. Set XENO_RENDER_STATS=1 to log frame times and key-to-screen latency to ~/.xeno/render-stats.jsonl."],"0.5.96":['The /model list is the full list the XENO API serves, read live. It shows "Loading models..." while it loads, says so plainly if the list cannot be loaded instead of offering a short built-in list, and keeps models that are temporarily unavailable at the bottom with the reason; picking one is refused with that reason.',"Switching to a model from the live list no longer makes a second network check, so the switch is immediate. Uses @xenosystem/agent-sdk 0.10.38."],"0.5.95":['Messages between sessions are now one line each. A sent message reads "sent to SESSION2: ... \xB7 queued" and its state (queued, held, delivered, running, reported, failed) updates in place; a received one reads "from SESSION1: ...". The full text and message id are behind ctrl+o, and the Send tool no longer prints its own call and JSON result.',"Tool rows no longer wait. A finished tool row settles at once instead of staying for at least 0.7 seconds, and the end of a turn no longer waits for it. Tool results open collapsed (ctrl+o to expand) instead of opening expanded and collapsing 2.2 seconds later."],"0.5.94":["You can save a model API key once with `xeno auth login --api-key`. It is read from a hidden prompt or from standard input, never from the command line, and it is checked with XENO before it is saved. XENO_API_KEY still takes precedence when it is set.","Where the key is kept: on Windows it is protected by Windows DPAPI for your Windows user account, using the native system call, and nothing is saved if that protection is unavailable. On Linux it goes into the desktop keyring (Secret Service, via secret-tool) when one is available, and otherwise into a file only you can read. On macOS it is a file only you can read.","If you used an earlier version, your saved API key moves to the new protected store the first time you start this version, and the old plaintext file loses only that key. Your previous sign-in cannot be carried over: run `xeno login` once to sign in again.","`xeno auth status` shows where the model credential is stored without printing any part of a key. On a machine that has never signed in it says 'not signed in' and how to sign in, rather than reporting a fault. `xeno logout` and `xeno auth logout` remove a saved key.","Account sign-in is available on Windows only for now. On macOS and Linux, `xeno login` says so and points to `xeno auth login --api-key` or XENO_API_KEY. Account sign-in is also bundled inside the CLI, so installing from npm needs nothing from a private registry.","Plan mode now works through the model's own tools: it starts planning by itself when the work calls for it and hands you the plan to approve. You can approve, approve with edits typed in your editor or the input box (your version is what gets carried out), or send it back with feedback. Tools from connected servers that only read keep working while planning. From @xenosystem/agent-sdk 0.10.35.","Stopping a helper at the exact moment it starts a tool no longer crashes the app.","Notification history and dismissal stay within the selected workspace, including isolated helper worktrees and deleted-parent recovery. Control Room actions accept the exact displayed snapshot for 60 seconds and refuse changed state.","MCP authentication failures identify the exact server and its dedicated login command. Repeated failures do not produce duplicate notices, and line-input chat shows the same recovery guidance as fullscreen chat.","Web fetch requests one page instead of exceeding the connected account's page quota. Map and crawl respect the account's page limit. Paid web search supports an explicit per-request USD budget and still defaults to no spending.","A prepared session handoff can now be cancelled from the original fullscreen or line-input chat. The exact offer is withdrawn before the conversation writer resumes; other detached execution stays refused."],"0.5.93":["Plan mode is here. Start with --permission-mode plan, type /plan, or press Shift+Tab: the agent can read and investigate but every change is refused until you approve its plan, including changes a helper agent would make. Plan mode survives a crash and resume, and xeno run returns the plan instead of waiting for an approval.","A session can now move to another enrolled computer with its conversation: the receiving computer downloads it from the execution authority and checks it is exactly the same before taking over. A computer that loses ownership now also stops the background tasks, helper sessions and workflow runs that session started.","Helper agents can be stopped one at a time from the agent list, cancelling a turn stops its helpers, and a helper that ran out of budget is shown as unfinished instead of done.","Every command that takes a prompt now refuses a /command it cannot run instead of sending it to the model, pause and resume on Windows really suspend the work, and slow Windows process queries no longer make commands time out. /goal clear, /goal pause and /loop stop now always win against a running goal loop, and a !command typed during a turn runs as a shell command."],"0.5.92":["A /command the chat does not know is no longer sent to the model as a prompt. Typos like /revew, commands this mode does not support, and commands from another lane now stop with a message naming the command and why, and nothing is sent. This covers the chat, xeno run, background runs and the app server.","Moving a session between computers through an execution authority now recovers safely: a computer that loses contact stops working on the session before another can take it, a failed or abandoned move hands the session back to the computer that offered it, and /handoff cancel withdraws an offer. The receiving computer checks it has exactly the same conversation before taking over.","Helper agents now keep their background tasks private: a helper can no longer read or stop its parent's or another helper's tasks, and the reverse."],"0.5.91":["You can now stop two computers from working on the same session at once. Run xeno app-server --http --execution-authority on one machine, enrol each computer with xeno executors add, and start chats with --execution-authority. While one computer has a session, another is refused until the first lets go or stops responding. Before, each computer only checked its own records, so two could both think they had the session."],"0.5.90":["Forking a conversation now makes you choose, instead of deciding silently: the whole conversation or only up to a checkpoint, and whether the fork shares this folder or gets its own git worktree. Use /fork in the chat, or xeno sessions fork with --history and --working-tree. An isolated fork says how many uncommitted changes it does not carry over. Before, every fork quietly shared the same folder, so both conversations changed the same files."],"0.5.89":["A helper started with dispatch_agent now shows in the agent list below the input while it works. Press Enter on it to open its conversation; what you type there reaches it at its next step, and once it finishes the conversation stays open to read. Before, it was one line in the transcript and its conversation could not be seen.","/agents now lists the agents started from this chat, numbered, so /attach 2 opens the one shown as 2."],"0.5.88":["With helper agents working, pressing Enter on a helper now opens its conversation in the chat, as it happens. While it is still working, what you type there reaches it at its next step. Once it has finished, the conversation stays open to read. Before, Enter showed only a status panel.","A large delegation budget no longer breaks the helpers. Given 200,000 tokens or more, a helper stopped before sending anything, because its whole budget was being reserved as room for one reply. From @xenosystem/agent-sdk 0.10.29."],"0.5.87":["Open a background agent's conversation right in the chat with /attach, by its name, its number in the agent list, or its id. Inside it, /attach opens an agent it started. Esc or /back goes back one level, and /main returns to your own chat. Before, opening an agent's agent lost the way back to the one you came from.","With helper agents working, the Down key now reaches the background agents below them too. Before, it stopped at the helpers."],"0.5.86":["An agent file's max-tokens and deadline now also apply when the agent is called as a helper in the middle of a chat, not only when it runs in the background."],"0.5.85":["xeno agents new now takes --max-tokens and --deadline (for example 30m), so a background run can have its own budget and time limit. They are kept with the run, so relaunching it does not reset them, and a reply in progress is stopped when the time limit passes.","An agent file can set a default budget with max-tokens and deadline at the top. It applies to background work started as that agent, unless you give a budget yourself. From @xenosystem/agent-sdk 0.10.28."],"0.5.84":["A background agent can now be given its own token budget and time limit when it is started. It stops once it has spent the budget, and when the time limit passes it stops, even in the middle of a reply. Both are kept with the session, so restarting the worker does not reset them. Before, a background agent had no limit of its own unless its parent goal had one."],"0.5.83":["With delegation on, each helper agent now stays inside its share of the delegation token budget. Before, the budget only limited each single reply, so a helper given 1,200 tokens could keep calling tools and spend several times that. It now stops once its share is spent and says how much it used. From @xenosystem/agent-sdk 0.10.26."],"0.5.82":["If the CLI closes while the agent is waiting for your answer, the question comes back when you resume the session, with the same choices. Before, the question was lost: the agent was told it had been interrupted and not to repeat it, so it never asked again. Press Esc to skip it and answer in your own words instead."],"0.5.81":["Tools from MCP servers now work with every model. Their names contain dots, and several models refused any request that included one: Claude and DeepSeek failed the whole turn, and gpt-6 answered with nothing. The tool still shows its real name in the terminal and in permission prompts. From @xenosystem/agent-sdk 0.10.23."],"0.5.80":["A tool server that sends a huge reply no longer ties up the agent. A reply over 16 MB is refused as it arrives, and the request fails right away with a clear error. Before, a 200 MB reply was read in full, which took about 48 seconds, and then almost all of it was thrown away. From @xenosystem/agent-sdk 0.10.22."],"0.5.79":["Long sessions stay fast to scroll. In a session of 10,000 messages, one scroll step took about 430 ms and now takes about 24 ms, and a keypress went from about 27 ms to about 4 ms. Resizing and entering scroll mode got faster too.","Images from tools now reach models that accept images even when the name is new, such as gpt-6, because the model list says which models take images. From @xenosystem/agent-sdk 0.10.21.","A reply that ends without the model sending anything now shows as an error instead of an empty, finished turn. From @xenosystem/agent-sdk 0.10.21."],"0.5.78":["When a tool's output is too long and gets shortened, the agent can now read the part that was left out. The full output is kept, and the new ToolOutput tool reads it back. Before, a long shell command lost its middle for good. From @xenosystem/agent-sdk 0.10.19.","ToolOutput reads appear in the compact tool-activity row with the other reads, and the tool line shows which stored output and offset it read."],"0.5.77":["Long sessions no longer slow down as they grow. Adding output used to re-draw the whole conversation every time, so each new line took longer the more was already on screen. Now 10,000 blocks of output take under a second instead of minutes, and memory stays flat.","The spinner on a running tool stays in the right place as output scrolls, including after it scrolls off screen and back."],"0.5.76":["Model endpoints behind a proxy that ignores streaming now work. Their reply is read as one complete answer instead of failing as a broken stream. From @xenosystem/agent-sdk 0.10.18."],"0.5.75":["A model reply cut off in the middle of a tool call no longer runs that tool with empty input. The agent is told the call was not run and nothing was changed.","If you stop the agent after it has sent a change, it is told the change may have happened, and to check before trying again, instead of being told it was cancelled. The same applies to a change that timed out.","The request time limit now covers the whole reply, not just the moment the reply starts. A reply that stalls part-way now ends at the limit instead of hanging. A timed-out request is not repeated automatically, because it may still be running.","`xeno harbor` analysis recognises the new timeout and dropped-stream messages as transport failures, as it did the old wording.","Uses @xenosystem/agent-sdk 0.10.17."],"0.5.74":["New Patch tool: the agent can change several files in one all-or-nothing edit, including adding, moving and deleting files. Nothing is written unless every change matches the files as they are. In accept-edits mode it is approved automatically, like Edit. From @xenosystem/agent-sdk 0.10.16.","Patch is treated as a file write everywhere a write is: it is denied in hosted runs that allow no edits, shown with the files it touches in the tool line and background session details, and counted by the completion checks that look at which files a run wrote."],"0.5.73":["Background and workflow workers that start slowly, for example on a busy machine, now claim their slot reliably. Before, a worker that took more than about 4 seconds to start could lose its slot and exit without a trace, leaving its run stuck as running. A worker that misses the longer start-up window is now refused with a recorded reason.","Stopping all of an agent's background processes now always finishes (from @xenosystem/agent-sdk 0.10.14)."],"0.5.72":['When no approval screen is available and the agent asks for permission in a plain terminal, typing "y" now approves. Before, every answer was recorded as a denial. For a command asking for extra access, the question now lists exactly what it wants and why. Uses @xenosystem/agent-sdk 0.10.13.'],"0.5.71":["Approving or rejecting an agent session's permission request in the Control Room now takes effect. Before, the session ignored the answer and kept waiting until it was stopped.","Control Room approvals and the SDK's built-in approval screens show a command's exact extra access and its reason, the same as the terminal prompt. Uses @xenosystem/agent-sdk 0.10.12."],"0.5.70":['When a command asks for access beyond its sandbox (network or extra folders), the approval prompt lists exactly what it wants and the reason it gave. It offers "Yes, for this call only" instead of "always", because an elevated command needs your approval every time. Uses @xenosystem/agent-sdk 0.10.11.'],"0.5.69":[`The agent can run a command in a specific directory, or through a specific shell (bash, sh, powershell, pwsh or cmd), for that one call, without moving the session's directory. The tool call line shows both, e.g. "npm test (in packages/app, via pwsh)".`,'Approving a command "always" covers only the directory and shell it was approved in, and the approval prompt names both.',"Requires @xenosystem/agent-sdk 0.10.10."],"0.5.68":["New: `xeno ctx-viz --audit` reports tools that are defined but registered by no lane, defined twice, or pointed at by an alias that goes nowhere. Run it from a CLI checkout; it exits 1 when it finds anything.",'Saving artifacts and other local records no longer fails intermittently on Windows with "EPERM: operation not permitted, rename" when another program briefly holds the file.',"Requires @xenosystem/agent-sdk 0.10.9."],"0.5.67":["Auto permission mode no longer asks before ElfAnalyze or ToolSearch, which default mode allows without asking.","The permission audit log labels every tool with the same risk level shown everywhere else.","New generated references: docs/TOOL_CATALOGUE.md (every tool per chat/run/ACP lane) and docs/TOOL_MAPPING.md (the permission decision per mode, how the terminal shows it, and its tests).","Requires @xenosystem/agent-sdk 0.10.8."],"0.5.66":["When a goal token budget runs out, the message now says how many tokens are left and how many the next request needs.",'A goal run no longer fails with "Ownership lease expired" when the process briefly stalls; the session keeps its lease as long as nobody else took it.',"Requires @xenosystem/agent-sdk 0.10.7."],"0.5.65":["Goal token limits now work on the XENO cloud route as a SOFT budget: each request's output is capped to what is left, measured usage is charged, and the goal stops once the limit is spent. One request may overshoot slightly, and the overshoot is recorded.","Local xeno-rt keeps its exact, hard limit. /goal status, xeno run and the chat notice say which kind of limit applies.","Requires @xenosystem/agent-sdk 0.10.5."],"0.5.64":["Removed the direct OpenAI Responses lane for bounded goals that 0.5.63 added. Token-limited goals run on local xeno-rt; other lanes refuse bounded work before inference, as in 0.5.62.","Background runs still refuse inline --api-key arguments, so a credential never reaches a worker's process arguments."],"0.5.63":["Bounded CLI goals can now use the official OpenAI Responses endpoint through an explicit OpenAI base URL and API key. Exact input counting, capped output and durable settlement share the same goal allowance as local xeno-rt.","The Responses lane refuses mutable remote image URLs, invalid counts and unsupported hosts before inference. It is fixture-qualified; live OpenAI and hosted/ACP quota qualification remain open.","Background runs refuse inline API keys before daemon handoff or worker spawn; use an environment or saved credential. Headless quota admission and execution now resolve the same provider endpoint."],"0.5.62":["Goals can use a durable total token limit in the local xeno-rt lane. The allowance survives restarts and is shared with local child agents; unsupported provider lanes refuse bounded work before inference.","TUI commands now execute in order, so renaming a session and immediately preparing a handoff cannot race their transcript and ownership changes.","Automatic goal continuation no longer inserts text into the command you are typing."],"0.5.61":["Goals can now carry an explicit total token limit with /goal set --max-tokens or xeno run --goal-max-tokens. The allowance survives restarts and is shared with local child agents.","Token-limited goals require a local xeno-rt runtime that advertises exact prompt counting and an enforced token ceiling. Other execution lanes report that requirement before starting work.","Automatic goal continuation no longer inserts text into a command you are typing. Human input received during a turn is queued for the next turn."],"0.5.60":[`The four canonical tools \u2014 Send, Receive, ListAgents, ListSessions \u2014 are now the CLI's own, bound to this session's peer runtime. 0.5.58 announced them and shipped the SDK's stock versions, which have no host: they recorded every message as coming from "unknown", so a delegated task's report had no sender to return to, and they forced every message to kind "task", so a note or a question ran a whole turn in the receiving session instead of being injected or asked. Both were silent. The name the release notes told the model to prefer was the one that got this wrong, while the legacy CoordinationSend it replaced got it right.`,"CoordinationSend and CoordinationQuery keep working, and are hidden again. They had been promoted back into the model's tool list beside their own canonical names, so one capability was offered twice.","ListAgents and ListSessions exist for the first time. They answer different questions on purpose \u2014 who you can send to, versus what is running where.","Sending now writes a Sent to row whoever sends. It was rendered only by the /peers command, so a human saw it and the model did not \u2014 the same asymmetry 0.5.59 fixed for arriving messages, in the other direction."],"0.5.59":["Inbound messages from other sessions now land as durable transcript rows on the live path: Received from, including a task waiting until idle and a held message with /peers accept, not a notice that scrolls away."],"0.5.58":["Unified agent architecture: sub-agents are full sessions, docked under the main-agent in the panel beneath the input box or detached as their own window \u2014 one engine, two presentations.","Messages between sessions are now first-class transcript rows in both directions: Sent to / Received from with the message visible, not a transient notice that scrolled away.","Wire vocabulary: the model gets four canonical tools \u2014 Send, Receive, ListAgents, ListSessions. CoordinationSend/CoordinationQuery keep working as hidden aliases.","Picks up SDK 0.10.0, which ships the canonical wire vocabulary and the alias layer."],"0.5.57":["Reliability pass from the goal-reconciliation: one shared projection now turns runtime events into assistant text (run turns and host-delegated branches used to keep separate copies, the class of bug where a tool payload renders as chat text).","Provider cockpit hardening: the host's durable conversation binding is validated before any mode or scope change, a mismatched host can no longer receive your project as a side effect, and the active provider lane is re-read every turn so a selection changed in another window takes effect immediately.","Tool start/end events are now driven by the interface contract's own vocabulary (phase, call id, success) instead of re-parsing raw type strings.","Release plumbing: the packed CLI manifest now records the publishable SDK version rather than the local build reference, and the security-boundary audit resolves file: SDK links through the installed package."],"0.5.56":["Independent sessions can now delegate to each other, the way Claude Code's SendMessage works: /rename names this session (shown on the input border), /peers lists every XENO Agent session on this machine, and /message <session> <task> hands it work that runs INSIDE that session with its own workspace and permissions; the result comes back here automatically.","The model has the same two primitives as the Interface - CoordinationQuery and CoordinationSend - so 'ask my DB - PLUGIN session to audit the auth flow' works in plain language. Delivery and completion are separate states; a task left running by a crashed session is marked recovery-required and never re-run.","Picks up SDK 0.9.39: the durable peer store behind this, a strict /rename commit (a failed disk write is a failed rename), and permission classification of the two coordination tools.","Typing a slash command that takes an argument ghosts its placeholder after the cursor, e.g. /rename [name].","Rendered artifacts, the way Claude Code's Artifact tool works: the model writes an HTML page and publishes it with the Artifact tool; the page appears as a link tray under the status bar (ctrl+] opens it) and is served from a private loopback viewer under a sandboxing CSP. Comments left on the page come back into the conversation as turns, and republishing the same artifact_id keeps the link.","Two homes, your choice: local is private to this machine and needs no account; home cloud (or /artifacts promote <id>) hosts the same revision on your XENO account at xenostudio.ai/a/<id>, private until /artifacts share <id> turns link sharing on. Hosted comments reach the session the same way local ones do."],"0.5.55":["Updated to SDK 0.9.38: app-server retries and permission responses enforce current tenant, workspace, and connection authority.","Fixed standalone startup by bundling the web-context client with the CLI.","Qualified context recovery, schemas, scheduling, subagents, skills, and app-server regression checks on Windows and Linux."],"0.5.54":["Picks up SDK 0.9.37, which corrects the root cause published in 0.9.36: the Linux install failure came from lockfile metadata, not from the dependency itself.","The 0.9.36 fix was correct and is retained; only its explanation was wrong, and a wrong cause is worse than none because the next person reasons from it.","Fixes a crash where a second CLI session in the same workspace killed the first one: listing schedules took a cross-process mutation lock, and the resulting error came from a background timer with no catch, which terminates the process."],"0.5.53":["Picks up SDK 0.9.36: a Windows-only native addon was a hard dependency, so `npm ci` failed outright on Linux - the SDK could not be installed there at all.","The addon is now optional and loaded lazily, which is what its call sites already assumed. Found by running the full suite on a real Linux filesystem rather than a mounted Windows drive."],"0.5.52":["Picks up SDK 0.9.35: a model the gateway cannot route was classified as a retryable server error, so a permanently wrong model id would be retried on a backoff loop forever.","A model that is temporarily unavailable stays retryable, so only the unroutable case changed. Found by a live provider conformance run against the XENO gateway."],"0.5.51":["Picks up SDK 0.9.34, which fixes provider error classification: a bad API key returning HTTP 400 was reported as a missing model capability rather than an authentication failure.","That told you your model lacked a feature when your key was simply wrong. Found by a live provider canary - offline tests prove what we send, never how we read what comes back."],"0.5.50":["Picks up SDK 0.9.33, which fixes a permission-rule wildcard that could span a carriage return: Bash(command:git*) matched 'git status\\rrm -rf /', so a prefix rule an operator wrote as a constraint could authorize a composed command.","On a terminal a carriage return returns the cursor to column zero, so an approval preview could display one command while the shell received a second one. A single * now stops at every line terminator and ** remains strictly broader."],"0.5.49":["Picks up SDK 0.9.32, which fixes a single-writer violation: a live session owner whose heartbeat stalled could be treated as stale and have its lock taken by a second writer.","A long tool call, a paused debugger or a saturated event loop no longer risks losing session ownership; a genuinely dead owner is still reclaimed immediately."],"0.5.48":["xeno handoff status gains --since-revision and --wait-ms: a caller passes the revision it already saw and the command returns when the session actually moves, instead of re-reading the whole session in a loop.","A wait that reaches its deadline exits 2 rather than 1, so an unchanged session reads as a retryable observation rather than a failure."],"0.5.47":["xeno sessions show gains --history and --cursor: recent transcript activity is read in a bounded window with a continuation cursor, instead of loading an entire transcript to display the last few entries.","New xeno agents wait <run-ids...> waits for the first of several background runs to reach a terminal state, or every run with --all. A deadline exits 2 rather than 1, so a caller can tell a timeout from a failure.","New xeno mcp resource-templates lists parameterized resources a connected MCP server offers; servers without template support are unaffected.","AskUser questions can now be cancelled, so an unanswered question no longer holds a turn open indefinitely (via SDK 0.9.31)."],"0.5.46":["Sessions can be branched: xeno sessions fork <id> creates a new session from an existing one without changing the original, carrying its transcript history and linking back to its parent, so both lines of work stay resumable.","Sessions can be titled, pinned and archived: xeno sessions title, pin and archive. Pinned sessions lead every listing regardless of activity, and archiving retains the transcript rather than deleting it.","xeno sessions list gains --archived, and shows titles and pin state inline."],"0.5.45":["The top-level xeno ctx-viz command now exposes the same bounded live tool inventory as the interactive TUI, with cursor paging and permission-safe metadata.","Inventory output clearly separates registered tools from request-loaded schemas and never grants execution authority."],"0.5.44":["File tools now complete reliably in standalone and packaged CLI processes, including guarded Edit and Write results after permission approval.","Durable interrupted-session recovery now preserves receipt-before-status crash ordering and requires explicit respawn for fresh input.","Worker stop, lease revocation, permission approval, workflow recovery, and goal-budget controls are qualified through the unsigned Windows candidate package.","Synced Agent SDK 0.9.28 with the awaited tool-operation liveness repair and recovery contracts."],"0.5.43":["Provider-native Codex and Claude continuations can be attached from the XENO provider cockpit without replacing the XENO TUI; exact provider session identity, workspace, and ownership survive detach, reattach, and Interface handoff.","The native terminal path mirrors user messages into the owning graphical conversation and keeps XENO application system instructions out of provider-visible chat text.","Synced XENO ACP 0.2.13 and Agent Interface 0.1.23 after the earlier immutable candidates were published without moving their npm latest tags."],"0.5.42":["Durable Web Context operations now render the canonical typed evidence progress stream in human and NDJSON modes without inventing counters.","SIGINT and external abort request exactly one service-side cancellation and report whether the durable job reached a confirmed terminal state.","Synced Web Context 0.1.1, Agent SDK 0.9.25, and Agent Interface 0.1.22 for the negotiated ACP v2 evidence contract."],"0.5.41":["Durable compaction now flushes the recoverable session snapshot before mutating resident history, so repeated long-context cycles and crash recovery retain completed turns.","Chat and non-interactive run paths bind the real host parent-session identity before delegating, keeping nested work and results attached to the correct resumable conversation.","Execution handoff preserves writer fencing and live ownership across A-to-B-to-C resume while Loop continuation remains unbounded by default.","Synced the public Agent SDK 0.9.24 and Agent Interface 0.1.21 registry packages for the qualified Goal / Loop / Handoff contract."],"0.5.40":["Added durable Goal records with explicit criteria, milestones, delegated tasks, progress, steering, and evidence-gated completion.","Added distinct scheduled, development, and goal-continuation loops that are unbounded by default, persist every iteration, survive restart, and remain recoverable after an iteration failure.","Added live, heartbeat-backed execution handoff across resumed terminals with atomic A-to-B-to-C transfer and immediate source fencing; one-shot commands cannot impersonate a live owner.","Handoff now flushes and relinquishes the source session-writer lock before printing the resume command, so the target can resume the same transcript without either terminal deleting or rewriting the other's lock state.","Synced Agent SDK 0.9.23 and Agent Interface 0.1.20 for the shared Goal / Loop / Handoff runtime contract."],"0.5.39":["Added XENO Web Context search, fetch, render, map, crawl, extract, job wait/cancel/resume, and Browser handoff commands with canonical evidence metadata.","Preserved Chat and Agent session mode/workspace identity across CLI and Interface resume paths.","Synced Agent SDK 0.9.22 and Agent Interface 0.1.19 for the typed Web Context runtime event contract."],"0.5.38":["Corrective Agent Interface handoff: explicit Chat, Agent, and resume launch intent now wins over restored persisted desktop tabs after session hydration.","`xeno agent --interface` preserves the exact granted workspace even when the desktop has existing Chat history, while `xeno chat --interface` remains Chat-only with no project grant.","Synced the Agent Interface client and contract packages to the installable 0.1.18 release."],"0.5.37":["`xeno chat --interface` opens the canonical desktop surface as XENO Chat with Chat-only authority and no project grant.","`xeno agent --interface` opens the same surface as XENO Agent and grants the exact current local workspace.","Synced the Agent Interface client and contract packages to 0.1.16."],"0.5.36":["`xeno chat` and `xeno agent` now launch the same canonical XENO terminal interface while preserving their invoked identity: Chat is branded XENO CHAT and Agent is branded XENO AGENT.","Chat mode owns a private managed workspace and cannot be promoted to Agent authority by saved settings or `--mode`; Agent mode keeps the explicit local-workspace and full-capability contract.","Windows Terminal multiline paste remains one editable composer item and submits as one persisted user message, including fragmented bracketed-paste frames.","Synced the Agent Interface client and contract packages to 0.1.15 and the Agent SDK to 0.9.21."],"0.5.35":["The provider cockpit now exposes durable provider lanes, exact native attach and detach, explicit stop and reconcile controls, and persists whether each Agent session is Chat mode or Agent mode.","The status bar shows the active provider lane, and non-interactive provider, lane, attach, and reconcile commands expose the same control plane to scripts.","The local release gate now builds the native Windows XENO PTY before integration tests and typechecks the complete test surface from a clean checkout.","Synced the Agent Interface client and contract packages to 0.1.12 and the Agent SDK to 0.9.18."],"0.5.34":["Windows multiline-paste recovery now keys off the actual win32 runtime even when terminal TTY capability probing reports an inconclusive profile.","Input diagnostics now record the runtime platform, terminal profile, and stdin/stdout TTY state so real-terminal evidence explains which paste path ran."],"0.5.33":["Windows Terminal multiline paste now remains one editable composer message even when Windows omits bracketed-paste markers because virtual-terminal input is unavailable.","Real bracketed-paste frames still retain stateful fragmented-stream handling, and an ordinary Enter remains a submit after the short paste-boundary grace period.","Synced the Agent Interface client and contract packages to 0.1.11 and the Agent SDK to 0.9.17."],"0.5.32":["Recent-session state now stays inside XENO_AGENT_HOME and uses durable per-workspace updates, preventing Windows EPERM contention and lost concurrent session entries.","PowerShell command completion now drains the final stdout pipe data before settling, so successful commands cannot intermittently return empty output."],"0.5.31":["Windows Terminal bracketed-paste mode is now explicitly negotiated for the full composer lifetime, correcting 0.5.30's incomplete decoder-only repair.","Native TUI and external-editor handoffs release terminal paste mode before transfer and restore it only after XENO regains terminal ownership.","`--interface` now waits for an exact nonce-bound acknowledgement from the desktop renderer instead of reporting success when an older app merely spawned and ignored the resume request.","Managed finite operations can continue beyond the generic three-turn safety cap, recent-session writes are serialized across processes, and background commands receive privacy-safe semantic fallback labels."],"0.5.30":["Multiline terminal pastes now remain one editable composer message even when Windows Terminal fragments the bracketed-paste frame across multiple input chunks.","Complete bracketed-paste frames are handled before generic Escape sequences, and their terminal markers never leak into the submitted prompt."],"0.5.29":["ACP provider cockpit: resume durable Codex, Claude, and compatible provider lanes without replaying the XENO transcript into a new native session.","Attach, detach, reattach, stop, and reconcile native provider TUIs with one-writer ownership between the XENO TUI, Agent Interface, and provider terminal.","`--interface` handoff now preserves the selected conversation host binding and exact provider continuation identity.","Background work uses semantic task names, and continuation checkpoints retain the original objective instead of ending a live operation at an arbitrary automatic-turn boundary.","Synced Agent Interface client/contract to 0.1.8 and @xenosystem/agent-sdk to 0.9.14."],"0.5.28":["The root `xeno --help` output now exposes `--interface` and `--resume [id]`, so terminal-to-desktop session handoff is discoverable at the exact command surface where it is used."],"0.5.27":["Open the XENO Agent Interface from the terminal with `xeno --interface`, resuming an exact session ID or the latest session in the current workspace.","Long-running background commands now stay alive while active, preserve native PowerShell syntax, and display meaningful task names.","Short follow-through messages such as do it and proceed now retain implementation authority, while nested continuations preserve the original objective.","Synced @xenosystem/agent-sdk to 0.9.13."],"0.5.26":["Terminal bracketed paste & multi-line input: bracketed paste frames are cleanly decoded, collapsed into `[Pasted text #N +N lines]` tokens for large blocks, and submitted with full uncorrupted text without escape code dropouts.","Dynamic terminal reflow: turn receipts, turn dividers, and prompt bubbles adapt smoothly to window resize events without clipping."],"0.5.25":["Interactive `/status`, `/config`, `/usage`, `/stats`, `/settings` multi-tab modal with live search, keyboard cycling, and instant ~/.xeno/config.json persistence.","Live 52-week session activity heatmap, longest/current streak metrics, active days summary, lifetime token metrics, and favorite model analytics.","Real-time git workspace analytics including active branch, ahead/behind counts, working tree diff additions/deletions, and live turn API elapsed times.","Turn receipt visual polish with right-margin padding and formatted recap indentation.","Interactive `/handoff` command: switch seamlessly between specialist agents with prompt context and intent transfer.","Zero-config `.claude/agents/*.md` & `.xeno/agents/*.md` discovery with level-ordered priority shadowing.","Host mid-turn steering (`turn.steer`) and subagent wire payload artifacts integration.","Synced @xenosystem/agent-sdk to 0.9.12 with enhanced offline grace monetization validation.","xeno-rt: resolved Qwen 3.8 / 3.5 MTP NextN architecture prefixes and prevented layer 32 recurrent tensor probe failure."],"0.5.24":["Published with exact matching CLI_VERSION literal, guarded by verify:version in CI.","Synced @xenosystem/agent-sdk to 0.9.11, pulling model-aware context budgets from live gateway `/v1/models` catalog.","`/import` now immediately triggers context reconstruction turns rather than pausing at the input prompt."],"0.5.23":["Model-aware context budget: queries gateway `/v1/models` catalog for authoritative `context_window` limits.","Context compaction request byte budget scaled to prevent false refusals on large toolsets."],"0.5.22":["`/context` divided by a hardcoded 200,000 regardless of which model you are on. That figure is XENO's window and nobody else's: on a 128,000-token OpenAI model the gauge read about 12% where the truth was 19%, and near the limit it said \"Context is healthy\" with compaction imminent; on Google's 1,000,000-token window it pegged at 100% from a fifth of the way in and warned permanently. It now divides by the budget the SDK actually resolved for the run.","The gauge also says how well it knows that number. A configured budget is exact and prints a plain percentage; a provider profile is one window for every model that provider serves, so it prints `~62%` and labels itself approximate. Before any turn has reported, it says the 200,000 is an assumption rather than presenting it as fact.","The numerator was always right and is unchanged: it sums the messages currently in context, so it falls when a compaction drops them. Only the denominator was asserted rather than resolved."],"0.5.21":["Security: undici 6.27.0 -> 6.28.0, closing a cookie-injection advisory. This repo had 12 open alerts and this was the ONLY one that reaches shipped code \u2014 the five rated HIGH are all build and test tooling. Fixing by severity rank would have addressed the wrong thing first.","Worktree cleanup could delete THROUGH a junction. That is the failure that destroyed two repositories on 2026-08-03: on Windows a recursive delete follows a junction and removes the target, and npm creates one for every file: dependency. Cleanup now clears the reparse point itself and never the thing it points at.","Worktree cleanup had also decayed into a no-op \u2014 its filter excluded every orphan it existed to remove, so it ran, reported success, and cleaned nothing. And a reparse-point scan that hits its cap now REFUSES rather than returning a short list, because a truncated scan that looks complete is how the delete above becomes safe-looking.","The control-plane `list()` was not a read: it wrote once per stale record, every time anything listed runs. Listing is now free of side effects.","`/import` brings a session from another agent CLI into XENO and continues it \u2014 including agy stores, where the obvious store turned out not to be the best source. `--imported` shows what is on disk and says plainly that it persists. The source transcript is never touched, and that is enforced rather than intended.","Delegated branches now run on the Agent host under XENO_AGENT_ATTACH, report tool progress while they work, and the CLI reads the HOST's audit rather than only its own. Previously a host-routed branch was silent until it finished, and a refusal blamed a missing stream that in fact existed.","`xeno host status` now reports WHICH lanes the host offers and why a blocked one is blocked \u2014 including whose environment the blockage is about, which was the part that made the old message useless.","Pinned to @xenosystem/agent-sdk 0.9.10. The pin had been two releases stale, so work that shipped in 0.9.9 reached nobody. 0.9.10 also reports how full an agent's context is: turn.completed carries the RESIDENT token count, not the cumulative billing counter, and context.pressure arrives after every model response. The obvious field re-adds the whole prompt each turn \u2014 measured live, three one-word turns reported 3049, 6106 then 9171 tokens while the context grew by about eight.","Budget accounting no longer reads the entire run store when no budget cap is configured."],"0.5.20":["Pinned to @xenosystem/agent-sdk 0.9.8. The SDK's ownership policy still labelled this CLI by a scope retired in 8363d30c, which had failed the release smoke on every run since 2026-08-13 \u2014 the mismatch was never in this repo, so the fix was a repin rather than a workaround.","The release smoke now derives how strict it should be from the release trust policy: while no signing identity is approved it holds the engineering bar, and it tightens by itself the moment one lands. It previously demanded a signature no ordinary CI run could produce, and had failed for long enough to read as background noise.","First test coverage of the native manifest signing path, which had never executed once. Signer and verifier each carry their own copy of the canonical-JSON serializer and cannot import each other, so a drift as small as key ordering would have invalidated every release signature \u2014 and would have surfaced on release day, looking like a key problem.","Windows: temporary-directory cleanup no longer loses a race with exiting child processes, and the certification matrix checks out correctly on Windows ARM. `force: true` suppresses ENOENT, not EPERM, so the previous cleanup looked defensive and was not.","Groundwork for interactive Ctrl+C on Windows: the native addon can now raise a real console interrupt. Writing 0x03 into a ConPTY does not raise a signal, which is why Ctrl+C has never worked there. NOT yet wired \u2014 the console attach succeeds and the event is raised, and a ConPTY client still does not observe it."],"0.5.19":["The CLI did nothing at all on Linux and macOS. Its entry point did not resolve symlinks, so every npx and global install ran the wrong path and exited silently \u2014 the install looked successful and the binary did nothing. Fixed.","Agent permission decisions now reach an actual human on both rails, rather than being resolved without one.","A remote run that is read-only now says so, instead of failing silently and leaving you to work out why nothing changed.","The version the binary REPORTS is now bound to the version npm publishes, and a test enforces it. They had drifted: 0.5.18 was published as a package whose `--version` said 0.5.17.","\u26A0\uFE0F 0.5.18 exists on npm and was published from a branch that was never merged. It is superseded by this release, which is cut from `main`. If you installed 0.5.18, upgrade."],"0.5.17":["The CLI now ships as @xenosystem/agent-cli. The former name @xeno-corporation/xeno-agent-cli is deprecated on npm and receives no further releases; the `xeno`, `xeno-agent` and `xeno-code` binaries are unchanged, so nothing in your shell or scripts has to change.","The exact SDK pin moves with it: the CLI is bound to @xenosystem/agent-sdk 0.8.12. 0.8.11 was never published under either name and cannot be \u2014 GitLab evaluates .gitlab-ci.yml as it exists at the tag, and tag sdk-v0.8.11 predates that pipeline.","This release cannot be installed until @xenosystem/agent-sdk 0.8.12 is live on the registry; the release pipeline fails closed on --require-dependencies-published until it is."],"0.5.16":["Windows 11 ARM64 containment certification now performs architecture-neutral MXC host preparation with the reviewed x64 helper through operating-system emulation while keeping the contained runtime native ARM64.","The CLI is bound exactly to SDK 0.8.11, whose host-preparation reports distinguish the host architecture from the reviewed setup-helper architecture and retain timeout diagnostics."],"0.5.15":["macOS and Linux standalone diagnostics now report their verified POSIX process-group lifecycle independently from the stronger process-hardened sandbox level, preserving truthful security status while certifying full-tree cancellation, timeout, and shutdown behavior.","Generated Harbor benchmark and audit workspaces are excluded from source control, keeping Windows ARM64 checkouts below platform path limits and removing 9,938 generated artifacts from release candidates."],"0.5.14":["Windows 11 24H2 containment admission now uses the authoritative non-server NT client build floor instead of rejecting current Azure and GitHub Windows 11 images whose legacy registry ProductName still says Windows 10.","Windows Server remains fail-closed, pre-26100 clients remain ineligible, and both x64 and ARM64 host identities have regression coverage."],"0.5.13":["Hosted Windows x64 containment certification now fails closed unless the runner is Windows 11 24H2 or newer, the platform supported by Microsoft MXC, instead of treating Windows Server runner failures as product failures.","The certification matrix accepts a protected XENO_WINDOWS_X64_RUNNER label for an ephemeral Windows 11 x64 runner while keeping all other hosted platform rows unchanged.","Containment failure reports preserve bounded head-and-tail diagnostics through SDK 0.8.10 so the actionable trailing Win32 or MXC error is retained."],"0.5.12":["Windows MXC containment now launches its unrestricted host from the prepared system-drive temporary directory, outside directories whose DACLs are mutated by the contained policy, and certification captures official redacted MXC diagnostics.","Internal background session workers no longer start a competing global reconciler, preventing slower macOS hosts from quarantining a healthy turn between transcript append and checkpoint commit.","The interactive attach/input/stop smoke now follows the actual persisted inbox sequence and records worker logs on failure; the CLI is bound exactly to SDK 0.8.9."],"0.5.11":["Windows x64 containment certification now launches the MXC host and contained runtime with working-directory and temporary paths on the prepared system drive, matching split-drive GitHub runners.","The CLI is bound exactly to SDK 0.8.8, preserving the passing Linux, macOS, and Windows ARM64 conformance behavior while repairing Windows x64 ProcessContainer startup."],"0.5.10":["Linux containment certification now keeps disposable fixtures under the OS-private temporary mount instead of GitHub's workspace-projected runner directory, preserving the unlisted-filesystem boundary probe.","Windows certification retains the MXC-prepared system-drive fixture root required by hosted runners whose workspace and default temp directory use another volume."],"0.5.9":["Windows containment certification now creates its disposable fixtures on the MXC-prepared system drive, including hosted runners whose workspace and default temp directory live on another volume.","Standalone Windows certification now performs the same explicit host preparation and temporary-root binding as the native package matrix."],"0.5.8":["Native containment certification now compiles its macOS UI-policy probe against the stable libsystem_sandbox ABI without depending on private SDK headers.","Windows certification now distinguishes MXC's persistent per-policy DACL requirement from its explicit one-time host-preparation warnings."],"0.5.7":["The immutable CLI candidate now binds SDK 0.8.5 to the exact canonical Linux npm tarball bytes used by certification."],"0.5.6":["Windows containment certification now performs Microsoft MXC's explicit idempotent host preparation before AppContainer+DACL conformance.","macOS ARM64 certification now records behavioral Seatbelt evidence for pasteboard, WindowServer, LaunchServices, and HID isolation."],"0.5.5":["Native certification now resolves the SDK candidate artifact from the same workspace path on Bash and PowerShell runners.","SDK containment assets retain executable package modes on Linux and macOS, with a source regression check for every reviewed Unix binary."],"0.5.4":["Native engineering certification jobs now download the exact SDK tarball produced by the successful parent gate before installing dependencies.","The six-platform matrix remains source-bound to one immutable CLI tag and one immutable SDK candidate artifact."],"0.5.3":["Candidate packaging accepts both npm 11 array-form and npm 12 package-keyed JSON, with explicit diagnostics for malformed output.","Hosted SDK packaging now parses a bounded JSON file instead of relying on a large shell variable or an obsolete npm output shape."],"0.5.2":["Hosted certification now caps SDK declaration generation at two concurrent entry points and cleans declaration output in isolated bounded-memory workers.","SDK build subprocess failures now report their terminating signal or exit status instead of producing a silent hosted-run failure."],"0.5.1":["Hosted certification now builds the exact SDK candidate in bounded declaration groups, preventing parallel TypeScript declaration generation from exhausting GitHub-hosted runner resources.","Post-freeze readiness now distinguishes exact candidate tags verified at the candidate commit from collisions in release, registry, feed, and service namespaces."],"0.5.0":["Agent Profiles now provide enforceable Assistant, SWE, Reviewer, Writer, Research, Product, CI, DevOps, and Legal Research identities with bounded tools, permissions, skills, hooks, memory, isolation, and external-action authority.","The XENO Artifact Protocol adds durable plans, patches, diffs, reviews, screenshots, recordings, reports, provenance, approvals, and evidence relationships shared across local, hosted, and Hub workflows.","Secure Execution Contracts and capability leases now make filesystem, network, secret, process, device, browser, and external-action authority explicit and auditable.","Skills v2 adds standards-compatible SKILL.md discovery, progressive loading, bundled resources, invocation policy, version identity, and compatibility with XENO, .agents, and Claude skill locations.","MCP now supports current Streamable HTTP sessions and OAuth discovery while retaining compatible stdio and legacy SSE connections.","Browser, computer-use, hosted-agent, semantic-index, production-review, spec-planning, secure-sharing, and provider-onboarding surfaces are integrated through the shared platform contracts.","The retained TUI now presents stable grouped tool activity, live task and subagent status, candidate-bound edit previews, context-pressure and compaction state, and clearer turn completion receipts.","Six-product candidate certification now binds the SDK, XENO Use, XENO Browser, Agents API, CLI, and Hub to exact source identities, versions, tags, evidence, and protected release gates."],"0.4.45":["This transitional release is engineering-tested but not GA-certified: native PTY artifacts are unsigned and remain disabled by default until the Azure signing identity is approved; ordinary CLI and pipe-mode commands remain available.","App Server v2 now provides durable threads and turns, typed clients, permission ownership and expiry, bounded replay and backpressure, authenticated HTTP access, and additive v1 compatibility.","The terminal renderer now uses committed retained frames, bounded coalescing, one normal write per frame, a responsive 50-agent footer, accessibility modes, and a native terminal compatibility matrix.","Release certification now fails closed on six native architectures, platform and manifest signatures, reproducible package payloads, SBOMs, provenance attestations, independent approvals, npm OIDC publication, and public clean-install verification.","Long chat prompts now soft-wrap into a growing six-row composer with Unicode-safe editing, visual Up/Down navigation, file-panel parity, and a temporary XENO_INPUT_SOFT_WRAP=0 rollback switch.","Long-running model-authored shell commands now use managed operations: Ctrl+B promotes the same process, finite background work waits without model polling, and durable continuations resume exactly once after terminal output arrives.","ReadImage now uses Xeno's dependency-free owned raster codec for bounded PNG, BMP, Netpbm, and core-SVG previews; /processes and doctor expose task control, process-tree containment, operation-schema, and codec status.","Dynamic workflows now expose first-class run limits and terminal reducer summaries in run records and inspect JSON.","Background agent sessions now deliver durable completion, failure, stop, and request-keyed needs-input notifications to interactive parent chats and bounded headless runs without clobbering prompt drafts.","Workflow orchestration includes grouped phase/child progress, parent-chat completion notifications, WorkflowWait, /workflows drill-down, watch JSONL snapshots, and ultracode workflow prompts.","Workflow starts now support plan preview and exact-definition approval memory, scheduler ticks are serialized, and workflow lifecycle metrics are available through the OTel usage export.","Tool activity now uses semantic Update and Search labels, contextual line-numbered edit previews, expandable read/search/shell output, and accurate failure rendering.","Interactive chat now blocks repeated inspections and unrequested mutations on short questions, gives explicit research a larger typo-tolerant evidence budget, and reserves a tool-free final-answer turn when work limits are reached."],"0.4.44":["Markdown source links now render as clickable terminal links in supported terminals, with visible URLs preserved when links are disabled."],"0.4.43":["New background agents now appear in the footer immediately after launch, and the footer can show up to eight agent sessions."],"0.4.42":["Background agent footer rows now fit the common three-agent fanout without hiding the first agent on compact terminals.","Completed background agent sessions now close after BackgroundAgentJoin returns their result to the main agent."],"0.4.41":["Completed background agent footer rows now keep a fixed runtime instead of continuing to count upward."],"0.4.40":["One-shot background agent sessions now mark done after returning their result, while user-follow-up sessions stay idle for continued chat."],"0.4.39":["Background agent session activity now uses concise status labels like Thinking instead of showing the full task prompt."],"0.4.38":["Opened background agent sessions now show their own session activity line while keeping main-agent tool progress isolated."],"0.4.37":["Opened background agent sessions no longer show the main agent's active tool progress line."],"0.4.36":["Opened background agent sessions now render the same main-chat transcript surface for user messages, assistant messages, tool calls, and tool results."],"0.4.35":["Background agent session chat now includes tool calls and tool results in its visible history."],"0.4.34":["Opening a footer background agent now switches the main chat surface into that agent session instead of showing a separate info panel.","Child-session input now queues messages to that agent while Esc returns to the main chat."],"0.4.33":["Background agent footer rows now repaint immediately during active turns.","Remembered background-agent approvals now apply to later background-agent launches."],"0.4.32":["Startup release-note hints now sit directly under the note text and render dimmed in the side panel."],"0.4.31":["Unread release notes now render beside the startup XENO AGENT header on wide terminals."],"0.4.30":["BackgroundAgentList now only reports current-chat footer sessions so old workspace agents do not hide missing new deployments."],"0.4.29":["Background agent footer markers now use filled and empty squares.","Opening a background agent from the footer now shows its session chat with transcript and message input."],"0.4.28":["First-run default model is now gpt-5.5 while saved user model choices are preserved.","Number keys in the model picker now type into search instead of selecting by index.","Model selections made with /model now persist as the user's saved default."],"0.4.27":["Background agent footer rows are now scoped to the current chat session."],"0.4.26":["Background agent rows now sit below the status line and inherit the live chat model."],"0.4.25":["Legacy BackgroundAgent calls now create footer-visible interactive background sessions."],"0.4.24":["Model picker support now has a `xeno models --json` command, share export proof, and GitHub review artifact contracts."],"0.4.23":["Model picker and /model listings now refresh Xeno API model availability before switching."],"0.4.22":["Hook review now shows command-hook hashes and supports trust, disable, and explain commands.","Expanded lifecycle hooks now cover permission decisions, stop failures, and delegated subagent start/stop events.","Set XENO_STATUS_LINE_COMMAND to replace the TUI status line with a cached command output.","Rewind now saves the abandoned conversation branch as a manual checkpoint before restoring.","Interactive chat now supports Ctrl+R history search, Ctrl+G prompt editing, /vim input mode, and /copy answer/block/diff clipboard copy.","/theme is now a discoverable alias for /color with user/project custom theme files, and /processes stop-all stops running background tasks."],"0.4.20":["Shell completions now include the current control-plane commands, flags, statuses, scopes, and usage groups.","The local app-server browser page now includes prompt and process controls on top of advanced JSON-RPC.","Published CLI and SDK packages now include GitHub repository metadata.","Docs now call out the temporary GitHub Actions startup_failure blocker while local gates remain authoritative."],"0.1.0":["Persistent shell sessions now preserve cwd and shell state across Bash calls.","Delegated planner, explorer, executor, and reviewer branches now support staged and parallel policies.","MCP now supports stdio and SSE transports, prompt discovery, resource reads, and live tool sync.","Notebook, ask-user, and memory tools are available in the shared agent runtime.","CLI operator workflows now include doctor, bug-report, config editing, cost summaries, and runtime inspection."]};function Lme(e=Re){return hsn[e]??[]}function gsn(e=Re){let t=Pt().lastReleaseNotesSeen;return Lme(e).length>0&&t!==e}function mx(e=Re){Do({lastReleaseNotesSeen:e})}function YX(e){let t=e??Re,n=Lme(t);return n.length===0?`No release notes available for version ${t}.`:[`Release notes for version ${t}`,"",...n.map(r=>`- ${r}`)].join(`
4397
4397
  `)}var wsn=4;function KKe(e=Re){if(!gsn(e))return;let t=Lme(e),n=t.slice(0,wsn),r=t.length-n.length;return[`What's new in XENO AGENT v${e}`,...n.map(o=>`- ${o}`),r>0?`...and ${r} more. Run \`xeno release-notes\` to see everything.`:"Run `xeno release-notes` to view this again."].join(`
4398
4398
  `)}jt();Tc();qi();hO();import{spawn as Asn}from"node:child_process";import{setTimeout as Fme}from"node:timers/promises";hA();import{resolve as ZX}from"node:path";var YKe="cancel",Bc={name:"WorkflowCancel",command:`workflows ${YKe}`,nativeVerb:YKe,description:"Request cancellation of a local workflow and stop its child work. Acceptance is not confirmed termination. Inspect or wait on the same workflow while cancellation is pending; do not start replacement work until cancellation is confirmed.",argument:{name:"run_id",type:"string",required:!0,description:"Explicit workflow run ID; never inferred from the selected UI row."},mode:"always",requiresDisplay:!1,reversibility:"irreversible",parity:"exposed",readingTools:["WorkflowInspect","WorkflowWait"],readingCommand:"workflows inspect <run-id> --json",replyFields:{accepted:"True only after the durable cancellation request was read back. False means no workflow target was found.",cancelled:"True only when readback confirms cancellation and no child termination remains pending. False means cancellation is not confirmed, not that work is still running.",pending:"True when the request was accepted but termination or readback remains incomplete. Re-read the same workflow; this is not a new request.",operationId:"Stable cancellation operation ID, or null when no request was accepted. Repeated cancellation requests retain this ID.",run:"Observed cancellation snapshot (workflowRunId, workflowName, status, updatedAt, cancellation), or null if absent/unconfirmed. The native CLI retains its existing full run record; use WorkflowInspect for child details.",warning:"Present when accepted cancellation could not be confirmed or processed. It never grants permission to restart work."},cancellationFields:{schemaVersion:"Cancellation metadata schema version, currently 1.",operationId:"The same durable cancellation operation ID as the top-level reply.",workflowRunId:"Exact workflow targeted by this request.",requestedAt:"UTC timestamp of the durably published request.",pendingChildCount:"Children whose termination remains unconfirmed; absent before the first reconciliation pass.",lastError:"Optional bounded diagnostic about an unconfirmed child; absence does not independently prove completion.",completedAt:"Present only after child termination is confirmed.",notificationEnqueuedAt:"Present after the workflow-cancelled notification was persisted; it does not mean the parent consumed it."}};function hx(e,t){let n=e.run?.workflowName??t;return e.accepted?e.cancelled?`Cancelled ${n}`:`Cancellation pending for ${n}; inspect operation ${e.operationId}`:`Workflow run not found: ${t}`}function ZKe(e){let t=e.run;return{...e,run:t?{workflowRunId:t.workflowRunId,workflowName:t.workflowName,status:t.status,updatedAt:t.updatedAt,cancellation:t.cancellation}:null}}var eYe=()=>[Bc.description,`Mode: ${Bc.mode}; requiresDisplay: ${Bc.requiresDisplay}; reversibility: ${Bc.reversibility}. Read back with ${Bc.readingTools.join(" or ")}.`,"Returns JSON: "+Object.entries(Bc.replyFields).map(([e,t])=>`${e}: ${t}`).join(" "),"Cancellation progress: "+Object.entries(Bc.cancellationFields).map(([e,t])=>`${e}: ${t}`).join(" ")].join(" ");function ec(e){process.stdout.write(JSON.stringify(e,null,2)+`
4399
4399
  `)}function ysn(e,t){if(t){ec(e);return}if(e.ok&&e.definition){process.stdout.write(`Workflow valid: ${e.definition.name}