@xenosystem/agent-sdk 0.10.40 → 0.10.42
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.
- package/dist/artifacts/index.cjs +1 -1
- package/dist/artifacts/index.js +1 -1
- package/dist/automation/index.cjs +1 -1
- package/dist/automation/index.js +1 -1
- package/dist/control-plane/index.cjs +1 -1
- package/dist/control-plane/index.js +1 -1
- package/dist/electron/index.cjs +1 -1
- package/dist/electron/index.js +1 -1
- package/dist/electron/metafile-cjs.json +1 -1
- package/dist/electron/metafile-esm.json +1 -1
- package/dist/governance/index.cjs +24 -24
- package/dist/governance/index.d.cts +12 -1
- package/dist/governance/index.d.ts +12 -1
- package/dist/governance/index.js +26 -26
- package/dist/governance/metafile-cjs.json +1 -1
- package/dist/governance/metafile-esm.json +1 -1
- package/dist/index.cjs +313 -313
- package/dist/index.d.cts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +318 -318
- package/dist/metafile-cjs.json +1 -1
- package/dist/metafile-esm.json +1 -1
- package/dist/session/index.cjs +1 -1
- package/dist/session/index.js +1 -1
- package/package.json +2 -2
package/dist/session/index.cjs
CHANGED
|
@@ -48,7 +48,7 @@ ${this.stringify(e.data)}
|
|
|
48
48
|
`)+`
|
|
49
49
|
`;await k(this.transcriptPath,a);let c=this.buildMarkdownDocument(o,"session store");if(await k(this.markdownPath,c),!this.workspaceMirrorDisabled){let u=await this.resolveWorkspaceMarkdownPath();if(u)try{let l=this.buildMarkdownDocument(o,"workspace mirror");await k(u,l)}catch(l){this.workspaceMirrorDisabled=!0,j("Transcript workspace mirror disabled",l)}}}async truncateAfterMessageCount(e){let t=await S(this.transcriptPath);if(!t)return;let r=te(t),s=Math.max(0,e),i=0,o=[];for(let u of r){if(u.type==="user_message"||u.type==="assistant_message"){if(i>=s)break;i+=1}o.push(u)}let a=o.length>0?o.map(u=>JSON.stringify(u)).join(`
|
|
50
50
|
`)+`
|
|
51
|
-
`:"";await k(this.transcriptPath,a);let c=this.buildMarkdownDocument(o,"session store");if(await k(this.markdownPath,c),!this.workspaceMirrorDisabled){let u=await this.resolveWorkspaceMarkdownPath();if(u)try{let l=this.buildMarkdownDocument(o,"workspace mirror");await k(u,l)}catch(l){this.workspaceMirrorDisabled=!0,j("Transcript workspace mirror disabled",l)}}}getSequence(){return this.sequence}async initialize(){try{let e=await S(this.transcriptPath);if(!e){this.sequence=0;return}let t=te(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);j(`Transcript initialization warning: ${t}. Starting with empty transcript.`),this.sequence=0}}async flush(){await this.writeQueue}};var re=M(require("path"),1),bt=require("crypto"),Et=require("fs/promises");var fr={View:"Read",Replace:"Write",GlobTool:"Glob",GrepTool:"Grep",SQLiteAnalyze:"SqliteAnalyze",ReadNotebook:"NotebookRead",NotebookEditCell:"NotebookEdit",CoordinationSend:"Send",CoordinationQuery:"Receive"};function ke(n){return fr[n]??n}var D=class{sessionDir;checkpointsDir;autoInterval;lastCheckpointMessageCount=0;constructor(e,t){this.sessionDir=e,this.checkpointsDir=re.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 $(this.checkpointsDir);let t=(0,bt.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=re.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 ft(this.checkpointsDir,/\.json$/),t=[];for(let r of e){let s=await S(r);if(s){let i=b(s,null);if(i){let o=await(0,Et.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=re.join(this.checkpointsDir,`${e}.json`),r;try{r=await S(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=b(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=ke(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=re.join(this.checkpointsDir,`${e}.json`);await L(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 U=M(require("path"),1),Xe=M(require("os"),1),H=M(require("fs"),1);var mr=Symbol.for("@xenosystem/agent-sdk/shutdown-registry"),hr=globalThis,Ge=hr[mr]??={cleanups:new Set,exitHandlerRegistered:!1,signalHandlersInstalled:!1},We=Ge.cleanups;function wr(){for(let n of We)try{n()}catch{}}function Pt(n){return We.add(n),!Ge.exitHandlerRegistered&&typeof process<"u"&&typeof process.on=="function"&&(Ge.exitHandlerRegistered=!0,process.on("exit",wr)),()=>{We.delete(n)}}var Rt="0.10.
|
|
51
|
+
`:"";await k(this.transcriptPath,a);let c=this.buildMarkdownDocument(o,"session store");if(await k(this.markdownPath,c),!this.workspaceMirrorDisabled){let u=await this.resolveWorkspaceMarkdownPath();if(u)try{let l=this.buildMarkdownDocument(o,"workspace mirror");await k(u,l)}catch(l){this.workspaceMirrorDisabled=!0,j("Transcript workspace mirror disabled",l)}}}getSequence(){return this.sequence}async initialize(){try{let e=await S(this.transcriptPath);if(!e){this.sequence=0;return}let t=te(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);j(`Transcript initialization warning: ${t}. Starting with empty transcript.`),this.sequence=0}}async flush(){await this.writeQueue}};var re=M(require("path"),1),bt=require("crypto"),Et=require("fs/promises");var fr={View:"Read",Replace:"Write",GlobTool:"Glob",GrepTool:"Grep",SQLiteAnalyze:"SqliteAnalyze",ReadNotebook:"NotebookRead",NotebookEditCell:"NotebookEdit",CoordinationSend:"Send",CoordinationQuery:"Receive"};function ke(n){return fr[n]??n}var D=class{sessionDir;checkpointsDir;autoInterval;lastCheckpointMessageCount=0;constructor(e,t){this.sessionDir=e,this.checkpointsDir=re.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 $(this.checkpointsDir);let t=(0,bt.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=re.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 ft(this.checkpointsDir,/\.json$/),t=[];for(let r of e){let s=await S(r);if(s){let i=b(s,null);if(i){let o=await(0,Et.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=re.join(this.checkpointsDir,`${e}.json`),r;try{r=await S(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=b(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=ke(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=re.join(this.checkpointsDir,`${e}.json`);await L(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 U=M(require("path"),1),Xe=M(require("os"),1),H=M(require("fs"),1);var mr=Symbol.for("@xenosystem/agent-sdk/shutdown-registry"),hr=globalThis,Ge=hr[mr]??={cleanups:new Set,exitHandlerRegistered:!1,signalHandlersInstalled:!1},We=Ge.cleanups;function wr(){for(let n of We)try{n()}catch{}}function Pt(n){return We.add(n),!Ge.exitHandlerRegistered&&typeof process<"u"&&typeof process.on=="function"&&(Ge.exitHandlerRegistered=!0,process.on("exit",wr)),()=>{We.delete(n)}}var Rt="0.10.42";var yr=1e4,kr=6e4,Sr="session.lock",xr="lock.json",ee=new Map;function Je(n,e){return n!=null&&n.pid===e.pid&&n.hostname===e.hostname&&n.processStartedAt===e.processStartedAt&&n.acquiredAt===e.acquiredAt}function Tr(){for(let[n,e]of ee)try{let t=b(H.readFileSync(n,"utf8"),null);Je(t,e)&&H.unlinkSync(n)}catch{}ee.clear()}Pt(Tr);var X=class n{sessionDir;lockPath;legacyLockPath;sessionId;heartbeatTimer;acquiredOwner;constructor(e){this.sessionDir=e,this.lockPath=U.join(e,Sr),this.legacyLockPath=U.join(e,xr),this.sessionId=U.basename(e)}async acquire(){let e=new Date().toISOString(),t={schemaVersion:1,name:`session:${this.sessionId}`,sessionId:this.sessionId,pid:process.pid,hostname:Xe.hostname(),processStartedAt:new Date(Date.now()-Math.floor(process.uptime()*1e3)).toISOString(),version:Rt,acquiredAt:e,updatedAt:e,heartbeat:e},r=U.dirname(this.lockPath);await H.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 L(s)}try{await H.promises.writeFile(this.lockPath,JSON.stringify(t,null,2),{flag:"wx",encoding:"utf-8"}),this.acquiredOwner=t,ee.set(this.lockPath,t)}catch(i){if(i.code==="EEXIST"){if(!await this.isStalePath(this.lockPath)){let c=await this.readLockAt(this.lockPath);throw new Error(`Session ${this.sessionId} is already locked by PID ${c?.pid} on ${c?.hostname}`)}await L(this.lockPath);try{await H.promises.writeFile(this.lockPath,JSON.stringify(t,null,2),{flag:"wx",encoding:"utf-8"})}catch(c){throw c.code==="EEXIST"?new Error(`Session ${this.sessionId} lock was acquired by another process during stale recovery`):c}this.acquiredOwner=t,ee.set(this.lockPath,t)}else throw i}}async release(){this.stopHeartbeat();let e=this.acquiredOwner;if(this.acquiredOwner=void 0,!e)return;ee.delete(this.lockPath);let t=await this.readLockAt(this.lockPath);Je(t,e)&&await L(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===Xe.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>kr}startHeartbeat(e=yr){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"){G("SessionLock: Session directory removed, stopping heartbeat"),this.stopHeartbeat();return}G(`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(!Je(e,t)){this.acquiredOwner=void 0,ee.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 S(e);return t?b(t,null):null}async findExistingLockPath(){return await S(this.lockPath)?this.lockPath:await S(this.legacyLockPath)?this.legacyLockPath:null}static async cleanStale(e){let t=await fe(e),r=[];for(let s of t){let i=new n(s);if(await i.isStale()){let a=await i.findExistingLockPath();a&&await L(a),r.push(U.basename(s))}}return r}};var C=M(require("path"),1);var ne=1;var A=M(require("path"),1);function vr(n,e){let t=A.resolve(n),r=A.resolve(n,e);return r===t?!0:t===A.parse(t).root?r.startsWith(t):r.startsWith(t+A.sep)}function J(n,e){if(A.isAbsolute(e))return A.resolve(e);if(!vr(n,e))throw new Error(`PathSecurity: Path traversal attempt detected: ${e}`);return A.resolve(n,e)}function Se(n,e=process.platform){let t=A.resolve(n);return e==="win32"?t.toLowerCase():t}function z(n){if(n!==void 0&&n!=="agent"&&n!=="chatOnly")throw new Error("Invalid session execution mode; expected agent or chatOnly.")}var P=M(require("path"),1),ve=M(require("os"),1),R=M(require("node:fs/promises"),1),be=require("node:crypto");var V=require("node:os");var se=require("node:path");var Dn=(0,V.platform)();var Cn=(0,V.release)(),On=(0,V.homedir)();function xe(){let n=process.env.XENO_AGENT_HOME?.trim();return n?(0,se.resolve)(n):(0,se.resolve)((0,V.homedir)(),".xeno-agent")}var Mt=1,_t="recent.json",br=".lock",At=".entries",Er=3e4,ze=6e4,Dt=new Set(["EACCES","EBUSY","EPERM"]),Pr=[5,10,20,40,80,160,320],Te=new Map;function Rr(n,e){let t=(0,be.createHash)("sha256").update(e).digest("hex");return P.join(`${n}${At}`,`${t}.json`)}async function Ve(n,e,t){let r={schemaVersion:1,key:e,entry:t};await k(Rr(n,e),JSON.stringify(r)+`
|
|
52
52
|
`)}async function Mr(n,e){let t=`${n}${At}`,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(P.join(t,s),"utf8").catch(()=>""),o=b(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 It(n){if(!Number.isInteger(n)||n<=0)return!1;try{return process.kill(n,0),!0}catch(e){return e.code==="EPERM"}}async function _r(n){try{let[e,t]=await Promise.all([R.readFile(P.join(n,"owner.json"),"utf8").catch(()=>""),R.stat(n)]),r=b(e,null);return r?.hostname===ve.hostname()&&It(r.pid)?!1:r?.hostname&&r.hostname!==ve.hostname()||!r?Date.now()-t.mtimeMs>ze:Date.now()-t.mtimeMs>ze||!It(r.pid)}catch{return!1}}async function Ct(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=Pr[e];if(process.platform!=="win32"||!r||!Dt.has(r)||s===void 0)throw t;await new Promise(i=>setTimeout(i,s))}}async function Ir(n,e){try{let t=await R.readFile(P.join(n,"owner.json"),"utf8");b(t,null)?.token===e&&await Ct(n)}catch(t){if(t.code!=="ENOENT")throw t}}async function Ke(n,e){let t=K(n),r=Te.get(t)??Promise.resolve(),s,i=new Promise(o=>{s=o});Te.set(t,i),await r;try{return await Ar(t,e)}finally{s(),Te.get(t)===i&&Te.delete(t)}}async function Ar(n,e){let t=`${n}${br}`,r=(0,be.randomUUID)(),s=Date.now();await R.mkdir(P.dirname(n),{recursive:!0});for(let i=0;;i+=1){let o={schemaVersion:1,token:r,pid:process.pid,hostname:ve.hostname(),acquiredAt:new Date().toISOString()};try{await R.mkdir(t),await R.writeFile(P.join(t,"owner.json"),JSON.stringify(o),"utf8");break}catch(a){let c=a.code,u=process.platform==="win32"&&!!c&&Dt.has(c);if(c!=="EEXIST"&&!u)throw a;if(await _r(t)){await Ct(t);continue}if(Date.now()-s>=Er)throw new Error(`Timed out waiting for recent-sessions index lock: ${t}`);let l=Math.min(100,5+i*5)+Math.floor(Math.random()*10);await new Promise(d=>setTimeout(d,l))}}try{return await e()}finally{await Ir(t,r)}}function K(n){return n===void 0?P.join(xe(),_t):P.join(n,".xeno-agent",_t)}function ie(n){let e=P.normalize(n).replace(/[\\/]+$/,""),t=e.length>0?e:P.parse(P.normalize(n)).root;return process.platform==="win32"?t.toLowerCase():t}async function q(n){let e=K(n),t=ge(e)?await S(e):null,r=t?b(t,null):null,s=r&&typeof r=="object"?r:null,i={},o=s?.version===Mt&&s.entries&&typeof s.entries=="object"?s.entries:{};for(let[a,c]of Object.entries(o)){if(!c||typeof c!="object")continue;let u=c;typeof u.sessionId!="string"||u.sessionId.length===0||typeof u.endedAt=="string"&&(i[a]={sessionId:u.sessionId,endedAt:u.endedAt,role:typeof u.role=="string"?u.role:void 0})}return await Mr(e,i),{version:Mt,entries:i}}async function Ee(n,e={}){let t=await q(e.homeDir),r=ie(n),s=t.entries[r];if(s&&!(e.role&&s.role&&s.role!==e.role))return s}async function Pe(n,e={}){let t=ie(n.cwd),r={sessionId:n.sessionId,role:n.role,endedAt:n.endedAt??new Date().toISOString()},s=K(e.homeDir);await Ve(s,t,r),await Ke(e.homeDir,async()=>{let i=await q(e.homeDir);i.entries[t]=r,await k(s,JSON.stringify(i,null,2)+`
|
|
53
53
|
`)})}async function Ot(n,e={}){let t=ie(n),r=K(e.homeDir);(await q(e.homeDir)).entries[t]&&(await Ve(r,t,null),await Ke(e.homeDir,async()=>{let i=await q(e.homeDir);delete i.entries[t],await k(r,JSON.stringify(i,null,2)+`
|
|
54
54
|
`)}))}async function oe(n,e={}){let t=await q(e.homeDir),r=Object.entries(t.entries).filter(([,i])=>i.sessionId===n).map(([i])=>i);if(r.length===0)return;let s=K(e.homeDir);await Promise.all(r.map(i=>Ve(s,i,null))),await Ke(e.homeDir,async()=>{let i=await q(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)+`
|
package/dist/session/index.js
CHANGED
|
@@ -48,7 +48,7 @@ ${this.stringify(e.data)}
|
|
|
48
48
|
`)+`
|
|
49
49
|
`;await y(this.transcriptPath,a);let c=this.buildMarkdownDocument(o,"session store");if(await y(this.markdownPath,c),!this.workspaceMirrorDisabled){let u=await this.resolveWorkspaceMarkdownPath();if(u)try{let l=this.buildMarkdownDocument(o,"workspace mirror");await y(u,l)}catch(l){this.workspaceMirrorDisabled=!0,B("Transcript workspace mirror disabled",l)}}}async truncateAfterMessageCount(e){let t=await k(this.transcriptPath);if(!t)return;let r=Y(t),s=Math.max(0,e),i=0,o=[];for(let u of r){if(u.type==="user_message"||u.type==="assistant_message"){if(i>=s)break;i+=1}o.push(u)}let a=o.length>0?o.map(u=>JSON.stringify(u)).join(`
|
|
50
50
|
`)+`
|
|
51
|
-
`:"";await y(this.transcriptPath,a);let c=this.buildMarkdownDocument(o,"session store");if(await y(this.markdownPath,c),!this.workspaceMirrorDisabled){let u=await this.resolveWorkspaceMarkdownPath();if(u)try{let l=this.buildMarkdownDocument(o,"workspace mirror");await y(u,l)}catch(l){this.workspaceMirrorDisabled=!0,B("Transcript workspace mirror disabled",l)}}}getSequence(){return this.sequence}async initialize(){try{let e=await k(this.transcriptPath);if(!e){this.sequence=0;return}let t=Y(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}};import*as Z from"path";import{randomUUID as or}from"crypto";import{stat as ar}from"fs/promises";var ir={View:"Read",Replace:"Write",GlobTool:"Glob",GrepTool:"Grep",SQLiteAnalyze:"SqliteAnalyze",ReadNotebook:"NotebookRead",NotebookEditCell:"NotebookEdit",CoordinationSend:"Send",CoordinationQuery:"Receive"};function ce(n){return ir[n]??n}var D=class{sessionDir;checkpointsDir;autoInterval;lastCheckpointMessageCount=0;constructor(e,t){this.sessionDir=e,this.checkpointsDir=Z.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 O(this.checkpointsDir);let t=or(),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=Z.join(this.checkpointsDir,`${t}.json`);return await y(i,JSON.stringify(s,null,2)),this.lastCheckpointMessageCount=e.messages.length,r}async list(){let e=await nt(this.checkpointsDir,/\.json$/),t=[];for(let r of e){let s=await k(r);if(s){let i=v(s,null);if(i){let o=await ar(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=Z.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=v(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=ce(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=Z.join(this.checkpointsDir,`${e}.json`);await N(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 j from"path";import*as Ae from"os";import*as F from"fs";var cr=Symbol.for("@xenosystem/agent-sdk/shutdown-registry"),ur=globalThis,_e=ur[cr]??={cleanups:new Set,exitHandlerRegistered:!1,signalHandlersInstalled:!1},Ie=_e.cleanups;function lr(){for(let n of Ie)try{n()}catch{}}function gt(n){return Ie.add(n),!_e.exitHandlerRegistered&&typeof process<"u"&&typeof process.on=="function"&&(_e.exitHandlerRegistered=!0,process.on("exit",lr)),()=>{Ie.delete(n)}}var ft="0.10.
|
|
51
|
+
`:"";await y(this.transcriptPath,a);let c=this.buildMarkdownDocument(o,"session store");if(await y(this.markdownPath,c),!this.workspaceMirrorDisabled){let u=await this.resolveWorkspaceMarkdownPath();if(u)try{let l=this.buildMarkdownDocument(o,"workspace mirror");await y(u,l)}catch(l){this.workspaceMirrorDisabled=!0,B("Transcript workspace mirror disabled",l)}}}getSequence(){return this.sequence}async initialize(){try{let e=await k(this.transcriptPath);if(!e){this.sequence=0;return}let t=Y(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}};import*as Z from"path";import{randomUUID as or}from"crypto";import{stat as ar}from"fs/promises";var ir={View:"Read",Replace:"Write",GlobTool:"Glob",GrepTool:"Grep",SQLiteAnalyze:"SqliteAnalyze",ReadNotebook:"NotebookRead",NotebookEditCell:"NotebookEdit",CoordinationSend:"Send",CoordinationQuery:"Receive"};function ce(n){return ir[n]??n}var D=class{sessionDir;checkpointsDir;autoInterval;lastCheckpointMessageCount=0;constructor(e,t){this.sessionDir=e,this.checkpointsDir=Z.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 O(this.checkpointsDir);let t=or(),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=Z.join(this.checkpointsDir,`${t}.json`);return await y(i,JSON.stringify(s,null,2)),this.lastCheckpointMessageCount=e.messages.length,r}async list(){let e=await nt(this.checkpointsDir,/\.json$/),t=[];for(let r of e){let s=await k(r);if(s){let i=v(s,null);if(i){let o=await ar(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=Z.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=v(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=ce(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=Z.join(this.checkpointsDir,`${e}.json`);await N(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 j from"path";import*as Ae from"os";import*as F from"fs";var cr=Symbol.for("@xenosystem/agent-sdk/shutdown-registry"),ur=globalThis,_e=ur[cr]??={cleanups:new Set,exitHandlerRegistered:!1,signalHandlersInstalled:!1},Ie=_e.cleanups;function lr(){for(let n of Ie)try{n()}catch{}}function gt(n){return Ie.add(n),!_e.exitHandlerRegistered&&typeof process<"u"&&typeof process.on=="function"&&(_e.exitHandlerRegistered=!0,process.on("exit",lr)),()=>{Ie.delete(n)}}var ft="0.10.42";var dr=1e4,pr=6e4,gr="session.lock",fr="lock.json",J=new Map;function De(n,e){return n!=null&&n.pid===e.pid&&n.hostname===e.hostname&&n.processStartedAt===e.processStartedAt&&n.acquiredAt===e.acquiredAt}function mr(){for(let[n,e]of J)try{let t=v(F.readFileSync(n,"utf8"),null);De(t,e)&&F.unlinkSync(n)}catch{}J.clear()}gt(mr);var z=class n{sessionDir;lockPath;legacyLockPath;sessionId;heartbeatTimer;acquiredOwner;constructor(e){this.sessionDir=e,this.lockPath=j.join(e,gr),this.legacyLockPath=j.join(e,fr),this.sessionId=j.basename(e)}async acquire(){let e=new Date().toISOString(),t={schemaVersion:1,name:`session:${this.sessionId}`,sessionId:this.sessionId,pid:process.pid,hostname:Ae.hostname(),processStartedAt:new Date(Date.now()-Math.floor(process.uptime()*1e3)).toISOString(),version:ft,acquiredAt:e,updatedAt:e,heartbeat:e},r=j.dirname(this.lockPath);await F.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 N(s)}try{await F.promises.writeFile(this.lockPath,JSON.stringify(t,null,2),{flag:"wx",encoding:"utf-8"}),this.acquiredOwner=t,J.set(this.lockPath,t)}catch(i){if(i.code==="EEXIST"){if(!await this.isStalePath(this.lockPath)){let c=await this.readLockAt(this.lockPath);throw new Error(`Session ${this.sessionId} is already locked by PID ${c?.pid} on ${c?.hostname}`)}await N(this.lockPath);try{await F.promises.writeFile(this.lockPath,JSON.stringify(t,null,2),{flag:"wx",encoding:"utf-8"})}catch(c){throw c.code==="EEXIST"?new Error(`Session ${this.sessionId} lock was acquired by another process during stale recovery`):c}this.acquiredOwner=t,J.set(this.lockPath,t)}else throw i}}async release(){this.stopHeartbeat();let e=this.acquiredOwner;if(this.acquiredOwner=void 0,!e)return;J.delete(this.lockPath);let t=await this.readLockAt(this.lockPath);De(t,e)&&await N(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===Ae.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>pr}startHeartbeat(e=dr){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"){H("SessionLock: Session directory removed, stopping heartbeat"),this.stopHeartbeat();return}H(`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(!De(e,t)){this.acquiredOwner=void 0,J.delete(this.lockPath),this.stopHeartbeat();return}e.heartbeat=new Date().toISOString(),e.updatedAt=e.heartbeat,await y(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?v(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 oe(e),r=[];for(let s of t){let i=new n(s);if(await i.isStale()){let a=await i.findExistingLockPath();a&&await N(a),r.push(j.basename(s))}}return r}};import*as I from"path";var ee=1;import*as M from"path";function hr(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 q(n,e){if(M.isAbsolute(e))return M.resolve(e);if(!hr(n,e))throw new Error(`PathSecurity: Path traversal attempt detected: ${e}`);return M.resolve(n,e)}function ue(n,e=process.platform){let t=M.resolve(n);return e==="win32"?t.toLowerCase():t}function G(n){if(n!==void 0&&n!=="agent"&&n!=="chatOnly")throw new Error("Invalid session execution mode; expected agent or chatOnly.")}import*as E from"path";import*as pe from"os";import*as P from"node:fs/promises";import{createHash as kr,randomUUID as Sr}from"node:crypto";import{homedir as ht,platform as wr,release as yr}from"node:os";import{delimiter as qn,join as Gn,resolve as mt}from"node:path";var Xn=wr();var Jn=yr(),zn=ht();function le(){let n=process.env.XENO_AGENT_HOME?.trim();return n?mt(n):mt(ht(),".xeno-agent")}var wt=1,yt="recent.json",xr=".lock",St=".entries",Tr=3e4,Ce=6e4,xt=new Set(["EACCES","EBUSY","EPERM"]),vr=[5,10,20,40,80,160,320],de=new Map;function br(n,e){let t=kr("sha256").update(e).digest("hex");return E.join(`${n}${St}`,`${t}.json`)}async function Oe(n,e,t){let r={schemaVersion:1,key:e,entry:t};await y(br(n,e),JSON.stringify(r)+`
|
|
52
52
|
`)}async function Er(n,e){let t=`${n}${St}`,r;try{r=await P.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 P.readFile(E.join(t,s),"utf8").catch(()=>""),o=v(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 kt(n){if(!Number.isInteger(n)||n<=0)return!1;try{return process.kill(n,0),!0}catch(e){return e.code==="EPERM"}}async function Pr(n){try{let[e,t]=await Promise.all([P.readFile(E.join(n,"owner.json"),"utf8").catch(()=>""),P.stat(n)]),r=v(e,null);return r?.hostname===pe.hostname()&&kt(r.pid)?!1:r?.hostname&&r.hostname!==pe.hostname()||!r?Date.now()-t.mtimeMs>Ce:Date.now()-t.mtimeMs>Ce||!kt(r.pid)}catch{return!1}}async function Tt(n){for(let e=0;;e+=1)try{await P.rm(n,{recursive:!0});return}catch(t){let r=t.code;if(r==="ENOENT")return;let s=vr[e];if(process.platform!=="win32"||!r||!xt.has(r)||s===void 0)throw t;await new Promise(i=>setTimeout(i,s))}}async function Rr(n,e){try{let t=await P.readFile(E.join(n,"owner.json"),"utf8");v(t,null)?.token===e&&await Tt(n)}catch(t){if(t.code!=="ENOENT")throw t}}async function Ne(n,e){let t=V(n),r=de.get(t)??Promise.resolve(),s,i=new Promise(o=>{s=o});de.set(t,i),await r;try{return await Mr(t,e)}finally{s(),de.get(t)===i&&de.delete(t)}}async function Mr(n,e){let t=`${n}${xr}`,r=Sr(),s=Date.now();await P.mkdir(E.dirname(n),{recursive:!0});for(let i=0;;i+=1){let o={schemaVersion:1,token:r,pid:process.pid,hostname:pe.hostname(),acquiredAt:new Date().toISOString()};try{await P.mkdir(t),await P.writeFile(E.join(t,"owner.json"),JSON.stringify(o),"utf8");break}catch(a){let c=a.code,u=process.platform==="win32"&&!!c&&xt.has(c);if(c!=="EEXIST"&&!u)throw a;if(await Pr(t)){await Tt(t);continue}if(Date.now()-s>=Tr)throw new Error(`Timed out waiting for recent-sessions index lock: ${t}`);let l=Math.min(100,5+i*5)+Math.floor(Math.random()*10);await new Promise(d=>setTimeout(d,l))}}try{return await e()}finally{await Rr(t,r)}}function V(n){return n===void 0?E.join(le(),yt):E.join(n,".xeno-agent",yt)}function ge(n){let e=E.normalize(n).replace(/[\\/]+$/,""),t=e.length>0?e:E.parse(E.normalize(n)).root;return process.platform==="win32"?t.toLowerCase():t}async function W(n){let e=V(n),t=ie(e)?await k(e):null,r=t?v(t,null):null,s=r&&typeof r=="object"?r:null,i={},o=s?.version===wt&&s.entries&&typeof s.entries=="object"?s.entries:{};for(let[a,c]of Object.entries(o)){if(!c||typeof c!="object")continue;let u=c;typeof u.sessionId!="string"||u.sessionId.length===0||typeof u.endedAt=="string"&&(i[a]={sessionId:u.sessionId,endedAt:u.endedAt,role:typeof u.role=="string"?u.role:void 0})}return await Er(e,i),{version:wt,entries:i}}async function $e(n,e={}){let t=await W(e.homeDir),r=ge(n),s=t.entries[r];if(s&&!(e.role&&s.role&&s.role!==e.role))return s}async function Le(n,e={}){let t=ge(n.cwd),r={sessionId:n.sessionId,role:n.role,endedAt:n.endedAt??new Date().toISOString()},s=V(e.homeDir);await Oe(s,t,r),await Ne(e.homeDir,async()=>{let i=await W(e.homeDir);i.entries[t]=r,await y(s,JSON.stringify(i,null,2)+`
|
|
53
53
|
`)})}async function _r(n,e={}){let t=ge(n),r=V(e.homeDir);(await W(e.homeDir)).entries[t]&&(await Oe(r,t,null),await Ne(e.homeDir,async()=>{let i=await W(e.homeDir);delete i.entries[t],await y(r,JSON.stringify(i,null,2)+`
|
|
54
54
|
`)}))}async function fe(n,e={}){let t=await W(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=>Oe(s,i,null))),await Ne(e.homeDir,async()=>{let i=await W(e.homeDir);for(let[o,a]of Object.entries(i.entries))a.sessionId===n&&delete i.entries[o];await y(s,JSON.stringify(i,null,2)+`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xenosystem/agent-sdk",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.42",
|
|
4
4
|
"description": "XENO Agent SDK built from the same engine as XENO CODE",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -219,9 +219,9 @@
|
|
|
219
219
|
},
|
|
220
220
|
"devDependencies": {
|
|
221
221
|
"@eslint/js": "^9.39.4",
|
|
222
|
-
"@xenosystem/web-context-client": "0.1.3",
|
|
223
222
|
"@types/node": "^22.12.0",
|
|
224
223
|
"@typescript/native": "npm:typescript@^7.0.2",
|
|
224
|
+
"@xenosystem/web-context-client": "0.1.5",
|
|
225
225
|
"eslint": "^9.39.4",
|
|
226
226
|
"tsup": "^8.5.1",
|
|
227
227
|
"typescript": "npm:@typescript/typescript6@^6.0.2",
|