eve
Version:
Filesystem-first framework for durable backend AI agents that run anywhere.
4 lines • 3.24 kB
JavaScript
import{readDevSessionEvents}from"./logs-events.js";import{basename,join}from"node:path";import{readFile,readdir,stat}from"node:fs/promises";const LOG_DIRECTORY_SEGMENTS=[`.eve`,`logs`],LOG_DISPLAY_DIRECTORY=LOG_DIRECTORY_SEGMENTS.join(`/`),LOG_ID_PATTERN=/^dev-(\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}\.\d{3}Z)-\d+\.log$/;async function listDevDiagnosticLogs(e){let t=join(e,...LOG_DIRECTORY_SEGMENTS),r;try{r=await readdir(t)}catch(e){if(e.code===`ENOENT`)return[];throw e}let s=r.filter(e=>LOG_ID_PATTERN.test(e)).sort().reverse();return Promise.all(s.map(async e=>{let r=join(t,e);return{id:e.slice(0,-4),path:r,startedAt:parseStartedAt(e),sizeBytes:(await stat(r)).size}}))}function parseStartedAt(e){let t=LOG_ID_PATTERN.exec(e);if(t===null)return;let n=t[1].replace(/T(\d{2})-(\d{2})-(\d{2})/,`T$1:$2:$3`),r=new Date(n);return Number.isNaN(r.getTime())?void 0:r}function resolveDevDiagnosticLog(e,n){let r=basename(n.replaceAll(`\\`,`/`)),i=r.endsWith(`.log`)?r.slice(0,-4):r,a=e.find(e=>e.id===i);if(a!==void 0)return a;let o=e.filter(e=>e.id.startsWith(i)||e.id.startsWith(`dev-${i}`));if(o.length===1)return o[0];throw o.length===0?Error(`No diagnostic log matches "${n}". Run \`eve logs ls\` to see available logs.`):Error([`"${n}" matches ${o.length} diagnostic logs:`,...o.map(e=>` ${e.id}`),`Pass a longer prefix or the full id.`].join(`
`))}async function runLogsShowCommand(t,n,i,a={}){let o=await listDevDiagnosticLogs(n);if(o.length===0){let e=`No dev diagnostic logs found under ${LOG_DISPLAY_DIRECTORY}.`;if(i!==void 0)throw Error(e);t.log(e);return}let c=i===void 0?o[0]:resolveDevDiagnosticLog(o,i),l=await readFile(c.path,`utf8`);if(a.events===!0){let t=eventWindowForLog(o,c,a.now??(()=>new Date)),r=await(a.readEvents??readDevSessionEvents)(n,t);r.length>0&&(l=mergeLogWithEvents(l,r))}if(a.dump!==!0){t.log(l.trimEnd());return}let u=c.path.slice(0,-4)+`.dump`,d;try{d=await readFile(u,`utf8`)}catch(e){if(e.code!==`ENOENT`)throw e}if(d===void 0){t.log(l.trimEnd());return}t.log(`${d.trimEnd()}\n${l.trimEnd()}`)}function eventWindowForLog(e,t,n){let r=e.findIndex(e=>e.id===t.id),i=r>0?e[r-1].startedAt:void 0;return{from:t.startedAt??new Date(0),to:i??n()}}function mergeLogWithEvents(e,t){let n=[],r=``;for(let t of e.split(`
`))if(t.trim().length!==0){try{let e=JSON.parse(t).at;typeof e==`string`&&(r=e)}catch{}n.push({at:r,line:t})}let i=t.map(e=>({at:e.at,line:JSON.stringify(e)})),a=[],o=0,s=0;for(;o<n.length||s<i.length;){let e=n[o],t=i[s];t===void 0||e!==void 0&&e.at<=t.at?(a.push(e.line),o+=1):(a.push(t.line),s+=1)}return`${a.join(`
`)}\n`}async function runLogsListCommand(e,t,n={}){let r=await listDevDiagnosticLogs(t);if(n.json){let t=r.map(e=>({id:e.id,path:e.path,startedAt:e.startedAt?.toISOString()??null,sizeBytes:e.sizeBytes}));e.log(JSON.stringify(t,null,2));return}if(r.length===0){e.log(`No dev diagnostic logs found under ${LOG_DISPLAY_DIRECTORY}.`);return}for(let t of r){let n=t.startedAt?.toISOString()??`unknown start`;e.log(`${t.id} ${n} ${formatSize(t.sizeBytes)}`)}}function formatSize(e){if(e<1024)return`${e} B`;let t=e/1024;return t<1024?`${t.toFixed(1)} KiB`:`${(t/1024).toFixed(1)} MiB`}export{listDevDiagnosticLogs,resolveDevDiagnosticLog,runLogsListCommand,runLogsShowCommand};