@xenosystem/agent-sdk 0.10.11 → 0.10.13

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.
@@ -48,7 +48,7 @@ ${this.stringify(e.data)}
48
48
  `)+`
49
49
  `;await k(this.transcriptPath,a);let l=this.buildMarkdownDocument(o,"session store");if(await k(this.markdownPath,l),!this.workspaceMirrorDisabled){let c=await this.resolveWorkspaceMarkdownPath();if(c)try{let u=this.buildMarkdownDocument(o,"workspace mirror");await k(c,u)}catch(u){this.workspaceMirrorDisabled=!0,B("Transcript workspace mirror disabled",u)}}}async truncateAfterMessageCount(e){let t=await x(this.transcriptPath);if(!t)return;let r=Z(t),s=Math.max(0,e),i=0,o=[];for(let c of r){if(c.type==="user_message"||c.type==="assistant_message"){if(i>=s)break;i+=1}o.push(c)}let a=o.length>0?o.map(c=>JSON.stringify(c)).join(`
50
50
  `)+`
51
- `:"";await k(this.transcriptPath,a);let l=this.buildMarkdownDocument(o,"session store");if(await k(this.markdownPath,l),!this.workspaceMirrorDisabled){let c=await this.resolveWorkspaceMarkdownPath();if(c)try{let u=this.buildMarkdownDocument(o,"workspace mirror");await k(c,u)}catch(u){this.workspaceMirrorDisabled=!0,B("Transcript workspace mirror disabled",u)}}}getSequence(){return this.sequence}async initialize(){try{let e=await x(this.transcriptPath);if(!e){this.sequence=0;return}let t=Z(e);if(t.length===0){this.sequence=0;return}let r=t[t.length-1];this.sequence=r.sequence+1}catch(e){let t=e instanceof Error?e.message:String(e);B(`Transcript initialization warning: ${t}. Starting with empty transcript.`),this.sequence=0}}async flush(){await this.writeQueue}};var ee=_(require("path"),1),lt=require("crypto"),ut=require("fs/promises");var qt={View:"Read",Replace:"Write",GlobTool:"Glob",GrepTool:"Grep",SQLiteAnalyze:"SqliteAnalyze",ReadNotebook:"NotebookRead",NotebookEditCell:"NotebookEdit",CoordinationSend:"Send",CoordinationQuery:"Receive"};function fe(n){return qt[n]??n}var I=class{sessionDir;checkpointsDir;autoInterval;lastCheckpointMessageCount=0;constructor(e,t){this.sessionDir=e,this.checkpointsDir=ee.join(e,"checkpoints"),this.autoInterval=t?.autoInterval??10}async initialize(){let e=await this.list();e.length>0&&(this.lastCheckpointMessageCount=e[0].messageCount)}async create(e){await N(this.checkpointsDir);let t=(0,lt.randomUUID)(),r={id:t,name:e.description,trigger:e.trigger,createdAt:new Date().toISOString(),messageCount:e.messages.length,tokenCount:this.estimateTokens(e.messages)},s={info:r,messages:e.messages},i=ee.join(this.checkpointsDir,`${t}.json`);return await k(i,JSON.stringify(s,null,2)),this.lastCheckpointMessageCount=e.messages.length,r}async list(){let e=await Ze(this.checkpointsDir,/\.json$/),t=[];for(let r of e){let s=await x(r);if(s){let i=E(s,null);if(i){let o=await(0,ut.stat)(r);t.push({info:i.info,modifiedAtMs:o.mtimeMs})}}}return t.sort((r,s)=>new Date(s.info.createdAt).getTime()-new Date(r.info.createdAt).getTime()||s.modifiedAtMs-r.modifiedAtMs).map(({info:r})=>r)}async restore(e){let t=ee.join(this.checkpointsDir,`${e}.json`),r;try{r=await x(t)}catch(i){let o=i instanceof Error?i.message:String(i);throw new Error(`Failed to read checkpoint ${e}: ${o}`)}if(!r)throw new Error(`Checkpoint not found: ${e} (path: ${t})`);let s=E(r,null);if(!s)throw new Error(`Invalid checkpoint data for ${e}: JSON parse failed`);if(!s.messages||!Array.isArray(s.messages))throw new Error(`Invalid checkpoint data for ${e}: missing or invalid messages array`);if(!s.info)throw new Error(`Invalid checkpoint data for ${e}: missing info object`);return{messages:s.messages,info:s.info}}shouldAutoCheckpoint(e){return e-this.lastCheckpointMessageCount>=this.autoInterval}static isDangerousOperation(e,t){if(e=fe(e),e==="Write")return!0;if(e==="Bash"){let s=t.command?.toLowerCase()||"";return["rm ","del ","git push","git reset","drop ","truncate"].some(o=>s.includes(o))}return!1}async delete(e){let t=ee.join(this.checkpointsDir,`${e}.json`);await $(t)}estimateTokens(e){let t=0;for(let r of e)if(typeof r.content=="string")t+=Math.ceil(r.content.length/4);else if(Array.isArray(r.content))for(let s of r.content)"text"in s&&(t+=Math.ceil(s.text.length/4));return t}};var F=_(require("path"),1),$e=_(require("os"),1),j=_(require("fs"),1);var Jt=Symbol.for("@xenosystem/agent-sdk/shutdown-registry"),Vt=globalThis,Oe=Vt[Jt]??={cleanups:new Set,exitHandlerRegistered:!1,signalHandlersInstalled:!1},Ne=Oe.cleanups;function zt(){for(let n of Ne)try{n()}catch{}}function dt(n){return Ne.add(n),!Oe.exitHandlerRegistered&&typeof process<"u"&&typeof process.on=="function"&&(Oe.exitHandlerRegistered=!0,process.on("exit",zt)),()=>{Ne.delete(n)}}var pt="0.10.11";var Xt=1e4,Kt=6e4,Yt="session.lock",Qt="lock.json",Q=new Map;function Le(n,e){return n!=null&&n.pid===e.pid&&n.hostname===e.hostname&&n.processStartedAt===e.processStartedAt&&n.acquiredAt===e.acquiredAt}function Zt(){for(let[n,e]of Q)try{let t=E(j.readFileSync(n,"utf8"),null);Le(t,e)&&j.unlinkSync(n)}catch{}Q.clear()}dt(Zt);var U=class n{sessionDir;lockPath;legacyLockPath;sessionId;heartbeatTimer;acquiredOwner;constructor(e){this.sessionDir=e,this.lockPath=F.join(e,Yt),this.legacyLockPath=F.join(e,Qt),this.sessionId=F.basename(e)}async acquire(){let e=new Date().toISOString(),t={schemaVersion:1,name:`session:${this.sessionId}`,sessionId:this.sessionId,pid:process.pid,hostname:$e.hostname(),processStartedAt:new Date(Date.now()-Math.floor(process.uptime()*1e3)).toISOString(),version:pt,acquiredAt:e,updatedAt:e,heartbeat:e},r=F.dirname(this.lockPath);await j.promises.mkdir(r,{recursive:!0});let s=await this.findExistingLockPath();if(s){if(!await this.isStalePath(s)){let o=await this.readLockAt(s);throw new Error(`Session ${this.sessionId} is already locked by PID ${o?.pid} on ${o?.hostname}`)}await $(s)}try{await j.promises.writeFile(this.lockPath,JSON.stringify(t,null,2),{flag:"wx",encoding:"utf-8"}),this.acquiredOwner=t,Q.set(this.lockPath,t)}catch(i){if(i.code==="EEXIST"){if(!await this.isStalePath(this.lockPath)){let l=await this.readLockAt(this.lockPath);throw new Error(`Session ${this.sessionId} is already locked by PID ${l?.pid} on ${l?.hostname}`)}await $(this.lockPath);try{await j.promises.writeFile(this.lockPath,JSON.stringify(t,null,2),{flag:"wx",encoding:"utf-8"})}catch(l){throw l.code==="EEXIST"?new Error(`Session ${this.sessionId} lock was acquired by another process during stale recovery`):l}this.acquiredOwner=t,Q.set(this.lockPath,t)}else throw i}}async release(){this.stopHeartbeat();let e=this.acquiredOwner;if(this.acquiredOwner=void 0,!e)return;Q.delete(this.lockPath);let t=await this.readLockAt(this.lockPath);Le(t,e)&&await $(this.lockPath)}async isLocked(){let e=await this.findExistingLockPath();return e?!await this.isStalePath(e):!1}async isStale(){let e=await this.findExistingLockPath();return e?this.isStalePath(e):!1}async isStalePath(e){let t=await this.readLockAt(e);if(!t)return!1;if(t.hostname===$e.hostname())try{return process.kill(t.pid,0),!1}catch(i){return i.code!=="EPERM"}let r=new Date(t.heartbeat).getTime();return Date.now()-r>Kt}startHeartbeat(e=Xt){this.heartbeatTimer&&this.stopHeartbeat(),this.heartbeatTimer=setInterval(async()=>{try{await this.updateHeartbeat()}catch(t){let r=t instanceof Error?t.message:String(t);if(t?.code==="ENOENT"){W("SessionLock: Session directory removed, stopping heartbeat"),this.stopHeartbeat();return}W(`SessionLock: Failed to update heartbeat: ${r}`)}},e),this.heartbeatTimer.unref()}stopHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=void 0)}async updateHeartbeat(){let e=await this.readLockAt(this.lockPath),t=this.acquiredOwner;if(!(!e||!t)){if(!Le(e,t)){this.acquiredOwner=void 0,Q.delete(this.lockPath),this.stopHeartbeat();return}e.heartbeat=new Date().toISOString(),e.updatedAt=e.heartbeat,await k(this.lockPath,JSON.stringify(e,null,2))}}async readLock(){let e=await this.findExistingLockPath();return e?this.readLockAt(e):null}async readLockAt(e){let t=await x(e);return t?E(t,null):null}async findExistingLockPath(){return await x(this.lockPath)?this.lockPath:await x(this.legacyLockPath)?this.legacyLockPath:null}static async cleanStale(e){let t=await le(e),r=[];for(let s of t){let i=new n(s);if(await i.isStale()){let a=await i.findExistingLockPath();a&&await $(a),r.push(F.basename(s))}}return r}};var A=_(require("path"),1);var C=_(require("path"),1);function er(n,e){let t=C.resolve(n),r=C.resolve(n,e);return r===t?!0:t===C.parse(t).root?r.startsWith(t):r.startsWith(t+C.sep)}function q(n,e){if(C.isAbsolute(e))return C.resolve(e);if(!er(n,e))throw new Error(`PathSecurity: Path traversal attempt detected: ${e}`);return C.resolve(n,e)}function J(n){if(n!==void 0&&n!=="agent"&&n!=="chatOnly")throw new Error("Invalid session execution mode; expected agent or chatOnly.")}var T=_(require("path"),1),ye=_(require("os"),1),R=_(require("node:fs/promises"),1),we=require("node:crypto");var V=require("node:os");var Be=require("node:path"),Kr=(0,V.platform)();var Yr=(0,V.release)(),Qr=(0,V.homedir)();function me(){let n=process.env.XENO_AGENT_HOME?.trim();return n?(0,Be.resolve)(n):(0,Be.resolve)((0,V.homedir)(),".xeno-agent")}var gt=1,ft="recent.json",tr=".lock",ht=".entries",rr=3e4,je=6e4,yt=new Set(["EACCES","EBUSY","EPERM"]),nr=[5,10,20,40,80,160,320],he=new Map;function sr(n,e){let t=(0,we.createHash)("sha256").update(e).digest("hex");return T.join(`${n}${ht}`,`${t}.json`)}async function Fe(n,e,t){let r={schemaVersion:1,key:e,entry:t};await k(sr(n,e),JSON.stringify(r)+`
51
+ `:"";await k(this.transcriptPath,a);let l=this.buildMarkdownDocument(o,"session store");if(await k(this.markdownPath,l),!this.workspaceMirrorDisabled){let c=await this.resolveWorkspaceMarkdownPath();if(c)try{let u=this.buildMarkdownDocument(o,"workspace mirror");await k(c,u)}catch(u){this.workspaceMirrorDisabled=!0,B("Transcript workspace mirror disabled",u)}}}getSequence(){return this.sequence}async initialize(){try{let e=await x(this.transcriptPath);if(!e){this.sequence=0;return}let t=Z(e);if(t.length===0){this.sequence=0;return}let r=t[t.length-1];this.sequence=r.sequence+1}catch(e){let t=e instanceof Error?e.message:String(e);B(`Transcript initialization warning: ${t}. Starting with empty transcript.`),this.sequence=0}}async flush(){await this.writeQueue}};var ee=_(require("path"),1),lt=require("crypto"),ut=require("fs/promises");var qt={View:"Read",Replace:"Write",GlobTool:"Glob",GrepTool:"Grep",SQLiteAnalyze:"SqliteAnalyze",ReadNotebook:"NotebookRead",NotebookEditCell:"NotebookEdit",CoordinationSend:"Send",CoordinationQuery:"Receive"};function fe(n){return qt[n]??n}var I=class{sessionDir;checkpointsDir;autoInterval;lastCheckpointMessageCount=0;constructor(e,t){this.sessionDir=e,this.checkpointsDir=ee.join(e,"checkpoints"),this.autoInterval=t?.autoInterval??10}async initialize(){let e=await this.list();e.length>0&&(this.lastCheckpointMessageCount=e[0].messageCount)}async create(e){await N(this.checkpointsDir);let t=(0,lt.randomUUID)(),r={id:t,name:e.description,trigger:e.trigger,createdAt:new Date().toISOString(),messageCount:e.messages.length,tokenCount:this.estimateTokens(e.messages)},s={info:r,messages:e.messages},i=ee.join(this.checkpointsDir,`${t}.json`);return await k(i,JSON.stringify(s,null,2)),this.lastCheckpointMessageCount=e.messages.length,r}async list(){let e=await Ze(this.checkpointsDir,/\.json$/),t=[];for(let r of e){let s=await x(r);if(s){let i=E(s,null);if(i){let o=await(0,ut.stat)(r);t.push({info:i.info,modifiedAtMs:o.mtimeMs})}}}return t.sort((r,s)=>new Date(s.info.createdAt).getTime()-new Date(r.info.createdAt).getTime()||s.modifiedAtMs-r.modifiedAtMs).map(({info:r})=>r)}async restore(e){let t=ee.join(this.checkpointsDir,`${e}.json`),r;try{r=await x(t)}catch(i){let o=i instanceof Error?i.message:String(i);throw new Error(`Failed to read checkpoint ${e}: ${o}`)}if(!r)throw new Error(`Checkpoint not found: ${e} (path: ${t})`);let s=E(r,null);if(!s)throw new Error(`Invalid checkpoint data for ${e}: JSON parse failed`);if(!s.messages||!Array.isArray(s.messages))throw new Error(`Invalid checkpoint data for ${e}: missing or invalid messages array`);if(!s.info)throw new Error(`Invalid checkpoint data for ${e}: missing info object`);return{messages:s.messages,info:s.info}}shouldAutoCheckpoint(e){return e-this.lastCheckpointMessageCount>=this.autoInterval}static isDangerousOperation(e,t){if(e=fe(e),e==="Write")return!0;if(e==="Bash"){let s=t.command?.toLowerCase()||"";return["rm ","del ","git push","git reset","drop ","truncate"].some(o=>s.includes(o))}return!1}async delete(e){let t=ee.join(this.checkpointsDir,`${e}.json`);await $(t)}estimateTokens(e){let t=0;for(let r of e)if(typeof r.content=="string")t+=Math.ceil(r.content.length/4);else if(Array.isArray(r.content))for(let s of r.content)"text"in s&&(t+=Math.ceil(s.text.length/4));return t}};var F=_(require("path"),1),$e=_(require("os"),1),j=_(require("fs"),1);var Jt=Symbol.for("@xenosystem/agent-sdk/shutdown-registry"),Vt=globalThis,Oe=Vt[Jt]??={cleanups:new Set,exitHandlerRegistered:!1,signalHandlersInstalled:!1},Ne=Oe.cleanups;function zt(){for(let n of Ne)try{n()}catch{}}function dt(n){return Ne.add(n),!Oe.exitHandlerRegistered&&typeof process<"u"&&typeof process.on=="function"&&(Oe.exitHandlerRegistered=!0,process.on("exit",zt)),()=>{Ne.delete(n)}}var pt="0.10.13";var Xt=1e4,Kt=6e4,Yt="session.lock",Qt="lock.json",Q=new Map;function Le(n,e){return n!=null&&n.pid===e.pid&&n.hostname===e.hostname&&n.processStartedAt===e.processStartedAt&&n.acquiredAt===e.acquiredAt}function Zt(){for(let[n,e]of Q)try{let t=E(j.readFileSync(n,"utf8"),null);Le(t,e)&&j.unlinkSync(n)}catch{}Q.clear()}dt(Zt);var U=class n{sessionDir;lockPath;legacyLockPath;sessionId;heartbeatTimer;acquiredOwner;constructor(e){this.sessionDir=e,this.lockPath=F.join(e,Yt),this.legacyLockPath=F.join(e,Qt),this.sessionId=F.basename(e)}async acquire(){let e=new Date().toISOString(),t={schemaVersion:1,name:`session:${this.sessionId}`,sessionId:this.sessionId,pid:process.pid,hostname:$e.hostname(),processStartedAt:new Date(Date.now()-Math.floor(process.uptime()*1e3)).toISOString(),version:pt,acquiredAt:e,updatedAt:e,heartbeat:e},r=F.dirname(this.lockPath);await j.promises.mkdir(r,{recursive:!0});let s=await this.findExistingLockPath();if(s){if(!await this.isStalePath(s)){let o=await this.readLockAt(s);throw new Error(`Session ${this.sessionId} is already locked by PID ${o?.pid} on ${o?.hostname}`)}await $(s)}try{await j.promises.writeFile(this.lockPath,JSON.stringify(t,null,2),{flag:"wx",encoding:"utf-8"}),this.acquiredOwner=t,Q.set(this.lockPath,t)}catch(i){if(i.code==="EEXIST"){if(!await this.isStalePath(this.lockPath)){let l=await this.readLockAt(this.lockPath);throw new Error(`Session ${this.sessionId} is already locked by PID ${l?.pid} on ${l?.hostname}`)}await $(this.lockPath);try{await j.promises.writeFile(this.lockPath,JSON.stringify(t,null,2),{flag:"wx",encoding:"utf-8"})}catch(l){throw l.code==="EEXIST"?new Error(`Session ${this.sessionId} lock was acquired by another process during stale recovery`):l}this.acquiredOwner=t,Q.set(this.lockPath,t)}else throw i}}async release(){this.stopHeartbeat();let e=this.acquiredOwner;if(this.acquiredOwner=void 0,!e)return;Q.delete(this.lockPath);let t=await this.readLockAt(this.lockPath);Le(t,e)&&await $(this.lockPath)}async isLocked(){let e=await this.findExistingLockPath();return e?!await this.isStalePath(e):!1}async isStale(){let e=await this.findExistingLockPath();return e?this.isStalePath(e):!1}async isStalePath(e){let t=await this.readLockAt(e);if(!t)return!1;if(t.hostname===$e.hostname())try{return process.kill(t.pid,0),!1}catch(i){return i.code!=="EPERM"}let r=new Date(t.heartbeat).getTime();return Date.now()-r>Kt}startHeartbeat(e=Xt){this.heartbeatTimer&&this.stopHeartbeat(),this.heartbeatTimer=setInterval(async()=>{try{await this.updateHeartbeat()}catch(t){let r=t instanceof Error?t.message:String(t);if(t?.code==="ENOENT"){W("SessionLock: Session directory removed, stopping heartbeat"),this.stopHeartbeat();return}W(`SessionLock: Failed to update heartbeat: ${r}`)}},e),this.heartbeatTimer.unref()}stopHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=void 0)}async updateHeartbeat(){let e=await this.readLockAt(this.lockPath),t=this.acquiredOwner;if(!(!e||!t)){if(!Le(e,t)){this.acquiredOwner=void 0,Q.delete(this.lockPath),this.stopHeartbeat();return}e.heartbeat=new Date().toISOString(),e.updatedAt=e.heartbeat,await k(this.lockPath,JSON.stringify(e,null,2))}}async readLock(){let e=await this.findExistingLockPath();return e?this.readLockAt(e):null}async readLockAt(e){let t=await x(e);return t?E(t,null):null}async findExistingLockPath(){return await x(this.lockPath)?this.lockPath:await x(this.legacyLockPath)?this.legacyLockPath:null}static async cleanStale(e){let t=await le(e),r=[];for(let s of t){let i=new n(s);if(await i.isStale()){let a=await i.findExistingLockPath();a&&await $(a),r.push(F.basename(s))}}return r}};var A=_(require("path"),1);var C=_(require("path"),1);function er(n,e){let t=C.resolve(n),r=C.resolve(n,e);return r===t?!0:t===C.parse(t).root?r.startsWith(t):r.startsWith(t+C.sep)}function q(n,e){if(C.isAbsolute(e))return C.resolve(e);if(!er(n,e))throw new Error(`PathSecurity: Path traversal attempt detected: ${e}`);return C.resolve(n,e)}function J(n){if(n!==void 0&&n!=="agent"&&n!=="chatOnly")throw new Error("Invalid session execution mode; expected agent or chatOnly.")}var T=_(require("path"),1),ye=_(require("os"),1),R=_(require("node:fs/promises"),1),we=require("node:crypto");var V=require("node:os");var Be=require("node:path"),Kr=(0,V.platform)();var Yr=(0,V.release)(),Qr=(0,V.homedir)();function me(){let n=process.env.XENO_AGENT_HOME?.trim();return n?(0,Be.resolve)(n):(0,Be.resolve)((0,V.homedir)(),".xeno-agent")}var gt=1,ft="recent.json",tr=".lock",ht=".entries",rr=3e4,je=6e4,yt=new Set(["EACCES","EBUSY","EPERM"]),nr=[5,10,20,40,80,160,320],he=new Map;function sr(n,e){let t=(0,we.createHash)("sha256").update(e).digest("hex");return T.join(`${n}${ht}`,`${t}.json`)}async function Fe(n,e,t){let r={schemaVersion:1,key:e,entry:t};await k(sr(n,e),JSON.stringify(r)+`
52
52
  `)}async function ir(n,e){let t=`${n}${ht}`,r;try{r=await R.readdir(t)}catch(s){if(s.code==="ENOENT")return;throw s}await Promise.all(r.filter(s=>s.endsWith(".json")).map(async s=>{let i=await R.readFile(T.join(t,s),"utf8").catch(()=>""),o=E(i,null);if(!(!o||o.schemaVersion!==1||typeof o.key!="string")){if(o.entry===null){delete e[o.key];return}typeof o.entry.sessionId!="string"||typeof o.entry.endedAt!="string"||(e[o.key]=o.entry)}}))}function mt(n){if(!Number.isInteger(n)||n<=0)return!1;try{return process.kill(n,0),!0}catch(e){return e.code==="EPERM"}}async function or(n){try{let[e,t]=await Promise.all([R.readFile(T.join(n,"owner.json"),"utf8").catch(()=>""),R.stat(n)]),r=E(e,null);return r?.hostname===ye.hostname()&&mt(r.pid)?!1:r?.hostname&&r.hostname!==ye.hostname()||!r?Date.now()-t.mtimeMs>je:Date.now()-t.mtimeMs>je||!mt(r.pid)}catch{return!1}}async function wt(n){for(let e=0;;e+=1)try{await R.rm(n,{recursive:!0});return}catch(t){let r=t.code;if(r==="ENOENT")return;let s=nr[e];if(process.platform!=="win32"||!r||!yt.has(r)||s===void 0)throw t;await new Promise(i=>setTimeout(i,s))}}async function ar(n,e){try{let t=await R.readFile(T.join(n,"owner.json"),"utf8");E(t,null)?.token===e&&await wt(n)}catch(t){if(t.code!=="ENOENT")throw t}}async function He(n,e){let t=z(n),r=he.get(t)??Promise.resolve(),s,i=new Promise(o=>{s=o});he.set(t,i),await r;try{return await cr(t,e)}finally{s(),he.get(t)===i&&he.delete(t)}}async function cr(n,e){let t=`${n}${tr}`,r=(0,we.randomUUID)(),s=Date.now();await R.mkdir(T.dirname(n),{recursive:!0});for(let i=0;;i+=1){let o={schemaVersion:1,token:r,pid:process.pid,hostname:ye.hostname(),acquiredAt:new Date().toISOString()};try{await R.mkdir(t),await R.writeFile(T.join(t,"owner.json"),JSON.stringify(o),"utf8");break}catch(a){let l=a.code,c=process.platform==="win32"&&!!l&&yt.has(l);if(l!=="EEXIST"&&!c)throw a;if(await or(t)){await wt(t);continue}if(Date.now()-s>=rr)throw new Error(`Timed out waiting for recent-sessions index lock: ${t}`);let u=Math.min(100,5+i*5)+Math.floor(Math.random()*10);await new Promise(p=>setTimeout(p,u))}}try{return await e()}finally{await ar(t,r)}}function z(n){return n===void 0?T.join(me(),ft):T.join(n,".xeno-agent",ft)}function te(n){let e=T.normalize(n).replace(/[\\/]+$/,""),t=e.length>0?e:T.parse(T.normalize(n)).root;return process.platform==="win32"?t.toLowerCase():t}async function H(n){let e=z(n),t=ce(e)?await x(e):null,r=t?E(t,null):null,s=r&&typeof r=="object"?r:null,i={},o=s?.version===gt&&s.entries&&typeof s.entries=="object"?s.entries:{};for(let[a,l]of Object.entries(o)){if(!l||typeof l!="object")continue;let c=l;typeof c.sessionId!="string"||c.sessionId.length===0||typeof c.endedAt=="string"&&(i[a]={sessionId:c.sessionId,endedAt:c.endedAt,role:typeof c.role=="string"?c.role:void 0})}return await ir(e,i),{version:gt,entries:i}}async function Se(n,e={}){let t=await H(e.homeDir),r=te(n),s=t.entries[r];if(s&&!(e.role&&s.role&&s.role!==e.role))return s}async function ke(n,e={}){let t=te(n.cwd),r={sessionId:n.sessionId,role:n.role,endedAt:n.endedAt??new Date().toISOString()},s=z(e.homeDir);await Fe(s,t,r),await He(e.homeDir,async()=>{let i=await H(e.homeDir);i.entries[t]=r,await k(s,JSON.stringify(i,null,2)+`
53
53
  `)})}async function St(n,e={}){let t=te(n),r=z(e.homeDir);(await H(e.homeDir)).entries[t]&&(await Fe(r,t,null),await He(e.homeDir,async()=>{let i=await H(e.homeDir);delete i.entries[t],await k(r,JSON.stringify(i,null,2)+`
54
54
  `)}))}async function re(n,e={}){let t=await H(e.homeDir),r=Object.entries(t.entries).filter(([,i])=>i.sessionId===n).map(([i])=>i);if(r.length===0)return;let s=z(e.homeDir);await Promise.all(r.map(i=>Fe(s,i,null))),await He(e.homeDir,async()=>{let i=await H(e.homeDir);for(let[o,a]of Object.entries(i.entries))a.sessionId===n&&delete i.entries[o];await k(s,JSON.stringify(i,null,2)+`
@@ -48,7 +48,7 @@ ${this.stringify(e.data)}
48
48
  `)+`
49
49
  `;await S(this.transcriptPath,a);let l=this.buildMarkdownDocument(o,"session store");if(await S(this.markdownPath,l),!this.workspaceMirrorDisabled){let c=await this.resolveWorkspaceMarkdownPath();if(c)try{let u=this.buildMarkdownDocument(o,"workspace mirror");await S(c,u)}catch(u){this.workspaceMirrorDisabled=!0,$("Transcript workspace mirror disabled",u)}}}async truncateAfterMessageCount(e){let t=await k(this.transcriptPath);if(!t)return;let r=K(t),s=Math.max(0,e),i=0,o=[];for(let c of r){if(c.type==="user_message"||c.type==="assistant_message"){if(i>=s)break;i+=1}o.push(c)}let a=o.length>0?o.map(c=>JSON.stringify(c)).join(`
50
50
  `)+`
51
- `:"";await S(this.transcriptPath,a);let l=this.buildMarkdownDocument(o,"session store");if(await S(this.markdownPath,l),!this.workspaceMirrorDisabled){let c=await this.resolveWorkspaceMarkdownPath();if(c)try{let u=this.buildMarkdownDocument(o,"workspace mirror");await S(c,u)}catch(u){this.workspaceMirrorDisabled=!0,$("Transcript workspace mirror disabled",u)}}}getSequence(){return this.sequence}async initialize(){try{let e=await k(this.transcriptPath);if(!e){this.sequence=0;return}let t=K(e);if(t.length===0){this.sequence=0;return}let r=t[t.length-1];this.sequence=r.sequence+1}catch(e){let t=e instanceof Error?e.message:String(e);$(`Transcript initialization warning: ${t}. Starting with empty transcript.`),this.sequence=0}}async flush(){await this.writeQueue}};import*as Y from"path";import{randomUUID as Lt}from"crypto";import{stat as Bt}from"fs/promises";var $t={View:"Read",Replace:"Write",GlobTool:"Glob",GrepTool:"Grep",SQLiteAnalyze:"SqliteAnalyze",ReadNotebook:"NotebookRead",NotebookEditCell:"NotebookEdit",CoordinationSend:"Send",CoordinationQuery:"Receive"};function ie(n){return $t[n]??n}var I=class{sessionDir;checkpointsDir;autoInterval;lastCheckpointMessageCount=0;constructor(e,t){this.sessionDir=e,this.checkpointsDir=Y.join(e,"checkpoints"),this.autoInterval=t?.autoInterval??10}async initialize(){let e=await this.list();e.length>0&&(this.lastCheckpointMessageCount=e[0].messageCount)}async create(e){await A(this.checkpointsDir);let t=Lt(),r={id:t,name:e.description,trigger:e.trigger,createdAt:new Date().toISOString(),messageCount:e.messages.length,tokenCount:this.estimateTokens(e.messages)},s={info:r,messages:e.messages},i=Y.join(this.checkpointsDir,`${t}.json`);return await S(i,JSON.stringify(s,null,2)),this.lastCheckpointMessageCount=e.messages.length,r}async list(){let e=await We(this.checkpointsDir,/\.json$/),t=[];for(let r of e){let s=await k(r);if(s){let i=P(s,null);if(i){let o=await Bt(r);t.push({info:i.info,modifiedAtMs:o.mtimeMs})}}}return t.sort((r,s)=>new Date(s.info.createdAt).getTime()-new Date(r.info.createdAt).getTime()||s.modifiedAtMs-r.modifiedAtMs).map(({info:r})=>r)}async restore(e){let t=Y.join(this.checkpointsDir,`${e}.json`),r;try{r=await k(t)}catch(i){let o=i instanceof Error?i.message:String(i);throw new Error(`Failed to read checkpoint ${e}: ${o}`)}if(!r)throw new Error(`Checkpoint not found: ${e} (path: ${t})`);let s=P(r,null);if(!s)throw new Error(`Invalid checkpoint data for ${e}: JSON parse failed`);if(!s.messages||!Array.isArray(s.messages))throw new Error(`Invalid checkpoint data for ${e}: missing or invalid messages array`);if(!s.info)throw new Error(`Invalid checkpoint data for ${e}: missing info object`);return{messages:s.messages,info:s.info}}shouldAutoCheckpoint(e){return e-this.lastCheckpointMessageCount>=this.autoInterval}static isDangerousOperation(e,t){if(e=ie(e),e==="Write")return!0;if(e==="Bash"){let s=t.command?.toLowerCase()||"";return["rm ","del ","git push","git reset","drop ","truncate"].some(o=>s.includes(o))}return!1}async delete(e){let t=Y.join(this.checkpointsDir,`${e}.json`);await O(t)}estimateTokens(e){let t=0;for(let r of e)if(typeof r.content=="string")t+=Math.ceil(r.content.length/4);else if(Array.isArray(r.content))for(let s of r.content)"text"in s&&(t+=Math.ceil(s.text.length/4));return t}};import*as B from"path";import*as Pe from"os";import*as L from"fs";var jt=Symbol.for("@xenosystem/agent-sdk/shutdown-registry"),Ft=globalThis,xe=Ft[jt]??={cleanups:new Set,exitHandlerRegistered:!1,signalHandlersInstalled:!1},ve=xe.cleanups;function Ht(){for(let n of ve)try{n()}catch{}}function Qe(n){return ve.add(n),!xe.exitHandlerRegistered&&typeof process<"u"&&typeof process.on=="function"&&(xe.exitHandlerRegistered=!0,process.on("exit",Ht)),()=>{ve.delete(n)}}var Ze="0.10.11";var Wt=1e4,Gt=6e4,Ut="session.lock",qt="lock.json",q=new Map;function Ee(n,e){return n!=null&&n.pid===e.pid&&n.hostname===e.hostname&&n.processStartedAt===e.processStartedAt&&n.acquiredAt===e.acquiredAt}function Jt(){for(let[n,e]of q)try{let t=P(L.readFileSync(n,"utf8"),null);Ee(t,e)&&L.unlinkSync(n)}catch{}q.clear()}Qe(Jt);var J=class n{sessionDir;lockPath;legacyLockPath;sessionId;heartbeatTimer;acquiredOwner;constructor(e){this.sessionDir=e,this.lockPath=B.join(e,Ut),this.legacyLockPath=B.join(e,qt),this.sessionId=B.basename(e)}async acquire(){let e=new Date().toISOString(),t={schemaVersion:1,name:`session:${this.sessionId}`,sessionId:this.sessionId,pid:process.pid,hostname:Pe.hostname(),processStartedAt:new Date(Date.now()-Math.floor(process.uptime()*1e3)).toISOString(),version:Ze,acquiredAt:e,updatedAt:e,heartbeat:e},r=B.dirname(this.lockPath);await L.promises.mkdir(r,{recursive:!0});let s=await this.findExistingLockPath();if(s){if(!await this.isStalePath(s)){let o=await this.readLockAt(s);throw new Error(`Session ${this.sessionId} is already locked by PID ${o?.pid} on ${o?.hostname}`)}await O(s)}try{await L.promises.writeFile(this.lockPath,JSON.stringify(t,null,2),{flag:"wx",encoding:"utf-8"}),this.acquiredOwner=t,q.set(this.lockPath,t)}catch(i){if(i.code==="EEXIST"){if(!await this.isStalePath(this.lockPath)){let l=await this.readLockAt(this.lockPath);throw new Error(`Session ${this.sessionId} is already locked by PID ${l?.pid} on ${l?.hostname}`)}await O(this.lockPath);try{await L.promises.writeFile(this.lockPath,JSON.stringify(t,null,2),{flag:"wx",encoding:"utf-8"})}catch(l){throw l.code==="EEXIST"?new Error(`Session ${this.sessionId} lock was acquired by another process during stale recovery`):l}this.acquiredOwner=t,q.set(this.lockPath,t)}else throw i}}async release(){this.stopHeartbeat();let e=this.acquiredOwner;if(this.acquiredOwner=void 0,!e)return;q.delete(this.lockPath);let t=await this.readLockAt(this.lockPath);Ee(t,e)&&await O(this.lockPath)}async isLocked(){let e=await this.findExistingLockPath();return e?!await this.isStalePath(e):!1}async isStale(){let e=await this.findExistingLockPath();return e?this.isStalePath(e):!1}async isStalePath(e){let t=await this.readLockAt(e);if(!t)return!1;if(t.hostname===Pe.hostname())try{return process.kill(t.pid,0),!1}catch(i){return i.code!=="EPERM"}let r=new Date(t.heartbeat).getTime();return Date.now()-r>Gt}startHeartbeat(e=Wt){this.heartbeatTimer&&this.stopHeartbeat(),this.heartbeatTimer=setInterval(async()=>{try{await this.updateHeartbeat()}catch(t){let r=t instanceof Error?t.message:String(t);if(t?.code==="ENOENT"){j("SessionLock: Session directory removed, stopping heartbeat"),this.stopHeartbeat();return}j(`SessionLock: Failed to update heartbeat: ${r}`)}},e),this.heartbeatTimer.unref()}stopHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=void 0)}async updateHeartbeat(){let e=await this.readLockAt(this.lockPath),t=this.acquiredOwner;if(!(!e||!t)){if(!Ee(e,t)){this.acquiredOwner=void 0,q.delete(this.lockPath),this.stopHeartbeat();return}e.heartbeat=new Date().toISOString(),e.updatedAt=e.heartbeat,await S(this.lockPath,JSON.stringify(e,null,2))}}async readLock(){let e=await this.findExistingLockPath();return e?this.readLockAt(e):null}async readLockAt(e){let t=await k(e);return t?P(t,null):null}async findExistingLockPath(){return await k(this.lockPath)?this.lockPath:await k(this.legacyLockPath)?this.legacyLockPath:null}static async cleanStale(e){let t=await ne(e),r=[];for(let s of t){let i=new n(s);if(await i.isStale()){let a=await i.findExistingLockPath();a&&await O(a),r.push(B.basename(s))}}return r}};import*as D from"path";import*as M from"path";function Vt(n,e){let t=M.resolve(n),r=M.resolve(n,e);return r===t?!0:t===M.parse(t).root?r.startsWith(t):r.startsWith(t+M.sep)}function H(n,e){if(M.isAbsolute(e))return M.resolve(e);if(!Vt(n,e))throw new Error(`PathSecurity: Path traversal attempt detected: ${e}`);return M.resolve(n,e)}function W(n){if(n!==void 0&&n!=="agent"&&n!=="chatOnly")throw new Error("Invalid session execution mode; expected agent or chatOnly.")}import*as b from"path";import*as ce from"os";import*as T from"node:fs/promises";import{createHash as Kt,randomUUID as Yt}from"node:crypto";import{homedir as tt,platform as zt,release as Xt}from"node:os";import{resolve as et}from"node:path";var cn=zt();var ln=Xt(),un=tt();function oe(){let n=process.env.XENO_AGENT_HOME?.trim();return n?et(n):et(tt(),".xeno-agent")}var rt=1,nt="recent.json",Qt=".lock",it=".entries",Zt=3e4,be=6e4,ot=new Set(["EACCES","EBUSY","EPERM"]),er=[5,10,20,40,80,160,320],ae=new Map;function tr(n,e){let t=Kt("sha256").update(e).digest("hex");return b.join(`${n}${it}`,`${t}.json`)}async function Te(n,e,t){let r={schemaVersion:1,key:e,entry:t};await S(tr(n,e),JSON.stringify(r)+`
51
+ `:"";await S(this.transcriptPath,a);let l=this.buildMarkdownDocument(o,"session store");if(await S(this.markdownPath,l),!this.workspaceMirrorDisabled){let c=await this.resolveWorkspaceMarkdownPath();if(c)try{let u=this.buildMarkdownDocument(o,"workspace mirror");await S(c,u)}catch(u){this.workspaceMirrorDisabled=!0,$("Transcript workspace mirror disabled",u)}}}getSequence(){return this.sequence}async initialize(){try{let e=await k(this.transcriptPath);if(!e){this.sequence=0;return}let t=K(e);if(t.length===0){this.sequence=0;return}let r=t[t.length-1];this.sequence=r.sequence+1}catch(e){let t=e instanceof Error?e.message:String(e);$(`Transcript initialization warning: ${t}. Starting with empty transcript.`),this.sequence=0}}async flush(){await this.writeQueue}};import*as Y from"path";import{randomUUID as Lt}from"crypto";import{stat as Bt}from"fs/promises";var $t={View:"Read",Replace:"Write",GlobTool:"Glob",GrepTool:"Grep",SQLiteAnalyze:"SqliteAnalyze",ReadNotebook:"NotebookRead",NotebookEditCell:"NotebookEdit",CoordinationSend:"Send",CoordinationQuery:"Receive"};function ie(n){return $t[n]??n}var I=class{sessionDir;checkpointsDir;autoInterval;lastCheckpointMessageCount=0;constructor(e,t){this.sessionDir=e,this.checkpointsDir=Y.join(e,"checkpoints"),this.autoInterval=t?.autoInterval??10}async initialize(){let e=await this.list();e.length>0&&(this.lastCheckpointMessageCount=e[0].messageCount)}async create(e){await A(this.checkpointsDir);let t=Lt(),r={id:t,name:e.description,trigger:e.trigger,createdAt:new Date().toISOString(),messageCount:e.messages.length,tokenCount:this.estimateTokens(e.messages)},s={info:r,messages:e.messages},i=Y.join(this.checkpointsDir,`${t}.json`);return await S(i,JSON.stringify(s,null,2)),this.lastCheckpointMessageCount=e.messages.length,r}async list(){let e=await We(this.checkpointsDir,/\.json$/),t=[];for(let r of e){let s=await k(r);if(s){let i=P(s,null);if(i){let o=await Bt(r);t.push({info:i.info,modifiedAtMs:o.mtimeMs})}}}return t.sort((r,s)=>new Date(s.info.createdAt).getTime()-new Date(r.info.createdAt).getTime()||s.modifiedAtMs-r.modifiedAtMs).map(({info:r})=>r)}async restore(e){let t=Y.join(this.checkpointsDir,`${e}.json`),r;try{r=await k(t)}catch(i){let o=i instanceof Error?i.message:String(i);throw new Error(`Failed to read checkpoint ${e}: ${o}`)}if(!r)throw new Error(`Checkpoint not found: ${e} (path: ${t})`);let s=P(r,null);if(!s)throw new Error(`Invalid checkpoint data for ${e}: JSON parse failed`);if(!s.messages||!Array.isArray(s.messages))throw new Error(`Invalid checkpoint data for ${e}: missing or invalid messages array`);if(!s.info)throw new Error(`Invalid checkpoint data for ${e}: missing info object`);return{messages:s.messages,info:s.info}}shouldAutoCheckpoint(e){return e-this.lastCheckpointMessageCount>=this.autoInterval}static isDangerousOperation(e,t){if(e=ie(e),e==="Write")return!0;if(e==="Bash"){let s=t.command?.toLowerCase()||"";return["rm ","del ","git push","git reset","drop ","truncate"].some(o=>s.includes(o))}return!1}async delete(e){let t=Y.join(this.checkpointsDir,`${e}.json`);await O(t)}estimateTokens(e){let t=0;for(let r of e)if(typeof r.content=="string")t+=Math.ceil(r.content.length/4);else if(Array.isArray(r.content))for(let s of r.content)"text"in s&&(t+=Math.ceil(s.text.length/4));return t}};import*as B from"path";import*as Pe from"os";import*as L from"fs";var jt=Symbol.for("@xenosystem/agent-sdk/shutdown-registry"),Ft=globalThis,xe=Ft[jt]??={cleanups:new Set,exitHandlerRegistered:!1,signalHandlersInstalled:!1},ve=xe.cleanups;function Ht(){for(let n of ve)try{n()}catch{}}function Qe(n){return ve.add(n),!xe.exitHandlerRegistered&&typeof process<"u"&&typeof process.on=="function"&&(xe.exitHandlerRegistered=!0,process.on("exit",Ht)),()=>{ve.delete(n)}}var Ze="0.10.13";var Wt=1e4,Gt=6e4,Ut="session.lock",qt="lock.json",q=new Map;function Ee(n,e){return n!=null&&n.pid===e.pid&&n.hostname===e.hostname&&n.processStartedAt===e.processStartedAt&&n.acquiredAt===e.acquiredAt}function Jt(){for(let[n,e]of q)try{let t=P(L.readFileSync(n,"utf8"),null);Ee(t,e)&&L.unlinkSync(n)}catch{}q.clear()}Qe(Jt);var J=class n{sessionDir;lockPath;legacyLockPath;sessionId;heartbeatTimer;acquiredOwner;constructor(e){this.sessionDir=e,this.lockPath=B.join(e,Ut),this.legacyLockPath=B.join(e,qt),this.sessionId=B.basename(e)}async acquire(){let e=new Date().toISOString(),t={schemaVersion:1,name:`session:${this.sessionId}`,sessionId:this.sessionId,pid:process.pid,hostname:Pe.hostname(),processStartedAt:new Date(Date.now()-Math.floor(process.uptime()*1e3)).toISOString(),version:Ze,acquiredAt:e,updatedAt:e,heartbeat:e},r=B.dirname(this.lockPath);await L.promises.mkdir(r,{recursive:!0});let s=await this.findExistingLockPath();if(s){if(!await this.isStalePath(s)){let o=await this.readLockAt(s);throw new Error(`Session ${this.sessionId} is already locked by PID ${o?.pid} on ${o?.hostname}`)}await O(s)}try{await L.promises.writeFile(this.lockPath,JSON.stringify(t,null,2),{flag:"wx",encoding:"utf-8"}),this.acquiredOwner=t,q.set(this.lockPath,t)}catch(i){if(i.code==="EEXIST"){if(!await this.isStalePath(this.lockPath)){let l=await this.readLockAt(this.lockPath);throw new Error(`Session ${this.sessionId} is already locked by PID ${l?.pid} on ${l?.hostname}`)}await O(this.lockPath);try{await L.promises.writeFile(this.lockPath,JSON.stringify(t,null,2),{flag:"wx",encoding:"utf-8"})}catch(l){throw l.code==="EEXIST"?new Error(`Session ${this.sessionId} lock was acquired by another process during stale recovery`):l}this.acquiredOwner=t,q.set(this.lockPath,t)}else throw i}}async release(){this.stopHeartbeat();let e=this.acquiredOwner;if(this.acquiredOwner=void 0,!e)return;q.delete(this.lockPath);let t=await this.readLockAt(this.lockPath);Ee(t,e)&&await O(this.lockPath)}async isLocked(){let e=await this.findExistingLockPath();return e?!await this.isStalePath(e):!1}async isStale(){let e=await this.findExistingLockPath();return e?this.isStalePath(e):!1}async isStalePath(e){let t=await this.readLockAt(e);if(!t)return!1;if(t.hostname===Pe.hostname())try{return process.kill(t.pid,0),!1}catch(i){return i.code!=="EPERM"}let r=new Date(t.heartbeat).getTime();return Date.now()-r>Gt}startHeartbeat(e=Wt){this.heartbeatTimer&&this.stopHeartbeat(),this.heartbeatTimer=setInterval(async()=>{try{await this.updateHeartbeat()}catch(t){let r=t instanceof Error?t.message:String(t);if(t?.code==="ENOENT"){j("SessionLock: Session directory removed, stopping heartbeat"),this.stopHeartbeat();return}j(`SessionLock: Failed to update heartbeat: ${r}`)}},e),this.heartbeatTimer.unref()}stopHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=void 0)}async updateHeartbeat(){let e=await this.readLockAt(this.lockPath),t=this.acquiredOwner;if(!(!e||!t)){if(!Ee(e,t)){this.acquiredOwner=void 0,q.delete(this.lockPath),this.stopHeartbeat();return}e.heartbeat=new Date().toISOString(),e.updatedAt=e.heartbeat,await S(this.lockPath,JSON.stringify(e,null,2))}}async readLock(){let e=await this.findExistingLockPath();return e?this.readLockAt(e):null}async readLockAt(e){let t=await k(e);return t?P(t,null):null}async findExistingLockPath(){return await k(this.lockPath)?this.lockPath:await k(this.legacyLockPath)?this.legacyLockPath:null}static async cleanStale(e){let t=await ne(e),r=[];for(let s of t){let i=new n(s);if(await i.isStale()){let a=await i.findExistingLockPath();a&&await O(a),r.push(B.basename(s))}}return r}};import*as D from"path";import*as M from"path";function Vt(n,e){let t=M.resolve(n),r=M.resolve(n,e);return r===t?!0:t===M.parse(t).root?r.startsWith(t):r.startsWith(t+M.sep)}function H(n,e){if(M.isAbsolute(e))return M.resolve(e);if(!Vt(n,e))throw new Error(`PathSecurity: Path traversal attempt detected: ${e}`);return M.resolve(n,e)}function W(n){if(n!==void 0&&n!=="agent"&&n!=="chatOnly")throw new Error("Invalid session execution mode; expected agent or chatOnly.")}import*as b from"path";import*as ce from"os";import*as T from"node:fs/promises";import{createHash as Kt,randomUUID as Yt}from"node:crypto";import{homedir as tt,platform as zt,release as Xt}from"node:os";import{resolve as et}from"node:path";var cn=zt();var ln=Xt(),un=tt();function oe(){let n=process.env.XENO_AGENT_HOME?.trim();return n?et(n):et(tt(),".xeno-agent")}var rt=1,nt="recent.json",Qt=".lock",it=".entries",Zt=3e4,be=6e4,ot=new Set(["EACCES","EBUSY","EPERM"]),er=[5,10,20,40,80,160,320],ae=new Map;function tr(n,e){let t=Kt("sha256").update(e).digest("hex");return b.join(`${n}${it}`,`${t}.json`)}async function Te(n,e,t){let r={schemaVersion:1,key:e,entry:t};await S(tr(n,e),JSON.stringify(r)+`
52
52
  `)}async function rr(n,e){let t=`${n}${it}`,r;try{r=await T.readdir(t)}catch(s){if(s.code==="ENOENT")return;throw s}await Promise.all(r.filter(s=>s.endsWith(".json")).map(async s=>{let i=await T.readFile(b.join(t,s),"utf8").catch(()=>""),o=P(i,null);if(!(!o||o.schemaVersion!==1||typeof o.key!="string")){if(o.entry===null){delete e[o.key];return}typeof o.entry.sessionId!="string"||typeof o.entry.endedAt!="string"||(e[o.key]=o.entry)}}))}function st(n){if(!Number.isInteger(n)||n<=0)return!1;try{return process.kill(n,0),!0}catch(e){return e.code==="EPERM"}}async function nr(n){try{let[e,t]=await Promise.all([T.readFile(b.join(n,"owner.json"),"utf8").catch(()=>""),T.stat(n)]),r=P(e,null);return r?.hostname===ce.hostname()&&st(r.pid)?!1:r?.hostname&&r.hostname!==ce.hostname()||!r?Date.now()-t.mtimeMs>be:Date.now()-t.mtimeMs>be||!st(r.pid)}catch{return!1}}async function at(n){for(let e=0;;e+=1)try{await T.rm(n,{recursive:!0});return}catch(t){let r=t.code;if(r==="ENOENT")return;let s=er[e];if(process.platform!=="win32"||!r||!ot.has(r)||s===void 0)throw t;await new Promise(i=>setTimeout(i,s))}}async function sr(n,e){try{let t=await T.readFile(b.join(n,"owner.json"),"utf8");P(t,null)?.token===e&&await at(n)}catch(t){if(t.code!=="ENOENT")throw t}}async function Re(n,e){let t=V(n),r=ae.get(t)??Promise.resolve(),s,i=new Promise(o=>{s=o});ae.set(t,i),await r;try{return await ir(t,e)}finally{s(),ae.get(t)===i&&ae.delete(t)}}async function ir(n,e){let t=`${n}${Qt}`,r=Yt(),s=Date.now();await T.mkdir(b.dirname(n),{recursive:!0});for(let i=0;;i+=1){let o={schemaVersion:1,token:r,pid:process.pid,hostname:ce.hostname(),acquiredAt:new Date().toISOString()};try{await T.mkdir(t),await T.writeFile(b.join(t,"owner.json"),JSON.stringify(o),"utf8");break}catch(a){let l=a.code,c=process.platform==="win32"&&!!l&&ot.has(l);if(l!=="EEXIST"&&!c)throw a;if(await nr(t)){await at(t);continue}if(Date.now()-s>=Zt)throw new Error(`Timed out waiting for recent-sessions index lock: ${t}`);let u=Math.min(100,5+i*5)+Math.floor(Math.random()*10);await new Promise(p=>setTimeout(p,u))}}try{return await e()}finally{await sr(t,r)}}function V(n){return n===void 0?b.join(oe(),nt):b.join(n,".xeno-agent",nt)}function le(n){let e=b.normalize(n).replace(/[\\/]+$/,""),t=e.length>0?e:b.parse(b.normalize(n)).root;return process.platform==="win32"?t.toLowerCase():t}async function G(n){let e=V(n),t=re(e)?await k(e):null,r=t?P(t,null):null,s=r&&typeof r=="object"?r:null,i={},o=s?.version===rt&&s.entries&&typeof s.entries=="object"?s.entries:{};for(let[a,l]of Object.entries(o)){if(!l||typeof l!="object")continue;let c=l;typeof c.sessionId!="string"||c.sessionId.length===0||typeof c.endedAt=="string"&&(i[a]={sessionId:c.sessionId,endedAt:c.endedAt,role:typeof c.role=="string"?c.role:void 0})}return await rr(e,i),{version:rt,entries:i}}async function _e(n,e={}){let t=await G(e.homeDir),r=le(n),s=t.entries[r];if(s&&!(e.role&&s.role&&s.role!==e.role))return s}async function Me(n,e={}){let t=le(n.cwd),r={sessionId:n.sessionId,role:n.role,endedAt:n.endedAt??new Date().toISOString()},s=V(e.homeDir);await Te(s,t,r),await Re(e.homeDir,async()=>{let i=await G(e.homeDir);i.entries[t]=r,await S(s,JSON.stringify(i,null,2)+`
53
53
  `)})}async function or(n,e={}){let t=le(n),r=V(e.homeDir);(await G(e.homeDir)).entries[t]&&(await Te(r,t,null),await Re(e.homeDir,async()=>{let i=await G(e.homeDir);delete i.entries[t],await S(r,JSON.stringify(i,null,2)+`
54
54
  `)}))}async function ue(n,e={}){let t=await G(e.homeDir),r=Object.entries(t.entries).filter(([,i])=>i.sessionId===n).map(([i])=>i);if(r.length===0)return;let s=V(e.homeDir);await Promise.all(r.map(i=>Te(s,i,null))),await Re(e.homeDir,async()=>{let i=await G(e.homeDir);for(let[o,a]of Object.entries(i.entries))a.sessionId===n&&delete i.entries[o];await S(s,JSON.stringify(i,null,2)+`
package/dist/ui/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var X=Object.defineProperty;var Z=Object.getOwnPropertyDescriptor;var ee=Object.getOwnPropertyNames;var te=Object.prototype.hasOwnProperty;var ne=(n,e)=>{for(var r in e)X(n,r,{get:e[r],enumerable:!0})},oe=(n,e,r,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of ee(e))!te.call(n,i)&&i!==r&&X(n,i,{get:()=>e[i],enumerable:!(t=Z(e,i))||t.enumerable});return n};var re=n=>oe(X({},"__esModule",{value:!0}),n);var ye={};ne(ye,{XENO_UI_RENDERER_API_VERSION:()=>I,createAgentUiController:()=>B,createAgentUiView:()=>z,dispatchAgentUiAction:()=>S,isSafeMarkdownHref:()=>q,mountAgentUi:()=>Y,parseMarkdown:()=>D,xenoUiCss:()=>H,xenoUiTokens:()=>K});module.exports=re(ye);var ie={View:"Read",Replace:"Write",GlobTool:"Glob",GrepTool:"Grep",SQLiteAnalyze:"SqliteAnalyze",ReadNotebook:"NotebookRead",NotebookEditCell:"NotebookEdit",CoordinationSend:"Send",CoordinationQuery:"Receive"};function se(n){return ie[n]??n}var ae=new Set(["Read","Glob","Grep","LS","MemoryRead","Think","dispatch_agent","ElfAnalyze","Receive","ListAgents","ListSessions","CoordinationQuery"]),le=new Set(["Write","Edit","MemoryWrite","Send","CoordinationSend"]),ce=new Set(["Bash"]);function G(n){let e=se(n);return ce.has(e)?"high":ae.has(e)?"low":(le.has(e),"medium")}var I=1;function de(n){let e=n.config;return e&&typeof e=="object"?e:null}function F(n){let e=n.tokenUsage;return{input:Number(e.input)||0,output:Number(e.output)||0,total:Number(e.total)||0}}function ue(n){let e=n.toLowerCase();return["rate limit","429","network","timeout","econnrefused","api error","unreachable"].some(r=>e.includes(r))}function B(n){let e=n.agent,r=n.now??Date.now,t=0,i=n.createId??(()=>`xeno-ui-${r()}-${++t}`),m=new Set,g=[],h="idle",R=F(e),_=null,d=null,k=null,v=null,c="",U=null,N=0,E=!1,b=!1,O=0,p=de(e),w=p?.permissionEngine,$=w?.promptFn;function T(){return Object.freeze({apiVersion:1,revision:O,items:Object.freeze([...g]),isProcessing:E,status:h,tokenUsage:Object.freeze({...R}),permissionRequest:_?Object.freeze({..._}):null,lastUserMessage:k})}function y(){O+=1;let s=T();for(let l of[...m])l(s)}function P(s){g=[...g,s],y()}function V(s){let l=[...g];for(let x=l.length-1;x>=0;x-=1){let a=l[x];if(a?.type==="message"&&a.data.role==="assistant"){l[x]={type:"message",data:s(a.data)},g=l,y();return}}}function j(s,l){let x=[...g];for(let a=x.length-1;a>=0;a-=1){let u=x[a];if(u?.type==="tool_call"&&u.data.id===s){x[a]={type:"tool_call",data:l(u.data)},g=x,y();return}}}function o(){v&&(V(s=>({...s,isStreaming:!1})),v=null,c="")}function C(s){let l={id:i(),message:s,retryable:ue(s),timestamp:r()};P({type:"error",data:l})}function f(s){p&&(p.onText=s.onText,p.onToolStart=s.onToolStart,p.onToolEnd=s.onToolEnd,p.onError=s.onError)}async function L(s){let l=s.trim();if(b||E||!l)return!1;E=!0,k=l,h="thinking",v=null,c="";let x={id:i(),role:"user",content:l,timestamp:r()};g=[...g,{type:"message",data:x}],y();let a={onText:p?.onText,onToolStart:p?.onToolStart,onToolEnd:p?.onToolEnd,onError:p?.onError};p&&(p.onText=u=>{a.onText?.(u),!b&&(c+=u,v?V(A=>({...A,content:c,isStreaming:!0})):(v=i(),P({type:"message",data:{id:v,role:"assistant",content:c,timestamp:r(),isStreaming:!0}})))},p.onToolStart=(u,A)=>{a.onToolStart?.(u,A),!b&&(o(),h="executing",U=i(),N=r(),P({type:"tool_call",data:{id:U,toolName:u,input:A,status:"running",timestamp:r()}}))},p.onToolEnd=(u,A)=>{a.onToolEnd?.(u,A),!b&&(U&&(j(U,J=>({...J,status:A.success?"success":"error",result:A,durationMs:Math.max(0,r()-N)})),U=null),h="thinking",y())},p.onError=(u,A)=>a.onError?.(u,A));try{await e.run(l),b||(o(),h="idle",R=F(e),y())}catch(u){if(!b){o();let A=u instanceof Error?u:new Error(String(u));h=A.name==="AgentInterruptedError"?"idle":"error",A.name!=="AgentInterruptedError"&&C(A.message),R=F(e),y()}}finally{E=!1,f(a),b||y()}return!0}return n.enablePermissionRequests&&w&&(w.promptFn=s=>(d&&d("deny"),new Promise(l=>{d=l,_={id:i(),toolName:s.toolName,detail:s.detail,description:s.description,operation:s.operation,preview:s.preview,riskLevel:G(s.toolName),timestamp:r()},y()}))),{apiVersion:1,getSnapshot:T,subscribe(s){if(b)throw new Error("Agent UI controller is disposed");return m.add(s),s(T()),()=>m.delete(s)},sendMessage:L,cancelExecution(){!b&&E&&e.cancelCurrentTurn()},clearMessages(){b||(g=[],v=null,c="",y())},retryLastMessage(){return b||E||!k?Promise.resolve(!1):(g=g.filter((s,l,x)=>s.type!=="error"?!0:x.slice(l+1).some(a=>a.type!=="error")),h="idle",y(),L(k))},resolvePermission(s,l){if(b||!_||_.id!==s||!d)return!1;let x=d;return d=null,_=null,y(),x(l),!0},dispose(){b||(b=!0,d&&d("deny"),d=null,_=null,w&&(w.promptFn=$),m.clear())}}}function me(n){let e=[],r=[[/```([\w-]*)\n([\s\S]*?)```/,t=>({kind:"code-block",language:t[1]??"",code:t[2]??""})],[/`([^`\n]+)`/,t=>({kind:"inline-code",code:t[1]??""})],[/\*\*(.+?)\*\*/,t=>({kind:"strong",text:t[1]??""})],[/\*([^*\n]+)\*/,t=>({kind:"emphasis",text:t[1]??""})],[/\[([^\]]+)\]\(([^)\s]+)\)/,t=>({kind:"link",text:t[1]??"",href:t[2]??""})]];for(let[t,i]of r){let m=n.match(t);m?.index!==void 0&&e.push({index:m.index,value:i(m),length:m[0].length})}return e.sort((t,i)=>t.index-i.index),e[0]??null}function D(n){let e=[],r=n;for(;r;){let t=me(r);if(!t){e.push({kind:"text",text:r});break}t.index>0&&e.push({kind:"text",text:r.slice(0,t.index)}),e.push(t.value),r=r.slice(t.index+t.length)}return e}function q(n){try{let e=new URL(n,"https://xeno.invalid/");return e.protocol==="https:"||e.protocol==="http:"||e.protocol==="mailto:"}catch{return!1}}var K=Object.freeze({background:"#101214",surface:"#181b1f",surfaceRaised:"#20242a",border:"#343a42",text:"#f2f4f7",textMuted:"#aab2bd",accent:"#5da9e9",success:"#56b881",warning:"#e7b65a",danger:"#e57373",focus:"#8bc5f4"}),H=`
1
+ "use strict";var X=Object.defineProperty;var Z=Object.getOwnPropertyDescriptor;var ee=Object.getOwnPropertyNames;var te=Object.prototype.hasOwnProperty;var ne=(n,t)=>{for(var i in t)X(n,i,{get:t[i],enumerable:!0})},oe=(n,t,i,e)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of ee(t))!te.call(n,r)&&r!==i&&X(n,r,{get:()=>t[r],enumerable:!(e=Z(t,r))||e.enumerable});return n};var ie=n=>oe(X({},"__esModule",{value:!0}),n);var ve={};ne(ve,{XENO_UI_RENDERER_API_VERSION:()=>L,createAgentUiController:()=>B,createAgentUiView:()=>z,dispatchAgentUiAction:()=>S,isSafeMarkdownHref:()=>q,mountAgentUi:()=>J,parseMarkdown:()=>D,xenoUiCss:()=>H,xenoUiTokens:()=>K});module.exports=ie(ve);var re={View:"Read",Replace:"Write",GlobTool:"Glob",GrepTool:"Grep",SQLiteAnalyze:"SqliteAnalyze",ReadNotebook:"NotebookRead",NotebookEditCell:"NotebookEdit",CoordinationSend:"Send",CoordinationQuery:"Receive"};function se(n){return re[n]??n}var ae=new Set(["Read","Glob","Grep","LS","MemoryRead","Think","dispatch_agent","ElfAnalyze","Receive","ListAgents","ListSessions","CoordinationQuery"]),le=new Set(["Write","Edit","MemoryWrite","Send","CoordinationSend"]),ce=new Set(["Bash"]);function G(n){let t=se(n);return ce.has(t)?"high":ae.has(t)?"low":(le.has(t),"medium")}var L=1;function de(n){let t=n.config;return t&&typeof t=="object"?t:null}function F(n){let t=n.tokenUsage;return{input:Number(t.input)||0,output:Number(t.output)||0,total:Number(t.total)||0}}function ue(n){let t=n.toLowerCase();return["rate limit","429","network","timeout","econnrefused","api error","unreachable"].some(i=>t.includes(i))}function B(n){let t=n.agent,i=n.now??Date.now,e=0,r=n.createId??(()=>`xeno-ui-${i()}-${++e}`),m=new Set,g=[],A="idle",N=F(t),_=null,u=null,k=null,h=null,d="",w=null,R=0,E=!1,b=!1,O=0,p=de(t),U=p?.permissionEngine,$=U?.promptFn;function C(){return Object.freeze({apiVersion:1,revision:O,items:Object.freeze([...g]),isProcessing:E,status:A,tokenUsage:Object.freeze({...N}),permissionRequest:_?Object.freeze({..._}):null,lastUserMessage:k})}function y(){O+=1;let s=C();for(let l of[...m])l(s)}function P(s){g=[...g,s],y()}function V(s){let l=[...g];for(let x=l.length-1;x>=0;x-=1){let a=l[x];if(a?.type==="message"&&a.data.role==="assistant"){l[x]={type:"message",data:s(a.data)},g=l,y();return}}}function j(s,l){let x=[...g];for(let a=x.length-1;a>=0;a-=1){let c=x[a];if(c?.type==="tool_call"&&c.data.id===s){x[a]={type:"tool_call",data:l(c.data)},g=x,y();return}}}function o(){h&&(V(s=>({...s,isStreaming:!1})),h=null,d="")}function T(s){let l={id:r(),message:s,retryable:ue(s),timestamp:i()};P({type:"error",data:l})}function f(s){p&&(p.onText=s.onText,p.onToolStart=s.onToolStart,p.onToolEnd=s.onToolEnd,p.onError=s.onError)}async function I(s){let l=s.trim();if(b||E||!l)return!1;E=!0,k=l,A="thinking",h=null,d="";let x={id:r(),role:"user",content:l,timestamp:i()};g=[...g,{type:"message",data:x}],y();let a={onText:p?.onText,onToolStart:p?.onToolStart,onToolEnd:p?.onToolEnd,onError:p?.onError};p&&(p.onText=c=>{a.onText?.(c),!b&&(d+=c,h?V(v=>({...v,content:d,isStreaming:!0})):(h=r(),P({type:"message",data:{id:h,role:"assistant",content:d,timestamp:i(),isStreaming:!0}})))},p.onToolStart=(c,v)=>{a.onToolStart?.(c,v),!b&&(o(),A="executing",w=r(),R=i(),P({type:"tool_call",data:{id:w,toolName:c,input:v,status:"running",timestamp:i()}}))},p.onToolEnd=(c,v)=>{a.onToolEnd?.(c,v),!b&&(w&&(j(w,Y=>({...Y,status:v.success?"success":"error",result:v,durationMs:Math.max(0,i()-R)})),w=null),A="thinking",y())},p.onError=(c,v)=>a.onError?.(c,v));try{await t.run(l),b||(o(),A="idle",N=F(t),y())}catch(c){if(!b){o();let v=c instanceof Error?c:new Error(String(c));A=v.name==="AgentInterruptedError"?"idle":"error",v.name!=="AgentInterruptedError"&&T(v.message),N=F(t),y()}}finally{E=!1,f(a),b||y()}return!0}return n.enablePermissionRequests&&U&&(U.promptFn=s=>(u&&u("deny"),new Promise(l=>{u=l,_={id:r(),toolName:s.toolName,detail:s.detail,description:s.description,operation:s.operation,preview:s.preview,riskLevel:G(s.toolName),timestamp:i(),...s.oneTime?{oneTime:!0}:{},...s.elevation?{elevation:{network:s.elevation.network,directories:[...s.elevation.directories],justification:s.elevation.justification}}:{}},y()}))),{apiVersion:1,getSnapshot:C,subscribe(s){if(b)throw new Error("Agent UI controller is disposed");return m.add(s),s(C()),()=>m.delete(s)},sendMessage:I,cancelExecution(){!b&&E&&t.cancelCurrentTurn()},clearMessages(){b||(g=[],h=null,d="",y())},retryLastMessage(){return b||E||!k?Promise.resolve(!1):(g=g.filter((s,l,x)=>s.type!=="error"?!0:x.slice(l+1).some(a=>a.type!=="error")),A="idle",y(),I(k))},resolvePermission(s,l){if(b||!_||_.id!==s||!u)return!1;_.oneTime&&l==="always"&&(l="allow");let x=u;return u=null,_=null,y(),x(l),!0},dispose(){b||(b=!0,u&&u("deny"),u=null,_=null,U&&(U.promptFn=$),m.clear())}}}function me(n){let t=[],i=[[/```([\w-]*)\n([\s\S]*?)```/,e=>({kind:"code-block",language:e[1]??"",code:e[2]??""})],[/`([^`\n]+)`/,e=>({kind:"inline-code",code:e[1]??""})],[/\*\*(.+?)\*\*/,e=>({kind:"strong",text:e[1]??""})],[/\*([^*\n]+)\*/,e=>({kind:"emphasis",text:e[1]??""})],[/\[([^\]]+)\]\(([^)\s]+)\)/,e=>({kind:"link",text:e[1]??"",href:e[2]??""})]];for(let[e,r]of i){let m=n.match(e);m?.index!==void 0&&t.push({index:m.index,value:r(m),length:m[0].length})}return t.sort((e,r)=>e.index-r.index),t[0]??null}function D(n){let t=[],i=n;for(;i;){let e=me(i);if(!e){t.push({kind:"text",text:i});break}e.index>0&&t.push({kind:"text",text:i.slice(0,e.index)}),t.push(e.value),i=i.slice(e.index+e.length)}return t}function q(n){try{let t=new URL(n,"https://xeno.invalid/");return t.protocol==="https:"||t.protocol==="http:"||t.protocol==="mailto:"}catch{return!1}}var K=Object.freeze({background:"#101214",surface:"#181b1f",surfaceRaised:"#20242a",border:"#343a42",text:"#f2f4f7",textMuted:"#aab2bd",accent:"#5da9e9",success:"#56b881",warning:"#e7b65a",danger:"#e57373",focus:"#8bc5f4"}),H=`
2
2
  .xeno-ui{box-sizing:border-box;display:grid;grid-template-rows:auto minmax(12rem,1fr) auto;width:min(32rem,100%);height:min(44rem,100%);min-height:24rem;border:1px solid var(--xeno-border,#343a42);background:var(--xeno-bg,#101214);color:var(--xeno-text,#f2f4f7);font:14px/1.45 ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;letter-spacing:0}
3
3
  .xeno-ui *{box-sizing:border-box;letter-spacing:0}
4
4
  .xeno-ui__header{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem;border-bottom:1px solid var(--xeno-border,#343a42);background:var(--xeno-surface,#181b1f)}
@@ -31,5 +31,5 @@
31
31
  .xeno-ui :focus-visible{outline:2px solid var(--xeno-focus,#8bc5f4);outline-offset:2px}
32
32
  @media (max-width:36rem){.xeno-ui{width:100%;height:100%;border-left:0;border-right:0}.xeno-ui__entry--user,.xeno-ui__entry--assistant{margin-left:0;margin-right:0}.xeno-ui__composer{grid-template-columns:1fr}.xeno-ui__controls{justify-content:flex-end}}
33
33
  @media (prefers-reduced-motion:reduce){.xeno-ui *{scroll-behavior:auto!important;transition:none!important}}
34
- `;var Q=64*1024;function pe(n){let e;try{e=JSON.stringify(n,null,2)??String(n)}catch{e="[Unserializable value]"}return e.length<=Q?e:`${e.slice(0,Q)}
35
- [truncated]`}function ge(n){if(n.type==="message"){let e=n.data.role==="assistant";return{key:n.data.id,kind:e?"assistant-message":"user-message",role:"article",accessibleName:e?"Assistant message":"Your message",text:n.data.content,streaming:n.data.isStreaming}}if(n.type==="tool_call"){let e=n.data.durationMs===void 0?"":` in ${n.data.durationMs} ms`;return{key:n.data.id,kind:"tool-call",role:"status",accessibleName:`${n.data.toolName} tool ${n.data.status}`,text:`${n.data.toolName}: ${n.data.status}${e}`,detail:pe({input:n.data.input,result:n.data.result}),state:n.data.status}}return{key:n.data.id,kind:"error",role:"alert",accessibleName:"Agent error",text:n.data.message,retryable:n.data.retryable}}function z(n,e={}){let r=e.agentName?.trim()||"Xeno Agent",t=n.permissionRequest;return{apiVersion:1,revision:n.revision,region:{role:"region",accessibleName:e.regionLabel?.trim()||`${r} chat`},header:{title:r,statusRole:"status",statusText:n.status,tokenText:`${n.tokenUsage.total.toLocaleString()} tokens`},timeline:{role:"log",live:"polite",busy:n.isProcessing,entries:n.items.map(ge)},permission:t?{role:"alertdialog",accessibleName:`Permission required for ${t.toolName}`,description:t.description||t.detail,riskLevel:t.riskLevel,requestId:t.id,controls:[{label:"Allow once",decision:"allow"},{label:"Always allow",decision:"always"},{label:"Deny",decision:"deny"}]}:null,composer:{role:"form",inputLabel:e.inputLabel?.trim()||"Message Xeno Agent",placeholder:e.inputPlaceholder?.trim()||"Message or command...",disabled:n.isProcessing,sendLabel:"Send",cancelLabel:"Cancel"}}}async function S(n,e){switch(e.type){case"send":return n.sendMessage(e.text);case"cancel":return n.cancelExecution(),!0;case"clear":return n.clearMessages(),!0;case"retry":return n.retryLastMessage();case"permission":return n.resolvePermission(e.requestId,e.decision)}}var W="xeno-owned-agent-ui-v1";function fe(n,e,r){for(let t of D(r)){if(t.kind==="text"){e.append(n.createTextNode(t.text));continue}if(t.kind==="code-block"){let i=n.createElement("pre"),m=n.createElement("code");t.language&&(m.dataset.language=t.language),m.textContent=t.code,i.append(m),e.append(i);continue}if(t.kind==="inline-code"){let i=n.createElement("code");i.textContent=t.code,e.append(i);continue}if(t.kind==="strong"||t.kind==="emphasis"){let i=n.createElement(t.kind==="strong"?"strong":"em");i.textContent=t.text,e.append(i);continue}if(t.kind==="link"){if(!q(t.href)){e.append(n.createTextNode(t.text));continue}let i=n.createElement("a");i.textContent=t.text,i.href=t.href,i.rel="noopener noreferrer",(i.protocol==="http:"||i.protocol==="https:")&&(i.target="_blank"),e.append(i)}}}function M(n,e,r=""){let t=n.createElement("button");return t.type="button",t.className=`xeno-ui__button${r?` ${r}`:""}`,t.textContent=e,t}function xe(n,e,r){let t=n.createElement(e.role==="article"?"article":"div");if(t.className=`xeno-ui__entry xeno-ui__entry--${e.kind==="user-message"?"user":e.kind==="assistant-message"?"assistant":e.kind==="tool-call"?"tool":"error"}`,t.setAttribute("role",e.role),t.setAttribute("aria-label",e.accessibleName),t.dataset.xenoKey=e.key,e.streaming&&t.setAttribute("aria-busy","true"),fe(n,t,e.text),e.detail){let i=n.createElement("details");i.className="xeno-ui__details";let m=n.createElement("summary");m.textContent="Details";let g=n.createElement("pre");g.textContent=e.detail,i.append(m,g),t.append(i)}if(e.retryable){let i=M(n,"Retry");i.addEventListener("click",()=>{S(r,{type:"retry"})}),t.append(n.createTextNode(" "),i)}return t}function be(n,e){if(n.getElementById(W))return;let r=n.createElement("style");r.id=W,e&&(r.nonce=e),r.textContent=H,n.head.append(r)}function Y(n,e,r={}){let t=n.ownerDocument;r.injectStyles!==!1&&be(t,r.styleNonce);let i=t.createElement("section");i.className=`xeno-ui${r.className?` ${r.className}`:""}`;let m=t.createElement("header");m.className="xeno-ui__header";let g=t.createElement("h2");g.className="xeno-ui__title";let h=t.createElement("span");h.className="xeno-ui__status",h.setAttribute("role","status"),h.setAttribute("aria-live","polite");let R=t.createElement("span");R.className="xeno-ui__tokens";let _=M(t,"Clear");if(_.setAttribute("aria-label","Clear conversation"),_.addEventListener("click",()=>{S(e,{type:"clear"})}),m.append(g,h,R,_),r.onClose){let o=M(t,"X");o.setAttribute("aria-label","Close agent chat"),o.addEventListener("click",r.onClose),m.append(o)}let d=t.createElement("div");d.className="xeno-ui__timeline",d.setAttribute("role","log"),d.setAttribute("aria-live","polite"),d.setAttribute("aria-relevant","additions text");let k=t.createElement("div"),v=t.createElement("form");v.className="xeno-ui__composer",v.setAttribute("role","form");let c=t.createElement("textarea");c.className="xeno-ui__input",c.rows=1;let U=t.createElement("div");U.className="xeno-ui__controls";let N=M(t,"Cancel","xeno-ui__button--danger");N.addEventListener("click",()=>{S(e,{type:"cancel"})});let E=M(t,"Send","xeno-ui__button--primary");E.type="submit",U.append(N,E),v.append(c,U),i.append(m,d,k,v),n.replaceChildren(i);function b(){c.style.height="auto";let o=44,C=144,f=Math.max(c.scrollHeight,o);c.style.height=`${Math.min(f,C)}px`,c.style.overflowY=f>C?"auto":"hidden"}async function O(){let o=c.value;await S(e,{type:"send",text:o})&&(c.value="",b())}v.addEventListener("submit",o=>{o.preventDefault(),O()}),c.addEventListener("keydown",o=>{o.key==="Enter"&&(o.ctrlKey||o.metaKey)&&(o.preventDefault(),O())}),c.addEventListener("input",b);let p=null,w=null;function $(o){if(o.permission&&p===o.permission.requestId&&k.children.length>0)return;if(k.replaceChildren(),!o.permission){if(p){let a=w??c;queueMicrotask(()=>a.focus())}p=null,w=null;return}let C=p!==o.permission.requestId;if(C){let a=t.activeElement;w=a&&"focus"in a?a:c,p=o.permission.requestId}let f=t.createElement("section");f.className="xeno-ui__permission",f.setAttribute("role",o.permission.role),f.setAttribute("aria-modal","true"),f.setAttribute("aria-label",o.permission.accessibleName),f.dataset.risk=o.permission.riskLevel;let L=t.createElement("h3");L.className="xeno-ui__permission-title",L.textContent=o.permission.accessibleName;let s=t.createElement("div");s.id=`xeno-ui-permission-${o.permission.requestId}`,s.textContent=o.permission.description,f.setAttribute("aria-describedby",s.id);let l=t.createElement("div");l.className="xeno-ui__permission-actions";let x=null;for(let a of o.permission.controls){let u=M(t,a.label,a.decision==="deny"?"xeno-ui__button--danger":"");u.dataset.decision=a.decision,x??=u,u.addEventListener("click",()=>{S(e,{type:"permission",requestId:o.permission.requestId,decision:a.decision})}),l.append(u)}f.append(L,s,l),k.append(f),C&&x&&queueMicrotask(()=>x?.focus())}function T(){let o=z(e.getSnapshot(),r);i.setAttribute("role",o.region.role),i.setAttribute("aria-label",o.region.accessibleName),g.textContent=o.header.title,h.textContent=o.header.statusText,R.textContent=o.header.tokenText,d.setAttribute("aria-busy",String(o.timeline.busy));let C=d.scrollHeight-d.scrollTop-d.clientHeight;if(o.timeline.entries.length===0){let f=t.createElement("div");f.className="xeno-ui__empty",f.textContent="No messages yet",d.replaceChildren(f)}else d.replaceChildren(...o.timeline.entries.map(f=>xe(t,f,e)));C<48&&(d.scrollTop=d.scrollHeight),$(o),c.disabled=o.composer.disabled,c.setAttribute("aria-label",o.composer.inputLabel),c.placeholder=o.composer.placeholder,E.textContent=o.composer.sendLabel,E.disabled=o.composer.disabled,N.textContent=o.composer.cancelLabel,N.hidden=!o.timeline.busy}let y=null,P=!1;function V(){let o=t.defaultView?.requestAnimationFrame;if(o){if(y!==null)return;y=o.call(t.defaultView,()=>{y=null,T()});return}P||(P=!0,queueMicrotask(()=>{P=!1,T()}))}let j=e.subscribe(V);return T(),b(),{element:i,render:T,focusInput(){c.focus()},dispose(){j(),y!==null&&t.defaultView?.cancelAnimationFrame&&t.defaultView.cancelAnimationFrame(y),i.remove()}}}0&&(module.exports={XENO_UI_RENDERER_API_VERSION,createAgentUiController,createAgentUiView,dispatchAgentUiAction,isSafeMarkdownHref,mountAgentUi,parseMarkdown,xenoUiCss,xenoUiTokens});
34
+ `;var Q=64*1024;function pe(n){let t;try{t=JSON.stringify(n,null,2)??String(n)}catch{t="[Unserializable value]"}return t.length<=Q?t:`${t.slice(0,Q)}
35
+ [truncated]`}function ge(n){if(n.type==="message"){let t=n.data.role==="assistant";return{key:n.data.id,kind:t?"assistant-message":"user-message",role:"article",accessibleName:t?"Assistant message":"Your message",text:n.data.content,streaming:n.data.isStreaming}}if(n.type==="tool_call"){let t=n.data.durationMs===void 0?"":` in ${n.data.durationMs} ms`;return{key:n.data.id,kind:"tool-call",role:"status",accessibleName:`${n.data.toolName} tool ${n.data.status}`,text:`${n.data.toolName}: ${n.data.status}${t}`,detail:pe({input:n.data.input,result:n.data.result}),state:n.data.status}}return{key:n.data.id,kind:"error",role:"alert",accessibleName:"Agent error",text:n.data.message,retryable:n.data.retryable}}function fe(n){return[...n.network?["Extra access: network"]:[],...n.directories.map(t=>`Extra access: directory ${t}`),`Justification: ${n.justification.replace(/\s+/g," ").trim()}`]}function z(n,t={}){let i=t.agentName?.trim()||"Xeno Agent",e=n.permissionRequest;return{apiVersion:1,revision:n.revision,region:{role:"region",accessibleName:t.regionLabel?.trim()||`${i} chat`},header:{title:i,statusRole:"status",statusText:n.status,tokenText:`${n.tokenUsage.total.toLocaleString()} tokens`},timeline:{role:"log",live:"polite",busy:n.isProcessing,entries:n.items.map(ge)},permission:e?{role:"alertdialog",accessibleName:`Permission required for ${e.toolName}`,description:e.description||e.detail,riskLevel:e.riskLevel,requestId:e.id,...e.elevation?{elevationLines:fe(e.elevation)}:{},controls:e.oneTime?[{label:"Allow for this call only",decision:"allow"},{label:"Deny",decision:"deny"}]:[{label:"Allow once",decision:"allow"},{label:"Always allow",decision:"always"},{label:"Deny",decision:"deny"}]}:null,composer:{role:"form",inputLabel:t.inputLabel?.trim()||"Message Xeno Agent",placeholder:t.inputPlaceholder?.trim()||"Message or command...",disabled:n.isProcessing,sendLabel:"Send",cancelLabel:"Cancel"}}}async function S(n,t){switch(t.type){case"send":return n.sendMessage(t.text);case"cancel":return n.cancelExecution(),!0;case"clear":return n.clearMessages(),!0;case"retry":return n.retryLastMessage();case"permission":return n.resolvePermission(t.requestId,t.decision)}}var W="xeno-owned-agent-ui-v1";function xe(n,t,i){for(let e of D(i)){if(e.kind==="text"){t.append(n.createTextNode(e.text));continue}if(e.kind==="code-block"){let r=n.createElement("pre"),m=n.createElement("code");e.language&&(m.dataset.language=e.language),m.textContent=e.code,r.append(m),t.append(r);continue}if(e.kind==="inline-code"){let r=n.createElement("code");r.textContent=e.code,t.append(r);continue}if(e.kind==="strong"||e.kind==="emphasis"){let r=n.createElement(e.kind==="strong"?"strong":"em");r.textContent=e.text,t.append(r);continue}if(e.kind==="link"){if(!q(e.href)){t.append(n.createTextNode(e.text));continue}let r=n.createElement("a");r.textContent=e.text,r.href=e.href,r.rel="noopener noreferrer",(r.protocol==="http:"||r.protocol==="https:")&&(r.target="_blank"),t.append(r)}}}function M(n,t,i=""){let e=n.createElement("button");return e.type="button",e.className=`xeno-ui__button${i?` ${i}`:""}`,e.textContent=t,e}function be(n,t,i){let e=n.createElement(t.role==="article"?"article":"div");if(e.className=`xeno-ui__entry xeno-ui__entry--${t.kind==="user-message"?"user":t.kind==="assistant-message"?"assistant":t.kind==="tool-call"?"tool":"error"}`,e.setAttribute("role",t.role),e.setAttribute("aria-label",t.accessibleName),e.dataset.xenoKey=t.key,t.streaming&&e.setAttribute("aria-busy","true"),xe(n,e,t.text),t.detail){let r=n.createElement("details");r.className="xeno-ui__details";let m=n.createElement("summary");m.textContent="Details";let g=n.createElement("pre");g.textContent=t.detail,r.append(m,g),e.append(r)}if(t.retryable){let r=M(n,"Retry");r.addEventListener("click",()=>{S(i,{type:"retry"})}),e.append(n.createTextNode(" "),r)}return e}function ye(n,t){if(n.getElementById(W))return;let i=n.createElement("style");i.id=W,t&&(i.nonce=t),i.textContent=H,n.head.append(i)}function J(n,t,i={}){let e=n.ownerDocument;i.injectStyles!==!1&&ye(e,i.styleNonce);let r=e.createElement("section");r.className=`xeno-ui${i.className?` ${i.className}`:""}`;let m=e.createElement("header");m.className="xeno-ui__header";let g=e.createElement("h2");g.className="xeno-ui__title";let A=e.createElement("span");A.className="xeno-ui__status",A.setAttribute("role","status"),A.setAttribute("aria-live","polite");let N=e.createElement("span");N.className="xeno-ui__tokens";let _=M(e,"Clear");if(_.setAttribute("aria-label","Clear conversation"),_.addEventListener("click",()=>{S(t,{type:"clear"})}),m.append(g,A,N,_),i.onClose){let o=M(e,"X");o.setAttribute("aria-label","Close agent chat"),o.addEventListener("click",i.onClose),m.append(o)}let u=e.createElement("div");u.className="xeno-ui__timeline",u.setAttribute("role","log"),u.setAttribute("aria-live","polite"),u.setAttribute("aria-relevant","additions text");let k=e.createElement("div"),h=e.createElement("form");h.className="xeno-ui__composer",h.setAttribute("role","form");let d=e.createElement("textarea");d.className="xeno-ui__input",d.rows=1;let w=e.createElement("div");w.className="xeno-ui__controls";let R=M(e,"Cancel","xeno-ui__button--danger");R.addEventListener("click",()=>{S(t,{type:"cancel"})});let E=M(e,"Send","xeno-ui__button--primary");E.type="submit",w.append(R,E),h.append(d,w),r.append(m,u,k,h),n.replaceChildren(r);function b(){d.style.height="auto";let o=44,T=144,f=Math.max(d.scrollHeight,o);d.style.height=`${Math.min(f,T)}px`,d.style.overflowY=f>T?"auto":"hidden"}async function O(){let o=d.value;await S(t,{type:"send",text:o})&&(d.value="",b())}h.addEventListener("submit",o=>{o.preventDefault(),O()}),d.addEventListener("keydown",o=>{o.key==="Enter"&&(o.ctrlKey||o.metaKey)&&(o.preventDefault(),O())}),d.addEventListener("input",b);let p=null,U=null;function $(o){if(o.permission&&p===o.permission.requestId&&k.children.length>0)return;if(k.replaceChildren(),!o.permission){if(p){let a=U??d;queueMicrotask(()=>a.focus())}p=null,U=null;return}let T=p!==o.permission.requestId;if(T){let a=e.activeElement;U=a&&"focus"in a?a:d,p=o.permission.requestId}let f=e.createElement("section");f.className="xeno-ui__permission",f.setAttribute("role",o.permission.role),f.setAttribute("aria-modal","true"),f.setAttribute("aria-label",o.permission.accessibleName),f.dataset.risk=o.permission.riskLevel;let I=e.createElement("h3");I.className="xeno-ui__permission-title",I.textContent=o.permission.accessibleName;let s=e.createElement("div");s.id=`xeno-ui-permission-${o.permission.requestId}`,s.textContent=o.permission.description,f.setAttribute("aria-describedby",s.id);for(let a of o.permission.elevationLines??[]){let c=e.createElement("div");c.className="xeno-ui__permission-elevation",c.textContent=a,s.append(e.createElement("br"),c)}let l=e.createElement("div");l.className="xeno-ui__permission-actions";let x=null;for(let a of o.permission.controls){let c=M(e,a.label,a.decision==="deny"?"xeno-ui__button--danger":"");c.dataset.decision=a.decision,x??=c,c.addEventListener("click",()=>{S(t,{type:"permission",requestId:o.permission.requestId,decision:a.decision})}),l.append(c)}f.append(I,s,l),k.append(f),T&&x&&queueMicrotask(()=>x?.focus())}function C(){let o=z(t.getSnapshot(),i);r.setAttribute("role",o.region.role),r.setAttribute("aria-label",o.region.accessibleName),g.textContent=o.header.title,A.textContent=o.header.statusText,N.textContent=o.header.tokenText,u.setAttribute("aria-busy",String(o.timeline.busy));let T=u.scrollHeight-u.scrollTop-u.clientHeight;if(o.timeline.entries.length===0){let f=e.createElement("div");f.className="xeno-ui__empty",f.textContent="No messages yet",u.replaceChildren(f)}else u.replaceChildren(...o.timeline.entries.map(f=>be(e,f,t)));T<48&&(u.scrollTop=u.scrollHeight),$(o),d.disabled=o.composer.disabled,d.setAttribute("aria-label",o.composer.inputLabel),d.placeholder=o.composer.placeholder,E.textContent=o.composer.sendLabel,E.disabled=o.composer.disabled,R.textContent=o.composer.cancelLabel,R.hidden=!o.timeline.busy}let y=null,P=!1;function V(){let o=e.defaultView?.requestAnimationFrame;if(o){if(y!==null)return;y=o.call(e.defaultView,()=>{y=null,C()});return}P||(P=!0,queueMicrotask(()=>{P=!1,C()}))}let j=t.subscribe(V);return C(),b(),{element:r,render:C,focusInput(){d.focus()},dispose(){j(),y!==null&&e.defaultView?.cancelAnimationFrame&&e.defaultView.cancelAnimationFrame(y),r.remove()}}}0&&(module.exports={XENO_UI_RENDERER_API_VERSION,createAgentUiController,createAgentUiView,dispatchAgentUiAction,isSafeMarkdownHref,mountAgentUi,parseMarkdown,xenoUiCss,xenoUiTokens});
@@ -163,6 +163,12 @@ interface AgentUiPermissionRequest {
163
163
  preview?: PermissionPromptPreview;
164
164
  riskLevel: "low" | "medium" | "high";
165
165
  timestamp: number;
166
+ oneTime?: boolean;
167
+ elevation?: {
168
+ network: boolean;
169
+ directories: readonly string[];
170
+ justification: string;
171
+ };
166
172
  }
167
173
  interface TokenUsage {
168
174
  input: number;
@@ -225,6 +231,7 @@ interface AgentUiPermissionView {
225
231
  description: string;
226
232
  riskLevel: "low" | "medium" | "high";
227
233
  requestId: string;
234
+ elevationLines?: readonly string[];
228
235
  controls: readonly {
229
236
  label: string;
230
237
  decision: PermissionDecision;
@@ -163,6 +163,12 @@ interface AgentUiPermissionRequest {
163
163
  preview?: PermissionPromptPreview;
164
164
  riskLevel: "low" | "medium" | "high";
165
165
  timestamp: number;
166
+ oneTime?: boolean;
167
+ elevation?: {
168
+ network: boolean;
169
+ directories: readonly string[];
170
+ justification: string;
171
+ };
166
172
  }
167
173
  interface TokenUsage {
168
174
  input: number;
@@ -225,6 +231,7 @@ interface AgentUiPermissionView {
225
231
  description: string;
226
232
  riskLevel: "low" | "medium" | "high";
227
233
  requestId: string;
234
+ elevationLines?: readonly string[];
228
235
  controls: readonly {
229
236
  label: string;
230
237
  decision: PermissionDecision;
package/dist/ui/index.js CHANGED
@@ -1,4 +1,4 @@
1
- var Q={View:"Read",Replace:"Write",GlobTool:"Glob",GrepTool:"Grep",SQLiteAnalyze:"SqliteAnalyze",ReadNotebook:"NotebookRead",NotebookEditCell:"NotebookEdit",CoordinationSend:"Send",CoordinationQuery:"Receive"};function W(n){return Q[n]??n}var Y=new Set(["Read","Glob","Grep","LS","MemoryRead","Think","dispatch_agent","ElfAnalyze","Receive","ListAgents","ListSessions","CoordinationQuery"]),J=new Set(["Write","Edit","MemoryWrite","Send","CoordinationSend"]),Z=new Set(["Bash"]);function F(n){let t=W(n);return Z.has(t)?"high":Y.has(t)?"low":(J.has(t),"medium")}var L=1;function ee(n){let t=n.config;return t&&typeof t=="object"?t:null}function H(n){let t=n.tokenUsage;return{input:Number(t.input)||0,output:Number(t.output)||0,total:Number(t.total)||0}}function te(n){let t=n.toLowerCase();return["rate limit","429","network","timeout","econnrefused","api error","unreachable"].some(r=>t.includes(r))}function ne(n){let t=n.agent,r=n.now??Date.now,e=0,i=n.createId??(()=>`xeno-ui-${r()}-${++e}`),m=new Set,g=[],h="idle",S=H(t),_=null,d=null,k=null,v=null,c="",U=null,R=0,E=!1,b=!1,O=0,p=ee(t),w=p?.permissionEngine,D=w?.promptFn;function T(){return Object.freeze({apiVersion:1,revision:O,items:Object.freeze([...g]),isProcessing:E,status:h,tokenUsage:Object.freeze({...S}),permissionRequest:_?Object.freeze({..._}):null,lastUserMessage:k})}function y(){O+=1;let s=T();for(let l of[...m])l(s)}function N(s){g=[...g,s],y()}function V(s){let l=[...g];for(let x=l.length-1;x>=0;x-=1){let a=l[x];if(a?.type==="message"&&a.data.role==="assistant"){l[x]={type:"message",data:s(a.data)},g=l,y();return}}}function q(s,l){let x=[...g];for(let a=x.length-1;a>=0;a-=1){let u=x[a];if(u?.type==="tool_call"&&u.data.id===s){x[a]={type:"tool_call",data:l(u.data)},g=x,y();return}}}function o(){v&&(V(s=>({...s,isStreaming:!1})),v=null,c="")}function C(s){let l={id:i(),message:s,retryable:te(s),timestamp:r()};N({type:"error",data:l})}function f(s){p&&(p.onText=s.onText,p.onToolStart=s.onToolStart,p.onToolEnd=s.onToolEnd,p.onError=s.onError)}async function I(s){let l=s.trim();if(b||E||!l)return!1;E=!0,k=l,h="thinking",v=null,c="";let x={id:i(),role:"user",content:l,timestamp:r()};g=[...g,{type:"message",data:x}],y();let a={onText:p?.onText,onToolStart:p?.onToolStart,onToolEnd:p?.onToolEnd,onError:p?.onError};p&&(p.onText=u=>{a.onText?.(u),!b&&(c+=u,v?V(A=>({...A,content:c,isStreaming:!0})):(v=i(),N({type:"message",data:{id:v,role:"assistant",content:c,timestamp:r(),isStreaming:!0}})))},p.onToolStart=(u,A)=>{a.onToolStart?.(u,A),!b&&(o(),h="executing",U=i(),R=r(),N({type:"tool_call",data:{id:U,toolName:u,input:A,status:"running",timestamp:r()}}))},p.onToolEnd=(u,A)=>{a.onToolEnd?.(u,A),!b&&(U&&(q(U,K=>({...K,status:A.success?"success":"error",result:A,durationMs:Math.max(0,r()-R)})),U=null),h="thinking",y())},p.onError=(u,A)=>a.onError?.(u,A));try{await t.run(l),b||(o(),h="idle",S=H(t),y())}catch(u){if(!b){o();let A=u instanceof Error?u:new Error(String(u));h=A.name==="AgentInterruptedError"?"idle":"error",A.name!=="AgentInterruptedError"&&C(A.message),S=H(t),y()}}finally{E=!1,f(a),b||y()}return!0}return n.enablePermissionRequests&&w&&(w.promptFn=s=>(d&&d("deny"),new Promise(l=>{d=l,_={id:i(),toolName:s.toolName,detail:s.detail,description:s.description,operation:s.operation,preview:s.preview,riskLevel:F(s.toolName),timestamp:r()},y()}))),{apiVersion:1,getSnapshot:T,subscribe(s){if(b)throw new Error("Agent UI controller is disposed");return m.add(s),s(T()),()=>m.delete(s)},sendMessage:I,cancelExecution(){!b&&E&&t.cancelCurrentTurn()},clearMessages(){b||(g=[],v=null,c="",y())},retryLastMessage(){return b||E||!k?Promise.resolve(!1):(g=g.filter((s,l,x)=>s.type!=="error"?!0:x.slice(l+1).some(a=>a.type!=="error")),h="idle",y(),I(k))},resolvePermission(s,l){if(b||!_||_.id!==s||!d)return!1;let x=d;return d=null,_=null,y(),x(l),!0},dispose(){b||(b=!0,d&&d("deny"),d=null,_=null,w&&(w.promptFn=D),m.clear())}}}function oe(n){let t=[],r=[[/```([\w-]*)\n([\s\S]*?)```/,e=>({kind:"code-block",language:e[1]??"",code:e[2]??""})],[/`([^`\n]+)`/,e=>({kind:"inline-code",code:e[1]??""})],[/\*\*(.+?)\*\*/,e=>({kind:"strong",text:e[1]??""})],[/\*([^*\n]+)\*/,e=>({kind:"emphasis",text:e[1]??""})],[/\[([^\]]+)\]\(([^)\s]+)\)/,e=>({kind:"link",text:e[1]??"",href:e[2]??""})]];for(let[e,i]of r){let m=n.match(e);m?.index!==void 0&&t.push({index:m.index,value:i(m),length:m[0].length})}return t.sort((e,i)=>e.index-i.index),t[0]??null}function z(n){let t=[],r=n;for(;r;){let e=oe(r);if(!e){t.push({kind:"text",text:r});break}e.index>0&&t.push({kind:"text",text:r.slice(0,e.index)}),t.push(e.value),r=r.slice(e.index+e.length)}return t}function $(n){try{let t=new URL(n,"https://xeno.invalid/");return t.protocol==="https:"||t.protocol==="http:"||t.protocol==="mailto:"}catch{return!1}}var re=Object.freeze({background:"#101214",surface:"#181b1f",surfaceRaised:"#20242a",border:"#343a42",text:"#f2f4f7",textMuted:"#aab2bd",accent:"#5da9e9",success:"#56b881",warning:"#e7b65a",danger:"#e57373",focus:"#8bc5f4"}),j=`
1
+ var Q={View:"Read",Replace:"Write",GlobTool:"Glob",GrepTool:"Grep",SQLiteAnalyze:"SqliteAnalyze",ReadNotebook:"NotebookRead",NotebookEditCell:"NotebookEdit",CoordinationSend:"Send",CoordinationQuery:"Receive"};function W(n){return Q[n]??n}var J=new Set(["Read","Glob","Grep","LS","MemoryRead","Think","dispatch_agent","ElfAnalyze","Receive","ListAgents","ListSessions","CoordinationQuery"]),Y=new Set(["Write","Edit","MemoryWrite","Send","CoordinationSend"]),Z=new Set(["Bash"]);function F(n){let t=W(n);return Z.has(t)?"high":J.has(t)?"low":(Y.has(t),"medium")}var I=1;function ee(n){let t=n.config;return t&&typeof t=="object"?t:null}function H(n){let t=n.tokenUsage;return{input:Number(t.input)||0,output:Number(t.output)||0,total:Number(t.total)||0}}function te(n){let t=n.toLowerCase();return["rate limit","429","network","timeout","econnrefused","api error","unreachable"].some(r=>t.includes(r))}function ne(n){let t=n.agent,r=n.now??Date.now,e=0,s=n.createId??(()=>`xeno-ui-${r()}-${++e}`),m=new Set,g=[],A="idle",S=H(t),_=null,u=null,k=null,h=null,d="",w=null,N=0,E=!1,b=!1,O=0,p=ee(t),U=p?.permissionEngine,D=U?.promptFn;function C(){return Object.freeze({apiVersion:1,revision:O,items:Object.freeze([...g]),isProcessing:E,status:A,tokenUsage:Object.freeze({...S}),permissionRequest:_?Object.freeze({..._}):null,lastUserMessage:k})}function y(){O+=1;let i=C();for(let l of[...m])l(i)}function R(i){g=[...g,i],y()}function V(i){let l=[...g];for(let x=l.length-1;x>=0;x-=1){let a=l[x];if(a?.type==="message"&&a.data.role==="assistant"){l[x]={type:"message",data:i(a.data)},g=l,y();return}}}function q(i,l){let x=[...g];for(let a=x.length-1;a>=0;a-=1){let c=x[a];if(c?.type==="tool_call"&&c.data.id===i){x[a]={type:"tool_call",data:l(c.data)},g=x,y();return}}}function o(){h&&(V(i=>({...i,isStreaming:!1})),h=null,d="")}function T(i){let l={id:s(),message:i,retryable:te(i),timestamp:r()};R({type:"error",data:l})}function f(i){p&&(p.onText=i.onText,p.onToolStart=i.onToolStart,p.onToolEnd=i.onToolEnd,p.onError=i.onError)}async function L(i){let l=i.trim();if(b||E||!l)return!1;E=!0,k=l,A="thinking",h=null,d="";let x={id:s(),role:"user",content:l,timestamp:r()};g=[...g,{type:"message",data:x}],y();let a={onText:p?.onText,onToolStart:p?.onToolStart,onToolEnd:p?.onToolEnd,onError:p?.onError};p&&(p.onText=c=>{a.onText?.(c),!b&&(d+=c,h?V(v=>({...v,content:d,isStreaming:!0})):(h=s(),R({type:"message",data:{id:h,role:"assistant",content:d,timestamp:r(),isStreaming:!0}})))},p.onToolStart=(c,v)=>{a.onToolStart?.(c,v),!b&&(o(),A="executing",w=s(),N=r(),R({type:"tool_call",data:{id:w,toolName:c,input:v,status:"running",timestamp:r()}}))},p.onToolEnd=(c,v)=>{a.onToolEnd?.(c,v),!b&&(w&&(q(w,K=>({...K,status:v.success?"success":"error",result:v,durationMs:Math.max(0,r()-N)})),w=null),A="thinking",y())},p.onError=(c,v)=>a.onError?.(c,v));try{await t.run(l),b||(o(),A="idle",S=H(t),y())}catch(c){if(!b){o();let v=c instanceof Error?c:new Error(String(c));A=v.name==="AgentInterruptedError"?"idle":"error",v.name!=="AgentInterruptedError"&&T(v.message),S=H(t),y()}}finally{E=!1,f(a),b||y()}return!0}return n.enablePermissionRequests&&U&&(U.promptFn=i=>(u&&u("deny"),new Promise(l=>{u=l,_={id:s(),toolName:i.toolName,detail:i.detail,description:i.description,operation:i.operation,preview:i.preview,riskLevel:F(i.toolName),timestamp:r(),...i.oneTime?{oneTime:!0}:{},...i.elevation?{elevation:{network:i.elevation.network,directories:[...i.elevation.directories],justification:i.elevation.justification}}:{}},y()}))),{apiVersion:1,getSnapshot:C,subscribe(i){if(b)throw new Error("Agent UI controller is disposed");return m.add(i),i(C()),()=>m.delete(i)},sendMessage:L,cancelExecution(){!b&&E&&t.cancelCurrentTurn()},clearMessages(){b||(g=[],h=null,d="",y())},retryLastMessage(){return b||E||!k?Promise.resolve(!1):(g=g.filter((i,l,x)=>i.type!=="error"?!0:x.slice(l+1).some(a=>a.type!=="error")),A="idle",y(),L(k))},resolvePermission(i,l){if(b||!_||_.id!==i||!u)return!1;_.oneTime&&l==="always"&&(l="allow");let x=u;return u=null,_=null,y(),x(l),!0},dispose(){b||(b=!0,u&&u("deny"),u=null,_=null,U&&(U.promptFn=D),m.clear())}}}function oe(n){let t=[],r=[[/```([\w-]*)\n([\s\S]*?)```/,e=>({kind:"code-block",language:e[1]??"",code:e[2]??""})],[/`([^`\n]+)`/,e=>({kind:"inline-code",code:e[1]??""})],[/\*\*(.+?)\*\*/,e=>({kind:"strong",text:e[1]??""})],[/\*([^*\n]+)\*/,e=>({kind:"emphasis",text:e[1]??""})],[/\[([^\]]+)\]\(([^)\s]+)\)/,e=>({kind:"link",text:e[1]??"",href:e[2]??""})]];for(let[e,s]of r){let m=n.match(e);m?.index!==void 0&&t.push({index:m.index,value:s(m),length:m[0].length})}return t.sort((e,s)=>e.index-s.index),t[0]??null}function z(n){let t=[],r=n;for(;r;){let e=oe(r);if(!e){t.push({kind:"text",text:r});break}e.index>0&&t.push({kind:"text",text:r.slice(0,e.index)}),t.push(e.value),r=r.slice(e.index+e.length)}return t}function $(n){try{let t=new URL(n,"https://xeno.invalid/");return t.protocol==="https:"||t.protocol==="http:"||t.protocol==="mailto:"}catch{return!1}}var ie=Object.freeze({background:"#101214",surface:"#181b1f",surfaceRaised:"#20242a",border:"#343a42",text:"#f2f4f7",textMuted:"#aab2bd",accent:"#5da9e9",success:"#56b881",warning:"#e7b65a",danger:"#e57373",focus:"#8bc5f4"}),j=`
2
2
  .xeno-ui{box-sizing:border-box;display:grid;grid-template-rows:auto minmax(12rem,1fr) auto;width:min(32rem,100%);height:min(44rem,100%);min-height:24rem;border:1px solid var(--xeno-border,#343a42);background:var(--xeno-bg,#101214);color:var(--xeno-text,#f2f4f7);font:14px/1.45 ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;letter-spacing:0}
3
3
  .xeno-ui *{box-sizing:border-box;letter-spacing:0}
4
4
  .xeno-ui__header{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem;border-bottom:1px solid var(--xeno-border,#343a42);background:var(--xeno-surface,#181b1f)}
@@ -31,5 +31,5 @@ var Q={View:"Read",Replace:"Write",GlobTool:"Glob",GrepTool:"Grep",SQLiteAnalyze
31
31
  .xeno-ui :focus-visible{outline:2px solid var(--xeno-focus,#8bc5f4);outline-offset:2px}
32
32
  @media (max-width:36rem){.xeno-ui{width:100%;height:100%;border-left:0;border-right:0}.xeno-ui__entry--user,.xeno-ui__entry--assistant{margin-left:0;margin-right:0}.xeno-ui__composer{grid-template-columns:1fr}.xeno-ui__controls{justify-content:flex-end}}
33
33
  @media (prefers-reduced-motion:reduce){.xeno-ui *{scroll-behavior:auto!important;transition:none!important}}
34
- `;var G=64*1024;function ie(n){let t;try{t=JSON.stringify(n,null,2)??String(n)}catch{t="[Unserializable value]"}return t.length<=G?t:`${t.slice(0,G)}
35
- [truncated]`}function se(n){if(n.type==="message"){let t=n.data.role==="assistant";return{key:n.data.id,kind:t?"assistant-message":"user-message",role:"article",accessibleName:t?"Assistant message":"Your message",text:n.data.content,streaming:n.data.isStreaming}}if(n.type==="tool_call"){let t=n.data.durationMs===void 0?"":` in ${n.data.durationMs} ms`;return{key:n.data.id,kind:"tool-call",role:"status",accessibleName:`${n.data.toolName} tool ${n.data.status}`,text:`${n.data.toolName}: ${n.data.status}${t}`,detail:ie({input:n.data.input,result:n.data.result}),state:n.data.status}}return{key:n.data.id,kind:"error",role:"alert",accessibleName:"Agent error",text:n.data.message,retryable:n.data.retryable}}function X(n,t={}){let r=t.agentName?.trim()||"Xeno Agent",e=n.permissionRequest;return{apiVersion:1,revision:n.revision,region:{role:"region",accessibleName:t.regionLabel?.trim()||`${r} chat`},header:{title:r,statusRole:"status",statusText:n.status,tokenText:`${n.tokenUsage.total.toLocaleString()} tokens`},timeline:{role:"log",live:"polite",busy:n.isProcessing,entries:n.items.map(se)},permission:e?{role:"alertdialog",accessibleName:`Permission required for ${e.toolName}`,description:e.description||e.detail,riskLevel:e.riskLevel,requestId:e.id,controls:[{label:"Allow once",decision:"allow"},{label:"Always allow",decision:"always"},{label:"Deny",decision:"deny"}]}:null,composer:{role:"form",inputLabel:t.inputLabel?.trim()||"Message Xeno Agent",placeholder:t.inputPlaceholder?.trim()||"Message or command...",disabled:n.isProcessing,sendLabel:"Send",cancelLabel:"Cancel"}}}async function P(n,t){switch(t.type){case"send":return n.sendMessage(t.text);case"cancel":return n.cancelExecution(),!0;case"clear":return n.clearMessages(),!0;case"retry":return n.retryLastMessage();case"permission":return n.resolvePermission(t.requestId,t.decision)}}var B="xeno-owned-agent-ui-v1";function ae(n,t,r){for(let e of z(r)){if(e.kind==="text"){t.append(n.createTextNode(e.text));continue}if(e.kind==="code-block"){let i=n.createElement("pre"),m=n.createElement("code");e.language&&(m.dataset.language=e.language),m.textContent=e.code,i.append(m),t.append(i);continue}if(e.kind==="inline-code"){let i=n.createElement("code");i.textContent=e.code,t.append(i);continue}if(e.kind==="strong"||e.kind==="emphasis"){let i=n.createElement(e.kind==="strong"?"strong":"em");i.textContent=e.text,t.append(i);continue}if(e.kind==="link"){if(!$(e.href)){t.append(n.createTextNode(e.text));continue}let i=n.createElement("a");i.textContent=e.text,i.href=e.href,i.rel="noopener noreferrer",(i.protocol==="http:"||i.protocol==="https:")&&(i.target="_blank"),t.append(i)}}}function M(n,t,r=""){let e=n.createElement("button");return e.type="button",e.className=`xeno-ui__button${r?` ${r}`:""}`,e.textContent=t,e}function le(n,t,r){let e=n.createElement(t.role==="article"?"article":"div");if(e.className=`xeno-ui__entry xeno-ui__entry--${t.kind==="user-message"?"user":t.kind==="assistant-message"?"assistant":t.kind==="tool-call"?"tool":"error"}`,e.setAttribute("role",t.role),e.setAttribute("aria-label",t.accessibleName),e.dataset.xenoKey=t.key,t.streaming&&e.setAttribute("aria-busy","true"),ae(n,e,t.text),t.detail){let i=n.createElement("details");i.className="xeno-ui__details";let m=n.createElement("summary");m.textContent="Details";let g=n.createElement("pre");g.textContent=t.detail,i.append(m,g),e.append(i)}if(t.retryable){let i=M(n,"Retry");i.addEventListener("click",()=>{P(r,{type:"retry"})}),e.append(n.createTextNode(" "),i)}return e}function ce(n,t){if(n.getElementById(B))return;let r=n.createElement("style");r.id=B,t&&(r.nonce=t),r.textContent=j,n.head.append(r)}function de(n,t,r={}){let e=n.ownerDocument;r.injectStyles!==!1&&ce(e,r.styleNonce);let i=e.createElement("section");i.className=`xeno-ui${r.className?` ${r.className}`:""}`;let m=e.createElement("header");m.className="xeno-ui__header";let g=e.createElement("h2");g.className="xeno-ui__title";let h=e.createElement("span");h.className="xeno-ui__status",h.setAttribute("role","status"),h.setAttribute("aria-live","polite");let S=e.createElement("span");S.className="xeno-ui__tokens";let _=M(e,"Clear");if(_.setAttribute("aria-label","Clear conversation"),_.addEventListener("click",()=>{P(t,{type:"clear"})}),m.append(g,h,S,_),r.onClose){let o=M(e,"X");o.setAttribute("aria-label","Close agent chat"),o.addEventListener("click",r.onClose),m.append(o)}let d=e.createElement("div");d.className="xeno-ui__timeline",d.setAttribute("role","log"),d.setAttribute("aria-live","polite"),d.setAttribute("aria-relevant","additions text");let k=e.createElement("div"),v=e.createElement("form");v.className="xeno-ui__composer",v.setAttribute("role","form");let c=e.createElement("textarea");c.className="xeno-ui__input",c.rows=1;let U=e.createElement("div");U.className="xeno-ui__controls";let R=M(e,"Cancel","xeno-ui__button--danger");R.addEventListener("click",()=>{P(t,{type:"cancel"})});let E=M(e,"Send","xeno-ui__button--primary");E.type="submit",U.append(R,E),v.append(c,U),i.append(m,d,k,v),n.replaceChildren(i);function b(){c.style.height="auto";let o=44,C=144,f=Math.max(c.scrollHeight,o);c.style.height=`${Math.min(f,C)}px`,c.style.overflowY=f>C?"auto":"hidden"}async function O(){let o=c.value;await P(t,{type:"send",text:o})&&(c.value="",b())}v.addEventListener("submit",o=>{o.preventDefault(),O()}),c.addEventListener("keydown",o=>{o.key==="Enter"&&(o.ctrlKey||o.metaKey)&&(o.preventDefault(),O())}),c.addEventListener("input",b);let p=null,w=null;function D(o){if(o.permission&&p===o.permission.requestId&&k.children.length>0)return;if(k.replaceChildren(),!o.permission){if(p){let a=w??c;queueMicrotask(()=>a.focus())}p=null,w=null;return}let C=p!==o.permission.requestId;if(C){let a=e.activeElement;w=a&&"focus"in a?a:c,p=o.permission.requestId}let f=e.createElement("section");f.className="xeno-ui__permission",f.setAttribute("role",o.permission.role),f.setAttribute("aria-modal","true"),f.setAttribute("aria-label",o.permission.accessibleName),f.dataset.risk=o.permission.riskLevel;let I=e.createElement("h3");I.className="xeno-ui__permission-title",I.textContent=o.permission.accessibleName;let s=e.createElement("div");s.id=`xeno-ui-permission-${o.permission.requestId}`,s.textContent=o.permission.description,f.setAttribute("aria-describedby",s.id);let l=e.createElement("div");l.className="xeno-ui__permission-actions";let x=null;for(let a of o.permission.controls){let u=M(e,a.label,a.decision==="deny"?"xeno-ui__button--danger":"");u.dataset.decision=a.decision,x??=u,u.addEventListener("click",()=>{P(t,{type:"permission",requestId:o.permission.requestId,decision:a.decision})}),l.append(u)}f.append(I,s,l),k.append(f),C&&x&&queueMicrotask(()=>x?.focus())}function T(){let o=X(t.getSnapshot(),r);i.setAttribute("role",o.region.role),i.setAttribute("aria-label",o.region.accessibleName),g.textContent=o.header.title,h.textContent=o.header.statusText,S.textContent=o.header.tokenText,d.setAttribute("aria-busy",String(o.timeline.busy));let C=d.scrollHeight-d.scrollTop-d.clientHeight;if(o.timeline.entries.length===0){let f=e.createElement("div");f.className="xeno-ui__empty",f.textContent="No messages yet",d.replaceChildren(f)}else d.replaceChildren(...o.timeline.entries.map(f=>le(e,f,t)));C<48&&(d.scrollTop=d.scrollHeight),D(o),c.disabled=o.composer.disabled,c.setAttribute("aria-label",o.composer.inputLabel),c.placeholder=o.composer.placeholder,E.textContent=o.composer.sendLabel,E.disabled=o.composer.disabled,R.textContent=o.composer.cancelLabel,R.hidden=!o.timeline.busy}let y=null,N=!1;function V(){let o=e.defaultView?.requestAnimationFrame;if(o){if(y!==null)return;y=o.call(e.defaultView,()=>{y=null,T()});return}N||(N=!0,queueMicrotask(()=>{N=!1,T()}))}let q=t.subscribe(V);return T(),b(),{element:i,render:T,focusInput(){c.focus()},dispose(){q(),y!==null&&e.defaultView?.cancelAnimationFrame&&e.defaultView.cancelAnimationFrame(y),i.remove()}}}export{L as XENO_UI_RENDERER_API_VERSION,ne as createAgentUiController,X as createAgentUiView,P as dispatchAgentUiAction,$ as isSafeMarkdownHref,de as mountAgentUi,z as parseMarkdown,j as xenoUiCss,re as xenoUiTokens};
34
+ `;var G=64*1024;function re(n){let t;try{t=JSON.stringify(n,null,2)??String(n)}catch{t="[Unserializable value]"}return t.length<=G?t:`${t.slice(0,G)}
35
+ [truncated]`}function se(n){if(n.type==="message"){let t=n.data.role==="assistant";return{key:n.data.id,kind:t?"assistant-message":"user-message",role:"article",accessibleName:t?"Assistant message":"Your message",text:n.data.content,streaming:n.data.isStreaming}}if(n.type==="tool_call"){let t=n.data.durationMs===void 0?"":` in ${n.data.durationMs} ms`;return{key:n.data.id,kind:"tool-call",role:"status",accessibleName:`${n.data.toolName} tool ${n.data.status}`,text:`${n.data.toolName}: ${n.data.status}${t}`,detail:re({input:n.data.input,result:n.data.result}),state:n.data.status}}return{key:n.data.id,kind:"error",role:"alert",accessibleName:"Agent error",text:n.data.message,retryable:n.data.retryable}}function ae(n){return[...n.network?["Extra access: network"]:[],...n.directories.map(t=>`Extra access: directory ${t}`),`Justification: ${n.justification.replace(/\s+/g," ").trim()}`]}function X(n,t={}){let r=t.agentName?.trim()||"Xeno Agent",e=n.permissionRequest;return{apiVersion:1,revision:n.revision,region:{role:"region",accessibleName:t.regionLabel?.trim()||`${r} chat`},header:{title:r,statusRole:"status",statusText:n.status,tokenText:`${n.tokenUsage.total.toLocaleString()} tokens`},timeline:{role:"log",live:"polite",busy:n.isProcessing,entries:n.items.map(se)},permission:e?{role:"alertdialog",accessibleName:`Permission required for ${e.toolName}`,description:e.description||e.detail,riskLevel:e.riskLevel,requestId:e.id,...e.elevation?{elevationLines:ae(e.elevation)}:{},controls:e.oneTime?[{label:"Allow for this call only",decision:"allow"},{label:"Deny",decision:"deny"}]:[{label:"Allow once",decision:"allow"},{label:"Always allow",decision:"always"},{label:"Deny",decision:"deny"}]}:null,composer:{role:"form",inputLabel:t.inputLabel?.trim()||"Message Xeno Agent",placeholder:t.inputPlaceholder?.trim()||"Message or command...",disabled:n.isProcessing,sendLabel:"Send",cancelLabel:"Cancel"}}}async function P(n,t){switch(t.type){case"send":return n.sendMessage(t.text);case"cancel":return n.cancelExecution(),!0;case"clear":return n.clearMessages(),!0;case"retry":return n.retryLastMessage();case"permission":return n.resolvePermission(t.requestId,t.decision)}}var B="xeno-owned-agent-ui-v1";function le(n,t,r){for(let e of z(r)){if(e.kind==="text"){t.append(n.createTextNode(e.text));continue}if(e.kind==="code-block"){let s=n.createElement("pre"),m=n.createElement("code");e.language&&(m.dataset.language=e.language),m.textContent=e.code,s.append(m),t.append(s);continue}if(e.kind==="inline-code"){let s=n.createElement("code");s.textContent=e.code,t.append(s);continue}if(e.kind==="strong"||e.kind==="emphasis"){let s=n.createElement(e.kind==="strong"?"strong":"em");s.textContent=e.text,t.append(s);continue}if(e.kind==="link"){if(!$(e.href)){t.append(n.createTextNode(e.text));continue}let s=n.createElement("a");s.textContent=e.text,s.href=e.href,s.rel="noopener noreferrer",(s.protocol==="http:"||s.protocol==="https:")&&(s.target="_blank"),t.append(s)}}}function M(n,t,r=""){let e=n.createElement("button");return e.type="button",e.className=`xeno-ui__button${r?` ${r}`:""}`,e.textContent=t,e}function ce(n,t,r){let e=n.createElement(t.role==="article"?"article":"div");if(e.className=`xeno-ui__entry xeno-ui__entry--${t.kind==="user-message"?"user":t.kind==="assistant-message"?"assistant":t.kind==="tool-call"?"tool":"error"}`,e.setAttribute("role",t.role),e.setAttribute("aria-label",t.accessibleName),e.dataset.xenoKey=t.key,t.streaming&&e.setAttribute("aria-busy","true"),le(n,e,t.text),t.detail){let s=n.createElement("details");s.className="xeno-ui__details";let m=n.createElement("summary");m.textContent="Details";let g=n.createElement("pre");g.textContent=t.detail,s.append(m,g),e.append(s)}if(t.retryable){let s=M(n,"Retry");s.addEventListener("click",()=>{P(r,{type:"retry"})}),e.append(n.createTextNode(" "),s)}return e}function de(n,t){if(n.getElementById(B))return;let r=n.createElement("style");r.id=B,t&&(r.nonce=t),r.textContent=j,n.head.append(r)}function ue(n,t,r={}){let e=n.ownerDocument;r.injectStyles!==!1&&de(e,r.styleNonce);let s=e.createElement("section");s.className=`xeno-ui${r.className?` ${r.className}`:""}`;let m=e.createElement("header");m.className="xeno-ui__header";let g=e.createElement("h2");g.className="xeno-ui__title";let A=e.createElement("span");A.className="xeno-ui__status",A.setAttribute("role","status"),A.setAttribute("aria-live","polite");let S=e.createElement("span");S.className="xeno-ui__tokens";let _=M(e,"Clear");if(_.setAttribute("aria-label","Clear conversation"),_.addEventListener("click",()=>{P(t,{type:"clear"})}),m.append(g,A,S,_),r.onClose){let o=M(e,"X");o.setAttribute("aria-label","Close agent chat"),o.addEventListener("click",r.onClose),m.append(o)}let u=e.createElement("div");u.className="xeno-ui__timeline",u.setAttribute("role","log"),u.setAttribute("aria-live","polite"),u.setAttribute("aria-relevant","additions text");let k=e.createElement("div"),h=e.createElement("form");h.className="xeno-ui__composer",h.setAttribute("role","form");let d=e.createElement("textarea");d.className="xeno-ui__input",d.rows=1;let w=e.createElement("div");w.className="xeno-ui__controls";let N=M(e,"Cancel","xeno-ui__button--danger");N.addEventListener("click",()=>{P(t,{type:"cancel"})});let E=M(e,"Send","xeno-ui__button--primary");E.type="submit",w.append(N,E),h.append(d,w),s.append(m,u,k,h),n.replaceChildren(s);function b(){d.style.height="auto";let o=44,T=144,f=Math.max(d.scrollHeight,o);d.style.height=`${Math.min(f,T)}px`,d.style.overflowY=f>T?"auto":"hidden"}async function O(){let o=d.value;await P(t,{type:"send",text:o})&&(d.value="",b())}h.addEventListener("submit",o=>{o.preventDefault(),O()}),d.addEventListener("keydown",o=>{o.key==="Enter"&&(o.ctrlKey||o.metaKey)&&(o.preventDefault(),O())}),d.addEventListener("input",b);let p=null,U=null;function D(o){if(o.permission&&p===o.permission.requestId&&k.children.length>0)return;if(k.replaceChildren(),!o.permission){if(p){let a=U??d;queueMicrotask(()=>a.focus())}p=null,U=null;return}let T=p!==o.permission.requestId;if(T){let a=e.activeElement;U=a&&"focus"in a?a:d,p=o.permission.requestId}let f=e.createElement("section");f.className="xeno-ui__permission",f.setAttribute("role",o.permission.role),f.setAttribute("aria-modal","true"),f.setAttribute("aria-label",o.permission.accessibleName),f.dataset.risk=o.permission.riskLevel;let L=e.createElement("h3");L.className="xeno-ui__permission-title",L.textContent=o.permission.accessibleName;let i=e.createElement("div");i.id=`xeno-ui-permission-${o.permission.requestId}`,i.textContent=o.permission.description,f.setAttribute("aria-describedby",i.id);for(let a of o.permission.elevationLines??[]){let c=e.createElement("div");c.className="xeno-ui__permission-elevation",c.textContent=a,i.append(e.createElement("br"),c)}let l=e.createElement("div");l.className="xeno-ui__permission-actions";let x=null;for(let a of o.permission.controls){let c=M(e,a.label,a.decision==="deny"?"xeno-ui__button--danger":"");c.dataset.decision=a.decision,x??=c,c.addEventListener("click",()=>{P(t,{type:"permission",requestId:o.permission.requestId,decision:a.decision})}),l.append(c)}f.append(L,i,l),k.append(f),T&&x&&queueMicrotask(()=>x?.focus())}function C(){let o=X(t.getSnapshot(),r);s.setAttribute("role",o.region.role),s.setAttribute("aria-label",o.region.accessibleName),g.textContent=o.header.title,A.textContent=o.header.statusText,S.textContent=o.header.tokenText,u.setAttribute("aria-busy",String(o.timeline.busy));let T=u.scrollHeight-u.scrollTop-u.clientHeight;if(o.timeline.entries.length===0){let f=e.createElement("div");f.className="xeno-ui__empty",f.textContent="No messages yet",u.replaceChildren(f)}else u.replaceChildren(...o.timeline.entries.map(f=>ce(e,f,t)));T<48&&(u.scrollTop=u.scrollHeight),D(o),d.disabled=o.composer.disabled,d.setAttribute("aria-label",o.composer.inputLabel),d.placeholder=o.composer.placeholder,E.textContent=o.composer.sendLabel,E.disabled=o.composer.disabled,N.textContent=o.composer.cancelLabel,N.hidden=!o.timeline.busy}let y=null,R=!1;function V(){let o=e.defaultView?.requestAnimationFrame;if(o){if(y!==null)return;y=o.call(e.defaultView,()=>{y=null,C()});return}R||(R=!0,queueMicrotask(()=>{R=!1,C()}))}let q=t.subscribe(V);return C(),b(),{element:s,render:C,focusInput(){d.focus()},dispose(){q(),y!==null&&e.defaultView?.cancelAnimationFrame&&e.defaultView.cancelAnimationFrame(y),s.remove()}}}export{I as XENO_UI_RENDERER_API_VERSION,ne as createAgentUiController,X as createAgentUiView,P as dispatchAgentUiAction,$ as isSafeMarkdownHref,ue as mountAgentUi,z as parseMarkdown,j as xenoUiCss,ie as xenoUiTokens};
@@ -1 +1 @@
1
- {"inputs":{"src/tools/tool-names.ts":{"bytes":2810,"imports":[],"format":"esm"},"src/ui/types.ts":{"bytes":4274,"imports":[],"format":"esm"},"src/ui/controller.ts":{"bytes":10384,"imports":[{"path":"src/tools/tool-names.ts","kind":"import-statement","original":"../tools/tool-names.js"},{"path":"src/ui/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/ui/markdown.ts":{"bytes":2181,"imports":[],"format":"esm"},"src/ui/styles.ts":{"bytes":4255,"imports":[],"format":"esm"},"src/ui/view-model.ts":{"bytes":3744,"imports":[{"path":"src/ui/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/ui/dom-renderer.ts":{"bytes":11767,"imports":[{"path":"src/ui/markdown.ts","kind":"import-statement","original":"./markdown.js"},{"path":"src/ui/styles.ts","kind":"import-statement","original":"./styles.js"},{"path":"src/ui/view-model.ts","kind":"import-statement","original":"./view-model.js"}],"format":"esm"},"src/ui/index.ts":{"bytes":1059,"imports":[{"path":"src/ui/controller.ts","kind":"import-statement","original":"./controller.js"},{"path":"src/ui/dom-renderer.ts","kind":"import-statement","original":"./dom-renderer.js"},{"path":"src/ui/markdown.ts","kind":"import-statement","original":"./markdown.js"},{"path":"src/ui/styles.ts","kind":"import-statement","original":"./styles.js"},{"path":"src/ui/view-model.ts","kind":"import-statement","original":"./view-model.js"},{"path":"src/ui/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"}},"outputs":{"dist/ui/index.cjs":{"imports":[],"exports":[],"entryPoint":"src/ui/index.ts","inputs":{"src/ui/index.ts":{"bytesInOutput":257},"src/tools/tool-names.ts":{"bytesInOutput":572},"src/ui/types.ts":{"bytesInOutput":8},"src/ui/controller.ts":{"bytesInOutput":3352},"src/ui/markdown.ts":{"bytesInOutput":864},"src/ui/styles.ts":{"bytesInOutput":4161},"src/ui/view-model.ts":{"bytesInOutput":2008},"src/ui/dom-renderer.ts":{"bytesInOutput":6079}},"bytes":17919}}}
1
+ {"inputs":{"src/tools/tool-names.ts":{"bytes":2810,"imports":[],"format":"esm"},"src/ui/types.ts":{"bytes":4678,"imports":[],"format":"esm"},"src/ui/controller.ts":{"bytes":10914,"imports":[{"path":"src/tools/tool-names.ts","kind":"import-statement","original":"../tools/tool-names.js"},{"path":"src/ui/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/ui/markdown.ts":{"bytes":2181,"imports":[],"format":"esm"},"src/ui/styles.ts":{"bytes":4255,"imports":[],"format":"esm"},"src/ui/view-model.ts":{"bytes":4490,"imports":[{"path":"src/ui/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/ui/dom-renderer.ts":{"bytes":12031,"imports":[{"path":"src/ui/markdown.ts","kind":"import-statement","original":"./markdown.js"},{"path":"src/ui/styles.ts","kind":"import-statement","original":"./styles.js"},{"path":"src/ui/view-model.ts","kind":"import-statement","original":"./view-model.js"}],"format":"esm"},"src/ui/index.ts":{"bytes":1059,"imports":[{"path":"src/ui/controller.ts","kind":"import-statement","original":"./controller.js"},{"path":"src/ui/dom-renderer.ts","kind":"import-statement","original":"./dom-renderer.js"},{"path":"src/ui/markdown.ts","kind":"import-statement","original":"./markdown.js"},{"path":"src/ui/styles.ts","kind":"import-statement","original":"./styles.js"},{"path":"src/ui/view-model.ts","kind":"import-statement","original":"./view-model.js"},{"path":"src/ui/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"}},"outputs":{"dist/ui/index.cjs":{"imports":[],"exports":[],"entryPoint":"src/ui/index.ts","inputs":{"src/ui/index.ts":{"bytesInOutput":257},"src/tools/tool-names.ts":{"bytesInOutput":572},"src/ui/types.ts":{"bytesInOutput":8},"src/ui/controller.ts":{"bytesInOutput":3559},"src/ui/markdown.ts":{"bytesInOutput":864},"src/ui/styles.ts":{"bytesInOutput":4161},"src/ui/view-model.ts":{"bytesInOutput":2338},"src/ui/dom-renderer.ts":{"bytesInOutput":6248}},"bytes":18625}}}
@@ -1 +1 @@
1
- {"inputs":{"src/tools/tool-names.ts":{"bytes":2810,"imports":[],"format":"esm"},"src/ui/types.ts":{"bytes":4274,"imports":[],"format":"esm"},"src/ui/controller.ts":{"bytes":10384,"imports":[{"path":"src/tools/tool-names.ts","kind":"import-statement","original":"../tools/tool-names.js"},{"path":"src/ui/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/ui/markdown.ts":{"bytes":2181,"imports":[],"format":"esm"},"src/ui/styles.ts":{"bytes":4255,"imports":[],"format":"esm"},"src/ui/view-model.ts":{"bytes":3744,"imports":[{"path":"src/ui/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/ui/dom-renderer.ts":{"bytes":11767,"imports":[{"path":"src/ui/markdown.ts","kind":"import-statement","original":"./markdown.js"},{"path":"src/ui/styles.ts","kind":"import-statement","original":"./styles.js"},{"path":"src/ui/view-model.ts","kind":"import-statement","original":"./view-model.js"}],"format":"esm"},"src/ui/index.ts":{"bytes":1059,"imports":[{"path":"src/ui/controller.ts","kind":"import-statement","original":"./controller.js"},{"path":"src/ui/dom-renderer.ts","kind":"import-statement","original":"./dom-renderer.js"},{"path":"src/ui/markdown.ts","kind":"import-statement","original":"./markdown.js"},{"path":"src/ui/styles.ts","kind":"import-statement","original":"./styles.js"},{"path":"src/ui/view-model.ts","kind":"import-statement","original":"./view-model.js"},{"path":"src/ui/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"}},"outputs":{"dist/ui/index.js":{"imports":[],"exports":["XENO_UI_RENDERER_API_VERSION","createAgentUiController","createAgentUiView","dispatchAgentUiAction","isSafeMarkdownHref","mountAgentUi","parseMarkdown","xenoUiCss","xenoUiTokens"],"entryPoint":"src/ui/index.ts","inputs":{"src/tools/tool-names.ts":{"bytesInOutput":562},"src/ui/types.ts":{"bytesInOutput":8},"src/ui/controller.ts":{"bytesInOutput":3353},"src/ui/index.ts":{"bytesInOutput":0},"src/ui/markdown.ts":{"bytesInOutput":864},"src/ui/styles.ts":{"bytesInOutput":4162},"src/ui/view-model.ts":{"bytesInOutput":2008},"src/ui/dom-renderer.ts":{"bytesInOutput":6080}},"bytes":17256}}}
1
+ {"inputs":{"src/tools/tool-names.ts":{"bytes":2810,"imports":[],"format":"esm"},"src/ui/types.ts":{"bytes":4678,"imports":[],"format":"esm"},"src/ui/controller.ts":{"bytes":10914,"imports":[{"path":"src/tools/tool-names.ts","kind":"import-statement","original":"../tools/tool-names.js"},{"path":"src/ui/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/ui/markdown.ts":{"bytes":2181,"imports":[],"format":"esm"},"src/ui/styles.ts":{"bytes":4255,"imports":[],"format":"esm"},"src/ui/view-model.ts":{"bytes":4490,"imports":[{"path":"src/ui/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"},"src/ui/dom-renderer.ts":{"bytes":12031,"imports":[{"path":"src/ui/markdown.ts","kind":"import-statement","original":"./markdown.js"},{"path":"src/ui/styles.ts","kind":"import-statement","original":"./styles.js"},{"path":"src/ui/view-model.ts","kind":"import-statement","original":"./view-model.js"}],"format":"esm"},"src/ui/index.ts":{"bytes":1059,"imports":[{"path":"src/ui/controller.ts","kind":"import-statement","original":"./controller.js"},{"path":"src/ui/dom-renderer.ts","kind":"import-statement","original":"./dom-renderer.js"},{"path":"src/ui/markdown.ts","kind":"import-statement","original":"./markdown.js"},{"path":"src/ui/styles.ts","kind":"import-statement","original":"./styles.js"},{"path":"src/ui/view-model.ts","kind":"import-statement","original":"./view-model.js"},{"path":"src/ui/types.ts","kind":"import-statement","original":"./types.js"}],"format":"esm"}},"outputs":{"dist/ui/index.js":{"imports":[],"exports":["XENO_UI_RENDERER_API_VERSION","createAgentUiController","createAgentUiView","dispatchAgentUiAction","isSafeMarkdownHref","mountAgentUi","parseMarkdown","xenoUiCss","xenoUiTokens"],"entryPoint":"src/ui/index.ts","inputs":{"src/tools/tool-names.ts":{"bytesInOutput":562},"src/ui/types.ts":{"bytesInOutput":8},"src/ui/controller.ts":{"bytesInOutput":3560},"src/ui/index.ts":{"bytesInOutput":0},"src/ui/markdown.ts":{"bytesInOutput":864},"src/ui/styles.ts":{"bytesInOutput":4162},"src/ui/view-model.ts":{"bytesInOutput":2338},"src/ui/dom-renderer.ts":{"bytesInOutput":6249}},"bytes":17962}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xenosystem/agent-sdk",
3
- "version": "0.10.11",
3
+ "version": "0.10.13",
4
4
  "description": "XENO Agent SDK built from the same engine as XENO CODE",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",